mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-27 04:07:05 +00:00
refactor: replace shadcn color vocabulary with semantic tokens
Remove the shadcn/ui color tokens (background, foreground, card, popover, muted, accent, secondary, destructive, input) and migrate every usage to LibreChat semantic surface/text/border tokens. Add surface-inverted/text-inverted for the neutral inverted CTA and surface-fixed/text-fixed for controls that must not flip with the theme (favicon chips, QR container, carousel arrows). New tokens are defined once in style.css (light + dark), createTailwindColors, the theme types, applyTheme and the default/dark theme objects so they stay overridable at runtime. Collapse paired dark: color variants into the dark-aware tokens and tokenize the remaining raw palette and white/black utilities, mapping status colors to the status-* tokens and legacy ring-black/ring-white focus rings to ring-text-primary. Retain the background, primary and ring tokens, which are still referenced by the SidePanel/Agents and SidePanel/Builder panels (excluded from this pass).
This commit is contained in:
parent
6a666aeabd
commit
fefaa45b70
141 changed files with 379 additions and 455 deletions
|
|
@ -36,7 +36,7 @@ const AccordionTrigger: React.ForwardRefExoticComponent<
|
|||
{...props}
|
||||
>
|
||||
{children}
|
||||
<ChevronDownIcon className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />
|
||||
<ChevronDownIcon className="h-4 w-4 shrink-0 text-text-secondary transition-transform duration-200" />
|
||||
</AccordionPrimitive.Trigger>
|
||||
</AccordionPrimitive.Header>
|
||||
));
|
||||
|
|
|
|||
|
|
@ -47,8 +47,7 @@ const AlertDialogContent: React.ForwardRefExoticComponent<
|
|||
<AlertDialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'fixed z-50 grid w-full max-w-lg scale-100 gap-4 bg-white p-6 opacity-100 animate-in fade-in-90 slide-in-from-bottom-10 sm:rounded-lg sm:zoom-in-90 sm:slide-in-from-bottom-0 md:w-full',
|
||||
'dark:bg-gray-900',
|
||||
'fixed z-50 grid w-full max-w-lg scale-100 gap-4 bg-surface-dialog p-6 opacity-100 animate-in fade-in-90 slide-in-from-bottom-10 sm:rounded-lg sm:zoom-in-90 sm:slide-in-from-bottom-0 md:w-full',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -88,7 +87,7 @@ const AlertDialogTitle: React.ForwardRefExoticComponent<
|
|||
>(({ className = '', ...props }, ref) => (
|
||||
<AlertDialogPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn('text-lg font-semibold text-gray-900', 'dark:text-gray-50', className)}
|
||||
className={cn('text-lg font-semibold text-text-primary', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
@ -106,7 +105,7 @@ const AlertDialogDescription: React.ForwardRefExoticComponent<
|
|||
>(({ className = '', ...props }, ref) => (
|
||||
<AlertDialogPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn('text-sm text-gray-500', 'dark:text-gray-400', className)}
|
||||
className={cn('text-sm text-text-secondary', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
@ -125,7 +124,7 @@ const AlertDialogAction: React.ForwardRefExoticComponent<
|
|||
<AlertDialogPrimitive.Action
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'inline-flex h-10 items-center justify-center rounded-md bg-gray-900 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-100 dark:text-gray-900 dark:hover:bg-gray-100 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900',
|
||||
'inline-flex h-10 items-center justify-center rounded-md bg-surface-inverted px-4 py-2 text-sm font-semibold text-text-inverted transition-colors hover:bg-surface-inverted-hover focus:outline-none focus:ring-2 focus:ring-text-primary focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -146,7 +145,7 @@ const AlertDialogCancel: React.ForwardRefExoticComponent<
|
|||
<AlertDialogPrimitive.Cancel
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'mt-2 inline-flex h-10 items-center justify-center rounded-md border border-gray-200 bg-transparent px-4 py-2 text-sm font-semibold text-gray-900 transition-colors hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:text-gray-100 dark:hover:bg-gray-800 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900 sm:mt-0',
|
||||
'mt-2 inline-flex h-10 items-center justify-center rounded-md border border-border-light bg-transparent px-4 py-2 text-sm font-semibold text-text-primary transition-colors hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-text-primary focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 sm:mt-0',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ const AnimatedSearchInput = ({
|
|||
<Search
|
||||
className={cn(
|
||||
`h-4 w-4 transition-all duration-500 ease-in-out`,
|
||||
isSearching && hasValue ? 'text-blue-400' : 'text-gray-500',
|
||||
isSearching && hasValue ? 'text-blue-400' : 'text-text-secondary',
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -40,7 +40,7 @@ const AnimatedSearchInput = ({
|
|||
onChange={onChange}
|
||||
placeholder={placeholder}
|
||||
aria-label={localize('com_ui_search')}
|
||||
className={`peer relative z-20 w-full rounded-lg bg-surface-secondary py-2 pl-10 outline-none backdrop-blur-sm transition-all duration-500 ease-in-out placeholder:text-gray-500 focus:ring-ring`}
|
||||
className={`peer relative z-20 w-full rounded-lg bg-surface-secondary py-2 pl-10 outline-none backdrop-blur-sm transition-all duration-500 ease-in-out placeholder:text-text-secondary focus:ring-text-primary`}
|
||||
/>
|
||||
|
||||
{/* Gradient overlay */}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const BreadcrumbList: React.ForwardRefExoticComponent<
|
|||
<ol
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5',
|
||||
'flex flex-wrap items-center gap-1.5 break-words text-sm text-text-secondary sm:gap-2.5',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -61,7 +61,7 @@ const BreadcrumbLink: React.ForwardRefExoticComponent<
|
|||
return (
|
||||
<Comp
|
||||
ref={ref}
|
||||
className={cn('transition-colors hover:text-foreground', className)}
|
||||
className={cn('transition-colors hover:text-text-primary', className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
|
@ -78,7 +78,7 @@ const BreadcrumbPage: React.ForwardRefExoticComponent<
|
|||
role="link"
|
||||
aria-disabled="true"
|
||||
aria-current="page"
|
||||
className={cn('font-normal text-foreground', className)}
|
||||
className={cn('font-normal text-text-primary', className)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
|
|
|
|||
|
|
@ -21,18 +21,17 @@ const buttonVariants: (
|
|||
} & ClassProp)
|
||||
| undefined,
|
||||
) => string = cva(
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium ring-offset-surface-primary transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
||||
destructive:
|
||||
'bg-surface-destructive text-destructive-foreground hover:bg-surface-destructive-hover',
|
||||
default: 'bg-surface-inverted text-text-inverted hover:bg-surface-inverted-hover',
|
||||
destructive: 'bg-surface-destructive text-white hover:bg-surface-destructive-hover',
|
||||
outline:
|
||||
'text-text-primary border border-border-light bg-transparent hover:bg-accent hover:text-accent-foreground',
|
||||
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
||||
ghost: 'hover:bg-surface-hover hover:text-accent-foreground',
|
||||
link: 'text-primary underline-offset-4 hover:underline',
|
||||
'text-text-primary border border-border-light bg-transparent hover:bg-surface-hover hover:text-text-primary',
|
||||
secondary: 'bg-surface-secondary text-text-primary hover:bg-surface-hover',
|
||||
ghost: 'hover:bg-surface-hover hover:text-text-primary',
|
||||
link: 'text-text-primary underline-offset-4 hover:underline',
|
||||
// hardcoded text color because of WCAG contrast issues (text-white)
|
||||
submit: 'bg-surface-submit text-white hover:bg-surface-submit-hover',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const Checkbox: React.ForwardRefExoticComponent<
|
|||
<CheckboxPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'peer h-4 w-4 shrink-0 rounded-sm border border-border-xheavy ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',
|
||||
'peer h-4 w-4 shrink-0 rounded-sm border border-border-xheavy ring-offset-surface-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-surface-inverted data-[state=checked]:text-text-inverted',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ export default function ComboboxComponent({
|
|||
isCollapsed
|
||||
? 'flex h-9 w-9 shrink-0 items-center justify-center p-0 [&>span]:w-auto [&>svg]:hidden'
|
||||
: '',
|
||||
'bg-white text-black hover:bg-gray-50 focus-visible:ring-2 focus-visible:ring-gray-500 dark:bg-gray-850 dark:text-white',
|
||||
'bg-surface-secondary text-text-primary hover:bg-surface-hover focus-visible:ring-2 focus-visible:ring-text-primary',
|
||||
)}
|
||||
>
|
||||
<SelectValue placeholder={selectPlaceholder}>
|
||||
|
|
@ -105,18 +105,18 @@ export default function ComboboxComponent({
|
|||
aria-label={ariaLabel + 's'}
|
||||
position="popper"
|
||||
className={cn(
|
||||
'bg-popover text-popover-foreground relative z-40 max-h-[52vh] min-w-[8rem] overflow-hidden rounded-md border border-gray-200 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 dark:border-gray-600',
|
||||
'relative z-40 max-h-[52vh] min-w-[8rem] overflow-hidden rounded-md border border-border-light bg-surface-secondary text-text-primary 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',
|
||||
'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1',
|
||||
'bg-white dark:bg-gray-700',
|
||||
'bg-surface-secondary',
|
||||
)}
|
||||
>
|
||||
<RadixSelect.Viewport className="mb-5 h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]">
|
||||
<div className="group sticky left-0 top-0 z-10 flex h-12 items-center gap-2 bg-white px-3 py-2 text-black duration-300 dark:bg-gray-700 dark:text-white">
|
||||
<SearchIcon className="h-4 w-4 text-gray-500 transition-colors duration-300 dark:group-focus-within:text-gray-300 dark:group-hover:text-gray-300" />
|
||||
<div className="group sticky left-0 top-0 z-10 flex h-12 items-center gap-2 bg-surface-secondary px-3 py-2 text-text-primary duration-300">
|
||||
<SearchIcon className="h-4 w-4 text-text-secondary transition-colors duration-300 group-focus-within:text-text-primary group-hover:text-text-primary" />
|
||||
<Combobox
|
||||
autoSelect
|
||||
placeholder={searchPlaceholder}
|
||||
className="flex-1 rounded-md border-none bg-transparent px-2.5 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-gray-700/10 dark:focus:ring-gray-200/10"
|
||||
className="flex-1 rounded-md border-none bg-transparent px-2.5 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-border-medium"
|
||||
// Ariakit's Combobox manually triggers a blur event on virtually
|
||||
// blurred items, making them work as if they had actual DOM
|
||||
// focus. These blur events might happen after the corresponding
|
||||
|
|
@ -133,7 +133,7 @@ export default function ComboboxComponent({
|
|||
/>
|
||||
<ComboboxCancel
|
||||
hideWhenEmpty={true}
|
||||
className="relative flex h-5 w-5 items-center justify-end text-gray-500 transition-colors duration-300 dark:group-focus-within:text-gray-300 dark:group-hover:text-gray-300"
|
||||
className="relative flex h-5 w-5 items-center justify-end text-text-secondary transition-colors duration-300 group-focus-within:text-text-primary group-hover:text-text-primary"
|
||||
/>
|
||||
</div>
|
||||
<ComboboxList className="overflow-y-auto p-1 py-2">
|
||||
|
|
@ -141,8 +141,8 @@ export default function ComboboxComponent({
|
|||
<RadixSelect.Item key={value} value={`${value ?? ''}`} asChild>
|
||||
<ComboboxItem
|
||||
className={cn(
|
||||
'relative flex w-full cursor-pointer 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',
|
||||
'rounded-lg hover:bg-gray-100/50 hover:bg-gray-50 dark:text-white dark:hover:bg-gray-600',
|
||||
'relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-surface-hover focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'rounded-lg hover:bg-surface-hover',
|
||||
)}
|
||||
/** Hacky fix for radix-ui Android issue: https://github.com/radix-ui/primitives/issues/1658 */
|
||||
onTouchEnd={() => {
|
||||
|
|
@ -156,7 +156,7 @@ export default function ComboboxComponent({
|
|||
</RadixSelect.ItemIndicator>
|
||||
</span>
|
||||
<RadixSelect.ItemText>
|
||||
<div className="flex items-center justify-center gap-3 dark:text-white [&_svg]:h-4 [&_svg]:w-4 [&_svg]:shrink-0 [&_svg]:text-foreground">
|
||||
<div className="flex items-center justify-center gap-3 [&_svg]:h-4 [&_svg]:w-4 [&_svg]:shrink-0 [&_svg]:text-text-primary">
|
||||
<div className="assistant-item overflow-hidden rounded-full">
|
||||
{icon && icon}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ const DeleteButton = memo(
|
|||
<Spinner className="size-4" />
|
||||
) : (
|
||||
<>
|
||||
<TrashIcon className="size-3.5 text-red-400 sm:size-4" />
|
||||
<TrashIcon className="size-3.5 text-text-destructive sm:size-4" />
|
||||
{!isSmallScreen && <span className="ml-2">Delete</span>}
|
||||
</>
|
||||
)}
|
||||
|
|
@ -429,7 +429,7 @@ export default function DataTable<TData, TValue>({
|
|||
<div
|
||||
ref={tableContainerRef}
|
||||
className={cn(
|
||||
'relative min-h-0 max-w-full flex-1 overflow-x-auto overflow-y-auto rounded-md border border-black/10 dark:border-white/10',
|
||||
'relative min-h-0 max-w-full flex-1 overflow-x-auto overflow-y-auto rounded-md border border-border-light',
|
||||
'transition-all duration-300 ease-out',
|
||||
isSearching && 'bg-surface-secondary/50',
|
||||
className,
|
||||
|
|
|
|||
|
|
@ -436,7 +436,7 @@ function DataTable<TData extends Record<string, unknown>, TValue>({
|
|||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'relative flex w-full flex-col overflow-hidden rounded-lg border border-border-light bg-background',
|
||||
'relative flex w-full flex-col overflow-hidden rounded-lg border border-border-light bg-surface-primary',
|
||||
'h-[calc(100vh-8rem)] max-h-[80vh]',
|
||||
className,
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ class DataTableErrorBoundaryInner extends Component<
|
|||
aria-labelledby="datatable-error-title"
|
||||
aria-describedby="datatable-error-desc"
|
||||
tabIndex={-1}
|
||||
className="before:bg-surface-destructive/80 relative w-full max-w-md overflow-hidden rounded-lg border border-border-light bg-surface-primary-alt p-6 shadow-sm outline-none before:absolute before:left-0 before:top-0 before:h-full before:w-1 focus:ring-2 focus:ring-ring focus:ring-offset-2 dark:border-border-medium dark:bg-surface-secondary"
|
||||
className="before:bg-surface-destructive/80 relative w-full max-w-md overflow-hidden rounded-lg border border-border-light bg-surface-primary-alt p-6 shadow-sm outline-none before:absolute before:left-0 before:top-0 before:h-full before:w-1 focus:ring-2 focus:ring-text-primary focus:ring-offset-2"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<RefreshCw className="h-4 w-4 text-surface-destructive" />
|
||||
|
|
@ -98,7 +98,7 @@ class DataTableErrorBoundaryInner extends Component<
|
|||
</div>
|
||||
|
||||
{import.meta.env.MODE === 'development' && this.state.error && (
|
||||
<details className="mt-4 max-w-md rounded-md bg-surface-secondary p-3 text-xs dark:bg-surface-tertiary">
|
||||
<details className="mt-4 max-w-md rounded-md bg-surface-secondary p-3 text-xs">
|
||||
<summary className="cursor-pointer font-medium text-text-primary">
|
||||
{this.props.localize('com_ui_error_details')}
|
||||
</summary>
|
||||
|
|
|
|||
|
|
@ -60,10 +60,9 @@ const DialogContent: React.ForwardRefExoticComponent<
|
|||
<DialogPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'fixed z-[999] grid w-full gap-4 rounded-b-lg bg-white pb-6 animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:rounded-lg',
|
||||
'dark:bg-gray-700',
|
||||
'fixed z-[999] grid w-full gap-4 rounded-b-lg bg-surface-dialog pb-6 animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:rounded-lg',
|
||||
isSmallScreen
|
||||
? 'fixed left-1/2 top-1/2 z-[999] m-auto grid w-11/12 -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-white pb-6'
|
||||
? 'fixed left-1/2 top-1/2 z-[999] m-auto grid w-11/12 -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-surface-dialog pb-6'
|
||||
: '',
|
||||
disableScroll ? 'overflow-hidden' : '',
|
||||
className ?? '',
|
||||
|
|
@ -72,8 +71,8 @@ const DialogContent: React.ForwardRefExoticComponent<
|
|||
>
|
||||
{children}
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close className="absolute right-6 top-[1.6rem] rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-gray-100 dark:focus:ring-white dark:focus:ring-offset-gray-700 dark:data-[state=open]:bg-gray-800">
|
||||
<X className="h-5 w-5 text-black dark:text-white" aria-hidden="true" />
|
||||
<DialogPrimitive.Close className="absolute right-6 top-[1.6rem] rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-text-primary focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-surface-hover">
|
||||
<X className="h-5 w-5 text-text-primary" aria-hidden="true" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
)}
|
||||
|
|
@ -90,7 +89,7 @@ const DialogHeader: {
|
|||
} = ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): JSX.Element => (
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col space-y-2 border-b border-black/10 p-6 pb-4 text-left dark:border-white/10',
|
||||
'flex flex-col space-y-2 border-b border-border-light p-6 pb-4 text-left',
|
||||
className ?? '',
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -118,7 +117,7 @@ const DialogTitle: React.ForwardRefExoticComponent<
|
|||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Title
|
||||
ref={ref}
|
||||
className={cn('text-lg font-semibold text-gray-900', 'dark:text-gray-50', className ?? '')}
|
||||
className={cn('text-lg font-semibold text-text-primary', className ?? '')}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
@ -133,7 +132,7 @@ const DialogDescription: React.ForwardRefExoticComponent<
|
|||
>(({ className, ...props }, ref) => (
|
||||
<DialogPrimitive.Description
|
||||
ref={ref}
|
||||
className={cn('text-sm text-gray-500', 'dark:text-gray-400', className ?? '')}
|
||||
className={cn('text-sm text-text-secondary', className ?? '')}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
@ -149,10 +148,10 @@ const DialogClose: React.ForwardRefExoticComponent<
|
|||
<DialogPrimitive.Close
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'mt-2 inline-flex h-10 items-center justify-center rounded-lg border border-gray-200 bg-transparent px-4 py-2 text-sm font-semibold text-gray-900 transition-colors hover:bg-gray-100 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:text-gray-100 dark:hover:bg-gray-800 sm:mt-0',
|
||||
'mt-2 inline-flex h-10 items-center justify-center rounded-lg border border-border-light bg-transparent px-4 py-2 text-sm font-semibold text-text-primary transition-colors hover:bg-surface-hover focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 sm:mt-0',
|
||||
className ?? '',
|
||||
/* Important: for accessibility */
|
||||
'focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900',
|
||||
'focus:ring-2 focus:ring-text-primary focus:ring-offset-2',
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
@ -170,10 +169,10 @@ const DialogButton: React.ForwardRefExoticComponent<
|
|||
ref={ref}
|
||||
variant="outline"
|
||||
className={cn(
|
||||
'mt-2 inline-flex h-10 items-center justify-center rounded-lg border border-gray-200 bg-transparent px-4 py-2 text-sm font-semibold text-gray-900 transition-colors hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:text-gray-100 dark:hover:bg-gray-800 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900 sm:mt-0',
|
||||
'mt-2 inline-flex h-10 items-center justify-center rounded-lg border border-border-light bg-transparent px-4 py-2 text-sm font-semibold text-text-primary transition-colors hover:bg-surface-hover focus:outline-none focus:ring-2 focus:ring-text-primary focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 sm:mt-0',
|
||||
className ?? '',
|
||||
/* Important: for accessibility */
|
||||
'focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900',
|
||||
'focus:ring-2 focus:ring-text-primary focus:ring-offset-2',
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -49,22 +49,20 @@ const DialogTemplate: ForwardRefExoticComponent<
|
|||
const Cancel = 'cancel';
|
||||
|
||||
const defaultSelect =
|
||||
'bg-gray-800 text-white transition-colors hover:bg-gray-700 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-200 dark:text-gray-800 dark:hover:bg-gray-200';
|
||||
'bg-surface-inverted text-text-inverted transition-colors hover:bg-surface-inverted-hover disabled:cursor-not-allowed disabled:opacity-50';
|
||||
return (
|
||||
<DialogContent
|
||||
showCloseButton={showCloseButton}
|
||||
ref={ref}
|
||||
className={cn('shadow-2xl dark:bg-gray-700', className || '')}
|
||||
className={cn('bg-surface-dialog shadow-2xl', className || '')}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<DialogHeader className={cn(headerClassName ?? '')}>
|
||||
<DialogTitle className="text-lg font-medium leading-6 text-gray-800 dark:text-gray-200">
|
||||
<DialogTitle className="text-lg font-medium leading-6 text-text-primary">
|
||||
{title}
|
||||
</DialogTitle>
|
||||
{description && (
|
||||
<DialogDescription className="text-gray-600 dark:text-gray-300">
|
||||
{description}
|
||||
</DialogDescription>
|
||||
<DialogDescription className="text-text-secondary">{description}</DialogDescription>
|
||||
)}
|
||||
</DialogHeader>
|
||||
<div className="px-6">{main ? main : null}</div>
|
||||
|
|
@ -72,7 +70,7 @@ const DialogTemplate: ForwardRefExoticComponent<
|
|||
<div>{leftButtons ? leftButtons : null}</div>
|
||||
<div className="flex h-auto gap-3">
|
||||
{showCancelButton && (
|
||||
<DialogClose className="border-gray-100 hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-600">
|
||||
<DialogClose className="border-border-light hover:bg-surface-hover">
|
||||
{Cancel}
|
||||
</DialogClose>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -137,8 +137,8 @@ const Dropdown: React.FC<DropdownProps> = ({
|
|||
store={selectProps}
|
||||
disabled={disabled}
|
||||
className={cn(
|
||||
'focus:ring-offset-ring-offset relative inline-flex items-center justify-between rounded-xl border border-input bg-background px-3 py-2 text-sm text-text-primary transition-all duration-200 ease-in-out hover:bg-accent hover:text-accent-foreground focus:ring-ring-primary',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-background disabled:hover:text-text-primary',
|
||||
'focus:ring-offset-ring-offset relative inline-flex items-center justify-between rounded-xl border border-border-medium bg-surface-primary px-3 py-2 text-sm text-text-primary transition-all duration-200 ease-in-out hover:bg-surface-hover hover:text-text-primary focus:ring-ring-primary',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-surface-primary disabled:hover:text-text-primary',
|
||||
iconOnly ? 'size-10' : 'w-fit gap-2',
|
||||
className,
|
||||
)}
|
||||
|
|
@ -176,7 +176,7 @@ const Dropdown: React.FC<DropdownProps> = ({
|
|||
>
|
||||
{searchable ? (
|
||||
<>
|
||||
<div className="sticky -top-2 z-10 -mx-2 -mt-2 mb-1 bg-surface-primary px-2 pb-1.5 pt-2 dark:bg-surface-secondary">
|
||||
<div className="sticky -top-2 z-10 -mx-2 -mt-2 mb-1 bg-surface-primary px-2 pb-1.5 pt-2">
|
||||
<div className="relative">
|
||||
<Search
|
||||
className="pointer-events-none absolute left-2 top-1/2 h-4 w-4 -translate-y-1/2 text-text-tertiary"
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ function DropdownMenuItem({
|
|||
data-inset={inset}
|
||||
data-variant={variant}
|
||||
className={cn(
|
||||
"data-[variant=destructive]:*:[svg]:!text-destructive outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[inset]:pl-8 data-[variant=destructive]:text-destructive data-[disabled]:opacity-50 data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"data-[variant=destructive]:*:[svg]:!text-text-destructive outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm focus:bg-surface-hover focus:text-text-primary data-[disabled]:pointer-events-none data-[inset]:pl-8 data-[variant=destructive]:text-text-destructive data-[disabled]:opacity-50 data-[variant=destructive]:focus:bg-status-error-subtle data-[variant=destructive]:focus:text-text-destructive [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-text-secondary [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -81,7 +81,7 @@ function DropdownMenuCheckboxItem({
|
|||
<DropdownMenuPrimitive.CheckboxItem
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
className={cn(
|
||||
"outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm focus:bg-surface-hover focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
|
|
@ -112,7 +112,7 @@ function DropdownMenuRadioItem({
|
|||
<DropdownMenuPrimitive.RadioItem
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
className={cn(
|
||||
"outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"outline-hidden relative flex cursor-default select-none items-center gap-2 rounded-sm py-1.5 pl-8 pr-2 text-sm focus:bg-surface-hover focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -161,7 +161,7 @@ function DropdownMenuShortcut({ className, ...props }: React.ComponentProps<'spa
|
|||
return (
|
||||
<span
|
||||
data-slot="dropdown-menu-shortcut"
|
||||
className={cn('ml-auto text-xs tracking-widest text-muted-foreground', className)}
|
||||
className={cn('ml-auto text-xs tracking-widest text-text-secondary', className)}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
|
@ -186,7 +186,7 @@ function DropdownMenuSubTrigger({
|
|||
data-slot="dropdown-menu-sub-trigger"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
'outline-hidden flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[inset]:pl-8 data-[state=open]:text-accent-foreground',
|
||||
'outline-hidden flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm focus:bg-surface-hover focus:text-text-primary data-[state=open]:bg-surface-hover data-[inset]:pl-8 data-[state=open]:text-text-primary',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ const Dropdown: FC<DropdownProps> = ({
|
|||
<ListboxButton
|
||||
data-testid={testId}
|
||||
className={cn(
|
||||
'relative inline-flex items-center justify-between rounded-md border-gray-50 bg-white py-2 pl-3 pr-8 text-black transition-all duration-100 ease-in-out hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 dark:focus:ring-white dark:focus:ring-offset-gray-700',
|
||||
'relative inline-flex items-center justify-between rounded-md border-border-light bg-surface-secondary py-2 pl-3 pr-8 text-text-primary transition-all duration-100 ease-in-out hover:bg-surface-hover',
|
||||
'w-auto',
|
||||
className,
|
||||
)}
|
||||
|
|
@ -70,7 +70,7 @@ const Dropdown: FC<DropdownProps> = ({
|
|||
viewBox="0 0 24 24"
|
||||
strokeWidth="2"
|
||||
stroke="currentColor"
|
||||
className="h-4 w-5 rotate-0 transform text-black transition-transform duration-300 ease-in-out dark:text-gray-50"
|
||||
className="h-4 w-5 rotate-0 transform text-text-primary transition-transform duration-300 ease-in-out"
|
||||
>
|
||||
<polyline points="6 9 12 15 18 9"></polyline>
|
||||
</svg>
|
||||
|
|
@ -83,7 +83,7 @@ const Dropdown: FC<DropdownProps> = ({
|
|||
>
|
||||
<ListboxOptions
|
||||
className={cn(
|
||||
'absolute z-50 mt-1 flex flex-col items-start gap-1 overflow-auto rounded-lg border border-gray-300 bg-white p-1.5 text-gray-700 shadow-lg transition-opacity focus:outline-none dark:border-gray-600 dark:bg-gray-700 dark:text-white',
|
||||
'absolute z-50 mt-1 flex flex-col items-start gap-1 overflow-auto rounded-lg border border-border-medium bg-surface-secondary p-1.5 text-text-primary shadow-lg transition-opacity focus:outline-none',
|
||||
sizeClasses,
|
||||
className,
|
||||
)}
|
||||
|
|
@ -94,7 +94,7 @@ const Dropdown: FC<DropdownProps> = ({
|
|||
key={index}
|
||||
value={item}
|
||||
className={cn(
|
||||
'relative cursor-pointer select-none rounded border-gray-300 bg-white py-2.5 pl-3 pr-3 text-sm text-gray-700 hover:bg-gray-100 dark:border-gray-300 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600',
|
||||
'relative cursor-pointer select-none rounded border-border-medium bg-surface-secondary py-2.5 pl-3 pr-3 text-sm text-text-primary hover:bg-surface-hover',
|
||||
)}
|
||||
style={{ width: '100%' }}
|
||||
data-theme={getValue(item)}
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ const Menu: React.FC<MenuProps> = ({
|
|||
)}
|
||||
{item.label}
|
||||
{item.kbd != null && (
|
||||
<kbd className="ml-auto hidden font-sans text-xs text-black/50 group-hover:inline group-focus:inline dark:text-white/50">
|
||||
<kbd className="ml-auto hidden font-sans text-xs text-text-tertiary group-hover:inline group-focus:inline">
|
||||
⌘{item.kbd}
|
||||
</kbd>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -35,14 +35,14 @@ const FilterInput: React.ForwardRefExoticComponent<
|
|||
placeholder=" "
|
||||
aria-label={label}
|
||||
className={cn(
|
||||
'peer flex h-9 w-full rounded-lg border border-border-light bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'peer flex h-9 w-full rounded-lg border border-border-light bg-transparent px-3 py-2 text-sm ring-offset-surface-primary placeholder:text-text-secondary focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
<label
|
||||
htmlFor={inputId}
|
||||
className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm text-text-secondary transition-all duration-200 peer-focus:top-0 peer-focus:bg-background peer-focus:px-1 peer-focus:text-xs peer-[:not(:placeholder-shown)]:top-0 peer-[:not(:placeholder-shown)]:bg-background peer-[:not(:placeholder-shown)]:px-1 peer-[:not(:placeholder-shown)]:text-xs"
|
||||
className="pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-sm text-text-secondary transition-all duration-200 peer-focus:top-0 peer-focus:bg-surface-primary peer-focus:px-1 peer-focus:text-xs peer-[:not(:placeholder-shown)]:top-0 peer-[:not(:placeholder-shown)]:bg-surface-primary peer-[:not(:placeholder-shown)]:px-1 peer-[:not(:placeholder-shown)]:text-xs"
|
||||
>
|
||||
{label}
|
||||
</label>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ const Input: React.ForwardRefExoticComponent<InputProps & React.RefAttributes<HT
|
|||
return (
|
||||
<input
|
||||
className={cn(
|
||||
'flex h-10 w-full rounded-lg border border-border-light bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'flex h-10 w-full rounded-lg border border-border-light bg-transparent px-3 py-2 text-sm ring-offset-surface-primary placeholder:text-text-secondary focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className ?? '',
|
||||
)}
|
||||
ref={ref}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const InputNumber: React.ForwardRefExoticComponent<
|
|||
return (
|
||||
<RCInputNumber
|
||||
className={cn(
|
||||
'flex max-h-5 w-full rounded-md border border-gray-300 bg-transparent px-3 py-2 text-sm placeholder:text-gray-400 focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:text-gray-50',
|
||||
'flex max-h-5 w-full rounded-md border border-border-medium bg-transparent px-3 py-2 text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className ?? '',
|
||||
)}
|
||||
ref={ref}
|
||||
|
|
|
|||
|
|
@ -109,8 +109,8 @@ const InputOTPSlot: React.ForwardRefExoticComponent<
|
|||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'text-md relative flex h-11 w-11 items-center justify-center border-y border-r border-input shadow-sm transition-all first:rounded-l-xl first:border-l last:rounded-r-xl',
|
||||
isActive && 'z-10 ring-1 ring-ring',
|
||||
'text-md relative flex h-11 w-11 items-center justify-center border-y border-r border-border-medium shadow-sm transition-all first:rounded-l-xl first:border-l last:rounded-r-xl',
|
||||
isActive && 'z-10 ring-1 ring-text-primary',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -118,7 +118,7 @@ const InputOTPSlot: React.ForwardRefExoticComponent<
|
|||
{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 h-4 w-px bg-text-primary duration-1000" />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ const InputWithDropdown: React.ForwardRefExoticComponent<
|
|||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="text-tertiary absolute inset-y-0 right-0 flex items-center rounded-md px-2 hover:text-secondary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring-primary"
|
||||
className="text-tertiary absolute inset-y-0 right-0 flex items-center rounded-md px-2 hover:text-text-secondary focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring-primary"
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
aria-label={isOpen ? 'Close dropdown' : 'Open dropdown'}
|
||||
>
|
||||
|
|
@ -132,8 +132,8 @@ const InputWithDropdown: React.ForwardRefExoticComponent<
|
|||
'cursor-pointer rounded-md px-3 py-2',
|
||||
'focus:bg-surface-tertiary focus:outline-none focus:ring-1 focus:ring-inset focus:ring-ring-primary',
|
||||
index === highlightedIndex
|
||||
? 'bg-surface-active text-primary'
|
||||
: 'text-secondary hover:bg-surface-tertiary',
|
||||
? 'bg-surface-active text-text-primary'
|
||||
: 'text-text-secondary hover:bg-surface-tertiary',
|
||||
)}
|
||||
onClick={() => handleSelect(option)}
|
||||
onKeyDown={(e) => {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const Label: React.ForwardRefExoticComponent<
|
|||
{...props}
|
||||
{...{
|
||||
className: cn(
|
||||
'block w-full break-all text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 dark:text-gray-200',
|
||||
'block w-full break-all text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 text-text-primary',
|
||||
className,
|
||||
),
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ export default function MultiSelect<T extends string>({
|
|||
className={cn(
|
||||
'flex items-center justify-between gap-2 rounded-xl px-3 py-2 text-sm',
|
||||
'bg-surface-tertiary text-text-primary shadow-sm hover:cursor-pointer hover:bg-surface-hover',
|
||||
'outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white',
|
||||
'outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary',
|
||||
selectClassName,
|
||||
selectedValues.length > 0 && selectItemsClassName != null && selectItemsClassName,
|
||||
)}
|
||||
|
|
@ -151,7 +151,7 @@ export default function MultiSelect<T extends string>({
|
|||
const label = getItemLabel(item);
|
||||
const defaultContent = (
|
||||
<>
|
||||
<SelectItemCheck className="mr-0.5 text-primary" />
|
||||
<SelectItemCheck className="mr-0.5 text-text-primary" />
|
||||
<span className="truncate">{label}</span>
|
||||
</>
|
||||
);
|
||||
|
|
@ -163,8 +163,8 @@ export default function MultiSelect<T extends string>({
|
|||
className={cn(
|
||||
'flex items-center gap-2 rounded-lg px-2 py-1.5 hover:cursor-pointer',
|
||||
'scroll-m-1 outline-none transition-colors',
|
||||
'hover:bg-black/[0.075] dark:hover:bg-white/10',
|
||||
'data-[active-item]:bg-black/[0.075] dark:data-[active-item]:bg-white/10',
|
||||
'hover:bg-surface-hover',
|
||||
'data-[active-item]:bg-surface-active',
|
||||
'w-full min-w-0 text-sm',
|
||||
itemClassName,
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ const OGDialogTemplate: ForwardRefExoticComponent<
|
|||
const { selectHandler, selectClasses, selectText, isLoading } = legacySelection ?? {};
|
||||
|
||||
const defaultSelect =
|
||||
'bg-gray-800 text-white transition-colors hover:bg-gray-700 disabled:cursor-not-allowed disabled:opacity-50 dark:bg-gray-200 dark:text-gray-800 dark:hover:bg-gray-200';
|
||||
'bg-surface-inverted text-text-inverted transition-colors hover:bg-surface-inverted-hover disabled:cursor-not-allowed disabled:opacity-50';
|
||||
|
||||
let selectionContent = null;
|
||||
if (isLegacySelection) {
|
||||
|
|
@ -121,7 +121,7 @@ const OGDialogTemplate: ForwardRefExoticComponent<
|
|||
overlayClassName={overlayClassName}
|
||||
showCloseButton={showCloseButton}
|
||||
ref={ref}
|
||||
className={cn('w-11/12 border-none bg-background text-foreground', className ?? '')}
|
||||
className={cn('w-11/12 border-none bg-surface-primary text-text-primary', className ?? '')}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<OGDialogHeader className={cn(headerClassName ?? '')}>
|
||||
|
|
|
|||
|
|
@ -154,14 +154,14 @@ const DialogContent: React.ForwardRefExoticComponent<
|
|||
style={{ ...style, zIndex: contentZIndex }}
|
||||
onEscapeKeyDown={handleEscapeKeyDown}
|
||||
className={cn(
|
||||
'max-w-11/12 fixed left-[50%] top-[50%] grid max-h-[90vh] w-full translate-x-[-50%] translate-y-[-50%] gap-4 overflow-y-auto rounded-2xl bg-background p-6 text-text-primary 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%]',
|
||||
'max-w-11/12 fixed left-[50%] top-[50%] grid max-h-[90vh] w-full translate-x-[-50%] translate-y-[-50%] gap-4 overflow-y-auto rounded-2xl bg-surface-primary p-6 text-text-primary 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%]',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
{showCloseButton && (
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-ring-primary 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="absolute right-4 top-4 rounded-sm opacity-70 ring-ring-primary ring-offset-surface-primary transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-text-primary focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-surface-hover data-[state=open]:text-text-secondary">
|
||||
<X className="h-6 w-6" aria-hidden="true" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,14 @@ const Progress: React.ForwardRefExoticComponent<
|
|||
>(({ className, value, ...props }, ref) => (
|
||||
<ProgressPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn('relative h-2 w-full overflow-hidden rounded-full bg-primary/20', className)}
|
||||
className={cn(
|
||||
'relative h-2 w-full overflow-hidden rounded-full bg-surface-tertiary',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
<ProgressPrimitive.Indicator
|
||||
className="h-full w-full flex-1 bg-primary transition-all"
|
||||
className="h-full w-full flex-1 bg-surface-inverted transition-all"
|
||||
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
|
||||
/>
|
||||
</ProgressPrimitive.Root>
|
||||
|
|
|
|||
|
|
@ -81,11 +81,11 @@ const Radio: React.NamedExoticComponent<RadioProps> = memo(function Radio({
|
|||
if (options.length === 0) {
|
||||
return (
|
||||
<div
|
||||
className="relative inline-flex items-center rounded-lg bg-muted p-1 opacity-50"
|
||||
className="relative inline-flex items-center rounded-lg bg-surface-tertiary p-1 opacity-50"
|
||||
role="radiogroup"
|
||||
aria-labelledby={ariaLabelledBy}
|
||||
>
|
||||
<span className="px-4 py-2 text-xs text-muted-foreground">
|
||||
<span className="px-4 py-2 text-xs text-text-secondary">
|
||||
{localize('com_ui_no_options')}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -96,13 +96,13 @@ const Radio: React.NamedExoticComponent<RadioProps> = memo(function Radio({
|
|||
|
||||
return (
|
||||
<div
|
||||
className={`relative ${fullWidth ? 'flex' : 'inline-flex'} items-center rounded-lg bg-muted ${className}`}
|
||||
className={`relative ${fullWidth ? 'flex' : 'inline-flex'} items-center rounded-lg bg-surface-tertiary ${className}`}
|
||||
role="radiogroup"
|
||||
aria-labelledby={ariaLabelledBy}
|
||||
>
|
||||
{selectedIndex >= 0 && isMounted && (
|
||||
<div
|
||||
className="pointer-events-none absolute inset-y-0 rounded-md border border-border/50 bg-background shadow-sm transition-all duration-300 ease-out"
|
||||
className="pointer-events-none absolute inset-y-0 rounded-md border border-border-light bg-surface-primary shadow-sm transition-all duration-300 ease-out"
|
||||
style={backgroundStyle}
|
||||
/>
|
||||
)}
|
||||
|
|
@ -117,8 +117,8 @@ const Radio: React.NamedExoticComponent<RadioProps> = memo(function Radio({
|
|||
aria-checked={currentValue === option.value}
|
||||
onClick={() => handleChange(option.value)}
|
||||
disabled={disabled}
|
||||
className={`relative z-10 flex h-[34px] items-center justify-center gap-2 rounded-md px-4 text-sm font-medium transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${
|
||||
currentValue === option.value ? 'text-foreground' : 'text-foreground'
|
||||
className={`relative z-10 flex h-[34px] items-center justify-center gap-2 rounded-md px-4 text-sm font-medium transition-colors duration-150 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary ${
|
||||
currentValue === option.value ? 'text-text-primary' : 'text-text-primary'
|
||||
} ${disabled ? 'cursor-not-allowed opacity-50' : ''} ${fullWidth ? 'flex-1' : ''} ${buttonClassName}`}
|
||||
>
|
||||
{option.icon && (
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@ const ResizableHandle = ({
|
|||
}): JSX.Element => (
|
||||
<Separator
|
||||
className={cn(
|
||||
'relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1',
|
||||
'relative flex w-px items-center justify-center bg-border-medium after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-text-primary focus-visible:ring-offset-1',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{withHandle && (
|
||||
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border">
|
||||
<div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border-medium">
|
||||
<GripVertical className="h-2.5 w-2.5" />
|
||||
</div>
|
||||
)}
|
||||
|
|
@ -44,13 +44,13 @@ const ResizableHandleAlt = ({
|
|||
}): JSX.Element => (
|
||||
<Separator
|
||||
className={cn(
|
||||
'group relative flex w-px items-center justify-center bg-border after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:ring-offset-1',
|
||||
'group relative flex w-px items-center justify-center bg-border-medium after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-text-primary focus-visible:ring-offset-1',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{withHandle && (
|
||||
<div className="invisible z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border group-hover:visible group-active:visible group-data-[separator=active]:visible">
|
||||
<div className="invisible z-10 flex h-4 w-3 items-center justify-center rounded-sm border bg-border-medium group-hover:visible group-active:visible group-data-[separator=active]:visible">
|
||||
<GripVertical className="h-2.5 w-2.5" />
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ const SecretInput: React.ForwardRefExoticComponent<
|
|||
id={id}
|
||||
type={isVisible ? 'text' : 'password'}
|
||||
className={cn(
|
||||
'flex h-10 w-full rounded-lg border border-border-light bg-transparent py-2 pl-3 text-sm transition-colors placeholder:text-muted-foreground hover:border-border-medium focus-visible:border-border-heavy focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
'flex h-10 w-full rounded-lg border border-border-light bg-transparent py-2 pl-3 text-sm transition-colors placeholder:text-text-secondary hover:border-border-medium focus-visible:border-border-heavy focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className ?? '',
|
||||
copyButton != null || showCopy ? 'pr-20' : 'pr-11',
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ const SelectTrigger: React.ForwardRefExoticComponent<
|
|||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-gray-200 border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 [&>span]:line-clamp-1',
|
||||
'rounded-lg hover:bg-gray-100/50 dark:hover:bg-gray-700',
|
||||
'flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-border-medium bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-surface-primary placeholder:text-text-secondary focus:outline-none disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1',
|
||||
'rounded-lg hover:bg-surface-hover',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -49,10 +49,7 @@ const SelectScrollUpButton: React.ForwardRefExoticComponent<
|
|||
>(({ className = '', ...props }, ref) => (
|
||||
<SelectPrimitive.ScrollUpButton
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex cursor-default items-center justify-center py-1 dark:text-white',
|
||||
className,
|
||||
)}
|
||||
className={cn('flex cursor-default items-center justify-center py-1', className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronUpIcon />
|
||||
|
|
@ -69,10 +66,7 @@ const SelectScrollDownButton: React.ForwardRefExoticComponent<
|
|||
>(({ className = '', ...props }, ref) => (
|
||||
<SelectPrimitive.ScrollDownButton
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'flex cursor-default items-center justify-center py-1 dark:text-white',
|
||||
className,
|
||||
)}
|
||||
className={cn('flex cursor-default items-center justify-center py-1', className)}
|
||||
{...props}
|
||||
>
|
||||
<ChevronDownIcon />
|
||||
|
|
@ -91,7 +85,7 @@ const SelectContent: React.ForwardRefExoticComponent<
|
|||
<SelectPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'bg-popover text-popover-foreground relative z-40 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-gray-200 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 dark:border-gray-600',
|
||||
'relative z-40 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-border-light bg-surface-secondary text-text-primary 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',
|
||||
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'
|
||||
: '',
|
||||
|
|
@ -142,8 +136,8 @@ const SelectItem: React.ForwardRefExoticComponent<
|
|||
<SelectPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'relative flex w-full cursor-pointer 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',
|
||||
'rounded-lg hover:bg-gray-100/50 dark:hover:bg-gray-700',
|
||||
'relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-surface-hover focus:text-text-primary data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
||||
'rounded-lg hover:bg-surface-hover',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -167,7 +161,7 @@ const SelectSeparator: React.ForwardRefExoticComponent<
|
|||
>(({ className = '', ...props }, ref) => (
|
||||
<SelectPrimitive.Separator
|
||||
ref={ref}
|
||||
className={cn('-mx-1 my-1 h-px bg-muted', className)}
|
||||
className={cn('-mx-1 my-1 h-px bg-surface-tertiary', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
|
|
|
|||
|
|
@ -119,13 +119,13 @@ function SelectDropDown({
|
|||
}
|
||||
}}
|
||||
className={cn(
|
||||
'relative flex w-full cursor-default flex-col rounded-md border border-black/10 bg-white py-2 pl-3 pr-10 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:bg-white dark:border-gray-600 dark:bg-gray-700 sm:text-sm',
|
||||
'relative flex w-full cursor-default flex-col rounded-md border border-border-light bg-surface-secondary py-2 pl-3 pr-10 text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary focus-visible:ring-offset-2 disabled:bg-surface-secondary sm:text-sm',
|
||||
className ?? '',
|
||||
)}
|
||||
>
|
||||
{showLabel && (
|
||||
<Label
|
||||
className="block text-xs text-gray-700 dark:text-gray-500"
|
||||
className="block text-xs text-text-secondary"
|
||||
id="headlessui-listbox-label-:r1:"
|
||||
data-headlessui-state=""
|
||||
>
|
||||
|
|
@ -135,13 +135,13 @@ function SelectDropDown({
|
|||
<span className="inline-flex w-full truncate">
|
||||
<span
|
||||
className={cn(
|
||||
'flex h-6 items-center gap-1 truncate text-sm text-gray-800 dark:text-white',
|
||||
'flex h-6 items-center gap-1 truncate text-sm text-text-primary',
|
||||
!showLabel ? 'text-xs' : '',
|
||||
currentValueClass ?? '',
|
||||
)}
|
||||
>
|
||||
{!showLabel && !emptyTitle && (
|
||||
<span className="text-xs text-gray-700 dark:text-gray-500">{title}:</span>
|
||||
<span className="text-xs text-text-secondary">{title}:</span>
|
||||
)}
|
||||
{renderIcon && optionIconSide !== 'right' && (
|
||||
<span className="icon-md flex items-center">
|
||||
|
|
@ -172,7 +172,7 @@ function SelectDropDown({
|
|||
viewBox="0 0 24 24"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className="h-4 w-4 text-gray-400"
|
||||
className="h-4 w-4 text-text-tertiary"
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -192,7 +192,7 @@ function SelectDropDown({
|
|||
>
|
||||
<ListboxOptions
|
||||
className={cn(
|
||||
'absolute z-10 mt-2 max-h-60 w-full overflow-auto rounded border bg-white text-xs ring-black/10 dark:border-gray-600 dark:bg-gray-700 dark:ring-white/20 md:w-[100%]',
|
||||
'absolute z-10 mt-2 max-h-60 w-full overflow-auto rounded border border-border-light bg-surface-secondary text-xs md:w-[100%]',
|
||||
optionsListClass ?? '',
|
||||
)}
|
||||
>
|
||||
|
|
@ -201,7 +201,7 @@ function SelectDropDown({
|
|||
key={'listbox-render-option'}
|
||||
value={null}
|
||||
className={cn(
|
||||
'group relative flex h-[42px] cursor-pointer select-none items-center overflow-hidden pl-3 pr-9 text-gray-800 hover:bg-gray-20 dark:text-white dark:hover:bg-gray-700',
|
||||
'group relative flex h-[42px] cursor-pointer select-none items-center overflow-hidden pl-3 pr-9 text-text-primary hover:bg-surface-hover',
|
||||
optionsClass ?? '',
|
||||
)}
|
||||
>
|
||||
|
|
@ -230,7 +230,7 @@ function SelectDropDown({
|
|||
value={option}
|
||||
className={({ active }) =>
|
||||
cn(
|
||||
'group relative flex h-[42px] cursor-pointer select-none items-center overflow-hidden pl-3 pr-9 text-gray-800 hover:bg-gray-20 dark:text-white dark:hover:bg-gray-600',
|
||||
'group relative flex h-[42px] cursor-pointer select-none items-center overflow-hidden pl-3 pr-9 text-text-primary hover:bg-surface-hover',
|
||||
active ? 'bg-surface-active text-text-primary' : '',
|
||||
optionsClass ?? '',
|
||||
)
|
||||
|
|
@ -239,7 +239,7 @@ function SelectDropDown({
|
|||
<span className="flex items-center gap-1.5 truncate">
|
||||
<span
|
||||
className={cn(
|
||||
'flex h-6 items-center gap-1 text-gray-800 dark:text-gray-200',
|
||||
'flex h-6 items-center gap-1 text-text-primary',
|
||||
option === value ? 'font-semibold' : '',
|
||||
iconSide === 'left' ? 'ml-4' : '',
|
||||
)}
|
||||
|
|
@ -259,7 +259,7 @@ function SelectDropDown({
|
|||
{currentValue === activeValue && (
|
||||
<span
|
||||
className={cn(
|
||||
'absolute inset-y-0 flex items-center text-gray-800 dark:text-gray-200',
|
||||
'absolute inset-y-0 flex items-center text-text-primary',
|
||||
iconSide === 'left' ? 'left-0 pl-2' : 'right-0 pr-3',
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -37,14 +37,16 @@ const Slider: React.ForwardRefExoticComponent<SliderProps & React.RefAttributes<
|
|||
}}
|
||||
>
|
||||
<SliderPrimitive.Track
|
||||
{...{ className: 'relative h-2 w-full grow overflow-hidden rounded-full bg-secondary' }}
|
||||
{...{
|
||||
className: 'relative h-2 w-full grow overflow-hidden rounded-full bg-surface-tertiary',
|
||||
}}
|
||||
>
|
||||
<SliderPrimitive.Range {...{ className: 'absolute h-full bg-primary' }} />
|
||||
<SliderPrimitive.Range {...{ className: 'absolute h-full bg-surface-inverted' }} />
|
||||
</SliderPrimitive.Track>
|
||||
<SliderPrimitive.Thumb
|
||||
{...{
|
||||
className:
|
||||
'block h-5 w-5 rounded-full border-2 border-primary bg-background ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
||||
'block h-5 w-5 rounded-full border-2 border-border-xheavy bg-surface-primary ring-offset-surface-primary transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
|
||||
'aria-labelledby': ariaLabelledBy,
|
||||
'aria-label': ariaLabel,
|
||||
'aria-describedby': ariaDescribedBy,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const Switch: React.ForwardRefExoticComponent<
|
|||
({ className, ...props }, ref) => (
|
||||
<SwitchPrimitives.Root
|
||||
className={cn(
|
||||
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent 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-switch-unchecked',
|
||||
'peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary focus-visible:ring-offset-2 focus-visible:ring-offset-surface-primary disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-surface-inverted data-[state=unchecked]:bg-switch-unchecked',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -31,7 +31,7 @@ const Switch: React.ForwardRefExoticComponent<
|
|||
>
|
||||
<SwitchPrimitives.Thumb
|
||||
className={cn(
|
||||
'pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0',
|
||||
'pointer-events-none block h-5 w-5 rounded-full bg-surface-primary shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0',
|
||||
)}
|
||||
/>
|
||||
</SwitchPrimitives.Root>
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ const TableFooter: React.ForwardRefExoticComponent<
|
|||
({ className, ...props }, ref) => (
|
||||
<tfoot
|
||||
ref={ref}
|
||||
className={cn('border-t bg-muted/50 font-medium [&>tr]:last:border-b-0', className)}
|
||||
className={cn('border-t bg-surface-tertiary font-medium [&>tr]:last:border-b-0', className)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
|
|
@ -59,7 +59,7 @@ const TableRow: React.ForwardRefExoticComponent<
|
|||
<tr
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'border-b border-border-light transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
|
||||
'border-b border-border-light transition-colors hover:bg-surface-tertiary data-[state=selected]:bg-surface-tertiary',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -75,7 +75,7 @@ const TableHead: React.ForwardRefExoticComponent<
|
|||
<th
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
|
||||
'h-12 px-4 text-left align-middle font-medium text-text-secondary [&:has([role=checkbox])]:pr-0',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -118,7 +118,7 @@ const TableCaption: React.ForwardRefExoticComponent<
|
|||
React.HTMLAttributes<HTMLTableCaptionElement> & React.RefAttributes<HTMLTableCaptionElement>
|
||||
> = React.forwardRef<HTMLTableCaptionElement, React.HTMLAttributes<HTMLTableCaptionElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<caption ref={ref} className={cn('mt-4 text-sm text-muted-foreground', className)} {...props} />
|
||||
<caption ref={ref} className={cn('mt-4 text-sm text-text-secondary', className)} {...props} />
|
||||
),
|
||||
);
|
||||
TableCaption.displayName = 'TableCaption';
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ const TabsTrigger: React.ForwardRefExoticComponent<
|
|||
>(({ className = '', ...props }, ref) => (
|
||||
<TabsPrimitive.Trigger
|
||||
className={cn(
|
||||
'inline-flex min-w-[100px] items-center justify-center rounded-[0.185rem] px-3 py-1.5 text-sm font-medium text-gray-700 transition-all disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-white data-[state=active]:text-gray-800 data-[state=active]:shadow-sm dark:data-[state=active]:bg-gray-700 dark:data-[state=active]:text-gray-200',
|
||||
'inline-flex min-w-[100px] items-center justify-center rounded-[0.185rem] px-3 py-1.5 text-sm font-medium text-text-secondary transition-all disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-surface-primary data-[state=active]:text-text-primary data-[state=active]:shadow-sm',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const Textarea: React.ForwardRefExoticComponent<
|
|||
return (
|
||||
<textarea
|
||||
className={cn(
|
||||
'flex h-20 w-full resize-none rounded-md border border-gray-300 bg-transparent px-3 py-2 text-sm placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-700 dark:text-gray-50 dark:focus:ring-gray-400 dark:focus:ring-offset-gray-900',
|
||||
'flex h-20 w-full resize-none rounded-md border border-border-medium bg-transparent px-3 py-2 text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none focus:ring-2 focus:ring-text-primary focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
|
||||
className,
|
||||
)}
|
||||
ref={ref}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ const Theme = ({ theme, onChange }: { theme: string; onChange: (value: string) =
|
|||
|
||||
return (
|
||||
<button
|
||||
className="flex items-center gap-2 rounded-lg p-2 text-text-primary transition-colors hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 dark:focus-visible:ring-0"
|
||||
className="flex items-center gap-2 rounded-lg p-2 text-text-primary transition-colors hover:bg-surface-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-text-primary focus-visible:ring-offset-2"
|
||||
aria-label={localize('com_ui_toggle_theme')}
|
||||
aria-keyshortcuts="Ctrl+Shift+T"
|
||||
onClick={(e) => {
|
||||
|
|
@ -90,7 +90,7 @@ const ThemeSelector = ({ returnThemeOnly }: { returnThemeOnly?: boolean }): JSX.
|
|||
}
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center bg-white pt-6 dark:bg-gray-900 sm:pt-0">
|
||||
<div className="flex flex-col items-center justify-center bg-surface-primary pt-6 sm:pt-0">
|
||||
<div className="absolute bottom-0 left-0 m-4">
|
||||
<Theme theme={theme} onChange={changeTheme} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { JSX } from 'react/jsx-runtime';
|
||||
|
||||
export default function DotsIcon({
|
||||
className = 'h-4 w-4 flex-shrink-0 text-gray-500',
|
||||
className = 'h-4 w-4 flex-shrink-0 text-text-secondary',
|
||||
}: {
|
||||
className?: string;
|
||||
}): JSX.Element {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export default function NewChatIcon({ className = '' }: { className?: string }):
|
|||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={cn('text-black dark:text-white', className)}
|
||||
className={cn('text-text-primary', className)}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default function SendIcon({
|
|||
height={size}
|
||||
viewBox={'0 0 24 24'}
|
||||
fill="none"
|
||||
className={cn('text-white dark:text-black', className)}
|
||||
className={cn('text-text-inverted', className)}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<path
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default function StopGeneratingIcon({
|
|||
viewBox="0 0 24 24"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
className={cn('h-3 w-3 text-gray-600 dark:text-gray-400', className)}
|
||||
className={cn('h-3 w-3 text-text-secondary', className)}
|
||||
height="1em"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ export const darkTheme: IThemeRGB = {
|
|||
'rgb-surface-destructive': '153 27 27', // #991b1b (red-800)
|
||||
'rgb-surface-destructive-hover': '127 29 29', // #7f1d1d (red-900)
|
||||
'rgb-surface-chat': '47 47 47', // #2f2f2f (gray-700)
|
||||
'rgb-surface-inverted': '255 255 255', // #fff (white)
|
||||
'rgb-surface-inverted-hover': '236 236 236', // #ececec (gray-100)
|
||||
'rgb-text-inverted': '23 23 23', // #171717 (gray-850)
|
||||
'rgb-surface-fixed': '255 255 255', // #fff (white) — same in light + dark
|
||||
'rgb-surface-fixed-hover': '236 236 236', // #ececec (gray-100) — same in light + dark
|
||||
'rgb-text-fixed': '33 33 33', // #212121 (gray-800) — same in light + dark
|
||||
|
||||
// Border colors
|
||||
'rgb-border-light': '47 47 47', // #2f2f2f (gray-700)
|
||||
|
|
@ -52,21 +58,9 @@ export const darkTheme: IThemeRGB = {
|
|||
// Presentation
|
||||
'rgb-presentation': '33 33 33', // #212121 (gray-800)
|
||||
|
||||
// Utility colors (mapped to existing colors for backwards compatibility)
|
||||
'rgb-background': '33 33 33', // Same as surface-primary
|
||||
'rgb-foreground': '255 255 255', // Same as text-primary
|
||||
'rgb-primary': '66 66 66', // Same as surface-active
|
||||
'rgb-primary-foreground': '255 255 255', // Same as surface-primary-contrast
|
||||
'rgb-secondary': '42 42 42', // Same as surface-secondary
|
||||
'rgb-secondary-foreground': '193 193 193', // Same as text-secondary
|
||||
'rgb-muted': '56 56 56', // Same as surface-tertiary
|
||||
'rgb-muted-foreground': '140 140 140', // Same as text-tertiary
|
||||
'rgb-accent': '82 82 82', // Same as surface-active-alt
|
||||
'rgb-accent-foreground': '255 255 255', // Same as text-primary
|
||||
'rgb-destructive-foreground': '255 255 255', // Same as text-primary
|
||||
'rgb-border': '82 82 82', // Same as border-medium
|
||||
'rgb-input': '66 66 66', // Same as border-light
|
||||
'rgb-ring': '255 255 255', // Same as ring-primary
|
||||
'rgb-card': '42 42 42', // Same as surface-secondary
|
||||
'rgb-card-foreground': '255 255 255', // Same as text-primary
|
||||
// Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration)
|
||||
'rgb-background': '18 18 18', // 0 0% 7%
|
||||
'rgb-primary': '250 250 250', // 0 0% 98%
|
||||
'rgb-primary-foreground': '23 23 23', // 0 0% 9%
|
||||
'rgb-ring': '212 212 212', // 0 0% 83.1%
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,6 +38,12 @@ export const defaultTheme: IThemeRGB = {
|
|||
'rgb-surface-destructive': '185 28 28', // #b91c1c (red-700)
|
||||
'rgb-surface-destructive-hover': '153 27 27', // #991b1b (red-800)
|
||||
'rgb-surface-chat': '255 255 255', // #fff (white)
|
||||
'rgb-surface-inverted': '23 23 23', // #171717 (gray-850)
|
||||
'rgb-surface-inverted-hover': '47 47 47', // #2f2f2f (gray-700)
|
||||
'rgb-text-inverted': '255 255 255', // #fff (white)
|
||||
'rgb-surface-fixed': '255 255 255', // #fff (white) — same in light + dark
|
||||
'rgb-surface-fixed-hover': '236 236 236', // #ececec (gray-100) — same in light + dark
|
||||
'rgb-text-fixed': '33 33 33', // #212121 (gray-800) — same in light + dark
|
||||
|
||||
// Border colors
|
||||
'rgb-border-light': '227 227 227', // #e3e3e3 (gray-200)
|
||||
|
|
@ -52,21 +58,9 @@ export const defaultTheme: IThemeRGB = {
|
|||
// Presentation
|
||||
'rgb-presentation': '255 255 255', // #fff (white)
|
||||
|
||||
// Utility colors (mapped to existing colors for backwards compatibility)
|
||||
'rgb-background': '255 255 255', // Same as surface-primary
|
||||
'rgb-foreground': '17 17 17', // Same as text-primary
|
||||
'rgb-primary': '235 235 235', // Same as surface-active
|
||||
'rgb-primary-foreground': '0 0 0', // Same as surface-primary-contrast
|
||||
'rgb-secondary': '247 247 248', // Same as surface-secondary
|
||||
'rgb-secondary-foreground': '66 66 66', // Same as text-secondary
|
||||
'rgb-muted': '250 250 250', // Same as surface-tertiary
|
||||
'rgb-muted-foreground': '120 120 120', // Same as text-tertiary
|
||||
'rgb-accent': '245 245 245', // Same as surface-active-alt
|
||||
'rgb-accent-foreground': '17 17 17', // Same as text-primary
|
||||
'rgb-destructive-foreground': '17 17 17', // Same as text-primary
|
||||
'rgb-border': '215 215 215', // Same as border-medium
|
||||
'rgb-input': '230 230 230', // Same as border-light
|
||||
'rgb-ring': '180 180 180', // Same as ring-primary
|
||||
'rgb-card': '247 247 248', // Same as surface-secondary
|
||||
'rgb-card-foreground': '17 17 17', // Same as text-primary
|
||||
// Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration)
|
||||
'rgb-background': '255 255 255', // 0 0% 100%
|
||||
'rgb-primary': '23 23 23', // 0 0% 9%
|
||||
'rgb-primary-foreground': '250 250 250', // 0 0% 98%
|
||||
'rgb-ring': '10 10 10', // 0 0% 3.9%
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,6 +36,12 @@ export interface IThemeRGB {
|
|||
'rgb-surface-destructive'?: string;
|
||||
'rgb-surface-destructive-hover'?: string;
|
||||
'rgb-surface-chat'?: string;
|
||||
'rgb-surface-inverted'?: string;
|
||||
'rgb-surface-inverted-hover'?: string;
|
||||
'rgb-text-inverted'?: string;
|
||||
'rgb-surface-fixed'?: string;
|
||||
'rgb-surface-fixed-hover'?: string;
|
||||
'rgb-text-fixed'?: string;
|
||||
|
||||
// Border colors
|
||||
'rgb-border-light'?: string;
|
||||
|
|
@ -50,23 +56,11 @@ export interface IThemeRGB {
|
|||
// Presentation
|
||||
'rgb-presentation'?: string;
|
||||
|
||||
// Utility colors
|
||||
// Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration)
|
||||
'rgb-background'?: string;
|
||||
'rgb-foreground'?: string;
|
||||
'rgb-primary'?: string;
|
||||
'rgb-primary-foreground'?: string;
|
||||
'rgb-secondary'?: string;
|
||||
'rgb-secondary-foreground'?: string;
|
||||
'rgb-muted'?: string;
|
||||
'rgb-muted-foreground'?: string;
|
||||
'rgb-accent'?: string;
|
||||
'rgb-accent-foreground'?: string;
|
||||
'rgb-destructive-foreground'?: string;
|
||||
'rgb-border'?: string;
|
||||
'rgb-input'?: string;
|
||||
'rgb-ring'?: string;
|
||||
'rgb-card'?: string;
|
||||
'rgb-card-foreground'?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -99,6 +93,12 @@ export interface IThemeVariables {
|
|||
'--surface-destructive': string;
|
||||
'--surface-destructive-hover': string;
|
||||
'--surface-chat': string;
|
||||
'--surface-inverted': string;
|
||||
'--surface-inverted-hover': string;
|
||||
'--text-inverted': string;
|
||||
'--surface-fixed': string;
|
||||
'--surface-fixed-hover': string;
|
||||
'--text-fixed': string;
|
||||
'--border-light': string;
|
||||
'--border-medium': string;
|
||||
'--border-medium-alt': string;
|
||||
|
|
@ -107,23 +107,11 @@ export interface IThemeVariables {
|
|||
'--brand-purple': string;
|
||||
'--presentation': string;
|
||||
|
||||
// Utility variables
|
||||
// Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration)
|
||||
'--background': string;
|
||||
'--foreground': string;
|
||||
'--primary': string;
|
||||
'--primary-foreground': string;
|
||||
'--secondary': string;
|
||||
'--secondary-foreground': string;
|
||||
'--muted': string;
|
||||
'--muted-foreground': string;
|
||||
'--accent': string;
|
||||
'--accent-foreground': string;
|
||||
'--destructive-foreground': string;
|
||||
'--border': string;
|
||||
'--input': string;
|
||||
'--ring': string;
|
||||
'--card': string;
|
||||
'--card-foreground': string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -156,6 +144,12 @@ export interface IThemeColors {
|
|||
'surface-destructive'?: string;
|
||||
'surface-destructive-hover'?: string;
|
||||
'surface-chat'?: string;
|
||||
'surface-inverted'?: string;
|
||||
'surface-inverted-hover'?: string;
|
||||
'text-inverted'?: string;
|
||||
'surface-fixed'?: string;
|
||||
'surface-fixed-hover'?: string;
|
||||
'text-fixed'?: string;
|
||||
'border-light'?: string;
|
||||
'border-medium'?: string;
|
||||
'border-medium-alt'?: string;
|
||||
|
|
@ -164,23 +158,11 @@ export interface IThemeColors {
|
|||
'brand-purple'?: string;
|
||||
presentation?: string;
|
||||
|
||||
// Utility colors
|
||||
// Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration)
|
||||
background?: string;
|
||||
foreground?: string;
|
||||
primary?: string;
|
||||
'primary-foreground'?: string;
|
||||
secondary?: string;
|
||||
'secondary-foreground'?: string;
|
||||
muted?: string;
|
||||
'muted-foreground'?: string;
|
||||
accent?: string;
|
||||
'accent-foreground'?: string;
|
||||
'destructive-foreground'?: string;
|
||||
border?: string;
|
||||
input?: string;
|
||||
ring?: string;
|
||||
card?: string;
|
||||
'card-foreground'?: string;
|
||||
}
|
||||
|
||||
export interface Theme {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,12 @@ function mapTheme(rgb: IThemeRGB): Partial<IThemeVariables> {
|
|||
'rgb-surface-destructive': '--surface-destructive',
|
||||
'rgb-surface-destructive-hover': '--surface-destructive-hover',
|
||||
'rgb-surface-chat': '--surface-chat',
|
||||
'rgb-surface-inverted': '--surface-inverted',
|
||||
'rgb-surface-inverted-hover': '--surface-inverted-hover',
|
||||
'rgb-text-inverted': '--text-inverted',
|
||||
'rgb-surface-fixed': '--surface-fixed',
|
||||
'rgb-surface-fixed-hover': '--surface-fixed-hover',
|
||||
'rgb-text-fixed': '--text-fixed',
|
||||
'rgb-border-light': '--border-light',
|
||||
'rgb-border-medium': '--border-medium',
|
||||
'rgb-border-medium-alt': '--border-medium-alt',
|
||||
|
|
@ -60,23 +66,11 @@ function mapTheme(rgb: IThemeRGB): Partial<IThemeVariables> {
|
|||
'rgb-brand-purple': '--brand-purple',
|
||||
'rgb-presentation': '--presentation',
|
||||
|
||||
// Utility colors
|
||||
// Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration)
|
||||
'rgb-background': '--background',
|
||||
'rgb-foreground': '--foreground',
|
||||
'rgb-primary': '--primary',
|
||||
'rgb-primary-foreground': '--primary-foreground',
|
||||
'rgb-secondary': '--secondary',
|
||||
'rgb-secondary-foreground': '--secondary-foreground',
|
||||
'rgb-muted': '--muted',
|
||||
'rgb-muted-foreground': '--muted-foreground',
|
||||
'rgb-accent': '--accent',
|
||||
'rgb-accent-foreground': '--accent-foreground',
|
||||
'rgb-destructive-foreground': '--destructive-foreground',
|
||||
'rgb-border': '--border',
|
||||
'rgb-input': '--input',
|
||||
'rgb-ring': '--ring',
|
||||
'rgb-card': '--card',
|
||||
'rgb-card-foreground': '--card-foreground',
|
||||
};
|
||||
|
||||
Object.entries(mappings).forEach(([rgbKey, cssVar]) => {
|
||||
|
|
|
|||
|
|
@ -99,6 +99,12 @@ function createTailwindColors() {
|
|||
'surface-destructive': cssVar('--surface-destructive'),
|
||||
'surface-destructive-hover': cssVar('--surface-destructive-hover'),
|
||||
'surface-chat': cssVar('--surface-chat'),
|
||||
'surface-inverted': cssVar('--surface-inverted'),
|
||||
'surface-inverted-hover': cssVar('--surface-inverted-hover'),
|
||||
'text-inverted': cssVar('--text-inverted'),
|
||||
'surface-fixed': cssVar('--surface-fixed'),
|
||||
'surface-fixed-hover': cssVar('--surface-fixed-hover'),
|
||||
'text-fixed': cssVar('--text-fixed'),
|
||||
|
||||
'border-light': cssVar('--border-light'),
|
||||
'border-medium': cssVar('--border-medium'),
|
||||
|
|
@ -123,36 +129,15 @@ function createTailwindColors() {
|
|||
'status-neutral-subtle': cssVar('--status-neutral-subtle'),
|
||||
'status-neutral-border': cssVar('--status-neutral-border'),
|
||||
|
||||
border: hslVar('--border'),
|
||||
input: hslVar('--input'),
|
||||
'switch-unchecked': hslVar('--switch-unchecked'),
|
||||
ring: hslVar('--ring'),
|
||||
|
||||
// Retained for excluded SidePanel/Agents + SidePanel/Builder (pending migration)
|
||||
background: hslVar('--background'),
|
||||
foreground: hslVar('--foreground'),
|
||||
ring: hslVar('--ring'),
|
||||
primary: {
|
||||
DEFAULT: hslVar('--primary'),
|
||||
foreground: hslVar('--primary-foreground'),
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: hslVar('--secondary'),
|
||||
foreground: hslVar('--secondary-foreground'),
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: hslVar('--destructive'),
|
||||
foreground: hslVar('--destructive-foreground'),
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: hslVar('--muted'),
|
||||
foreground: hslVar('--muted-foreground'),
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: hslVar('--accent'),
|
||||
foreground: hslVar('--accent-foreground'),
|
||||
},
|
||||
card: {
|
||||
DEFAULT: hslVar('--card'),
|
||||
foreground: hslVar('--card-foreground'),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue