import React, { useState, useRef, useEffect } from 'react'; import ReactDOM from 'react-dom'; // Import ReactDOM import { CaretDown, Check } from '@phosphor-icons/react'; import { motion } from 'framer-motion'; const CustomDropdown = ({ options, value, onChange, icon: Icon, label, className = '', variant = 'default', fullWidth = false, }) => { const [isOpen, setIsOpen] = useState(false); const dropdownRef = useRef(null); // Ref for the button const menuRef = useRef(null); // Ref for the dropdown menu const [dropdownMenuPosition, setDropdownMenuPosition] = useState({}); const isBrutalist = variant === 'brutalist'; const isPaper = variant === 'paper'; useEffect(() => { const handleClickOutside = (event) => { const isClickInsideButton = dropdownRef.current && dropdownRef.current.contains(event.target); const isClickInsideMenu = menuRef.current && menuRef.current.contains(event.target); if (!isClickInsideButton && !isClickInsideMenu) { setIsOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, []); useEffect(() => { if (isOpen && dropdownRef.current) { const rect = dropdownRef.current.getBoundingClientRect(); setDropdownMenuPosition({ top: rect.bottom + window.scrollY + 8, // 8px for mt-2 left: rect.left + window.scrollX, width: rect.width, }); } }, [isOpen]); const handleSelect = (optionValue) => { onChange(optionValue); setIsOpen(false); }; const selectedOption = options.find((opt) => opt.value === value); // Render the dropdown menu (options list) using a Portal const renderDropdownMenu = () => { if (!isOpen) return null; return ReactDOM.createPortal(
{options.map((option) => ( ))}
, document.body, ); }; return (
{renderDropdownMenu()}
); }; export default CustomDropdown;