Skip to main content

DropdownMenu

Displays a menu triggered by a button, such as a set of actions or functions.

Submit feedback
github

Migration Information

For teams migrating from the V1 to V2 component, please refer to the migration guide for changes to the component.
Component Guide
import { DropdownMenu } from '@uhg-abyss/web/ui/DropdownMenu';

Overview

The DropdownMenu component displays a menu triggered by a button, known as the Action Menu. This menu can contain various items, including action items, checkboxes, radio groups, and submenus. Each item can have an icon.

Label

Use the label prop to set the text displayed on the trigger. Alternatively, you can use the iconOnly prop to display only an icon without text.

Note: To meet accessibility standards, you must still provide a label prop when using iconOnly.

Outline

Use the outline prop to control the outline of the Dropdown menu. The default is true. When setting the prop to false, the border radius will be removed and the component will have a flat appearance.

Note: An outline should be used if the DropdownMenu is used on a background that does not meet the 3:1 color contrast ratio.

isDisabled

Use the isDisabled prop to disable the DropdownMenu.

isLoading

Use the isLoading prop to place the Action Menu in a loading state. This will display a loading spinner in place of the menu items while the menu is loading.

You can also provide the optional prop loadingLabel for additional context when the menu is in a loading state. This prop takes the form of an object, as explained in our LoadingSpinner documentation.

Use the menuItems prop to specify what will be displayed in the Action Menu. The prop requires an array of objects that have the following forms:

Action item

interface ActionMenuItemProps {
title: string;
onClick: Function;
icon: ReactNode; //optional
isSeparated: boolean; //optional
disabled: boolean; //optional
}

Checkbox

interface ActionMenuCheckboxItemProps {
checkboxes: Array<{
label: string;
checked: bool;
onChange: func;
disabled: bool; //optional
}>;
}

Radio group

interface ActionMenuRadioItemProps {
label: string;
value: string;
onChange: Function;
radios: Array<{
label: string;
value: string;
disabled: bool; //optional
}>;
}
interface ActionMenuItemGroupSubMenuItem {
title: string;
subMenu: ActionMenuItemGroupItem[]; // any of the above types
}

Inserting icons

There are three different types of icons that can be added to the DropdownMenu:

  • Use the before prop to insert an icon before the trigger label.
  • Use the iconOnly prop to only display an icon in the trigger button without displaying the label.
  • The iconOnly prop can be used to display only an icon in the trigger button without displaying the label.
    • iconOnly also accepts a React node, allowing you to use any custom icon component.
  • Use the icon prop in the menu items to insert icons before to the item title. While this prop accepts any React node, the examples on this page use our IconSymbol component.

onClick

Use the onClick function on each menu item to trigger a custom function when that item is clicked.

onChange

Use the onChange function to trigger a custom function when a checkbox or a radio item is clicked. You can use this to update your checked state, among other things.

Disabled menu items

When the disabled flag is set to true on a menu item, that item cannot be interacted with. This prop applies to all item types, including action items, checkboxes, and radio groups. The item will be visually styled to indicate that it is disabled.

isSeparated

When the isSeparated flag is set to true on a menu item, a horizontal divider will be inserted after that item. Checkbox and radio group items automatically render a divider both before and after the item, so no isSeparated flag is required. A divider will not be rendered before the first item or after the last item.

onOutsideClick

Use onOutsideClick prop to trigger a custom function when the user clicks outside an open menu.

Use the open and onOpenChange props together to control the dropdown open state. open is a boolean that determines whether the dropdown is open or closed, and onOpenChange is a function that is called when the open state changes. This allows you to manage the open state of the dropdown programmatically.

Height

Use the height prop to set a custom height for the Action Menu. The default height is 500px. This prop accepts any valid CSS height value.

SplitButton vs. DropdownMenu

DropdownMenu is a versatile component that can be used for various menu actions, while SplitButton is specifically designed for a button with a dropdown menu that allows users to perform an action or select from a list of options.SplitButton is more suitable when you want to combine a primary action with a secondary dropdown menu.

DropdownMenu Props

NameTypeDefaultRequiredDescription
before
React.ReactNode
--
* A React node (IconSymbol) to be displayed before the label in the dropdown trigger.
className
string
--
CSS class name to apply to each element within the component
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
height
Property.Height | undefined
500
-
The height of the menu content area.
iconOnly
React.ReactNode
false
-
If set to true, renders a standard icon button. If set to false, renders a button with a label.
Alternatively, you can provide an IconSymbol to use a custom icon element.
isDisabled
boolean
false
-
Disables the dropdown menu trigger and interactions.
isLoading
boolean
false
-
Displays a loading state for the dropdown menu content.
label
string
-
The label for the dropdown menu trigger.
loadingLabel
{ heading: string; headingLevel?: 2 | 1 | 3 | 4 | 5 | 6 | undefined; bodyText?: string | undefined; } | undefined
--
The label shown when the dropdown content is loading.
menuItems
GenericActionMenuItem[]
--
An array of menu items to be rendered in the dropdown.
modal
boolean
true
-
Determines if the dropdown behaves as a modal dialog.
onOpenChange
(open: boolean) => void
--
Callback fired when the dropdown menu open state changes.
onOutsideClick
(event: MouseEvent | TouchEvent) => void
--
Callback fired when a click outside the dropdown menu is detected.
open
boolean | null
'null'
-
Controls the open state of the dropdown menu (controlled mode).
outline
boolean
true
-
Applies an outline style to the dropdown menu trigger.

