Skip to main content

What it is

A container that groups a small set of related Buttons so they read as one control rather than several independent ones — shared spacing, a shared boundary, and (for the contained, default and destructive colors) a border treatment that makes adjacent buttons look seamless.

Live example

Exports

Choose ButtonGroup when

  • Two or three Buttons represent closely related actions a reader compares or chooses between at the same moment — not actions scattered across a region.
  • The buttons share the same prominence and are meant to be read as one decision with several outcomes, not a hierarchy of primary and secondary actions.

Choose something else when

Anatomy

ButtonGroup declares no props of its own — every prop it accepts, including variant, size, orientation, and color, is inherited from its base in full.

Variants, sizes, and states

size accepts three values; none renders distinctly. The override that themes a grouped button’s padding and font weight applies identically regardless of size — there is no small/medium/large branch in source. Whatever visual difference the three values produce comes entirely from the underlying framework default, not from a Titan decision.
The design library’s Type axis has three values, not two, and neither side fully covers the other. Confirmed directly from the Figma file (not from Code Connect, which undercounts this): Type is Solid, Ghost, or Icon, at two sizes (Medium, Small). Solid and Ghost correspond to code’s contained and outlined. Neither side has a confirmed counterpart for the other’s third value — code’s text variant has no matching Figma Type, and Figma’s Icon type has no confirmed code equivalent.

Edge and failure states

Tokens

Verified directly from ButtonGroup.overrides.ts — no per-component token emitter exists yet for this concept, so this table is hand-confirmed rather than generated.

Composition

Every published example composes ButtonGroup from plain Button children using the system’s two real color intents — default and destructive, per Button’s own vocabulary. No example mixes the two colors within a single group.

Content

Button label rules apply unchanged to every grouped child — see Button → Content.

Accessibility

  • Renders with a native role="group". Published examples are inconsistent about giving that group an accessible name: some set aria-label (for example, "medium outlined button group"), others set none at all.
  • Each individual Button keeps its own accessible name regardless of the group’s label, so a screen reader user always hears what each button does — an unlabeled group only loses the “these belong together” context, not the individual actions.

Constraints

Known issues

ButtonGroup: open issues

Divergences, open decisions, and undocumented gaps for ButtonGroup.

Why it works this way

The border-hiding treatment is scoped to two colors on purpose, not by oversight. Forcing every adjacent border to match the page background only works cleanly when every child shares one color — which is also the composition rule every published example already follows. A group that mixed colors would need the divider to stay visible to remain legible, so the narrow override and the “one color per group” guidance are the same decision seen twice.

Status

  • Button — the unit ButtonGroup composes
  • Menu — for disclosing more options than a group should show at once
Last modified on September 7, 2026