ngx-theme-stack 3.8.2 → 3.8.3
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 +9 -9
- package/package.json +1 -1
- package/schematics/skill/index.js +93 -229
- package/schematics/skill/index.js.map +1 -1
package/README.md
CHANGED
|
@@ -303,18 +303,18 @@ export class MyAdvancedComponent {
|
|
|
303
303
|
|
|
304
304
|
:root,
|
|
305
305
|
.light {
|
|
306
|
-
--
|
|
307
|
-
--
|
|
306
|
+
--background: #ffffff;
|
|
307
|
+
--foreground: #333333;
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
.dark {
|
|
311
|
-
--
|
|
312
|
-
--
|
|
311
|
+
--background: #121212;
|
|
312
|
+
--foreground: #ffffff;
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
.sunset {
|
|
316
|
-
--
|
|
317
|
-
--
|
|
316
|
+
--background: #ff5f6d;
|
|
317
|
+
--foreground: #ffffff;
|
|
318
318
|
}
|
|
319
319
|
```
|
|
320
320
|
|
|
@@ -329,15 +329,15 @@ export class MyAdvancedComponent {
|
|
|
329
329
|
@import 'tailwindcss';
|
|
330
330
|
|
|
331
331
|
@theme {
|
|
332
|
-
--color-
|
|
333
|
-
--color-
|
|
332
|
+
--color-background: var(--background);
|
|
333
|
+
--color-foreground: var(--foreground);
|
|
334
334
|
}
|
|
335
335
|
```
|
|
336
336
|
|
|
337
337
|
### Use in components — no `dark:` prefix needed
|
|
338
338
|
|
|
339
339
|
```html
|
|
340
|
-
<div class="bg-
|
|
340
|
+
<div class="bg-background text-foreground shadow-xl">
|
|
341
341
|
<!-- automatically reflects the active theme -->
|
|
342
342
|
</div>
|
|
343
343
|
```
|
package/package.json
CHANGED
|
@@ -2,306 +2,170 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateSkill = generateSkill;
|
|
4
4
|
exports.skill = skill;
|
|
5
|
-
// ── SKILL.md (Tier 2 — loaded on activation)
|
|
5
|
+
// ── SKILL.md (Tier 2 — loaded on activation) ─────────
|
|
6
6
|
const SKILL_CONTENT = `---
|
|
7
7
|
name: ngx-theme-stack
|
|
8
|
-
description:
|
|
9
|
-
Use when installing, configuring, or building theme-switching UI with
|
|
10
|
-
ngx-theme-stack in Angular 20+. Covers provideThemeStack setup,
|
|
11
|
-
ThemeToggle/Cycle/Select services, SSR hydration guards, CSS variable
|
|
12
|
-
theming, and Tailwind CSS v4 integration. Do not use for generic Angular
|
|
13
|
-
styling, standalone dark-mode CSS, or projects not using ngx-theme-stack.
|
|
8
|
+
description: Signal-based theme manager for Angular 20+. Covers setup, services, SSR guards, and Tailwind v4.
|
|
14
9
|
compatibility: Angular 20+ with TypeScript. Optional Tailwind CSS v4.
|
|
15
10
|
metadata:
|
|
16
11
|
author: WanderleeDev
|
|
17
|
-
version:
|
|
12
|
+
version: '1.1.0'
|
|
18
13
|
---
|
|
19
14
|
|
|
20
15
|
# ngx-theme-stack
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
Supports dark/light/system/custom themes, SSR, and zero-flash rendering.
|
|
24
|
-
|
|
25
|
-
## Architecture
|
|
26
|
-
|
|
27
|
-
\`\`\`
|
|
28
|
-
provideThemeStack() ← DI configuration (app.config.ts)
|
|
29
|
-
│
|
|
30
|
-
CoreThemeService ← Foundation: state, persistence, DOM updates
|
|
31
|
-
│
|
|
32
|
-
┌────┼────────────┐
|
|
33
|
-
│ │ │
|
|
34
|
-
Toggle Cycle Select ← Convenience services (pick ONE per component)
|
|
35
|
-
\`\`\`
|
|
17
|
+
Headless, signal-based theme manager for Angular 20+.
|
|
36
18
|
|
|
37
19
|
## Interaction Rules
|
|
38
20
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
52
|
-
## Constraints
|
|
53
|
-
|
|
54
|
-
- Always import from \`'ngx-theme-stack'\` — never deep-import internal paths.
|
|
55
|
-
- Call \`provideThemeStack()\` exactly once, in the root \`app.config.ts\` providers.
|
|
56
|
-
- Custom themes are **merged** with built-ins. Passing \`['sepia']\` resolves to \`['system', 'light', 'dark', 'sepia']\`.
|
|
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
|
-
- \`isDark()\` and \`isLight()\` return \`false\` for custom themes — use \`resolvedTheme()\` directly.
|
|
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
|
-
- Never call \`setTheme()\` with a theme name not registered in the \`themes\` array — it throws \`NgxThemeStackError\`.
|
|
61
|
-
- Pick ONE convenience service per component — do not mix Toggle, Cycle, and Select in the same component.
|
|
62
|
-
|
|
63
|
-
## Installation
|
|
64
|
-
|
|
65
|
-
\`\`\`bash
|
|
66
|
-
ng add ngx-theme-stack
|
|
67
|
-
\`\`\`
|
|
68
|
-
|
|
69
|
-
For Bun environments (where \`ng add\` is unsupported):
|
|
70
|
-
\`\`\`bash
|
|
71
|
-
bun add ngx-theme-stack
|
|
72
|
-
ng generate ngx-theme-stack:ng-add
|
|
73
|
-
\`\`\`
|
|
74
|
-
|
|
75
|
-
## Configuration
|
|
76
|
-
|
|
77
|
-
Configure in \`app.config.ts\` via \`provideThemeStack()\`:
|
|
78
|
-
|
|
79
|
-
\`\`\`typescript
|
|
80
|
-
import { provideThemeStack } from 'ngx-theme-stack';
|
|
81
|
-
|
|
82
|
-
export const appConfig: ApplicationConfig = {
|
|
83
|
-
providers: [
|
|
84
|
-
provideThemeStack({
|
|
85
|
-
themes: ['sunset', 'ocean'] as const,
|
|
86
|
-
defaultTheme: 'system',
|
|
87
|
-
mode: 'class',
|
|
88
|
-
strategy: 'critters',
|
|
89
|
-
storageKey: 'ngx-theme-stack',
|
|
90
|
-
}),
|
|
91
|
-
],
|
|
92
|
-
};
|
|
93
|
-
\`\`\`
|
|
94
|
-
|
|
95
|
-
| Option | Type | Default | Description |
|
|
96
|
-
| -------------- | ---------- | ----------------------------- | ---------------------------- |
|
|
97
|
-
| \`themes\` | \`string[]\` | \`['light', 'dark', 'system']\` | Merged with built-ins |
|
|
98
|
-
| \`defaultTheme\` | \`string\` | \`'system'\` | Theme on first visit |
|
|
99
|
-
| \`mode\` | \`NgMode\` | \`'class'\` | How the theme is applied |
|
|
100
|
-
| \`strategy\` | \`NgStrategy\`| \`'critters'\` | Anti-flash strategy |
|
|
101
|
-
| \`storageKey\` | \`string\` | \`'ngx-theme-stack'\` | localStorage persistence key |
|
|
102
|
-
|
|
103
|
-
## Services Quick Reference
|
|
104
|
-
|
|
105
|
-
| Service | Method | Use case |
|
|
106
|
-
| -------------------- | ------------ | --------------------------------- |
|
|
107
|
-
| \`ThemeToggleService\` | \`toggle()\` | Binary dark/light switch |
|
|
108
|
-
| \`ThemeCycleService\` | \`cycle()\` | Rotate through all themes |
|
|
109
|
-
| \`ThemeSelectService\` | \`select(t)\` | Dropdown / radio / tab selection |
|
|
110
|
-
| \`CoreThemeService\` | \`setTheme(t)\`| Advanced / low-level access |
|
|
111
|
-
|
|
112
|
-
All services expose these signals: \`selectedTheme()\`, \`resolvedTheme()\`, \`isDark()\`, \`isLight()\`, \`isSystem()\`, \`isHydrated()\`.
|
|
21
|
+
- **MANDATORY RULE**: If the user asks for theme components/switching, you **MUST** ask them to choose:
|
|
22
|
+
- **Toggle** (\`ThemeToggleService\`) - Binary dark/light toggle.
|
|
23
|
+
- **Cycle** (\`ThemeCycleService\`) - Rotate through all themes.
|
|
24
|
+
- **Select** (\`ThemeSelectService\`) - Full picker dropdown/radio selection.
|
|
25
|
+
- **Custom Themes Inquiry**: Ask if they want custom themes (e.g. \`sunset\`, colors, or CSS variables).
|
|
26
|
+
- **DO NOT** generate code or configs until the user responds to these questions.
|
|
113
27
|
|
|
114
|
-
|
|
28
|
+
## Constraints & Rules
|
|
115
29
|
|
|
116
|
-
|
|
30
|
+
- Call \`provideThemeStack()\` once in root \`app.config.ts\`. Custom themes merge with defaults.
|
|
31
|
+
- **Theme Synchronization**: Run \`ng generate ngx-theme-stack:sync --project PROJECT_NAME\` after changing config.
|
|
32
|
+
- \`isDark()\` / \`isLight()\` return false for custom themes (use \`resolvedTheme()\`).
|
|
33
|
+
- Pick ONE convenience service per component. Do not write custom localStorage or direct DOM logic.
|
|
117
34
|
|
|
118
|
-
## SSR Hydration
|
|
35
|
+
## SSR Hydration & Layout Stability
|
|
119
36
|
|
|
120
|
-
|
|
37
|
+
Wrap theme-dependent elements in \`@if (theme.isHydrated())\` to prevent layout shift and SSR mismatches. Fallback placeholders in \`@else\` must match the exact hydrated dimensions.
|
|
121
38
|
|
|
122
39
|
\`\`\`html
|
|
123
40
|
@if (theme.isHydrated()) {
|
|
124
|
-
|
|
41
|
+
<img [src]="theme.isDark() ? darkLogo : lightLogo" />
|
|
125
42
|
} @else {
|
|
126
|
-
|
|
127
|
-
<div class="logo-skeleton" style="width: 150px; height: 40px; display: inline-block;"></div>
|
|
43
|
+
<div class="logo-skeleton"></div>
|
|
128
44
|
}
|
|
129
45
|
\`\`\`
|
|
130
46
|
|
|
131
|
-
|
|
47
|
+
## Configuration & API
|
|
132
48
|
|
|
133
|
-
|
|
134
|
-
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.
|
|
135
|
-
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.
|
|
49
|
+
See [references/api-reference.md](references/api-reference.md) for APIs. Examples: [Toggle](assets/theme-toggle.ts) · [Cycle](assets/theme-cycle.ts) · [Select](assets/theme-select.ts).
|
|
136
50
|
|
|
137
|
-
|
|
51
|
+
\`\`\`typescript
|
|
52
|
+
import { provideThemeStack } from 'ngx-theme-stack';
|
|
53
|
+
export const appConfig = {
|
|
54
|
+
providers: [provideThemeStack({ themes: ['sunset'] as const, strategy: 'critters' })],
|
|
55
|
+
};
|
|
56
|
+
\`\`\`
|
|
138
57
|
|
|
139
|
-
|
|
58
|
+
| Service | Method | Signals |
|
|
59
|
+
| -------------------- | ----------- | ------------------------------------------------------------------------------------------- |
|
|
60
|
+
| \`ThemeToggleService\` | \`toggle()\` | \`selectedTheme()\`, \`resolvedTheme()\`, \`isDark()\`, \`isLight()\`, \`isSystem()\`, \`isHydrated()\` |
|
|
61
|
+
| \`ThemeCycleService\` | \`cycle()\` | |
|
|
62
|
+
| \`ThemeSelectService\` | \`select(t)\` | |
|
|
140
63
|
|
|
141
|
-
|
|
142
|
-
:root, .light { --bg: #fff; --text: #1a1a1a; }
|
|
143
|
-
.dark { --bg: #0a0a0a; --text: #f5f5f5; }
|
|
144
|
-
.sunset { --bg: #ff5f6d; --text: #fff; }
|
|
145
|
-
\`\`\`
|
|
64
|
+
## Styling: CSS Variables & Tailwind Separation
|
|
146
65
|
|
|
147
|
-
|
|
66
|
+
Define CSS variables in \`src/themes.css\` and map them to Tailwind in \`src/styles.css\` (use semantic classes, not \`dark:\`):
|
|
148
67
|
|
|
149
|
-
|
|
68
|
+
\`\`\`css
|
|
69
|
+
/* src/themes.css */
|
|
70
|
+
:root,
|
|
71
|
+
.light {
|
|
72
|
+
--background: #fff;
|
|
73
|
+
--foreground: #1a1a1a;
|
|
74
|
+
}
|
|
75
|
+
.dark {
|
|
76
|
+
--background: #0a0a0a;
|
|
77
|
+
--foreground: #f5f5f5;
|
|
78
|
+
}
|
|
79
|
+
.sunset {
|
|
80
|
+
--background: #ff5f6d;
|
|
81
|
+
--foreground: #fff;
|
|
82
|
+
}
|
|
83
|
+
\`\`\`
|
|
150
84
|
|
|
151
85
|
\`\`\`css
|
|
86
|
+
/* src/styles.css */
|
|
152
87
|
@import 'tailwindcss';
|
|
153
88
|
@theme {
|
|
154
|
-
--color-
|
|
155
|
-
--color-
|
|
89
|
+
--color-background: var(--background);
|
|
90
|
+
--color-foreground: var(--foreground);
|
|
156
91
|
}
|
|
157
92
|
\`\`\`
|
|
158
93
|
|
|
159
|
-
Use semantic classes — no \`dark:\` prefix needed: \`bg-bg text-text\`.
|
|
160
|
-
|
|
161
94
|
## Anti-patterns
|
|
162
95
|
|
|
163
|
-
- Do NOT
|
|
164
|
-
- Do NOT use
|
|
165
|
-
- Do NOT
|
|
166
|
-
- Do NOT use
|
|
167
|
-
- Do NOT skip \`ngx-theme-stack:sync\` after changing \`provideThemeStack()\` config.
|
|
96
|
+
- Do NOT mix Toggle, Cycle, and Select in the same component.
|
|
97
|
+
- Do NOT use Tailwind's \`dark:\` utility modifier (use semantic classes mapped from themes).
|
|
98
|
+
- Do NOT skip \`ngx-theme-stack:sync\` schematic after updating providers.
|
|
99
|
+
- Do NOT use theme signals in templates without an \`@if (theme.isHydrated())\` guard.
|
|
168
100
|
`;
|
|
169
|
-
// ── references/api-reference.md (Tier 3 — loaded on demand)
|
|
101
|
+
// ── references/api-reference.md (Tier 3 — loaded on demand) ──────────────────
|
|
170
102
|
const API_REFERENCE = `# ngx-theme-stack API Reference
|
|
171
103
|
|
|
172
104
|
## provideThemeStack(config?)
|
|
173
105
|
|
|
174
|
-
|
|
106
|
+
Configures the Theme Stack in \`app.config.ts\`. Custom themes merge with built-ins (\`system\`, \`light\`, \`dark\`).
|
|
175
107
|
|
|
176
108
|
\`\`\`typescript
|
|
177
109
|
provideThemeStack({
|
|
178
110
|
themes: ['sunset', 'ocean'] as const,
|
|
179
111
|
defaultTheme: 'system',
|
|
180
112
|
storageKey: 'ngx-theme-stack',
|
|
181
|
-
mode: 'class',
|
|
182
|
-
strategy: 'critters',
|
|
113
|
+
mode: 'class', // 'class' | 'attribute' | 'both'
|
|
114
|
+
strategy: 'critters', // 'critters' | 'blocking'
|
|
183
115
|
})
|
|
184
116
|
\`\`\`
|
|
185
117
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
### Throws \`NgxThemeStackError\` when:
|
|
190
|
-
- A theme entry is empty or whitespace-only.
|
|
191
|
-
- \`defaultTheme\` is not in the resolved themes array.
|
|
192
|
-
- \`storageKey\` is empty or whitespace-only.
|
|
118
|
+
**Throws \`NgxThemeStackError\` when:**
|
|
119
|
+
- A theme entry is empty, or \`defaultTheme\` is not in themes, or \`storageKey\` is empty.
|
|
193
120
|
|
|
194
121
|
---
|
|
195
122
|
|
|
196
123
|
## CoreThemeService
|
|
197
124
|
|
|
198
|
-
Foundation service
|
|
199
|
-
system preference detection (matchMedia), and safe DOM manipulation (SSR compatible).
|
|
200
|
-
|
|
201
|
-
### Signals
|
|
202
|
-
|
|
203
|
-
| Signal | Type | Description |
|
|
204
|
-
| ------------------ | ------------------- | --------------------------------------------------- |
|
|
205
|
-
| \`selectedTheme()\` | \`Signal<string>\` | Theme chosen by the user. May be \`'system'\`. |
|
|
206
|
-
| \`resolvedTheme()\` | \`Signal<string>\` | Theme applied to DOM. Never \`'system'\`. |
|
|
207
|
-
| \`isDark()\` | \`Signal<boolean>\` | \`true\` when resolved is \`'dark'\`. \`false\` for custom. |
|
|
208
|
-
| \`isLight()\` | \`Signal<boolean>\` | \`true\` when resolved is \`'light'\`. \`false\` for custom.|
|
|
209
|
-
| \`isSystem()\` | \`Signal<boolean>\` | \`true\` when user selected \`'system'\`. |
|
|
210
|
-
| \`isHydrated()\` | \`Signal<boolean>\` | \`true\` after first browser render. Guard SSR content.|
|
|
125
|
+
Foundation service managing state (signals), persistence, system preference, and DOM manipulation (SSR safe).
|
|
211
126
|
|
|
212
|
-
### Methods
|
|
127
|
+
### Signals, Methods & Properties
|
|
213
128
|
|
|
214
|
-
|
|
|
215
|
-
|
|
|
216
|
-
| \`
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
|
221
|
-
|
|
|
222
|
-
| \`availableThemes\` | \`string[]\` | Resolved list including built-ins. |
|
|
129
|
+
| Name | Type | Description |
|
|
130
|
+
| --- | --- | --- |
|
|
131
|
+
| \`selectedTheme()\` | \`Signal<string>\` | Chosen theme (can be \`'system'\`). |
|
|
132
|
+
| \`resolvedTheme()\` | \`Signal<string>\` | Active theme applied to DOM (never \`'system'\`). |
|
|
133
|
+
| \`isDark()\` / \`isLight()\` | \`Signal<boolean>\` | \`true\` for dark/light (returns \`false\` for custom themes). |
|
|
134
|
+
| \`isSystem()\` / \`isHydrated()\` | \`Signal<boolean>\` | System choice active / SSR hydration finished. |
|
|
135
|
+
| \`availableThemes\` | \`string[]\` | All configured themes including built-ins. |
|
|
136
|
+
| \`setTheme(theme)\` | \`(theme: string) => void\` | Validates, persists, and applies the theme to DOM. |
|
|
223
137
|
|
|
224
138
|
---
|
|
225
139
|
|
|
226
|
-
##
|
|
227
|
-
|
|
228
|
-
Binary switch between \`'dark'\` and \`'light'\`.
|
|
229
|
-
|
|
230
|
-
### Signals
|
|
231
|
-
Inherits: \`selectedTheme()\`, \`resolvedTheme()\`, \`isDark()\`, \`isLight()\`, \`isSystem()\`, \`isHydrated()\`.
|
|
232
|
-
|
|
233
|
-
### Methods
|
|
234
|
-
|
|
235
|
-
| Method | Description |
|
|
236
|
-
| ---------- | ---------------------------------------------- |
|
|
237
|
-
| \`toggle()\` | If resolved is dark → light. Otherwise → dark. |
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## ThemeCycleService
|
|
242
|
-
|
|
243
|
-
Rotates through all configured themes in order.
|
|
140
|
+
## Convenience Services
|
|
244
141
|
|
|
245
|
-
|
|
246
|
-
Inherits all from CoreThemeService, plus:
|
|
142
|
+
Specialized services implementing different theme selection behaviors.
|
|
247
143
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
| \`upcoming()\` | \`Signal<string>\` | Next theme in the cycle. |
|
|
252
|
-
| \`preceding()\` | \`Signal<string>\` | Previous theme in the cycle. |
|
|
253
|
-
|
|
254
|
-
### Methods
|
|
255
|
-
|
|
256
|
-
| Method | Description |
|
|
257
|
-
| --------- | ---------------------------- |
|
|
258
|
-
| \`cycle()\` | Advances to the next theme. |
|
|
259
|
-
|
|
260
|
-
### Properties
|
|
261
|
-
|
|
262
|
-
| Property | Type | Description |
|
|
263
|
-
| ----------------- | ----------- | ---------------------------------- |
|
|
264
|
-
| \`availableThemes\` | \`string[]\` | Full list of themes in cycle order.|
|
|
265
|
-
|
|
266
|
-
---
|
|
267
|
-
|
|
268
|
-
## ThemeSelectService
|
|
269
|
-
|
|
270
|
-
Exposes the full theme list for dropdowns, radios, or tab selection.
|
|
271
|
-
|
|
272
|
-
### Signals
|
|
273
|
-
Inherits: \`selectedTheme()\`, \`resolvedTheme()\`, \`isDark()\`, \`isLight()\`, \`isSystem()\`, \`isHydrated()\`.
|
|
274
|
-
|
|
275
|
-
### Methods
|
|
276
|
-
|
|
277
|
-
| Method | Signature | Description |
|
|
278
|
-
| ----------------- | ---------------------- | --------------------------- |
|
|
279
|
-
| \`select()\` | \`(theme: string): void\`| Applies the given theme. |
|
|
144
|
+
### ThemeToggleService
|
|
145
|
+
Binary switch between \`'dark'\` and \`'light'\`.
|
|
146
|
+
- \`toggle()\`: Toggles the theme.
|
|
280
147
|
|
|
281
|
-
###
|
|
148
|
+
### ThemeCycleService
|
|
149
|
+
Rotates through all themes in configuration order.
|
|
150
|
+
- \`cycle()\`: Moves to the next theme.
|
|
151
|
+
- \`cycleIndex()\`: \`Signal<number>\` - Current theme index.
|
|
152
|
+
- \`upcoming()\` / \`preceding()\`: \`Signal<string>\` - Next / previous theme in cycle.
|
|
282
153
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
154
|
+
### ThemeSelectService
|
|
155
|
+
Full list control for select dropdowns, radio buttons, or lists.
|
|
156
|
+
- \`select(theme)\`: Sets the chosen theme.
|
|
286
157
|
|
|
287
158
|
---
|
|
288
159
|
|
|
289
|
-
## Types
|
|
290
|
-
|
|
291
|
-
| Type | Definition | Description |
|
|
292
|
-
| ------------- | ----------------------------------- | --------------------------------- |
|
|
293
|
-
| \`NgTheme<T>\` | \`'system' \\| 'light' \\| 'dark' \\| T\`| Theme identifier union |
|
|
294
|
-
| \`NgSystemTheme\`| \`'light' \\| 'dark'\` | Resolved system theme |
|
|
295
|
-
| \`NgMode\` | \`'class' \\| 'attribute' \\| 'both'\` | How theme is applied to DOM |
|
|
296
|
-
| \`NgStrategy\` | \`'critters' \\| 'blocking'\` | Anti-flash rendering strategy |
|
|
297
|
-
| \`NgConfig<T>\` | \`interface\` | Full library configuration |
|
|
298
|
-
|
|
299
|
-
## Errors
|
|
160
|
+
## Types & Errors
|
|
300
161
|
|
|
301
|
-
|
|
302
|
-
|
|
|
303
|
-
|
|
162
|
+
### Core Types
|
|
163
|
+
- \`NgTheme<T>\`: \`'system' | 'light' | 'dark' | T\`
|
|
164
|
+
- \`NgMode\`: \`'class' | 'attribute' | 'both'\`
|
|
165
|
+
- \`NgStrategy\`: \`'critters' | 'blocking'\`
|
|
304
166
|
|
|
167
|
+
### Errors
|
|
168
|
+
- \`NgxThemeStackError\`: Thrown for invalid configurations, storage keys, or theme names.
|
|
305
169
|
Catch with: \`if (e instanceof NgxThemeStackError) { ... }\`
|
|
306
170
|
`;
|
|
307
171
|
// ── assets/ component examples (Tier 3 — pure TypeScript, read on demand) ───
|
|
@@ -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":";;AAgQA,sCAUC;AAED,sBAMC;AA/QD,wDAAwD;AACxD,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8FrB,CAAC;AAEF,gFAAgF;AAEhF,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoErB,CAAC;AAEF,+EAA+E;AAE/E,MAAM,eAAe,GACrB;;;;;;;;;;;;;;;;;;CAkBC,CAAC;AAEF,MAAM,cAAc,GACpB;;;;;;;;;;;;;;;;CAgBC,CAAC;AAEF,MAAM,eAAe,GACrB;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BC,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,yBAAyB,EAAE,OAAO,EAAE,eAAe,EAAE;IAC1E,EAAE,IAAI,EAAE,GAAG,UAAU,wBAAwB,EAAE,OAAO,EAAE,cAAc,EAAE;IACxE,EAAE,IAAI,EAAE,GAAG,UAAU,yBAAyB,EAAE,OAAO,EAAE,eAAe,EAAE;CAC3E,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"}
|