ActionMenu - Menu Item Props

NameTypeDefaultRequiredDescription
className
string
--
CSS class name to apply to each element within the component
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disabled
boolean
false
-
If true, the menu item will be disabled
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
icon
React.ReactNode
''
-
The icon type to display in the menu item
isSeparated
boolean
false
-
If true, the menu item will be separated by a horizontal line
onClick
(event: React.MouseEvent<HTMLLIElement, MouseEvent>) => void
--
Callback function when the menu item is clicked
title
string
-
The title of the menu item

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

ActionMenu - Checkbox Item Props

NameTypeDefaultRequiredDescription
checkboxes
CheckboxOption[]
-
An array of checkbox options to display.
Each checkbox option should include a label and optionally disabled, checked state, and change handler.
className
string
--
CSS class name to apply to each element within the component
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
isSeparatedBottom
boolean
false
-
If true, a separator is shown below the last checkbox.
isSeparatedTop
boolean
false
-
If true, a separator is shown above the first checkbox.

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

ActionMenu - Radio Item Props

NameTypeDefaultRequiredDescription
className
string
--
CSS class name to apply to each element within the component
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disabled
boolean
false
-
If true, disables the entire radio group.
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
isSeparatedBottom
boolean
true
-
If true, a separator is shown below the radio group.
isSeparatedTop
boolean
true
-
If true, a separator is shown above the radio group.
label
string
''
The label for the radio group.
onChange
(value: any) => void
--
Callback when the selected radio changes.
radios
RadioOption[]
-
An array of radio items to display.
Each radio item should include a label, value, and optionally disabled state.
value
any
-
The current value for the radio group.

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

ActionMenu - Item Group Props

NameTypeDefaultRequiredDescription
firstItemRef
React.Ref<HTMLElement>
--
The ref for the first item in the group. Typically used for focus control.
menuItems
GenericActionMenuItem[]
--
An array of menu items. Each item can be a basic menu item,
a submenu trigger, a checkbox group, or a radio group.
width
string | number
--
The width that should be applied to the rendered menu group.

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

ActionMenu - SubMenu Trigger Props

NameTypeDefaultRequiredDescription
className
string
--
CSS class name to apply to each element within the component
css
Abyss.CSSProperties | Partial<Record<`abyss-${T}`, Abyss.CSSProperties>>
--
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation

See CSS Prop Styling for more information
data-testid
string
--
Suffix used to create a unique ID used for automated testing

See Component Testing for more information
disabled
boolean
false
-
Whether the sub menu trigger is disabled.
disableDefaultProviderProps
boolean
false
-
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
icon
React.ReactNode
''
-
The icon type to display in the menu item
isOpen
boolean
false
-
Whether the sub menu trigger is open.
title
string
-
Title of the sub menu trigger item.

Below are the link(s) to the relevant GitHub type files:

Abyss.d.ts

DropdownMenu Classes

Class NameDescription
.abyss-dropdown-menu-rootRoot container for the dropdown menu
.abyss-dropdown-menu-portalPortal container for the dropdown menu

ActionMenu - Menu Item Classes

Class NameDescription
.abyss-action-menu-item-list-itemList item element for the action menu item
.abyss-action-menu-itemItem element
.abyss-action-menu-item-left-containerContainer for the icon in the item
.abyss-action-menu-item-titleTitle text in the item

ActionMenu - Checkbox Item Classes

Class NameDescription
.abyss-action-menu-checkbox-list-itemList item element for the action menu item
.abyss-action-menu-checkboxCheckbox item element
.abyss-action-menu-checkbox-iconCheckbox icon element

ActionMenu - Radio Item Classes

Class NameDescription
.abyss-action-menu-radio-group-list-itemList item element for the entire radio group
.abyss-action-menu-radio-groupContainer element for the radio group
.abyss-action-menu-radio-group-labelLabel for the radio group
.abyss-action-menu-radioRadio item element
.abyss-action-menu-radio-left-containerContainer for the left region (icon) in the radio item
.abyss-action-menu-radio-iconIndicator icon for the radio item
.abyss-action-menu-radio-titleTitle of the radio item

ActionMenu - SubMenu Trigger Classes

Class NameDescription
.abyss-action-menu-sub-triggerSub trigger element
.abyss-action-menu-item-left-containerContainer for the icon in the sub trigger
.abyss-action-menu-item-titleTitle text in the sub trigger
.abyss-action-menu-sub-trigger-right-containerContainer for the right side of the sub trigger, typically for the chevron icon
.abyss-action-menu-sub-trigger-icon-rightIcon element on the right side of the sub trigger, typically a chevron icon

