import React, { useRef, useState, useCallback, useEffect } from 'react'; import { CSSTransition } from 'react-transition-group'; import styles from './Dropdown.module.css'; export const Item = ({ value, display, onSelect, children }) => (
onSelect(value ?? children, display ?? value ?? children)}> {children ?? display ?? value}
); export const Dropdown = ({ open, onSelect, onClick, children }) => { const transitionRef = useRef(null); const [ displayed, setDisplayed ] = useState(null); const onSelectCallback = useCallback((value, display) => { setDisplayed(display); onSelect(value); }, [onSelect]); useEffect(() => { if (displayed) { return; } let found = null; children.forEach(element => { if (React.isValidElement(element) && !found && element.props['default']) { const { value, display } = element.props; found = display ?? value; } }); setDisplayed(found); }, [children, displayed]); return (
{displayed}
{children.map((child, key) => React.cloneElement(child, { onSelect: onSelectCallback, key }))}
) }; export const DropdownGroup = ({ children }) => { const [ open, setOpen ] = useState(null); return ( <> { children.map((child, key) => React.cloneElement(child, { open: open === child.props.open, onClick: () => setOpen(o => o === child.props.open ? null : child.props.open), onSelect: v => { child.props.onSelect(v); setOpen(null); }, key, })) } ); }