import { useState, useRef, useEffect } from 'react'; interface ComboBoxOption { value: string; label: string; } interface ComboBoxProps { value: string | number; onChange: (value: string) => void; options: ComboBoxOption[]; placeholder?: string; className?: string; } export function ComboBox({ value, onChange, options, placeholder, className }: ComboBoxProps) { const [isOpen, setIsOpen] = useState(false); const containerRef = useRef(null); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setIsOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const selectedOption = options.find((opt) => opt.value === String(value)); const displayText = selectedOption?.label || placeholder || '선택'; return (
setIsOpen(!isOpen)} > {displayText}
{isOpen && (
{options.map((option) => (
{ onChange(option.value); setIsOpen(false); }} className="text-label-2 cursor-pointer" style={{ padding: '8px 10px', color: option.value === String(value) ? 'var(--color-accent)' : 'var(--fg-sub)', background: option.value === String(value) ? 'rgba(6,182,212,0.1)' : 'transparent', transition: '0.1s', borderLeft: option.value === String(value) ? '2px solid var(--color-accent)' : '2px solid transparent', }} onMouseEnter={(e) => { if (option.value !== String(value)) { e.currentTarget.style.background = 'rgba(255,255,255,0.03)'; } }} onMouseLeave={(e) => { if (option.value !== String(value)) { e.currentTarget.style.background = 'transparent'; } }} > {option.label}
))}
)}
); }