import React, { type HTMLProps, type ReactNode, useEffect, useRef, useState, } from 'react'; import type { GetPropsCommonOptions, GetMenuPropsOptions } from 'downshift'; import { DropdownMenuContentList } from './DropdownMenuContentList'; import { classNames, getStyleFromPlacement, type Placement } from '../../utils'; import usePrevious from '../../hooks/usePrevious'; import { useFormFieldContext } from '../FormField/FormFieldContext'; import styles from './DropdownMenuContent.module.css'; import commonStyles from '../../theme/common.module.css'; type OptionGroup = { key: string; label: string; options: T[] }; type Option = { key: string; label: string }; type Overwrite = Pick> & U; export type Props = { className?: string; isOpen?: boolean; isLoading?: boolean; placement?: Placement; maxHeight?: string; options: (T | OptionGroup)[]; renderSearchBar?: () => ReactNode; getItemProps(options: { item: T; index: number }): HTMLProps; getMenuProps( options?: GetMenuPropsOptions, otherOptions?: GetPropsCommonOptions, // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Overwrite, { ref?: any }>; renderOption(option: T, index: number): ReactNode; // should always return a DropdownItem component renderOptionGroup?(optionGroup: OptionGroup): ReactNode; renderNoOptions?(): ReactNode; renderLoadingOptions?(): ReactNode; }; export const DropdownMenuContent = ({ className, isOpen = true, isLoading = false, maxHeight, options, placement = 'bottom-start', getItemProps, getMenuProps, renderOption, renderOptionGroup, renderNoOptions, renderLoadingOptions, renderSearchBar, }: Props) => { const [visible, setVisible] = useState(isOpen); const refTimeout = useRef>(undefined); const previousOpenState = usePrevious(isOpen); const context = useFormFieldContext(); useEffect(() => { if (isOpen) { clearTimeout(refTimeout.current); setVisible(isOpen); } else if (previousOpenState) { refTimeout.current = setTimeout(() => { if (!isOpen) { setVisible(false); } }, 200); } }, [isOpen, previousOpenState]); useEffect(() => { return () => clearTimeout(refTimeout.current); }, []); return (
    { if (!isOpen) { setVisible(false); } }} > {visible ? ( <> {renderSearchBar && renderSearchBar()} ) : null}
); };