import React, { useState, useCallback, useRef, useContext, useEffect } from 'react'; import { Caret } from '../assets/index'; import cx from 'classnames'; import useOnClickOutside from 'use-onclickoutside'; export type CurrentValue = { value: number; label: string; }; type ContextValues = { open: boolean; disabled: boolean; fullwidth: boolean; current: CurrentValue | undefined; onChange: (value: CurrentValue) => void; toggleOpen: () => void; }; type ItemProps = { label: string; value: number; }; const DropdownContext = React.createContext({ open: false, fullwidth: false, disabled: false, current: undefined, onChange: () => {}, toggleOpen: () => {}, }); const useDropdownContext = (): ContextValues => { const context = useContext(DropdownContext); if (!context) { throw new Error(`NOPE`); } return context; }; const Item: React.FC = ({ label, value }) => { const { onChange } = useDropdownContext(); return ( onChange({ label, value })}> {label} ); }; const Label: React.FC<{ valueDataTestid?: string }> = ({ children, valueDataTestid }) => { const { current, fullwidth, disabled } = useDropdownContext(); return (
); }; const Menu: React.FC = ({ children }) => { return ( ); }; type CompoundComponents = { Item: React.FC; Menu: React.FC; Label: React.FC<{ valueDataTestid?: string }>; }; type DropdownProps = { fullwidth: boolean; disabled: boolean; onChange: (value: number) => void; initial?: CurrentValue; dataTestid?: string; title?: string; }; const Dropdown: React.FC & CompoundComponents = ({ onChange, title, disabled, fullwidth, children, initial, dataTestid, }) => { const [current, setCurrent] = useState(initial); const [open, setOpen] = useState(false); useEffect(() => { setCurrent(initial); }, [initial]); const handleChange = useCallback( ({ value, label }) => { if (!disabled) { setCurrent({ value, label }); onChange && onChange(value); } }, [disabled, onChange] ); const toggleOpen = useCallback(() => { if (!disabled) { setOpen((open) => !open); } }, [disabled]); const node = useRef(null); useOnClickOutside(node, () => setOpen(false)); return (
{children}
); }; Dropdown.Item = Item; Dropdown.Menu = Menu; Dropdown.Label = Label; export default Dropdown;