From 8afe9bac6abac4b65eb1686c7e7c91275001a466 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Sun, 13 Sep 2026 16:25:35 +0200 Subject: [PATCH] Keep planning notes out of the repository docs/plans is ignored from now on; the notes stay on the machine that wrote them. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy --- .gitignore | 3 + docs/plans/livewire-material.md | 658 -------------------------------- 2 files changed, 3 insertions(+), 658 deletions(-) delete mode 100644 docs/plans/livewire-material.md diff --git a/.gitignore b/.gitignore index fb0525dc..c5a70662 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ /workbench/public/hot /tests/Browser/Screenshots .DS_Store + +# Planning notes stay local +/docs/plans diff --git a/docs/plans/livewire-material.md b/docs/plans/livewire-material.md deleted file mode 100644 index ce9e217f..00000000 --- a/docs/plans/livewire-material.md +++ /dev/null @@ -1,658 +0,0 @@ -# Livewire Material: a shared Material 3 Expressive component library - -> Split on 2026-09-13 from SealShare's `docs/plans/livewire-material.md`, where the plan was -> made. SealShare's adoption (Phase 11) stays in SealShare's copy. - -## Goal - -ReStride has just left maryUI and daisyUI for **Material 3 Expressive on its own Blade -components** (`ReStride/docs/plans/material-expressive.md`, done 2026-09-10). Doing that -again, by hand, in every Laravel + Livewire app is what this package avoids. - -**`nonameweb/livewire-material`** carries the whole current M3 Expressive component catalogue -as Blade components for Livewire, together with everything around them — colour scheme -generation, tokens, the theme script, Material Symbols, Google Sans Flex, motion, error pages, -a mail theme, a showcase, test helpers and AI guidelines. SealShare converts to it once it is -complete (`1.0.0`); ReStride adopts it later, in a plan of its own. - -## Context - -**Stacks.** SealShare: Laravel 13.31, Livewire 4.4, maryUI 2.9.10 (no prefix), daisyUI 5.7, -Tailwind 4.3, Pest 5.1, Octane on FrankenPHP, PHP 8.5; public on GitHub under MIT, image -published to `ghcr.io/surtic86/sealshare`. ReStride: same Laravel / Livewire / Tailwind / Pest, -private on `gitea.nonameweb.ch`, CI through Gitea act_runner. - -**What ReStride already solved** (and the package generalises): - -- 45 anonymous components in `resources/views/components/`, maryUI's names and props, M3 - styling; class components only where PHP earns it. -- `resources/css/material/{color,shape,type,motion,elevation,field,menu,table,list}.css`; - `@theme` (never `inline`) mapping M3 roles to utilities; `--color-*: initial` so only tokens - compile; `:root` dark + `[data-theme=light]`, each with its own `color-scheme`. -- Material Symbols Rounded (400/0/24) as local SVGs registered as `blade-icons` sets - (`ms`/`msf`), `config/blade-icons.php` turning off blade-icons' own ``. -- Google Sans Flex, a 63 KB Latin subset (weight 400–700, ROND 0–100). -- Spring motion as CSS `linear()` curves; press shape-morph; Expressive shapes generated by - formula into `resources/svg/shapes`. -- `App\Livewire\Concerns\Toasts` (protected `success|error|warning|info`, dispatching a window - event) and a snackbar ``. -- ~30 component tests (`$this->blade()`), browser tests (Pest browser plugin), and guard tests - (`DesignLanguageTest`, `MaterialTokensTest`, `MaterialSymbolsTest`). -- The Livewire traps, recorded in `../ReStride/.ai/rules/ui.md`: `wire:ignore.self` on a - `showModal()` dialog; never pass `hidden` or a position to a component (wrap it); Blade - directives do not compile inside a component tag's attributes; `wire('model')->value()` is - `false`, not `null`, without `wire:model`; a field's states are CSS selectors (`:has()`), - marked with `data-invalid` / `data-floated` / `data-readonly` where the control cannot carry - them; the customizable select's traps (`../ReStride/.ai/rules/components-views-components.md`). -- Mail on M3 (`../ReStride/docs/plans/material-mail.md`): one theme CSS inlined onto bare - tags, light only, because `CssToInlineStyles` strips `@media`. - -**What in ReStride is app-specific** and does not move: the doctrine (two button weights, no -tertiary / primary-container — enforced by its build), `restride-theme`, `$store.install` / -`$store.connection` in the shell, `--bottom-bar` set by its layout, sport / zone / route -tokens, `training-row`, `map-shell`, `map-chip`, `product-shot`, `star-rating`, -`share-button`, the unDraw repaint, the Ace code editor. - -**Constraints found.** - -- `gitea.nonameweb.ch` requires sign-in to view anything (`/explore/repos` → login, API 403). - A "public" repo there cannot be installed anonymously until that changes. - *(Resolved in step 1.)* -- Laravel's Markdown mail accepts a namespaced view as theme - (`Illuminate/Mail/Markdown.php:114`), so a package can render the theme CSS from data. -- Laravel **replaces** the `errors` view namespace at render time with - `config('view.paths')` + `/errors` and the framework's own - (`Illuminate/Foundation/Exceptions/RegisterErrorViewPaths.php`), so error views a package - adds with `addNamespace('errors', …)` are wiped; only a path in `view.paths` survives. -- M3 Expressive deprecates bottom app bar, navigation drawer, the original navigation bar, - segmented button, small FAB and medium/large top app bar (material-components-android docs). -- CSS anchor positioning is in Chrome 125+, Firefox 147+, Safari 18.4+ (flip via - `@position-try` from Safari 18.4). -- Boost loads a package's `resources/boost/guidelines/core.blade.php` and its skills on - `boost:install` / `boost:update --discover`. - -## Decisions - -- **A shared Composer package, SealShare its first consumer; ReStride adopts later in its own - plan** — SealShare's small surface proves the API; ReStride's three-day-old migration is not - put at risk. -- **Public repo on `gitea.nonameweb.ch`, MIT** — SealShare is public; its CI, Docker build, - manual install and fork PRs must install the package without credentials. SealShare - requires it through a `vcs` repository entry. Material Symbols (Apache-2.0), Google Sans - Flex (OFL) and material-web token values (Apache-2.0) are compatible; attributions ship in - `NOTICE`. -- **Prerequisite: Gitea allows anonymous reads** (`[service] REQUIRE_SIGNIN_VIEW = false`, or - `expensive` on 1.23+) — otherwise "public" is not installable. -- **Name `nonameweb/livewire-material`, namespace `NoNameWeb\LivewireMaterial`, - `config/livewire-material.php`, views `livewire-material::`, commands `material:*`** — says - what it is and what it is for. -- **Components unprefixed by default, prefix configurable** (maryUI's model, via - `Blade::anonymousComponentPath($path, $prefix)`) — ReStride's call sites keep their names; - SealShare's maryUI tags keep theirs. The provider sets `blade-icons.components.default` to - `null`, or blade-icons' class `` beats ours. -- **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, 4,135 symbols, - 5.3 MB), fetched by a maintenance script in the package repo, never at runtime — any name works - in any app. **`` 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 `` 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 - primary-container included) and container is available; each app enforces its own rules - through a configurable guard helper the package ships. -- **`variant` + `color` props** — `variant="filled|tonal|outlined|text|elevated"`, - `color="primary|secondary|tertiary|error|success|warning|info"`, default `text` in primary; - both validated against fixed lists, unknown values fall back to the default. Shorthands - kept: `primary` = filled primary, `danger` = filled error, `caution` = filled warning. The - same pattern for badge, alert, chip, icon button and FAB (`tone` stays an alias of `color` - where ReStride used it). -- **`php artisan material:scheme {seed} --variant=`** — runs Google's - `material-color-utilities` from a single prebundled Node script inside the package; writes - the app's `resources/css/material-scheme.css` (dark and light `--md-sys-color-*`, plus - `success`/`warning`/`info` custom colours, harmonisation off) and - `resources/css/material-scheme.json` (the light hexes, for the mail theme). Output is - committed. -- **Theme: a head script component, `light | dark | system`** — sets `data-theme` before paint; - CSS keys only on the attribute and never asks `prefers-color-scheme`; only the script reads - the OS (and follows its changes while `system`). `$store.theme` is the one state every - toggle shares. Config: `theme.default`, `theme.storage_key`, `theme.legacy_keys` (adopted - once, then removed). -- **The whole M3 Expressive catalogue, current components only** — the six deprecated ones are - skipped; their names alias where free (`` renders a connected button group, FAB - `size="sm"` renders medium). -- **Plus the non-M3 pieces apps need** — data table, sort header, pagination views, file input, - password, stat, alert, empty state, collapse, section nav, account menu, theme toggle, an - adaptive app-shell composition, error pages, mail theme. -- **Modern browser floor, no third-party JS** — Chrome 125+, Firefox 147+, Safari 18.4+: - native ``, Popover API, CSS anchor positioning, customizable `