@pure-ds/core 0.5.60 → 0.6.1

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 (43) hide show
  1. package/dist/types/packages/pds-configurator/src/pds-home-content.d.ts +375 -0
  2. package/dist/types/packages/pds-configurator/src/pds-home-content.d.ts.map +1 -0
  3. package/dist/types/packages/pds-configurator/src/pds-home.d.ts +2 -0
  4. package/dist/types/packages/pds-configurator/src/pds-home.d.ts.map +1 -0
  5. package/dist/types/pds.config.d.ts +4 -8
  6. package/dist/types/pds.config.d.ts.map +1 -1
  7. package/dist/types/pds.d.ts +3 -1
  8. package/dist/types/public/assets/js/pds-manager.d.ts.map +1 -1
  9. package/dist/types/public/assets/js/pds.d.ts.map +1 -1
  10. package/dist/types/public/assets/pds/components/pds-live-edit.d.ts +150 -0
  11. package/dist/types/public/assets/pds/components/pds-live-edit.d.ts.map +1 -0
  12. package/dist/types/public/assets/pds/components/pds-omnibox.d.ts +2 -0
  13. package/dist/types/public/assets/pds/components/pds-omnibox.d.ts.map +1 -1
  14. package/dist/types/public/assets/pds/components/pds-richtext.d.ts.map +1 -1
  15. package/dist/types/public/assets/pds/components/pds-theme.d.ts +5 -0
  16. package/dist/types/public/assets/pds/components/pds-theme.d.ts.map +1 -1
  17. package/dist/types/src/js/pds-core/pds-config.d.ts +457 -0
  18. package/dist/types/src/js/pds-core/pds-config.d.ts.map +1 -1
  19. package/dist/types/src/js/pds-core/pds-enhancers.d.ts.map +1 -1
  20. package/dist/types/src/js/pds-core/pds-live.d.ts.map +1 -1
  21. package/dist/types/src/js/pds-core/pds-ontology.d.ts.map +1 -1
  22. package/dist/types/src/js/pds-core/pds-start-helpers.d.ts.map +1 -1
  23. package/dist/types/src/js/pds-core/pds-theme-utils.d.ts +6 -0
  24. package/dist/types/src/js/pds-core/pds-theme-utils.d.ts.map +1 -0
  25. package/dist/types/src/js/pds.d.ts.map +1 -1
  26. package/package.json +1 -4
  27. package/packages/pds-cli/bin/templates/bootstrap/pds.config.js +9 -2
  28. package/public/assets/js/app.js +106 -5636
  29. package/public/assets/js/pds-manager.js +156 -156
  30. package/public/assets/js/pds.js +7 -7
  31. package/public/assets/pds/components/pds-live-edit.js +1555 -0
  32. package/public/assets/pds/components/pds-omnibox.js +558 -369
  33. package/public/assets/pds/components/pds-richtext.js +57 -7
  34. package/public/assets/pds/components/pds-theme.js +58 -0
  35. package/readme.md +2 -2
  36. package/src/js/pds-core/pds-config.js +705 -1
  37. package/src/js/pds-core/pds-enhancers.js +61 -4
  38. package/src/js/pds-core/pds-live.js +545 -437
  39. package/src/js/pds-core/pds-ontology.js +8 -0
  40. package/src/js/pds-core/pds-start-helpers.js +15 -0
  41. package/src/js/pds-core/pds-theme-utils.js +33 -0
  42. package/src/js/pds.d.ts +3 -1
  43. package/src/js/pds.js +22 -0
@@ -1,5 +1,707 @@
1
1
  import { enums } from "./pds-enums.js";
2
2
 
