Skip to content

IconButton

An icon-only action with a required name, shown as a tooltip on hover and keyboard focus.

  • Free core, MIT
  • Version 2.0.0-rc.1
  • APG pattern: Button (with Tooltip)

Examples

These are the real React components. Use them with a mouse, touch or keyboard, and switch the theme and density for every example at once.

Default

Show the code

Default, code

<IconButton icon={Settings} label="Settings" />

Variants

Show the code

Variants, code

<div className="flex flex-wrap items-center gap-gap-md">
  <IconButton icon={Search} label="Search" variant="default" />
  <IconButton icon={Pencil} label="Edit" variant="secondary" />
  <IconButton icon={Bell} label="Notifications" variant="outline" />
  <IconButton icon={Settings} label="Settings" variant="ghost" />
  <IconButton icon={Trash2} label="Delete" variant="destructive" />
</div>

Sizes

Show the code

Sizes, code

<div className="flex flex-wrap items-center gap-gap-md">
  <IconButton icon={Settings} label="Settings, small" size="sm" variant="outline" />
  <IconButton icon={Settings} label="Settings, default" variant="outline" />
  <IconButton icon={Settings} label="Settings, large" size="lg" variant="outline" />
  <IconButton icon={Settings} label="Settings, touch" size="touch" variant="outline" />
</div>

Inline

Show the code

Inline, code

<div className="flex items-center gap-gap-lg p-inset-md">
  <IconButton icon={X} label="Clear, inline" size="inline" />
  <IconButton icon={X} label="Clear, inline outline" size="inline" variant="outline" />
  <IconButton icon={X} label="Clear, inline round" size="inline" shape="round" variant="secondary" />
</div>

Surfaces

Show the code

Surfaces, code

<div className="flex flex-wrap items-center gap-gap-lg">
  <div className="flex items-center gap-gap-md rounded-surface bg-surface p-inset-lg">
    <IconButton icon={Pause} label="Pause" surface="media" shape="round" />
    <IconButton icon={Heart} label="Like" surface="media" />
    <IconButton icon={Camera} label="Switch camera" surface="media" size="touch" shape="round" />
    <IconButton icon={Share} label="Share, disabled" surface="media" isDisabled />
  </div>
  <div className="flex items-center gap-gap-md rounded-surface bg-action-primary p-inset-lg">
    <IconButton icon={X} label="Close banner" surface="brand" />
    <IconButton icon={Share} label="Share offer" surface="brand" shape="round" />
  </div>
</div>

Shapes

Show the code

Shapes, code

<div className="flex flex-wrap items-center gap-gap-md">
  <IconButton icon={ArrowLeft} label="Back" variant="outline" />
  <IconButton icon={ArrowLeft} label="Back, round" variant="outline" shape="round" />
  <IconButton icon={X} label="Close, round ghost" shape="round" />
  <IconButton icon={X} label="Close, round touch" variant="secondary" shape="round" size="touch" />
</div>

Tooltip open

Show the code

Tooltip open, code

<div className="flex items-center gap-gap-md pt-16">
  <IconButton icon={Settings} label="Settings" variant="outline" defaultTooltipOpen />
</div>

Disabled

Show the code

Disabled, code

<IconButton icon={Settings} label="Settings" isDisabled variant="outline" />

Tokens

The 21 design tokens IconButton reads, with the value each has in the theme and density chosen above. Change a token and the component follows, in Figma and in code.

Show all 21 tokens
Tokens IconButton reads
TokenValue nowCSS variable
button.height.lg…--sd-button-height-lg
button.height.sm…--sd-button-height-sm
color.action.primary…--sd-color-action-primary
color.action.primary-hover…--sd-color-action-primary-hover
color.action.primary-pressed…--sd-color-action-primary-pressed
color.bg.on-media…--sd-color-bg-on-media
color.bg.on-media-hover…--sd-color-bg-on-media-hover
color.border.control…--sd-color-border-control
color.text.on-media…--sd-color-text-on-media
color.text.on-primary…--sd-color-text-on-primary
elevation.2…--sd-elevation-2
icon-button.icon…--sd-icon-button-icon
icon-button.size…--sd-icon-button-size
layer.tooltip…--sd-layer-tooltip
radius.full…--sd-radius-full
size.icon.sm…--sd-size-icon-sm
space.8…--sd-space-8
target.min…--sd-target-min
tooltip.bg…--sd-tooltip-bg
tooltip.fg…--sd-tooltip-fg
tooltip.radius…--sd-tooltip-radius

