Button
Button triggers an action when clicked. It wraps the Spar headless button
primitive and adds Takeoff visual vocabulary — variant, size, loading state, and
icon slots.
Usage
import { Button } from '@takeoff-ui/react-spar';
<Button variant="primary" size="base">
Click me
</Button>
Playground
Variants
Appearance
Sizes
Loading
Disabled
Toggle
Icons
Accessibility & Keyboard
- Renders a native
<button>element by default with correcttype="button". loadingsurfacesaria-busy="true"andaria-live="polite"for screen readers.- Toggle mode exposes
aria-pressedreflecting the current state. - Disabled buttons set
tabIndex={-1}and the nativedisabledattribute.
| Key | Behavior |
|---|---|
| Enter / Space | Activate the button. |
| Tab | Move focus to/from button. |
API Reference
Button
See Spar Button docs for primitive behavior.
Props
| Name | Type | Default | Description |
|---|---|---|---|
| children | React.ReactNode | - | Button label content. |
| variant | ButtonVariant | 'primary' | Color variant. |
| appearance | ButtonAppearance | 'filled' | Visual appearance. |
| size | ButtonSize | 'base' | Size scale. |
| rounded | boolean | false | Renders a pill-shaped (circular) button. Ideal for icon-only actions. |
| startContent | React.ReactNode | - | Content rendered before children — typically an icon, but accepts any node (spinner, badge, kbd, etc.). Wrapped in the icon slot. |
| endContent | React.ReactNode | - | Content rendered after children. Same shape as startContent. |
| loading | boolean | - | Whether the button shows a loading spinner. |
| pressed | boolean | - | Whether the button is pressed. When defined, creates a toggle button. |
| classNames | Partial<Record<ButtonSlot, string>> | - | Per-slot extra classes. |
| slotProps | Partial<Record<ButtonSlot, React.HTMLAttributes<HTMLElement>>> | - | Per-slot HTML-attribute overrides. |
| className | string | - | Appends custom classes to the root slot of this part. |
Events
| Name | Type | Default | Description |
|---|---|---|---|
| onPressedChange | (pressed: boolean) => void | - | Callback fired when toggle state changes |
Data attributes
| Attribute | Applied when | Purpose |
|---|---|---|
| data-slot="root" | Always | Stable selector for wrapper styling on the root slot. |
| data-variant | Always | Reflects the resolved variant prop for theme recipe scoping. |
| data-type | Always | Reflects the resolved appearance prop for theme recipe scoping. |
| data-size | Always | Reflects the resolved size prop for theme recipe scoping. |
| data-rounded | When rounded is true | Styling hook for the pill-shaped state. |
| data-icon-only | When icon-only | Auto-detected when icons exist but no children. |
| data-loading | When loading is true | Styling hook for the loading state. |
| data-disabled | When disabled is true | Styling hook for the disabled state. |
Type Definitions
| Name | Definition |
|---|---|
'primary' | 'secondary' | 'neutral' | 'info' | 'success' | 'danger' | 'warning' | 'white' | 'black' | |
'filled' | 'filledLight' | 'outlined' | 'text' | |
'small' | 'base' | 'large' | |
'root' | 'content' | 'label' | 'spinner' |