Select (components/ui/select.tsx)¶
Overview¶
A customizable select component built with Radix UI that provides accessible dropdown selection functionality.
Features¶
- Option groups
- Placeholder support
- Custom triggers
- Search functionality
- Keyboard navigation
- Focus management
- Animation effects
- Accessibility support
- Responsive design
- Error state handling
Dependencies¶
import * as React from 'react'
import * as SelectPrimitive from '@radix-ui/react-select'
import { Check, ChevronDown } from 'lucide-react'
import { cn } from '@/lib/utils'
Props¶
interface SelectProps extends SelectPrimitive.SelectProps {
placeholder?: string;
error?: boolean;
className?: string;
children: ReactNode;
}
interface SelectTriggerProps extends SelectPrimitive.SelectTriggerProps {
className?: string;
children: ReactNode;
}
interface SelectContentProps extends SelectPrimitive.SelectContentProps {
className?: string;
children: ReactNode;
}
interface SelectItemProps extends SelectPrimitive.SelectItemProps {
className?: string;
children: ReactNode;
}
interface SelectGroupProps extends SelectPrimitive.SelectGroupProps {
className?: string;
children: ReactNode;
}
Implementation¶
State Management¶
const [open, setOpen] = useState(false);
const [value, setValue] = useState('');
const handleValueChange = (value: string) => {
setValue(value);
onChange?.(value);
};
const handleOpenChange = (open: boolean) => {
setOpen(open);
onOpenChange?.(open);
};
Methods¶
const handleKeyDown = (event: React.KeyboardEvent) => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();
setOpen(true);
}
};
const handleBlur = () => {
setOpen(false);
};
Unique Functionality¶
- Option group handling
- Value management
- Focus control
- Animation states
- Position calculation
- Error state handling
HTML Structure¶
<SelectPrimitive.Root
open={open}
onOpenChange={handleOpenChange}
value={value}
onValueChange={handleValueChange}
>
<SelectPrimitive.Trigger
className={cn(
"flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
error && "border-destructive focus:ring-destructive",
className
)}
onKeyDown={handleKeyDown}
onBlur={handleBlur}
>
<SelectPrimitive.Value placeholder={placeholder} />
<SelectPrimitive.Icon>
<ChevronDown className="h-4 w-4 opacity-50" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
<SelectPrimitive.Portal>
<SelectPrimitive.Content
className={cn(
"relative z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md animate-in fade-in-80",
position === "popper" && "translate-y-1",
className
)}
position={position}
{...props}
>
<SelectPrimitive.Viewport className="p-1">
{children}
</SelectPrimitive.Viewport>
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
</SelectPrimitive.Root>
API Integration¶
No direct API integration required.
Components Used¶
- Select
- SelectGroup
- SelectValue
- SelectTrigger
- SelectContent
- SelectLabel
- SelectItem
- SelectSeparator
Notes¶
- Built on Radix UI primitives
- Handles keyboard navigation
- Manages focus states
- Supports option groups
- Provides custom triggers
- Maintains accessibility features
- Uses React Portal for rendering