import React, { useRef, useState, useCallback, useEffect } from "react"; import { CSSTransition } from "react-transition-group"; import flagLookup from "../../../domain/flagLookup"; import styles from "./Dropdown.module.css"; export const Item = ({ value, display, onSelect, children }) => { const onClick = () => onSelect(value ?? children, display ?? value ?? children); return (
{ if (key === "Enter") { onClick(); } }} > {children ?? display ?? value}
); }; export const Dropdown = ({ selected, 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 (selected === undefined) { return; } let found = null; React.Children.toArray(children).forEach(element => { if ( React.isValidElement(element) && found === null && element.props.value === selected ) { const { value, display } = element.props; found = display ?? value; } }); setDisplayed(found); }, [children, selected]); return (
{ if (key === "Enter") { onClick(); } }} > {displayed}
{React.Children.toArray(children).map(child => React.cloneElement(child, { onSelect: onSelectCallback, key: JSON.stringify(child.props.value), }) )}
); }; export const CountryDropdown = ({ countryLookup, selected, onSelect, onClick, open, }) => { const transitionRef = useRef(null); const [search, setSearch] = useState(""); const found = countryLookup(search) ?? []; const onSelectCallback = useCallback( code => { setSearch(""); onSelect(code); }, [onSelect] ); return (
{ if (key === "Enter") { onClick(); } }} > {flagLookup(selected)}
setSearch(target.value)} onKeyDown={({ key }) => { if (key === "Enter") { onSelectCallback(found?.[0]?.item?.alpha2); } else if (key === "Escape") { onSelectCallback(selected); } }} /> {found.map(({ item: { country, alpha2 } }) => (
onSelectCallback(alpha2)} onKeyDown={({ key }) => { if (key === "Enter") { onSelectCallback(alpha2); } }} > {flagLookup(alpha2)} - {country}
))}
onSelectCallback(null)} onKeyDown={({ key }) => { if (key === "Enter") { onSelectCallback(null); } }} > {flagLookup(null)} - All Countries
); }; export const DropdownGroup = ({ children }) => { const [open, setOpen] = useState(null); return ( <> {children.map(child => 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: child.props.open, }) )} ); };