Give a card per-state elevation and M3's two keyboard models

Plan step 19, containment.md C-13, C-23 and the directly actionable card
of C-13/C-18. A card had one elevation and never changed it, and its
hover replaced the elevated card's shadow with the state layer; it now
names its variant in `data-card` and moves a step on hover (elevated
1 to 2, filled and outlined 0 to 1) with the layer over it. The 12 to 16
corner morph on hover is gone: M3 gives a card one shape and lists shape
morph for buttons, FABs and list items only. New `actionable` prop for
M3's directly actionable card — the card is the one tab stop, with
`role="button"` (or `link`), its `title` as the name, and Enter or Space
reaching the opener from resources/js/list-rows.js.

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:07:14 +02:00
co-authored by Claude Opus 5
parent 26a9230a48
commit 675cfc806a
7 changed files with 131 additions and 18 deletions
+19 -3
View File
@@ -214,12 +214,28 @@ it('dismisses a bottom sheet dragged down past a quarter of its height', functio
it('opens a row\'s opener from a press anywhere on the row, but not from its own buttons', function () {
$page = containment();
$page->script("window.__opened = 0; document.querySelector('#containment [data-card][data-list-row] [data-list-open]').addEventListener('click', (event) => { event.preventDefault(); window.__opened++ })");
$row = '#containment [data-card][data-list-row]:not([data-list-actionable])';
$page->click('#containment [data-card][data-list-row] p')
$page->script("window.__opened = 0; document.querySelector('{$row} [data-list-open]').addEventListener('click', (event) => { event.preventDefault(); window.__opened++ })");
$page->click("{$row} p")
->assertScript('window.__opened === 1');
$page->click('#containment [data-card][data-list-row] button:has-text("Copy link")')
$page->click("{$row} button:has-text(\"Copy link\")")
->assertScript('window.__opened === 1');
});
it('makes a directly actionable card the one tab stop, answering Enter', function () {
$card = '#containment [data-card][data-list-actionable]';
$page = containment();
$page->script("window.__opened = 0; document.querySelector('{$card} [data-list-open]').addEventListener('click', (event) => { event.preventDefault(); window.__opened++ })");
$page->script("document.querySelector('{$card}').focus()")
->assertScript("document.activeElement.matches('{$card}')");
$page->keys($card, 'Enter')
->assertScript('window.__opened === 1');
});