Skip to content

IconButton

A button that shows only an icon: close a dialog, copy a link, open a page in a new tab.

import { IconButton } from '@zitdevs/ui';

quiet has no border, ghost is outlined, primary is filled — the Button’s own words for the same looks.

<IconButton icon="copy" label="Copy link" />
<IconButton icon="download" label="Download the report" variant="ghost" />
<IconButton icon="search" label="Search" variant="primary" />

32, 40 and 48px squares, with 16, 20 and 24px icons.

asChild renders its one child instead of a <button>: the child brings the element and its routing props, the icon button its look, icon and name. See Router links.

import Link from 'next/link';
<IconButton asChild icon="external-link" label="Open the guide" variant="ghost">
<Link href="/guide" />
</IconButton>;

The label is never shown. Where a sighted reader needs it too, wrap the button in a Tooltip, which shows it on hover and on keyboard focus.

<Tooltip id="copy-tip" label="Copy link">
<IconButton icon="copy" label="Copy link" />
</Tooltip>
Prop Type Default Notes
icon IconName required See Icon.
label string required The accessible name, never shown. Say what it does (“Close”), not what it shows (“X”).
variant 'quiet' | 'ghost' | 'primary' 'quiet' No border, outlined, filled.
size 'sm' | 'md' | 'lg' 'md' 32 / 40 / 48px squares, 16 / 20 / 24px icons.
type 'button' | 'submit' | 'reset' 'button' Never submits a form by accident.
disabled boolean false Always renders <button disabled>, even with asChild.
asChild boolean false Renders its one child element (a router’s link) with the button’s classes, icon and name.
children ReactElement — With asChild, the element to render as. Its own children are replaced by the icon.
ref Ref<HTMLButtonElement | HTMLAnchorElement> — The element that renders.
className string — Merged last with cn().
anything else <button> attributes — aria-describedby, aria-expanded, data-*, handlers, and the dialog commands (dialogCloseProps).

Exported types: IconButtonProps, IconButtonVariant, IconButtonSize.

  • Its name is label, as aria-label; the icon is hidden from assistive technology. Name the action (“Copy link”), in the page’s language.
  • No native title: that tooltip shows only to a mouse, late, and cannot be hovered or dismissed. Use Tooltip for a visible label.
  • type="button" unless told otherwise. A disabled one is a <button disabled>, never a dead link.
  • The focus ring is the kit’s own, drawn by the button itself; forced-colours modes paint its outline.
  • The glyph reaches 4.5:1 on its field in every variant. The smallest size, 32px, is above the 24px target minimum (WCAG 2.5.8); prefer md where a finger is the pointer.

A native <button>: it submits a form, runs a dialog’s invoker command, or does what its handler says once the page’s script runs. With asChild and a link, it navigates. A Server Component.

body, ink, subtle, border-default, surface-hover, surface-active, primary, primary-hover, primary-active, primary-disabled, on-primary; the focus ring.

Use instead: an action whose icon alone does not say what it does → Button with icon, which shows its label.