Menu

Navigation

Stablev1.0.0

Dropdown menu with keyboard navigation and checkbox support, built on Ariakit.

Preview

Installation

pnpm add @component-labs/ui

Usage

import { Menu } from "@component-labs/ui";

<Menu.Root>
  <Menu.Trigger>Open Menu</Menu.Trigger>
  <Menu.Content>
    <Menu.Item>Item 1</Menu.Item>
    <Menu.Item>Item 2</Menu.Item>
  </Menu.Content>
</Menu.Root>

Props

NameTypeDefaultDescription
variant'default' | 'primary' | 'ghost''default'Visual style variant of the menu trigger button (Menu.Trigger)
size'sm' | 'md' | 'lg''md'Size of the menu trigger button (Menu.Trigger)
showArrowbooleantrueWhether to show arrow icon on trigger (Menu.Trigger)
gutternumber8Space between trigger and menu content (Menu.Content / Menu.SubContent)
Menu.Item.commandstring-Keyboard shortcut displayed on the right side of the item
Menu.SubRootComponent-Wrapper that provides context for a nested submenu
Menu.SubTriggerComponent-Menu item that opens a nested submenu on hover/focus
Menu.SubContentComponent-The dropdown panel for a nested submenu

Examples

Basic Menu

Simple dropdown menu with items and separator

<Menu.Root>
  <Menu.Trigger>Actions</Menu.Trigger>
  <Menu.Content>
    <Menu.Item>Edit</Menu.Item>
    <Menu.Item>Duplicate</Menu.Item>
    <Menu.Separator />
    <Menu.Item>Delete</Menu.Item>
  </Menu.Content>
</Menu.Root>

With Checkboxes

Menu with checkbox items for toggleable options

<Menu.Root>
  <Menu.Trigger>View Options</Menu.Trigger>
  <Menu.Content>
    <Menu.ItemCheckbox defaultChecked>Show toolbar</Menu.ItemCheckbox>
    <Menu.ItemCheckbox>Show sidebar</Menu.ItemCheckbox>
    <Menu.ItemCheckbox defaultChecked>Show footer</Menu.ItemCheckbox>
  </Menu.Content>
</Menu.Root>

Trigger Variants

Different trigger button styles

<div className="flex gap-2">
  <Menu.Root>
    <Menu.Trigger variant="default">Default</Menu.Trigger>
    <Menu.Content>
      <Menu.Item>Item 1</Menu.Item>
    </Menu.Content>
  </Menu.Root>

  <Menu.Root>
    <Menu.Trigger variant="primary">Primary</Menu.Trigger>
    <Menu.Content>
      <Menu.Item>Item 1</Menu.Item>
    </Menu.Content>
  </Menu.Root>

  <Menu.Root>
    <Menu.Trigger variant="ghost">Ghost</Menu.Trigger>
    <Menu.Content>
      <Menu.Item>Item 1</Menu.Item>
    </Menu.Content>
  </Menu.Root>
</div>

Without Arrow

Menu trigger without arrow indicator

<Menu.Root>
  <Menu.Trigger showArrow={false}>No Arrow</Menu.Trigger>
  <Menu.Content>
    <Menu.Item>Item 1</Menu.Item>
  </Menu.Content>
</Menu.Root>

With Commands

Menu items with keyboard shortcut hints

<Menu.Root>
  <Menu.Trigger>Edit</Menu.Trigger>
  <Menu.Content>
    <Menu.Item command="⌘Z">Undo</Menu.Item>
    <Menu.Item command="⌘⇧Z">Redo</Menu.Item>
    <Menu.Separator />
    <Menu.Item command="⌘X">Cut</Menu.Item>
    <Menu.Item command="⌘C">Copy</Menu.Item>
    <Menu.Item command="⌘V">Paste</Menu.Item>
  </Menu.Content>
</Menu.Root>

Submenu

Nested submenu triggered on hover or keyboard

<Menu.Root>
  <Menu.Trigger>Options</Menu.Trigger>
  <Menu.Content>
    <Menu.Item>New File</Menu.Item>
    <Menu.Item>Open</Menu.Item>
    <Menu.SubRoot>
      <Menu.SubTrigger>Share</Menu.SubTrigger>
      <Menu.SubContent>
        <Menu.Item>Email</Menu.Item>
        <Menu.Item>Copy Link</Menu.Item>
        <Menu.Item>Export PDF</Menu.Item>
      </Menu.SubContent>
    </Menu.SubRoot>
    <Menu.Separator />
    <Menu.Item>Delete</Menu.Item>
  </Menu.Content>
</Menu.Root>

Performance

Bundle Size

~5kB gzipped

Minified and gzipped

Dependencies

  • @ariakit/react
  • class-variance-authority

Accessibility

  • Built on Ariakit's accessible Menu component
  • Full keyboard navigation (Arrow keys, Enter, Escape)
  • Proper ARIA attributes (aria-haspopup, aria-expanded)
  • Focus management and trap within menu
  • Screen reader announcements
  • Automatic focus return to trigger on close