import React, { type HTMLProps, type ReactNode, Fragment } from 'react';
import { DropdownItem } from '../DropdownItem';
import styles from './DropdownMenuContentList.module.css';
type Option = { key: string; label: string };
type OptionGroup = { key: string; label: string; options: T[] };
export type Props = {
isLoading?: boolean;
options: (T | OptionGroup)[];
getItemProps(options: { item: T; index: number }): HTMLProps;
renderOption(option: T, index: number): ReactNode; // should always return a DropdownItem component
renderOptionGroup?(optionGroup: OptionGroup): ReactNode;
renderNoOptions?(): ReactNode;
renderLoadingOptions?(): ReactNode;
};
export const DropdownMenuContentList = ({
isLoading = false,
options,
getItemProps,
renderOption,
renderOptionGroup = (optionGroup) => (
),
renderNoOptions,
renderLoadingOptions,
}: Props) => {
const internalRenderOption = (option: T, index: number) => {
const itemProps = getItemProps({ index, item: option });
return (
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events
{
event.preventDefault();
}}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (itemProps.onClick) {
itemProps.onClick(e);
}
}}
>
{renderOption(option, index)}
);
};
let optionIndex = -1;
return (
<>
{!isLoading &&
options.length > 0 &&
options.map((option) => {
if ('options' in option) {
if (!option.options.length) {
return null;
}
return (
{renderOptionGroup?.(option)}
{option.options.map((option) => {
optionIndex += 1;
return internalRenderOption(option, optionIndex);
})}
);
}
optionIndex += 1;
return internalRenderOption(option, optionIndex);
})}
{!isLoading && options.length === 0 && renderNoOptions?.()}
{isLoading && renderLoadingOptions?.()}
>
);
};