9 Commits
Author SHA1 Message Date
Andreas Reinhold / reiniandClaude Opus 5 bae1df09da Give a segmented list item a fill that reads against the page
tests / lint (push) Successful in 1m6s
tests / feature (8.4) (push) Failing after 1m41s
tests / feature (8.5) (push) Failing after 1m46s
tests / browser (chrome, chromium) (push) Failing after 6m21s
tests / browser (firefox, firefox) (push) Failing after 4m16s
tests / browser (safari, webkit) (push) Failing after 11m12s
`ItemSegmentedContainerColor get() = ColorSchemeKeyTokens.Surface`
(ListTokens.kt, C-21) was taken literally, but foundation/base.css
paints the page `surface` too — so a segmented list was invisible on any
default page. The token reads against a Compose scaffold, not against
this package's own page.

The tile is `surface-container` now, the step M3 names for a container
that has to read against the page, and what 1.x drew. Found in
SealShare: the files chosen for an upload list under the drop zone with
nothing to set them apart from it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 22:23:16 +02:00
Andreas Reinhold / reiniandClaude Opus 5 7d3abdd506 Keep a list row's fill under its state layer
Plan step 36 review of 9ff5a7a8. The rewrite dropped the unlayered
selected rule into material.components beside the segmented fill and the
row tint, so on equal or greater weight a selected item in a segmented
list drew surface instead of secondary-container, and hovering, pressing
or focusing any selected row (or a table's selected row) swapped its
fill for a translucent tint. Each fill now names itself
--md-list-row-fill, and the row's layer is its ink mixed over that fill
at the state tokens, which is also C-08's second suggested fix.

A disabled item inks the whole row at the disabled-content token, as the
old root colour did, so the check, the leading slot and the end slot dim
with the text; the three-line padding is a literal 12px like alert.css;
list-rows.js named list.css.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 22:00:03 +02:00
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
Andreas Reinhold / reiniandClaude Fable 5.1 927e439064 Lead a list item with M3's video slot
Plan step 23, containment.md § Missing ("Lists: leading video slot").
`<x-list-item video="…">` (or `<x-slot:video>`) draws M3's leading media
in its landscape sizes: 100×56px in a two-line item, 114×64px in a
three-line one (ListTokens' LeadingVideoSmall 56×100dp and
LeadingVideoLarge 64×114dp), with the small corner the leading image
takes. The tallest element sets an item's height, so a video lifts the
item to at least the 72px two-line row — 56 + 2×8 is 72 exactly, and
64 + 2×12 is 88.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 06:32:15 +02:00
Andreas Reinhold / reiniandClaude Opus 5 26a9230a48 Give a list item M3's gaps, alignment and expressive icon size
Plan step 19, containment.md C-14, C-15 and C-26. The leading and
trailing gap was 12px where ListItem.kt's LeadingContentEndPadding and
TrailingContentStartPadding are 16dp; a three-line item was
middle-aligned and padded 10px where M3 top-aligns an 88dp item and
Compose pads it 12; and a segmented list's icons stayed at the baseline
24dp instead of ListTokens' expressive 20dp, which the item now reads
from its list with `@aware` and draws from the 20 optical cut.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 06:04:19 +02:00
Andreas Reinhold / reiniandClaude Opus 5 dcd28707dd Let a segmented row answer, and inset a list's dividers
Plan step 19, containment.md C-08, C-21, C-22 and C-16. The segmented
fill was declared unlayered, so it beat every state layer in
@layer components and a segmented row lit up for nothing: it now sits in
the layer, `:where()`d to weigh nothing, ahead of the state rules. Its
tone is `surface`, which is ListTokens' ItemSegmentedContainerColor, and
a keyboard-focused row morphs to the large corner like a pressed one.
`<x-list dividers>` draws ListTokens' 16dp-inset rule instead of a
full-bleed `divide-y`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 06:03:12 +02:00
Andreas Reinhold / reiniandClaude Opus 5 d64fb91303 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
2026-09-14 05:57:00 +02:00
Andreas Reinhold / reiniandClaude Opus 5 7f67856916 Stop a disabled list item answering the keyboard
Plan step 12, containment.md C-02. `pointer-events-none` blocked the
pointer but not Tab and Enter: the item's `<a href>` stayed in the tab
order and navigated, and nothing announced it disabled. A disabled item
now renders its title as text, is no longer a `data-list-row`, and
carries `aria-disabled="true"`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
2026-09-14 05:54:25 +02:00
Andreas Reinhold / reiniandClaude Opus 5 fef20a9178 Add cards, lists, dialogs, sheets and the rest of M3's containment
tests / lint (push) Failing after 2m6s
tests / feature (8.4) (push) Successful in 1m3s
tests / feature (8.5) (push) Successful in 1m7s
tests / browser (safari, webkit) (push) Successful in 3m14s
tests / browser (chrome, chromium) (push) Successful in 2m9s
tests / browser (firefox, firefox) (push) Successful in 2m29s
<x-card> (filled, elevated, outlined), <x-list> and <x-list-item>
(plain or M3 Expressive's segmented list), <x-divider>, <x-collapse> on
<details>, <x-modal> on the native <dialog>, <x-drawer> as a side sheet or
list-detail pane, and <x-bottom-sheet> with drag to dismiss. Dialogs and
sheets bind to a Livewire flag or id and write back false or null on close,
or use the surrounding Alpine scope. Rows open from anywhere on them through
data-list-row and data-list-open. DesignGuard now also reports Blade
directives written inside a component tag, where they do not compile.

Browser test helpers wait for a complete document with Alpine and Livewire
running: in Firefox, networkidle alone could return before a repeated visit
had loaded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
2026-09-13 07:28:05 +02:00