Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

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.

Quarterly review
100%

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.

Spring launch plan

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

PropTypeDefaultDescription
icon

required

ComponentType<IconComponentProps>The icon to draw, such as Undo2 from lucide-react.
label

required

stringWhat 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".
tooltipbooleantrueWhether 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.
dotbooleanDraws an accent dot at the icon's top end, for something new behind the button, and adds it to the name.
dotLabelstring"new"What the dot adds to the button's name. Defaults to "new", read as "Notifications, new".
asChildbooleanRender 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.

KeysWhat they do
Enter or SpacePresses it, unless it's aria-disabled
EnterFollows 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.

See it in the roastery demo. See it in the Halfmoon shop demo. See it in the Deckhand demo.