DropdownMenu#

The <DropdownMenu> component renders a dropdown menu that is attached to a disclosure (a button).

Import#

import { DropdownMenu } from 'bumbag';

Usage#

Supply a set of <DropdownMenu.Item> components to the menu prop to create a menu.

Editable example

Grouped items#

You can group your menu by using the <DropdownMenu.Group> component.

Editable example

Option groups#

The DropdownMenu component can also have selectable option items which can act as checkbox or radio items.

Editable example

Accessibility#

The <DropdownMenu> component follows the WAI ARIA Menu Pattern.

Rules#

  • DropdownMenu's menu prop must consist of a set of DropdownMenu.Item components.

Patterns#

  • DropdownMenu has a role of menu.
  • DropdownMenu has the aria-expended attribute set to true or false depending if the menu is visible.
  • DropdownMenu has the aria-controls attribute set to the menu popover element.
  • Pressing Enter or Space on the menu button will trigger the dropdown menu.
  • If the menu is open, pressing Esc will close the dropdown menu.
  • If the menu is open, clicking outside the menu bounds will close the dropdown menu.
  • If the menu is open, pressing or will navigate the menu items.
  • If the menu is open, DropdownMenu has aria-haspopup set to "menu".
  • A DropdownMenu.Item has the role of menuitem.
  • Each DropdownMenu.Item has it's tabindex set to -1 except either the first element if the menu is closed, or the active element if the menu is open, where it will be 0.
  • When a DropdownMenu.Item is disabled, aria-disabled will be set to true.

References#

Props#

DropdownMenu Props#

menu any Required

children Required

ReactElement<any, string
  | ((props: any) => ReactElement<any, string
  | ...
  | (new (props: any) => Component<any, any, any>)>)
  | (new (props: any) => Component<any, any, any>)>

visible boolean

baseId string

dropdownMenuState

Partial<Pick<unstable_IdState, "baseId">> & Partial<Pick<CompositeState, "unstable_virtual"
  | "currentId"
  | "orientation"
  | ... 4 more ...
  | "unstable_includesBaseElement">> & ... 4 more ... & { ...; }
Inherits Box props

use

string
  | (ComponentClass<any, any> & { useProps: any; })
  | (FunctionComponent<any> & { useProps: any; })

className string

alignX "right" | "left" | "center"

alignY "top" | "bottom" | "center"

variant string

colorMode string

disabled boolean

overrides

{
  useCSSVariables?: boolean;
  altitudes?: AltitudesThemeConfig;
  borders?: BordersThemeConfig;
  borderRadii?: BorderRadiiThemeConfig;
  ... 95 more ...;
  Template?: TemplateThemeConfig;
}

elementRef ((instance: any) => void) | RefObject<any>

themeKey string

DropdownMenu.Popover Props#

isTabbable boolean

baseId string Required

ID that will serve as a base for all the items IDs.

visible boolean

Whether it's visible or not.

animating boolean

Whether it's animating or not.

animated number | boolean

If true, animating will be set to true when visible is updated. It'll wait for stopAnimation to be called or a CSS transition ends. If animated is set to a number, stopAnimation will be called only after the same number of milliseconds have passed.

stopAnimation () => void

Stops animation. It's called automatically if there's a CSS transition.

modal boolean

Toggles Dialog's modal state.

  • Non-modal: preventBodyScroll doesn't work and focus is free.
  • Modal: preventBodyScroll is automatically enabled, focus is trapped within the dialog and the dialog is rendered within a Portal by default.

hide () => void

Changes the visible state to false

hideOnClickOutside boolean

When enabled, user can hide the dialog by clicking outside it.

preventBodyScroll boolean

When enabled, user can't scroll on body when the dialog is visible. This option doesn't work if the dialog isn't modal.

disabled boolean

Same as the HTML attribute.

focusable boolean

When an element is disabled, it may still be focusable. It works similarly to readOnly on form elements. In this case, only aria-disabled will be set.

18 state props
These props are returned by the state hook. You can spread them into this component (...state) or pass them separately. You can also provide these props from your own state logic.

placement Required

