Components / Overlays
DropdownMenu Stable A menu of actions or options opened from a button, with groups, checkable items and submenus.
Use DropdownMenu for a set of actions that apply to the current context, such as everything you can do with a signature template. For choosing a value in a form, use Select; for site navigation, use NavigationMenu. DropdownMenu implements the WAI-ARIA menu pattern with roving focus, typeahead and submenus, and has no third-party dependencies.
Overview tsx Copy
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, Icon } from '@bindshq/stance-react';
export function Basic() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" trailingIcon={<Icon name="chevron-down" />}>
Template actions
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Edit template</DropdownMenuItem>
<DropdownMenuItem>Duplicate</DropdownMenuItem>
<DropdownMenuItem>Assign to users</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem destructive>Delete template</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}Light, dark and high contrast Every Stance component is designed and tested in all three appearance modes.
Import tsx Copy
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent } from '@bindshq/stance-react';DropdownMenu has native counterparts. They share Stance tokens and intent, and use each platform’s own controls and conventions. The live previews on this page are the web implementation.
Web · React iOS and iPadOS · SwiftUI Android · Jetpack Compose
tsx Copy
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent } from '@bindshq/stance-react';Examples Icons sit before the label; shortcuts are hints only and are hidden from assistive technology.
Signature
tsx Copy
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, Icon } from '@bindshq/stance-react';
export function WithIconsAndShortcuts() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="secondary">Signature</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem icon={<Icon name="pencil" />}>
Edit <DropdownMenuShortcut>⌘E</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem icon={<Icon name="copy" />}>
Copy HTML <DropdownMenuShortcut>⌘C</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem icon={<Icon name="download" />}>Download as image</DropdownMenuItem>
<DropdownMenuItem icon={<Icon name="send" />} disabled>
Deploy (no integration)
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem icon={<Icon name="trash" />} destructive>
Delete
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}Checkable items keep the menu open so several settings can be changed at once.
tsx Copy
import * as React from 'react';
import { Button, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, Icon } from '@bindshq/stance-react';
export function Checkable() {
const [banner, setBanner] = React.useState(true);
const [social, setSocial] = React.useState(false);
const [layout, setLayout] = React.useState('horizontal');
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" leadingIcon={<Icon name="sliders" />}>
Preview options
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>Show</DropdownMenuLabel>
<DropdownMenuCheckboxItem checked={banner} onCheckedChange={setBanner}>
Promotional banner
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem checked={social} onCheckedChange={setSocial}>
Social icons
</DropdownMenuCheckboxItem>
<DropdownMenuSeparator />
<DropdownMenuLabel>Layout</DropdownMenuLabel>
<DropdownMenuRadioGroup value={layout} onValueChange={setLayout}>
<DropdownMenuRadioItem value="horizontal">Horizontal</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="stacked">Stacked</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="compact">Compact</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
);
}tsx Copy
import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger, Icon } from '@bindshq/stance-react';
export function Groups() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" leadingIcon={<Icon name="user" />}>
Amara Okafor
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuGroup label="Account">
<DropdownMenuItem icon={<Icon name="user" />}>Profile</DropdownMenuItem>
<DropdownMenuItem icon={<Icon name="settings" />}>Settings</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup label="Organisation">
<DropdownMenuItem icon={<Icon name="building" />}>Binds Ltd</DropdownMenuItem>
<DropdownMenuItem icon={<Icon name="credit-card" />}>Billing</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuItem icon={<Icon name="log-out" />}>Sign out</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}Accessibility The trigger has aria-haspopup="menu", aria-expanded and aria-controls; the menu is labelled by the trigger. Items use role menuitem, menuitemcheckbox or menuitemradio with aria-checked, so state is announced. Focus moves into the menu on open and returns to the trigger when it closes by Escape, selection or Tab. Disabled items expose aria-disabled and are skipped by arrow keys. Clicks inside a submenu never dismiss the parent; clicks outside dismiss the whole menu. High contrast mode adds a visible focus ring to the highlighted item; Windows forced colours use the system Highlight. Keyboard Usage guidelines Do Group related actions and put destructive ones last, after a separator. Keep labels short and verb-first: “Duplicate”, “Assign to users”. Don’t Use a menu for navigation links; use NavigationMenu. Nest submenus more than one level deep.