ActionMenu - Menu Content Classes

Class NameDescription
.abyss-action-menu-contentContainer for the menu content
.abyss-action-menu-content-listList container for the menu content items
.abyss-action-menu-content-themeTheme container for styling the menu content

ActionMenu - Menu Separator Classes

Class NameDescription
.abyss-action-menu-item-separatorRoot element for the menu separator

Use for application menu settings and actions only - NOT navigation

From an accessibility and WAI-ARIA perspective, dropdown and split button menus are intended only for application settings and actions—not navigation. Unlike navigation components, these rely solely on arrow keys for making selections. When using navigation components, tabbing between links is an expected behavior. Use NavMenu or other components for navigating between web pages.

WAI-ARIA implementation

This component implements several WAI-ARIA design patterns beginning with Menu Button. Nested menus are of single-menu examples from Menu Bar (using roving tabindex to manage focus movement). Radio button and checkbox option operation are based upon the Editor Menu Example.

Keyboard Interactions

KeyDescription
TabMoves focus to the next focusable element.
EnterIf focus is on a Dropdown menu button, opens the relevant Dropdown menu. If focus is on a menu item with a trigger, opens the relevant sub-menu. If focus is on radio button or checkbox, will select/deselect it.
SpaceIf focus is on a Dropdown menu button, opens the relevant Dropdown menu. If focus is on a menu item with a trigger, opens the relevant sub-menu. If focus is on radio button or checkbox, will select/deselect it.
EscapeCloses open Dropdown menu and moves focus to its Dropdown menu button.
Up ArrowFocuses the previous menu item.
Down ArrowFocuses the next menu item.
Right ArrowOpens a sub-menu if focus is on a menu item with a trigger.
Left ArrowCloses a sub-menu if open.
HomeMoves focus to the first item in the Dropdown menu.
EndMoves focus to the last item in the Dropdown menu.

Component Tokens

Note: Click on the token row to copy the token to your clipboard.

DropdownMenu Tokens

Token NameValue
dropdown-menu.color.border.button
#002677
dropdown-menu.color.icon.secondary.default
#002677
dropdown-menu.color.icon.secondary.disabled
#4B4D4F
dropdown-menu.color.icon.tertiary.rest
#196ECF
dropdown-menu.color.icon.tertiary.hover
#004BA0
dropdown-menu.color.icon.tertiary.active
#002677
dropdown-menu.color.icon.tertiary.disabled
#7D7F81
dropdown-menu.color.icon.tertiary.selected
#196ECF
dropdown-menu.color.surface.container.rest
#FFFFFF
dropdown-menu.color.surface.container.hover
#F3F3F3
dropdown-menu.color.surface.container.active
#E5E5E6
dropdown-menu.color.surface.container.disabled
#F3F3F3
dropdown-menu.color.surface.container.selected
#EDF3FB
dropdown-menu.color.text.label.secondary.default
#002677
dropdown-menu.color.text.label.secondary.disabled
#4B4D4F
dropdown-menu.color.text.label.tertiary.rest
#196ECF
dropdown-menu.color.text.label.tertiary.hover
#004BA0
dropdown-menu.color.text.label.tertiary.active
#002677
dropdown-menu.color.text.label.tertiary.disabled
#7D7F81
dropdown-menu.color.text.label.tertiary.selected
#196ECF
dropdown-menu.border-radius.all.container
500px
dropdown-menu.border-width.all.button
1px
dropdown-menu.sizing.all.icon.utility
20px
dropdown-menu.sizing.height.button
40px
dropdown-menu.sizing.width.button
40px
dropdown-menu.spacing.gap.horizontal.button
8px
dropdown-menu.spacing.gap.vertical.button-dropdown
8px
dropdown-menu.spacing.padding.all.icon-only
8px
dropdown-menu.spacing.padding.left.default
16px
dropdown-menu.spacing.padding.right.default
12px
dropdown-menu.spacing.padding.horizontal.leading-icon
12px
dropdown-menu.spacing.padding.vertical.button
8px

ActionMenu Tokens

Token NameValue
action-menu.color.border.container
#CBCCCD
action-menu.color.surface.container
#FFFFFF
action-menu.color.surface.menu-item.rest
#FFFFFF
action-menu.color.surface.menu-item.hover
#F3F3F3
action-menu.color.surface.menu-item.active
#E5E5E6
action-menu.color.surface.separator
#CBCCCD
action-menu.color.text.menu-item.default
#4B4D4F
action-menu.color.text.menu-item.disabled
#7D7F81
action-menu.color.icon.menu-item.default
#323334
action-menu.color.icon.menu-item.disabled
#7D7F81
action-menu.border-radius.all.container
4px
action-menu.border-width.all.container
1px
action-menu.spacing.gap.horizontal.menu-item
8px
action-menu.spacing.margin.all.separator
8px
action-menu.spacing.padding.horizontal.menu-item
16px
action-menu.spacing.padding.vertical.loading
24px
action-menu.spacing.padding.vertical.menu-item
8px
Table of Contents