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
'smenu
prop must consist of a set ofDropdownMenu.Item
components.
Patterns#
DropdownMenu
has a role ofmenu
.DropdownMenu
has thearia-expended
attribute set totrue
orfalse
depending if the menu is visible.DropdownMenu
has thearia-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
hasaria-haspopup
set to"menu"
. - A
DropdownMenu.Item
has the role ofmenuitem
. - Each
DropdownMenu.Item
has it'stabindex
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 be0
. - When a
DropdownMenu.Item
is disabled,aria-disabled
will 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:
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 aPortal
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 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.
true
wraps between rows and columns.horizontal
wraps only between rows.vertical
wraps only between columns.- If
loop
matches 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.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