import React, { useState, useRef, useEffect } from 'react'; import { createPortal } from 'react-dom'; import { ChevronDownIcon } from '@heroicons/react/24/outline'; interface Option { value: string | number; label: string; } interface RecurrenceSelectDropdownProps { value: string | number; onChange: (value: string | number) => void; options: Option[]; placeholder?: string; disabled?: boolean; className?: string; } const RecurrenceSelectDropdown: React.FC = ({ value, onChange, options, placeholder = 'Select option', disabled = false, className = '', }) => { const [isOpen, setIsOpen] = useState(false); const [position, setPosition] = useState({ top: 0, left: 0, width: 0, openUpward: false, }); const dropdownRef = useRef(null); const menuRef = useRef(null); const handleToggle = () => { if (disabled) return; if (!isOpen && dropdownRef.current) { const rect = dropdownRef.current.getBoundingClientRect(); const spaceBelow = window.innerHeight - rect.bottom; const spaceAbove = rect.top; const menuHeight = Math.min(options.length * 40 + 16, 200); // Max height with scroll const openUpward = spaceAbove > spaceBelow && spaceBelow < menuHeight; setPosition({ top: openUpward ? rect.top - menuHeight - 8 : rect.bottom + 8, left: rect.left, width: rect.width, openUpward, }); } setIsOpen(!isOpen); }; const handleClickOutside = (event: MouseEvent) => { if ( dropdownRef.current && !dropdownRef.current.contains(event.target as Node) && menuRef.current && !menuRef.current.contains(event.target as Node) ) { setIsOpen(false); } }; const handleSelect = (selectedValue: string | number) => { try { onChange(selectedValue); setIsOpen(false); } catch (error) { console.error('Error in dropdown selection:', error); setIsOpen(false); } }; useEffect(() => { if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } else { document.removeEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); const selectedOption = options.find((option) => option.value === value); return (
{isOpen && createPortal(
e.stopPropagation()} > {options.map((option) => ( ))}
, document.body )}
); }; export default RecurrenceSelectDropdown;