Role and semantics
Section titled “Role and semantics”IconButton is a native <button type="button"> rendered by Base UI Button. label gives the name as aria-label; the icon carries aria-hidden="true". label is required at type level: TypeScript reports an error without it.
Keyboard
Section titled “Keyboard”| Key | Behaviour |
|---|---|
| Tab | Moves focus to the button; skips it when disabled (unless focusableWhenDisabled). |
| Enter, Space | Runs the action. Nothing happens while loading or disabled. |
On keyboard focus a 2 px color-focus-ring ring appears 2 px outside the box; a mouse click does not show it (focus-visible). Focus stays on the button while it loads.
Screen reader output
Section titled “Screen reader output”| Example | Output |
|---|---|
<IconButton icon="x" label="Close" /> |
“Close, button” |
When loading starts |
“Close, button”, then “Loading” once |
disabled focusableWhenDisabled |
“Close, button, dimmed” or “unavailable” |
Contrast
Section titled “Contrast”The icon uses the variant’s text token and has at least 3:1 contrast on its background (non-text element). The token package test checks these pairs in every brand and mode.
WCAG 2.2
Section titled “WCAG 2.2”| Criterion | How IconButton meets it | What the product team does |
|---|---|---|
| 1.1.1 Non-text content | The icon is hidden; the name comes from label. |
Write label as a verb that describes the action. |
| 2.4.7 Focus visible | focus-visible ring. |
Do not remove the ring with className. |
| 2.5.3 Label in name | There is no visible text; the name is label only. |
Keep the tooltip text and the name the same. |
| 2.5.8 Target size (minimum) | The smallest size is 32 × 32 px, above the 24 px threshold. | Leave space between buttons. |
| 4.1.2 Name, role, value | Native <button>, aria-label, aria-disabled. |
Do not change the role through render. |