import React, { useState, ReactNode, useRef, useEffect } from 'react'; import { animated, useSpring } from '@react-spring/web'; interface DropdownProps { title?: ReactNode; open?: boolean; setIsOpen?: React.Dispatch> | ((isOpen: boolean) => void); className?: string; contentWrapperClassName?: string; titleClassName?: string; bottomPadding?: number; disabled?: boolean, wrapperClassName?: string; customTitle?: ReactNode; children: ReactNode; } const Dropdown: React.FC = ({ title, open = false, titleClassName = "", setIsOpen: externalSetIsOpen, className = "w-full text-left font-semibold flex justify-between items-center p-4", contentWrapperClassName = "px-6", bottomPadding = 12, disabled = false, customTitle = undefined, wrapperClassName, children }) => { const [internalIsOpen, setInternalIsOpen] = useState(open); const isOpen = externalSetIsOpen !== undefined ? open : internalIsOpen; const toggleOpen = externalSetIsOpen !== undefined ? externalSetIsOpen : setInternalIsOpen; const contentRef = useRef(null); const [contentHeight, setContentHeight] = useState(0); useEffect(() => { let resizeObserver: ResizeObserver | null = null; if (contentRef.current) { resizeObserver = new ResizeObserver(entries => { for (let entry of entries) { if (entry.borderBoxSize && entry.borderBoxSize.length > 0) { const height = entry.borderBoxSize[0].blockSize; setContentHeight(height + bottomPadding); } else { // Fallback for browsers that don't support borderBoxSize const height = entry.contentRect.height; setContentHeight(height + bottomPadding); } } }); resizeObserver.observe(contentRef.current); } return () => { if (resizeObserver) { resizeObserver.disconnect(); } }; }, [bottomPadding]); const springProps = useSpring({ height: isOpen ? contentHeight : 0, opacity: isOpen ? 1 : 0, config: { tension: 300, friction: 30 } }); return (
{children}
); }; export default Dropdown;