ngx-theme-stack 3.6.1 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/schematics/skill/index.js +26 -17
- package/schematics/skill/index.js.map +1 -1
package/README.md
CHANGED
|
@@ -105,7 +105,7 @@ The installation command automates the following:
|
|
|
105
105
|
| `package.json` | Adds a `"prebuild"` script for theme synchronization |
|
|
106
106
|
| `angular.json` | Registers `themes.css` and optimizes build config |
|
|
107
107
|
| `themes.css` | Scaffolds base theme tokens if they don't exist |
|
|
108
|
-
| `SKILL.md` | Generates an AI Agent Skill under `.
|
|
108
|
+
| `SKILL.md` | Generates an AI Agent Skill under `.agents/skills/` (optional) |
|
|
109
109
|
|
|
110
110
|
> [!TIP]
|
|
111
111
|
> **Re-configuration support:** Run `ng add` multiple times freely. The schematic updates existing code without duplicating it.
|
|
@@ -372,7 +372,7 @@ The AI Agent Skill tells coding assistants exactly how to implement theme toggle
|
|
|
372
372
|
|
|
373
373
|
### Setup
|
|
374
374
|
|
|
375
|
-
1. **Automatic:** During `ng add`, you are prompted to generate the skill file. Selecting **Yes** automatically creates `.
|
|
375
|
+
1. **Automatic:** During `ng add`, you are prompted to generate the skill file. Selecting **Yes** automatically creates `.agents/skills/ngx-theme-stack/SKILL.md` in your project root.
|
|
376
376
|
2. **Manual:** If you did not generate it during installation, or deleted it, you can create/re-create the skill by running:
|
|
377
377
|
```bash
|
|
378
378
|
ng generate ngx-theme-stack:skill
|
package/package.json
CHANGED
|
@@ -36,27 +36,27 @@ Toggle Cycle Select ← Convenience services (pick ONE per component)
|
|
|
36
36
|
|
|
37
37
|
## Interaction Rules
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
2. **Cycle** —
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
39
|
+
> [!IMPORTANT]
|
|
40
|
+
> **MANDATORY INTERACTION RULE**: If the user asks to implement theme switching, configuration, or a theme-related component but does NOT explicitly specify which convenience service to use (\`ThemeToggleService\`, \`ThemeCycleService\`, or \`ThemeSelectService\`), you **MUST NOT** make assumptions or start writing code.
|
|
41
|
+
> You **MUST** stop and ask the user to explicitly choose one of the three patterns before proceeding.
|
|
42
|
+
>
|
|
43
|
+
> Present these options clearly:
|
|
44
|
+
> 1. **Toggle** (\`ThemeToggleService\`) — Binary toggle between dark and light themes (best for simple buttons or icon toggles).
|
|
45
|
+
> 2. **Cycle** (\`ThemeCycleService\`) — Rotates through all configured themes (best for 3+ themes with a single button).
|
|
46
|
+
> 3. **Select** (\`ThemeSelectService\`) — Full dropdown/radio list of all available themes (best for settings pages or explicit pickers).
|
|
47
|
+
>
|
|
48
|
+
> **Custom Themes Inquiry**: In addition to the service choice, you **MUST** ask the user if they want to configure or need any **custom themes** (e.g. \`sunset\`, \`ocean\`, \`sepia\`) beyond the default \`light\`, \`dark\`, and \`system\`. Prompt the user for details on what they are looking for or need (such as specific custom theme names, colors, or CSS variables) to help them scaffold these customizations.
|
|
49
|
+
>
|
|
50
|
+
> **DO NOT** generate any component code or configurations until the user has explicitly responded to these questions.
|
|
51
51
|
|
|
52
52
|
## Constraints
|
|
53
53
|
|
|
54
54
|
- Always import from \`'ngx-theme-stack'\` — never deep-import internal paths.
|
|
55
55
|
- Call \`provideThemeStack()\` exactly once, in the root \`app.config.ts\` providers.
|
|
56
56
|
- Custom themes are **merged** with built-ins. Passing \`['sepia']\` resolves to \`['system', 'light', 'dark', 'sepia']\`.
|
|
57
|
-
- After
|
|
57
|
+
- **Mandatory Theme Synchronization**: After configuring, adding, or modifying themes in \`provideThemeStack()\`, you **MUST** run the synchronization schematic command: \`ng generate ngx-theme-stack:sync --project PROJECT_NAME\` (or explicitly instruct the user to run it if you cannot execute commands). Failing to synchronize themes after modification is a critical violation that breaks theme compilation.
|
|
58
58
|
- \`isDark()\` and \`isLight()\` return \`false\` for custom themes — use \`resolvedTheme()\` directly.
|
|
59
|
-
- Guard theme-dependent template
|
|
59
|
+
- **Mandatory SSR Guard**: You MUST guard all theme-dependent template elements (e.g. text, icons, images, styling classes based on theme signals) using \`@if (theme.isHydrated())\`. Using theme signals (\`isDark()\`, \`resolvedTheme()\`, etc.) directly in templates without checking \`isHydrated()\` causes content flickering and critical Angular hydration mismatch errors in SSR.
|
|
60
60
|
- Never call \`setTheme()\` with a theme name not registered in the \`themes\` array — it throws \`NgxThemeStackError\`.
|
|
61
61
|
- Pick ONE convenience service per component — do not mix Toggle, Cycle, and Select in the same component.
|
|
62
62
|
|
|
@@ -114,16 +114,25 @@ All services expose these signals: \`selectedTheme()\`, \`resolvedTheme()\`, \`i
|
|
|
114
114
|
For complete component templates, copy from \`assets/\` directory in this skill folder.
|
|
115
115
|
For full API details, read \`references/api-reference.md\`.
|
|
116
116
|
|
|
117
|
-
## SSR Hydration Guard
|
|
117
|
+
## SSR Hydration Guard & Layout Stability
|
|
118
|
+
|
|
119
|
+
Guard theme-dependent template content behind \`isHydrated()\` in SSR to prevent hydration mismatches and layout flickering.
|
|
118
120
|
|
|
119
121
|
\`\`\`html
|
|
120
122
|
@if (theme.isHydrated()) {
|
|
121
123
|
<img [src]="theme.isDark() ? 'dark-logo.png' : 'light-logo.png'">
|
|
122
124
|
} @else {
|
|
123
|
-
|
|
125
|
+
<!-- The placeholder/skeleton MUST match the exact size and spacing of the hydrated image -->
|
|
126
|
+
<div class="logo-skeleton" style="width: 150px; height: 40px; display: inline-block;"></div>
|
|
124
127
|
}
|
|
125
128
|
\`\`\`
|
|
126
129
|
|
|
130
|
+
### Skeleton & Layout Stability Guidelines
|
|
131
|
+
|
|
132
|
+
When designing fallback skeleton loaders/placeholders:
|
|
133
|
+
1. **Dimension & Spacing Match**: The fallback element (e.g., inside the \`@else\` block) MUST occupy the exact same space, size, margins, padding, positioning, and responsive constraints as the hydrated element. This ensures zero layout shift (preventing CLS issues) and keeps the Largest Contentful Paint (LCP) optimized.
|
|
134
|
+
2. **Granular Skeletons**: NEVER wrap an entire complex component or large layout block in an \`isHydrated()\` guard if only a single word, label, icon, or sub-element changes dynamically based on the theme. Instead, place the \`isHydrated()\` guard at the most granular level possible (e.g., directly wrapping just the dynamic text or icon inside the button), leaving the surrounding button wrapper and layout static. A full-element skeleton should only be used if the entire component's structure/layout is completely dynamic.
|
|
135
|
+
|
|
127
136
|
## CSS Theme Tokens
|
|
128
137
|
|
|
129
138
|
Define in \`src/themes.css\` (scaffolded by \`ng add\`):
|
|
@@ -380,7 +389,7 @@ export class ThemeSelect {
|
|
|
380
389
|
\`\`\`
|
|
381
390
|
`;
|
|
382
391
|
// ── Schematic logic ─────────────────────────────────────────────────────────
|
|
383
|
-
const SKILL_ROOT = '.
|
|
392
|
+
const SKILL_ROOT = '.agents/skills/ngx-theme-stack';
|
|
384
393
|
const FILES = [
|
|
385
394
|
{ path: `${SKILL_ROOT}/SKILL.md`, content: SKILL_CONTENT },
|
|
386
395
|
{ path: `${SKILL_ROOT}/references/api-reference.md`, content: API_REFERENCE },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/skill/index.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../projects/ngx-theme-stack/schematics/skill/index.ts"],"names":[],"mappings":";;AAyZA,sCAUC;AAED,sBAMC;AAxaD,+EAA+E;AAE/E,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiKrB,CAAC;AAEF,+EAA+E;AAE/E,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwIrB,CAAC;AAEF,+EAA+E;AAE/E,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBvB,CAAC;AAEF,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;CAwBtB,CAAC;AAEF,MAAM,eAAe,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCvB,CAAC;AAEF,+EAA+E;AAE/E,MAAM,UAAU,GAAG,gCAAgC,CAAC;AAEpD,MAAM,KAAK,GAAwC;IACjD,EAAE,IAAI,EAAE,GAAG,UAAU,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE;IAC1D,EAAE,IAAI,EAAE,GAAG,UAAU,8BAA8B,EAAE,OAAO,EAAE,aAAa,EAAE;IAC7E,EAAE,IAAI,EAAE,GAAG,UAAU,mCAAmC,EAAE,OAAO,EAAE,eAAe,EAAE;IACpF,EAAE,IAAI,EAAE,GAAG,UAAU,kCAAkC,EAAE,OAAO,EAAE,cAAc,EAAE;IAClF,EAAE,IAAI,EAAE,GAAG,UAAU,mCAAmC,EAAE,OAAO,EAAE,eAAe,EAAE;CACrF,CAAC;AAEF,SAAgB,aAAa,CAAC,IAAU,EAAE,OAAyB;IACjE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACxC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,IAAI,YAAY,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAgB,KAAK,CAAC,OAAe;IACnC,OAAO,CAAC,IAAU,EAAE,OAAyB,EAAE,EAAE;QAC/C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,0CAA0C,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QACjF,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}
|