Axismundi v3.5.2 · Wave 1

Icon button full-spec module

Baseline classes stay authoritative. This lab page catalogs the Icon button contract for variants, selected states, accessible names, and disabled handling without adding runtime JavaScript.

Experimental lab preview — source authority remains components.css §3 plus icons.css §1/§5. This page does not modify the public style guide.

§2. Variants

Four baseline variants, each rendered as a native button with an accessible name and an aria-hidden Material Symbols glyph.

§3. Selected / unselected states

Static catalog specimens — aria-pressed values are fixed; no JS toggle handler. Production usage wires actual toggle behavior at the integrator level (theme JS / block editor / plugin).

정적 카탈로그 specimen — aria-pressed 값 고정, JS toggle 없음. 실제 사용 시 통합 레벨(theme JS / block editor / plugin)에서 toggle handler 배선.

Filled · false

Filled · true

Tonal · false

Tonal · true

Outlined · false

Outlined · true

Standard · false

Standard · true

§4. Accessible name contract

Icon-only controls require a programmatic name. The visible glyph is decorative and remains aria-hidden="true".

Named by aria-label

Upload

Named by aria-labelledby

Anti-pattern snippet — missing accessible name (not rendered)
<!-- Do not render this as a live control. The glyph is aria-hidden
     and there is no aria-label / aria-labelledby. -->
<button class="ax-icon-button is-standard has-state-layer" type="button">
  <span class="material-symbols-rounded" aria-hidden="true">search</span>
</button>

§5. Disabled — native attribute

Native disabled blocks activation and applies the baseline disabled styling for every variant.

§5a. Disabled — aria-disabled (plugin-managed)

aria-disabled="true" styles and announces state, but does not block activation by itself. Use only when app/plugin code also prevents activation.

aria-disabled="true"는 상태를 표시하고 전달하지만, 단독으로 activation을 차단하지 않는다. app/plugin 코드가 activation을 함께 막을 때만 사용.

Plugin-managed disabled

§6. has-state-layer opt-out

The baseline supports an explicit opt-out path. The specimen without has-state-layer is expected to lack hover/focus opacity overlay.

With state-layer

state-layer 적용

No state-layer overlay

state-layer 생략

§7. Code snippets

Canonical variant
<button class="ax-icon-button is-standard has-state-layer" type="button" aria-label="Search">
  <span class="material-symbols-rounded notranslate"
        translate="no" aria-hidden="true" draggable="false">search</span>
</button>
Selected state
<button class="ax-icon-button is-tonal has-state-layer"
        type="button" aria-label="Star selected" aria-pressed="true">
  <span class="material-symbols-rounded notranslate"
        translate="no" aria-hidden="true" draggable="false">star</span>
</button>
aria-labelledby
<span id="upload-label">Upload</span>
<button class="ax-icon-button is-tonal has-state-layer"
        type="button" aria-labelledby="upload-label">
  <span class="material-symbols-rounded notranslate"
        translate="no" aria-hidden="true" draggable="false">upload</span>
</button>
Native disabled
<button class="ax-icon-button is-filled has-state-layer"
        type="button" aria-label="Add" disabled>
  <span class="material-symbols-rounded notranslate"
        translate="no" aria-hidden="true" draggable="false">add</span>
</button>
aria-disabled — plugin-managed
<!-- App/plugin code must also prevent activation. -->
<button class="ax-icon-button is-filled has-state-layer"
        type="button" aria-label="Sync paused" aria-disabled="true">
  <span class="material-symbols-rounded notranslate"
        translate="no" aria-hidden="true" draggable="false">sync</span>
</button>

§8. Cross-references