import React, { useState, useEffect, useRef } from "react"; import { createPortal } from "react-dom"; interface DropdownProps { header: string; options: string[]; onSelect: (option: string) => void; search?: boolean; onClick?: () => void; onChange?: () => void; } const RegularDropDown: React.FC = ({ header, options, onSelect, search = true, }) => { const [isOpen, setIsOpen] = useState(false); const [selectedOption, setSelectedOption] = useState(null); const [searchTerm, setSearchTerm] = useState(""); const [filteredOptions, setFilteredOptions] = useState(options); const dropdownRef = useRef(null); const [position, setPosition] = useState<{ top: number; left: number; width: number; }>({ top: 0, left: 0, width: 0, }); // Reset when closed useEffect(() => { if (!isOpen) { setSelectedOption(null); setSearchTerm(""); setFilteredOptions(options); } }, [isOpen, options]); // Reset when header changes useEffect(() => { setSelectedOption(null); setSearchTerm(""); setFilteredOptions(options); }, [header, options]); // Close if clicked outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) ) { setIsOpen(false); } }; document.addEventListener("click", handleClickOutside); return () => document.removeEventListener("click", handleClickOutside); }, []); // Recalculate position when opening useEffect(() => { if (isOpen && dropdownRef.current) { const rect = dropdownRef.current.getBoundingClientRect(); setPosition({ top: rect.bottom + window.scrollY, left: rect.left + window.scrollX, width: rect.width, }); } }, [isOpen]); const toggleDropdown = () => setIsOpen((prev) => !prev); const handleOptionClick = (option: string) => { setSelectedOption(option); onSelect(option); setIsOpen(false); }; const handleSearchChange = (event: React.ChangeEvent) => { const term = event.target.value; setSearchTerm(term); setFilteredOptions( options.filter((option) => option.toLowerCase().includes(term.toLowerCase()) ) ); }; return (
{ setIsOpen(false); }} > {/* Header */}
{selectedOption || header}
{/* Options rendered in portal */} {isOpen && createPortal(
{search && (
)} {filteredOptions.length > 0 ? ( filteredOptions.map((option, index) => (
handleOptionClick(option)} title={option} > {option}
)) ) : (
No options found
)}
, document.body )}
); }; export default RegularDropDown;