┌─── Menu Container (283 px) ───────────────────┐
│ Group Label │ ← 32 px
├───────────────────────────────────────────────│
│ 📋 Menu Item 1 │ ← 42 px
│ ✅ Menu Item 2 (checked) │
│ Menu Item 3 (active state) │
├───────────────────────────────────────────────│ ← Divider
│ ⚠️ Danger Action (error color) │
└───────────────────────────────────────────────┘
- Container — Width ≈ 283 px, with radius
--ds-radius-md and floating shadow
- Section Label — 32 px tall, identifying functional groups
- Menu Item — Fixed 42 px tall, 275 px wide
- Icon — Optional, placed to the left of text
- Divider — Separates different groups
✅ Do
- Group items by frequency of use or logical relationship
- Place destructive actions (delete, logout, etc.) in the last group using Error color style
- Use dividers to separate functional groups for better readability
- Icons aid recognition — keep icon style consistent within a group (all or none)
❌ Don't
- Keep a single group to ≤ 7 items, total groups ≤ 3 — excessive items make the menu too long
- Don't use menus for complex form operations
- Don't mix icon and non-icon items within the same menu
- Don't nest more than 2 levels of submenus — deep nesting is hard to navigate
| State | Description |
|---|
| Default | White background, normal text color |
| Hover | Background highlights to --ds-color-background-tertiary |
| Activated | Background --ds-color-brand-accent1-background, text --ds-color-brand-accent1-default |
| Disabled | Text grays out, pointer-events: none |
| Keyboard navigation | ↑↓ move focus; → expand submenu; ← / Escape close; Enter/Space trigger |
| Requirement | Implementation |
|---|
| Menu container | role="menu" |
| Menu items | role="menuitem" |
| Checkbox menu item | role="menuitemcheckbox" + aria-checked |
| Active item | aria-current="true" |
| Disabled item | aria-disabled="true" |
| Submenu | aria-haspopup="menu" + aria-expanded |
| Focus management | Focus moves to first item on open; returns to trigger on close |