Add the Material 3 Expressive foundation
tests / lint (push) Successful in 1m0s
tests / feature (8.4) (push) Successful in 1m0s
tests / feature (8.5) (push) Successful in 1m1s
tests / browser (safari, webkit) (push) Successful in 1m59s
tests / browser (chrome, chromium) (push) Successful in 1m49s
tests / browser (firefox, firefox) (push) Successful in 1m54s
tests / lint (push) Successful in 1m0s
tests / feature (8.4) (push) Successful in 1m0s
tests / feature (8.5) (push) Successful in 1m1s
tests / browser (safari, webkit) (push) Successful in 1m59s
tests / browser (chrome, chromium) (push) Successful in 1m49s
tests / browser (firefox, firefox) (push) Successful in 1m54s
Colour, shape, type, elevation and motion as tokens and Tailwind utilities; `php artisan material:scheme`, which generates an app's colour roles with Google's material-color-utilities (spec 2025); the theme head script with light, dark and system and its Alpine store; Google Sans Flex; every Material Symbol (4,135, outlined and filled) drawn by <x-icon> without blade-icons; all 35 M3 Expressive shapes, ported from androidx, as <x-shape>; the x-figure directive; the Toasts concern; DesignGuard for applications' tests; and a showcase with every token, both themes side by side and an icon search. Colour utilities are `@theme inline`, so a section with its own data-theme repaints; without it they resolve once on :root. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
co-authored by
Claude Opus 5
parent
9b53891a8e
commit
b48e879254
@@ -93,9 +93,12 @@ tokens, `training-row`, `map-shell`, `map-chip`, `product-shot`, `star-rating`,
|
||||
- **CSS and JS imported from `vendor/`** (`@import`, `@source`, `import`) — one dependency, one
|
||||
version; consuming Dockerfiles install Composer packages before the Vite build.
|
||||
`@source` covers the package's views and PHP, never its SVG folders.
|
||||
- **The full Material Symbols Rounded set** (400 / 0 / 24, outlined and filled, ~7,800 SVGs,
|
||||
~3–4 MB), produced by a maintenance script in the package repo, not fetched at runtime —
|
||||
any name works in any app; `icons:cache` keeps lookups cheap under Octane.
|
||||
- **The full Material Symbols Rounded set** (400 / 0 / 24, outlined and filled, 4,135 symbols,
|
||||
5.3 MB), fetched by a maintenance script in the package repo, never at runtime — any name works
|
||||
in any app. **`<x-icon>` reads the SVG files itself; blade-icons is not used for them** (decided
|
||||
after Phase 1): blade-icons registers one Blade component per icon whenever the view factory
|
||||
resolves, ~8,000 registrations per request here. blade-icons stays a dev dependency, only to
|
||||
test that the provider still keeps its `<x-icon>` from shadowing ours in apps that have it.
|
||||
- **Google Sans Flex bundled** (ReStride's subset) via `@font-face` in the package CSS; an app
|
||||
overrides `--font-sans`.
|
||||
- **Full M3, not ReStride's doctrine** — every variant, colour role (tertiary and
|
||||
@@ -273,6 +276,47 @@ tokens, `training-row`, `map-shell`, `map-chip`, `product-shot`, `star-rating`,
|
||||
per foundation piece (colour roles in both themes, type scale, shapes, motion, icons
|
||||
search).
|
||||
|
||||
**Phase 2 is done (2026-09-13).** What changed from the steps above:
|
||||
|
||||
- **Icons without blade-icons** (see Decisions): `NoNameWeb\LivewireMaterial\Support\SvgFile`
|
||||
reads a symbol or shape file on first use and keeps it for the worker. An unknown name throws,
|
||||
and a Heroicon-style name (`o-home`) throws with a pointer to the catalogue. `bin/fetch-symbols`
|
||||
sparse-checks-out google/material-design-icons (5 GB, cloned without blobs) for the
|
||||
`_24px` and `_fill1_24px` files: 4,135 symbols, byte-identical to ReStride's hand-picked ones.
|
||||
The `@material-symbols/svg-400` npm package was rejected: its "rounded" SVGs are optical size 48.
|
||||
- **All 35 M3 Expressive shapes**, ported from androidx `MaterialShapes.kt` and graphics-shapes
|
||||
into `bin/shapes.mjs` (commit in its header), each fitted to 2–98 of a 100-unit box; eight had
|
||||
control points outside the box and are split into more segments along the same outline.
|
||||
- **The scheme script** lives at `resources/node/scheme.mjs` (93 KB, esbuild bundle of
|
||||
material-color-utilities 0.4.0, spec 2025 — M3 Expressive's colour; variants the 2025 spec
|
||||
does not define fall back to 2021). The library's extensionless imports mean it cannot run
|
||||
unbundled. 65 roles per theme plus `inverse-{error,success,warning,info}`. Default state
|
||||
sources: success `#22a06b`, warning `#e2a400`, info `#1d7afc`. `config('livewire-material.node')`
|
||||
names the binary. The package's own default is `#6750A4`, tonal-spot, in `tokens/scheme.css`.
|
||||
- **Colour utilities are `@theme inline`** — contrary to ReStride's rule that `inline` breaks
|
||||
theme switching. Verified in Chromium: without `inline`, `--color-primary` resolves once on
|
||||
`:root`, so a `data-theme="dark"` section inside a light page keeps light colours; with it the
|
||||
utility reads `var(--md-sys-color-primary)` on the element and both the page toggle and nested
|
||||
themes work. Only blocks whose values are variables are inline. A browser test fails without it.
|
||||
- **Tailwind emits only the theme variables that are used**, and cannot see a class assembled in
|
||||
Blade (`type-{{ $style }}`): the showcase lists every class literally.
|
||||
- **`dark:`** is keyed on `data-theme`, so it follows the page's theme rather than the OS.
|
||||
- **Theme script** writes nothing for a visitor who never chose (a later change of
|
||||
`theme.default` still reaches them); only an adopted legacy value is stored. `data-theme-choice`
|
||||
and `data-theme-key` on `<html>` hand the state to `$store.theme` (`choice`, `resolved`, `set`,
|
||||
`toggle`, `value`).
|
||||
- **Moved out of Phase 2:** the snackbar listener goes to Phase 4 with `<x-toast>`; `data-list-row`
|
||||
rows (JS and CSS) and the list keyboard go to Phase 5 with `list` and `card`, which they style.
|
||||
`Toasts` dispatches `toast` with a 4 s default (M3's snackbar range is 4–10 s; ReStride used 3 s).
|
||||
- **`DesignGuard`**: `secondary` is a valid role now that the package exposes full M3, so it is no
|
||||
longer flagged as a daisyUI colour; icon attributes are checked per component tag (`icon` and
|
||||
`icon-right` on the same tag).
|
||||
- **Pest browser trap:** a bare `html` selector is taken as text to search for and times out;
|
||||
assert on `document.documentElement` through `assertScript`. `@name` targets `data-test`.
|
||||
- **Showcase**: colour roles in both themes side by side, type, corners and shapes, elevation,
|
||||
springs and `x-figure`, and an icon search drawing matches as CSS masks from a showcase-only
|
||||
symbol route (relative URLs — an absolute one carries `APP_URL` and misses the dev server's port).
|
||||
|
||||
### Phase 3 — Actions (`0.3.0`)
|
||||
|
||||
19. Primitives the actions need: `loading` (M3 Expressive loading indicator, contained and
|
||||
@@ -370,7 +414,7 @@ Tracked in SealShare's `docs/plans/livewire-material.md`, after `1.0.0`.
|
||||
normalisation (`false` → `null`); prefix config renames the tags.
|
||||
- **Foundation tests:** every `--md-sys-color-*` role defined in both theme blocks and
|
||||
different between them; each block declares `color-scheme`; no `prefers-color-scheme` in
|
||||
the CSS; `@theme` never `inline`; the scheme command writes both files for a known seed
|
||||
the CSS; colour blocks are `@theme inline`; the scheme command writes both files for a known seed
|
||||
(snapshot of a few roles) and fails cleanly without Node; the theme script lands before
|
||||
`@vite` and resolves `system`; `<x-icon>` throws on an unknown name; every shape fills the
|
||||
100-unit box with `currentColor` only; `Toasts` dispatches and survives `redirectTo`;
|
||||
@@ -399,8 +443,8 @@ Tracked in SealShare's `docs/plans/livewire-material.md`, after `1.0.0`.
|
||||
app records its own rules.
|
||||
- **Livewire morphing against Alpine state** inside components. Mitigation: ReStride's
|
||||
recorded traps become package rules in the skill, with tests pinning each.
|
||||
- **~7,800 SVGs** make dist archives and `vendor/` larger (~4 MB) and a cold icon lookup
|
||||
slower. Mitigation: `.gitattributes` keeps dev files out, `icons:cache` in deploys, `@source`
|
||||
- **~8,300 SVGs** make dist archives and `vendor/` larger (5.3 MB). Mitigation: each file is read
|
||||
only when drawn and kept per worker; `.gitattributes` keeps dev files out; `@source`
|
||||
never scans the SVG folders.
|
||||
- **Maintenance of a public package** is one person's job; breaking changes need semver
|
||||
discipline once ReStride also depends on it.
|
||||
|
||||
Reference in New Issue
Block a user