Announce a selectable list as M3's list box of options
Plan step 12, containment.md C-03. `selected` was colour alone on a `listitem`, which cannot carry a selected state at all. `<x-list selectable>` (or `selection="single|multi"`) now makes the container a `role="listbox"` and each item an `option` with `aria-selected`; a plain list keeps `role="list"` and marks a selected item `aria-current`. A selected option draws a trailing check as M3's second cue, which `icon-right` replaces. The item reads its list's mode with `@aware`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
7f67856916
commit
d64fb91303
@@ -15,7 +15,12 @@
|
||||
control that opens — see resources/js/list-rows.js. `selected` (true) is M3's selected item,
|
||||
in secondary-container; `disabled` greys it to 38%, drops its link and announces it
|
||||
`aria-disabled` — M3's states model treats disabled as not interactive, so a disabled item
|
||||
answers neither the pointer nor the keyboard. --}}
|
||||
answers neither the pointer nor the keyboard.
|
||||
|
||||
It takes its role from the `<x-list>` around it: a `listitem` in a plain list, where
|
||||
`selected` is `aria-current`, and an `option` announcing `aria-selected` in a `selectable`
|
||||
one. M3 asks for two cues on a selected item, never colour alone, so a selected option also
|
||||
draws a trailing check unless `icon-right` says otherwise. --}}
|
||||
|
||||
@props([
|
||||
'title' => null,
|
||||
@@ -33,14 +38,23 @@
|
||||
'disabled' => false,
|
||||
])
|
||||
|
||||
{{-- Whether the `<x-list>` around it is one a person chooses from, and how many it takes. --}}
|
||||
@aware([
|
||||
'selectable' => false,
|
||||
'selection' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
$isLink = filled($link) && ! $disabled;
|
||||
$lines = (filled($overline) ? 1 : 0) + (filled($description) ? 1 : 0);
|
||||
$initials = filled($avatar) && ! str_contains((string) $avatar, '/') && ! str_contains((string) $avatar, '.');
|
||||
$option = $selectable || $selection !== null;
|
||||
$check = $option && $selected && blank($iconRight);
|
||||
@endphp
|
||||
|
||||
<div
|
||||
role="listitem"
|
||||
role="{{ $option ? 'option' : 'listitem' }}"
|
||||
@if ($option) aria-selected="{{ $selected ? 'true' : 'false' }}" @elseif ($selected) aria-current="true" @endif
|
||||
data-list-item
|
||||
@if ($isLink) data-list-row @endif
|
||||
@if ($selected) data-selected @endif
|
||||
@@ -98,5 +112,7 @@
|
||||
|
||||
@if ($iconRight)
|
||||
<x-livewire-material::icon :name="$iconRight" :class="\Illuminate\Support\Arr::toCssClasses(['size-6', 'text-on-surface-variant' => ! $selected && ! $disabled])" />
|
||||
@elseif ($check)
|
||||
<x-livewire-material::icon name="check" class="size-6" />
|
||||
@endif
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user