import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks'
import * as IconButtonStories from './IconButton.stories'

<Meta of={IconButtonStories} />

# IconButton

A square button around a 16px icon: 4px padding, 8px radius, three
variants. For the actions a surface repeats too often to label every time.

<Canvas of={IconButtonStories.AllVariants} />

## When

- Toolbars and row-hover actions — edit, copy, dismiss, more.
- A dialog's close.
- `tooltip` names it on hover; `primary` exists for the rare icon action
  that is the point of its surface.

## When not

- The action deserves a visible label → **Button** (words are cheaper than
  a guessed icon).
- Inside a menu → **MenuItem** with `leading`.
- A strip of these acting on one thing → **Toolbar**. The moment rows toggle
  and persist state, see **Checkbox**.

## How

```tsx
import { IconButton } from '@estiva-app/ui'
import { IconPencil } from '@tabler/icons-react'

<IconButton aria-label="Edit" tooltip="Edit" onClick={edit}>
  <IconPencil size={16} stroke={1.5} />
</IconButton>
```

- **`aria-label` is required** — nothing visible names an icon-only
  control. The `tooltip` shows sighted hover users the same word; it does
  not replace the label.
- The icon is 16px at stroke 1.5.
- `variant="current"` takes the colour of what it sits in — the ✕ on a
  `Banner` wears the banner's tone. `variant="resolve"` is `muted` that turns
  green when pointed at in Signal: Resolve, wherever it appears.
- `pressed` is a toggle that is on — Bold while the selection is bold: the
  active fill, and `aria-pressed`. A `ToolbarButton` takes it too.
- `glow` lights it in Signal — the send arrow while there is something to send.
- **Placed from outside, never restyled.** `className` takes space, size,
  flex and grid, and position; a colour, a text size, a border, a corner or a
  shadow is refused by the lint (`estiva/no-restyled-part`).
- `type` defaults to `"button"`; it is a native `<button>` on Base UI's
  Button, and every native prop passes through.
- `disabledReason="Read only"` disables it, keeps it reachable by Tab,
  and shows the reason in place of the tooltip — **on keyboard focus as
  well as on hover**.
- **`href`** makes it a link that looks like the button: an anchor, so the
  address stays real for a modified click or a new tab. It changes page as
  **Link** does. While it cannot be used it
  is the button — a link cannot be disabled.
- `tooltip` costs no wrapper: the button is the tooltip's trigger, so
  this component's root is the `<button>` whether it carries one or not,
  and both sit at the same height. A `Dialog.Close` or a `Menu.Trigger`
  can be an IconButton that has a tooltip.

## What it owns

It does these by itself. Write none of them around it.

| It does | So you never write | Refused when written by hand |
|---|---|---|
| Says what it is to assistive technology: a button | `role="button"` | ✓ |
| Is reachable with Tab, also when it is disabled with a reason | a `tabIndex` | ✓ |
| Presses on Enter and Space, and does nothing while disabled | a key handler |  |

## Keys

| Key | Does |
|---|---|
| Tab | Onto the button, also when it is disabled with a reason; never when it is plain `disabled`. |
| Space / Enter | The action. Nothing while disabled. |

## Props

<Controls of={IconButtonStories.Muted} />
