import { cn } from "@/core/lib/utils"; import { ChevronDown, Search } from "lucide-react"; import { forwardRef, type InputHTMLAttributes, useEffect, useRef, useState, } from "react"; type Option = { value: string; label: string }; type BaseDropdownProps = Omit< InputHTMLAttributes, "onChange" > & { label?: string; error?: string; variant?: "primary" | "error"; options: Option[]; placeholder?: string; value?: string; onChange?: (value: string) => void; onInputChange?: (inputValue: string) => void; }; export const BaseDropdown = forwardRef( ( { label, error, variant = "primary", options, placeholder = "انتخاب کنید", className, value, onChange, disabled, onInputChange, }, ref ) => { const [isOpen, setIsOpen] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const dropdownRef = useRef(null); const inputRef = useRef(null); const selectedOption = options.find((option) => option.value === value); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) ) { setIsOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, []); useEffect(() => { if (isOpen) { setTimeout(() => inputRef.current?.focus(), 0); } }, [isOpen]); const handleSelect = (option: Option) => { if (onChange) { onChange(option.value); } setIsOpen(false); setSearchQuery(""); }; const filteredOptions = options.filter((option) => option.label.toLowerCase().includes(searchQuery.toLowerCase()) ); const hasError = !!error; return (
{label && ( )}
{isOpen && (
{ setSearchQuery(e.target.value); if (onInputChange) { onInputChange(e.target.value); } }} />
    {filteredOptions.map((option) => (
  • handleSelect(option)} className="cursor-pointer px-4 py-2 text-sm text-gray-700 hover:bg-gray-100" > {option.label}
  • ))}
)}
{hasError && (

{error}

)}
); } ); BaseDropdown.displayName = "BaseDropdown";