Skip to main content
A dropdown menu displays a list of actions or options when triggered, supporting nested submenus, checkboxes, radio groups, and keyboard navigation.

Installation

npm install @kuzenbo/core

Usage

Basic Example

import { DropdownMenu, Button } from "@kuzenbo/core";

export default function DropdownMenuExample() {
  return (
    <DropdownMenu>
      <DropdownMenu.Trigger render={<Button variant="outline" />}>
        Workspace: Acme Platform
      </DropdownMenu.Trigger>
      <DropdownMenu.Content>
        <DropdownMenu.Group>
          <DropdownMenu.Label>Workspace actions</DropdownMenu.Label>
          <DropdownMenu.Item>Open workspace settings</DropdownMenu.Item>
          <DropdownMenu.Item>Invite teammate</DropdownMenu.Item>
        </DropdownMenu.Group>
        <DropdownMenu.Separator />
        <DropdownMenu.Item variant="danger">Leave workspace</DropdownMenu.Item>
      </DropdownMenu.Content>
    </DropdownMenu>
  );
}

With Checkbox Items

import { DropdownMenu, Button } from "@kuzenbo/core";

export default function CheckboxExample() {
  return (
    <DropdownMenu>
      <DropdownMenu.Trigger render={<Button variant="outline" />}>
        Columns
      </DropdownMenu.Trigger>
      <DropdownMenu.Content>
        <DropdownMenu.Group>
          <DropdownMenu.Label>Table columns</DropdownMenu.Label>
          <DropdownMenu.CheckboxItem defaultChecked>
            Status
          </DropdownMenu.CheckboxItem>
          <DropdownMenu.CheckboxItem defaultChecked>
            Owner
          </DropdownMenu.CheckboxItem>
          <DropdownMenu.CheckboxItem>
            Priority
          </DropdownMenu.CheckboxItem>
        </DropdownMenu.Group>
      </DropdownMenu.Content>
    </DropdownMenu>
  );
}

With Submenu

import { DropdownMenu, Button } from "@kuzenbo/core";

export default function SubmenuExample() {
  return (
    <DropdownMenu>
      <DropdownMenu.Trigger render={<Button variant="outline" />}>
        Options
      </DropdownMenu.Trigger>
      <DropdownMenu.Content>
        <DropdownMenu.Item>Open dashboard</DropdownMenu.Item>
        <DropdownMenu.Sub>
          <DropdownMenu.SubTrigger>Switch workspace</DropdownMenu.SubTrigger>
          <DropdownMenu.SubContent>
            <DropdownMenu.Item>Acme Platform</DropdownMenu.Item>
            <DropdownMenu.Item>Security Ops</DropdownMenu.Item>
            <DropdownMenu.Item>Customer Success</DropdownMenu.Item>
          </DropdownMenu.SubContent>
        </DropdownMenu.Sub>
        <DropdownMenu.Separator />
        <DropdownMenu.Item>Settings</DropdownMenu.Item>
      </DropdownMenu.Content>
    </DropdownMenu>
  );
}

With Shortcuts

import { DropdownMenu, Button } from "@kuzenbo/core";

export default function ShortcutsExample() {
  return (
    <DropdownMenu>
      <DropdownMenu.Trigger render={<Button variant="outline" />}>
        Actions
      </DropdownMenu.Trigger>
      <DropdownMenu.Content>
        <DropdownMenu.Group>
          <DropdownMenu.Label>Release workflow</DropdownMenu.Label>
          <DropdownMenu.Item>
            Start release
            <DropdownMenu.Shortcut>⌘R</DropdownMenu.Shortcut>
          </DropdownMenu.Item>
          <DropdownMenu.Item>
            Rollback
            <DropdownMenu.Shortcut>⇧⌘R</DropdownMenu.Shortcut>
          </DropdownMenu.Item>
        </DropdownMenu.Group>
      </DropdownMenu.Content>
    </DropdownMenu>
  );
}

Composed Anatomy

import { DropdownMenu, Button } from "@kuzenbo/core";