3
+ /**
4
+ * Design config types (SSoT) - mirror generator input and document output impact.
5
+ * These types are used for validation and live-edit mapping.
6
+ */
7
+
8
+ /**
9
+ * @typedef {Object} PDSDarkModeColorsConfig
10
+ * @property {string} [background] - Affects dark surface palette and smart surface tokens.
11
+ * @property {string} [primary] - Affects --color-dark-primary-* and interactive dark fills.
12
+ * @property {string} [secondary] - Affects --color-dark-gray-* and dark borders/text.
13
+ * @property {string} [accent] - Affects --color-dark-accent-* and accent interactions.
14
+ */
15
+
16
+ /**
17
+ * @typedef {Object} PDSColorsConfig
18
+ * @property {string} [primary] - Drives primary scale: --color-primary-50..900 and interactive tokens.
19
+ * @property {string} [secondary] - Drives neutral scale: --color-gray-50..900.
20
+ * @property {string} [accent] - Drives accent scale: --color-accent-50..900.
21
+ * @property {string} [background] - Drives surface shades: --color-surface-* and smart surfaces.
22
+ * @property {string | null} [success] - Drives semantic success scale: --color-success-*.
23
+ * @property {string | null} [warning] - Drives semantic warning scale: --color-warning-*.
24
+ * @property {string | null} [danger] - Drives semantic danger scale: --color-danger-*.
25
+ * @property {string | null} [info] - Drives semantic info scale: --color-info-*.
26
+ * @property {number} [gradientStops] - Affects generated gradient scales.
27
+ * @property {number} [elevationOpacity] - Affects smart surface shadows (opacity).
28
+ * @property {PDSDarkModeColorsConfig} [darkMode] - Overrides dark mode palette generation.
29
+ */
30
+
31
+ /**
32
+ * @typedef {Object} PDSTypographyConfig
33
+ * @property {string} [fontFamilyHeadings] - Affects --font-family-headings and heading styles.
34
+ * @property {string} [fontFamilyBody] - Affects --font-family-body and body text.
35
+ * @property {string} [fontFamilyMono] - Affects --font-family-mono and code styling.
36
+ * @property {number} [baseFontSize] - Sets base scale for --font-size-*.
37
+ * @property {number} [fontScale] - Controls modular scale for --font-size-*.
38
+ * @property {string | number} [fontWeightLight] - Affects --font-weight-light.
39
+ * @property {string | number} [fontWeightNormal] - Affects --font-weight-normal.
40
+ * @property {string | number} [fontWeightMedium] - Affects --font-weight-medium.
41
+ * @property {string | number} [fontWeightSemibold] - Affects --font-weight-semibold.
42
+ * @property {string | number} [fontWeightBold] - Affects --font-weight-bold.
43
+ * @property {string | number} [lineHeightTight] - Affects --line-height-tight.
44
+ * @property {string | number} [lineHeightNormal] - Affects --line-height-normal.
45
+ * @property {string | number} [lineHeightRelaxed] - Affects --line-height-relaxed.
46
+ * @property {number} [letterSpacingTight] - Affects --letter-spacing-tight.
47
+ * @property {number} [letterSpacingNormal] - Affects --letter-spacing-normal.
48
+ * @property {number} [letterSpacingWide] - Affects --letter-spacing-wide.
49
+ */
50
+
51
+ /**
52
+ * @typedef {Object} PDSSpatialRhythmConfig
53
+ * @property {number} [baseUnit] - Generates spacing scale --spacing-1..N.
54
+ * @property {number} [scaleRatio] - Reserved for derived spacing systems.
55
+ * @property {number} [maxSpacingSteps] - Caps spacing tokens output.
56
+ * @property {number | string} [containerMaxWidth] - Affects layout container sizing.
57
+ * @property {number} [containerPadding] - Affects container padding tokens.
58
+ * @property {number} [inputPadding] - Affects input padding tokens.
59
+ * @property {number} [buttonPadding] - Affects button padding tokens.
60
+ * @property {number} [sectionSpacing] - Affects section spacing tokens.
61
+ */
62
+
63
+ /**
64
+ * @typedef {Object} PDSShapeConfig
65
+ * @property {string | number} [radiusSize] - Drives --radius-* scale.
66
+ * @property {string | number | null} [customRadius] - Overrides radius scale base.
67
+ * @property {string | number} [borderWidth] - Drives --border-width-* scale.
68
+ */
69
+
70
+ /**
71
+ * @typedef {Object} PDSBehaviorConfig
72
+ * @property {string | number} [transitionSpeed] - Drives --transition-* durations.
73
+ * @property {string} [animationEasing] - Drives --ease-* tokens.
74
+ * @property {number | null} [customTransitionSpeed] - Overrides transition durations.
75
+ * @property {string | null} [customEasing] - Overrides easing curve.
76
+ * @property {number} [focusRingWidth] - Affects focus ring thickness.
77
+ * @property {number} [focusRingOpacity] - Affects focus ring opacity.
78
+ * @property {number} [hoverOpacity] - Affects hover overlay opacity.
79
+ */
80
+
81
+ /**
82
+ * @typedef {Object} PDSLayoutConfig
83
+ * @property {number | string} [maxWidth] - Drives layout max width tokens.
84
+ * @property {{ sm?: number | string, md?: number | string, lg?: number | string, xl?: number | string }} [maxWidths] - Per-breakpoint max widths.
85
+ * @property {number | string} [containerPadding] - Drives layout container padding token.
86
+ * @property {{ sm?: number, md?: number, lg?: number, xl?: number }} [breakpoints] - Drives breakpoint tokens.
87
+ * @property {number} [gridColumns] - Affects grid utilities.
88
+ * @property {number} [gridGutter] - Affects grid gap utilities.
89
+ * @property {number} [densityCompact] - Affects density tokens/utilities.
90
+ * @property {number} [densityNormal] - Affects density tokens/utilities.
91
+ * @property {number} [densityComfortable] - Affects density tokens/utilities.
92
+ * @property {number} [buttonMinHeight] - Affects min-height tokens for buttons.
93
+ * @property {number} [inputMinHeight] - Affects min-height tokens for inputs.
94
+ * @property {number} [baseShadowOpacity] - Affects layout shadow opacity.
95
+ * @property {{ baseShadowOpacity?: number }} [darkMode] - Dark mode shadow opacity overrides.
96
+ * @property {Record<string, any>} [utilities] - Toggles layout utilities generation.
97
+ * @property {Record<string, any>} [gridSystem] - Grid system configuration.
98
+ * @property {number | string} [containerMaxWidth] - Affects container sizing token.
99
+ */
100
+
101
+ /**
102
+ * @typedef {Object} PDSLayersConfig
103
+ * @property {number} [baseShadowOpacity] - Drives --shadow-* opacity.
104
+ * @property {number} [shadowBlurMultiplier] - Scales shadow blur.
105
+ * @property {number} [shadowOffsetMultiplier] - Scales shadow offsets.
106
+ * @property {string} [shadowDepth] - Base depth style selection.
107
+ * @property {number} [blurLight] - Affects blur tokens.
108
+ * @property {number} [blurMedium] - Affects blur tokens.
109
+ * @property {number} [blurHeavy] - Affects blur tokens.
110
+ * @property {number} [baseZIndex] - Drives z-index token base.
111
+ * @property {number} [zIndexStep] - Drives z-index step scale.
112
+ * @property {number} [zIndexBase]
113
+ * @property {number} [zIndexDropdown]
114
+ * @property {number} [zIndexSticky]
115
+ * @property {number} [zIndexFixed]
116
+ * @property {number} [zIndexModal]
117
+ * @property {number} [zIndexPopover]
118
+ * @property {number} [zIndexTooltip]
119
+ * @property {number} [zIndexNotification]
120
+ * @property {{ baseShadowOpacity?: number }} [darkMode] - Dark mode shadow opacity overrides.
121
+ */
122
+
123
+ /**
124
+ * @typedef {Object} PDSIconsConfig
125
+ * @property {string} [set] - Icon set name, affects icon resolution.
126
+ * @property {string} [weight] - Default icon weight.
127
+ * @property {number} [defaultSize] - Default icon size token.
128
+ * @property {Record<string, number | string>} [sizes] - Icon size scale tokens.
129
+ * @property {string} [spritePath] - Sprite URL used by icon component.
130
+ * @property {string} [externalPath] - External icon path for on-demand icons.
131
+ * @property {Record<string, string[]>} [include] - Icon allowlist for build.
132
+ */
133
+
134
+ /**
135
+ * @typedef {Object} PDSEnhancer
136
+ * @property {string} selector
137
+ * @property {string} [description]
138
+ * @property {(element: Element) => void} run
139
+ */
140
+
141
+ /**
142
+ * @typedef {Object} PDSAutoDefineConfig
143
+ * @property {string[]} [predefine]
144
+ * @property {(tag: string) => (string | undefined | null)} [mapper]
145
+ * @property {PDSEnhancer[]} [enhancers]
146
+ * @property {boolean} [scanExisting]
147
+ * @property {boolean} [observeShadows]
148
+ * @property {boolean} [patchAttachShadow]
149
+ * @property {number} [debounceMs]
150
+ * @property {(error: any) => void} [onError]
151
+ */
152
+
153
+ /**
154
+ * @typedef {Object} PDSDesignConfig
155
+ * @property {string} [id]
156
+ * @property {string} [name]
157
+ * @property {string[]} [tags]
158
+ * @property {string} [description]
159
+ * @property {Record<string, any>} [options]
160
+ * @property {Record<string, any>} [form]
161
+ * @property {PDSColorsConfig} [colors] - Affects tokens.colors and --color-* variables.
162
+ * @property {PDSTypographyConfig} [typography] - Affects tokens.typography and --font-* variables.
163
+ * @property {PDSSpatialRhythmConfig} [spatialRhythm] - Affects tokens.spacing and --spacing-* variables.
164
+ * @property {PDSShapeConfig} [shape] - Affects tokens.radius/borderWidths and --radius-* variables.
165
+ * @property {PDSBehaviorConfig} [behavior] - Affects tokens.transitions and motion variables.
166
+ * @property {PDSLayoutConfig} [layout] - Affects tokens.layout and layout utilities.
167
+ * @property {PDSLayersConfig} [layers] - Affects tokens.shadows/zIndex and layer effects.
168
+ * @property {Record<string, any>} [advanced]
169
+ * @property {Record<string, any>} [a11y]
170
+ * @property {PDSIconsConfig} [icons] - Affects tokens.icons and icon component behavior.
171
+ * @property {Record<string, any>} [components]
172
+ * @property {number} [gap]
173
+ * @property {boolean} [debug]
174
+ */
175
+
176
+ /**
177
+ * @typedef {Object} PDSInitConfig
178
+ * @property {string} [mode]
179
+ * @property {string} [preset]
180
+ * @property {PDSDesignConfig} [design]
181
+ * @property {PDSEnhancer[] | Record<string, PDSEnhancer>} [enhancers]
182
+ * @property {boolean} [applyGlobalStyles]
183
+ * @property {boolean} [manageTheme]
184
+ * @property {string} [themeStorageKey]
185
+ * @property {boolean} [preloadStyles]
186
+ * @property {string[]} [criticalLayers]
187
+ * @property {PDSAutoDefineConfig} [autoDefine]
188
+ * @property {string} [managerURL]
189
+ * @property {any} [manager]
190
+ * @property {boolean} [liveEdit]
191
+ * @property {any} [log]
192
+ */
193
+
194
+ const __ANY_TYPE__ = "any";
195
+
196
+ const __DESIGN_CONFIG_SPEC__ = {
197
+ type: "object",
198
+ allowUnknown: false,
199
+ properties: {
200
+ id: { type: "string" },
201
+ name: { type: "string" },
202
+ tags: { type: "array", items: { type: "string" } },
203
+ description: { type: "string" },
204
+ options: { type: "object", allowUnknown: true },
205
+ form: { type: "object", allowUnknown: true },
206
+ colors: {
207
+ type: "object",
208
+ allowUnknown: false,
209
+ properties: {
210
+ primary: {
211
+ type: "string",
212
+ relations: {
213
+ tokens: [
214
+ "--color-primary-*",
215
+ "--color-primary-fill",
216
+ "--color-primary-text",
217
+ "--background-mesh-*",
218
+ ],
219
+ },
220
+ },
221
+ secondary: {
222
+ type: "string",
223
+ relations: {
224
+ tokens: ["--color-secondary-*", "--color-gray-*", "--background-mesh-*"]
225
+ },
226
+ },
227
+ accent: {
228
+ type: "string",
229
+ relations: {
230
+ tokens: ["--color-accent-*", "--background-mesh-*"]
231
+ },
232
+ },
233
+ background: {
234
+ type: "string",
235
+ relations: {
236
+ tokens: [
237
+ "--color-surface-*",
238
+ "--color-surface-translucent-*",
239
+ "--surface-*-bg",
240
+ "--surface-*-text",
241
+ "--surface-*-text-secondary",
242
+ "--surface-*-text-muted",
243
+ "--surface-*-icon",
244
+ "--surface-*-icon-subtle",
245
+ "--surface-*-shadow",
246
+ "--surface-*-border",
247
+ ],
248
+ },
249
+ },
250
+ success: {
251
+ type: ["string", "null"],
252
+ relations: { tokens: ["--color-success-*"] },
253
+ },
254
+ warning: {
255
+ type: ["string", "null"],
256
+ relations: { tokens: ["--color-warning-*"] },
257
+ },
258
+ danger: {
259
+ type: ["string", "null"],
260
+ relations: { tokens: ["--color-danger-*"] },
261
+ },
262
+ info: {
263
+ type: ["string", "null"],
264
+ relations: { tokens: ["--color-info-*"] },
265
+ },
266
+ gradientStops: { type: "number" },
267
+ elevationOpacity: {
268
+ type: "number",
269
+ relations: { tokens: ["--surface-*-shadow"] },
270
+ },
271
+ darkMode: {
272
+ type: "object",
273
+ allowUnknown: true,
274
+ properties: {
275
+ background: {
276
+ type: "string",
277
+ relations: {
278
+ theme: "dark",
279
+ tokens: [
280
+ "--color-surface-*",
281
+ "--color-surface-translucent-*",
282
+ "--surface-*-bg",
283
+ "--surface-*-text",
284
+ "--surface-*-text-secondary",
285
+ "--surface-*-text-muted",
286
+ "--surface-*-icon",
287
+ "--surface-*-icon-subtle",
288
+ "--surface-*-shadow",
289
+ "--surface-*-border",
290
+ ],
291
+ },
292
+ },
293
+ primary: {
294
+ type: "string",
295
+ relations: {
296
+ theme: "dark",
297
+ tokens: ["--color-primary-*", "--color-primary-fill", "--color-primary-text"],
298
+ },
299
+ },
300
+ secondary: {
301
+ type: "string",
302
+ relations: {
303
+ theme: "dark",
304
+ tokens: ["--color-secondary-*", "--color-gray-*"]
305
+ },
306
+ },
307
+ accent: {
308
+ type: "string",
309
+ relations: { theme: "dark", tokens: ["--color-accent-*"] },
310
+ },
311
+ },
312
+ },
313
+ },
314
+ },
315
+ typography: {
316
+ type: "object",
317
+ allowUnknown: false,
318
+ properties: {
319
+ fontFamilyHeadings: {
320
+ type: "string",
321
+ relations: { tokens: ["--font-family-headings"] },
322
+ },
323
+ fontFamilyBody: {
324
+ type: "string",
325
+ relations: { tokens: ["--font-family-body"] },
326
+ },
327
+ fontFamilyMono: {
328
+ type: "string",
329
+ relations: { tokens: ["--font-family-mono"] },
330
+ },
331
+ baseFontSize: {
332
+ type: "number",
333
+ relations: { tokens: ["--font-size-*"] },
334
+ },
335
+ fontScale: {
336
+ type: "number",
337
+ relations: { tokens: ["--font-size-*"] },
338
+ },
339
+ fontWeightLight: {
340
+ type: ["string", "number"],
341
+ relations: { tokens: ["--font-weight-light"] },
342
+ },
343
+ fontWeightNormal: {
344
+ type: ["string", "number"],
345
+ relations: { tokens: ["--font-weight-normal"] },
346
+ },
347
+ fontWeightMedium: {
348
+ type: ["string", "number"],
349
+ relations: { tokens: ["--font-weight-medium"] },
350
+ },
351
+ fontWeightSemibold: {
352
+ type: ["string", "number"],
353
+ relations: { tokens: ["--font-weight-semibold"] },
354
+ },
355
+ fontWeightBold: {
356
+ type: ["string", "number"],
357
+ relations: { tokens: ["--font-weight-bold"] },
358
+ },
359
+ lineHeightTight: {
360
+ type: ["string", "number"],
361
+ relations: { tokens: ["--font-line-height-tight"] },
362
+ },
363
+ lineHeightNormal: {
364
+ type: ["string", "number"],
365
+ relations: { tokens: ["--font-line-height-normal"] },
366
+ },
367
+ lineHeightRelaxed: {
368
+ type: ["string", "number"],
369
+ relations: { tokens: ["--font-line-height-relaxed"] },
370
+ },
371
+ letterSpacingTight: { type: "number" },
372
+ letterSpacingNormal: { type: "number" },
373
+ letterSpacingWide: { type: "number" },
374
+ },
375
+ },
376
+ spatialRhythm: {
377
+ type: "object",
378
+ allowUnknown: false,
379
+ properties: {
380
+ baseUnit: {
381
+ type: "number",
382
+ relations: { tokens: ["--spacing-*"] },
383
+ },
384
+ scaleRatio: { type: "number" },
385
+ maxSpacingSteps: {
386
+ type: "number",
387
+ relations: { tokens: ["--spacing-*"] },
388
+ },
389
+ containerMaxWidth: { type: ["number", "string"] },
390
+ containerPadding: { type: "number" },
391
+ inputPadding: {
392
+ type: "number",
393
+ relations: {
394
+ rules: [{ selectors: ["input", "textarea", "select"], properties: ["padding"] }],
395
+ },
396
+ },
397
+ buttonPadding: {
398
+ type: "number",
399
+ relations: {
400
+ rules: [{ selectors: ["button", ".btn"], properties: ["padding"] }],
401
+ },
402
+ },
403
+ sectionSpacing: {
404
+ type: "number",
405
+ relations: {
406
+ rules: [{ selectors: ["section"], properties: ["margin", "padding"] }],
407
+ },
408
+ },
409
+ },
410
+ },
411
+ shape: {
412
+ type: "object",
413
+ allowUnknown: false,
414
+ properties: {
415
+ radiusSize: {
416
+ type: ["string", "number"],
417
+ relations: { tokens: ["--radius-*"] },
418
+ },
419
+ customRadius: { type: ["string", "number", "null"] },
420
+ borderWidth: {
421
+ type: ["string", "number"],
422
+ relations: { tokens: ["--border-width-*"] },
423
+ },
424
+ },
425
+ },
426
+ behavior: {
427
+ type: "object",
428
+ allowUnknown: false,
429
+ properties: {
430
+ transitionSpeed: {
431
+ type: ["string", "number"],
432
+ relations: { tokens: ["--transition-*"] },
433
+ },
434
+ animationEasing: { type: "string" },
435
+ customTransitionSpeed: { type: ["number", "null"] },
436
+ customEasing: { type: ["string", "null"] },
437
+ focusRingWidth: {
438
+ type: "number",
439
+ relations: { rules: [{ selectors: [":focus-visible"], properties: ["outline-width", "box-shadow"] }] },
440
+ },
441
+ focusRingOpacity: {
442
+ type: "number",
443
+ relations: { rules: [{ selectors: [":focus-visible"], properties: ["box-shadow", "outline-color"] }] },
444
+ },
445
+ hoverOpacity: { type: "number" },
446
+ },
447
+ },
448
+ layout: {
449
+ type: "object",
450
+ allowUnknown: false,
451
+ properties: {
452
+ maxWidth: {
453
+ type: ["number", "string"],
454
+ relations: { tokens: ["--layout-max-width", "--layout-max-width-*"] },
455
+ },
456
+ maxWidths: {
457
+ type: "object",
458
+ allowUnknown: false,
459
+ properties: {
460
+ sm: { type: ["number", "string"], relations: { tokens: ["--layout-max-width-sm"] } },
461
+ md: { type: ["number", "string"], relations: { tokens: ["--layout-max-width-md"] } },
462
+ lg: { type: ["number", "string"], relations: { tokens: ["--layout-max-width-lg"] } },
463
+ xl: { type: ["number", "string"], relations: { tokens: ["--layout-max-width-xl"] } },
464
+ },
465
+ },
466
+ containerPadding: {
467
+ type: ["number", "string"],
468
+ relations: { tokens: ["--layout-container-padding"] },
469
+ },
470
+ breakpoints: {
471
+ type: "object",
472
+ allowUnknown: false,
473
+ properties: {
474
+ sm: { type: "number" },
475
+ md: { type: "number" },
476
+ lg: { type: "number" },
477
+ xl: { type: "number" },
478
+ },
479
+ },
480
+ gridColumns: { type: "number" },
481
+ gridGutter: { type: "number" },
482
+ densityCompact: { type: "number" },
483
+ densityNormal: { type: "number" },
484
+ densityComfortable: { type: "number" },
485
+ buttonMinHeight: { type: "number" },
486
+ inputMinHeight: { type: "number" },
487
+ baseShadowOpacity: {
488
+ type: "number",
489
+ relations: { tokens: ["--shadow-*"] },
490
+ },
491
+ darkMode: {
492
+ type: "object",
493
+ allowUnknown: true,
494
+ properties: {
495
+ baseShadowOpacity: { type: "number", relations: { theme: "dark", tokens: ["--shadow-*"] } },
496
+ },
497
+ },
498
+ utilities: { type: "object", allowUnknown: true },
499
+ gridSystem: { type: "object", allowUnknown: true },
500
+ containerMaxWidth: { type: ["number", "string"] },
501
+ },
502
+ },
503
+ layers: {
504
+ type: "object",
505
+ allowUnknown: false,
506
+ properties: {
507
+ baseShadowOpacity: {
508
+ type: "number",
509
+ relations: { tokens: ["--shadow-*"] },
510
+ },
511
+ shadowBlurMultiplier: {
512
+ type: "number",
513
+ relations: { tokens: ["--shadow-*"] },
514
+ },
515
+ shadowOffsetMultiplier: {
516
+ type: "number",
517
+ relations: { tokens: ["--shadow-*"] },
518
+ },
519
+ shadowDepth: { type: "string" },
520
+ blurLight: { type: "number" },
521
+ blurMedium: { type: "number" },
522
+ blurHeavy: { type: "number" },
523
+ baseZIndex: { type: "number", relations: { tokens: ["--z-*"] } },
524
+ zIndexStep: { type: "number", relations: { tokens: ["--z-*"] } },
525
+ zIndexBase: { type: "number" },
526
+ zIndexDropdown: { type: "number" },
527
+ zIndexSticky: { type: "number" },
528
+ zIndexFixed: { type: "number" },
529
+ zIndexModal: { type: "number" },
530
+ zIndexPopover: { type: "number" },
531
+ zIndexTooltip: { type: "number" },
532
+ zIndexNotification: { type: "number" },
533
+ darkMode: {
534
+ type: "object",
535
+ allowUnknown: true,
536
+ properties: {
537
+ baseShadowOpacity: { type: "number", relations: { theme: "dark", tokens: ["--shadow-*"] } },
538
+ },
539
+ },
540
+ },
541
+ },
542
+ advanced: { type: "object", allowUnknown: true },
543
+ a11y: { type: "object", allowUnknown: true },
544
+ icons: {
545
+ type: "object",
546
+ allowUnknown: false,
547
+ properties: {
548
+ set: { type: "string" },
549
+ weight: { type: "string" },
550
+ defaultSize: { type: "number", relations: { tokens: ["--icon-size"] } },
551
+ sizes: { type: "object", allowUnknown: true },
552
+ spritePath: { type: "string" },
553
+ externalPath: { type: "string" },
554
+ include: { type: "object", allowUnknown: true },
555
+ },
556
+ },
557
+ components: { type: "object", allowUnknown: true },
558
+ gap: { type: "number" },
559
+ debug: { type: "boolean" },
560
+ },
561
+ };
562
+
563
+ const __INIT_CONFIG_SPEC__ = {
564
+ type: "object",
565
+ allowUnknown: true,
566
+ properties: {
567
+ mode: { type: "string" },
568
+ preset: { type: "string" },
569
+ design: __DESIGN_CONFIG_SPEC__,
570
+ enhancers: { type: ["object", "array"] },
571
+ applyGlobalStyles: { type: "boolean" },
572
+ manageTheme: { type: "boolean" },
573
+ themeStorageKey: { type: "string" },
574
+ preloadStyles: { type: "boolean" },
575
+ criticalLayers: { type: "array", items: { type: "string" } },
576
+ autoDefine: {
577
+ type: "object",
578
+ allowUnknown: false,
579
+ properties: {
580
+ predefine: { type: "array", items: { type: "string" } },
581
+ mapper: { type: __ANY_TYPE__ },
582
+ enhancers: { type: ["object", "array"] },
583
+ scanExisting: { type: "boolean" },
584
+ observeShadows: { type: "boolean" },
585
+ patchAttachShadow: { type: "boolean" },
586
+ debounceMs: { type: "number" },
587
+ onError: { type: __ANY_TYPE__ },
588
+ baseURL: { type: "string" },
589
+ },
590
+ },
591
+ managerURL: { type: "string" },
592
+ manager: { type: __ANY_TYPE__ },
593
+ liveEdit: { type: "boolean" },
594
+ log: { type: __ANY_TYPE__ },
595
+ },
596
+ };
597
+
598
+ function __getValueType(value) {
599
+ if (value === null) return "null";
600
+ if (Array.isArray(value)) return "array";
601
+ return typeof value;
602
+ }
603
+
604
+ function __matchesExpectedType(value, expected) {
605
+ if (expected === __ANY_TYPE__) return true;
606
+ const actual = __getValueType(value);
607
+ if (Array.isArray(expected)) {
608
+ return expected.includes(actual);
609
+ }
610
+ return actual === expected;
611
+ }
612
+
613
+ function __validateAgainstSpec(value, spec, path, issues) {
614
+ if (!spec) return;
615
+ const expectedType = spec.type || __ANY_TYPE__;
616
+ if (!__matchesExpectedType(value, expectedType)) {
617
+ issues.push({
618
+ path,
619
+ expected: expectedType,
620
+ actual: __getValueType(value),
621
+ message: `Expected ${expectedType} but got ${__getValueType(value)}`,
622
+ });
623
+ return;
624
+ }
625
+
626
+ if (expectedType === "array" && spec.items && Array.isArray(value)) {
627
+ value.forEach((item, index) => {
628
+ __validateAgainstSpec(item, spec.items, `${path}[${index}]`, issues);
629
+ });
630
+ }
631
+
632
+ if (expectedType === "object" && value && typeof value === "object") {
633
+ const props = spec.properties || {};
634
+ for (const [key, val] of Object.entries(value)) {
635
+ if (!Object.prototype.hasOwnProperty.call(props, key)) {
636
+ if (!spec.allowUnknown) {
637
+ issues.push({
638
+ path: `${path}.${key}`,
639
+ expected: "known property",
640
+ actual: "unknown",
641
+ message: `Unknown property "${key}"`,
642
+ });
643
+ }
644
+ continue;
645
+ }
646
+ __validateAgainstSpec(val, props[key], `${path}.${key}`, issues);
647
+ }
648
+ }
649
+ }
650
+
651
+ function __collectRelations(spec, basePath = "", out = {}) {
652
+ if (!spec || typeof spec !== "object") return out;
653
+ if (spec.relations && basePath) {
654
+ out[basePath] = spec.relations;
655
+ }
656
+
657
+ if (spec.type === "object" && spec.properties) {
658
+ Object.entries(spec.properties).forEach(([key, value]) => {
659
+ const nextPath = basePath ? `${basePath}.${key}` : key;
660
+ __collectRelations(value, nextPath, out);
661
+ });
662
+ }
663
+
664
+ if (spec.type === "array" && spec.items) {
665
+ const nextPath = `${basePath}[]`;
666
+ __collectRelations(spec.items, nextPath, out);
667
+ }
668
+
669
+ return out;
670
+ }
671
+
672
+ /**
673
+ * Machine-readable config relations for live editing.
674
+ * Keys are design config paths (e.g., "colors.accent").
675
+ */
676
+ export const PDS_CONFIG_RELATIONS = __collectRelations(
677
+ __DESIGN_CONFIG_SPEC__,
678
+ ""
679
+ );
680
+
681
+ export function validateDesignConfig(designConfig, { log, context = "PDS config" } = {}) {
682
+ if (!designConfig || typeof designConfig !== "object") return [];
683
+ const issues = [];
684
+ __validateAgainstSpec(designConfig, __DESIGN_CONFIG_SPEC__, "design", issues);
685
+ if (issues.length && typeof log === "function") {
686
+ issues.forEach((issue) => {
687
+ log("warn", `[${context}] ${issue.message} at ${issue.path}`);
688
+ });
689
+ }
690
+ return issues;
691
+ }
692
+
693
+ export function validateInitConfig(initConfig, { log, context = "PDS config" } = {}) {
694
+ if (!initConfig || typeof initConfig !== "object") return [];
695
+ const issues = [];
696
+ __validateAgainstSpec(initConfig, __INIT_CONFIG_SPEC__, "config", issues);
697
+ if (issues.length && typeof log === "function") {
698
+ issues.forEach((issue) => {
699
+ log("warn", `[${context}] ${issue.message} at ${issue.path}`);
700
+ });
701
+ }
702
+ return issues;
703
+ }
704
+
3
705
  /**
4
706
  * Design system presets - pre-configured themes for quick starts.
5
707
  * Expose as an object keyed by preset id.
@@ -113,6 +815,7 @@ export const presets = {
113
815
  id: "paper-and-ink",
114
816
  name: "Paper & Ink",
115
817
  tags: ["app", "featured"],
818
+ themes: ["light"], // Not optimized for dark mode
116
819
  description: "Ultra-minimal design with focus on typography and whitespace",
117
820
  colors: {
118
821
  primary: "#171717",
@@ -351,6 +1054,7 @@ export const presets = {
351
1054
  "pastel-play": {
352
1055
  id: "pastel-play",
353
1056
  name: "Pastel Play",
1057
+ themes: ["light"], // Not optimized for dark mode due to pastel contrast challenges
354
1058
  description:
355
1059
  "Playful pastels with soft surfaces and friendly rounded shapes",
356
1060
  colors: {
@@ -395,7 +1099,7 @@ export const presets = {
395
1099
  accent: "#06b6d4", // cyan signal
396
1100
  background: "#f8fafc",
397
1101
  darkMode: {
398
- background: "#0b0b0b",
1102
+ background: "#0c0c0c",
399
1103
  secondary: "#9ca3af",
400
1104
  // Set a chromatic primary in dark mode to ensure both:
401
1105
  // - outline/link contrast on dark surface, and