import { type ComponentPropsWithoutRef, type ReactElement, type ReactNode } from 'react'; import { type ButtonProps } from '../Button'; import { type IconButtonProps } from '../IconButton'; import { type PopoverProps } from '../Popover'; type DropdownMenuCommonProps = { /** * The list of the dropdown menu. * * Only one or more composition components of a Menu component other than Menu.Container will be accepted. * (Menu.Container is already defined inside the DropdownMenu component.) * * @example * ```jsx * * Item 1 * Item 2 * * Item 3 * * ``` */ children: ReactNode; /** * The label of the trigger button of the dropdown menu. * * If the icon prop is provided, the label prop will be set as the aria-label of the icon button. * If the icon prop is not provided, the label prop will be set as the label of the button. */ label: string; /** * The properties for the popover content panel. * * @property className - The class name of the popover content panel. * * @property minWidth - The minimum width of the popover content panel. * * @property allowedPlacements - Allowed placements for the popover relative to the trigger element. */ menuPopoverProps?: Pick, 'className'> & { minWidth?: PopoverProps['minWidth']; allowedPlacements?: PopoverProps['allowedPlacements']; }; /** * The disabled state of the trigger element. */ disabled?: boolean; /** * The icon of the trigger icon button of the dropdown menu. * * If the icon is provided, the trigger button will be rendered as the IconButton component. * If the icon is not provided, the trigger button will be rendered as the Button. */ icon?: ReactElement; /** * Callback fired when the open state of the DropdownMenu changes. * * @param open - The new open state of the DropdownMenu. */ onOpenStateChanged?: (open: boolean) => void; /** * The callback function that is called when the DropdownMenu loses focus. * This will only fire when the user truly leaves the component (not when the popover opens). * * @param event - The blur event from the trigger element * * @example * ```tsx * { * console.log('DropdownMenu lost focus'); * // Perform validation or other actions * }} * > * Item 1 * * ``` */ onBlur?: (event: React.FocusEvent) => void; }; type DropdownMenuPropsWithIcon = { icon: ReactElement; /** * Button component and the IconButton component. * The props of the trigger button. * Use this prop if you need to customize the style of the trigger button. * * If the icon prop is provided, the following props are acceptable as props of the IconButton component: * 'outlined' | 'className' */ triggerProps?: Pick; }; type DropdownMenuPropsWithoutIcon = { icon?: undefined; /** * Button component and the IconButton component. * The props of the trigger button. * Use this prop if you need to customize the style of the trigger button. * * If the icon prop is not provided, the following props are acceptable as props of the Button component: * 'size' | 'priority' | 'destructive' | 'leftIcon' | 'loading' | 'className' */ triggerProps?: Pick; }; export type DropdownMenuProps = DropdownMenuCommonProps & (IconType extends ReactElement ? DropdownMenuPropsWithIcon : DropdownMenuPropsWithoutIcon) & Pick; export {};