Files
livewire-material/resources/views/components/list.blade.php
T
Andreas Reinhold / reiniandClaude Sonnet 5 9ff5a7a809 Rewrite list and list-item without Tailwind
Plan step 36 (containment group, last of its four components): moves
into resources/css/components/list.css (the container: display, the
2px segmented gap) and list-item.css (everything else — anatomy,
states, the segmented item's own background/corner, and the row
interaction pattern list.css used to carry). One commit for both:
list-item.css keys heavily on list's own data-md-list="segmented"
attribute and the two files are designed together.

Kept, now on data-md-* hooks: selectable/selection listbox semantics
(role="listbox"/"option", aria-selected, a trailing check as the
second cue, C-03), a disabled item's link dropped entirely rather than
left focusable (C-02), the segmented row's own state layer no longer
racing its background through an unlayered escape hatch (C-08 doesn't
recur — nothing here is unlayered), leading video/icon/avatar slots,
three-line top alignment and 12px vertical padding (C-15), 16px
leading/trailing gap (C-14), dividers inset 16px (C-16), the segmented
list's surface fill (C-21) and its hover/focus/pressed/selected corner
morph (C-22). The segmented icon size (20px) is now the `size` prop
`<x-icon>` already takes from the parent's @aware(['segmented']),
replacing the CSS override C-26's fix suggested.

data-md-lines="1|2|3" replaces the old line-count classes; data-md-list-item-*
hooks replace every other class list.

Hooks renamed data-list -> data-md-list, data-list-item -> data-md-list-item,
data-dividers -> data-md-dividers, data-selected -> data-md-selected, the
generic data-list-row/-open row pattern's last consumer (list-item)
moved, so list-rows.js drops the transitional dual-hook fallback the
card commit added. table.css now @imports list-item.css, completing
what its own comment already claimed (a row answers a pointer as a
list row does) under the new per-component-import architecture.

Imported from the Containment block of components.css; leaves
tailwind.css, which now carries only dialog.css for this group.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 20:37:38 +02:00

49 lines
2.1 KiB
PHP

{{-- An M3 list: `<x-list-item>`s, one under another.
Plain by default the items sit on the surface around them, with `dividers` between them if
asked, inset 16px from both ends as ListTokens' `DividerLeadingSpace`/`DividerTrailingSpace`
say (resources/css/components/list.css draws them). `segmented` is M3 Expressive's list: each
item its own surface tile, 2px apart, with small corners that open to large at the ends and
while hovered, pressed, focused or selected (ListTokens, androidx Compose Material 3,
Apache-2.0).
A plain list is a `role="list"` of `listitem`s. `selectable` (or `selection="single"` /
`selection="multi"`) makes it the list a person chooses from: M3 maps single- and
multi-select lists on the web to a **list box** of **options** with a selected state
(docs/reference/m3/components-actions-communication-containment.md § Lists Accessibility),
so the container becomes `role="listbox"` (`aria-multiselectable` when multi) and each item
an `option` that announces `aria-selected`. A selected option also draws a trailing check, so
selection is never colour alone; give the items a leading checkbox or radio instead and pass
`icon-right` to keep the check off.
For keyboard walking between rows, `j`/`k` or arrows, the application can use `data-md-list`
(resources/js/list-rows.js marks rows; a list keyboard arrives with the list-detail pane).
`label` names the list. --}}
@props([
'segmented' => false,
'dividers' => false,
'label' => null,
'selectable' => false,
'selection' => null,
])
@php
$selection = match (true) {
in_array($selection, ['single', 'multi'], true) => $selection,
$selectable || $selection !== null => 'single',
default => null,
};
@endphp
<div
role="{{ $selection === null ? 'list' : 'listbox' }}"
@if ($selection === 'multi') aria-multiselectable="true" @endif
data-md-list="{{ $segmented ? 'segmented' : 'plain' }}"
@if ($dividers && ! $segmented) data-md-dividers @endif
@if ($label) aria-label="{{ $label }}" @endif
{{ $attributes }}
>
{{ $slot }}
</div>