IconButton
A square button that shows only an icon, named by a label that also appears as its tooltip.
import { IconButton } from "@butteryui/react";Demo
When to use it
Use it for
- Header and toolbar actions with a well-known icon: undo, redo, help, settings
- Closing a dialog (size sm)
- Toggles, with aria-pressed
- Something new behind it, such as notifications, with dot
- A top bar's round create button, with variant="primary" and size sm
- An action that should read as a button before it's hovered, such as a card's or a phone toolbar's, with variant="soft" or "outline"
- A 48px row of buttons or fields, or a touch target of its own, with size="lg"
Not for
- An action without an icon everyone reads the same way: use Button with a label
- A page's main action, which needs its words: use Button variant primary
Examples
Canvas toolbar
A slide editor's toolbar: zoom out and in around the zoom level, each aria-disabled at its end, and the grid.
Grid toggle
A toggle that stays tinted while it's on; its name stays put and aria-pressed says whether it's on.
Grid lines show on the slide
History actions
Undo and redo in a header, each aria-disabled, and still focusable, while there's nothing for it to do.
Variants and sizes
Ghost at 36 and 28px with a dot for something new, soft and outline at rest, a 48px soft one and a primary create button.
Last action: Nothing yet
Variants and states
Sizes
36px in headers and toolbars, 28px to close a dialog, 48px beside 48px buttons and fields. Hover or focus one for its tooltip.
Ghost, soft, outline and primary
Ghost shows its background only on hover; soft sits on bg-control and outline draws a 1px edge, so either reads as a button at rest; primary is the round create button. Each at sm, md and lg.
With a dot
An accent dot for something new behind the button; its name says so too.
Toggle and disabled
A toggle holds its background while aria-pressed; a soft toggle fills with the primary color, as a ticked checkbox does.
Props
IconButton
| Prop | Type | Default | Description |
|---|---|---|---|
iconrequired | ComponentType<IconComponentProps> | The icon to draw, such as Undo2 from lucide-react. | |
labelrequired | string | What the button does. Screen readers announce it, and it shows as the tooltip. | |
size | "sm" | "md" | "lg" | "md" | "md" (36px, the default) in headers and toolbars, "sm" (28px) to close a dialog or act inline, or "lg"
(48px, 40 compact) beside 48px buttons and fields, or as a touch target of its own. |
variant | "ghost" | "soft" | "outline" | "primary" | "ghost" | "ghost" (the default), with a background only on hover; "soft", on bg-control at rest, for an action
that should read as a button without hovering, filling with the primary color while aria-pressed;
"outline", a 1px border-strong edge; or "primary", a round create button on the primary color, as in
a top bar. |
tooltipSide | "top" | "right" | "bottom" | "left" | "top" | Which side the tooltip opens on. Defaults to "top". |
tooltip | boolean | true | Whether the label shows as a tooltip. Defaults to true; turn it off while the same words show
elsewhere, such as in a popover the button opened. |
dot | boolean | Draws an accent dot at the icon's top end, for something new behind the button, and adds it to the name. | |
dotLabel | string | "new" | What the dot adds to the button's name. Defaults to "new", read as "Notifications, new". |
asChild | boolean | Render the single child element (such as a link) as the button, with the icon merged in. |
It also takes ComponentPropsWithRef<"button">.
Accessibility
A native button named by label (aria-label); the same label shows as a tooltip on hover and keyboard focus, which doesn't also describe the button, since it repeats the name; a description given in aria-describedby stays. Toggles use aria-pressed. A dot adds ", new" (or dotLabel) to the name.
| Keys | What they do |
|---|---|
| Enter or Space | Presses it, unless it's aria-disabled |
| Enter | Follows the link, when it's a link with asChild |
Motion
It scales to 97% while it's pressed, over `--bt-dur-press`, and springs back when it's let go.
With reduced motion: It presses in at once, without easing, while its hover color still fades over 120ms.
Layout
It's a circle 36px across (--bt-h-button) at size="md", the default, 28px (--bt-h-sm) at "sm" or 48px (--bt-h-cta, 40 compact) at "lg", and it never shrinks. The whole circle is the hit area. Its 16px icon sits in the middle at every size, an outline's 1px edge is drawn inside the circle, and the dot sits on the icon's top end corner without changing the button's size.
Related
See it in the roastery demo. See it in the Halfmoon shop demo. See it in the Deckhand demo.