import React, { forwardRef, useId } from 'react'; import { cn } from '../../utils/cn'; export interface SelectOption { label: string; value: string | number; disabled?: boolean; } export interface SelectProps extends Omit, 'size'> { /** * Label text for the select */ label?: React.ReactNode; /** * Array of select options */ options?: SelectOption[]; /** * Error message or error state */ error?: boolean | string; /** * Help text displayed below the select */ helpText?: React.ReactNode; /** * Size variant * @default 'md' */ size?: 'sm' | 'md' | 'lg'; /** * Visual style variant * @default 'default' */ variant?: 'default' | 'outline' | 'filled' | 'unstyled'; /** * Make the select take the full width of its container * @default false */ fullWidth?: boolean; /** * Custom class for the container */ containerClassName?: string; /** * Custom class for the label */ labelClassName?: string; /** * Placeholder text (shown as first disabled option) */ placeholder?: string; /** * Icon to display at the end of the select */ icon?: React.ReactNode; /** * Whether the select is in a loading state * @default false */ isLoading?: boolean; /** * Groups options by key */ groups?: { [key: string]: SelectOption[] }; } export const Select = forwardRef( ( { id, label, options = [], error, helpText, size = 'md', variant = 'default', className, containerClassName, labelClassName, fullWidth = false, disabled, placeholder, icon, isLoading = false, groups, required, ...props }, ref ) => { const generatedId = useId(); const selectId = id || `select-${generatedId}`; // Default chevron icon const defaultIcon = ( ); return (
{label && ( )}
{/* Select icon or loading indicator */}
{isLoading ? ( ) : ( icon || defaultIcon )}
{error && typeof error === 'string' && (
{error}
)} {helpText && !error && (
{helpText}
)}
); } ); Select.displayName = 'Select'; export default Select;