Axismundi · v3.5.10 · Wave 1 #6

Button group — Full Spec Module

Baseline components.css §28 remains authoritative. This lab page demonstrates Pattern A native radio groups, Pattern B aria-pressed toggles, bounded segment ripple, and the v3.5.9 finite connected-pill radius.

Experimental lab preview. tokens.css and components.css are not edited by this module. --_button-group-pill-radius stays local in §28; public Button group token promotion is deferred.

§2. Standard Button group

Standard groups keep individual button separation. Pattern A uses native radios; selected width expansion comes from baseline §28.

View mode

Pattern A. Browser radio behavior owns selection and arrow-key flow.

Pattern B. Local demo JS flips aria-pressed; no public runtime API is created.

§3. Connected Button group

Connected groups preserve outer pill corners and morph inner corners. v3.5.9 replaced unstable 9999px interpolation with finite local radius.

Density

Connected Pattern A. Each label is the ripple host; the fieldset is not.

Connected Pattern B. M3 web button-item keyboard guidance maps here.

§4. Segment count matrix

Representative 2 / 3 / 4 / 5 segment connected groups. Full cartesian combinations are intentionally avoided.

Billing cycle

2 segments.

Range

3 segments.

4 segments, icon-only. Accessible names required.

Priority

5 segments inside a 390px QA shell.

§5. Content matrix

Label-only, icon+label, and icon-only segments. Icon-bearing specimens consume icon-system conditionally.

Sort

Label-only.

Icon + label.

Icon-only. Every segment has an accessible name.

§6. Size hooks — partial baseline

Baseline §28 has XS/S gap hooks and connected L/XL corner hooks, but it does not yet change segment height, typography, or horizontal padding. Button group adapts to child Button sizes; Button #1 still ships only the 40px baseline size.

Phase 3 finding: these are size hooks, not complete M3 XS/S/M/L/XL Button group implementations. Full size support requires Button / Icon button size variants first.

XS size

XS hook: wider gap, 48px min-inline-size, extra-small inner corners. Height remains the baseline 40px.

Large size
Extra large size

L/XL hooks: larger inner corner rules only. Segment height remains 40px because child Button size variants are not implemented yet.

§7. Disabled states

Pattern A applies native disabled to the input; Pattern B applies native disabled to buttons. Aria-disabled is plugin-managed.

Native disabled radio

Native disabled segment.

Native disabled button segment.

Aria-disabled is semantic only. Plugin code must suppress activation and explain why the segment is unavailable.

§8. Bounded ripple protocol

Ripple attaches to each visible segment, never to the group container.

QA expectation: group container has no data-ax-ripple; all three segments do.

§9. WordPress approximation specimen

core/buttons can approximate an inline row visually, but cannot express connected selection semantics by itself.

Theme pattern markup or plugin ownership is required for radio / pressed state. This specimen is documentation only; no block style is registered in v3.5.10.

§10. Code snippets

Minimal authoring contracts for both patterns.

<fieldset class="ax-button-group ax-button-group--connected">
  <legend class="u-vh">Density</legend>
  <input type="radio" name="density" id="density-a"
         class="ax-button-group__input" checked>
  <label for="density-a"
         class="ax-button is-tonal has-state-layer"
         data-ax-ripple="bounded">Comfort</label>
</fieldset>
<div class="ax-button-group ax-button-group--connected"
     role="group"
     aria-label="Formatting"
     data-button-group-toggle-demo>
  <button type="button"
          class="ax-button is-tonal has-state-layer"
          aria-pressed="true"
          data-ax-ripple="bounded">Bold</button>
</div>

§11. Cross-references