diff --git a/components.json b/components.json index 33c68fa0..1582dcee 100644 --- a/components.json +++ b/components.json @@ -1,6 +1,6 @@ { "$schema": "https://ui.shadcn.com/schema.json", - "style": "radix-lyra", + "style": "radix-mira", "rsc": false, "tsx": true, "tailwind": { @@ -11,6 +11,7 @@ "prefix": "" }, "iconLibrary": "lucide", + "rtl": false, "aliases": { "components": "@/components", "utils": "@/lib/utils", diff --git a/src/client/src/components/ui/accordion.tsx b/src/client/src/components/ui/accordion.tsx index fee9510d..2689c9bd 100644 --- a/src/client/src/components/ui/accordion.tsx +++ b/src/client/src/components/ui/accordion.tsx @@ -11,7 +11,10 @@ function Accordion({ return ( ); @@ -24,7 +27,7 @@ function AccordionItem({ return ( ); @@ -40,7 +43,7 @@ function AccordionTrigger({
diff --git a/src/client/src/components/ui/alert.tsx b/src/client/src/components/ui/alert.tsx index fa2749ce..0a53564c 100644 --- a/src/client/src/components/ui/alert.tsx +++ b/src/client/src/components/ui/alert.tsx @@ -4,7 +4,7 @@ import { cva, type VariantProps } from 'class-variance-authority'; import { cn } from '@/lib/utils'; const alertVariants = cva( - "group/alert relative grid w-full gap-0.5 rounded-none border px-2.5 py-2 text-left text-xs has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4", + "group/alert relative grid w-full gap-0.5 rounded-lg border px-2 py-1.5 text-left text-xs/relaxed has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-1.5 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-3.5", { variants: { variant: { @@ -55,7 +55,7 @@ function AlertDescription({
) { return (
); diff --git a/src/client/src/components/ui/badge.tsx b/src/client/src/components/ui/badge.tsx index 4f2dc5e5..813de1c6 100644 --- a/src/client/src/components/ui/badge.tsx +++ b/src/client/src/components/ui/badge.tsx @@ -5,7 +5,7 @@ import { Slot } from 'radix-ui'; import { cn } from '@/lib/utils'; const badgeVariants = cva( - 'group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-none border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!', + 'group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-[0.625rem] font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-2.5!', { variants: { variant: { @@ -15,7 +15,7 @@ const badgeVariants = cva( destructive: 'bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20', outline: - 'border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground', + 'border-border bg-input/20 text-foreground dark:bg-input/30 [a]:hover:bg-muted [a]:hover:text-muted-foreground', ghost: 'hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50', link: 'text-primary underline-offset-4 hover:underline', diff --git a/src/client/src/components/ui/button.tsx b/src/client/src/components/ui/button.tsx index 2a6e473e..3097c0d7 100644 --- a/src/client/src/components/ui/button.tsx +++ b/src/client/src/components/ui/button.tsx @@ -5,13 +5,13 @@ import { Slot } from 'radix-ui'; import { cn } from '@/lib/utils'; const buttonVariants = cva( - "group/button inline-flex shrink-0 items-center justify-center rounded-none border border-transparent bg-clip-padding text-xs font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-1 focus-visible:ring-ring/50 active:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-1 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-xs/relaxed font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", { variants: { variant: { - default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80', + default: 'bg-primary text-primary-foreground hover:bg-primary/80', outline: - 'border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50', + 'border-border hover:bg-input/50 hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:bg-input/30', secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground', ghost: @@ -22,14 +22,14 @@ const buttonVariants = cva( }, size: { default: - 'h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2', - xs: "h-6 gap-1 rounded-none px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", - sm: "h-7 gap-1 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", - lg: 'h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3', - icon: 'size-8', - 'icon-xs': "size-6 rounded-none [&_svg:not([class*='size-'])]:size-3", - 'icon-sm': 'size-7 rounded-none', - 'icon-lg': 'size-9', + "h-7 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", + xs: "h-5 gap-1 rounded-sm px-2 text-[0.625rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-2.5", + sm: "h-6 gap-1 px-2 text-xs/relaxed has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", + lg: "h-8 gap-1 px-2.5 text-xs/relaxed has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2 [&_svg:not([class*='size-'])]:size-4", + icon: "size-7 [&_svg:not([class*='size-'])]:size-3.5", + 'icon-xs': "size-5 rounded-sm [&_svg:not([class*='size-'])]:size-2.5", + 'icon-sm': "size-6 [&_svg:not([class*='size-'])]:size-3", + 'icon-lg': "size-8 [&_svg:not([class*='size-'])]:size-4", }, }, defaultVariants: { @@ -39,38 +39,27 @@ const buttonVariants = cva( } ); -const Button = React.forwardRef< - HTMLButtonElement, - React.ComponentProps<'button'> & - VariantProps & { - asChild?: boolean; - } ->( - ( - { - className, - variant = 'default', - size = 'default', - asChild = false, - ...props - }, - ref - ) => { - const Comp = asChild ? Slot.Root : 'button'; +function Button({ + className, + variant = 'default', + size = 'default', + asChild = false, + ...props +}: React.ComponentProps<'button'> & + VariantProps & { + asChild?: boolean; + }) { + const Comp = asChild ? Slot.Root : 'button'; - return ( - - ); - } -); - -Button.displayName = 'Button'; + return ( + + ); +} export { Button, buttonVariants }; diff --git a/src/client/src/components/ui/card.tsx b/src/client/src/components/ui/card.tsx index fe034cd2..fd638715 100644 --- a/src/client/src/components/ui/card.tsx +++ b/src/client/src/components/ui/card.tsx @@ -2,32 +2,30 @@ import * as React from 'react'; import { cn } from '@/lib/utils'; -const Card = React.forwardRef< - HTMLDivElement, - React.ComponentProps<'div'> & { size?: 'default' | 'sm' } ->(({ className, size = 'default', ...props }, ref) => { +function Card({ + className, + size = 'default', + ...props +}: React.ComponentProps<'div'> & { size?: 'default' | 'sm' }) { return (
img:first-child]:pt-0 data-[size=sm]:gap-2 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none', + 'group/card flex flex-col gap-4 overflow-hidden rounded-lg bg-card py-4 text-xs/relaxed text-card-foreground ring-1 ring-foreground/10 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 *:[img:first-child]:rounded-t-lg *:[img:last-child]:rounded-b-lg', className )} {...props} /> ); -}); - -Card.displayName = 'Card'; +} function CardHeader({ className, ...props }: React.ComponentProps<'div'>) { return (
) { return (
); @@ -86,7 +81,7 @@ function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
) { return (
); @@ -128,7 +128,7 @@ function DialogTitle({ return ( ); diff --git a/src/client/src/components/ui/dropdown-menu.tsx b/src/client/src/components/ui/dropdown-menu.tsx index 55ded470..00f0ae19 100644 --- a/src/client/src/components/ui/dropdown-menu.tsx +++ b/src/client/src/components/ui/dropdown-menu.tsx @@ -42,7 +42,7 @@ function DropdownMenuContent({ sideOffset={sideOffset} align={align} className={cn( - 'z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-none bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95', + 'z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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 data-[state=closed]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95', className )} {...props} @@ -74,7 +74,7 @@ function DropdownMenuItem({ data-inset={inset} data-variant={variant} className={cn( - "group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-none px-2 py-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive", + "group/dropdown-menu-item relative flex min-h-7 cursor-default items-center gap-2 rounded-md px-2 py-1 text-xs/relaxed outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7.5 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 data-[variant=destructive]:*:[svg]:text-destructive", className )} {...props} @@ -96,7 +96,7 @@ function DropdownMenuCheckboxItem({ data-slot="dropdown-menu-checkbox-item" data-inset={inset} className={cn( - "relative flex cursor-default items-center gap-2 rounded-none py-2 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5", className )} checked={checked} @@ -139,7 +139,7 @@ function DropdownMenuRadioItem({ data-slot="dropdown-menu-radio-item" data-inset={inset} className={cn( - "relative flex cursor-default items-center gap-2 rounded-none py-2 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + "relative flex min-h-7 cursor-default items-center gap-2 rounded-md py-1.5 pr-8 pl-2 text-xs outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7.5 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5", className )} {...props} @@ -169,7 +169,7 @@ function DropdownMenuLabel({ data-slot="dropdown-menu-label" data-inset={inset} className={cn( - 'px-2 py-2 text-xs text-muted-foreground data-inset:pl-7', + 'px-2 py-1.5 text-xs text-muted-foreground data-inset:pl-7.5', className )} {...props} @@ -184,7 +184,7 @@ function DropdownMenuSeparator({ return ( ); @@ -198,7 +198,7 @@ function DropdownMenuShortcut({ ) { data-slot="input-group" role="group" className={cn( - 'group/input-group relative flex h-8 w-full min-w-0 items-center rounded-none border border-input transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-1 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-1 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-disabled:bg-input/80 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5', + 'group/input-group relative flex h-7 w-full min-w-0 items-center rounded-md border border-input bg-input/20 transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-data-[align=block-end]:rounded-md has-data-[align=block-start]:rounded-md has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-2 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/30 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-2 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[textarea]:rounded-md has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5', className )} {...props} @@ -21,18 +21,18 @@ function InputGroup({ className, ...props }: React.ComponentProps<'div'>) { } const inputGroupAddonVariants = cva( - "flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-xs font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-none [&>svg:not([class*='size-'])]:size-4", + "flex h-auto cursor-text items-center justify-center gap-1 py-2 text-xs/relaxed font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 **:data-[slot=kbd]:rounded-[calc(var(--radius-sm)-2px)] **:data-[slot=kbd]:bg-muted-foreground/10 **:data-[slot=kbd]:px-1 **:data-[slot=kbd]:text-[0.625rem] [&>svg:not([class*='size-'])]:size-3.5", { variants: { align: { 'inline-start': - 'order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]', + 'order-first pl-2 has-[>button]:ml-[-0.275rem] has-[>kbd]:ml-[-0.275rem]', 'inline-end': - 'order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]', + 'order-last pr-2 has-[>button]:mr-[-0.275rem] has-[>kbd]:mr-[-0.275rem]', 'block-start': - 'order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2', + 'order-first w-full justify-start px-2 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2', 'block-end': - 'order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2', + 'order-last w-full justify-start px-2 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2', }, }, defaultVariants: { @@ -64,13 +64,13 @@ function InputGroupAddon({ } const inputGroupButtonVariants = cva( - 'flex items-center gap-2 text-xs shadow-none', + 'flex items-center gap-2 rounded-md text-xs/relaxed shadow-none', { variants: { size: { - xs: "h-6 gap-1 rounded-none px-1.5 [&>svg:not([class*='size-'])]:size-3.5", + xs: "h-5 gap-1 rounded-[calc(var(--radius-sm)-2px)] px-1 [&>svg:not([class*='size-'])]:size-3", sm: 'gap-1', - 'icon-xs': 'size-6 rounded-none p-0 has-[>svg]:p-0', + 'icon-xs': 'size-6 p-0 has-[>svg]:p-0', 'icon-sm': 'size-7 p-0 has-[>svg]:p-0', }, }, @@ -103,7 +103,7 @@ function InputGroupText({ className, ...props }: React.ComponentProps<'span'>) { return ( >( - ({ className, type, ...props }, ref) => { - return ( - - ); - } -); - -Input.displayName = 'Input'; +function Input({ className, type, ...props }: React.ComponentProps<'input'>) { + return ( + + ); +} export { Input }; diff --git a/src/client/src/components/ui/native-select.tsx b/src/client/src/components/ui/native-select.tsx index 4d9ce411..6d182ab7 100644 --- a/src/client/src/components/ui/native-select.tsx +++ b/src/client/src/components/ui/native-select.tsx @@ -24,11 +24,11 @@ function NativeSelect({