Build the theme and contrast rows on the connected button group

`mode="picker"` hand-rolled an outlined segmented button, point for point the
design M3 Expressive deprecates, and its own arrow keys neither wrapped nor
handled Up/Down. Both rows are now <x-group>: native radios in a fieldset, so the
browser supplies the radiogroup, both axes, the wrap and the roving tab stop, and
the store is bound through an x-model accessor — a contrast row still marks the
resolved level but writes through setContrast(). A new `label` prop legends the
row. Plan: docs/plans/material-3-alignment.md, step 14 (navigation N-04, N-17).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 06:00:07 +02:00
co-authored by Claude Opus 5
parent 98afef7b45
commit a99fbd3794
5 changed files with 85 additions and 69 deletions
+4 -4
View File
@@ -31,9 +31,9 @@ it('keeps the visitor\'s choice over the operating system', function () {
->assertScript("document.readyState === 'complete' && typeof window.Alpine !== 'undefined' && typeof window.Livewire !== 'undefined'")
->assertScript(theme('data-theme', 'dark'));
$page->click('[data-theme-option="light"]')
$page->click('label:has(input[name="material-theme"][value="light"])')
->assertScript(theme('data-theme', 'light'))
->assertAttribute('[data-theme-option="light"]', 'aria-checked', 'true')
->assertScript('document.querySelector(\'input[name="material-theme"][value="light"]\').checked')
->assertScript("localStorage.getItem('material-theme') === 'light'");
$page->refresh()
@@ -98,7 +98,7 @@ it('adds a theme-color meta in the painted surface, and follows the theme and th
->assertScript(themeColorIs($profiles['baseline']['light']['surface']))
->assertScript(pageSurfaceIs($profiles['baseline']['light']['surface']));
$page->click('[data-theme-option="dark"]')
$page->click('label:has(input[name="material-theme"][value="dark"])')
->assertScript(theme('data-theme', 'dark'))
->assertScript(themeColorIs($profiles['baseline']['dark']['surface']))
->assertScript(pageSurfaceIs($profiles['baseline']['dark']['surface']));
@@ -108,7 +108,7 @@ it('adds a theme-color meta in the painted surface, and follows the theme and th
->assertScript(themeColorIs($profiles['rose']['dark']['surface']))
->assertScript(pageSurfaceIs($profiles['rose']['dark']['surface']));
$page->click('[data-theme-option="light"]')
$page->click('label:has(input[name="material-theme"][value="light"])')
->assertScript(themeColorIs($profiles['rose']['light']['surface']))
->assertScript(pageSurfaceIs($profiles['rose']['light']['surface']))
->assertNoJavaScriptErrors();