# IconButton

> A square action with only an icon, a required accessible label and a tooltip-friendly hit area.

Category: Actions. Docs page: https://rime.mjsons.net/components/icon-button

## Installation

```bash
npx shadcn@latest add KezLahd/rime/icon-button
```

IconButton is for compact, well-known actions (close, more, print, remove) where a label would crowd the layout. It takes the same variants as Button, minus the danger secondary, and a pressed state for toggles.

## Usage

```tsx
import { IconButton, IconX } from "@/components/ui";

<IconButton label="Close" icon={<IconX size={18} />} onClick={onClose} />
```

## Props: IconButton

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` (required) | `string` |  | Required: an icon-only control has no other accessible name. |
| `icon` (required) | `ReactNode` |  |  |
| `variant` | `"ghost" \| "secondary" \| "primary" \| "danger"` | `"ghost"` |  |
| `size` | `"sm" \| "md" \| "lg"` | `"md"` |  |
| `loading` | `boolean` |  |  |
| `pressed` | `boolean` |  | Makes it a toggle button (aria-pressed). |
| `asChild` | `boolean` |  | Render the single child element (a Next <Link>, an <a>) with the icon button's look; pass the icon inside the child. |

Also accepts the native attributes of: AriaAttributes, ButtonHTMLAttributes, DOMAttributes, HTMLAttributes.

## Examples

### Variants and states

```tsx
<IconButton label="More actions" icon={<IconMoreHorizontal size={18} />} />
<IconButton label="Print invoice" icon={<IconPrinter size={17} />} variant="secondary" />
<IconButton label="Add project" icon={<IconPlus size={17} />} variant="primary" />
<IconButton label="Filter" icon={<IconFilter size={16} />} pressed />
<IconButton label="Loading" icon={<IconMail size={16} />} loading />
```

## Theme tokens

Per-component tokens. Undeclared by default: the default below is the fallback the CSS uses. Set any of them at :root or on a wrapper to restyle every instance.

| Token | Default |
| --- | --- |
| `--button-height-lg` | `var(--control-h-lg)` |
| `--button-height-md` | `var(--control-h-md)` |
| `--button-height-sm` | `var(--control-h-sm)` |
| `--icon-button-radius` | `var(--r-xs)` / `var(--r-sm)` / `var(--r-md)` |

System tokens it reads: `--blur-callout`, `--brand-gradient`, `--control-h-lg`, `--control-h-md`, `--control-h-sm`, `--danger-fill`, `--danger-ink`, `--dur`, `--ease`, `--focus-ring`, `--glass-edge-strong`, `--glow-md`, `--glow-md-hover`, `--glow-sm`, `--ink-brand`, `--ink-disabled`, `--ink-heading`, `--ink-inverse`, `--ink-muted`, `--r-md`, `--r-sm`, `--r-xs`, `--rgb-brand-deep`, `--rgb-contact`, `--rgb-danger`, `--rgb-white`, `--shadow-control`, `--shadow-specular`, `--shadow-specular-dark`, `--surface-solid`, `--wash-active`, `--wash-subtle`.

## Accessibility

- label is required and becomes the accessible name (aria-label); the icon is hidden from assistive tech.
- pressed sets aria-pressed for toggle buttons.
- sm is 28px: only inside dense rows. Use md (36px) or lg (44px) where it is the main target on touch.

## Do

- Pair an unfamiliar icon with a Tooltip carrying the same label.

## Don't

- Don't use an IconButton for the primary action of a screen; it needs words.

Related: https://rime.mjsons.net/components/button, https://rime.mjsons.net/components/tooltip
