'use client' import { button } from './button' import { separator } from './separator' import * as SelectPrimitive from '@radix-ui/react-select' import { IconSelector, IconCheck, IconChevronDown, IconChevronUp } from '@tabler/icons-react' import { forwardRef } from 'react' import { tv } from 'tailwind-variants' import type { Merge } from 'type-fest' const select = tv({ slots: { trigger: button({ variant: 'outline' }).root({ className: 'justify-between' }), triggerIcon: button({ variant: 'outline' }).rightIcon({ className: 'text-fg-weaker' }), scrollUpButton: button({ variant: 'ghost', size: 'sm' }).root(), scrollUpButtonIcon: button({ variant: 'ghost', size: 'sm' }).icon(), scrollDownButton: button({ variant: 'ghost', size: 'sm' }).root(), scrollDownButtonIcon: button({ variant: 'ghost', size: 'sm' }).icon(), content: [ 'relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md', 'border bg-bg--contrast 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', ], viewport: 'p-1', label: 'px-2 py-1.5 text-sm font-semibold', item: button({ variant: 'ghost', size: 'sm' }).root({ className: [ 'flex justify-between w-full px-2 text-sm outline-none', 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50', ], }), itemIndicator: button({ variant: 'ghost', size: 'sm' }).rightIcon(), separator: separator({ variant: 'weak' }).root({ className: '-mx-1 my-1' }), }, variants: { position: { 'popper': { content: 'data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1', viewport: 'h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]', }, 'item-aligned': null, }, }, defaultVariants: { position: 'item-aligned', }, }) const SelectTrigger = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { iconProps?: React.ComponentProps } > >(({ iconProps, children, ...props }, ref) => { const { trigger, triggerIcon } = select() return ( {children} ) }) SelectTrigger.displayName = SelectPrimitive.Trigger.displayName const SelectScrollUpButton = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { iconProps?: React.ComponentProps } > >(({ iconProps, ...props }, ref) => { const { scrollUpButton, scrollUpButtonIcon } = select() return ( ) }) SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName const SelectScrollDownButton = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { iconProps?: React.ComponentProps } > >(({ iconProps, ...props }, ref) => { const { scrollDownButton, scrollDownButtonIcon } = select() return ( ) }) SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName const SelectContent = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { portalProps?: React.ComponentProps viewportProps?: React.ComponentProps scrollUpButtonProps?: React.ComponentProps scrollDownButtonProps?: React.ComponentProps } > >( ( { portalProps, viewportProps, scrollUpButtonProps, scrollDownButtonProps, children, position = 'popper', ...props }, ref, ) => { const { content, viewport } = select({ position }) return ( {children} ) }, ) SelectContent.displayName = SelectPrimitive.Content.displayName const SelectLabel = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >((props, ref) => { const { label } = select() return ( ) }) SelectLabel.displayName = SelectPrimitive.Label.displayName const SelectItem = forwardRef< React.ElementRef, Merge< React.ComponentPropsWithoutRef, { indicatorProps?: React.ComponentProps } > >(({ indicatorProps, children, ...props }, ref) => { const { item, itemIndicator } = select() return ( {children} ) }) SelectItem.displayName = SelectPrimitive.Item.displayName const SelectSeparator = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >((props, ref) => { const { separator } = select() return ( ) }) SelectSeparator.displayName = SelectPrimitive.Separator.displayName const Select = Object.assign(SelectPrimitive.Root, { Trigger: SelectTrigger, Value: SelectPrimitive.Value, Content: SelectContent, Group: SelectPrimitive.Group, Label: SelectLabel, Item: SelectItem, Separator: SelectSeparator, }) export default Select export { select, SelectPrimitive }