Button

Button.Root is the control. Button.Icon is a compound part. Icon position is DOM order. The icon is decorative (aria-hidden). Icon-only roots need aria-label or aria-labelledby on Button.Root.

Icon-only roots tip that name. A labeled button tips the full string only while the label overflows. tooltip={false} opts out. Fitting labeled buttons do not tip. Auto tips are never interactive.

Variants use the existing paint packs. Default type is button.

Leading icon, trailing icon, icon-only.

Overflowing label.

Toggle

Pass pressed or defaultPressed and the button becomes a toggle: it sets aria-pressed and flips on click. onPressedChange gets the new state. A pressed button keeps the active colors with an inset ring. For a set of toggles, use ToggleGroup.

<Button.Root variant="secondary" pressed={muted} onPressedChange={setMuted}>
  Mute
</Button.Root>

Button.Group

Sibling chrome. role="group". Children are Button.Root. Attached edges overlap by 1px and share the outer radius. No selection state.

When to use

Button.Root

When: One action in a native button. Variants primary / secondary / ghost; default type="button". Icon-only needs aria-label, which it auto-tips.

When not: Navigation → native link (no Link shipped). A setting that takes effect at once → Switch. A form choice → Checkbox. Selected segment → ToggleGroup (Button.Group has no selection).

Button.Icon

When: Decorative icon inside Button.Root. Position = DOM order. Always aria-hidden.

When not: Icon in a field → Field.Icon. Icon as the only name with no aria-label on Root. Outside Button.Root.

Button.Group

When: Attached horizontal row of related Button.Root actions (role="group"). Name it with aria-label.

When not: Toggles → ToggleGroup (no selection state here). Vertical or wrapping rows → Stack. Unrelated actions → separate buttons in Stack.

Props

Button.Root props
NameTypeRequiredDefaultDescription
variant"primary" | "secondary" | "ghost"no"primary"Visual style. Non-primary sets data-button-variant.
type"button" | "submit" | "reset"no"button"Native button type.
disabledbooleannofalseDisables the control.
aria-labelstringno—Required accessible name when the only child is Button.Icon. Auto-tip text for icon-only.
tooltipbooleannotrueIcon-only tips the accessible name. Overflowing labels tip the full string. False opts out. Never tips a fitting labeled button.
pressedbooleanno—Controlled pressed state. Makes the button a toggle with aria-pressed.
defaultPressedbooleanno—Starting pressed state for an uncontrolled toggle. Makes the button a toggle with aria-pressed.
onPressedChange(pressed: boolean) => voidno—Called with the new state when a toggle is clicked. onClick runs first; preventDefault() there skips the change.
childrenReact.ReactNodeno—Label and optional Button.Icon. Order is leading or trailing.
Button.Icon props
NameTypeRequiredDefaultDescription
childrenReact.ReactNodeno—Icon graphic.
Button.Group props
NameTypeRequiredDefaultDescription
aria-labelstringno—Accessible name for the group.
childrenReact.ReactNodeno—Button.Root children. Horizontal only.