srcdev-nuxt-components 9.1.55 → 9.1.57

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.
Files changed (104) hide show
  1. package/.claude/settings.json +30 -2
  2. package/.claude/skills/components/alert-content-inner.md +60 -0
  3. package/.claude/skills/components/display-dialog.md +80 -0
  4. package/.claude/skills/components/display-prompt.md +163 -0
  5. package/.claude/skills/components/display-toast.md +235 -0
  6. package/.claude/skills/index.md +7 -3
  7. package/.claude/skills/theming-colour-ramps.md +328 -0
  8. package/.claude/skills/theming-override-default.md +115 -186
  9. package/.claude/skills/theming-partial-override.md +88 -75
  10. package/README.md +166 -0
  11. package/app/app.config.ts +44 -0
  12. package/app/assets/styles/setup/01.config/_head.css +3 -3
  13. package/app/assets/styles/setup/02.colours/_amber.css +12 -10
  14. package/app/assets/styles/setup/02.colours/_blue.css +10 -9
  15. package/app/assets/styles/setup/02.colours/_green.css +12 -11
  16. package/app/assets/styles/setup/02.colours/_orange.css +12 -10
  17. package/app/assets/styles/setup/02.colours/_red.css +10 -9
  18. package/app/assets/styles/setup/02.colours/_slate.css +12 -11
  19. package/app/assets/styles/setup/02.colours/_sunset.css +12 -10
  20. package/app/assets/styles/setup/02.colours/_theme-params.css +18 -0
  21. package/app/assets/styles/setup/02.colours/index.css +1 -0
  22. package/app/assets/styles/setup/03.theming/_default.css +87 -0
  23. package/app/assets/styles/setup/03.theming/_error.css +14 -0
  24. package/app/assets/styles/setup/03.theming/_success.css +4 -0
  25. package/app/assets/styles/setup/03.theming/_theme-slots.css +16 -0
  26. package/app/assets/styles/setup/03.theming/_warning.css +13 -0
  27. package/app/assets/styles/setup/03.theming/index.css +6 -4
  28. package/app/assets/styles/setup/03.theming/theme-ramp.css +19 -0
  29. package/app/assets/styles/setup/04.elements/forms/00.element-defaults.css +0 -7
  30. package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
  31. package/app/assets/styles/setup/index.css +1 -1
  32. package/app/components/01.atoms/display-dialog/DisplayDialog.vue +74 -24
  33. package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +148 -14
  34. package/app/components/01.atoms/display-dialog/tests/__snapshots__/DisplayDialog.spec.ts.snap +3 -3
  35. package/app/components/01.atoms/prompt/DisplayPrompt.vue +113 -0
  36. package/app/components/01.atoms/prompt/stories/DisplayPrompt.stories.ts +112 -0
  37. package/app/components/01.atoms/prompt/tests/DisplayPrompt.spec.ts +205 -0
  38. package/app/components/01.atoms/toast/DisplayToast.vue +327 -0
  39. package/app/components/01.atoms/toast/DisplayToastProvider.vue +362 -0
  40. package/app/components/01.atoms/toast/stories/DisplayToast.stories.ts +195 -0
  41. package/app/components/01.atoms/toast/stories/DisplayToastProvider.stories.ts +142 -0
  42. package/app/components/01.atoms/toast/tests/DisplayToast.spec.ts +266 -0
  43. package/app/components/01.atoms/toast/tests/DisplayToastProvider.spec.ts +256 -0
  44. package/app/components/02.molecules/action-menu/ActionMenu.vue +8 -1
  45. package/app/components/02.molecules/action-menu/ActionMenuItemCore.vue +11 -3
  46. package/app/components/02.molecules/alert-content/AlertContent.vue +67 -0
  47. package/app/components/02.molecules/alert-content/AlertContentInner.vue +153 -0
  48. package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +131 -0
  49. package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +135 -0
  50. package/app/components/02.molecules/alert-content/tests/AlertContentInner.spec.ts +135 -0
  51. package/app/components/02.molecules/alert-masked-content/AlertMaskedContent.vue +78 -0
  52. package/app/components/02.molecules/alert-masked-content/stories/AlertMaskedContent.stories.ts +132 -0
  53. package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +149 -0
  54. package/app/components/05.forms/input-button/InputButtonCore.vue +35 -39
  55. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioButton.vue +8 -8
  56. package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioCore.vue +5 -5
  57. package/app/components/05.forms/input-copy/InputCopyCore.vue +7 -7
  58. package/app/components/05.forms/input-number/InputNumberCore.vue +5 -5
  59. package/app/components/05.forms/input-select/InputSelectCore.vue +6 -6
  60. package/app/components/05.forms/input-text/InputTextCore.vue +6 -6
  61. package/app/components/05.forms/input-text/variants/InputTextAsNumberWithLabel.vue +2 -2
  62. package/app/components/05.forms/input-textarea/InputTextareaCore.vue +5 -5
  63. package/app/components/05.forms/pending-effect/PendingEffect.vue +60 -60
  64. package/app/components/05.forms/toggle-switch/ToggleSwitchCore.vue +10 -10
  65. package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +4 -4
  66. package/app/components/display-theme-switch/DisplayThemeSwitch.vue +4 -4
  67. package/app/components/display-tooltip/DisplayTooltip.vue +4 -4
  68. package/app/composables/useBodyLock.ts +21 -0
  69. package/app/composables/useDialogControls.ts +11 -11
  70. package/app/composables/useToastQueue.ts +39 -0
  71. package/app/layouts/default.vue +1 -1
  72. package/app/pages/ui/display-dialog.vue +275 -127
  73. package/app/pages/ui/display-prompt.vue +255 -52
  74. package/app/pages/ui/display-toast.vue +278 -299
  75. package/app/pages/ui/mask-element.vue +25 -3
  76. package/app/pages/ui/settings.vue +9 -35
  77. package/app/types/app-config.d.ts +41 -0
  78. package/app/types/components/display-prompt.d.ts +11 -0
  79. package/app/types/components/display-toast.d.ts +11 -9
  80. package/app/types/components/index.ts +2 -0
  81. package/app/types/components/semantic-theme.d.ts +1 -0
  82. package/nuxt.config.ts +16 -0
  83. package/package.json +8 -4
  84. package/ramps.config.mjs +28 -0
  85. package/scripts/check-ramps.mjs +50 -0
  86. package/scripts/generate-consumer-ramps.mjs +100 -0
  87. package/scripts/generate-ramps.mjs +92 -0
  88. package/app/assets/styles/setup/03.theming/default/_dark.css +0 -156
  89. package/app/assets/styles/setup/03.theming/default/_light.css +0 -166
  90. package/app/assets/styles/setup/03.theming/default/index.css +0 -2
  91. package/app/assets/styles/setup/03.theming/error/_dark.css +0 -56
  92. package/app/assets/styles/setup/03.theming/error/_light.css +0 -74
  93. package/app/assets/styles/setup/03.theming/error/index.css +0 -2
  94. package/app/assets/styles/setup/03.theming/success/_dark.css +0 -50
  95. package/app/assets/styles/setup/03.theming/success/_light.css +0 -65
  96. package/app/assets/styles/setup/03.theming/success/index.css +0 -2
  97. package/app/assets/styles/setup/03.theming/warning/_dark.css +0 -50
  98. package/app/assets/styles/setup/03.theming/warning/_light.css +0 -64
  99. package/app/assets/styles/setup/03.theming/warning/index.css +0 -2
  100. package/app/components/display-prompt/DisplayPromptCore.vue +0 -228
  101. package/app/components/display-prompt/variants/DisplayPromptError.vue +0 -53
  102. package/app/components/display-toast/DisplayToast.vue +0 -447
  103. package/app/components/display-toast/molecules/DefaultToastContent.vue +0 -163
  104. package/app/components/display-toast/stories/DisplayToast.stories.ts +0 -380
