bx

Dropdown Menu

Displays a menu to the user triggered by a button.

tsx
<DropdownMenu>
  <DropdownMenuTrigger for="menu">
    <Button variant="outline">Open</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent id="menu">
    <DropdownMenuLabel>My Account</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuItem href="/profile">Profile</DropdownMenuItem>
    <DropdownMenuItem>Log out</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

DropdownMenu — menu déroulant classique déclenché au clic (kebab menu, actions user, actions row d'une table). Basé sur le pattern Popover avec des items menu.

Composition : trigger + content + items. Items peuvent être des <a href> ou <div> avec data-ui="close" — cliquer ferme le menu.

Installation

Terminal
$ bext ui add dropdown-menu

Usage

tsx
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator } from "@bext-stack/ui/primitives"

<DropdownMenu>
  <DropdownMenuTrigger for="user-menu">
    <Button variant="outline">Open</Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent id="user-menu" align="end">
    <DropdownMenuLabel>My Account</DropdownMenuLabel>
    <DropdownMenuSeparator />
    <DropdownMenuItem href="/profile">Profile</DropdownMenuItem>
    <DropdownMenuItem href="/settings">Settings</DropdownMenuItem>
    <DropdownMenuSeparator />
    <DropdownMenuItem>Log out</DropdownMenuItem>
  </DropdownMenuContent>
</DropdownMenu>

Anatomy

<DropdownMenu>
  ├── <DropdownMenuTrigger for="menu-id">
  │   └── <Button>Open</Button>
  └── <DropdownMenuContent id="menu-id" align="start|end">
      ├── <DropdownMenuLabel>My Account</DropdownMenuLabel>
      ├── <DropdownMenuSeparator />
      ├── <DropdownMenuItem href="/profile">Profile</DropdownMenuItem>
      └── <DropdownMenuItem>Log out</DropdownMenuItem>

API Reference

Prop Type Default Description
className string Wrapper relative inline-block.
Prop Type Default Description
for string Match l'id du Content.
Prop Type Default Description
id string Match Trigger.for.
align "start" | "end" "start" Alignement horizontal du panel.
className string min-width:8rem par défaut, absolute top-full mt-2 border bg-popover p-1 shadow-md.
Prop Type Default Description
href string Si présent, rend et navigue. Sinon
qui ferme juste le menu.
children ReactNode Label + icônes optionnelles.
Prop Type Default Description
children ReactNode Header non-cliquable (nom de section, ex "My Account").
Prop Type Default Description
Trait fin bg-muted entre groupes d'items.

Data Attributes

Attributs qu'on peut cibler en CSS custom pour override le style par état.

Attribute On Values Description
data-ui="toggle-pop" Trigger data-target="#id" Cliquer ouvre/ferme.
data-overlay data-light Content hidden Popover léger — clic extérieur ferme.
data-ui="close" Item Ferme au clic.

Keyboard

Key Action
Enter / Space Sur trigger : ouvre. Sur item : active + ferme.
Escape Ferme.

Accessibility

Trigger devrait porter aria-haspopup="menu" et aria-expanded. Content devrait porter role="menu", items role="menuitem".

Actuellement en PRISM ces attributs ne sont pas auto — poser à la main sur les items critiques.

Examples

Aligned end (kebab menu)

tsx
<DropdownMenuContent align="end">…</DropdownMenuContent>
Try it live
Open in play

Edit this component live in the bext playground. The PRISM + signals version is the bext-native idiom — fine-grained reactivity, no virtual DOM.

src/app/page.tsx 2 files · signals · runs in your browser
Pure PRISM + real bext signals — fine-grained, no re-render.