import React, { useMemo } from 'react'; import { Menu as HeadlessMenu } from '@headlessui/react'; import { clsx } from 'clsx'; import { applyClassName } from '../utils/misc'; import { forwardRef } from '../utils/react'; import { MenuItem, MenuItemButton, MenuItemIcon, MenuItemProps } from '../menu'; import * as css from './dropdown-menu-item.css'; /*-- Types --*/ type HeadlessMenuItemContext = { active: boolean; disabled: boolean; }; type HeadlessMenuItemProps = { children?: | React.ReactNode | ((context: HeadlessMenuItemContext) => React.ReactNode); className?: string | ((context: HeadlessMenuItemContext) => string); }; export interface DropdownMenuItemProps extends MenuItemProps, Omit { disabled?: boolean; icon?: | React.ReactNode | ((context: HeadlessMenuItemContext) => React.ReactNode); className?: | HeadlessMenuItemProps['className'] | { base?: HeadlessMenuItemProps['className']; button?: HeadlessMenuItemProps['className']; icon?: HeadlessMenuItemProps['className']; body?: HeadlessMenuItemProps['className']; }; } /*-- Main --*/ export const DropdownMenuItem = forwardRef<'li', DropdownMenuItemProps>( function DropdownMenuItem( { children, className, disabled, icon, ...rest }, ref, ) { const cn = useMemo(() => { const classNameObject = typeof className === 'string' || typeof className === 'function' ? { base: className } : className || {}; return { base: (itemContext: HeadlessMenuItemContext) => applyClassName(classNameObject.base, itemContext), button: (itemContext: HeadlessMenuItemContext) => clsx(applyClassName(classNameObject.button, itemContext), { [css.itemFocused]: itemContext.active, }), body: (itemContext: HeadlessMenuItemContext) => applyClassName(classNameObject.body, itemContext), icon: (itemContext: HeadlessMenuItemContext) => applyClassName(classNameObject.icon, itemContext), }; }, [className]); return ( {itemContext => ( {icon && ( {typeof icon === 'function' ? icon(itemContext) : icon} )} {typeof children === 'function' ? children(itemContext) : children} )} ); }, );