Walk a chip set with the arrow keys

M3's chip keyboard table makes a set one tab stop that the arrows move
through; ten filter chips cost ten Tab presses today. The set now keeps a
roving tabindex — re-applied whenever a Livewire morph rewrites the chips
— and walks left, right, Home and End, following the writing direction.
The input chip's remove button also grows to a full 48x48 target, where
it was 34px wide.

Plan step 20, findings IN-13 and IN-14.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-14 06:05:41 +02:00
co-authored by Claude Fable 5.1
parent 47ed4603d0
commit dd3d8afdb9
5 changed files with 100 additions and 14 deletions
+9 -4
View File
@@ -186,7 +186,9 @@ it('gives a removable input chip a named remove button that calls wire:remove',
->toContain('wire:click="removeRecipient(3)"')
->toContain('x-on:click="removeChip($event)"')
->toContain('<input type="hidden" name="to[]" value="3" />')
->toContain('ps-2.75 pe-2');
->toContain('ps-2.75 pe-2')
// 18px icon, 15px out on every side: M3's 48dp minimum for the close icon's target.
->toContain('after:absolute after:-inset-3.75');
});
it('runs an Alpine remove expression, or takes the chip off the page with neither', function () {
@@ -219,10 +221,13 @@ it('groups chips in a wrapping row named by its label, with a hint', function ()
expect($html)
->toContain('role="group"')
->toContain('data-chip-set class="flex flex-wrap gap-2"')
->toContain('data-chip-set x-data="materialChipSet"')
->toContain('flex flex-wrap gap-2')
// M3's chip keyboard: the set is one tab stop and the arrows walk it.
->toContain('x-on:keydown="key($event)"')
->toContain('x-on:focusin="rove($event.target)"')
->toContain("id=\"{$labelledBy[1]}\" class=\"mb-2 type-label-lg text-on-surface-variant\">File types</p>")
->toContain("id=\"{$describedBy[1]}\" class=\"mt-1 type-body-sm text-on-surface-variant\">Show only these</p>")
->not->toContain('materialChipSet');
->toContain("id=\"{$describedBy[1]}\" class=\"mt-1 type-body-sm text-on-surface-variant\">Show only these</p>");
});
it('scrolls a chip set on one line with fading edges', function () {