Skip to content

IconButton

A round button holding a single glyph. Use it where there is no room for a label: a toolbar, a list row.

tsx
import { IconButton } from 'neba';

<IconButton icon={<PlusIcon />} label="Add item" />;

Props

PropTypeDefaultDescription
icon * ReactNodeThe glyph. Passed bare it is sized in em against the button; wrap it in an Icon when it needs a size of its own
label * stringWhat the button does, in words. The one required prop here: a button whose whole label is a drawing has no accessible name at all, and that is the single most common accessibility defect a component library ships
variantshared'solid' | 'outline' | 'text''solid'Weight of the surface: filled, hairline, or none
sizeshared'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Button's own height ladder, so a disc drops into a row of buttons without the row losing its baseline
colorshared'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info''primary'Semantic colour role. Arbitrary colour values are not accepted
densityshared'default' | 'compact''default'Passed through but invisible: an icon-only control is square, so its horizontal padding is zero
elevationshared0 | 1 | 2 | 30Drop shadow depth. 0 means no shadow at all
loadingbooleanfalsePuts a spinner in the glyph’s place and stops the button activating, while keeping it focusable
readOnlybooleanfalseInert but not dimmed: the action exists, it just is not available here
disabledbooleanfalseUnavailable. Drops the colour family for neutral grey

Every native <button> attribute passes through. It uses Button's axes unchanged, including variant, elevation, loading and readOnly.

For a square icon control, a Button with no children already is one.

Examples

size

The same control heights Button uses, so a disc drops into a row of buttons without the row losing its baseline.

loading · readOnly · disabled

They behave exactly as the same props do on Button. loading puts a spinner in place of the glyph.

label

label is a required prop. A button whose only content is a glyph has no other way to get an accessible name, so the type demands one.

tsx
// Type error.
<IconButton icon={<TrashIcon />} />

// This.
<IconButton icon={<TrashIcon />} label="Delete file" />

label is not shown on screen. Wrap the button in a Tooltip to make the name visible too.

Accessibility

  • label is passed through as aria-label.
  • The focus ring only appears on :focus-visible.

Released under the MIT License