Components
Icon button
View in FigmaSquare, icon-only button that reuses the button variants and requires an accessible label.
Install
npx shadcn@latest add @alix/iconButtonPreview
Usage
<IconButton aria-label="Add">
<Plus />
</IconButton>
<IconButton variant="outline" aria-label="Next">
<ArrowRight />
</IconButton>
<IconButton size="iconSm" aria-label="Search">
<Search />
</IconButton>
<IconButton loading aria-label="Saving">
<Plus />
</IconButton>Examples
01
Compact toolbar sizes
Use the smaller square sizes when a dense toolbar needs several familiar actions in one row.
<IconButton size="iconXs" variant="ghost" aria-label="Search insights"><Search /></IconButton>
<IconButton size="iconSm" variant="outline" aria-label="Download report"><Download /></IconButton>
<IconButton aria-label="Add workstream"><Plus /></IconButton>
<IconButton size="iconLg" variant="secondary" aria-label="Next service"><ArrowRight /></IconButton>02
Destructive and busy states
Destructive, disabled, and loading states keep icon-only actions honest when the label is hidden.
<IconButton variant="destructive" aria-label="Remove person"><Trash2 /></IconButton>
<IconButton variant="outline" disabled aria-label="Download locked report"><Download /></IconButton>
<IconButton loading aria-label="Saving action"><Plus /></IconButton>03
Toolbar with visible escape
Pair a visible Button with tooltip-backed icon actions when only the secondary commands can be icon-only.
<Inline gap="sm">
<Button variant="outline" leftIcon={<Download />}>Export report</Button>
<Tooltip content="Search insights">
<IconButton variant="ghost" aria-label="Search insights"><Search /></IconButton>
</Tooltip>
<Tooltip content="More actions">
<IconButton variant="ghost" aria-label="More actions"><MoreHorizontal /></IconButton>
</Tooltip>
</Inline>When to use it
Use it for
- Dense toolbars where the action icon is conventional: search, download, close, or more actions.
- Secondary commands beside a labelled Button when the row would otherwise become noisy.
- Transient loading on icon-only actions where aria-busy needs to follow the disabled state.
Reach for something else
- Primary page actions that need a visible verb — use Button instead.
- Overflow lists or more than three hidden commands — use Menu instead.
- Hints that explain an unfamiliar icon — wrap the IconButton in Tooltip.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| aria-label | string | — | Required accessible label — the button has no visible text, so this names it for assistive tech. |
| children | ReactNode | — | The icon to render. Replaced by a spinner while loading. |
| variant | "default" | "secondary" | "destructive" | "outline" | "ghost" | "default" | Visual style. The "link" variant is excluded — an underline makes no sense on an icon-only control. |
| size | "icon" | "iconXs" | "iconSm" | "iconLg" | "icon" | Square control size — padding plus the icon dimension. |
| loading | boolean | false | Shows a spinner, disables interaction, and sets aria-busy. |