Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions en/framework/facade.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ Three scopes apply: **global** (everywhere), **host** (the Web Host chrome — s
| Parameter | Scope | Default | Description |
|-----------|-------|---------|-------------|
| `custom_css` | global | Google Fonts import | Global CSS — reaches host chrome, `view.page` iframes, and `view.component` shadow roots (1.0.43+). |
| `css_variables` | global | `{}` | JSON map of CSS custom properties; reaches every surface (variables inherit into shadow roots). |
| `css_variables` | global | `{}` | JSON map of arbitrary CSS custom properties; compiled for Auto and forced modes and bridged into component shadow roots. |
| `icon_sets` | global | `[]` | Iconify icon-set URLs (inline JSON only — no `fs://`) |
| `host_custom_css` | host | `""` | CSS for the host chrome only — not children. Scope class-based rules to `.wippy-host-app`. |
| `host_css_variables` | host | `{}` | CSS custom properties for the host chrome only |
Expand Down Expand Up @@ -141,7 +141,7 @@ Use `fs://` (resolved by `content_fs` at runtime), **not** `file://` — `file:/
A standalone page then links both:

- **`custom_css`** — already a `.css` file, so link it directly from where it is served.
- **`css_variables`** — JSON, so it is not linkable as-is. The facade renders it as a stylesheet at **`GET /facade/variables.css`** (a `text/css` `:root { … }` sheet, with `@dark` / `@light` compiled to `@media (prefers-color-scheme: …)`, cached 1h). It is registered on the same public router as `/facade/config`, so it carries the router prefix.
- **`css_variables`** — JSON, so it is not linkable as-is. The facade renders it at **`GET /facade/variables.css`** as base plus effective Auto-light, Auto-dark, forced Light, and forced Dark blocks. Top-level values apply everywhere; `@light` / `@dark` replace selected names. The sheet is cached for 1h and registered on the same public router as `/facade/config`, so it carries the router prefix.

```html
<!-- in login.html, served outside the Web Host -->
Expand Down
18 changes: 12 additions & 6 deletions en/frontend/micro-frontends/compliance-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -1220,7 +1220,7 @@ A Wippy module composes itself from `ns.dependency` entries. **One of those is `
|---|---|
| `app_title`, `app_name`, `app_icon` | brand identity |
| `custom_css` | shared facade-theme CSS — reaches the host chrome, `view.page` documents, and `view.component` shadow roots on supported hosts. Put shared PrimeVue appearance here; keep necessary domain layout and novel structure in module CSS. |
| `css_variables` | JSON map of CSS variable overrides (`--p-primary`, `--p-surface-*`, brand-specific `--k-*` tokens, etc.); custom properties inherit into every surface, shadow roots included. |
| `css_variables` | JSON map of arbitrary custom-property overrides. The compiler emits effective Auto/forced mode blocks, and WippyElement bridges every configured name into its inner theme root before `customCSS`. |
| `host_custom_css` | host-chrome-only CSS (not delivered to children — scope class rules to `.wippy-host-app`). Use `children_custom_css` for CSS that should reach those children but not the host chrome. |
| `hide_nav_bar`, `show_admin`, `history_mode`, `session_type`, `login_path` | UX shell behaviour |
| `fe_mode`, `host_config_layout` | managed-layout mode + layout declaration |
Expand Down Expand Up @@ -1268,7 +1268,7 @@ Mismatched placement is the #1 source of theme drift. The rule:
Anti-pattern (REJECT):
```css
.card { background: var(--p-surface-100); } /* fixed; doesn't flip */
.card { background: var(--p-primary); } /* invalid token; --p-primary-color is the right one */
.card { background: var(--p-primary); } /* valid palette seed, wrong semantic consumer; use --p-primary-color */
```

Canonical:
Expand Down Expand Up @@ -1304,7 +1304,7 @@ Canonical:

### 5.4 `@light` / `@dark` blocks

The host SUPPORTS `@light` and `@dark` keys in `cssVariables` maps — they compile to `@media (prefers-color-scheme: light/dark) { :root { ... } }` blocks ONLY. They are NOT a `[data-theme]` attribute and do not emit any attribute-scoped selector at injection time — binding is solely on the OS color-scheme preference (see `createCssVariables` in `src/shared/util/createStyle.ts`).
The host supports `@light` and `@dark` keys in `cssVariables`. Top-level variables apply to every mode; mode maps replace only their named entries. The compiler emits effective Auto-light/Auto-dark media blocks and forced `.w-theme-light` / `.w-theme-dark` selectors, with shadow-aware anchors for Web Fragments.

Example:
```yaml
Expand All @@ -1319,7 +1319,13 @@ css_variables:
--p-text-color: '#fafafa'
```

An app that toggles themes via `document.documentElement.setAttribute('data-theme', ...)` will NOT trigger these overrides; the host injects no `[data-theme]` CSS. To support a manual toggle, document it as a project-specific extension and emit your own `[data-theme]`-scoped variable block. See also [micro-frontend-app-theming.md](./micro-frontend-app-theming.md) and [host-less-mode.md](./host-less-mode.md).
Applications must use the host theme mode and `.w-theme-light` / `.w-theme-dark` protocol; do not invent `data-theme` selectors. Pages that may also render as Web Fragments pair `:root.w-theme-*` with `:host(.w-theme-*)`; a pure shadow-DOM component may use `:host(.w-theme-*)` alone. See also [micro-frontend-app-theming.md](./micro-frontend-app-theming.md) and [host-less-mode.md](./host-less-mode.md).

### 5.4.1 Exact propagation acceptance

For any configured palette, static presence checks are insufficient. Drive the inventory from `@wippy-fe/theme/tokens.json` and verify `primary`, `secondary`, `accent`, `danger`, `success`, `warn`, `info`, and `help` independently. For each family assert its base, every 50–950 shade, the four semantic aliases, and one direct shade/alias override. Also cover a surface token and an arbitrary sentinel property.

Run the same assertions in Auto-light, Auto-dark, forced Light, and forced Dark. Compare exact values at page root, WC host, and WC inner `[data-wippy-theme-root]`, then use rendered color probes so the browser physically resolves `color-mix()`. Changing primary must not change any severity family. Reject a primary-only bridge, a hand-maintained family whitelist, or advice to duplicate complete palettes in application CSS.

### 5.5 `customCSS` scoping

Expand Down Expand Up @@ -1879,7 +1885,7 @@ REJECT a submission if any of the following are true.
42b. ANY child-app `.css` file contains `:root { --p-* … }` or `:root { --<other-host-var> … }` redefinition (§5.1.2). Move to facade theming or per-page YAML `config_overrides.customization.cssVariables`.
43. PrimeVue component tokens are restyled with `!important` in `styles.css`.
43a. A child module duplicates shared PrimeVue appearance in local `.p-*` rules. Move shared appearance to facade `custom_css`; retain module CSS only for justified domain layout or novel structure.
44. Any Vue file uses `var(--p-primary)` (invalid token; must be `--p-primary-color`).
44. Any rendered UI uses palette seed `var(--p-primary)` where the mode-aware semantic consumer `--p-primary-color` is required.
45. Any Vue file uses raw Tailwind color names (`bg-red-*`, `bg-sky-*`, etc.) for semantic meaning.
46. Any hardcoded hex/rgb in Vue source for semantic colors (use `--p-danger-*` etc., or `color-mix()`).
46a. Page renders correctly in only one of `prefers-color-scheme: dark` / `light`. Verify in a browser emulator before claiming the page is shippable (§10.7).
Expand Down Expand Up @@ -2062,7 +2068,7 @@ interface ProxyConfig {
primevue: boolean // PrimeVue component CSS
markdown: boolean // markdown typography
customCss: boolean // theming.global.customCSS
customVariables: boolean // theming.global.cssVariables → :root
customVariables: boolean // theming.global.cssVariables → effective Auto/forced mode blocks
}
tailwindConfig: boolean // window.tailwind.config
resizeObserver: boolean // report iframe size
Expand Down
42 changes: 29 additions & 13 deletions en/frontend/micro-frontends/debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,39 @@ The dev overlay starts with `themeConfig`, `primevue`, `markdown`, and `iframe`

Open the dev overlay FAB → toggle the CSS injections you need → check "Auto-accept on reload".

**2. Verify CSS variables are active:**

For micro frontend apps — open DevTools, select the **inner iframe** context (not the outer page) in the frame selector:
```javascript
getComputedStyle(document.documentElement).getPropertyValue('--p-primary-color')
// non-empty = themeConfig injection is working
**2. Compare the complete effective chain:**

A non-empty token is not sufficient. Use distinct values so a stock-palette reset or accidental family alias is obvious:

```yaml
css_variables:
"--p-primary": "#dc2626"
"--p-secondary": "#7c3aed"
"--p-accent": "#0d9488"
"--p-danger": "#be123c"
"--p-success": "#15803d"
"--p-warn": "#c2410c"
"--p-info": "#0369a1"
"--p-help": "#9333ea"
"--theme-diagnostic-sentinel": "#123456"
```

For web components — in DevTools, select your custom element's **shadow root** context:
```javascript
getComputedStyle(document.documentElement).getPropertyValue('--p-primary-color')
// custom properties cross shadow boundary; empty = something wrong upstream
```
Then compare, in this order:

1. **Effective configured map:** inspect `config.theming.global.cssVariables` and confirm the base plus the active `@light` / `@dark` replacements.
2. **Page root:** read the exact token with `getComputedStyle(document.documentElement).getPropertyValue(name).trim()`.
3. **WC host:** read the same token from `getComputedStyle(customElement)`.
4. **WC inner root:** read it from `getComputedStyle(customElement.shadowRoot.querySelector('[data-wippy-theme-root]'))`.
5. **Rendered semantic color:** put `background-color: var(--p-<family>-color)` on a probe and compare its computed `backgroundColor`; this physically resolves `color-mix()`.

Repeat in Auto-light, Auto-dark, forced Light, and forced Dark. For each configured family verify its base, all 50–950 shades, `color`, `contrast-color`, `hover-color`, and `active-color`; also verify a direct shade/alias override, a surface token, and the sentinel. Page, host, and inner values must agree.

Interpret the first divergence: wrong effective map means configuration/merge; wrong page root means variable compilation/injection; correct page but wrong WC host means host propagation; correct WC host but wrong inner root means the forced-theme bridge or local defaults; equal tokens but wrong rendered color means the consuming selector or semantic alias is wrong.

**3. Web component specific:**
- If CSS vars are empty inside shadow root: check that `hostCssKeys` includes `'themeConfigUrl'` in your `wippyConfig`
- If PrimeVue components render unstyled: add `'primeVueCssUrl'` to `hostCssKeys`
- If the platform defaults are absent, check that `hostCssKeys` includes `'themeConfigUrl'`.
- If the host is correct but the inner root resets to stock values, verify a current `@wippy-fe/webcomponent-core`; do not copy a palette into component CSS.
- If PrimeVue components render unstyled, add `'primeVueCssUrl'` to `hostCssKeys`.

See [Theming: Micro Frontend Apps](./micro-frontend-app-theming.md) or [Theming: Web Components](./web-component-theming.md) for the full injection pipeline.

Expand Down
2 changes: 1 addition & 1 deletion en/frontend/micro-frontends/host-less-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ When an app or WC has drifted from the standalone-aware contract, the symptoms a
| `import` from a sibling app's source files | Shared code is being copy-pasted across module boundaries. | Extract to a workspace package or duplicate intentionally; never reach across app folders. |
| Hardcoded `fetch('/api/…')` calls | Bypasses the axios instance the proxy provides; won't pick up `env.APP_API_URL` overrides. | Use `useApi()` (apps) or `import { api } from '@wippy-fe/proxy'` (WCs). |
| `new EventSource(...)` for live data | Bypasses the host's auth/relay bridge; standalone mode has no equivalent. | Use `on('your.topic', cb)` — works in both modes (in standalone the topic just doesn't fire unless you simulate it). |
| `document.documentElement.setAttribute('data-theme', ...)` for theme switch | Custom theme attribute is invisible to the proxy's `cssVariables.@dark/@light` (those bind to `prefers-color-scheme`). | Either drive theme from OS preference and use `@dark`/`@light` blocks, or document the attribute as a project-specific extension. See [micro-frontend-app-theming.md](./micro-frontend-app-theming.md#l3--per-page-config_overrides-in-registry-yaml). |
| `document.documentElement.setAttribute('data-theme', ...)` for theme switch | `data-theme` is not the Wippy theme protocol. | Use Auto mode or the host-managed `.w-theme-light` / `.w-theme-dark` classes. Configured `@light` / `@dark` values support both paths. See [micro-frontend-app-theming.md](./micro-frontend-app-theming.md#l3--per-page-config_overrides-in-registry-yaml). |
| `import '@wippy-fe/theme/theme-config.css'` in `app.ts` | Redundant — the host injects theme-config via `themeConfig: true` proxy injection. In host-less mode dev-proxy injects it too. | Remove the import. |
| Hardcoded API base URLs in api/ modules | Won't work in host-less mode against a different env. | Read from `appConfig.env.APP_API_URL` via `useApi()`. |

Expand Down
8 changes: 4 additions & 4 deletions en/frontend/micro-frontends/micro-frontend-app-theming.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ CSS vars set in the facade's global theming scope reach the host and all iframes

```yaml
- name: css_variables
value: '{"--p-primary":"#4f8ef7","--p-primary-color":"#4f8ef7"}'
value: '{"--p-primary":"#4f8ef7","--p-secondary":"#6f7385","--p-danger":"#dc2626"}'
```

### L2 — Scoped (host or children scope)
Expand Down Expand Up @@ -54,7 +54,7 @@ Give a page its own theme by setting `config_overrides.customization.cssVariable
.demo-banner { background: var(--p-primary-color); color: var(--p-primary-contrast-color); }
```

`@dark` and `@light` keys compile to `@media (prefers-color-scheme: dark/light)` blocks — they are OS-preference based, not a `[data-theme]` attribute.
Top-level entries apply in every theme mode. `@dark` and `@light` replace selected entries and compile to both Auto-mode media blocks and forced `.w-theme-dark` / `.w-theme-light` selectors. The host owns those classes; applications do not invent a parallel `data-theme` protocol.

A `package.json` mirror under `wippy.configOverrides` provides the same shape for host-less rendering (standalone dev preview, unit tests). Keep both in sync; the YAML wins when a host is present.

Expand Down Expand Up @@ -88,7 +88,7 @@ The iframe proxy has broad runtime defaults when flags are omitted. **Enable the
- `css.themeConfig` — the full `--p-*` CSS variable system (`theme-config.css`). Enable to inherit the theme palette.
- `css.primevue` — PrimeVue component styles. Enable for apps using PrimeVue.
- `css.customCss` — the host-composed child-facing custom CSS: facade **global + children** custom CSS merged into `config.theming.global.customCSS`, plus any per-page override. The flag gates this injection rather than naming a single scope. Enable to receive facade/per-page custom CSS.
- `css.customVariables` — child-projected `config.theming.global.cssVariables` as `:root { … }`. Enable to receive theme variable overrides.
- `css.customVariables` — child-projected `config.theming.global.cssVariables` as effective base, Auto-light, Auto-dark, forced Light, and forced Dark blocks. Enable to receive theme variable overrides.
- `css.markdown` — `.data-body` markdown styles. Enable only if your page renders markdown content.

Full flag reference and runtime defaults: [CSS Injection](../web-host/css-injection.md).
Expand Down Expand Up @@ -124,7 +124,7 @@ To confirm CSS variables are active in your running page: open DevTools, select
getComputedStyle(document.documentElement).getPropertyValue('--p-primary-color')
```

A non-empty result confirms `themeConfig` injection is working. Full debugging workflow: [Debugging](./debugging.md).
A non-empty result proves only that some theme CSS loaded. Compare the exact configured value at the page root, WC host, WC inner root, and rendered semantic color; verify every configured family. Full workflow: [Debugging](./debugging.md).

---

Expand Down
Loading