@@ -0,0 +1,328 @@
1
+ # Colour Ramp System
2
+
3
+ ## Overview
4
+
5
+ The layer uses a parametric oklch colour ramp system. A single formula computes an 11-step colour
6
+ scale (`--colour-theme-0` to `--colour-theme-10`) from two CSS custom properties: `--theme-hue`
7
+ and `--theme-chroma`. Changing those two variables on any element switches the entire colour theme
8
+ for that element's subtree — buttons, inputs, prompts, and toasts all respond automatically.
9
+
10
+ Named palettes are pre-defined in `ramps.config.mjs` and generated to CSS. Themes swap palettes by
11
+ reassigning `--theme-hue` and `--theme-chroma`.
12
+
13
+ ## How the formula works
14
+
15
+ `theme-ramp.css` (generated) declares the formula on every potential theme host:
16
+
17
+ ```css
18
+ :where(html, [data-theme], [data-invalid]) {
19
+ --colour-theme-0: oklch(98% calc(var(--theme-chroma) * 0.045) var(--theme-hue));
20
+ --colour-theme-1: oklch(94% calc(var(--theme-chroma) * 0.18) var(--theme-hue));
21
+ --colour-theme-2: oklch(88% calc(var(--theme-chroma) * 0.32) var(--theme-hue));
22
+ --colour-theme-3: oklch(80% calc(var(--theme-chroma) * 0.50) var(--theme-hue));
23
+ --colour-theme-4: oklch(72% calc(var(--theme-chroma) * 0.68) var(--theme-hue));
24
+ --colour-theme-5: oklch(64% calc(var(--theme-chroma) * 0.86) var(--theme-hue));
25
+ --colour-theme-6: oklch(56% calc(var(--theme-chroma) * 1.00) var(--theme-hue));
26
+ --colour-theme-7: oklch(48% calc(var(--theme-chroma) * 0.95) var(--theme-hue));
27
+ --colour-theme-8: oklch(40% calc(var(--theme-chroma) * 0.86) var(--theme-hue));
28
+ --colour-theme-9: oklch(32% calc(var(--theme-chroma) * 0.77) var(--theme-hue));
29
+ --colour-theme-10: oklch(25% calc(var(--theme-chroma) * 0.64) var(--theme-hue));
30
+ }
31
+ ```
32
+
33
+ Scale direction: **00 = lightest, 10 = darkest**. Chroma tapers at both extremes and peaks at
34
+ step 06.
35
+
36
+ The formula is declared on every potential theme host (not just `html`) so that `[data-theme]`
37
+ elements get direct declarations — not inherited ones. This is critical: inherited `--colour-theme-*`
38
+ values would not re-evaluate when `--theme-hue` changes on a child element.
39
+
40
+ ### Hue drift
41
+
42
+ Ramps can declare `drift` to rotate the hue angle linearly across steps. The `sunset` palette uses
43
+ `drift: -25`, producing:
44
+
45
+ ```css
46
+ var(--theme-hue) + var(--theme-hue-drift, 0) * (i / 10)
47
+ /* step 00: 50 + (-25 × 0.0) = 50° (amber) */
48
+ /* step 05: 50 + (-25 × 0.5) = 37° (orange) */
49
+ /* step 10: 50 + (-25 × 1.0) = 25° (red-orange) */
50
+ ```
51
+
52
+ ## Named palettes
53
+
54
+ Defined in `ramps.config.mjs`, generated to `_theme-params.css` as `--palette-{name}-hue`,
55
+ `--palette-{name}-chroma`, and (if drift is set) `--palette-{name}-drift`:
56
+
57
+ | Name | Hue | Max chroma | Notes |
58
+ |--------|-----|------------|-------------------------------|
59
+ | blue | 255 | 0.22 | Layer default |
60
+ | red | 30 | 0.24 | Error/danger theme |
61
+ | green | 157 | 0.19 | Success theme |
62
+ | amber | 75 | 0.19 | |
63
+ | orange | 60 | 0.15 | |
64
+ | sunset | 50 | 0.22 | Warning theme — drift: -25 |
65
+ | slate | 260 | 0.02 | Near-neutral grey |
66
+
67
+ Also generates one named-step file per palette, e.g. `_blue.css` with `--blue-00` … `--blue-10`.
68
+ These are used by components that need a specific step by name (e.g. error state colours in
69
+ `_error.css` reference `--red-06`).
70
+
71
+ ## Semantic slots
72
+
73
+ Nine shared colour roles are declared in `_theme-slots.css` on the same selector as the ramp.
74
+ All themed components (buttons, inputs, prompts, toasts) read only these tokens:
75
+
76
+ | Token | Light (step) | Dark (step) | Role |
77
+ |-------------------------|--------------|-------------|-----------------------------------|
78
+ | `--theme-surface` | 7 | 9 | Filled button/chip surface |
79
+ | `--theme-surface-hover` | 9 | 7 | Hover state of filled surface |
80
+ | `--theme-accent` | 5 | 4 | Decorative accent strip (prompt/toast left edge) |
81
+ | `--theme-surface-subtle`| 1 | 9 | Subtle body bg for prompt/toast, outline element hover |
82
+ | `--theme-border` | 6 | 5 | Input/card border |
83
+ | `--theme-border-focus` | 4 | 3 | Focused border |
84
+ | `--theme-ring` | 1 | 9 | Focus ring (outline) |
85
+ | `--theme-on-surface` | 0 | 0 | Text/icon on filled surface |
86
+ | `--theme-text` | 9 | 2 | Text on page, outline element text|
87
+
88
+ Additional context tokens (declared in `_default.css`):
89
+
90
+ | Token | Role |
91
+ |--------------------------------|----------------------------------|
92
+ | `--theme-input-surface` | Input field background |
93
+ | `--theme-input-surface-hover` | Input field hover background |
94
+ | `--theme-input-text-color-normal` | Input text colour |
95
+ | `--theme-input-placeholder` | Placeholder text colour |
96
+ | `--theme-checkbox-symbol-surface` | Checkbox/radio symbol surface |
97
+ | `--page-bg` | Page background |
98
+ | `--colour-text-default` | Body text |
99
+ | `--colour-text-accent` | Accent / heading text |
100
+ | `--colour-text-eyebrow` | Eyebrow text |
101
+
102
+ ## Built-in component themes
103
+
104
+ | `data-theme` value | Palette | Notes |
105
+ |--------------------|---------|----------------------------------------------|
106
+ | `"default"` | blue | Page-level default |
107
+ | `"success"` | green | |
108
+ | `"warning"` | sunset | Overrides surface to step 5 for warm feel |
109
+ | `"error"` | red | Also applied on `[data-invalid]` elements |
110
+
111
+ ## Generator
112
+
113
+ ### Key files
114
+
115
+ | File | Description |
116
+ |-------------------------------------------------------------|------------------------------------------------|
117
+ | `ramps.config.mjs` | Source of truth — hue/chroma/drift per palette |
118
+ | `scripts/generate-ramps.mjs` | Generator — reads config, emits CSS |
119
+ | `scripts/check-ramps.mjs` | CI check — errors if CSS is out of date |
120
+ | `app/assets/styles/setup/02.colours/_<name>.css` | Named steps `--name-00` … `--name-10` |
121
+ | `app/assets/styles/setup/02.colours/_theme-params.css` | `--palette-*` vars |
122
+ | `app/assets/styles/setup/03.theming/theme-ramp.css` | Formula (the `--colour-theme-*` declarations) |
123
+
124
+ ### Scripts
125
+
126
+ ```bash
127
+ npm run generate:ramps # rebuild all generated CSS from ramps.config.mjs
128
+ npm run check:ramps # CI: fail if generated CSS is out of date
129
+ ```
130
+
131
+ ### Adding a new named palette
132
+
133
+ 1. Open `ramps.config.mjs` and add an entry:
134
+
135
+ ```js
136
+ export const ramps = {
137
+ // existing entries...
138
+ gold: { hue: 85, chroma: 0.20 },
139
+ // with hue drift across steps:
140
+ // copper: { hue: 45, chroma: 0.21, drift: -15 },
141
+ };
142
+ ```
143
+
144
+ 1. Regenerate:
145
+
146
+ ```bash
147
+ npm run generate:ramps
148
+ ```
149
+
150
+ Produces `_gold.css` with `--gold-00` … `--gold-10`, and adds `--palette-gold-hue` /
151
+ `--palette-gold-chroma` to `_theme-params.css`.
152
+
153
+ 1. Reference from a theme selector:
154
+
155
+ ```css
156
+ [data-theme="gold"] {
157
+ --theme-hue: var(--palette-gold-hue);
158
+ --theme-chroma: var(--palette-gold-chroma);
159
+ }
160
+ ```
161
+
162
+ ## Consumer app: generating a custom palette
163
+
164
+ The recommended approach is to generate named colour files so you can reference clean step
165
+ variables (`--gold-09`, `--gold-04`) in your theme overrides rather than raw oklch values.
166
+
167
+ ### 1. Create `ramps.config.mjs` in your project root
168
+
169
+ Define the palettes you want. You can add new ones, reuse a built-in name to override the
170
+ layer's values, or both. Consumer CSS loads after the layer, so generated files win the
171
+ cascade automatically:
172
+
173
+ ```js
174
+ // ramps.config.mjs
175
+ export const ramps = {
176
+ // New palette — adds --gold-00..10 and --palette-gold-* vars
177
+ gold: { hue: 85, chroma: 0.20 },
178
+
179
+ // Override a built-in — replaces the layer's --blue-00..10 with your values
180
+ // blue: { hue: 240, chroma: 0.18 },
181
+
182
+ // Override the error/invalid palette — all error states use your red
183
+ // red: { hue: 15, chroma: 0.26 },
184
+
185
+ // Optional — hue drift rotates colour linearly across the 11 steps:
186
+ // copper: { hue: 45, chroma: 0.21, drift: -15 },
187
+ };
188
+ ```
189
+
190
+ ### 2. Add the generator to `package.json`
191
+
192
+ The script lives in the layer's `node_modules` — no copying required. Prepend it to `dev`,
193
+ `build`, and `generate` so generated CSS never drifts out of sync with `ramps.config.mjs`:
194
+
195
+ ```json
196
+ "scripts": {
197
+ "generate:ramps": "node node_modules/srcdev-nuxt-components/scripts/generate-consumer-ramps.mjs",
198
+ "dev": "npm run generate:ramps && nuxt dev",
199
+ "build": "npm run generate:ramps && nuxt build",
200
+ "generate": "npm run generate:ramps && nuxt generate"
201
+ }
202
+ ```
203
+
204
+ Also add it to `postinstall` so it runs automatically after every `npm install`:
205
+
206
+ ```json
207
+ "postinstall": "nuxt prepare && npm run generate:ramps && npm run setup:claude"
208
+ ```
209
+
210
+ > **Do not manually edit generated files.** They carry a `/* GENERATED */` comment at the top
211
+ > and are overwritten every time the generator runs. All changes belong in `ramps.config.mjs`.
212
+
213
+ ### 3. Run the generator
214
+
215
+ ```bash
216
+ npm run generate:ramps
217
+ ```
218
+
219
+ Produces in `app/assets/styles/setup/02.colours/`:
220
+
221
+ - `_gold.css` — `--gold-00` … `--gold-10` (literal oklch values, same lightness/chroma curve as the layer)
222
+ - `_palette-params.css` — `--palette-gold-hue`, `--palette-gold-chroma`
223
+
224
+ ### 4. Import the generated files
225
+
226
+ In `app/assets/styles/setup/02.colours/index.css` (create if it doesn't exist):
227
+
228
+ ```css
229
+ @import "./_palette-params";
230
+ @import "./_gold";
231
+ ```
232
+
233
+ ### 5. Set the palette as the theme default
234
+
235
+ ```css
236
+ /* app/assets/styles/setup/03.theming/_default.css */
237
+ :where(html) {
238
+ --theme-hue: var(--palette-gold-hue);
239
+ --theme-chroma: var(--palette-gold-chroma);
240
+
241
+ /* Page-level tokens — readable named steps, not raw oklch */
242
+ --colour-text-accent: light-dark(var(--gold-09), var(--gold-04));
243
+ --colour-text-eyebrow: light-dark(var(--gold-09), var(--gold-04));
244
+ }
245
+
246
+ /* Optional: make it available as a data-theme variant too */
247
+ [data-theme="gold"] {
248
+ --theme-hue: var(--palette-gold-hue);
249
+ --theme-chroma: var(--palette-gold-chroma);
250
+ }
251
+ ```
252
+
253
+ ### 6. Wire up in your setup index
254
+
255
+ ```css
256
+ /* app/assets/styles/setup/index.css */
257
+ @import "./02.colours/";
258
+ @import "./03.theming/_default.css";
259
+ ```
260
+
261
+ ```css
262
+ /* app/assets/styles/main.css */
263
+ @import "./setup/";
264
+ ```
265
+
266
+ ### Quick palette-only override (no generator)
267
+
268
+ If you only need to shift the hue without named step references, you can skip the generator and
269
+ set the params directly. All components recalculate automatically:
270
+
271
+ ```css
272
+ :where(html) {
273
+ --theme-hue: 85;
274
+ --theme-chroma: 0.20;
275
+ }
276
+ ```
277
+
278
+ This works for components but gives you no named steps for page-level tokens — use the generator
279
+ approach whenever you need `--gold-09` style references in your CSS.
280
+
281
+ ## Light / dark mode
282
+
283
+ Semantic slots use `light-dark()`, which responds to `color-scheme` on `html` (set by the layer's
284
+ `_head.css`):
285
+
286
+ ```css
287
+ html {
288
+ color-scheme: light dark; /* OS preference */
289
+ &.light { color-scheme: light; }
290
+ &.dark { color-scheme: dark; }
291
+ }
292
+ ```
293
+
294
+ Use `light-dark()` in your own override values too:
295
+
296
+ ```css
297
+ :where(html) {
298
+ --theme-hue: 85;
299
+ --theme-chroma: 0.20;
300
+ --page-bg: light-dark(var(--slate-00), var(--slate-08));
301
+ }
302
+ ```
303
+
304
+ **Multi-value caveat**: `light-dark()` cannot contain comma-separated values (e.g. box-shadow
305
+ lists). Use intermediate scalar vars:
306
+
307
+ ```css
308
+ --_shadow-a: light-dark(0.08, 0.5);
309
+ --my-shadow: 0 8px 32px rgba(0, 0, 0, var(--_shadow-a));
310
+ ```
311
+
312
+ The `useColourScheme()` composable toggles the `.light` / `.dark` class on `<html>`. See
313
+ `composable-colour-scheme.md` for the full API.
314
+
315
+ ## Hue angle reference
316
+
317
+ | Range | Colour |
318
+ |--------|------------------|
319
+ | 0–30 | Red / pink |
320
+ | 30–70 | Orange / amber |
321
+ | 70–100 | Yellow / gold |
322
+ | 100–160| Green |
323
+ | 160–220| Cyan / teal |
324
+ | 220–270| Blue |
325
+ | 270–310| Violet / purple |
326
+ | 310–360| Magenta / rose |
327
+
328
+ Use [oklch.com](https://oklch.com) to preview values before committing.