# Dropdown menu

Dropdown menu is a neobrutalist React component from Cruise UI. A short list of actions behind one button, with icons, hints and a destructive item.

Install (with the @cruiseui registry in components.json, see Installation):

```bash
npx shadcn@latest add @cruiseui/dropdown-menu
```

Import: `import { CruiseDropdownMenu } from "@/components/cruise/dropdown-menu";`

## When to use

A few actions behind one button: edit, share, delete.

## When not to

Choosing a value in a form (use a Select).

## Example (React)

```tsx
"use client";

import { Copy, Pencil, Share2, Trash2 } from "lucide-react";
import { CruiseDropdownMenu } from "@/components/cruise/dropdown-menu";

export default function DropdownMenuExample() {
  return (
    <CruiseDropdownMenu
      label="Order options"
      items={[
        { label: "Edit order", icon: <Pencil aria-hidden="true" />, hint: "E" },
        { label: "Duplicate", icon: <Copy aria-hidden="true" />, hint: "D" },
        { label: "Share receipt", icon: <Share2 aria-hidden="true" /> },
        "separator",
        { label: "Cancel order", icon: <Trash2 aria-hidden="true" />, danger: true },
      ]}
    />
  );
}
```

## HTML

Needs theme.css (https://cruiseui.dev/theme.css).

```html
<div class="menu-wrap" data-menu>
  <button type="button" class="brutal btn btn-secondary" id="order-btn" aria-haspopup="menu" aria-expanded="false" aria-controls="order-menu">
    Order options
    <svg class="menu-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
  </button>
  <div class="menu" role="menu" id="order-menu" aria-labelledby="order-btn" hidden>
    <div class="menu-item" role="menuitem" tabindex="-1">Edit order<span class="menu-hint">E</span></div>
    <div class="menu-item" role="menuitem" tabindex="-1">Share receipt</div>
    <div class="menu-sep" role="separator"></div>
    <div class="menu-item" role="menuitem" tabindex="-1" data-danger>Cancel order</div>
  </div>
</div>

<!-- Custom select: same script, role="listbox" -->
<div class="field">
  <span class="field-label" id="area-label">Delivery area</span>
  <div class="menu-wrap" data-menu style="display: block">
    <button type="button" class="select select-trigger" aria-haspopup="listbox" aria-expanded="false" aria-controls="area-list" aria-labelledby="area-label area-value">
      <span class="select-value" id="area-value">Yaba</span>
      <svg class="menu-chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>
    </button>
    <div class="menu" role="listbox" id="area-list" aria-labelledby="area-label" hidden>
      <div class="menu-item" role="option" tabindex="-1" aria-selected="false"><svg class="menu-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Ikeja</div>
      <div class="menu-item" role="option" tabindex="-1" aria-selected="true"><svg class="menu-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" aria-hidden="true"><path d="M20 6 9 17l-5-5"/></svg>Yaba</div>
    </div>
  </div>
</div>
```

## Props: CruiseDropdownMenu

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `ReactNode` | — | Trigger text. |
| `items` | `CruiseMenuEntry[]` | — | — |
| `variant?` | `CruiseButtonVariant` | `"secondary"` | — |
| `align?` | `"start" \| "end"` | `"start"` | — |
| `popupClassName?` | `string` | — | Extra classes on the menu, e.g. "nepa-mode" (it renders in <body>). |
| `className?` | `string` | — | — |

## Accessibility

- role="menu" with menuitems; arrows, Home/End and typing a letter move.
- Esc closes it and returns focus to the trigger; items are 44px tall.
