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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| variant | "primary" | "secondary" | "ghost" | no | "primary" | Visual style. Non-primary sets data-button-variant. |
| type | "button" | "submit" | "reset" | no | "button" | Native button type. |
| disabled | boolean | no | false | Disables the control. |
| aria-label | string | no | — | Required accessible name when the only child is Button.Icon. Auto-tip text for icon-only. |
| tooltip | boolean | no | true | Icon-only tips the accessible name. Overflowing labels tip the full string. False opts out. Never tips a fitting labeled button. |
| pressed | boolean | no | — | Controlled pressed state. Makes the button a toggle with aria-pressed. |
| defaultPressed | boolean | no | — | Starting pressed state for an uncontrolled toggle. Makes the button a toggle with aria-pressed. |
| onPressedChange | (pressed: boolean) => void | no | — | Called with the new state when a toggle is clicked. onClick runs first; preventDefault() there skips the change. |
| children | React.ReactNode | no | — | Label and optional Button.Icon. Order is leading or trailing. |
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| children | React.ReactNode | no | — | Icon graphic. |
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| aria-label | string | no | — | Accessible name for the group. |
| children | React.ReactNode | no | — | Button.Root children. Horizontal only. |