import { type ReactNode, type Ref } from "react"; import { DropdownMenuContent, DropdownMenuItem as PrimitiveDropdownMenuItem } from "src/primitives/DropdownMenu"; import type { ButtonProps } from "src/components/Button"; import type { IconProp } from "src/shared/renderIcon"; export type DropdownPosition = "top" | "bottom" | "left" | "right" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "left-start" | "left-end" | "right-start" | "right-end" | "auto"; /** * Mirrors the primitive `DropdownMenuItem`'s `variant` vocabulary so the * wrapper speaks the same language. Keep in sync with Radix primitive. */ export type MenuItemVariant = "default" | "destructive"; /** * Props forwarded to the trigger button. Sourced from the `Button` wrapper, * so consumers can pass `variant`, `size`, `loading`, `tooltipProps`, * `fullWidth`, `iconPosition`, etc. * * The dropdown owns these and so they are excluded: * - `label`/`icon`: top-level props on `DropdownMenu` * - `trailing`: the chevron * - `disabled`: `DropdownMenu`'s own `disabled` prop is authoritative * - `onClick`: use `DropdownMenu`'s `onClick` (drives split-button mode) * - `to`/`href`: a navigating trigger doesn't open a menu * - `asChild`/`children`: use `customTarget` / `label` instead */ export type DropdownButtonProps = Omit; export interface BaseTriggerProps { label?: string; icon?: IconProp; buttonProps?: DropdownButtonProps; disabled: boolean; isOpen: boolean; onClick?: (e: React.MouseEvent) => void; } export interface DropdownProps { /** Text label displayed inside the trigger button. */ label?: string; /** Icon rendered inside the trigger button. */ icon?: IconProp; /** * Props forwarded to the trigger button (variant, size, className, * loading, tooltipProps, fullWidth, iconPosition, …). In split-button * mode, forwarded to the action button; the chevron half visually mirrors * `variant`/`size`. Accepts the full `Button` prop type minus the props * the dropdown controls. */ buttonProps?: DropdownButtonProps; /** Custom trigger element. Overrides the default button trigger. */ customTarget?: ReactNode | ((props: { isOpen: boolean; }) => ReactNode); /** Whether the dropdown is disabled. */ disabled?: boolean; /** Dropdown menu content. */ children?: ReactNode; /** Position of the dropdown menu relative to the trigger. */ position?: DropdownPosition; /** Whether pressing Escape closes the dropdown. */ closeOnEsc?: boolean; /** Whether selecting an item closes the dropdown. */ closeOnSelect?: boolean; /** Whether clicking outside closes the dropdown. */ closeOnOutsideClick?: boolean; /** * Whether the dropdown is modal. When `true`, the rest of the page is made * inert: focus is trapped, body scroll is locked, and sibling content is * hidden from assistive tech. Defaults to `false` to match the WAI-ARIA * `menu` pattern. Opt in only when the menu must own the user's attention * (e.g. a command palette). */ modal?: boolean; /** Controlled open state. */ isOpen?: boolean; /** Callback fired when the dropdown closes. */ onClose?: () => void; /** * Callback fired when the trigger button is clicked. * When provided (without `customTarget`), renders a **split-button**: * a primary action button (fires `onClick`) paired with a separate * chevron that opens the dropdown menu. */ onClick?: (e: React.MouseEvent) => void; /** Additional CSS class names for the trigger wrapper. */ className?: string; /** Ref forwarded to the trigger button. In split-button mode, forwarded to the action button. */ triggerRef?: Ref; /** Extra props forwarded to the DropdownMenuContent. */ dropdownProps?: Omit, "side" | "align">; } export interface MenuItemProps extends Omit, "prefix" | "variant" | "onClick"> { /** Highlight as active. */ isActive?: boolean; /** Disable the menu item. */ isDisabled?: boolean; /** Visual variant of the menu item. */ variant?: MenuItemVariant; /** Content rendered before the label. */ prefix?: ReactNode; /** Content rendered after the label. */ suffix?: ReactNode; /** Internal route (renders as anchor). */ to?: string; /** External link (renders as anchor). */ href?: string; /** Callback fired when the item is selected. */ onClick?: (e: Event) => void; /** Children / label text. */ children?: ReactNode; /** Additional CSS class names. */ className?: string; } export declare const DropdownContext: import("react").Context<{ closeOnSelect: boolean; }>;