Import
import { Menu } from '@dnb/eufemia'
Description
Menu provides an accessible dropdown menu for actions and navigation with a composable, tree-shakeable API.
Use Menu.Root as the wrapper, Menu.Button for the trigger, Menu.List for the list container, Menu.Action for individual items, and Menu.Divider for visual separators.
Menu.Button supports all Button props (e.g. text, icon, variant, size, disabled), so you can customise the trigger the same way you would with a regular Button.
Nested menus are supported by nesting another Menu.Root inside Menu.List — use a Menu.Action as the direct child of the nested Menu.Root to serve as the sub-menu trigger.
For inline expandable groups, use Menu.Accordion instead of a nested Menu.Root. It reveals child items with a height animation inside the current menu, rather than opening a separate popover.
Relevant links
- Source code: https://github.com/dnbexperience/eufemia/tree/main/packages/dnb-eufemia/src/components/menu
- Docs code: https://github.com/dnbexperience/eufemia/tree/main/packages/dnb-design-system-portal/src/docs/uilib/components/menu
Accessibility
- The menu uses ARIA
role="menu"androle="menuitem"semantics. - The trigger receives
aria-haspopup="menu"andaria-expandedattributes automatically. - Keyboard navigation follows the WAI-ARIA Menu Pattern:
- Arrow Up/Down: Move focus between items (wraps around).
- Home/End: Jump to first/last item.
- Enter/Space: Activate the focused item.
- Escape: Close the menu.
- Tab: Close the menu and move focus naturally.
- Arrow Right: Open a sub-menu (when the item has one).
- Arrow Left: Close a sub-menu and return to the parent.
- Type-ahead: pressing a letter key jumps to the first matching item.
- Focus is moved to the menu container when it opens. Arrow keys then move focus to individual items. Focus returns to the trigger when the menu closes.
- Disabled items receive
aria-disabledand are skipped during keyboard navigation. - Dividers use
role="separator".
Demos
Basic Menu
<Menu.Root> <Menu.Button /> <Menu.List> <Menu.Action text="Action" onClick={() => null} /> <Menu.Action text="Link" href="https://www.dnb.no/" /> </Menu.List> </Menu.Root>
Accordion
<Menu.Root> <Menu.Button text="File" icon="chevron_down" /> <Menu.List> <Menu.Action icon={file_add} text="New" onClick={() => console.log('new')} /> <Menu.Action icon={folder} text="Open" onClick={() => console.log('open')} /> <Menu.Divider /> <Menu.Accordion icon={folder} text="Export as"> <Menu.Action icon={file_pdf} text="PDF" onClick={() => console.log('export pdf')} /> <Menu.Action icon={file_png} text="PNG" onClick={() => console.log('export png')} /> </Menu.Accordion> <Menu.Divider /> <Menu.Action icon={save} text="Save" onClick={() => console.log('save')} /> </Menu.List> </Menu.Root>
Nested Menu
<Menu.Root arrowPosition="left"> <Menu.Button text="File" icon="chevron_down" /> <Menu.List> <Menu.Action icon={file_add} text="New" onClick={() => console.log('new')} /> <Menu.Action icon={folder} text="Open" onClick={() => console.log('open')} /> <Menu.Divider /> <Menu.Root placement="right" arrowPosition="top"> <Menu.Action icon={folder} text="Export as" /> <Menu.List> <Menu.Action icon={file_pdf} text="PDF" onClick={() => console.log('export pdf')} /> <Menu.Action icon={file_png} text="PNG" onClick={() => console.log('export png')} /> <Menu.Action icon={file} text="SVG" onClick={() => console.log('export svg')} /> </Menu.List> </Menu.Root> <Menu.Divider /> <Menu.Action icon="close" text="Close" onClick={() => console.log('close')} /> </Menu.List> </Menu.Root>
With Links
<Menu.Root> <Menu.Button text="Navigate" icon="chevron_down" variant="tertiary" /> <Menu.List> <Menu.Action icon={home} text="Home" href="/" /> <Menu.Action icon={layout_card} text="Dashboard" href="/dashboard" /> <Menu.Action icon={launch} text="External" href="https://example.com" target="_blank" rel="noopener noreferrer" /> </Menu.List> </Menu.Root>
Max Visible List Items
<Menu.Root> <Menu.Button text="Long list" icon="chevron_down" /> <Menu.List maxVisibleListItems={4}> <Menu.Action text="Item 1" /> <Menu.Action text="Item 2" /> <Menu.Action text="Item 3" /> <Menu.Action text="Item 4" /> <Menu.Action text="Item 5" /> <Menu.Action text="Item 6" /> <Menu.Action text="Item 7" /> <Menu.Action text="Item 8" /> </Menu.List> </Menu.Root>
With Headers
<Menu.Root> <Menu.Button text="Edit" icon="chevron_down" /> <Menu.List> <Menu.Header text="Clipboard" /> <Menu.Action icon={scissors} text="Cut" onClick={() => console.log('cut')} /> <Menu.Action icon={copy} text="Copy" onClick={() => console.log('copy')} /> <Menu.Action icon={edit} text="Paste" disabled /> <Menu.Divider /> <Menu.Header text="Selection" /> <Menu.Action icon="check" text="Select All" /> </Menu.List> </Menu.Root>