Skip to main content

Overview

Profile
Settings ⌘S
Log out
Dropdown Menu is a floating panel triggered by a click — used for contextual actions, user account menus, and option lists. It supports icons, keyboard shortcuts, checkboxes, radio items, sub-menus, and separators.

Installation

npm install @araf-ds/core

Usage

import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuShortcut,
} from "@araf-ds/core"

export default function Example() {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="outline">My account</Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem>
          <UserIcon size={14} /> Profile
        </DropdownMenuItem>
        <DropdownMenuItem>
          <SettingsIcon size={14} /> Settings
          <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem variant="destructive">
          <LogOutIcon size={14} /> Log out
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Variants

Basic with Icons and Shortcuts

My account
Log out ⇧⌘Q
<DropdownMenu>
  <DropdownMenuTrigger asChild>
    <Button variant="outline">Open</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent align="end" className="w-48">
    <DropdownMenuLabel>My account</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuItem>
      <UserIcon size={14} /> Profile
      <DropdownMenuShortcut>⌘P</DropdownMenuShortcut>
    </DropdownMenuItem>
    <DropdownMenuItem>
      <StarIcon size={14} /> Billing
      <DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
    </DropdownMenuItem>
    <DropdownMenuItem>
      <BarChartIcon size={14} /> Settings
      <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
    </DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem variant="destructive">
      <LogOutIcon size={14} /> Log out
      <DropdownMenuShortcut>⇧⌘Q</DropdownMenuShortcut>
    </DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

With Checkbox Items

Appearance
const [showStatusBar, setShowStatusBar] = useState(true)
const [showSidebar, setShowSidebar] = useState(true)

<DropdownMenuContent>
  <DropdownMenuLabel>Appearance</DropdownMenuLabel>
  <DropdownMenuSeparator />
  <DropdownMenuCheckboxItem
    checked={showStatusBar}
    onCheckedChange={setShowStatusBar}
  >
    Show status bar
  </DropdownMenuCheckboxItem>
  <DropdownMenuCheckboxItem
    checked={showSidebar}
    onCheckedChange={setShowSidebar}
  >
    Show sidebar
  </DropdownMenuCheckboxItem>
</DropdownMenuContent>

With Sub-menu

Edit
Duplicate
Share
<DropdownMenuContent>
  <DropdownMenuItem><EditIcon size={14} /> Edit</DropdownMenuItem>
  <DropdownMenuItem><CopyIcon size={14} /> Duplicate</DropdownMenuItem>
  <DropdownMenuSub>
    <DropdownMenuSubTrigger>
      <ShareIcon size={14} /> Share
    </DropdownMenuSubTrigger>
    <DropdownMenuSubContent>
      <DropdownMenuItem>Email link</DropdownMenuItem>
      <DropdownMenuItem>Copy link</DropdownMenuItem>
      <DropdownMenuItem>Twitter</DropdownMenuItem>
    </DropdownMenuSubContent>
  </DropdownMenuSub>
</DropdownMenuContent>

API Reference

open
boolean
Controlled open state.
onOpenChange
(open: boolean) => void
Callback fired when open state changes.
defaultOpen
boolean
default:"false"
Uncontrolled default open state.
align
string
default:"start"
Horizontal alignment relative to the trigger. Values: start · center · end
side
string
default:"bottom"
Which side to render on. Values: top · right · bottom · left
sideOffset
number
default:"4"
Distance in px between the trigger and the menu.
className
string
Additional class names for the menu panel.
variant
string
default:"default"
Visual style. "destructive" renders item in red.
disabled
boolean
default:"false"
Disables the item — it becomes non-interactive and grayed out.
onSelect
() => void
Callback fired when the item is selected. Menu closes automatically.
checked
boolean
Controlled checked state.
onCheckedChange
(checked: boolean) => void
Callback fired when checked state changes.

Accessibility

  • Dropdown menu uses role="menu" with aria-orientation="vertical"
  • Each item has role="menuitem" (or "menuitemcheckbox" / "menuitemradio")
  • Trigger has aria-haspopup="menu" and aria-expanded
  • Keyboard: Arrow keys navigate items, Enter/Space selects, Escape closes, Tab closes and moves focus
  • Sub-menus open on ArrowRight and close on ArrowLeft or Escape

Do’s & Don’ts

Do

  • Group related actions with DropdownMenuSeparator
  • Use DropdownMenuLabel to label groups of items
  • Add keyboard shortcuts via DropdownMenuShortcut for power users
  • Mark destructive items with variant="destructive" for visual clarity

Don't

  • Don’t use Dropdown Menu for navigation — use a Navbar or Sidebar
  • Don’t put more than 10–12 items without grouping or sub-menus
  • Don’t use it for single-action triggers — use a Button
  • Don’t nest sub-menus more than 2 levels deep