export default function ComposedDropdown() {
  return (
    <DropdownMenu>
      <DropdownMenu.Trigger render={<Button variant="outline" />}>
        Account
      </DropdownMenu.Trigger>
      <DropdownMenu.Portal>
        <DropdownMenu.Backdrop />
        <DropdownMenu.Positioner>
          <DropdownMenu.Popup>
            <DropdownMenu.Arrow />
            <DropdownMenu.Group>
              <DropdownMenu.Label>Account</DropdownMenu.Label>
              <DropdownMenu.Item>Profile</DropdownMenu.Item>
              <DropdownMenu.LinkItem href="/billing">
                Billing
              </DropdownMenu.LinkItem>
            </DropdownMenu.Group>
            <DropdownMenu.Separator />
            <DropdownMenu.Item variant="danger">Sign out</DropdownMenu.Item>
          </DropdownMenu.Popup>
        </DropdownMenu.Positioner>
      </DropdownMenu.Portal>
    </DropdownMenu>
  );
}

API Reference

defaultOpen
boolean
The initial open state when uncontrolled.
open
boolean
The controlled open state of the menu.
onOpenChange
(open: boolean) => void
Callback fired when the open state changes.
size
'xs' | 'sm' | 'md' | 'lg' | 'xl'
default:"'md'"
The size variant for the menu.
side
'top' | 'right' | 'bottom' | 'left'
default:"'bottom'"
The preferred side of the trigger to render against.
sideOffset
number
default:"4"
The distance in pixels from the trigger.
align
'start' | 'center' | 'end'
default:"'start'"
The alignment of the menu relative to the trigger.
alignOffset
number
default:"0"
The offset in pixels from the alignment axis.
size
'xs' | 'sm' | 'md' | 'lg' | 'xl'
Override the root size for this content.
className
string
Additional CSS classes to apply.
variant
'default' | 'danger'
default:"'default'"
The visual variant of the item.
disabled
boolean
Whether the item is disabled.
onSelect
() => void
Callback fired when the item is selected.
checked
boolean
The controlled checked state.
defaultChecked
boolean
The initial checked state when uncontrolled.
onCheckedChange
(checked: boolean) => void
Callback fired when the checked state changes.
value
string
The controlled value of the selected radio item.
defaultValue
string
The initial value when uncontrolled.
onValueChange
(value: string) => void
Callback fired when the value changes.
value
string
required
The value of this radio item.
href
string
required
The URL to navigate to.
children
ReactNode
The label content.
Visual separator between menu items.
children
ReactNode
The keyboard shortcut text.
render
ReactElement
The element to render as the trigger.

Component Parts

  • DropdownMenu - Root component that manages state
  • DropdownMenu.Trigger - Opens the menu
  • DropdownMenu.Portal - Portals the menu content
  • DropdownMenu.Positioner - Positions the menu relative to trigger
  • DropdownMenu.Popup - The menu container
  • DropdownMenu.Content - Convenience wrapper
  • DropdownMenu.Item - A menu item
  • DropdownMenu.CheckboxItem - A checkable menu item
  • DropdownMenu.RadioGroup - Groups radio items
  • DropdownMenu.RadioItem - A radio menu item
  • DropdownMenu.LinkItem - A navigation menu item
  • DropdownMenu.Label - A non-interactive label
  • DropdownMenu.Separator - Visual separator
  • DropdownMenu.Shortcut - Keyboard shortcut indicator
  • DropdownMenu.Sub - Submenu root
  • DropdownMenu.SubTrigger - Opens a submenu
  • DropdownMenu.SubContent - Submenu content
  • DropdownMenu.Group - Groups related items
  • DropdownMenu.Arrow - Visual arrow indicator
  • DropdownMenu.Backdrop - Optional backdrop overlay

Accessibility

  • Full keyboard navigation support
  • Arrow keys navigate between items
  • Enter or Space activates items
  • Escape closes the menu
  • Type-ahead to focus items
  • Proper ARIA attributes
  • Focus management on open/close

Build docs developers (and LLMs) love