Skip to content

select-menu

This requires the following theme to be installed:

select-menu

ts
import { buttonGroupVariant } from '@/ui/theme/button-group'

export default {
  slots: {
    base:
      'relative group rounded-md inline-flex items-center focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors',
    leading: 'absolute inset-y-0 start-0 flex items-center',
    leadingIcon: 'shrink-0 text-dimmed',
    leadingAvatar: 'shrink-0',
    leadingAvatarSize: '',
    trailing: 'absolute inset-y-0 end-0 flex items-center',
    trailingIcon: 'shrink-0 text-dimmed',
    value: 'truncate pointer-events-none',
    placeholder: 'truncate text-dimmed',
    arrow: 'fill-default',
    content: 'max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto w-(--reka-combobox-trigger-width)',
    viewport: 'divide-y divide-default scroll-py-1',
    group: 'p-1 isolate',
    empty: 'py-2 text-center text-sm text-muted',
    label: 'font-semibold text-highlighted',
    input: 'border-b border-default',
    focusScope: 'flex flex-col min-h-0',
    separator: '-mx-1 my-1 h-px bg-border',
    item: 'group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-md data-disabled:cursor-not-allowed data-disabled:opacity-75 text-default data-highlighted:not-data-disabled:text-highlighted data-highlighted:not-data-disabled:before:bg-elevated/50 transition-colors before:transition-colors',
    itemLeadingIcon: 'shrink-0 text-dimmed group-data-highlighted:not-group-data-disabled:text-default transition-colors',
    itemLeadingAvatar: 'shrink-0',
    itemLeadingAvatarSize: '',
    itemLeadingChip: 'shrink-0',
    itemLeadingChipSize: '',
    itemTrailing: 'ms-auto inline-flex gap-1.5 items-center',
    itemTrailingIcon: 'shrink-0',
    itemLabel: 'truncate',
  },
  variants: {
    ...buttonGroupVariant,
    variant: {
      outline: 'text-highlighted bg-default ring ring-inset ring-accented',
      soft: 'text-highlighted bg-elevated/50 hover:bg-elevated focus:bg-elevated disabled:bg-elevated/50',
      subtle: 'text-highlighted bg-elevated ring ring-inset ring-accented',
      ghost: 'text-highlighted bg-transparent hover:bg-elevated focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
      none: 'text-highlighted bg-transparent',
    },
    color: {
      primary: '',
      secondary: '',
      success: '',
      info: '',
      warning: '',
      error: '',
      neutral: '',
    },
    leading: {
      true: '',
    },
    trailing: {
      true: '',
    },
    loading: {
      true: '',
    },
    highlight: {
      true: '',
    },
    type: {
      file: 'file:me-1.5 file:font-medium file:text-muted file:outline-none',
    },
    size: {
      xs: {
        base: 'px-2 py-1 text-xs gap-1',
        leading: 'ps-2',
        trailing: 'pe-2',
        leadingIcon: 'size-4',
        leadingAvatarSize: '3xs',
        trailingIcon: 'size-4',
        label: 'p-1 text-[10px]/3 gap-1',
        item: 'p-1 text-xs gap-1',
        itemLeadingIcon: 'size-4',
        itemLeadingAvatarSize: '3xs',
        itemLeadingChip: 'size-4',
        itemLeadingChipSize: 'sm',
        itemTrailingIcon: 'size-4',
      },
      sm: {
        base: 'px-2.5 py-1.5 text-xs gap-1.5',
        leading: 'ps-2.5',
        trailing: 'pe-2.5',
        leadingIcon: 'size-4',
        leadingAvatarSize: '3xs',
        trailingIcon: 'size-4',
        label: 'p-1.5 text-[10px]/3 gap-1.5',
        item: 'p-1.5 text-xs gap-1.5',
        itemLeadingIcon: 'size-4',
        itemLeadingAvatarSize: '3xs',
        itemLeadingChip: 'size-4',
        itemLeadingChipSize: 'sm',
        itemTrailingIcon: 'size-4',
      },
      md: {
        base: 'px-2.5 py-1.5 text-sm gap-1.5',
        leading: 'ps-2.5',
        trailing: 'pe-2.5',
        leadingIcon: 'size-5',
        leadingAvatarSize: '2xs',
        trailingIcon: 'size-5',
        label: 'p-1.5 text-xs gap-1.5',
        item: 'p-1.5 text-sm gap-1.5',
        itemLeadingIcon: 'size-5',
        itemLeadingAvatarSize: '2xs',
        itemLeadingChip: 'size-5',
        itemLeadingChipSize: 'md',
        itemTrailingIcon: 'size-5',
      },
      lg: {
        base: 'px-3 py-2 text-sm gap-2',
        leading: 'ps-3',
        trailing: 'pe-3',
        leadingIcon: 'size-5',
        leadingAvatarSize: '2xs',
        trailingIcon: 'size-5',
        label: 'p-2 text-xs gap-2',
        item: 'p-2 text-sm gap-2',
        itemLeadingIcon: 'size-5',
        itemLeadingAvatarSize: '2xs',
        itemLeadingChip: 'size-5',
        itemLeadingChipSize: 'md',
        itemTrailingIcon: 'size-5',
      },
      xl: {
        base: 'px-3 py-2 text-base gap-2',
        leading: 'ps-3',
        trailing: 'pe-3',
        leadingIcon: 'size-6',
        leadingAvatarSize: 'xs',
        trailingIcon: 'size-6',
        label: 'p-2 text-sm gap-2',
        item: 'p-2 text-base gap-2',
        itemLeadingIcon: 'size-6',
        itemLeadingAvatarSize: 'xs',
        itemLeadingChip: 'size-6',
        itemLeadingChipSize: 'lg',
        itemTrailingIcon: 'size-6',
      },
    },
  },
  compoundVariants: [
    {
      color: 'primary' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary',
    },
    {
      color: 'primary',
      highlight: true,
      class: 'ring ring-inset ring-primary',
    } as const,
    {
      color: 'secondary' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-secondary',
    },
    {
      color: 'secondary',
      highlight: true,
      class: 'ring ring-inset ring-secondary',
    } as const,
    {
      color: 'success' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-success',
    },
    {
      color: 'success',
      highlight: true,
      class: 'ring ring-inset ring-success',
    } as const,
    {
      color: 'info' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-info',
    },
    {
      color: 'info',
      highlight: true,
      class: 'ring ring-inset ring-info',
    } as const,
    {
      color: 'warning' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-warning',
    },
    {
      color: 'warning',
      highlight: true,
      class: 'ring ring-inset ring-warning',
    } as const,
    {
      color: 'error' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-error',
    },
    {
      color: 'error',
      highlight: true,
      class: 'ring ring-inset ring-error',
    } as const,
    {
      color: 'neutral' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted',
    },
    {
      color: 'neutral',
      highlight: true,
      class: 'ring ring-inset ring-inverted',
    } as const,
    {
      leading: true,
      size: 'xs',
      class: 'ps-7',
    } as const,
    {
      leading: true,
      size: 'sm',
      class: 'ps-8',
    } as const,
    {
      leading: true,
      size: 'md',
      class: 'ps-9',
    } as const,
    {
      leading: true,
      size: 'lg',
      class: 'ps-10',
    } as const,
    {
      leading: true,
      size: 'xl',
      class: 'ps-11',
    } as const,
    {
      trailing: true,
      size: 'xs',
      class: 'pe-7',
    } as const,
    {
      trailing: true,
      size: 'sm',
      class: 'pe-8',
    } as const,
    {
      trailing: true,
      size: 'md',
      class: 'pe-9',
    } as const,
    {
      trailing: true,
      size: 'lg',
      class: 'pe-10',
    } as const,
    {
      trailing: true,
      size: 'xl',
      class: 'pe-11',
    } as const,
    {
      loading: true,
      leading: true,
      class: {
        leadingIcon: 'animate-spin',
      },
    } as const,
    {
      loading: true,
      leading: false,
      trailing: true,
      class: {
        trailingIcon: 'animate-spin',
      },
    } as const,
  ],
  defaultVariants: {
    size: 'md',
    color: 'primary',
    variant: 'outline',
  } as const,
}
ts
import { buttonGroupVariant } from '@/UI/Theme/button-group'

