UNPKG

@atlaskit/menu

Version:

A list of options to help users navigate, or perform actions.

379 lines (378 loc) 14.3 kB
import { type ComponentType, type PropsWithChildren, type Ref } from 'react'; import { type StrictXCSSProp } from '@atlaskit/css'; import type { SpacingMode } from './internal/components/menu-context'; export interface RenderFunction<TProps = {}> { (Component: ComponentType | string, props: TProps): React.ReactNode; } export type Dimension = string | number; export interface MenuGroupSizing { /** * Use this to constrain the menu group's minimum height to a specific value. */ minHeight?: Dimension; /** * Use this to constrain the menu group's height to a specific value. * This must be set if you want to have scrollable sections. */ maxHeight?: Dimension; /** * Use this to constrain the menu group's minimum width to a specific value. */ minWidth?: Dimension; /** * Use this to constrain the menu group's maximum width to a specific value. */ maxWidth?: Dimension; } export interface MenuGroupProps extends MenuGroupSizing { /** * Children of the menu group. * This should generally be `Section` components. */ children: React.ReactNode; /** * Used this to tell assistive technologies that the menu group is loading. */ isLoading?: boolean; /** * Configure the density of the menu group content. */ spacing?: SpacingMode; /** * Use this to override the accessibility role for the element. */ role?: string; /** * A `testId` prop is provided for specified elements, * which is a unique string that appears as a data attribute `data-testid` in the rendered code, * serving as a hook for automated tests. */ testId?: string; /** * Handler called when clicking on this element, * or any children elements. * Useful when needing to stop propagation of child events. */ onClick?: (event: React.MouseEvent | React.KeyboardEvent) => void; /** * Provide an accessible label via `aria-label` for the menu element for assistive technology. */ menuLabel?: string; } export interface SectionProps { /** * Unique identifier for the element. */ id?: string; /** * Enables scrolling within the section. * This won't work unless `maxHeight` is set on the parent `MenuGroup` component. */ isScrollable?: boolean; /** * Use this to render a border at the top of the section. */ hasSeparator?: boolean; /** * Children of the section. * This should generally be `Item` or `Heading` components, * but can also be [`EmptyState`](https://atlaskit.atlassian.com/packages/design-system/empty-state)s if you want to render errors. */ children: React.ReactNode; /** * A `testId` prop is provided for specified elements, * which is a unique string that appears as a data attribute `data-testid` in the rendered code, * serving as a hook for automated tests. */ testId?: string; /** * The text passed into the internal `HeadingItem`. If a title isn't provided, * the `HeadingItem` won't be rendered, and this component will act as a regular `Section`. */ title?: string; /** * ID referenced by the menu group wrapper's `aria-labelledby` attribute. This ID should be assigned to the group title element. * Usage of either this, or the `label` attribute is strongly recommended. */ titleId?: string; /** * If your menu contains a list, use this to add `<ul>` and `<li>` tags around the items. This is essential for offering better, accessible semantic markup in a list of items. */ isList?: boolean; /** * When `true`, section header inline padding is reduced. * @deprecated This API exists to support functionality in `@atlaskit/side-navigation` and should not be used. Once the new navigation is fully rolled out, this prop will be removed. */ isSideNavSection?: boolean; } export interface MenuItemPrimitiveProps { children: (props: { className?: string; children: React.ReactNode; }) => JSX.Element; title: React.ReactNode | undefined; description: React.ReactNode | undefined; iconAfter: React.ReactNode | undefined; iconBefore: React.ReactNode | undefined; shouldTitleWrap: boolean | undefined; shouldDescriptionWrap: boolean | undefined; isDisabled: boolean | undefined; isSelected: boolean | undefined; /** * @deprecated This API exists to support functionality in `@atlaskit/side-navigation` and should not be used. Once the new navigation is fully rolled out, this prop will be removed. */ isTitleHeading: boolean | undefined; className?: string; testId?: string; } export interface MenuItemProps { /** * Not recommended for general use as it enables unsafe style overrides. */ className?: string; /** * Element to render before the item text. * Usually this is an [icon](https://atlaskit.atlassian.com/packages/design-system/icon) component. */ iconBefore?: React.ReactNode; /** * Element to render after the item text. * Usually this is an [icon](https://atlaskit.atlassian.com/packages/design-system/icon) component. */ iconAfter?: React.ReactNode; /** * Event that's triggered when the element is clicked. */ onClick?: (e: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>) => void; /** * Event that's triggered when the element has been pressed. */ onMouseDown?: React.MouseEventHandler; /** * Description of the item. * This will render smaller text below the primary text of the item, and slightly increase the height of the item. */ description?: string | JSX.Element; /** * Makes the element appear disabled as well as removing interactivity. Avoid disabling menu items wherever possible as this isn’t accessible or usable. */ isDisabled?: boolean; /** * Makes the element appear selected. */ isSelected?: boolean; /** * Primary content for the item. */ children?: React.ReactNode; /** * A `testId` prop is provided for specified elements, * which is a unique string that appears as a data attribute `data-testid` in the rendered code, * serving as a hook for automated tests. */ testId?: string; /** * When `true`, the title of the item will wrap multiple lines if it's long enough. */ shouldTitleWrap?: boolean; /** * When `true`, the description of the item will wrap multiple lines if it's long enough. */ shouldDescriptionWrap?: boolean; /** * When `true`, the title of the item will render as a `h2` rather than a `span` * @deprecated This API exists to support functionality in `@atlaskit/side-navigation` and should not be used. Once the new navigation is fully rolled out, this prop will be removed. */ isTitleHeading?: boolean; /** * An optional name used to identify events for [React UFO (Unified Frontend Observability) press interactions](https://developer.atlassian.com/platform/ufo/react-ufo/react-ufo/getting-started/#quick-start--press-interactions). For more information, see [React UFO integration into Design System components](https://go.atlassian.com/react-ufo-dst-integration). */ interactionName?: string; } export interface ButtonItemProps extends MenuItemProps { /** * Unique identifier for the element. */ id?: string; /** * Use this to override the accessibility role for the element. */ role?: string; } export interface LinkItemProps extends MenuItemProps { /** * Link to another page. */ href?: string; /** * Where to display the linked URL, * see [anchor information](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a) on mdn for more information. */ target?: string; /** * The relationship of the linked URL as space-separated link types. * Generally you'll want to set this to "noopener noreferrer" when `target` is "_blank". */ rel?: string; /** * Use this to override the accessibility role for the element. */ role?: string; /** * Use this to opt out of using a router link and instead use a regular anchor element. * Marked as "unsafe" because ideally, router links should be used for all internal links. */ UNSAFE_shouldDisableRouterLink?: boolean; /** * Use this to prevent disable of drag functionality on the menu item. * Marked as "unsafe" as this may break existing instances of drag handling. */ UNSAFE_isDraggable?: boolean; } export interface CustomItemComponentProps { /** * The children of the item. */ children: React.ReactNode; /** * Class to apply to the root container of the custom component. * Ensure this has been applied so the item styling is consistent. */ className?: string; /** * Test ID that's passed through to the custom component. */ 'data-testid'?: string; /** * Event handler that's passed through to the custom component. */ onClick?: (event: React.MouseEvent<HTMLElement>) => void; /** * Event handler that's passed through to the custom component. */ onMouseDown?: (event: React.MouseEvent<HTMLElement>) => void; /** * Event handler that's passed through to the custom component. * Use this to disable the element from being draggable. */ onDragStart?: (event: React.DragEvent) => void; /** * Turns off the element being draggable. */ draggable?: boolean; /** * React ref for the raw DOM element, * make sure to place this on the outermost DOM element. */ ref?: Ref<any>; /** * If the tab is selected, the tab index is `0` and is focusable. Otherwise it is `-1` and is not focusable. */ tabIndex?: number; /** * Makes the element appear disabled as well as removing interactivity. Avoid disabling menu items wherever possible as this isn’t accessible or usable. */ disabled?: boolean; } export interface CustomItemProps<TCustomComponentProps = CustomItemComponentProps> extends MenuItemProps { /** * Custom component to render as an item. This can be both a functional component or a class component. * * Will return `null` if no component is defined. * * Props passed to `CustomItem` will be passed down to this component. If the props for `component` have TypeScript types, * CustomItem will extend them, providing type safety for your custom item. * * E.g. `<CustomItem to="/link" component={RouterLink} />`. * * __NOTE:__ Make sure the reference for this component does not change between renders else undefined behavior may happen. */ component?: React.ComponentType<PropsWithChildren<TCustomComponentProps>>; /** * Use this to prevent disable of drag functionality on the menu item. * Marked as "unsafe" as this may break existing instances of drag handling. */ UNSAFE_isDraggable?: boolean; } export interface SkeletonItemProps { /** * Renders a skeleton circle in the `iconBefore` location. * Takes priority over `hasIcon`. */ hasAvatar?: boolean; /** * Renders a skeleton square in the `iconBefore` location. */ hasIcon?: boolean; /** * * Width of the skeleton item. * You usually don't need to specify this, as it has a staggered width based on `:nth-child` by default. */ width?: Dimension; /** * A `testId` prop is provided for specified elements, * which is a unique string that appears as a data attribute `data-testid` in the rendered code, * serving as a hook for automated tests. */ testId?: string; /** * Causes to the skeleton to have a slight horizontal shimmer. * Only use this when you want to bring more attention to the loading content. */ isShimmering?: boolean; /** * When `true`, the size/spacing of the skeleton size/spacing is adjusted to match the side navigation menu item. * @deprecated This API exists to support functionality in `@atlaskit/side-navigation` and should not be used. Once the new navigation is fully rolled out, this prop will be removed. */ isSideNavSkeleton?: boolean; /** * Bounded style overrides. */ xcss?: StrictXCSSProp<'minHeight' | 'paddingBlock' | 'paddingInline' | 'paddingBlockStart' | 'paddingBlockEnd' | 'paddingInlineStart' | 'paddingInlineEnd', never>; } export interface HeadingItemProps { /** * The text of the heading. */ children: React.ReactNode; /** * A unique identifier that can be referenced in the `labelledby` prop of a * section to allow assistive technology to announce the name of groups. */ id?: string; /** * A `testId` prop is provided for specified elements, * which is a unique string that appears as a data attribute `data-testid` in the rendered code, * serving as a hook for automated tests. */ testId?: string; /** * Specifies the heading level in the document structure. * If not specified, the default is `h2`. */ headingLevel?: 1 | 2 | 3 | 4 | 5 | 6; } export interface SkeletonHeadingItemProps { /** * * Width of the skeleton heading item. * You usually don't need to specify this, as it has a staggered width based on `:nth-child` by default. */ width?: Dimension; /** * A `testId` prop is provided for specified elements, * which is a unique string that appears as a data attribute `data-testid` in the rendered code, * serving as a hook for automated tests. */ testId?: string; /** * Causes to the skeleton to have a slight horizontal shimmer. * Only use this when you want to bring more attention to the loading content. */ isShimmering?: boolean; /** * Bounded style overrides. */ xcss?: StrictXCSSProp<'paddingBlock' | 'paddingInline' | 'paddingBlockStart' | 'paddingBlockEnd' | 'paddingInlineStart' | 'paddingInlineEnd', never>; }