"auto-start"
  | "auto"
  | "auto-end"
  | "top-start"
  | "top"
  | "top-end"
  | "right-start"
  | "right"
  | "right-end"
  | "bottom-end"
  | "bottom"
  | "bottom-start"
  | "left-end"
  | "left"
  | "left-start"

Actual placement.

baseId string

ID that will serve as a base for all the items IDs.

currentId string

The current focused item id.

  • undefined will automatically focus the first enabled composite item.
  • null will focus the base composite element and users will be able to navigate out of it using arrow keys.
  • If currentId is initially set to null, the base composite element itself will have focus and users will be able to navigate to it using arrow keys.

orientation "horizontal" | "vertical"

Defines the orientation of the composite widget. If the composite has a single row or column (one-dimensional), the orientation value determines which arrow keys can be used to move focus:

  • undefined: all arrow keys work.
  • horizontal: only left and right arrow keys work.
  • vertical: only up and down arrow keys work.

It doesn't have any effect on two-dimensional composites.

wrap boolean | "horizontal" | "vertical"

Has effect only on two-dimensional composites. If enabled, moving to the next item from the last one in a row or column will focus the first item in the next row or column and vice-versa.

  • true wraps between rows and columns.
  • horizontal wraps only between rows.
  • vertical wraps only between columns.
  • If loop matches the value of wrap, it'll wrap between the last item in the last row or column and the first item in the first row or column and vice-versa.

groups Group[]

Lists all the composite groups with their id and DOM ref. This state is automatically updated when registerGroup and unregisterGroup are called.

items Item[] Required

Lists all the composite items with their id, DOM ref, disabled state and groupId if any. This state is automatically updated when registerItem and unregisterItem are called.

setCurrentId (value: SetStateAction<string>) => void Required

Sets currentId. This is different from composite.move as this only updates the currentId state without moving focus. When the composite widget gets focused by the user, the item referred by the currentId state will get focus.

first () => void Required

Moves focus to the first item.

last () => void Required

Moves focus to the last item.

move (id: string) => void Required

Moves focus to a given item ID.

orientation "horizontal" | "vertical"

Defines the orientation of the composite widget. If the composite has a single row or column (one-dimensional), the orientation value determines which arrow keys can be used to move focus:

  • undefined: all arrow keys work.
  • horizontal: only left and right arrow keys work.
  • vertical: only up and down arrow keys work.

It doesn't have any effect on two-dimensional composites.

items Item[] Required

Lists all the composite items with their id, DOM ref, disabled state and groupId if any. This state is automatically updated when registerItem and unregisterItem are called.

move (id: string) => void Required

Moves focus to a given item ID.

next (unstable_allTheWay?: boolean) => void Required

Moves focus to the next item.

previous (unstable_allTheWay?: boolean) => void Required

Moves focus to the previous item.

Inherits Box props

use

string
  | (ComponentClass<any, any> & { useProps: any; })
  | (FunctionComponent<any> & { useProps: any; })

className string

children

string
  | number
  | boolean
  | {}
  | ReactElement<any, string
  | ((props: any) => ReactElement<any, string
  | ...
  | (new (props: any) => Component<any, any, any>)>)
  | (new (props: any) => Component<...>)>
  | ReactNodeArray
  | ReactPortal
  | ((props: BoxProps) => ReactNode)

alignX "right" | "left" | "center"

alignY "top" | "bottom" | "center"

variant string

colorMode string

overrides

{
  useCSSVariables?: boolean;
  altitudes?: AltitudesThemeConfig;
  borders?: BordersThemeConfig;
  borderRadii?: BorderRadiiThemeConfig;
  ... 95 more ...;
  Template?: TemplateThemeConfig;
}

elementRef ((instance: any) => void) | RefObject<any>

themeKey string

DropdownMenu.Item Props#

hideOnClick boolean

iconAfter

string
  | IconDefinition
  | { viewBoxHeight: number; viewBoxWidth: number; paths?: string[]; tree?: any[]; }

Icon that appears on the right side of the menu item.

iconAfterProps

{
  unstable_system?: any;
  top?: string | number | {
    [key: string]: string
  }; right?: string | number | {
    [key: string]: string
  }; bottom?: string | number | {
    [key: string]: string
  }; left?: string | number | {
    [key: string]: string
  }; ... 787 more ...;
  label?: string;
}

