import * as React from 'react'; // 创建Select上下文 const SelectContext = React.createContext<{ value: string; setValue: (value: string) => void; open: boolean; setOpen: (open: boolean) => void; } | null>(null); // Select组件接口 export interface SelectProps { defaultValue?: string; value?: string; onValueChange?: (value: string) => void; children: React.ReactNode; className?: string; } // SelectTrigger组件接口 export interface SelectTriggerProps { children: React.ReactNode; className?: string; } // SelectValue组件接口 export interface SelectValueProps { placeholder?: string; children?: React.ReactNode; } // SelectContent组件接口 export interface SelectContentProps { children: React.ReactNode; className?: string; } // SelectItem组件接口 export interface SelectItemProps { value: string; children: React.ReactNode; className?: string; } /** * Select组件 - 管理选择器的状态 */ export const Select: React.FC = ({ defaultValue = '', value: valueProp, onValueChange, children, className = '' }) => { const [valueState, setValueState] = React.useState(defaultValue); const [open, setOpen] = React.useState(false); const value = valueProp !== undefined ? valueProp : valueState; const setValue = valueProp !== undefined && onValueChange ? onValueChange : setValueState; // 点击外部关闭下拉菜单 React.useEffect(() => { if (open) { const handleClickOutside = (event: MouseEvent) => { const target = event.target as HTMLElement; if (!target.closest(`.${className}`) && !target.closest('.select-trigger')) { setOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; } }, [open, className]); return (
{children}
); }; /** * SelectTrigger组件 - 选择器的触发器按钮 */ export const SelectTrigger: React.FC = ({ children, className = '' }) => { const context = React.useContext(SelectContext); if (!context) { throw new Error('SelectTrigger must be used within a Select component'); } const handleClick = () => { context.setOpen(!context.open); }; return ( ); }; /** * SelectValue组件 - 显示当前选中的值或占位符 */ export const SelectValue: React.FC = ({ placeholder, children }) => { const context = React.useContext(SelectContext); if (!context) { throw new Error('SelectValue must be used within a Select component'); } if (context.value && children) { return {children}; } return placeholder ? ( {placeholder} ) : null; }; /** * SelectContent组件 - 包含选项的下拉菜单 */ export const SelectContent: React.FC = ({ children, className = '' }) => { const context = React.useContext(SelectContext); if (!context) { throw new Error('SelectContent must be used within a Select component'); } if (!context.open) { return null; } return (
{children}
); }; /** * SelectItem组件 - 选择器中的单个选项 */ export const SelectItem: React.FC = ({ value, children, className = '' }) => { const context = React.useContext(SelectContext); if (!context) { throw new Error('SelectItem must be used within a Select component'); } const isSelected = context.value === value; const handleClick = () => { context.setValue(value); context.setOpen(false); }; return ( ); }; export default Select;