---
title: "IconButton"
description: "Square button for an action represented by an icon. It requires an accessible name because the icon alone does not explain the action."
kind: component
id: C-004
registry: "icon-button"
docs: "https://koten.codehive.com.co/components/icon-button"
markdown: "https://koten.codehive.com.co/md/components/icon-button.md"
install: "npx shadcn@latest add https://koten.codehive.com.co/r/icon-button.json"
language: en
---

# IconButton · アイコン

> Component C-004 in the Koten UI catalog.

Square button for an action represented by an icon. It requires an accessible name because the icon alone does not explain the action.

> Japanese labels in this page are documentation metadata. Keep the consumer UI in the product's language and do not add Japanese decoration unless the user asks (R-031).

## Install

Install `koten-theme` first when the project does not have Koten tokens yet. Use the runner of your project.

```bash
# Node
npx shadcn@latest add https://koten.codehive.com.co/r/icon-button.json

# Bun
bunx shadcn@latest add https://koten.codehive.com.co/r/icon-button.json
```

## Files

- `@/components/ui/icon-button.tsx`
- `@/lib/koten/cn.ts`
- `@/lib/koten/format.ts`
- `@/lib/koten/intl.ts`
- `@/lib/koten/labels.ts`
- `@/lib/koten/provider.tsx`

## Examples

### Sizes and variants

Height comes from density; sm, md and lg change the side of the square.

```tsx
<IconButton label="Download" variant="outline" size="sm">
  <Download className="size-3.5" aria-hidden="true" />
</IconButton>
<IconButton label="Download" variant="outline">
  <Download className="size-4" aria-hidden="true" />
</IconButton>
<IconButton label="Settings" variant="primary" size="lg">
  <Settings className="size-4" aria-hidden="true" />
</IconButton>
<IconButton label="Delete" variant="danger">
  <Trash2 className="size-4" aria-hidden="true" />
</IconButton>
<IconButton label="Delete" variant="ghost" disabled>
  <Trash2 className="size-4" aria-hidden="true" />
</IconButton>
```

### Composition with render

render draws a link with the same style; nativeButton=false avoids a nested button.

```tsx
<IconButton
  label="Open settings"
  variant="ghost"
  render={<a href="/settings" />}
  nativeButton={false}
>
  <Settings className="size-4" aria-hidden="true" />
</IconButton>
<IconButton label="Filter orders" variant="outline">
  <Filter className="size-4" aria-hidden="true" />
</IconButton>
```

## Props

| Prop | Type | Default | Notes |
| --- | --- | --- | --- |
| `label` | `string` | `—` | Required; it is the accessible name and replaces visible text. |
| `size` | `sm \| md \| lg` | `md` | Square; the side and height come from density. |
| `variant` | `primary \| secondary \| outline \| ghost \| danger \| link` | `secondary` | The same semantic roles as Button. |
| `disabled` | `boolean` | `false` | Blocks the action and removes it from focus. |
| `loading` | `boolean` | `false` | Shows the spinner, announces aria-busy and disables the button. |
| `render` | `ReactElement \| function` | `—` | Base UI composition; use nativeButton={false} for links. |

## Accessibility

- label is required and becomes aria-label; the icon is aria-hidden.
- Focus and the disabled state follow the Button rules, with a visible outline.
- loading adds aria-busy and disables the button while the action runs.
- For a toggle state use ToggleGroup, not an IconButton with a restyled state.

## Sources

- Catalog page: https://koten.codehive.com.co/components/icon-button
- Markdown: https://koten.codehive.com.co/md/components/icon-button.md
- Repository: https://github.com/codehive-colombia/koten
