diff --git a/UPGRADE.md b/UPGRADE.md index 2c94c9dd..3c5fa58c 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -17,6 +17,12 @@ family now too: `border-collapse`, `border-spacing-*`, `from-10%`, `via-none`, `fill-none`, `stroke-*`, `text-shadow-*`, `text-inherit`, and Tailwind 4.2's `mauve`, `olive`, `mist` and `taupe` palettes. A test that expects no findings may fail on them. +- **A selected row written by hand** — `data-md-list-row` with `data-md-selected` on an `
  • `, a + `
    ` or a ``, not `` or `` — is drawn in `secondary-container` with + `on-secondary-container` ink again, as 1.x's `data-list-row` with `data-selected` was; 2.0.0 + dropped the fill without saying so. Hover, focus and press now tint the fill instead of hiding + it. In `` a plain row takes `data-md-selected` too, beside `aria-selected="true"`. A + card still takes no selected fill. ## From 2.0.0 to 2.1.0 diff --git a/resources/boost/skills/livewire-material-development/SKILL.md b/resources/boost/skills/livewire-material-development/SKILL.md index 3d1807b1..9a486c64 100644 --- a/resources/boost/skills/livewire-material-development/SKILL.md +++ b/resources/boost/skills/livewire-material-development/SKILL.md @@ -514,7 +514,7 @@ The `illustration` slot draws the application's own artwork in place of the shap `variant`: `filled` (default, surface-container-highest), `elevated`, `outlined`; medium corner. Props `title`, `subtitle`, `separator`, `heading` (the title's element, `h3` by default: pass `h2` for a card straight under the page's `h1`); slots `figure` (full-bleed media), `menu` (top-end), `actions` (end-aligned). A card holds content and actions about one subject (M3); a table of many rows or a group of settings is a headed section, not a card. Choose its fill with `variant`, not a background of your own. -A card or list item that opens something is a **row**: `data-md-list-row` on it and `data-md-list-open` on its one opener (the title link or a button). A press anywhere else on the row reaches the opener; its other controls keep their own presses. Never wrap a card in `` or use a stretched link. A row answers with the state layer and one step of elevation; its corner does not move. +A card or list item that opens something is a **row**: `data-md-list-row` on it and `data-md-list-open` on its one opener (the title link or a button). A press anywhere else on the row reaches the opener; its other controls keep their own presses. Never wrap a card in `` or use a stretched link. A row answers with the state layer and one step of elevation; its corner does not move. `data-md-selected` on a row that is not a card — your own `
  • `, `
    ` or ``, the one whose sheet is open — fills it secondary-container with on-secondary-container ink, the state layer over the fill (`` writes it itself); a card takes no selected fill. ```blade @@ -1141,7 +1141,7 @@ A choice of colour profile (see Colour profiles): a swatch per generated profile ### ``, `` -A data table: write plain ``, ``, ``, `` inside ``; the text classes on a cell (`md-text-end`, `md-nowrap`, `md-tabular`) always win over the table's own alignment. Rows are 52px — a target a finger can hit. `dense` tightens them to 36px and `size="xs"` is for a table inside a panel inside a panel (32px rows); M3 says density is always an opt-in, so neither is a default and both are yours to justify. Scrolling is yours: wrap it in an element that scrolls sideways (`overflow-x: auto` in your own CSS). A row that opens something is `data-md-list-row` with one `data-md-list-open` control; a selected row is `aria-selected="true"`. +A data table: write plain ``, ``, ``, `` inside ``; the text classes on a cell (`md-text-end`, `md-nowrap`, `md-tabular`) always win over the table's own alignment. Rows are 52px — a target a finger can hit. `dense` tightens them to 36px and `size="xs"` is for a table inside a panel inside a panel (32px rows); M3 says density is always an opt-in, so neither is a default and both are yours to justify. Scrolling is yours: wrap it in an element that scrolls sideways (`overflow-x: auto` in your own CSS). A row that opens something is `data-md-list-row` with one `data-md-list-open` control; a selected row is `data-md-selected`, or `aria-selected="true"` in a table that is a grid — the only place ARIA allows it on a row. `Size` sorts through the Livewire property `sortBy` (`['column' => …, 'direction' => 'asc'|'desc']`; `model` names another), with `aria-sort`. diff --git a/resources/css/components/list-item.css b/resources/css/components/list-item.css index 2b0181a0..9e673f4b 100644 --- a/resources/css/components/list-item.css +++ b/resources/css/components/list-item.css @@ -15,7 +15,9 @@ * or focused row keeps its fill under the tint instead of trading it for a translucent one (C-08's * second fix). `data-md-selected` is M3's selected item, secondary-container filled, which also * lifts the description/overline/trailing/icon colour rules below since they exclude it — the - * container's own colour takes over by inheritance. A selected option draws a second cue, a + * container's own colour takes over by inheritance. The same attribute on any other row that is + * not a card — an application's own `
  • `, `
    ` or `` — draws the same fill and ink, as + * 1.x's `data-selected` did; a card keeps its own container. A selected option draws a second cue, a * trailing check, so selection is never colour alone (C-03). `aria-disabled` inks the whole item * on-surface at the disabled-content opacity (38%) and blocks the pointer; the view drops the * item's link entirely rather than leaving a focusable, activatable control behind it (C-02). @@ -93,6 +95,15 @@ color: var(--md-sys-color-on-secondary-container); } + /* A row written by hand — list-rows.js's contract, not an `` — selected the same + way. The state layers below are mixed over this fill, as they are over an item's. */ + [data-md-list-row][data-md-selected]:not([data-md-card], [data-md-list-item]) { + --md-list-row-fill: var(--md-sys-color-secondary-container); + + background-color: var(--md-list-row-fill); + color: var(--md-sys-color-on-secondary-container); + } + [data-md-list-item][aria-disabled='true'] { pointer-events: none; color: color-mix(in srgb, var(--md-sys-color-on-surface) calc(var(--md-sys-state-disabled-content-opacity) * 100%), transparent); diff --git a/resources/css/components/table.css b/resources/css/components/table.css index fde8b65c..a93f369f 100644 --- a/resources/css/components/table.css +++ b/resources/css/components/table.css @@ -7,7 +7,8 @@ * always wins, whatever layer it comes from. Header cells in title-small on-surface-variant over an * outline-variant rule, body cells in body-medium between outline-variant rules — the role itself, * never a fraction of it, since M3 reserves opacity for state layers and disabled. A selected row - * (`aria-selected="true"`) is secondary-container. A row that opens something is `data-md-list-row` + * (`data-md-selected`, or `aria-selected="true"` where the table is a grid, the only place ARIA + * allows it on a row) is secondary-container. A row that opens something is `data-md-list-row` * and answers a pointer as a list row does (components/list-item.css, shared with `` and * ``); a selected one names its fill `--md-list-row-fill`, so that state layer is laid * over the secondary-container rather than in place of it. @@ -84,7 +85,7 @@ border-bottom: 0; } - [data-md-table] :where(tbody tr[aria-selected='true']) { + [data-md-table] :where(tbody tr:is([aria-selected='true'], [data-md-selected])) { --md-list-row-fill: var(--md-sys-color-secondary-container); background-color: var(--md-list-row-fill); diff --git a/resources/js/list-rows.js b/resources/js/list-rows.js index 8587f31e..33823141 100644 --- a/resources/js/list-rows.js +++ b/resources/js/list-rows.js @@ -9,6 +9,11 @@ * keep their own clicks. How a row looks while that happens is * resources/css/components/card.css and list-item.css. * + * `data-md-selected` on a row that is not a card — the one whose sheet is open, say — draws M3's + * selected state, secondary-container under on-secondary-container ink, with the state layers over + * it (list-item.css; `` writes it itself, and in `` a plain row takes + * it too, table.css). A card keeps its own container. + * * Not a stretched link (`::after { inset: 0 }`): Safari makes no containing block of a , so in * a table every overlay would cover the whole table; and not one