caliper uidocs

Dropdown menu

Free

A menu of actions anchored to a trigger, with groups, shortcuts and separators.

Installs components/ui/dropdown-menu.tsxDepends on @radix-ui/react-dropdown-menu, lucide-reactMotion none in component source
pnpm dlx shadcn@latest add https://caliperui.site/r/dropdown-menu.json

3 files selected

When to use #

Use it for

  • Row, toolbar and account menus with several actions.
  • Items that deserve keyboard shortcuts or a destructive style.

Skip it when

  • One action is the default; use a split button.
  • The choice sets a form value; use a select.

Installation #

terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/dropdown-menu.json

Adds its 3 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.

Usage #

example.tsx
import { Copy, FolderOpen, Pencil, Trash2 } from "lucide-react"
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuConfirmItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"

export function ProjectMenu() {
  const [status, setStatus] = useState("3 files selected");
  const [sidebar, setSidebar] = useState(true);
  return (
    <div className="grid justify-items-center gap-3 pb-48">
      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button variant="secondary">File actions</Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="start" className="w-64">
          <DropdownMenuLabel>3 files selected</DropdownMenuLabel>
          <DropdownMenuItem onSelect={() => setStatus("Opened 3 files in new tabs.")}><FolderOpen aria-hidden="true" />Open<DropdownMenuShortcut>↵</DropdownMenuShortcut></DropdownMenuItem>
          <DropdownMenuItem onSelect={() => setStatus("Renaming Q3 reconciliation.csv…")}><Pencil aria-hidden="true" />Rename<DropdownMenuShortcut>F2</DropdownMenuShortcut></DropdownMenuItem>
          <DropdownMenuItem onSelect={() => setStatus("Duplicated 3 files.")}><Copy aria-hidden="true" />Duplicate<DropdownMenuShortcut>⌘D</DropdownMenuShortcut></DropdownMenuItem>
          <DropdownMenuSeparator />
          <DropdownMenuCheckboxItem checked={sidebar} onCheckedChange={(value) => setSidebar(value === true)}>Show in sidebar</DropdownMenuCheckboxItem>
          <DropdownMenuSeparator />
          <DropdownMenuConfirmItem
            label="Delete 3 files"
            icon={<Trash2 aria-hidden="true" />}
            question="Delete 3 files?"
            detail="They move to Trash for 30 days."
            onConfirm={() => setStatus("Moved 3 files to Trash. Restore within 30 days.")}
          />
        </DropdownMenuContent>
      </DropdownMenu>
      <p role="status" className="text-sm text-muted-foreground">{status}</p>
    </div>
  );
}

API reference #

DropdownMenu

component

No props of its own; it accepts the native props of its root element.

DropdownMenuTrigger

component

No props of its own; it accepts the native props of its root element.

DropdownMenuContent

component

No props of its own; it accepts the native props of its root element.

DropdownMenuGroup

component

No props of its own; it accepts the native props of its root element.

DropdownMenuItem

component

No props of its own; it accepts the native props of its root element.

DropdownMenuCheckboxItem

component

No props of its own; it accepts the native props of its root element.

DropdownMenuRadioGroup

component

No props of its own; it accepts the native props of its root element.

DropdownMenuRadioItem

component

No props of its own; it accepts the native props of its root element.

DropdownMenuLabel

component

No props of its own; it accepts the native props of its root element.

DropdownMenuSeparator

component

No props of its own; it accepts the native props of its root element.

DropdownMenuShortcut

component

No props of its own; it accepts the native props of its root element.

DropdownMenuConfirmItem

component
PropTypeDefaultDescription
label *string—
iconReactNode—
question *string—e.g. "Delete 3 files?"
detailstring—e.g. "They move to Trash for 30 days."
confirmLabelstring"Delete"
onConfirm *() => void—

Accessibility #

It exposes group semantics, with aria-hidden and aria-label kept in step with state.

Keyboard and focus handling comes from Radix dropdown-menu: arrow keys move through items, Enter and Space select, and Escape closes and returns focus.

Motion #

It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.