# IconButton

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

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

## IconButton props

| Prop | Type | Default | Description |
| - | - | - | - |
| `icon` | `IconName` | | Icon to display. Required — this is the button's visual content. |
| `label` | `string` | | Accessible label. Required — icon-only buttons must have a label for screen readers since there's no visible text. |
| `className?` | `string` | | Additional CSS class names. |
| `disabled?` | `boolean` | | Disabled state. |
| `href?` | `string` | | Only in some variants; the others reject it. |
| `loading?` | `boolean` | | 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. |
| `pressed?` | `boolean` | | Pressed state for toggle buttons. When true, applies aria-pressed="true" and active styling. |
| `shape?` | `"circle" \| "square"` | `'square'` | Button shape. Use `'circle'` for avatar-adjacent actions, FABs, or anywhere a round affordance is expected. |
| `showTooltip?` | `boolean` | `false` | Show the label as a tooltip on hover. Since icon-only buttons have no visible text, enabling this helps sighted users discover what the button does. Recommended for most standalone icon buttons. Can be omitted in toolbars where a shared Tooltip provider handles it, or where adjacent visible text already communicates the action. |
| `size?` | `"lg" \| "md" \| "sm" \| "xs"` | `'sm'` | Size of the button. `'xs'`: 24px — below WCAG 2.5.8 minimum target size (24×24 CSS px). Use only in dense, mouse-first UIs (toolbars, table rows) where touch is not expected. Consider pairing with adequate spacing or a larger touch target via padding/margin. `'sm'`: 32px (default); `'md'`: 40px; `'lg'`: 48px |
| `theme?` | `"danger" \| "info" \| "primary" \| "secondary" \| "success" \| "warning"` | `'secondary'` | Semantic color theme. Note: Defaults to 'secondary' (unlike Button which defaults to 'primary') because IconButtons are typically used for toolbar/utility actions. |
| `tooltipSide?` | `"bottom" \| "left" \| "right" \| "top"` | `'top'` | Tooltip placement side. |
| `variant?` | `"ghost" \| "outline" \| "solid"` | `'ghost'` | Visual style variant. `'solid'`: Filled background; `'outline'`: Border only, transparent background; `'ghost'`: No border or background, icon only — has no at-rest visual affordance. Best suited for toolbar groups, icon bars, or other contexts where surrounding UI makes the interactive nature obvious. |

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, Common Use Cases, States, Pressed State (Toggles), As Link, Circle Shape, With Tooltip ([interactive page](https://storybook-tangible-ui.pages.dev/?path=/docs/primitives-iconbutton--docs)).

## Component API tokens

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

- `--tui-icon-button-bg`
- `--tui-icon-button-fg`
- `--tui-icon-button-border`
- `--tui-icon-button-radius`
- `--tui-icon-button-bg-interact`
- `--tui-icon-button-fg-interact`
- `--tui-icon-button-bg-pressed`
- `--tui-icon-button-fg-pressed`

---

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