export default {
  slots: {
    base:
      'relative group rounded-md inline-flex items-center focus:outline-none disabled:cursor-not-allowed disabled:opacity-75 transition-colors',
    leading: 'absolute inset-y-0 start-0 flex items-center',
    leadingIcon: 'shrink-0 text-dimmed',
    leadingAvatar: 'shrink-0',
    leadingAvatarSize: '',
    trailing: 'absolute inset-y-0 end-0 flex items-center',
    trailingIcon: 'shrink-0 text-dimmed',
    value: 'truncate pointer-events-none',
    placeholder: 'truncate text-dimmed',
    arrow: 'fill-default',
    content: 'max-h-60 w-(--reka-select-trigger-width) bg-default shadow-lg rounded-md ring ring-default overflow-hidden data-[state=open]:animate-[scale-in_100ms_ease-out] data-[state=closed]:animate-[scale-out_100ms_ease-in] origin-(--reka-select-content-transform-origin) pointer-events-auto w-(--reka-combobox-trigger-width)',
    viewport: 'divide-y divide-default scroll-py-1',
    group: 'p-1 isolate',
    empty: 'py-2 text-center text-sm text-muted',
    label: 'font-semibold text-highlighted',
    input: 'border-b border-default',
    focusScope: 'flex flex-col min-h-0',
    separator: '-mx-1 my-1 h-px bg-border',
    item: 'group relative w-full flex items-center select-none outline-none before:absolute before:z-[-1] before:inset-px before:rounded-md data-disabled:cursor-not-allowed data-disabled:opacity-75 text-default data-highlighted:not-data-disabled:text-highlighted data-highlighted:not-data-disabled:before:bg-elevated/50 transition-colors before:transition-colors',
    itemLeadingIcon: 'shrink-0 text-dimmed group-data-highlighted:not-group-data-disabled:text-default transition-colors',
    itemLeadingAvatar: 'shrink-0',
    itemLeadingAvatarSize: '',
    itemLeadingChip: 'shrink-0',
    itemLeadingChipSize: '',
    itemTrailing: 'ms-auto inline-flex gap-1.5 items-center',
    itemTrailingIcon: 'shrink-0',
    itemLabel: 'truncate',
  },
  variants: {
    ...buttonGroupVariant,
    variant: {
      outline: 'text-highlighted bg-default ring ring-inset ring-accented',
      soft: 'text-highlighted bg-elevated/50 hover:bg-elevated focus:bg-elevated disabled:bg-elevated/50',
      subtle: 'text-highlighted bg-elevated ring ring-inset ring-accented',
      ghost: 'text-highlighted bg-transparent hover:bg-elevated focus:bg-elevated disabled:bg-transparent dark:disabled:bg-transparent',
      none: 'text-highlighted bg-transparent',
    },
    color: {
      primary: '',
      secondary: '',
      success: '',
      info: '',
      warning: '',
      error: '',
      neutral: '',
    },
    leading: {
      true: '',
    },
    trailing: {
      true: '',
    },
    loading: {
      true: '',
    },
    highlight: {
      true: '',
    },
    type: {
      file: 'file:me-1.5 file:font-medium file:text-muted file:outline-none',
    },
    size: {
      xs: {
        base: 'px-2 py-1 text-xs gap-1',
        leading: 'ps-2',
        trailing: 'pe-2',
        leadingIcon: 'size-4',
        leadingAvatarSize: '3xs',
        trailingIcon: 'size-4',
        label: 'p-1 text-[10px]/3 gap-1',
        item: 'p-1 text-xs gap-1',
        itemLeadingIcon: 'size-4',
        itemLeadingAvatarSize: '3xs',
        itemLeadingChip: 'size-4',
        itemLeadingChipSize: 'sm',
        itemTrailingIcon: 'size-4',
      },
      sm: {
        base: 'px-2.5 py-1.5 text-xs gap-1.5',
        leading: 'ps-2.5',
        trailing: 'pe-2.5',
        leadingIcon: 'size-4',
        leadingAvatarSize: '3xs',
        trailingIcon: 'size-4',
        label: 'p-1.5 text-[10px]/3 gap-1.5',
        item: 'p-1.5 text-xs gap-1.5',
        itemLeadingIcon: 'size-4',
        itemLeadingAvatarSize: '3xs',
        itemLeadingChip: 'size-4',
        itemLeadingChipSize: 'sm',
        itemTrailingIcon: 'size-4',
      },
      md: {
        base: 'px-2.5 py-1.5 text-sm gap-1.5',
        leading: 'ps-2.5',
        trailing: 'pe-2.5',
        leadingIcon: 'size-5',
        leadingAvatarSize: '2xs',
        trailingIcon: 'size-5',
        label: 'p-1.5 text-xs gap-1.5',
        item: 'p-1.5 text-sm gap-1.5',
        itemLeadingIcon: 'size-5',
        itemLeadingAvatarSize: '2xs',
        itemLeadingChip: 'size-5',
        itemLeadingChipSize: 'md',
        itemTrailingIcon: 'size-5',
      },
      lg: {
        base: 'px-3 py-2 text-sm gap-2',
        leading: 'ps-3',
        trailing: 'pe-3',
        leadingIcon: 'size-5',
        leadingAvatarSize: '2xs',
        trailingIcon: 'size-5',
        label: 'p-2 text-xs gap-2',
        item: 'p-2 text-sm gap-2',
        itemLeadingIcon: 'size-5',
        itemLeadingAvatarSize: '2xs',
        itemLeadingChip: 'size-5',
        itemLeadingChipSize: 'md',
        itemTrailingIcon: 'size-5',
      },
      xl: {
        base: 'px-3 py-2 text-base gap-2',
        leading: 'ps-3',
        trailing: 'pe-3',
        leadingIcon: 'size-6',
        leadingAvatarSize: 'xs',
        trailingIcon: 'size-6',
        label: 'p-2 text-sm gap-2',
        item: 'p-2 text-base gap-2',
        itemLeadingIcon: 'size-6',
        itemLeadingAvatarSize: 'xs',
        itemLeadingChip: 'size-6',
        itemLeadingChipSize: 'lg',
        itemTrailingIcon: 'size-6',
      },
    },
  },
  compoundVariants: [
    {
      color: 'primary' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-primary',
    },
    {
      color: 'primary',
      highlight: true,
      class: 'ring ring-inset ring-primary',
    } as const,
    {
      color: 'secondary' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-secondary',
    },
    {
      color: 'secondary',
      highlight: true,
      class: 'ring ring-inset ring-secondary',
    } as const,
    {
      color: 'success' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-success',
    },
    {
      color: 'success',
      highlight: true,
      class: 'ring ring-inset ring-success',
    } as const,
    {
      color: 'info' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-info',
    },
    {
      color: 'info',
      highlight: true,
      class: 'ring ring-inset ring-info',
    } as const,
    {
      color: 'warning' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-warning',
    },
    {
      color: 'warning',
      highlight: true,
      class: 'ring ring-inset ring-warning',
    } as const,
    {
      color: 'error' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-error',
    },
    {
      color: 'error',
      highlight: true,
      class: 'ring ring-inset ring-error',
    } as const,
    {
      color: 'neutral' as const,
      variant: ['outline' as const, 'subtle' as const],
      class: 'focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-inverted',
    },
    {
      color: 'neutral',
      highlight: true,
      class: 'ring ring-inset ring-inverted',
    } as const,
    {
      leading: true,
      size: 'xs',
      class: 'ps-7',
    } as const,
    {
      leading: true,
      size: 'sm',
      class: 'ps-8',
    } as const,
    {
      leading: true,
      size: 'md',
      class: 'ps-9',
    } as const,
    {
      leading: true,
      size: 'lg',
      class: 'ps-10',
    } as const,
    {
      leading: true,
      size: 'xl',
      class: 'ps-11',
    } as const,
    {
      trailing: true,
      size: 'xs',
      class: 'pe-7',
    } as const,
    {
      trailing: true,
      size: 'sm',
      class: 'pe-8',
    } as const,
    {
      trailing: true,
      size: 'md',
      class: 'pe-9',
    } as const,
    {
      trailing: true,
      size: 'lg',
      class: 'pe-10',
    } as const,
    {
      trailing: true,
      size: 'xl',
      class: 'pe-11',
    } as const,
    {
      loading: true,
      leading: true,
      class: {
        leadingIcon: 'animate-spin',
      },
    } as const,
    {
      loading: true,
      leading: false,
      trailing: true,
      class: {
        trailingIcon: 'animate-spin',
      },
    } as const,
  ],
  defaultVariants: {
    size: 'md',
    color: 'primary',
    variant: 'outline',
  } as const,
}