import { ComponentPropsWithoutRef, ElementRef, forwardRef, ReactElement, ReactNode, useCallback, useMemo } from 'react'; import * as SelectPrimitive from '@radix-ui/react-select'; import { FaChevronDown, FaChevronUp, FaCheck } from 'react-icons/fa6'; import { cn } from '../libs'; const SelectRoot = SelectPrimitive.Root; const SelectValue = SelectPrimitive.Value; const SelectTrigger = forwardRef< ElementRef, ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( span]:line-clamp-1', className )} {...props} > {children} )); SelectTrigger.displayName = SelectPrimitive.Trigger.displayName; const SelectScrollUpButton = forwardRef< ElementRef, ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName; const SelectScrollDownButton = forwardRef< ElementRef, ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName; const SelectContent = forwardRef< ElementRef, ComponentPropsWithoutRef >(({ className, children, position = 'popper', ...props }, ref) => ( {children} )); SelectContent.displayName = SelectPrimitive.Content.displayName; const SelectLabel = forwardRef< ElementRef, ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); SelectLabel.displayName = SelectPrimitive.Label.displayName; const SelectItem = forwardRef< ElementRef, ComponentPropsWithoutRef >(({ className, children, ...props }, ref) => ( {children} )); SelectItem.displayName = SelectPrimitive.Item.displayName; const SelectSeparator = forwardRef< ElementRef, ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( )); SelectSeparator.displayName = SelectPrimitive.Separator.displayName; export interface SelectProps { placeholder?: string; values: T[]; value: T | undefined; getValueId?: (value: T) => string; getValueLabel?: (value: T) => ReactNode; onChange: (value: T) => void; fullWidth?: boolean; disabled?: boolean; contentClass?: string; customOption?: ReactNode; } const Component = ({ placeholder = 'Seleccionar...', value, values, getValueId = (val: any) => val.id, getValueLabel = (val: any) => val.name, onChange, fullWidth, customOption, disabled, contentClass, }: SelectProps) => { let id: string | undefined; if (value) { id = getValueId(value); } const valuesLookup = useMemo( () => values.reduce((acc, val) => { const id = getValueId(val); acc[id] = val; return acc; }, {} as Record), [getValueId, values] ); const onValueChange = useCallback( (id: string) => { const selectedValue = valuesLookup[id]; onChange(selectedValue); }, [onChange, valuesLookup] ); return ( {values.map((val, key) => { const itemId = getValueId(val); const label = getValueLabel(val); return ( {label} ); })} {customOption} ); }; import { memo } from '../utils'; export const Select = memo(Component) as (props: SelectProps) => ReactElement;