Square icon-only action primitive named by an explicit accessible label.
Install @wyrd-company/react or the Flutter package and use it directly —
your DESIGN.md does the styling.
catalog/contracts/icon-button.ymlsource of truth · verbatim
$schema: https://thewyrdingway.dev/schemas/component-contract.schema.ymlcontractVersion: 0.1.0identity:name: IconButtontag: wyrd-icon-buttonpackage: wyrd.component.icon-buttontitle: IconButtonsummary: Square icon-only action primitive named by an explicit accessible label.relationships:related-to: - quality-parity-and-gatesclassification:category: actioncomposition: single-slotinteractive: truetarget-strategy:react: requiredflutter: requiredsurface:properties: - name: labeltype:kind: stringrequired: trueserializable: truesummary: Accessible name for the icon-only button. - name: varianttype:kind: enumvalues: - primary - secondary - ghost - dangerrequired: falsedefault: primaryreflects: trueserializable: truesummary: Visual and semantic action emphasis. - name: is-disabledtype:kind: booleanrequired: falsedefault: falsereflects: trueserializable: truesummary: Prevents activation and exposes disabled platform semantics. - name: is-loadingtype:kind: booleanrequired: falsedefault: falsereflects: trueserializable: truesummary: Shows pending action state while preserving dimensions and suppressing duplicate activation.slots: - name: iconrequired: truecardinality: exactly-oneaccepts: - component - iconsummary: Visible icon content.events: - name: presspayload:source:kind: enumvalues: - pointer - keyboard - assistiveaction:kind: action-refbubbles: truecomposed: truecancelable: truesummary: Canonical activation event emitted once per accepted activation.states: - name: defaultsource: platformsummary: Idle enabled state. - name: hoversource: interactionsummary: Pointer hover state on hover-capable devices. - name: focus-visiblesource: platformsummary: Keyboard-visible focus state. - name: pressedsource: interactionsummary: Active press state. - name: disabledsource: propertysummary: Disabled state derived from is-disabled. - name: loadingsource: propertysummary: Pending state derived from is-loading.parts: - name: rootsummary: Interactive platform control root.slots: - icon - name: iconsummary: Icon slot container.slots: - icontokens:primary:background: color.primarybackground-hover: color.primary-hoverbackground-pressed: color.primary-pressedforeground: color.on-primarysecondary:background: color.secondaryforeground: color.on-secondaryghost:background: transparentforeground: color.primarydanger:background: color.errorforeground: color.on-errordisabled:background: color.disabledforeground: color.on-disabledradius: rounded.mdsize: spacing.xlpadding: spacing.smicon-size: spacing.mdmessages: []obligations:accessibility:role: buttonname: Label property provides the accessible name.keyboard: - Enter activates the button. - Space activates the button.semantics: - Web projections set aria-label from the label property because visible content is icon-only. - Flutter projections expose Semantics label and button state from the label property. - Disabled state is exposed through native disabled semantics where the target has them. - Loading state keeps the accessible name stable and prevents duplicate activation without dimming below contrast.behavior:model: statelessinteractions: - Activation emits press when the button is enabled and not loading. - Touch activation does not create hover state.hostEffects: - Dispatch activation event. - Invoke action binding for SDUI when present.conditions: - rtl - reduced-motion - cvd-deuteranopia - density-compactsdui:status: serializableserializableProperties: - label - variant - is-disabled - is-loadingserializableSlots: - iconeventBindings: - pressnotes: IconButton serializes its label, visual state, icon slot, and optional press binding.examples: - name: primarystate: defaultproperties:label: Savevariant: primaryslots:icon: save - name: loadingstate: loadingproperties:label: Savingvariant: primaryis-loading: trueslots:icon: save - name: dangerstate: defaultproperties:label: Deletevariant: dangerslots:icon: delete
01
Examples
Generated from the contract's examples block.
Previews are the published @wyrd-company/react component, themed by the
brand's role tokens — flip the site's light/dark toggle and they follow.
Prevents activation and exposes disabled platform semantics.
is-loading
boolean
false
Shows pending action state while preserving dimensions and suppressing duplicate activation.
03
Slots & events
Slot
Cardinality
Accepts
Summary
icon
exactly-one
component, icon
Visible icon content.
Event
Payload
Summary
press
source, action
Canonical activation event emitted once per accepted activation.
04
Tokens
The contract's token bindings. Open the shared contextual sidebar from any example;
primary swatches reflect the color you pick there. Error swatches show the active
preset's values; editing any knob switches to custom and resets error to TWW · Ink.
Binding
Token
primary.background
color.primary
primary.background-hover
color.primary-hover
primary.background-pressed
color.primary-pressed
primary.foreground
color.on-primary
secondary.background
color.secondary
secondary.foreground
color.on-secondary
ghost.background
transparent
ghost.foreground
color.primary
danger.background
color.error
danger.foreground
color.on-error
disabled.background
color.disabled
disabled.foreground
color.on-disabled
radius
rounded.md
size
spacing.xl
padding
spacing.sm
icon-size
spacing.md
05
States
State
Source
Summary
default
platform
Idle enabled state.
hover
interaction
Pointer hover state on hover-capable devices.
focus-visible
platform
Keyboard-visible focus state.
pressed
interaction
Active press state.
disabled
property
Disabled state derived from is-disabled.
loading
property
Pending state derived from is-loading.
06
Accessibility
From the contract's accessibility obligations. Role button; Label property provides the accessible name.
Enter activates the button.
Space activates the button.
Web projections set aria-label from the label property because visible content is icon-only.
Flutter projections expose Semantics label and button state from the label property.
Disabled state is exposed through native disabled semantics where the target has them.
Loading state keeps the accessible name stable and prevents duplicate activation without dimming below contrast.