Install

The npm package isn’t published yet. When it is, this is the install line; until then, this page runs the same build of the package (from commit fa3abf8).

Install

npm i @superduperui/react @superduperui/tokens

Import

import { IconButton } from "@superduperui/react"

Props

IconButton also takes the props of the React Aria component it’s built on.

IconButton props
PropTypeWhat it does
iconrequiredLucideIconThe Lucide icon.
labelrequiredstringRequired accessible name: becomes aria-label and the tooltip text. An unnamed icon button does not compile.
variantExclude<ButtonVariant, 'link'>Default 'ghost'
sizeButtonSize | 'touch' | 'inline'Default 'default'sm 36px visual (44px hit area), default 44 x 44, lg 52 x 52, touch 48 x 48 with a 24px icon (the mobile preset; never under target.min), inline a 32px box with a 16px icon whose 44px target reaches outside it (a clear button inside a field, so the row keeps its own height; keep 44px clear around it).
surface'media' | 'brand'For a button on something other than the screen background. media: the on-media backing with a white glyph, for photos, video, maps and camera views (proven against a white image underneath). brand: the brand fill with the on-primary glyph, for a button on a brand-coloured surface. Either one replaces the variant's colours. In Figma this is the MediaButton set.
shape'square' | 'round'Default 'square'square (default) uses the control radius; round is a circle (radius full), for header and overlay buttons. The size, and so the 44px target, is the same.
showTooltipbooleanDefault trueShow the label as a tooltip on hover and keyboard focus (1.4.13: hoverable, dismissable with Esc). Default true.
tooltipPlacement'top' | 'bottom' | 'start' | 'end'Default 'top'
defaultTooltipOpenbooleanStart with the tooltip open (docs, previews and the accessibility suite's open-tooltip story).

When to use it

Use it for

  • Toolbars and dense rows where the icon is widely understood (close, edit, more)
  • Round header buttons (back, close) in onboarding and media screens: shape round, same size and target
  • Controls over photos, video, maps and camera views (surface media), or on a brand-coloured surface (surface brand)
  • A clear button inside a field row (size inline: a 32px box, so the row keeps its own height)

Use something else for

  • Primary actions: use Button with a text label
  • When the icon needs explaining: use Button

Accessibility

Screen readers announce "Settings, button" (the tooltip repeats the label as a description).

WCAG 2.2 AAA criteria the component meets in Comfortable density: 1.4.6, 1.4.9, 2.1.3, 2.3.2, 2.4.13, 2.5.5, 2.5.6, 2.3.3.

Compact density meets AA (2.5.8, 24px targets), not AAA.

What your product still has to do

  • Choose a label that says what happens, not what the icon looks like

This release’s test results

Test results for IconButton in this release
axe-core (WCAG A, AA, AAA and best practice)180 runs across every story, theme, density and width: 0 violations
Rendered text contrast30 text runs: 0 below 7:1, lowest 16.71:1
Target size96 targets: 0 under 44px in Comfortable
Focus appearance (2.4.13)108 focus stops in 3 browser engines: all pass
Keyboard scriptChromium 2 of 2, Firefox 2 of 2, WebKit 2 of 2

Manual passes with VoiceOver and NVDA haven’t been done yet.

Keyboard

Each step is scripted and run in Chromium, Firefox and WebKit.

IconButton keyboard steps
KeyWhat happens
TabTab reaches the button; its name is the label and the tooltip opens on focus
EscapeEsc dismisses the tooltip without moving focus (1.4.13)

In Figma

The Figma component is IconButton, with Variant (Default, Secondary, Outline, Ghost, Destructive); Size (Small, Default, Large, Touch, Inline); State (Default, Hover, Pressed, Focus, Disabled); Shape (Square, Round). The Figma library isn’t published yet.

Figma to code: Variant → variant (Default = "default", Secondary = "secondary", Outline = "outline", Ghost = "ghost", Destructive = "destructive"); Size → size (Small = "sm", Default = "default", Large = "lg", Touch = "touch", Inline = "inline"); State (Default, Hover, Pressed, Focus, Disabled = isDisabled); Label → label; Icon → icon; Shape → shape (Square = "square", Round = "round").