feat(10.1-02): render header and form partials through an allowlisted node renderer
- partialNodes rebuilds the server node tree with h() under the server's tag, attribute and URL lists - PartialHost owns the skeleton, empty and failure states and keeps nodes visible on refetch - type: partial is a valueless group-labelled field rendered on create and update - ListView shows headerPartial above the list card and refetches it after bulk delete - summer-partial and summer-stats style kit in main.css, documented in the cabana README; dist rebuilt
This commit is contained in:
@@ -67,6 +67,22 @@ A statistics strip above a list, for example:
|
||||
</dl>
|
||||
```
|
||||
|
||||
### Partial style kit and plugin CSS variables
|
||||
|
||||
The admin SPA ships a small set of stable CSS classes that partial templates may use through the allowlisted `class` attribute, so server-rendered content looks native without any plugin CSS:
|
||||
|
||||
| Class | Use |
|
||||
|-------|-----|
|
||||
| `summer-partial` | Set by the SPA on every partial's root: 14px/1.5 body text, long words and URLs wrap, `p`/`ul`/`ol` spaced 8px apart, links underlined with the focus ring. |
|
||||
| `summer-stats` | A card strip (surface background, border, 16px radius, card shadow, 16px 20px padding) whose items wrap onto more rows with a 32px column gap and an 8px row gap. Safe on a `<dl>`. |
|
||||
| `summer-stat` | One item of the strip: the value is shown above the label while `<dt>` stays first in the DOM. |
|
||||
| `summer-stat__label` | The item label: 13px, muted, wraps. |
|
||||
| `summer-stat__value` | The item value: 20px, weight 600, tabular numbers. |
|
||||
|
||||
Use `<dl class="summer-stats">` with one `<div class="summer-stat">` per item holding a `<dt class="summer-stat__label">` and a `<dd class="summer-stat__value">`, as in the example above.
|
||||
|
||||
Plugin CSS (declared through `pact.AdminClientAssets`) and any widget shadow DOM may read only these public variables. They inherit into shadow roots and switch automatically in dark mode: `--c-bg`, `--c-surface`, `--c-subtle`, `--c-border`, `--c-border-strong`, `--c-text`, `--c-muted`, `--c-placeholder`, `--c-primary`, `--c-on-primary`, `--c-danger`, `--c-danger-soft`, `--c-hover`, `--c-sel`, `--c-skel`, `--c-ring`. Plugins must not hardcode hex colours and must not rely on Tailwind utility classes: the SPA build purges every utility it does not use itself. A controller's stylesheets are disabled while another controller's list or form is open.
|
||||
|
||||
### Controller assets
|
||||
|
||||
`GET <prefix>/assets/{vendor}/{plugin}/{file...}` serves the files controllers declare through `pact.AdminClientAssets`. A plugin file `assets/js/lookup.js` of plugin `acme.blog` is served at `<prefix>/assets/acme/blog/js/lookup.js`, and the schemas list it as `<prefix>/assets/acme/blog/js/lookup.js?v=<first 12 hex characters of its sha256>`. The route is public, like the SPA shell, and serves only the exact files declared at boot, never the plugin's embedded tree: YAML and templates are not reachable, and any other path falls through to the SPA, which also serves its own build assets under `<prefix>/assets/`. Each response carries an explicit JavaScript or CSS `Content-Type`, `X-Content-Type-Options: nosniff`, the admin Content-Security-Policy (`script-src 'self'`), `Cross-Origin-Resource-Policy: same-origin`, `Cache-Control: no-cache` and a sha256 `ETag`, so conditional requests answer 304 and a rebuilt binary is picked up at once.
|
||||
|
||||
Reference in New Issue
Block a user