Tailwind CSS 4 Migration (#100)

* Updated to TailwindCSS v4
* Moved CSS module to its own CSS file because of lightingcss strict validation
* Respect next parameter in middleware
* Updated all packages. 
* Split CSSs for better organization.
* Redesigned theme and auth pages
* Improved pill and header design
* Formatted files using Prettier
* Better footer layout
* Better auth layout
* Bump version of the repository to 2.0.0
This commit is contained in:
Giancarlo Buomprisco
2025-01-28 13:19:52 +07:00
committed by GitHub
parent d799f54ede
commit 4e91f267e0
109 changed files with 1347 additions and 1178 deletions

View File

@@ -58,7 +58,7 @@
"react-hook-form": "^7.54.2",
"react-i18next": "^15.4.0",
"sonner": "^1.7.2",
"tailwindcss": "3.4.17",
"tailwindcss": "4.0.0",
"tailwindcss-animate": "^1.0.7",
"typescript": "^5.7.3",
"zod": "^3.24.1"

View File

@@ -39,7 +39,7 @@ export function BorderedNavigationMenuItem(props: {
<Button
asChild
variant={'ghost'}
className={cn('relative active:shadow-sm', props.buttonClassName)}
className={cn('relative active:shadow-xs', props.buttonClassName)}
>
<Link
href={props.path}
@@ -58,7 +58,7 @@ export function BorderedNavigationMenuItem(props: {
{active ? (
<span
className={cn(
'absolute -bottom-2.5 left-0 h-0.5 w-full bg-primary animate-in fade-in zoom-in-90',
'bg-primary animate-in fade-in zoom-in-90 absolute -bottom-2.5 left-0 h-0.5 w-full',
)}
/>
) : null}

View File

@@ -17,7 +17,7 @@ export const CardButton: React.FC<
return (
<Comp
className={cn(
'group relative flex h-36 flex-col rounded-lg border transition-all hover:bg-secondary/20 hover:shadow active:bg-secondary active:bg-secondary/50 active:shadow-lg dark:shadow-primary/20',
'group hover:bg-secondary/20 active:bg-secondary active:bg-secondary/50 dark:shadow-primary/20 relative flex h-36 flex-col rounded-lg border transition-all hover:shadow-xs active:shadow-lg',
className,
)}
{...props}
@@ -39,7 +39,7 @@ export const CardButtonTitle: React.FC<
<Comp
className={cn(
className,
'align-super text-sm font-medium text-muted-foreground transition-colors group-hover:text-secondary-foreground',
'text-muted-foreground group-hover:text-secondary-foreground align-super text-sm font-medium transition-colors',
)}
{...props}
>
@@ -69,7 +69,7 @@ export const CardButtonHeader: React.FC<
<ChevronRight
className={cn(
'absolute right-2 top-4 h-4 text-muted-foreground transition-colors group-hover:text-secondary-foreground',
'text-muted-foreground group-hover:text-secondary-foreground absolute top-4 right-2 h-4 transition-colors',
{
hidden: !displayArrow,
},

View File

@@ -188,7 +188,7 @@ function Pagination<T>({
table: ReactTable<T>;
}>) {
return (
<div className="flex items-center justify-end space-x-4">
<div className="flex items-center justify-end gap-x-4">
<span className="flex items-center text-sm">
<Trans
i18nKey={'common:pageOfPages'}
@@ -199,7 +199,7 @@ function Pagination<T>({
/>
</span>
<div className="flex items-center justify-end space-x-1">
<div className="flex items-center justify-end gap-x-2">
<Button
size={'icon'}
variant={'ghost'}

View File

@@ -18,7 +18,7 @@ const EmptyStateText: React.FC<React.HTMLAttributes<HTMLParagraphElement>> = ({
className,
...props
}) => (
<p className={cn('text-sm text-muted-foreground', className)} {...props} />
<p className={cn('text-muted-foreground text-sm', className)} {...props} />
);
EmptyStateText.displayName = 'EmptyStateText';
@@ -60,7 +60,7 @@ const EmptyState: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({
return (
<div
className={cn(
'flex flex-1 items-center justify-center rounded-lg border border-dashed shadow-sm',
'flex flex-1 items-center justify-center rounded-lg border border-dashed shadow-xs',
className,
)}
{...props}

View File

@@ -138,14 +138,14 @@ export const ImageUploadInput: React.FC<Props> =
return (
<label
id={'image-upload-input'}
className={`relative flex h-10 w-full cursor-pointer rounded-md border border-dashed border-input bg-background px-3 py-2 text-sm outline-none ring-primary ring-offset-2 ring-offset-background transition-all file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus:ring-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50`}
className={`border-input bg-background ring-primary ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring relative flex h-10 w-full cursor-pointer rounded-md border border-dashed px-3 py-2 text-sm ring-offset-2 outline-hidden transition-all file:border-0 file:bg-transparent file:text-sm file:font-medium focus:ring-2 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50`}
>
<Input />
<div className={'flex items-center space-x-4'}>
<div className={'flex'}>
<If condition={!state.image}>
<UploadCloud className={'h-5 text-muted-foreground'} />
<UploadCloud className={'text-muted-foreground h-5'} />
</If>
<If condition={state.image}>
@@ -188,7 +188,7 @@ export const ImageUploadInput: React.FC<Props> =
<If condition={state.image}>
<Button
size={'icon'}
className={'!h-5 !w-5'}
className={'h-5! w-5!'}
onClick={imageRemoved}
>
<X className="h-4" />

View File

@@ -20,14 +20,14 @@ export function LoadingOverlay({
'flex flex-col items-center justify-center space-y-4',
className,
{
[`fixed left-0 top-0 z-[100] h-screen w-screen bg-background`]:
[`bg-background fixed top-0 left-0 z-100 h-screen w-screen`]:
fullPage,
},
)}
>
<Spinner className={spinnerClassName} />
<div className={'text-sm text-muted-foreground'}>{children}</div>
<div className={'text-muted-foreground text-sm'}>{children}</div>
</div>
);
}

View File

@@ -1,45 +1,28 @@
import React from 'react';
import { cn } from '../../lib/utils';
import {
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '../../shadcn/card';
import { CardDescription, CardHeader, CardTitle } from '../../shadcn/card';
interface FeatureCardProps extends React.HTMLAttributes<HTMLDivElement> {
label: string;
description: string;
image?: React.ReactNode;
}
export const FeatureCard: React.FC<FeatureCardProps> = ({
className,
label,
description,
image,
children,
...props
}) => {
return (
<div
className={cn(
'rounded-3xl p-2 ring-2 ring-gray-100 dark:ring-primary/10',
className,
)}
{...props}
>
<div className={cn('rounded-xl border p-4', className)} {...props}>
<CardHeader>
<CardTitle className="text-xl font-semibold">{label}</CardTitle>
<CardDescription className="max-w-xs text-sm font-semibold tracking-tight text-muted-foreground">
<CardTitle className="text-xl font-medium">{label}</CardTitle>
<CardDescription className="text-muted-foreground max-w-xs text-sm font-normal">
{description}
</CardDescription>
</CardHeader>
<CardContent>
{image}
{children}
</CardContent>
</div>
);
};

View File

@@ -20,7 +20,7 @@ export const FeatureShowcase: React.FC<FeatureShowcaseProps> =
className={cn('flex flex-col justify-between space-y-8', className)}
{...props}
>
<div className="flex w-full max-w-5xl flex-col space-y-4">
<div className="flex w-full max-w-5xl flex-col gap-y-4">
{icon && <div className="flex">{icon}</div>}
<h3 className="text-3xl font-normal tracking-tight xl:text-5xl">
{heading}
@@ -40,7 +40,7 @@ export function FeatureShowcaseIconContainer(
<div className={'flex'}>
<div
className={cn(
'flex items-center justify-center space-x-4 rounded-lg p-3 font-semibold',
'flex items-center justify-center space-x-4 rounded-lg p-3 font-medium',
props.className,
)}
>

View File

@@ -26,31 +26,35 @@ export const Footer: React.FC<FooterProps> = ({
return (
<footer
className={cn(
'site-footer relative mt-auto w-full py-8 2xl:py-16',
'site-footer relative mt-auto w-full py-8 2xl:py-20',
className,
)}
{...props}
>
<div className="container">
<div className="flex flex-col space-y-8 lg:flex-row lg:space-y-0">
<div className="flex w-full space-x-2 lg:w-4/12 xl:w-4/12 xl:space-x-6 2xl:space-x-8">
<div className="flex flex-col space-y-4">
<div className="flex w-full gap-x-3 lg:w-4/12 xl:w-4/12 xl:space-x-6 2xl:space-x-8">
<div className="flex flex-col gap-y-4">
<div>{logo}</div>
<div className="flex flex-col space-y-4">
<div className="flex flex-col gap-y-4">
<div>
<p className="text-sm text-muted-foreground">{description}</p>
<p className="text-muted-foreground text-sm tracking-tight">
{description}
</p>
</div>
<div className="flex text-xs text-muted-foreground">
<div className="text-muted-foreground flex text-xs">
<p>{copyright}</p>
</div>
</div>
</div>
</div>
<div className="flex w-full flex-col space-y-8 lg:flex-row lg:justify-end lg:space-x-6 lg:space-y-0 xl:space-x-16">
<div className="flex w-full flex-col gap-y-4 lg:flex-row lg:justify-end lg:gap-x-6 lg:gap-y-0 xl:gap-x-12">
{sections.map((section, index) => (
<div key={index}>
<div className="flex flex-col space-y-2.5">
<div className="flex flex-col gap-y-2.5">
<FooterSectionHeading>{section.heading}</FooterSectionHeading>
<FooterSectionList>
@@ -71,11 +75,15 @@ export const Footer: React.FC<FooterProps> = ({
};
function FooterSectionHeading(props: React.PropsWithChildren) {
return <span className="font-heading">{props.children}</span>;
return (
<span className="font-heading text-sm font-semibold tracking-tight">
{props.children}
</span>
);
}
function FooterSectionList(props: React.PropsWithChildren) {
return <ul className="flex flex-col space-y-2.5">{props.children}</ul>;
return <ul className="flex flex-col gap-y-2">{props.children}</ul>;
}
function FooterLink({
@@ -83,7 +91,7 @@ function FooterLink({
children,
}: React.PropsWithChildren<{ href: string }>) {
return (
<li className="text-sm text-muted-foreground hover:underline [&>a]:transition-colors">
<li className="text-muted-foreground text-sm tracking-tight hover:underline [&>a]:transition-colors">
<a href={href}>{children}</a>
</li>
);

View File

@@ -12,7 +12,7 @@ export const GradientSecondaryText: React.FC<
return (
<Comp
className={cn(
'bg-gradient-to-r from-foreground/50 to-foreground bg-clip-text text-transparent',
'dark:from-foreground/60 dark:to-foreground text-secondary-foreground dark:bg-linear-to-r dark:bg-clip-text dark:text-transparent',
className,
)}
{...props}

View File

@@ -7,7 +7,7 @@ export const GradientText: React.FC<React.HTMLAttributes<HTMLSpanElement>> =
return (
<span
className={cn(
'bg-gradient-to-r bg-clip-text text-transparent',
'bg-linear-to-r bg-clip-text text-transparent',
className,
)}
{...props}

View File

@@ -16,7 +16,7 @@ export const Header: React.FC<HeaderProps> = function ({
return (
<div
className={cn(
'site-header sticky top-0 z-10 w-full bg-background/80 py-2 backdrop-blur-md dark:bg-background/50',
'site-header bg-background/80 dark:bg-background/50 sticky top-0 z-10 w-full py-1 backdrop-blur-md',
className,
)}
{...props}
@@ -25,9 +25,7 @@ export const Header: React.FC<HeaderProps> = function ({
<div className="grid h-14 grid-cols-3 items-center">
<div className={'mx-auto lg:mx-0'}>{logo}</div>
<div className="order-first md:order-none">{navigation}</div>
<div className="flex items-center justify-end space-x-1">
{actions}
</div>
<div className="flex items-center justify-end gap-x-2">{actions}</div>
</div>
</div>
</div>

View File

@@ -12,7 +12,7 @@ export const HeroTitle: React.FC<
return (
<Comp
className={cn(
'hero-title flex flex-col text-center font-sans text-4xl font-semibold tracking-tighter dark:text-white sm:text-6xl lg:max-w-5xl lg:text-7xl xl:text-[4.85rem]',
'hero-title flex flex-col text-center font-sans text-4xl font-semibold tracking-tighter sm:text-6xl lg:max-w-5xl lg:text-7xl xl:text-[4.5rem] dark:text-white',
className,
)}
{...props}

View File

@@ -29,17 +29,17 @@ export function Hero({
MozAnimationDuration: '100ms',
}}
className={cn(
'mx-auto flex flex-1 flex-col items-center justify-center duration-1000 md:flex-row',
'mx-auto flex flex-1 flex-col items-center justify-center duration-800 md:flex-row',
{
['animate-in fade-in zoom-in-90 slide-in-from-top-36']: animate,
['animate-in fade-in zoom-in-90 slide-in-from-top-24']: animate,
},
)}
>
<div className="flex w-full flex-1 flex-col items-center space-y-6 xl:space-y-8 2xl:space-y-10">
<div className="flex w-full flex-1 flex-col items-center gap-y-6 xl:gap-y-8 2xl:gap-y-12">
{pill && (
<div
className={cn({
['delay-300 duration-700 animate-in fade-in fill-mode-both']:
['animate-in fade-in fill-mode-both delay-300 duration-700']:
animate,
})}
>
@@ -47,12 +47,12 @@ export function Hero({
</div>
)}
<div className="flex flex-col items-center space-y-8">
<div className="flex flex-col items-center gap-y-6">
<HeroTitle>{title}</HeroTitle>
{subtitle && (
<div className="flex max-w-2xl flex-col space-y-1">
<h3 className="p-0 text-center font-sans text-xl font-normal tracking-tight text-muted-foreground">
<div className="flex max-w-lg">
<h3 className="text-muted-foreground p-0 text-center font-sans text-2xl font-normal tracking-tight">
{subtitle}
</h3>
</div>
@@ -62,7 +62,7 @@ export function Hero({
{cta && (
<div
className={cn({
['delay-500 duration-1000 animate-in fade-in fill-mode-both']:
['animate-in fade-in fill-mode-both delay-500 duration-1000']:
animate,
})}
>
@@ -78,7 +78,7 @@ export function Hero({
MozAnimationDuration: '100ms',
}}
className={cn('container mx-auto flex justify-center py-8', {
['delay-1000 duration-1000 animate-in fade-in zoom-in-95 slide-in-from-top-32 fill-mode-both']:
['animate-in fade-in zoom-in-90 slide-in-from-top-32 fill-mode-both delay-600 duration-1000']:
animate,
})}
>

View File

@@ -46,7 +46,7 @@ export function NewsletterSignup({
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSignup)}
className="flex flex-col space-y-2"
className="flex flex-col gap-y-3"
>
<FormField
control={form.control}

View File

@@ -1,6 +1,7 @@
import { Slot, Slottable } from '@radix-ui/react-slot';
import { cn } from '../../lib/utils';
import { GradientSecondaryText } from './gradient-secondary-text';
export const Pill: React.FC<
React.HTMLAttributes<HTMLHeadingElement> & {
@@ -13,7 +14,7 @@ export const Pill: React.FC<
return (
<Comp
className={cn(
'space-x-2.5 rounded-full border border-gray-100 px-2 py-2.5 text-center text-sm font-medium text-transparent dark:border-primary/10',
'bg-muted/50 flex items-center gap-x-1.5 rounded-full border px-2 py-1.5 pr-2 text-center text-sm font-medium text-transparent',
className,
)}
{...props}
@@ -21,15 +22,38 @@ export const Pill: React.FC<
{props.label && (
<span
className={
'rounded-2xl bg-primary px-2.5 py-1.5 text-sm font-semibold text-primary-foreground'
'text-primary-foreground bg-primary rounded-2xl border px-1.5 py-0.5 text-xs font-bold tracking-tight'
}
>
{props.label}
</span>
)}
<Slottable>
<span className={'text-secondary-foreground'}>{props.children}</span>
<GradientSecondaryText
className={'flex items-center gap-x-2 font-semibold tracking-tight'}
>
{props.children}
</GradientSecondaryText>
</Slottable>
</Comp>
);
};
export const PillActionButton: React.FC<
React.HTMLAttributes<HTMLButtonElement> & {
asChild?: boolean;
}
> = ({ asChild, ...props }) => {
const Comp = asChild ? Slot : 'button';
return (
<Comp
{...props}
className={
'text-secondary-foreground bg-input active:bg-primary active:text-primary-foreground hover:ring-muted-foreground/50 rounded-full px-1.5 py-1.5 text-center text-sm font-medium ring ring-transparent transition-colors'
}
>
{props.children}
</Comp>
);
};

View File

@@ -53,8 +53,8 @@ export function ModeToggle(props: { className?: string }) {
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="icon" className={props.className}>
<Sun className="h-[0.9rem] w-[0.9rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
<Moon className="absolute h-[0.9rem] w-[0.9rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
<Sun className="h-[0.9rem] w-[0.9rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" />
<Moon className="absolute h-[0.9rem] w-[0.9rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" />
<span className="sr-only">Toggle theme</span>
</Button>
</DropdownMenuTrigger>
@@ -99,7 +99,7 @@ export function SubMenuModeToggle() {
<DropdownMenuSub>
<DropdownMenuSubTrigger
className={
'hidden w-full items-center justify-between space-x-2 lg:flex'
'hidden w-full items-center justify-between gap-x-3 lg:flex'
}
>
<span className={'flex space-x-2'}>

View File

@@ -42,7 +42,7 @@ function PageWithSidebar(props: PageProps) {
<div
className={
'flex flex-1 flex-col overflow-y-auto bg-background px-4 lg:px-0'
'bg-background flex flex-1 flex-col overflow-y-auto px-4 lg:px-0'
}
>
{Children}
@@ -81,7 +81,7 @@ function PageWithHeader(props: PageProps) {
>
<div
className={cn(
'flex h-14 items-center justify-between bg-muted/40 px-4 dark:border-border dark:shadow-primary/10 lg:justify-start lg:shadow-sm',
'bg-muted/40 dark:border-border dark:shadow-primary/10 flex h-14 items-center justify-between px-4 lg:justify-start lg:shadow-xs',
{
'sticky top-0 z-10 backdrop-blur-md': props.sticky ?? true,
},
@@ -119,7 +119,7 @@ export function PageNavigation(props: React.PropsWithChildren) {
export function PageDescription(props: React.PropsWithChildren) {
return (
<div className={'h-6'}>
<div className={'text-xs font-normal leading-none text-muted-foreground'}>
<div className={'text-muted-foreground text-xs leading-none font-normal'}>
{props.children}
</div>
</div>
@@ -130,7 +130,7 @@ export function PageTitle(props: React.PropsWithChildren) {
return (
<h1
className={
'h-6 font-heading font-bold leading-none tracking-tight dark:text-white'
'font-heading text-xl leading-none font-bold tracking-tight dark:text-white'
}
>
{props.children}
@@ -155,7 +155,7 @@ export function PageHeader({
return (
<div
className={cn(
'flex items-center justify-between py-4 lg:px-4',
'flex items-center justify-between py-5 lg:px-4',
className,
)}
>

View File

@@ -144,7 +144,7 @@ export function SidebarGroup({
}
return (
<span className={'text-xs font-semibold uppercase text-muted-foreground'}>
<span className={'text-muted-foreground text-xs font-semibold uppercase'}>
{props.children}
</span>
);
@@ -189,7 +189,7 @@ export function SidebarGroup({
return (
<div
className={cn('flex flex-col', {
'space-y-1 py-1': !collapsed,
'gap-y-2 py-1': !collapsed,
})}
>
<Wrapper />
@@ -232,7 +232,7 @@ export function SidebarItem({
<Button
asChild
className={cn(
'flex w-full text-sm shadow-none active:bg-secondary/60',
'active:bg-secondary/60 flex w-full text-sm shadow-none',
{
'justify-start space-x-2.5': !collapsed,
'hover:bg-initial': active,
@@ -267,7 +267,7 @@ export function SidebarItem({
function getClassNameBuilder(className: string) {
return cva([
cn(
'group/sidebar transition-width fixed box-content flex h-screen w-2/12 flex-col bg-inherit backdrop-blur-sm duration-200',
'group/sidebar transition-width fixed box-content flex h-screen w-2/12 flex-col bg-inherit backdrop-blur-xs duration-200',
className,
),
]);

View File

@@ -75,7 +75,7 @@ export function Stepper(props: {
const containerClassName = cn('w-full', {
['flex justify-between']: variant === 'numbers',
['flex space-x-0.5']: variant === 'default',
['flex space-x-2.5 self-center']: variant === 'dots',
['flex gap-x-4 self-center']: variant === 'dots',
});
return (
@@ -92,7 +92,7 @@ function getClassNameBuilder() {
default: `flex h-[2.5px] w-full flex-col transition-all duration-500`,
numbers:
'flex h-9 w-9 items-center justify-center rounded-full border text-sm font-bold',
dots: 'h-2.5 w-2.5 rounded-full bg-muted transition-colors',
dots: 'bg-muted h-2.5 w-2.5 rounded-full transition-colors',
},
selected: {
true: '',
@@ -183,7 +183,7 @@ function StepDivider({
complete: boolean;
}>) {
const spanClassName = cn('min-w-max text-sm font-medium', {
['hidden text-muted-foreground sm:flex']: !selected,
['text-muted-foreground hidden sm:flex']: !selected,
['text-secondary-foreground']: selected || complete,
['font-medium']: selected,
});
@@ -200,7 +200,7 @@ function StepDivider({
<div
className={
'divider h-[1px] w-full bg-gray-200 transition-colors' +
' hidden group-last:hidden dark:bg-border sm:flex'
' dark:bg-border hidden group-last:hidden sm:flex'
}
/>
</div>

View File

@@ -18,7 +18,7 @@ const AlertDialogOverlay: React.FC<
> = ({ className, ...props }) => (
<AlertDialogPrimitive.Overlay
className={cn(
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',
className,
)}
{...props}
@@ -33,7 +33,7 @@ const AlertDialogContent: React.FC<
<AlertDialogOverlay />
<AlertDialogPrimitive.Content
className={cn(
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg',
className,
)}
{...props}
@@ -47,10 +47,7 @@ const AlertDialogHeader = ({
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
'flex flex-col space-y-2 text-center sm:text-left',
className,
)}
className={cn('flex flex-col gap-y-3 text-center sm:text-left', className)}
{...props}
/>
);
@@ -84,7 +81,7 @@ const AlertDialogDescription: React.FC<
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>
> = ({ className, ...props }) => (
<AlertDialogPrimitive.Description
className={cn('text-sm text-muted-foreground', className)}
className={cn('text-muted-foreground text-sm', className)}
{...props}
/>
);

View File

@@ -5,18 +5,18 @@ import { type VariantProps, cva } from 'class-variance-authority';
import { cn } from '../lib/utils';
const alertVariants = cva(
'relative w-full rounded-lg border bg-gradient-to-r px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7',
'[&>svg]:text-foreground relative flex w-full flex-col gap-y-2 rounded-lg border bg-linear-to-r px-4 py-3.5 text-sm [&>svg]:absolute [&>svg]:top-4 [&>svg]:left-4 [&>svg+div]:translate-y-[-3px] [&>svg~*]:pl-7',
{
variants: {
variant: {
default: 'bg-background text-foreground',
destructive:
'border-destructive/50 from-red-50 from-10% via-background to-background text-destructive dark:border-destructive dark:from-red-500/10 [&>svg]:text-destructive',
'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive',
success:
'border-green-600/50 from-green-50 from-10% via-background to-background text-green-600 dark:border-green-600 dark:from-green-500/10 [&>svg]:text-green-600',
'border-green-600/50 text-green-600 dark:border-green-600 [&>svg]:text-green-600',
warning:
'border-orange-600/50 from-orange-50 from-10% via-background to-background text-orange-600 dark:border-orange-600 dark:from-orange-500/10 [&>svg]:text-orange-600',
info: 'border-blue-600/50 from-blue-50 from-10% via-background to-background text-blue-600 dark:border-blue-600 dark:from-blue-500/10 [&>svg]:text-blue-600',
'border-orange-600/50 text-orange-600 dark:border-orange-600 [&>svg]:text-orange-600',
info: 'border-blue-600/50 text-blue-600 dark:border-blue-600 [&>svg]:text-blue-600',
},
},
defaultVariants: {
@@ -41,7 +41,7 @@ const AlertTitle: React.FC<React.HTMLAttributes<HTMLHeadingElement>> = ({
...props
}) => (
<h5
className={cn('mb-1 font-bold leading-none tracking-tight', className)}
className={cn('leading-none font-bold tracking-tight', className)}
{...props}
/>
);

View File

@@ -5,16 +5,16 @@ import { type VariantProps, cva } from 'class-variance-authority';
import { cn } from '../lib/utils';
const badgeVariants = cva(
'inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
'focus:ring-ring inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-hidden',
{
variants: {
variant: {
default:
'border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80',
'bg-primary text-primary-foreground hover:bg-primary/80 border-transparent shadow-xs',
secondary:
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
'bg-secondary text-secondary-foreground hover:bg-secondary/80 border-transparent',
destructive:
'border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80',
'bg-destructive text-destructive-foreground hover:bg-destructive/80 border-transparent shadow-xs',
outline: 'text-foreground',
success:
'border-transparent bg-green-50 text-green-500 hover:bg-green-50 dark:bg-green-500/20 dark:hover:bg-green-500/20',

View File

@@ -7,18 +7,18 @@ import type { VariantProps } from 'class-variance-authority';
import { cn } from '../lib/utils';
const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50',
'focus-visible:ring-ring inline-flex items-center justify-center rounded-md text-sm font-medium whitespace-nowrap transition-colors focus-visible:ring-1 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default:
'bg-primary text-primary-foreground shadow hover:bg-primary/90',
'bg-primary text-primary-foreground hover:bg-primary/90 shadow-xs',
destructive:
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
'bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-xs',
outline:
'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
'border-input bg-background hover:bg-accent hover:text-accent-foreground border shadow-xs',
secondary:
'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
'bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-xs',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'decoration-primary underline-offset-4 hover:underline',
},

View File

@@ -26,7 +26,7 @@ function Calendar({
month: 'space-y-4',
caption: 'flex justify-center pt-1 relative items-center',
caption_label: 'text-sm font-medium',
nav: 'space-x-1 flex items-center',
nav: 'gap-x-2 flex items-center',
nav_button: cn(
buttonVariants({ variant: 'outline' }),
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',

View File

@@ -52,7 +52,7 @@ const ChartContainer: React.FC<
<div
data-chart={chartId}
className={cn(
"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none",
"[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border flex aspect-video justify-center text-xs [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden",
className,
)}
{...props}
@@ -177,7 +177,7 @@ const ChartTooltipContent: React.FC<
<div
ref={ref}
className={cn(
'grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl',
'border-border/50 bg-background grid min-w-[8rem] items-start gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl',
className,
)}
>
@@ -192,7 +192,7 @@ const ChartTooltipContent: React.FC<
<div
key={item.dataKey}
className={cn(
'flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground',
'[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5',
indicator === 'dot' && 'items-center',
)}
>
@@ -206,7 +206,7 @@ const ChartTooltipContent: React.FC<
!hideIndicator && (
<div
className={cn(
'shrink-0 rounded-[2px] border-[--color-border] bg-[--color-bg]',
'shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)',
{
'h-2.5 w-2.5': indicator === 'dot',
'w-1': indicator === 'line',
@@ -237,7 +237,7 @@ const ChartTooltipContent: React.FC<
</span>
</div>
{item.value && (
<span className="font-mono font-medium tabular-nums text-foreground">
<span className="text-foreground font-mono font-medium tabular-nums">
{item.value.toLocaleString()}
</span>
)}
@@ -294,7 +294,7 @@ const ChartLegendContent: React.FC<
<div
key={item.value}
className={cn(
'flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground',
'[&>svg]:text-muted-foreground flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3',
)}
>
{itemConfig?.icon && !hideIcon ? (

View File

@@ -12,7 +12,7 @@ const Checkbox: React.FC<
> = ({ className, ...props }) => (
<CheckboxPrimitive.Root
className={cn(
'peer h-4 w-4 shrink-0 rounded-sm border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
'peer border-primary focus-visible:ring-ring data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground h-4 w-4 shrink-0 rounded-xs border shadow-xs focus-visible:ring-1 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...props}

View File

@@ -14,7 +14,7 @@ const Command: React.FC<
> = ({ className, ...props }) => (
<CommandPrimitive
className={cn(
'flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground',
'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-md',
className,
)}
{...props}
@@ -28,7 +28,7 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
return (
<Dialog {...props}>
<DialogContent className="overflow-hidden p-0">
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
<Command className="[&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
{children}
</Command>
</DialogContent>
@@ -44,7 +44,7 @@ const CommandInput: React.FC<
<MagnifyingGlassIcon className="mr-2 h-4 w-4 shrink-0 opacity-50" />
<CommandPrimitive.Input
className={cn(
'flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50',
'placeholder:text-muted-foreground flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...props}
@@ -58,7 +58,7 @@ const CommandList: React.FC<
React.ComponentPropsWithRef<typeof CommandPrimitive.List>
> = ({ className, ...props }) => (
<CommandPrimitive.List
className={cn('max-h-[300px] overflow-y-auto overflow-x-hidden', className)}
className={cn('max-h-[300px] overflow-x-hidden overflow-y-auto', className)}
{...props}
/>
);
@@ -78,7 +78,7 @@ const CommandGroup: React.FC<
> = ({ className, ...props }) => (
<CommandPrimitive.Group
className={cn(
'overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground',
'text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium',
className,
)}
{...props}
@@ -91,7 +91,7 @@ const CommandSeparator: React.FC<
React.ComponentPropsWithRef<typeof CommandPrimitive.Separator>
> = ({ className, ...props }) => (
<CommandPrimitive.Separator
className={cn('-mx-1 h-px bg-border', className)}
className={cn('bg-border -mx-1 h-px', className)}
{...props}
/>
);
@@ -102,7 +102,7 @@ const CommandItem: React.FC<
> = ({ className, ...props }) => (
<CommandPrimitive.Item
className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-[selected='true']:bg-accent aria-[selected='true']:text-accent-foreground data-[disabled='true']:pointer-events-none data-[disabled='true']:opacity-50",
"aria-selected:bg-accent aria-selected:text-accent-foreground relative flex cursor-default items-center rounded-xs px-2 py-1.5 text-sm outline-hidden select-none data-[disabled='true']:pointer-events-none data-[disabled='true']:opacity-50",
className,
)}
{...props}
@@ -118,7 +118,7 @@ const CommandShortcut = ({
return (
<span
className={cn(
'ml-auto text-xs tracking-widest text-muted-foreground',
'text-muted-foreground ml-auto text-xs tracking-widest',
className,
)}
{...props}

View File

@@ -20,7 +20,7 @@ const DialogOverlay: React.FC<
> = ({ className, ...props }) => (
<DialogPrimitive.Overlay
className={cn(
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',
className,
)}
{...props}
@@ -35,13 +35,13 @@ const DialogContent: React.FC<
<DialogOverlay />
<DialogPrimitive.Content
className={cn(
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border p-6 shadow-lg duration-200 sm:rounded-lg',
className,
)}
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<DialogPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
<Cross2Icon className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
@@ -83,7 +83,7 @@ const DialogTitle: React.FC<
> = ({ className, ...props }) => (
<DialogPrimitive.Title
className={cn(
'text-lg font-semibold leading-none tracking-tight',
'text-lg leading-none font-semibold tracking-tight',
className,
)}
{...props}
@@ -95,7 +95,7 @@ const DialogDescription: React.FC<
React.ComponentPropsWithRef<typeof DialogPrimitive.Description>
> = ({ className, ...props }) => (
<DialogPrimitive.Description
className={cn('text-sm text-muted-foreground', className)}
className={cn('text-muted-foreground text-sm', className)}
{...props}
/>
);

View File

@@ -30,7 +30,7 @@ const DropdownMenuSubTrigger: React.FC<
> = ({ className, inset, children, ...props }) => (
<DropdownMenuPrimitive.SubTrigger
className={cn(
'flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent',
'focus:bg-accent data-[state=open]:bg-accent flex cursor-default items-center rounded-xs px-2 py-1.5 text-sm outline-hidden select-none',
inset && 'pl-8',
className,
)}
@@ -48,7 +48,7 @@ const DropdownMenuSubContent: React.FC<
> = ({ className, ...props }) => (
<DropdownMenuPrimitive.SubContent
className={cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg',
className,
)}
{...props}
@@ -64,7 +64,7 @@ const DropdownMenuContent: React.FC<
<DropdownMenuPrimitive.Content
sideOffset={sideOffset}
className={cn(
'z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md',
'bg-popover text-popover-foreground z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-md',
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
className,
)}
@@ -81,7 +81,7 @@ const DropdownMenuItem: React.FC<
> = ({ className, inset, ...props }) => (
<DropdownMenuPrimitive.Item
className={cn(
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-xs px-2 py-1.5 text-sm outline-hidden transition-colors select-none data-disabled:pointer-events-none data-disabled:opacity-50',
inset && 'pl-8',
className,
)}
@@ -95,7 +95,7 @@ const DropdownMenuCheckboxItem: React.FC<
> = ({ className, children, checked, ...props }) => (
<DropdownMenuPrimitive.CheckboxItem
className={cn(
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden transition-colors select-none data-disabled:pointer-events-none data-disabled:opacity-50',
className,
)}
checked={checked}
@@ -117,7 +117,7 @@ const DropdownMenuRadioItem: React.FC<
> = ({ className, children, ...props }) => (
<DropdownMenuPrimitive.RadioItem
className={cn(
'relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center rounded-xs py-1.5 pr-2 pl-8 text-sm outline-hidden transition-colors select-none data-disabled:pointer-events-none data-disabled:opacity-50',
className,
)}
{...props}
@@ -152,7 +152,7 @@ const DropdownMenuSeparator: React.FC<
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
> = ({ className, ...props }) => (
<DropdownMenuPrimitive.Separator
className={cn('-mx-1 my-1 h-px bg-muted', className)}
className={cn('bg-muted -mx-1 my-1 h-px', className)}
{...props}
/>
);

View File

@@ -76,7 +76,7 @@ const FormItem: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({
return (
<FormItemContext.Provider value={{ id }}>
<div className={cn('space-y-2', className)} {...props} />
<div className={cn('flex flex-col gap-y-2', className)} {...props} />
</FormItemContext.Provider>
);
};
@@ -127,7 +127,7 @@ const FormDescription: React.FC<React.HTMLAttributes<HTMLParagraphElement>> = ({
return (
<p
id={formDescriptionId}
className={cn('text-[0.8rem] text-muted-foreground', className)}
className={cn('text-muted-foreground text-[0.8rem]', className)}
{...props}
/>
);
@@ -149,7 +149,7 @@ const FormMessage: React.FC<React.HTMLAttributes<HTMLParagraphElement>> = ({
return (
<p
id={formMessageId}
className={cn('text-[0.8rem] font-medium text-destructive', className)}
className={cn('text-destructive text-[0.8rem] font-medium', className)}
{...props}
>
{typeof body === 'string' ? (

View File

@@ -14,7 +14,7 @@ const InputOTP: React.FC<React.ComponentPropsWithoutRef<typeof OTPInput>> = ({
}) => (
<OTPInput
containerClassName={cn(
'flex items-center gap-2 has-[:disabled]:opacity-50',
'flex items-center gap-2 has-disabled:opacity-50',
containerClassName,
)}
className={cn('disabled:cursor-not-allowed', className)}
@@ -45,8 +45,8 @@ const InputOTPSlot: React.FC<
return (
<div
className={cn(
'relative flex h-9 w-9 items-center justify-center border-y border-r border-input text-sm shadow-sm transition-all first:rounded-l-md first:border-l last:rounded-r-md',
isActive && 'z-10 ring-1 ring-ring',
'border-input relative flex h-9 w-9 items-center justify-center border-y border-r text-sm shadow-xs transition-all first:rounded-l-md first:border-l last:rounded-r-md',
isActive && 'ring-ring z-10 ring-1',
className,
)}
{...props}
@@ -54,7 +54,7 @@ const InputOTPSlot: React.FC<
{char}
{hasFakeCaret && (
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
<div className="animate-caret-blink h-4 w-px bg-foreground duration-1000" />
<div className="animate-caret-blink bg-foreground h-4 w-px duration-1000" />
</div>
)}
</div>

View File

@@ -13,7 +13,7 @@ const Input: React.FC<InputProps> = ({
<input
type={type}
className={cn(
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
'border-input file:text-foreground hover:border-ring/50 placeholder:text-muted-foreground focus-visible:ring-ring flex h-9 w-full rounded-md border bg-transparent px-3 py-1 text-base shadow-2xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-1 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
className,
)}
{...props}

View File

@@ -40,7 +40,7 @@ NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
const NavigationMenuItem = NavigationMenuPrimitive.Item;
const navigationMenuTriggerStyle = cva(
'group inline-flex h-9 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[active]:bg-accent/50 data-[state=open]:bg-accent/50',
'group bg-background hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground data-active:bg-accent/50 data-[state=open]:bg-accent/50 inline-flex h-9 w-max items-center justify-center rounded-md px-4 py-2 text-sm font-medium transition-colors focus:outline-hidden disabled:pointer-events-none disabled:opacity-50',
);
const NavigationMenuTrigger: React.FC<
@@ -64,7 +64,7 @@ const NavigationMenuContent: React.FC<
> = ({ className, ...props }) => (
<NavigationMenuPrimitive.Content
className={cn(
'left-0 top-0 w-full data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 md:absolute md:w-auto',
'data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 top-0 left-0 w-full md:absolute md:w-auto',
className,
)}
{...props}
@@ -77,10 +77,10 @@ const NavigationMenuLink = NavigationMenuPrimitive.Link;
const NavigationMenuViewport: React.FC<
React.ComponentPropsWithoutRef<typeof NavigationMenuPrimitive.Viewport>
> = ({ className, ...props }) => (
<div className={cn('absolute left-0 top-full flex justify-center')}>
<div className={cn('absolute top-full left-0 flex justify-center')}>
<NavigationMenuPrimitive.Viewport
className={cn(
'origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border bg-popover text-popover-foreground shadow data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]',
'origin-top-center bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border shadow-xs md:w-[var(--radix-navigation-menu-viewport-width)]',
className,
)}
{...props}
@@ -95,12 +95,12 @@ const NavigationMenuIndicator: React.FC<
> = ({ className, ...props }) => (
<NavigationMenuPrimitive.Indicator
className={cn(
'top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in',
'data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-1 flex h-1.5 items-end justify-center overflow-hidden',
className,
)}
{...props}
>
<div className="relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm bg-border shadow-md" />
<div className="bg-border relative top-[60%] h-2 w-2 rotate-45 rounded-tl-sm shadow-md" />
</NavigationMenuPrimitive.Indicator>
);
NavigationMenuIndicator.displayName =

View File

@@ -20,7 +20,7 @@ const PopoverContent: React.FC<
align={align}
sideOffset={sideOffset}
className={cn(
'z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-hidden',
className,
)}
{...props}

View File

@@ -25,13 +25,13 @@ const RadioGroupItem: React.FC<
return (
<RadioGroupPrimitive.Item
className={cn(
'aspect-square h-4 w-4 rounded-full border border-primary text-primary shadow focus:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
'border-primary text-primary focus-visible:ring-ring aspect-square h-4 w-4 rounded-full border shadow-xs focus:outline-hidden focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...props}
>
<RadioGroupPrimitive.Indicator className="flex items-center justify-center">
<CheckIcon className="h-3.5 w-3.5 fill-primary" />
<CheckIcon className="fill-primary h-3.5 w-3.5" />
</RadioGroupPrimitive.Indicator>
</RadioGroupPrimitive.Item>
);
@@ -49,11 +49,11 @@ const RadioGroupItemLabel = (
className={cn(
props.className,
'flex cursor-pointer rounded-md' +
' items-center space-x-4 border border-input' +
' transition-duration-500 p-4 text-sm transition-all focus-within:border-primary',
' border-input items-center space-x-4 border' +
' transition-duration-500 focus-within:border-primary p-4 text-sm transition-all',
{
[`border-primary`]: props.selected,
[`hover:border-primary`]: !props.selected,
[`bg-muted`]: props.selected,
[`hover:bg-muted`]: !props.selected,
},
)}
>

View File

@@ -23,7 +23,7 @@ const SelectTrigger: React.FC<
> = ({ className, children, ...props }) => (
<SelectPrimitive.Trigger
className={cn(
'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
'border-input ring-offset-background placeholder:text-muted-foreground focus:ring-ring flex h-9 w-full items-center justify-between rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-2xs focus:ring-1 focus:outline-hidden disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
className,
)}
{...props}
@@ -73,7 +73,7 @@ const SelectContent: React.FC<
<SelectPrimitive.Portal>
<SelectPrimitive.Content
className={cn(
'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2',
'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border shadow-md',
position === 'popper' &&
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
className,
@@ -112,7 +112,7 @@ const SelectItem: React.FC<
> = ({ className, children, ...props }) => (
<SelectPrimitive.Item
className={cn(
'relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
'focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-default items-center rounded-xs py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50',
className,
)}
{...props}
@@ -131,7 +131,7 @@ const SelectSeparator: React.FC<
React.ComponentPropsWithRef<typeof SelectPrimitive.Separator>
> = ({ className, ...props }) => (
<SelectPrimitive.Separator
className={cn('-mx-1 my-1 h-px bg-muted', className)}
className={cn('bg-muted -mx-1 my-1 h-px', className)}
{...props}
/>
);

View File

@@ -21,7 +21,7 @@ const SheetOverlay: React.FC<
> = ({ className, ...props }) => (
<SheetPrimitive.Overlay
className={cn(
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80',
className,
)}
{...props}
@@ -30,16 +30,16 @@ const SheetOverlay: React.FC<
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName;
const sheetVariants = cva(
'fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out',
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 gap-4 p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
{
variants: {
side: {
top: 'inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top',
top: 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 border-b',
bottom:
'inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom',
left: 'inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm',
'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 border-t',
left: 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
right:
'inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm',
'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
},
},
defaultVariants: {
@@ -64,7 +64,7 @@ const SheetContent: React.FC<SheetContentProps> = ({
className={cn(sheetVariants({ side }), className)}
{...props}
>
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
<Cross2Icon className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
@@ -79,10 +79,7 @@ const SheetHeader = ({
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
'flex flex-col space-y-2 text-center sm:text-left',
className,
)}
className={cn('flex flex-col gap-y-3 text-center sm:text-left', className)}
{...props}
/>
);
@@ -106,7 +103,7 @@ const SheetTitle: React.FC<
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
> = ({ className, ...props }) => (
<SheetPrimitive.Title
className={cn('text-lg font-semibold text-foreground', className)}
className={cn('text-foreground text-lg font-semibold', className)}
{...props}
/>
);
@@ -116,7 +113,7 @@ const SheetDescription: React.FC<
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
> = ({ className, ...props }) => (
<SheetPrimitive.Description
className={cn('text-sm text-muted-foreground', className)}
className={cn('text-muted-foreground text-sm', className)}
{...props}
/>
);

View File

@@ -182,7 +182,7 @@ const SidebarProvider: React.FC<
}
data-minimized={minimized}
className={cn(
'group flex min-h-svh w-full text-sidebar-foreground has-[[data-variant=inset]]:bg-sidebar',
'group text-sidebar-foreground has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full',
className,
)}
ref={ref}
@@ -253,7 +253,7 @@ const Sidebar: React.FC<
return (
<div
className={cn(
'flex h-full w-[--sidebar-width] flex-col bg-sidebar text-sidebar-foreground',
'bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col',
className,
{
[SIDEBAR_MINIMIZED_WIDTH]: minimized,
@@ -274,7 +274,7 @@ const Sidebar: React.FC<
data-sidebar="sidebar"
data-mobile="true"
className={cn(
'w-[--sidebar-width] p-0 text-sidebar-foreground [&>button]:hidden',
'text-sidebar-foreground w-(--sidebar-width) p-0 [&>button]:hidden',
{
'bg-background': variant === 'ghost',
'bg-sidebar': variant !== 'ghost',
@@ -307,12 +307,12 @@ const Sidebar: React.FC<
{/* This is what handles the sidebar gap on desktop */}
<div
className={cn(
'relative w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear',
'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',
'group-data-[collapsible=offcanvas]:w-0',
'group-data-[side=right]:rotate-180',
variant === 'floating' || variant === 'inset'
? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]'
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon]',
? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'
: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
{
'h-svh': variant !== 'ghost',
},
@@ -320,14 +320,14 @@ const Sidebar: React.FC<
/>
<div
className={cn(
'fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex',
'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex',
side === 'left'
? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
// Adjust the padding for floating and inset variants.
variant === 'floating' || variant === 'inset'
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]'
: 'group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l',
? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',
className,
)}
{...props}
@@ -335,9 +335,9 @@ const Sidebar: React.FC<
<div
data-sidebar="sidebar"
className={cn(
'flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow',
'bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm',
{
'bg-background': variant === 'ghost',
'bg-transparent': variant === 'ghost',
},
)}
>
@@ -390,10 +390,10 @@ const SidebarRail: React.FC<React.ComponentProps<'button'>> = ({
onClick={toggleSidebar}
title="Toggle Sidebar"
className={cn(
'absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex',
'[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize',
'hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex',
'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',
'[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',
'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar',
'hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full',
'[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',
'[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',
className,
@@ -411,8 +411,8 @@ const SidebarInset: React.FC<React.ComponentProps<'main'>> = ({
return (
<main
className={cn(
'relative flex min-h-svh flex-1 flex-col bg-background',
'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',
'bg-background relative flex min-h-svh flex-1 flex-col',
'peer-data-[variant=inset]:min-h-[calc(100svh-(--spacing(4)))] md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2',
className,
)}
{...props}
@@ -429,7 +429,7 @@ const SidebarInput: React.FC<React.ComponentPropsWithRef<typeof Input>> = ({
<Input
data-sidebar="input"
className={cn(
'h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring',
'bg-background focus-visible:ring-sidebar-ring h-8 w-full shadow-none focus-visible:ring-2',
className,
)}
{...props}
@@ -473,7 +473,7 @@ const SidebarSeparator: React.FC<React.ComponentProps<typeof Separator>> = ({
return (
<Separator
data-sidebar="separator"
className={cn('mx-2 w-auto bg-sidebar-border', className)}
className={cn('bg-sidebar-border mx-2 w-auto', className)}
{...props}
/>
);
@@ -520,7 +520,7 @@ const SidebarGroupLabel: React.FC<
<Comp
data-sidebar="group-label"
className={cn(
'flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-muted-foreground outline-none ring-sidebar-ring transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
'text-muted-foreground ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opa] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
className,
)}
@@ -539,9 +539,9 @@ const SidebarGroupAction: React.FC<
<Comp
data-sidebar="group-action"
className={cn(
'absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
// Increases the hit area of the button on mobile.
'after:absolute after:-inset-2 after:md:hidden',
'after:absolute after:-inset-2 md:after:hidden',
'group-data-[collapsible=icon]:hidden',
className,
)}
@@ -588,18 +588,18 @@ const SidebarMenuItem: React.FC<React.ComponentProps<'li'>> = ({
SidebarMenuItem.displayName = 'SidebarMenuItem';
const sidebarMenuButtonVariants = cva(
'peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus:ring-primary focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
'peer/menu-button ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus:ring-primary active:bg-sidebar-accent active:text-sidebar-accent-foreground data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:font-medium [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
{
variants: {
variant: {
default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
outline:
'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
'bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
},
size: {
default: 'h-8 text-sm',
sm: 'h-7 text-xs',
lg: 'h-12 text-sm group-data-[collapsible=icon]:!p-0',
lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
},
},
defaultVariants: {
@@ -677,15 +677,15 @@ const SidebarMenuAction: React.FC<
<Comp
data-sidebar="menu-action"
className={cn(
'absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0',
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',
// Increases the hit area of the button on mobile.
'after:absolute after:-inset-2 after:md:hidden',
'after:absolute after:-inset-2 md:after:hidden',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
'peer-data-[size=lg]/menu-button:top-2.5',
'group-data-[collapsible=icon]:hidden',
showOnHover &&
'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0',
'peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0',
className,
)}
{...props}
@@ -701,7 +701,7 @@ const SidebarMenuBadge: React.FC<React.ComponentProps<'div'>> = ({
<div
data-sidebar="menu-badge"
className={cn(
'pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground',
'text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none',
'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
'peer-data-[size=sm]/menu-button:top-1',
'peer-data-[size=default]/menu-button:top-1.5',
@@ -737,7 +737,7 @@ const SidebarMenuSkeleton: React.FC<
/>
)}
<Skeleton
className="h-4 max-w-[--skeleton-width] flex-1"
className="h-4 max-w-(--skeleton-width) flex-1"
data-sidebar="menu-skeleton-text"
style={
{
@@ -757,7 +757,7 @@ const SidebarMenuSub: React.FC<React.ComponentProps<'ul'>> = ({
<ul
data-sidebar="menu-sub"
className={cn(
'mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5',
'border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5',
'group-data-[collapsible=icon]:hidden',
className,
)}
@@ -787,7 +787,7 @@ const SidebarMenuSubButton: React.FC<
data-size={size}
data-active={isActive}
className={cn(
'flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground',
'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',
'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
size === 'sm' && 'text-xs',
size === 'md' && 'text-sm',
@@ -966,7 +966,7 @@ export function SidebarNavigation({
>
<Link
className={cn('flex items-center', {
'mx-auto w-full !gap-0 [&>svg]:flex-1':
'mx-auto w-full gap-0! [&>svg]:flex-1':
minimized,
})}
href={path}
@@ -1030,7 +1030,7 @@ export function SidebarNavigation({
className={cn(
'flex items-center',
{
'mx-auto w-full !gap-0 [&>svg]:flex-1':
'mx-auto w-full gap-0! [&>svg]:flex-1':
minimized,
},
)}

View File

@@ -11,14 +11,14 @@ const Switch: React.FC<
> = ({ className, ...props }) => (
<SwitchPrimitives.Root
className={cn(
'peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input',
'peer focus-visible:ring-ring focus-visible:ring-offset-background data-[state=checked]:bg-primary data-[state=unchecked]:bg-input inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-xs transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...props}
>
<SwitchPrimitives.Thumb
className={cn(
'pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0',
'bg-background pointer-events-none block h-4 w-4 rounded-full ring-0 shadow-lg transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0',
)}
/>
</SwitchPrimitives.Root>

View File

@@ -35,7 +35,7 @@ const TableFooter: React.FC<React.HTMLAttributes<HTMLTableSectionElement>> = ({
}) => (
<tfoot
className={cn(
'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
'bg-muted/50 border-t font-medium last:[&>tr]:border-b-0',
className,
)}
{...props}
@@ -49,7 +49,7 @@ const TableRow: React.FC<React.HTMLAttributes<HTMLTableRowElement>> = ({
}) => (
<tr
className={cn(
'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors',
className,
)}
{...props}
@@ -63,7 +63,7 @@ const TableHead: React.FC<React.ThHTMLAttributes<HTMLTableCellElement>> = ({
}) => (
<th
className={cn(
'h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
'text-muted-foreground h-10 px-2 text-left align-middle font-medium [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
className,
)}
{...props}
@@ -90,7 +90,7 @@ const TableCaption: React.FC<React.HTMLAttributes<HTMLTableCaptionElement>> = ({
...props
}) => (
<caption
className={cn('mt-4 text-sm text-muted-foreground', className)}
className={cn('text-muted-foreground mt-4 text-sm', className)}
{...props}
/>
);

View File

@@ -13,7 +13,7 @@ const TabsList: React.FC<
> = ({ className, ...props }) => (
<TabsPrimitive.List
className={cn(
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground',
'bg-muted text-muted-foreground inline-flex h-10 items-center justify-center rounded-md p-1',
className,
)}
{...props}
@@ -26,7 +26,7 @@ const TabsTrigger: React.FC<
> = ({ className, ...props }) => (
<TabsPrimitive.Trigger
className={cn(
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',
'ring-offset-background focus-visible:ring-ring data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex items-center justify-center rounded-xs px-3 py-1.5 text-sm font-medium whitespace-nowrap transition-all focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-xs',
className,
)}
{...props}
@@ -39,7 +39,7 @@ const TabsContent: React.FC<
> = ({ className, ...props }) => (
<TabsPrimitive.Content
className={cn(
'mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
'ring-offset-background focus-visible:ring-ring mt-2 focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-hidden',
className,
)}
{...props}

View File

@@ -8,7 +8,7 @@ const Textarea: React.FC<TextareaProps> = ({ className, ...props }) => {
return (
<textarea
className={cn(
'flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
'border-input placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[60px] w-full rounded-md border bg-transparent px-3 py-2 text-sm shadow-xs focus-visible:ring-1 focus-visible:outline-hidden disabled:cursor-not-allowed disabled:opacity-50',
className,
)}
{...props}

View File

@@ -1,12 +0,0 @@
/*
* This file is not used for any compilation purpose, it is only used
* for Tailwind Intellisense & Autocompletion in the source files
*/
import type { Config } from 'tailwindcss';
import baseConfig from '@kit/tailwind-config';
export default {
content: baseConfig.content,
presets: [baseConfig],
} satisfies Config;