An over-engineering audit of the whole tree, applied in five reviewed batches. Behaviour stays the same except where UPGRADE.md says otherwise. PHP: the showcase and error-page stylesheets are prebuilt into resources/dist by bin/stylesheets.mjs, through Vite's own postcss-import (first occurrence kept, the order an application's build gives), instead of Stylesheets::bundle() inlining imports on every request; only the import walk DesignGuard needs stays. SchemeStylesheet::withProfiles() replaces three copies of the scheme-plus-profiles loop, material:scheme leaves spec and contrast checks to the node script that already made them, and the error page's scheme cache, the hashed view namespace, the translations path with no lang/ folder and DesignGuard's 1.x-name hints are gone. JS: the androidx shape port progress.js and both bin scripts each carried lives once in resources/js/shapes.js (the generated SVGs are unchanged); util.js holds ringIndex(), ms(), reopenGuard() and remember(), which were written out several times; listeners are released through AbortController; tooltip.js's hoverPopover() serves the rich tooltip too. CSS: every rule for an element inside the navigation rail queries `--md-navigation-rail-value` instead of repeating the seven collapsed conditions under five media branches; badge, alert, progress, slider and button read one non-inheriting colour-role table (components/color.css); the dialog chrome, the submenu's popover chrome, the chip's state layer and touch target, and the visually-hidden inputs use the shared rules they copied; foundation/tokens.css is folded into foundation.css. Views: Support\Field and Support\Link replace the error-key, bound-value and link-attribute blocks copied into the fields and link components; the timepicker period group, the menu filter and the showcase head are partials; the datepicker's steppers and entry fields are loops; component docblocks no longer restate SKILL.md. Tests and tooling: one dataset-driven ComponentStylesheetsTest replaces four per-group files, DesignGuardTest and the layout-component tests use datasets, browser tests share one ready() helper, CSS parsing lives in ComponentStylesheet alone. docs/audits and the finding IDs citing it are removed, as are pestphp/pest-plugin-laravel, the unused composer scripts and check:font; the lint job runs in the feature job, which now installs node packages so the prebuilt-stylesheet staleness test runs in CI. Feature suite 1177 passed, Chrome browser suite 299 passed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
50 lines
2.3 KiB
PHP
50 lines
2.3 KiB
PHP
{{-- M3's feed canonical layout: cards or items to browse, in columns that multiply as the room
|
||
grows — news, photos, posts.
|
||
|
||
<x-feed min-item="280px">
|
||
@foreach ($posts as $post)
|
||
<x-card wire:key="post-{{ $post->id }}" :title="$post->title">…</x-card>
|
||
@endforeach
|
||
</x-feed>
|
||
|
||
M3's feed rules, row by row (docs/reference/m3/foundations-supplement.md § Canonical layouts →
|
||
Feed): a compact window (below 600px) stacks one card per row at the full width of the pane;
|
||
medium (600–839) splits into equal-width columns; expanded, large and extra-large have more
|
||
columns than medium, each usually wider. So below 600px it is one column, and from 600px it
|
||
fits as many equal columns of at least `min-item` as the feed has room for — more on a wider
|
||
window, and wider until another fits. M3 publishes no minimum or count for the web, so
|
||
`min-item` (`240px` by default; `280px`, `18rem`, `20ch` or a number of px) is yours to set
|
||
by the content. It follows the feed's own width, so a feed inside a pane beside another
|
||
stays sensible.
|
||
|
||
The items keep their order, which M3 makes the reading order ("item order is determined by
|
||
position"). The space between them is M3's spacer, 16px on a compact window and 24px from
|
||
medium, unless `gap` names a spacing token (`space25` … `space900`; an unknown name is no
|
||
gap). A card that should span two columns can say so in its own `style`.
|
||
|
||
It takes `as` (`div` by default; `ul` for a list of items, with `li` children), `hide-below`
|
||
and `hide-from` like every layout component, and the caller's `class` and `style` land on it
|
||
untouched. Drawn by resources/css/layout/feed.css. --}}
|
||
|
||
@props([
|
||
'as' => null,
|
||
'minItem' => null,
|
||
'gap' => null,
|
||
'hideBelow' => null,
|
||
'hideFrom' => null,
|
||
])
|
||
|
||
@php
|
||
$layout = \NoNameWeb\LivewireMaterial\Support\Layout::class;
|
||
$element = $layout::element($as);
|
||
$minItem = $layout::length($minItem) ?? '240px';
|
||
|
||
$attributes = $attributes->merge([
|
||
'data-md-feed' => true,
|
||
'data-md-gap' => $layout::spacing($gap),
|
||
'style' => "--md-min-item: {$minItem};",
|
||
] + $layout::visibility($hideBelow, $hideFrom));
|
||
@endphp
|
||
|
||
<{{ $element }} {{ $attributes }}>{{ $slot }}</{{ $element }}>
|