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
102 lines
4.2 KiB
CSS
102 lines
4.2 KiB
CSS
/*
|
|
* Rows a person can go into (`data-list-row`, resources/js/list-rows.js), and M3 Expressive lists.
|
|
*
|
|
* A row answers a pointer with M3's state layer — hover 8%, press and focus 10% — but not while the
|
|
* pointer is on one of its own controls, which light only themselves. Hover only under
|
|
* `(hover: hover)`, because a touch screen keeps the last hover after a tap. The opener draws no
|
|
* focus ring inside a row; the row draws it, inset, so keyboard focus shows which row Enter opens.
|
|
* `data-selected` is M3's selected list item, in secondary-container.
|
|
*
|
|
* Unlayered where a component paints its fill as a utility (`<x-card>`): anything in a @layer loses
|
|
* to a utility whatever its specificity.
|
|
*/
|
|
|
|
@layer components {
|
|
:where([data-list-row]) {
|
|
cursor: pointer;
|
|
transition: background-color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast),
|
|
border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);
|
|
}
|
|
|
|
@media (hover: hover) {
|
|
:where([data-list-row]:not([data-card]):hover:not(:has(:is(a, button, input, select, textarea, label, summary):not([data-list-open]):hover))) {
|
|
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent);
|
|
}
|
|
}
|
|
|
|
:where([data-list-row]:not([data-card]):has([data-list-open]:focus-visible)) {
|
|
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);
|
|
outline: 3px solid var(--md-sys-color-secondary);
|
|
outline-offset: -3px;
|
|
}
|
|
|
|
:where([data-list-row]:not([data-card]):active:not(:has(:is(a, button, input, select, textarea, label, summary):not([data-list-open]):active))) {
|
|
background-color: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);
|
|
}
|
|
}
|
|
|
|
[data-list-row] [data-list-open]:focus-visible {
|
|
outline: none;
|
|
}
|
|
|
|
[data-list='segmented'] > [data-list-item] {
|
|
background-color: var(--md-sys-color-surface-container);
|
|
}
|
|
|
|
:is([data-list-row], [data-list-item])[data-selected]:not([data-card]) {
|
|
background-color: var(--md-sys-color-secondary-container);
|
|
color: var(--md-sys-color-on-secondary-container);
|
|
}
|
|
|
|
/* A card that opens answers with its container one tone up and its corner opening a step. */
|
|
[data-card][data-list-row] {
|
|
transition-property: border-radius, background-color, box-shadow;
|
|
transition-duration: var(--md-sys-motion-spatial-default-duration);
|
|
transition-timing-function: var(--md-sys-motion-spatial-default);
|
|
}
|
|
|
|
@media (hover: hover) {
|
|
[data-card][data-list-row]:hover:not(:has(:is(a, button, input, select, textarea, label, summary):not([data-list-open]):hover)) {
|
|
border-radius: var(--md-sys-shape-corner-lg);
|
|
box-shadow: inset 0 0 0 100vmax color-mix(in srgb, var(--md-sys-color-on-surface) 8%, transparent);
|
|
}
|
|
}
|
|
|
|
[data-card][data-list-row]:active:not(:has(:is(a, button, input, select, textarea, label, summary):not([data-list-open]):active)) {
|
|
box-shadow: inset 0 0 0 100vmax color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);
|
|
}
|
|
|
|
[data-card][data-list-row]:has([data-list-open]:focus-visible) {
|
|
outline: 3px solid var(--md-sys-color-secondary);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/*
|
|
* M3 Expressive's segmented list (`<x-list segmented>`): each item its own surface, 2px apart,
|
|
* extra-small corners that open to large at the ends, and to large while hovered, pressed or
|
|
* selected (ListTokens, androidx Compose Material 3, Apache-2.0).
|
|
*/
|
|
[data-list='segmented'] > [data-list-item] {
|
|
border-radius: var(--md-sys-shape-corner-xs);
|
|
}
|
|
|
|
[data-list='segmented'] > [data-list-item]:first-child {
|
|
border-start-start-radius: var(--md-sys-shape-corner-lg);
|
|
border-start-end-radius: var(--md-sys-shape-corner-lg);
|
|
}
|
|
|
|
[data-list='segmented'] > [data-list-item]:last-child {
|
|
border-end-start-radius: var(--md-sys-shape-corner-lg);
|
|
border-end-end-radius: var(--md-sys-shape-corner-lg);
|
|
}
|
|
|
|
@media (hover: hover) {
|
|
[data-list='segmented'] > [data-list-item][data-list-row]:hover {
|
|
border-radius: var(--md-sys-shape-corner-md);
|
|
}
|
|
}
|
|
|
|
[data-list='segmented'] > [data-list-item]:is([data-selected], [data-list-row]:active) {
|
|
border-radius: var(--md-sys-shape-corner-lg);
|
|
}
|