# Button

```tsx
import { Button } from '@tangible/ui';
```

Interactive docs and examples: [Button in Storybook](https://storybook-tangible-ui.pages.dev/?path=/docs/primitives-button--docs).

## Button props

| Prop | Type | Default | Description |
| - | - | - | - |
| `children?` | `React.ReactNode` | | Rich content for the button. Used when label is not provided. Use this for buttons with custom markup. |
| `className?` | `string` | | Additional CSS class names. Note: Use sparingly. Prefer component API tokens for customization. |
| `disabled?` | `boolean` | `false` | Disabled state. Prevents interaction. |
| `fullWidth?` | `boolean` | `false` | Make button full width of container. |
| `href?` | `string` | | Only in some variants; the others reject it. URL for the link. When provided, Button renders as <a>. |
| `label?` | `React.ReactNode` | | Button label text. If provided, renders as the button content. Use this for simple text buttons. |
| `labels?` | `ButtonLabels` | | Override default English strings for i18n. Covers strings not already handled by existing props (e.g. `loadingLabel`). |
| `leftIcon?` | `React.ReactNode` | | Custom left icon element. Overrides leftIconName. |
| `leftIconName?` | `IconName` | | Icon to display before the label. Use icon registry paths like "system/check". |
| `loading?` | `boolean` | `false` | Loading state: shows a spinner and blocks activation while keeping the button focusable (`aria-disabled`, not native `disabled`), so a keyboard user who triggered it keeps their place. Only `onClick` is guarded: put the action there, not in `onKeyDown`/`onPointerDown`. The start and end of loading aren't announced; confirm completion through your own status message (a Toast, say). |
| `loadingLabel?` | `string` | `` `${label}, loading` (English) `` | Accessible label override during loading state. For i18n support. When loading, this replaces the auto-composed label. |
| `onClick?` | `React.MouseEventHandler<HTMLButtonElement \| HTMLAnchorElement>` | | Click handler. Works for both button and anchor variants. |
| `rel?` | `string` | | Link rel attribute (for anchor variant). |
| `rightIcon?` | `React.ReactNode` | | Custom right icon element. Overrides rightIconName. |
| `rightIconName?` | `IconName` | | Icon to display after the label. Use icon registry paths like "system/chevron-right". |
| `size?` | `"lg" \| "md" \| "sm" \| "xs"` | `'md'` | Size of the button. |
| `style?` | `React.CSSProperties` | | Inline styles. |
| `target?` | `React.HTMLAttributeAnchorTarget` | | Link target (for anchor variant). |
| `theme?` | `"danger" \| "destructive" \| "info" \| "primary" \| "secondary" \| "success" \| "warning"` | `'primary'` | Semantic color theme. Note: Defaults to 'primary' (unlike IconButton which defaults to 'secondary') because Buttons are typically primary CTAs. |
| `variant?` | `"ghost" \| "link" \| "outline" \| "solid"` | `'solid'` | Visual style variant. |

Also accepts the standard attributes of `AnchorHTMLAttributes` and `ButtonHTMLAttributes` (`data-*`, `aria-*`, event handlers), passed to the element it renders.

## Examples

Stories: Playground, Variants, Themes, Sizes, States, With Icons, As Anchor, Full Width, Toggle (aria-pressed), Common Use Cases ([interactive page](https://storybook-tangible-ui.pages.dev/?path=/docs/primitives-button--docs)).

## Component API tokens

Read via fallback, never declared. Set one on an ancestor to restyle every instance under it.

- `--tui-button-bg`
- `--tui-button-fg`
- `--tui-button-border`
- `--tui-button-radius`
- `--tui-button-bg-interact`
- `--tui-button-fg-interact`
- `--tui-button-border-interact`
- `--tui-button-icon-scale`
- `--tui-control-height-xs`
- `--tui-control-height-sm`
- `--tui-control-height-md`
- `--tui-control-height-lg`

---

Interactive version: https://storybook-tangible-ui.pages.dev/?path=/docs/primitives-button--docs
