Skip to the content

Kongens Nytorv

Metro M1, M2 and M3.

Variants and states

RestHoverPressedFocusDisabled
Neutral
Brand
  • Rest
  • Hover
  • Pressed
  • Focus
  • Disabled

Sizes

Mediumsize.control · 34 px
Large

Props

NameTypeDefaultDescription
label*string—The words that name the action, in sentence case, such as "Zoom in". Required: the icon is hidden from screen readers, so these words are the button's name. Never seen, read by screen readers.
color'neutral' | 'brand''neutral'The intent: neutral is quiet ink, for every action but the main one; brand is the brand yellow, for the one main action of a screen.
size'medium' | 'large''medium'The icon's step in the size.control square: medium is icon.size.400, for icons drawn on the 16 px grid; large is icon.size.450, for the top bar's icons drawn on the 18 px grid.
disabledbooleanfalseWhether the button ignores the pointer and the keys. A disabled button leaves the tab order unless focusableWhenDisabled is set.
childrenReactNode—The icon, such as an SVG from packages/perron/icons/ with the perron-icon class. Hidden from screen readers: label names the button.
classNamestring—Reaches the root. className is merged after pn-IconButton.
styleCSSProperties—Reaches the root. className is merged after pn-IconButton.
refRef<HTMLButtonElement>—Reaches the root. className is merged after pn-IconButton.
label (required)string, default —
The words that name the action, in sentence case, such as "Zoom in". Required: the icon is hidden from screen readers, so these words are the button's name. Never seen, read by screen readers.
color'neutral' | 'brand', default 'neutral'
The intent: neutral is quiet ink, for every action but the main one; brand is the brand yellow, for the one main action of a screen.
size'medium' | 'large', default 'medium'
The icon's step in the size.control square: medium is icon.size.400, for icons drawn on the 16 px grid; large is icon.size.450, for the top bar's icons drawn on the 18 px grid.
disabledboolean, default false
Whether the button ignores the pointer and the keys. A disabled button leaves the tab order unless focusableWhenDisabled is set.
childrenReactNode, default —
The icon, such as an SVG from packages/perron/icons/ with the perron-icon class. Hidden from screen readers: label names the button.
classNamestring, default —
Reaches the root. className is merged after pn-IconButton.
styleCSSProperties, default —
Reaches the root. className is merged after pn-IconButton.
refRef<HTMLButtonElement>, default —
Reaches the root. className is merged after pn-IconButton.

Use it

import { IconButton } from '@mylder/perron'

Ask your agent

get_reference({ library: "base-ui", component: "Button" })

Keyboard and ARIA

From the Base UI reference for Button and the installed useButton, as on Button. "From" says who does it.

KeyDoesFrom
Tab, Shift+TabMoves focus to the button and away; a disabled button is skipped unless focusableWhenDisabledThe browser, and Base UI
EnterActivates the button: fires onClick, or submits the form with type="submit"The browser; Base UI for a non-button render
SpaceActivates the button on releaseThe browser; Base UI for a non-button render
ElementRoleAccessible name fromStates announced
rootbutton, native; role="button" from Base UI when render gives a non-button elementIts text content: the label in the VisuallyHidden span; aria-label or aria-labelledby from the caller winDisabled: the native disabled, or aria-disabled with focusableWhenDisabled
iconnone: aria-hidden="true"nonenone
labelnone: text inside the buttonnone: it is the namenone

What axe won't catch, from the contract, each with how this component meets it:

  • Everything the eye is told, the ear is told, for every shape each prop accepts: the icon is aria-hidden and label says in words what it shows, as Icons asks of an icon alone; color carries emphasis, not meaning; disabled is announced by the native attribute or aria-disabled.
  • Every landmark and named region has an accessible name: none here; a button is neither.
  • Every default label can be overridden: none here; IconButton owns no strings, and label is the caller's.
  • Every shape the type accepts renders, in every variant: children renders a string, an element and a list alike, centred in the square, in both colours and both sizes, and the icon span clips a string wider than the square so it stays inside; label is a string.
  • A hidden copy kept for animation is aria-hidden, and a collapsed region is inert: none here; IconButton keeps no hidden copy and collapses nothing. The VisuallyHidden label is the name, not a copy.
  • Native semantics first: a native <button> from Base UI's Button, named by its own text; with render and nativeButton={false}, Base UI's role="button". No ARIA of its own.
  • Focus moves in reading order and returns on close: the button is one tab stop in document order, and opens nothing of its own to return from.
  • Every target is at least size.target-min square: every IconButton is size.control (34 px) square, in both sizes.
  • Loops stop when the system asks for less motion: none here; IconButton has no loop and no transition.

Owned strings

No owned strings: every word comes from the caller, as label.

Do and don't

For a caller using the component, with the reason. Each row is a rule: a must row's Don't is never right, a should row's needs a reason, and Checked by says what catches the Don't in a caller's code.

RuleLevelDoDon'tChecked by
DD-1mustGive label the action in sentence case, as a verb and what it acts on: "Zoom in", "Centre the map"Name the icon rather than the action ("Plus", "Magnifier"), or write Title Case or an exclamation mark (Content design)review
DD-2shouldUse IconButton only where the icon is one people know at a glance, such as zoom, locate, close or search, and use Button with words otherwisePut an icon whose meaning has to be guessed in an IconButton: the label reaches only screen readers, and the eye gets the icon alonereview
DD-3shouldGive size="large" to an icon drawn on the 18 px grid (monitor, info), and keep the default medium for the 16 px onesSet --perron-icon-size or a width on the icon yourself, or give a 16 px icon large: an icon drawn on one grid blurs when scaled to anotherreview
DD-4mustGive one action per screen color="brand", for its main actionUse brand for emphasis, or set two brand actions on one screenreview
DD-5shouldSet icon buttons on a panel, a sheet or the top bar's glass, which mark where they sitFloat a neutral icon button straight over the map: its transparent fill disappears on the land and waterreview
DD-6mustPut each action of a Toolbar in a ToolbarButton, so the arrow keys reach itPut an IconButton inside a Toolbar: it falls out of the arrow-key order and adds a tab stopreview
DD-7mustUse a toggle component, such as FilterChip, for an icon that turns something on and offSet aria-pressed on an IconButton and restyle it: IconButton keeps no pressed state, and a toggle says its state in wordsreview
DD-8mustSet disabled when the action can't run, with focusableWhenDisabled so the button can still be reached and its name heardRestyle a disabled icon button with opacity: disabled is color.text.tertiary, a colourreview