iconBefore

string
  | IconDefinition
  | { viewBoxHeight: number; viewBoxWidth: number; paths?: string[]; tree?: any[]; }

Icon that appears on the left side of the menu item.

iconBeforeProps

{
  unstable_system?: any;
  top?: string | number | {
    [key: string]: string
  }; right?: string | number | {
    [key: string]: string
  }; bottom?: string | number | {
    [key: string]: string
  }; left?: string | number | {
    [key: string]: string
  }; ... 787 more ...;
  label?: string;
}

isTabbable boolean

Inherits Box props

use

string
  | (ComponentClass<any, any> & { useProps: any; })
  | (FunctionComponent<any> & { useProps: any; })

className string

children

string
  | number
  | boolean
  | {}
  | ReactElement<any, string
  | ((props: any) => ReactElement<any, string
  | ...
  | (new (props: any) => Component<any, any, any>)>)
  | (new (props: any) => Component<...>)>
  | ReactNodeArray
  | ReactPortal
  | ((props: BoxProps) => ReactNode)

alignX "right" | "left" | "center"

alignY "top" | "bottom" | "center"

variant string

colorMode string

disabled boolean

overrides

{
  useCSSVariables?: boolean;
  altitudes?: AltitudesThemeConfig;
  borders?: BordersThemeConfig;
  borderRadii?: BorderRadiiThemeConfig;
  ... 95 more ...;
  Template?: TemplateThemeConfig;
}

elementRef ((instance: any) => void) | RefObject<any>

themeKey string

DropdownMenu.Divider Props#

orientation "horizontal" | "vertical"

Separator's orientation.

Inherits Box props

use

string
  | (ComponentClass<any, any> & { useProps: any; })
  | (FunctionComponent<any> & { useProps: any; })

className string

children

string
  | number
  | boolean
  | {}
  | ReactElement<any, string
  | ((props: any) => ReactElement<any, string
  | ...
  | (new (props: any) => Component<any, any, any>)>)
  | (new (props: any) => Component<...>)>
  | ReactNodeArray
  | ReactPortal
  | ((props: BoxProps) => ReactNode)

alignX "right" | "left" | "center"

alignY "top" | "bottom" | "center"

variant string

colorMode string

disabled boolean

overrides

{
  useCSSVariables?: boolean;
  altitudes?: AltitudesThemeConfig;
  borders?: BordersThemeConfig;
  borderRadii?: BorderRadiiThemeConfig;
  ... 95 more ...;
  Template?: TemplateThemeConfig;
}

elementRef ((instance: any) => void) | RefObject<any>

themeKey string

DropdownMenu.Group Props#

title string

Inherits Box props

use

string
  | (ComponentClass<any, any> & { useProps: any; })
  | (FunctionComponent<any> & { useProps: any; })

className string

children

string
  | number
  | boolean
  | {}
  | ReactElement<any, string
  | ((props: any) => ReactElement<any, string
  | ...
  | (new (props: any) => Component<any, any, any>)>)
  | (new (props: any) => Component<...>)>
  | ReactNodeArray
  | ReactPortal
  | ((props: BoxProps) => ReactNode)

alignX "right" | "left" | "center"

alignY "top" | "bottom" | "center"

variant string

colorMode string

disabled boolean

overrides

{
  useCSSVariables?: boolean;
  altitudes?: AltitudesThemeConfig;
  borders?: BordersThemeConfig;
  borderRadii?: BorderRadiiThemeConfig;
  ... 95 more ...;
  Template?: TemplateThemeConfig;
}

elementRef ((instance: any) => void) | RefObject<any>

themeKey string

Theming#

DropdownMenu.styles.base
DropdownMenu.Popover.styles.base
DropdownMenu.Button.styles.base
DropdownMenu.Item.styles.base
DropdownMenu.Item.Icon.styles.base
DropdownMenu.Divider.styles.base
DropdownMenu.Group.styles.base
DropdownMenu.Group.Title.styles.base
Copyright © 2021 Jake Moxey