ButtonGroup

Segmented glass control wrapping related buttons — mark the active segment with primary (or leave siblings as glass / ghost).

Preview

Live

<div class="btn-group" role="group" aria-label="View density">
  <button type="button" class="btn btn-compact">Comfortable</button>
  <button type="button" class="btn btn-compact btn-primary">Compact</button>
  <button type="button" class="btn btn-compact">Dense</button>
</div>

Variants

Active segment

Mix .btn-primary with glass siblings for the selected option.

Ghost + glass

Ghost and default buttons sit flush inside the pill chrome.

Compact children

Prefer .btn-compact so segments fit dense toolbars.

Accessibility

  • Always provide an accessible name on the group via aria-label (or aria-labelledby).
  • Use role="group" on the wrapper (React ButtonGroup sets this for you).
  • Children should be real <button> elements — not links styled as buttons.
  • Disabled segments use native disabled; focus still moves to enabled siblings.
  • Focus rings are visible on children — do not remove outline without a replacement.

API

HTML classes

Class Description
.btn-group Segmented glass wrapper; children are .btn elements.
.btn (child) Button segments — radius and shadow reset inside the group.
.btn-primary / .btn-ghost / .btn-danger Variant modifiers on children (same as Button).
.btn-compact Recommended on segments for dense groups.

React props

From src/core/ButtonGroup.tsx — extends HTMLAttributes<HTMLDivElement>.

Prop Type Default Description
aria-label string Required accessible name for the group.
children ReactNode Typically Button children.
className string Merged via cx onto .btn-group.