Menu buttons
Buttons that open a menu of actions: a labelled Menu button, a Combo button that pairs the main action with related ones, and the Overflow button that tucks secondary actions behind three dots.
Live preview
Rendered by the component itself from the same generated tokens as the rest of the site.
<MenuButton
label="Actions"
items={items}
/>Installation
Install it with the shadcn CLI, along with everything it uses. New project? Set it up first, as Quick start shows.
npx shadcn@latest add https://www.graphite-ui.com/r/menu-button.jsonimport { ComboButton, MenuButton, OverflowMenu } from '@/components/ui/menu-button'Anatomy
The trigger is the governed Button and the menu the governed Menu, flush under it (or over it). A Combo button is the primary action and a chevron button 1 apart; only the chevron opens the menu, which lines up with the pair’s start.
- TriggerRequiredThe governed Button. The Menu button form is a primary Button whose label names the menu, with a trailing chevron; the combo form is the primary action and, 1 apart, a primary icon-only Button with the chevron that opens related actions; the overflow form is a ghost icon-only Button with the menu dots. Icon-only triggers are named ("More actions", "Options").
- MenuRequiredThe governed Menu, flush on its trigger. Its rows take the trigger's size.
Variants
Menu button is a labelled primary Button with a chevron that turns over while open. Combo button keeps one action in reach and the rest in the menu. Overflow is a ghost icon button with the menu dots; its menu lines up with the trigger’s start or end.
States
Hover, Focus and Active are Button’s own. Open is the menu showing, with the chevron turned over. Disabled disables the whole trigger.
API reference
Generated from the contract, versioned with it, and checked by drift-check. This table cannot describe props the component does not have.
| Prop | Type | Default | Notes |
|---|---|---|---|
| items | — | — | Menu's items. |
| size | 'sm' | 'md' | 'lg' | — | The kit's Size. The trigger at 32, 40 or 48 (the kit draws the labelled Large Button at 50, Button's +2), and the menu's rows with it. Large by default, as the kit's sets are. |
| placement | 'bottom' | 'top' | — | The kit's Position. |
| label | — | — | The Menu button's text; the combo form's primary action; the overflow form's accessible name ("Options" by default). |
| align | 'start' | 'end' | — | The overflow form's Alignment, which edge of the trigger the menu lines up with. The combo form's menu lines up with the pair's start; the Menu button's with its start. |
| onClick / menuLabel | — | — | The combo form's primary action, and the name of its menu button ("More actions" by default). |
| disabled | boolean | — |
Design tokens
Every swatch is live. Change the source color in the header and this table repaints, because it reads the same roles the component does.
motionThe chevron turning over while the menu is open.
Usage
The contract's prohibitions, written as the choices you will actually face.
Do
- Name a Menu button for what is in the menu: “Actions”, “Export”.
- Use a Combo button where one action is the usual one and the rest are its variants.
- Use Overflow for secondary actions on a row or a card, aligned to the end at the right edge.
- Keep destructive items last, after a separator.
Don’t
- Open a menu of one item. That is a Button.
- Put the only route to an action behind Overflow when there is room to show it.
- Leave an icon-only trigger unnamed.
- Restyle the trigger or the menu. They are the governed Button and Menu.
Accessibility
What the component does for you, and what it leaves to you.
- Roles
- Each trigger is a button with
aria-haspopup="menu"andaria-expanded; the menu is amenuofmenuitems, as Menu draws it. - Keyboard
- Enter, Space or Arrow Down opens the menu on its first item; Arrow Up on its last. Arrows move, Escape closes and returns focus to the trigger, Tab leaves.
- Names
- A Menu button is named by its label. Combo button’s chevron is “More actions”, Overflow is “Options” by default; both can be renamed.
- Focus
- Each trigger takes Button’s focus ring; the items take Menu’s.
Figma parity
The kit’s Menu buttons page has three public sets. The code has one component for each, over Button and Menu.
| Kit axis | Values | Code | How it maps |
|---|---|---|---|
| Set | Menu button · Combo button · Overflow | — | Three components, one contract. |
| Size | Large · Medium · Small | size | The trigger at 48, 40 or 32 and the menu’s rows with it. |
| Position | Bottom · Top | placement | Menu’s placement, flush on the trigger. |
| Alignment | Start · End | align | Overflow only: Menu’s align. |
| State | Enabled · Hover · Focus · Active · Disabled | disabled | Hover, Focus and Active are Button’s pseudo-classes. |
| Open | False · True | — | The menu showing; the chevron turns over (the kit draws no open glyph). |
| Glyph | fi-rs-plus-small | — | All three sets draw Button’s default plus, never swapped. The code draws the chevron and the menu dots. |
