diff --git a/.changeset/huge-friends-flash.md b/.changeset/huge-friends-flash.md new file mode 100644 index 00000000..388510c9 --- /dev/null +++ b/.changeset/huge-friends-flash.md @@ -0,0 +1,12 @@ +--- +'@genseki/ui': patch +--- + +[FIX] General UI fixes + +- Consistent disabled state tokens across form primitives (Input, Textarea, Select, Switch, RadioGroup, Checkbox, Toggle, Tabs, Slider, Command, ColorPicker, Calendar) +- InputGroup auto-detects disabled descendant input/textarea and aria-disabled, so wrappers around RichTextEditor and fieldset-disabled forms render the disabled chrome consistently +- InputGroup wrapping a direct `` is now exactly h-18 to match sibling Buttons (was 74px due to wrapper border on top of inner Input h-18) +- Filter popover: trigger keeps a focus ring while the popover is open, and the popover content aligns to the trigger's end edge +- Filter popover: highlight the currently active column in the left list +- Filter popover: disable "Reset All" when no filter is selected diff --git a/packages/ui/src/components/primitives/calendar.tsx b/packages/ui/src/components/primitives/calendar.tsx index 164adc39..c69de8cb 100644 --- a/packages/ui/src/components/primitives/calendar.tsx +++ b/packages/ui/src/components/primitives/calendar.tsx @@ -137,11 +137,7 @@ function Calendar({ defaultClassNames.outside, classNames?.outside ), - disabled: cn( - 'text-muted-foreground opacity-50', - defaultClassNames.disabled, - classNames?.disabled - ), + disabled: cn('text-text-disabled', defaultClassNames.disabled, classNames?.disabled), hidden: cn('invisible', defaultClassNames.hidden, classNames?.hidden), }} components={{ diff --git a/packages/ui/src/components/primitives/color-picker.tsx b/packages/ui/src/components/primitives/color-picker.tsx index f269fc02..57991839 100644 --- a/packages/ui/src/components/primitives/color-picker.tsx +++ b/packages/ui/src/components/primitives/color-picker.tsx @@ -214,7 +214,7 @@ export const ColorPickerHue = ({ className, ...props }: ColorPickerHueProps) => - + ) } @@ -241,7 +241,7 @@ export const ColorPickerAlpha = ({ className, ...props }: ColorPickerAlphaProps)
- + ) } diff --git a/packages/ui/src/components/primitives/command.tsx b/packages/ui/src/components/primitives/command.tsx index 0bff1a00..93f38b20 100644 --- a/packages/ui/src/components/primitives/command.tsx +++ b/packages/ui/src/components/primitives/command.tsx @@ -63,7 +63,7 @@ function CommandInput({ ({ options, onChange, classNames (acc, [_, options]) => acc + options.filter((option) => option.isSelected).length, 0 ) + const internalTotalSelected = Object.values(internalOptions).reduce( + (acc, opts) => acc + opts.filter((option) => option.isSelected).length, + 0 + ) return ( - - +
({ options, onChange, classNames {columns.map((column) => (
  • setSelectedColumn(column)} > @@ -155,7 +169,7 @@ export function Filter({ options, onChange, classNames
  • - diff --git a/packages/ui/src/components/primitives/input-group.tsx b/packages/ui/src/components/primitives/input-group.tsx index 29d27fe1..0811ce66 100644 --- a/packages/ui/src/components/primitives/input-group.tsx +++ b/packages/ui/src/components/primitives/input-group.tsx @@ -31,7 +31,12 @@ function InputGroup({ role="group" className={cn( 'group/input-group data-disabled:bg-surface-primary-disabled data-disabled:border-border-primary bg-background border-input dark:bg-input/30 relative flex items-center rounded-md border shadow-xs transition-[color,box-shadow] outline-none', + 'has-[input:disabled]:bg-surface-primary-disabled has-[input:disabled]:border-border-disabled has-[input:disabled]:cursor-not-allowed', + 'has-[textarea:disabled]:bg-surface-primary-disabled has-[textarea:disabled]:border-border-disabled has-[textarea:disabled]:cursor-not-allowed', + 'aria-disabled:bg-surface-primary-disabled aria-disabled:border-border-disabled aria-disabled:cursor-not-allowed', + 'aria-disabled:[&_[data-slot=input-group-control]]:!bg-transparent aria-disabled:[&_[data-slot=input-group-control]]:!text-text-disabled', 'h-auto min-w-0 has-[>textarea]:h-auto', + 'has-[>input]:h-18 has-[>input]:[&_[data-slot=input-group-control]]:h-full', // Variants based on alignment. 'has-[>[data-align=inline-start]]:[&>input]:pl-4', diff --git a/packages/ui/src/components/primitives/input.tsx b/packages/ui/src/components/primitives/input.tsx index 1e3ee3b6..a726b74d 100644 --- a/packages/ui/src/components/primitives/input.tsx +++ b/packages/ui/src/components/primitives/input.tsx @@ -12,7 +12,7 @@ function Input({ type={type} className={cn( 'bg-background file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-18 w-full min-w-0 rounded-md border px-6 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:bg-transparent file:rounded-sm file:px-4 file:h-full file:border-0 file:text-sm file:font-medium', - 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:text-text-disabled disabled:border-border-primary disabled:placeholder:text-text-disabled', + 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-surface-disabled disabled:text-text-disabled disabled:border-border-disabled disabled:placeholder:text-text-disabled', 'focus-visible:border-ring focus-visible:ring-ring focus-visible:ring-[2px]', 'aria-invalid:ring-destructive dark:aria-invalid:ring-destructive aria-invalid:border-destructive', className diff --git a/packages/ui/src/components/primitives/radio-group.tsx b/packages/ui/src/components/primitives/radio-group.tsx index 15ae5d07..8f933870 100644 --- a/packages/ui/src/components/primitives/radio-group.tsx +++ b/packages/ui/src/components/primitives/radio-group.tsx @@ -28,7 +28,7 @@ function RadioGroupItem({ ))} diff --git a/packages/ui/src/components/primitives/switch.tsx b/packages/ui/src/components/primitives/switch.tsx index dbf50d63..fe6e819d 100644 --- a/packages/ui/src/components/primitives/switch.tsx +++ b/packages/ui/src/components/primitives/switch.tsx @@ -11,7 +11,7 @@ function Switch({ className, ...props }: React.ComponentProps }>( ) const tabVariants = cva<{ variant: Record }>( - "inline-flex flex-1 items-center justify-center text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-8", + "inline-flex flex-1 items-center justify-center text-sm font-medium whitespace-nowrap transition-[color,box-shadow] outline-none disabled:pointer-events-none disabled:text-text-disabled [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-8", { variants: { variant: { diff --git a/packages/ui/src/components/primitives/textarea.tsx b/packages/ui/src/components/primitives/textarea.tsx index e9188a94..1d07a17f 100644 --- a/packages/ui/src/components/primitives/textarea.tsx +++ b/packages/ui/src/components/primitives/textarea.tsx @@ -8,7 +8,7 @@ function Textarea({ className, ...props }: React.ComponentProps<'textarea'>) { data-slot="textarea" className={cn( 'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring aria-invalid:ring-destructive dark:aria-invalid:ring-destructive aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-32 w-full rounded-md border bg-transparent px-7 py-6 text-base shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[2px]', - 'disabled:pointer-events-none disabled::cursor-not-allowed disabled:text-text-disabled disabled:border-border-primary disabled:placeholder:text-text-disabled', + 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-surface-disabled disabled:text-text-disabled disabled:border-border-disabled disabled:placeholder:text-text-disabled', className )} {...props} diff --git a/packages/ui/src/components/primitives/toggle.tsx b/packages/ui/src/components/primitives/toggle.tsx index d19cc3ee..2250911e 100644 --- a/packages/ui/src/components/primitives/toggle.tsx +++ b/packages/ui/src/components/primitives/toggle.tsx @@ -8,7 +8,7 @@ import { cva, type VariantProps } from 'class-variance-authority' import { cn } from '../../utils/cn' const toggleVariants = cva( - "inline-flex items-center justify-center gap-4 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-8 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[2px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive aria-invalid:border-destructive whitespace-nowrap", + "inline-flex items-center justify-center gap-4 rounded-md text-sm font-medium hover:bg-muted hover:text-muted-foreground disabled:pointer-events-none disabled:bg-surface-disabled disabled:text-text-disabled data-[state=on]:bg-accent data-[state=on]:text-accent-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-8 [&_svg]:shrink-0 focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[2px] outline-none transition-[color,box-shadow] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive aria-invalid:border-destructive whitespace-nowrap", { variants: { variant: {