import * as React from 'react'; import * as SelectPrimitive from '@radix-ui/react-select'; import { tv, type VariantProps } from 'tailwind-variants'; import { assignRef } from '../../hooks/useMergedRef'; import { cn } from '../../utils/cn'; import { radiusVariant } from '../../utils/variant-common'; import { CheckIcon, ChevronDownIcon, ChevronUpIcon, CloseIcon } from '../icons'; const SelectProvider = SelectPrimitive.Root; const SelectGroup = SelectPrimitive.Group; const SelectValue = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >((props, ref) => { return (
); }); export const selectTriggerVariants = tv({ base: [ 'flex items-center justify-between text-foreground data-[placeholder]:text-muted [&>span]:line-clamp-1', 'border outline-none ', 'focus:outline-none outline-none group', 'disabled:cursor-not-allowed disabled:shadow-xs disabled:bg-background-disabled disabled:text-disabled', ], variants: { variant: { default: 'bg-input border-input-border data-[state=open]:shadow-brand-xs data-[state=open]:border-brand-300', background: 'bg-background border-input-border data-[state=open]:shadow-brand-xs data-[state=open]:border-brand-300', destructive: 'border-error-300 bg-input data-[state=open]:shadow-error-xs data-[state=open]:border-error-300', }, size: { none: 'min-h-0', xs: 'h-8 px-3 py-1', sm: 'h-10 px-3 py-2', md: 'h-11 px-3.5 py-2.5', }, radius: radiusVariant, fullWidth: { true: 'w-full', false: 'w-auto', }, }, defaultVariants: { size: 'md', radius: 'xs', variant: 'default', fullWidth: true, }, }); export interface SelectTriggerProps extends React.ComponentPropsWithoutRef, VariantProps {} const SelectTrigger = React.forwardRef, SelectTriggerProps>( ({ className, variant, size, fullWidth, children, ...props }, ref) => ( {children} ) ); SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; const SelectScrollUpButton = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName; const SelectScrollDownButton = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName; interface SelectContentProps extends React.ComponentPropsWithoutRef { withScrollAction?: boolean; withScrollbar?: boolean; } const SelectContent = React.forwardRef, SelectContentProps>( ({ className, withScrollAction = true, withScrollbar, children, position = 'popper', ...props }, forwardedRef) => { const selectRef = React.useRef(null); React.useEffect(() => { if (withScrollbar) { setTimeout(() => { const style = selectRef.current?.querySelector('style'); if (!style) return; style.innerHTML = ''; }, 1500); } return () => { // eslint-disable-next-line react-hooks/exhaustive-deps selectRef.current?.removeEventListener('touchend', (e) => e.cancelable && e.preventDefault()); }; }, [withScrollbar]); return ( { if (!ref) return; assignRef(forwardedRef, ref); assignRef(selectRef, ref); selectRef.current?.addEventListener('touchend', (e) => e.cancelable && e.preventDefault()); }} className={cn( 'bg-background 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 border-border-secondary text-foreground z-100 relative mt-1 min-w-[8rem] overflow-hidden rounded-md border shadow-lg', 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', className )} position={position} {...props} > {withScrollAction ? : null} {children} {withScrollAction ? : null} ); } ); SelectContent.displayName = SelectPrimitive.Content.displayName; const SelectLabel = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); SelectLabel.displayName = SelectPrimitive.Label.displayName; const SelectItem = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} )); SelectItem.displayName = SelectPrimitive.Item.displayName; const SelectSeparator = React.forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); SelectSeparator.displayName = SelectPrimitive.Separator.displayName; export { SelectContent, SelectGroup, SelectItem, SelectLabel, SelectProvider, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, };