Menu
A short list of actions behind a button, usually the row actions on a server or skill.
Examples
Row menu
The default trigger is a small ghost "more" button, named by `label`.
<Menu
label="Actions for GitHub"
items={[
{ name: 'test', label: 'Test connection', icon: 'plug-zap' },
{ name: 'rename', label: 'Rename server', icon: 'pencil' },
{ name: 'logs', label: 'View logs', icon: 'activity' },
{ separator: true },
{ name: 'delete', label: 'Delete server', icon: 'trash', tone: 'danger' },
]}
/>Text trigger, checkbox items
<Menu
label="Show transports"
trigger={{ text: 'Transports', icon: 'cable' }}
placement="bottom-start"
items={[
{ name: 'http', label: 'HTTP', checked: true },
{ name: 'sse', label: 'SSE', checked: true },
{ name: 'stdio', label: 'stdio', checked: false, disabled: true },
]}
/>Usage
import { Menu } from '@switchboard/ui'
<Menu
label={`Actions for ${server.name}`}
items={[
{ name: 'logs', label: 'View logs', icon: 'activity', href: routes.servers.logs.href({ id }) },
{ name: 'pause', label: 'Pause routing', icon: 'route', form: { action: routes.servers.pause.href({ id }) } },
]}
/>Props
Every component also takes mix, for css() and mixins applied after its own style.
Menu
| Prop | Type | Default | Description |
|---|---|---|---|
| label* | string | – | Accessible name of the menu, and of the icon trigger: "Actions for GitHub". |
| items* | MenuEntry[] | – | Items, { separator: true } and { heading: string } (a small group label) entries, in order. |
| trigger | { text?, icon?, variant?, size?, avatar? } | – | With text: a button with a chevron (secondary). With avatar (a name): a round avatar button (account menus). Otherwise a ghost icon button, more-horizontal by default. |
| header | { title: string; description?: string } | – | Non-interactive block over the items: who is signed in. |
| placement | AnchorPlacement | 'bottom-end' | Where the menu opens relative to the trigger. |
MenuEntry
| Prop | Type | Default | Description |
|---|---|---|---|
| name* | string | – | Unique key, sent in the bubbling select event. |
| label* | string | – | Item text. |
| icon | IconName | – | Leading icon. |
| href | string | – | Navigate here when chosen. |
| form | { action: string; fields?: Record<string, string> } | – | POST here when chosen; fields become hidden inputs. |
| tone | 'danger' | – | Red text and highlight, for destructive items. |
| disabled | boolean | – | Shown but not choosable. |
| shortcut | string | – | Hint on the right, e.g. "⌘D". |
| checked | boolean | – | Makes it a checkbox item; shows a check when true. |
| radio | boolean | – | With checked: a radio item (menuitemradio), e.g. the Theme group in the account menu. |
Accessibility
- The trigger is a button with aria-haspopup and aria-expanded; the list has role="menu" and items role="menuitem" (menuitemcheckbox when checked is set).
- Arrow keys move, Home/End jump, typing a letter jumps to an item, Enter or Space chooses.
- Escape and clicks outside close it and return focus to the trigger.
Guidance
Do
- Name the menu after its object: "Actions for GitHub".
- Put destructive items last, after a separator.
Don’t
- Hide the only way to do a common task in a menu; make it a button.
- Put more than about seven items or nested menus in one.