Components · Actions
Button group
Joins related buttons into a single segmented control. The outer corners round, the inner borders collapse into shared seams, and the group reads as one unit — a view switch, a density toggle, a small set of mutually-related actions.
Preview
Build with the skill
No package to install — hand this to your AI to generate or migrate the component in your stack.
Apply the Zetta "Button group" component to this project using the zetta-design-md skill.
WHEN TO USE
- Migrating or fixing existing code (the common case): audit the current implementation against the `button-group` spec (variants: item-first, item, item-last) and CORRECT every deviation — replace off-spec values, don't only add new ones.
- New component: build it to the `button-group` spec in this project's stack.
AUDIT & FIX (when the component already exists)
Compare it to the skill's spec and fix, don't just append: hardcoded colors/hex, off-scale radius, wrong fonts, dark/navy fills, shadows used in place of borders (or missing borders), brand lime used as a CTA or interaction (must be primary indigo), and any missing or wrong hover / focus / active / disabled / invalid state or missing 2px focus ring. Replace each with the correct Zetta token.
ALWAYS
- Pull the authoritative spec and tokens from the skill — never guess or hardcode values.
- Use this project's own component conventions and framework idioms.
- Honor the Zetta guardrails (brand = identity only, primary = interaction, shadows for overlays) and verify in Light, Dark, and Accessibility. Anatomy & rules
┌──────────┬──────────┬──────────┐
│ Item 1 │ Item 2 │ Item 3 │
└──────────┴──────────┴──────────┘
↑ ↑ ↑
first middle last
Button Group inherits all states from its child buttons. Additional group-level states:
| State | Visual |
|---|---|
| Default | Child buttons at rest, equal weight |
| One selected | Selected child applies button-icon-selected token set |
| All disabled | disabled prop propagates to all children |
When to use
- A set of mutually related actions that belong together visually (Bold / Italic / Underline, List / Grid / Table view).
- Segmented controls where only one item can be selected at a time.
When not to use
- More than 4 items — use a dropdown or overflow menu.
- Unrelated actions — use individual buttons with spacing between them.
Do
- Use consistent variant across all items in the group (all
button-outlineor allbutton-ghost). - Keep labels short — 1–2 words per button.
- Provide
aria-labelon the group container describing the collective purpose.
Don't
- Don't mix variants within one group (e.g. primary + outline).
- Don't use for navigation — use Tabs instead.
- Parallel structure: all labels should be the same grammatical form (all nouns or all verbs).
- Sentence case. No icons unless all items have icons.
Keyboard
Button Group has no keyboard behavior of its own. Keyboard interaction is handled by the individual child buttons: Tab moves focus to and between the group's buttons, and Enter/Space activates the focused button. See Button for keyboard spec.
Accessibility
- Wrap in
<div role="group" aria-label="...">to expose the group relationship to assistive technology. - Each button within the group must have its own accessible label.
- For segmented selection: use
aria-pressedon each button to indicate selected state.
Spec
Values and token references resolved straight from the Zetta spec.
button-group
- display
- inline-flex
- alignItems
- stretch
- gap
- 0
button-group-item
- borderRadius
- {rounded.none}
- borderRightWidth
- 0
button-group-item-first
- borderRadius
- {rounded.base} 0 0 {rounded.base}
button-group-item-last
- borderRadius
- 0 {rounded.base} {rounded.base} 0
- borderRightWidth
- 1px
button-group-item-only
- borderRadius
- {rounded.base}
- borderRightWidth
- 1px
Known gaps
- Overflow behavior for 5+ items — no defined collapse pattern; use dropdown menu instead.
- Vertical orientation variant — not yet tokenized.