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.
Grouped items#
You can group your menu by using the <DropdownMenu.Group> component.
Option groups#
The DropdownMenu component can also have selectable option items which can act as checkbox or radio items.
Accessibility#
The <DropdownMenu> component follows the WAI ARIA Menu Pattern.
Rules#
DropdownMenu'smenuprop must consist of a set ofDropdownMenu.Itemcomponents.
Patterns#
DropdownMenuhas a role ofmenu.DropdownMenuhas thearia-expendedattribute set totrueorfalsedepending if the menu is visible.DropdownMenuhas thearia-controlsattribute 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,
DropdownMenuhasaria-haspopupset to"menu". - A
DropdownMenu.Itemhas the role ofmenuitem. - Each
DropdownMenu.Itemhas it'stabindexset to-1except either the first element if the menu is closed, or the active element if the menu is open, where it will be0. - When a
DropdownMenu.Itemis disabled,aria-disabledwill be set totrue.
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:
preventBodyScrolldoesn't work and focus is free. - Modal:
preventBodyScrollis automatically enabled, focus is trapped within the dialog and the dialog is rendered within aPortalby 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.
undefinedwill automatically focus the first enabled composite item.nullwill focus the base composite element and users will be able to navigate out of it using arrow keys.- If
currentIdis initially set tonull, 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.
truewraps between rows and columns.horizontalwraps only between rows.verticalwraps only between columns.- If
loopmatches the value ofwrap, 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.baseDropdownMenu.Popover.styles.baseDropdownMenu.Button.styles.baseDropdownMenu.Item.styles.baseDropdownMenu.Item.Icon.styles.baseDropdownMenu.Divider.styles.baseDropdownMenu.Group.styles.baseDropdownMenu.Group.Title.styles.base