import React, { FC, MutableRefObject, useEffect, useRef, useState, } from 'react'; import classNames from 'classnames'; import css from './index.module.css'; import { getModifier } from '../../helpers/getModifier'; import { Link } from '../../index'; export interface DropdownListOptions { [key: string]: DropdownListOption; } export interface DropdownListOption { value: string; name: string; url: string; } export interface DropdownListProps { options: DropdownListOptions; value?: string; type?: 'normal' | 'filled' | 'category'; onChange?: (val: string) => void; category?: string; } const DropdownList: FC = ({ options, value, type = 'normal', onChange, category, }) => { const [showPanel, togglePanel] = useState(false); // Define type, otherwise Typescript throws error const dropdown: MutableRefObject = useRef(); // Close dropdown when clicked outside const handleClick = (e): void => { if (dropdown.current && dropdown.current.contains(e.target)) { if ( !( e.target instanceof HTMLUListElement || e.target instanceof HTMLSpanElement ) ) { return; } togglePanel(prevState => !prevState); return; } togglePanel(false); }; useEffect(() => { // add when mounted document.addEventListener('mousedown', handleClick); // return function to be called when unmounted return (): void => { document.removeEventListener('mousedown', handleClick); }; }, []); const dropdownClassNames = classNames(css.dropdown, { [`${css[`dropdown${getModifier(type)}`]}`]: type, }); return (
    {options[value] ? `${type === 'category' ? `${category}: ` : ''} ${ options[value].name }` : ''} {showPanel && options && Object.keys(options).map(key => { return options[key].value != value ? (
  • { event.stopPropagation(); if (onChange) { togglePanel(false); onChange(options[key].value); } }} > {type === 'category' && <>{options[key].name}} {type !== 'category' && ( {options[key].name} )}
  • ) : null; })}
); }; export default DropdownList;