UNPKG

@zendeskgarden/container-menu

Version:

Containers relating to Menu in the Garden Design System

140 lines (139 loc) 6.15 kB
/** * Copyright Zendesk, Inc. * * Use of this source code is governed under the Apache License, Version 2.0 * found at http://www.apache.org/licenses/LICENSE-2.0. */ import { AnchorHTMLAttributes, ButtonHTMLAttributes, HTMLProps, ReactNode, RefObject } from 'react'; export interface ISelectedItem { value: string; label?: string; name?: string; type?: 'radio' | 'checkbox'; disabled?: boolean; href?: string; external?: boolean; } export interface IMenuItemBase extends ISelectedItem { selected?: boolean; isNext?: boolean; isPrevious?: boolean; } export interface IMenuItemSeparator { value: string; separator: boolean; } export interface IMenuItemGroup { label: string; items: (IMenuItemBase | IMenuItemSeparator)[]; } export type MenuItem = IMenuItemBase | IMenuItemSeparator | IMenuItemGroup; export interface IUseMenuProps<T = HTMLButtonElement, M = HTMLElement> { /** * Provides an ordered list of menu items * * @param {string} item.value Unique item value * @param {string} item.label Optional human-readable text value (defaults to `item.value`) * @param {string} item.name A shared name corresponding to an item radio group * @param {string} item.href The URL to navigate to when the link item is clicked * @param {boolean} item.external Indicates that link item is an external link * @param {boolean} item.disabled Indicates the item is not interactive * @param {boolean} item.selected Sets initial selection for the option. The initial selection persists for link items. * @param {boolean} item.isNext - Indicates the item transitions to a nested menu * @param {boolean} item.isPrevious - Indicates the item will transition back from a nested menu * @param {boolean} item.separator Indicates the item is a placeholder for a separator * @param {(IMenuItemBase | IMenuItemSeparator)[]} item.items Groups a list of items */ items: MenuItem[]; /** Provides ref access to the underlying trigger element */ triggerRef: RefObject<T>; /** Provides ref access to the underlying menu element */ menuRef: RefObject<M>; /** Determines right-to-left layout */ rtl?: boolean; /** Prefixes IDs for the menu */ idPrefix?: string; /** Sets the expansion in a controlled menu */ isExpanded?: boolean; /** Determines menu expansion on menu initialization */ defaultExpanded?: boolean; /** Sets the focused value in a controlled menu */ focusedValue?: string | null; /** Determines focused value on menu initialization */ defaultFocusedValue?: string; /** Returns keyboard focus to the element that triggered the menu */ restoreFocus?: boolean; /** Sets the selected values in a controlled menu */ selectedItems?: ISelectedItem[]; /** * Handles menu state changes * * @param {string} changes.type The event type that triggered the change * @param {string} [changes.value] The item value * @param {boolean} [changes.isExpanded] The updated menu expansion * @param {string | null} [changes.focusedValue] The updated focused value * @param {ISelectedItem[]} [changes.selectedItems] The updated selected items */ onChange?: (changes: { type: string; value?: string; isExpanded?: boolean; focusedValue?: string | null; selectedItems?: ISelectedItem[]; }) => void; /** Sets the environment where the menu is rendered */ environment?: Window; } export interface IUseMenuReturnValue { isExpanded: boolean; selection: ISelectedItem[]; focusedValue?: string | null; getTriggerProps: (props?: Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'role' | 'type'> & { role?: 'button' | null; type?: 'button' | null; }) => ButtonHTMLAttributes<HTMLButtonElement>; getMenuProps: <T extends Element>(props?: Omit<HTMLProps<T>, 'role'> & { role?: 'menu' | null; }) => HTMLProps<T>; getItemGroupProps: <T extends Element>(props: Omit<HTMLProps<T>, 'role' | 'aria-label'> & { role?: 'group' | null; 'aria-label': NonNullable<HTMLProps<T>['aria-label']>; }) => HTMLProps<T>; getItemProps: <T extends Element>(props: Omit<HTMLProps<T>, 'role'> & { item: IMenuItemBase; role?: 'menuitem' | 'menuitemradio' | 'menuitemcheckbox' | 'none' | null; }) => HTMLProps<T>; getAnchorProps: (props: Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'role'> & { item: IMenuItemBase; role?: 'link' | null; }) => AnchorHTMLAttributes<HTMLAnchorElement> | undefined; getSeparatorProps: <T extends Element>(props?: HTMLProps<T> & { role?: 'separator' | 'none' | null; }) => HTMLProps<T>; } export interface IMenuContainerProps<T = HTMLElement, M = HTMLElement> extends IUseMenuProps<T, M> { /** * Provides menu render prop functions * * @param {function} [options.getTriggerProps] Trigger props getter * @param {function} [options.getMenuProps] Menu props getter * @param {function} [options.getItemProps] Menu item props getter * @param {function} [options.getAnchorProps] Menu link item props getter * @param {function} [options.getSeparatorProps] Separator item props getter * @param {boolean} [options.isExpanded] Current menu expansion * @param {ISelectedItem[]} [options.selection] Current selection * @param {string | null} [options.focusedValue] Current focused value */ render?: (options: { getTriggerProps: IUseMenuReturnValue['getTriggerProps']; getMenuProps: IUseMenuReturnValue['getMenuProps']; getItemProps: IUseMenuReturnValue['getItemProps']; getAnchorProps: IUseMenuReturnValue['getAnchorProps']; getSeparatorProps: IUseMenuReturnValue['getSeparatorProps']; isExpanded: IUseMenuReturnValue['isExpanded']; selection: IUseMenuReturnValue['selection']; focusedValue?: IUseMenuReturnValue['focusedValue']; }) => ReactNode; /** @ignore */ children?: (options: IUseMenuReturnValue) => ReactNode; }