@pure-ds/core 0.4.26 → 0.4.28

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.
@@ -1,4 +1,4 @@
1
- {
1
+ {
2
2
  "schemaVersion": "1.0.0",
3
3
  "readme": "",
4
4
  "modules": [
@@ -506,169 +506,6 @@
506
506
  }
507
507
  ]
508
508
  },
509
- {
510
- "kind": "javascript-module",
511
- "path": "public/assets/pds/components/pds-icon.js",
512
- "declarations": [
513
- {
514
- "kind": "class",
515
- "description": "SVG Icon Web Component",
516
- "name": "SvgIcon",
517
- "members": [
518
- {
519
- "kind": "field",
520
- "name": "spritePromises",
521
- "static": true,
522
- "default": "new Map()"
523
- },
524
- {
525
- "kind": "field",
526
- "name": "inlineSprites",
527
- "static": true,
528
- "default": "new Map()"
529
- },
530
- {
531
- "kind": "field",
532
- "name": "externalIconCache",
533
- "static": true,
534
- "default": "new Map()"
535
- },
536
- {
537
- "kind": "field",
538
- "name": "externalIconPromises",
539
- "static": true,
540
- "default": "new Map()"
541
- },
542
- {
543
- "kind": "field",
544
- "name": "instances",
545
- "static": true,
546
- "default": "new Set()"
547
- },
548
- {
549
- "kind": "method",
550
- "name": "spriteAvailable",
551
- "description": "Check if sprite sheet is available",
552
- "privacy": "public",
553
- "return": {
554
- "type": {
555
- "text": "boolean"
556
- }
557
- }
558
- },
559
- {
560
- "kind": "method",
561
- "name": "fetchExternalIcon",
562
- "static": true,
563
- "parameters": [
564
- {
565
- "name": "iconName",
566
- "description": "The icon name (without .svg extension)",
567
- "type": {
568
- "text": "string"
569
- }
570
- }
571
- ],
572
- "description": "Fetch an external SVG icon and cache it",
573
- "return": {
574
- "type": {
575
- "text": "Promise<boolean>"
576
- }
577
- }
578
- },
579
- {
580
- "kind": "method",
581
- "name": "ensureInlineSprite",
582
- "static": true,
583
- "parameters": [
584
- {
585
- "name": "spriteURL"
586
- }
587
- ]
588
- },
589
- {
590
- "kind": "method",
591
- "name": "notifyInstances",
592
- "static": true
593
- }
594
- ],
595
- "attributes": [
596
- {
597
- "name": "icon",
598
- "type": {
599
- "text": "string"
600
- },
601
- "description": "Icon name from the sprite sheet"
602
- },
603
- {
604
- "name": "size",
605
- "type": {
606
- "text": "string|number"
607
- },
608
- "description": "Icon size in pixels or named size (xs, sm, md, lg, xl, 2xl)"
609
- },
610
- {
611
- "name": "color",
612
- "type": {
613
- "text": "string"
614
- },
615
- "description": "Icon color (CSS color value, default: currentColor)"
616
- },
617
- {
618
- "name": "label",
619
- "type": {
620
- "text": "string"
621
- },
622
- "description": "Accessible label for the icon (adds role=\"img\")"
623
- },
624
- {
625
- "name": "rotate",
626
- "type": {
627
- "text": "number"
628
- },
629
- "description": "Rotation angle in degrees"
630
- },
631
- {
632
- "type": {
633
- "text": "string"
634
- },
635
- "description": "Override sprite sheet path",
636
- "name": "sprite"
637
- },
638
- {
639
- "type": {
640
- "text": "boolean"
641
- },
642
- "description": "Force fallback icon rendering",
643
- "name": "no-sprite"
644
- }
645
- ],
646
- "superclass": {
647
- "name": "HTMLElement"
648
- },
649
- "tagName": "pds-icon",
650
- "customElement": true
651
- }
652
- ],
653
- "exports": [
654
- {
655
- "kind": "js",
656
- "name": "SvgIcon",
657
- "declaration": {
658
- "name": "SvgIcon",
659
- "module": "public/assets/pds/components/pds-icon.js"
660
- }
661
- },
662
- {
663
- "kind": "custom-element-definition",
664
- "name": "pds-icon",
665
- "declaration": {
666
- "name": "SvgIcon",
667
- "module": "public/assets/pds/components/pds-icon.js"
668
- }
669
- }
670
- ]
671
- },
672
509
  {
673
510
  "kind": "javascript-module",
674
511
  "path": "public/assets/pds/components/pds-form.js",
@@ -711,6 +548,10 @@
711
548
  "kind": "method",
712
549
  "name": "submit"
713
550
  },
551
+ {
552
+ "kind": "method",
553
+ "name": "reset"
554
+ },
714
555
  {
715
556
  "kind": "field",
716
557
  "name": "jsonSchema",
@@ -978,6 +819,169 @@
978
819
  }
979
820
  ]
980
821
  },
822
+ {
823
+ "kind": "javascript-module",
824
+ "path": "public/assets/pds/components/pds-icon.js",
825
+ "declarations": [
826
+ {
827
+ "kind": "class",
828
+ "description": "SVG Icon Web Component",
829
+ "name": "SvgIcon",
830
+ "members": [
831
+ {
832
+ "kind": "field",
833
+ "name": "spritePromises",
834
+ "static": true,
835
+ "default": "new Map()"
836
+ },
837
+ {
838
+ "kind": "field",
839
+ "name": "inlineSprites",
840
+ "static": true,
841
+ "default": "new Map()"
842
+ },
843
+ {
844
+ "kind": "field",
845
+ "name": "externalIconCache",
846
+ "static": true,
847
+ "default": "new Map()"
848
+ },
849
+ {
850
+ "kind": "field",
851
+ "name": "externalIconPromises",
852
+ "static": true,
853
+ "default": "new Map()"
854
+ },
855
+ {
856
+ "kind": "field",
857
+ "name": "instances",
858
+ "static": true,
859
+ "default": "new Set()"
860
+ },
861
+ {
862
+ "kind": "method",
863
+ "name": "spriteAvailable",
864
+ "description": "Check if sprite sheet is available",
865
+ "privacy": "public",
866
+ "return": {
867
+ "type": {
868
+ "text": "boolean"
869
+ }
870
+ }
871
+ },
872
+ {
873
+ "kind": "method",
874
+ "name": "fetchExternalIcon",
875
+ "static": true,
876
+ "parameters": [
877
+ {
878
+ "name": "iconName",
879
+ "description": "The icon name (without .svg extension)",
880
+ "type": {
881
+ "text": "string"
882
+ }
883
+ }
884
+ ],
885
+ "description": "Fetch an external SVG icon and cache it",
886
+ "return": {
887
+ "type": {
888
+ "text": "Promise<boolean>"
889
+ }
890
+ }
891
+ },
892
+ {
893
+ "kind": "method",
894
+ "name": "ensureInlineSprite",
895
+ "static": true,
896
+ "parameters": [
897
+ {
898
+ "name": "spriteURL"
899
+ }
900
+ ]
901
+ },
902
+ {
903
+ "kind": "method",
904
+ "name": "notifyInstances",
905
+ "static": true
906
+ }
907
+ ],
908
+ "attributes": [
909
+ {
910
+ "name": "icon",
911
+ "type": {
912
+ "text": "string"
913
+ },
914
+ "description": "Icon name from the sprite sheet"
915
+ },
916
+ {
917
+ "name": "size",
918
+ "type": {
919
+ "text": "string|number"
920
+ },
921
+ "description": "Icon size in pixels or named size (xs, sm, md, lg, xl, 2xl)"
922
+ },
923
+ {
924
+ "name": "color",
925
+ "type": {
926
+ "text": "string"
927
+ },
928
+ "description": "Icon color (CSS color value, default: currentColor)"
929
+ },
930
+ {
931
+ "name": "label",
932
+ "type": {
933
+ "text": "string"
934
+ },
935
+ "description": "Accessible label for the icon (adds role=\"img\")"
936
+ },
937
+ {
938
+ "name": "rotate",
939
+ "type": {
940
+ "text": "number"
941
+ },
942
+ "description": "Rotation angle in degrees"
943
+ },
944
+ {
945
+ "type": {
946
+ "text": "string"
947
+ },
948
+ "description": "Override sprite sheet path",
949
+ "name": "sprite"
950
+ },
951
+ {
952
+ "type": {
953
+ "text": "boolean"
954
+ },
955
+ "description": "Force fallback icon rendering",
956
+ "name": "no-sprite"
957
+ }
958
+ ],
959
+ "superclass": {
960
+ "name": "HTMLElement"
961
+ },
962
+ "tagName": "pds-icon",
963
+ "customElement": true
964
+ }
965
+ ],
966
+ "exports": [
967
+ {
968
+ "kind": "js",
969
+ "name": "SvgIcon",
970
+ "declaration": {
971
+ "name": "SvgIcon",
972
+ "module": "public/assets/pds/components/pds-icon.js"
973
+ }
974
+ },
975
+ {
976
+ "kind": "custom-element-definition",
977
+ "name": "pds-icon",
978
+ "declaration": {
979
+ "name": "SvgIcon",
980
+ "module": "public/assets/pds/components/pds-icon.js"
981
+ }
982
+ }
983
+ ]
984
+ },
981
985
  {
982
986
  "kind": "javascript-module",
983
987
  "path": "public/assets/pds/components/pds-richtext.js",
@@ -1,4 +1,118 @@
1
- import { enhancerMetadata } from "./pds-enhancer-metadata.js";
1
+ /**
2
+ * PDS Enhancers - Single Source of Truth
3
+ *
4
+ * This file defines all progressive enhancements for the Pure Design System.
5
+ * Each enhancer has:
6
+ * - selector: CSS selector to target elements
7
+ * - description: Human-readable explanation
8
+ * - demoHtml: Example usage markup
9
+ * - run: Enhancement function (added at the end)
10
+ */
11
+
12
+ // ============================================================================
13
+ // ENHANCEMENT METADATA DEFINITIONS
14
+ // ============================================================================
15
+
16
+ const enhancerDefinitions = [
17
+ {
18
+ selector: ".accordion",
19
+ description:
20
+ "Ensures only one <details> element can be open at a time within the accordion.",
21
+ demoHtml: `
22
+ <div class="accordion">
23
+ <details>
24
+ <summary>Section 1</summary>
25
+ <p>Content for section 1</p>
26
+ </details>
27
+ <details>
28
+ <summary>Section 2</summary>
29
+ <p>Content for section 2</p>
30
+ </details>
31
+ <details>
32
+ <summary>Section 3</summary>
33
+ <p>Content for section 3</p>
34
+ </details>
35
+ </div>
36
+ `.trim(),
37
+ },
38
+ {
39
+ selector: "nav[data-dropdown]",
40
+ description:
41
+ "Enhances a nav element with data-dropdown to function as a dropdown menu.",
42
+ demoHtml: `
43
+ <nav data-dropdown>
44
+ <button class="btn-primary">Menu</button>
45
+ <menu>
46
+ <li><a href="#">Item 1</a></li>
47
+ <li><a href="#">Item 2</a></li>
48
+ </menu>
49
+ </nav>
50
+ `.trim(),
51
+ },
52
+ {
53
+ selector: "label[data-toggle]",
54
+ description: "Creates a toggle switch element from a checkbox.",
55
+ demoHtml: `
56
+ <label data-toggle>
57
+ <input type="checkbox">
58
+ <span data-label>Enable notifications</span>
59
+ </label>
60
+ `.trim(),
61
+ },
62
+ {
63
+ selector: 'input[type="range"]',
64
+ description: "Enhances range inputs with an attached <output>.",
65
+ demoHtml: `
66
+ <label class="range-output">
67
+ <span data-label>Volume</span>
68
+ <input type="range" min="0" max="100" value="40">
69
+ </label>
70
+ `.trim(),
71
+ },
72
+ {
73
+ selector: "form[data-required]",
74
+ description:
75
+ "Enhances required form fields using an asterisk in the label.",
76
+ demoHtml: `
77
+ <form data-required action="#" method="post">
78
+ <label>
79
+ <span>Field Label</span>
80
+ <input type="text" required>
81
+ </label>
82
+ <nav class="form-actions">
83
+ <button type="submit" class="btn-primary">Submit</button>
84
+ </nav>
85
+ </form>
86
+ `.trim(),
87
+ },
88
+ {
89
+ selector: "fieldset[role=group][data-open]",
90
+ description:
91
+ "Enhances a checkbox/radio group to be open (have a way to add and remove items).",
92
+ demoHtml: `
93
+ <fieldset role="group" data-open>
94
+ <label>
95
+ <span data-label>Test</span>
96
+ <input value="lala" name="test1" type="radio" />
97
+ </label>
98
+ </fieldset>
99
+ `.trim(),
100
+ },
101
+ {
102
+ selector: "button, a[class*='btn-']",
103
+ description:
104
+ "Automatically manages spinner icon for buttons with .btn-working class",
105
+ demoHtml: `
106
+ <button class="btn-primary btn-working">
107
+ <span>Saving</span>
108
+ </button>
109
+ `.trim(),
110
+ },
111
+ ];
112
+
113
+ // ============================================================================
114
+ // ENHANCEMENT RUNTIME FUNCTIONS
115
+ // ============================================================================
2
116
 
3
117
  function enhanceAccordion(elem) {
4
118
  if (elem.dataset.enhancedAccordion) return;
@@ -367,6 +481,11 @@ function enhanceButtonWorking(elem) {
367
481
  });
368
482
  }
369
483
 
484
+ // ============================================================================
485
+ // EXPORTS
486
+ // ============================================================================
487
+
488
+ // Map selectors to their run functions
370
489
  const enhancerRunners = new Map([
371
490
  [".accordion", enhanceAccordion],
372
491
  ["nav[data-dropdown]", enhanceDropdown],
@@ -377,9 +496,23 @@ const enhancerRunners = new Map([
377
496
  ["button, a[class*='btn-']", enhanceButtonWorking],
378
497
  ]);
379
498
 
380
- export const defaultPDSEnhancers = enhancerMetadata.map((meta) => ({
499
+ /**
500
+ * Complete enhancers with runtime functions.
501
+ * Used by PDS.enhancer() and AutoDefiner at runtime.
502
+ *
503
+ * This is the canonical runtime array of enhancer objects.
504
+ */
505
+ export const defaultPDSEnhancers = enhancerDefinitions.map((meta) => ({
381
506
  ...meta,
382
507
  run: enhancerRunners.get(meta.selector) || (() => {}),
383
508
  }));
384
509
 
385
- export const defaultPDSEnhancerMetadata = enhancerMetadata;
510
+ /**
511
+ * Metadata-only export for build tools and documentation.
512
+ * This is semantically identical to enhancerDefinitions but exported
513
+ * for tooling that wants to explicitly access metadata without run functions.
514
+ *
515
+ * Build tools can safely import defaultPDSEnhancers too - Node.js won't
516
+ * execute browser-only DOM code in the run functions.
517
+ */
518
+ export const defaultPDSEnhancerMetadata = enhancerDefinitions;
package/src/js/pds.js CHANGED
@@ -1033,7 +1033,7 @@ async function __setupAutoDefinerAndEnhancers(options) {
1033
1033
  }
1034
1034
  // Rely on AutoDefiner to run enhancers across light and shadow DOMs
1035
1035
 
1036
- return { autoDefiner };
1036
+ return { autoDefiner, mergedEnhancers };
1037
1037
  }
1038
1038
 
1039
1039
  async function live(config) {
@@ -1226,6 +1226,7 @@ async function live(config) {
1226
1226
 
1227
1227
  // 5) Set up AutoDefiner + run enhancers (defaults merged with user)
1228
1228
  let autoDefiner = null;
1229
+ let mergedEnhancers = [];
1229
1230
  try {
1230
1231
  const res = await __setupAutoDefinerAndEnhancers({
1231
1232
  autoDefineBaseURL: derivedAutoDefineBaseURL,
@@ -1240,6 +1241,7 @@ async function live(config) {
1240
1241
  autoDefinePreferModule: !(cfgAuto && cfgAuto.baseURL),
1241
1242
  });
1242
1243
  autoDefiner = res.autoDefiner;
1244
+ mergedEnhancers = res.mergedEnhancers || [];
1243
1245
  } catch (error) {
1244
1246
  generatorConfig?.log?.("error", "❌ Failed to initialize AutoDefiner/Enhancers:", error);
1245
1247
  }
@@ -1256,6 +1258,7 @@ async function live(config) {
1256
1258
  design: structuredClone(normalized.generatorConfig.design),
1257
1259
  preset: normalized.generatorConfig.preset,
1258
1260
  theme: resolvedTheme,
1261
+ enhancers: mergedEnhancers,
1259
1262
  });
1260
1263
 
1261
1264
  // Emit event to notify that PDS is ready (unified)
@@ -1394,6 +1397,7 @@ async function staticInit(config) {
1394
1397
 
1395
1398
  // 5) AutoDefiner + Enhancers
1396
1399
  let autoDefiner = null;
1400
+ let mergedEnhancers = [];
1397
1401
  try {
1398
1402
  const res = await __setupAutoDefinerAndEnhancers({
1399
1403
  autoDefineBaseURL,
@@ -1404,6 +1408,7 @@ async function staticInit(config) {
1404
1408
  autoDefinePreferModule: !(cfgAuto && cfgAuto.baseURL),
1405
1409
  });
1406
1410
  autoDefiner = res.autoDefiner;
1411
+ mergedEnhancers = res.mergedEnhancers || [];
1407
1412
  } catch (error) {
1408
1413
  // No config available in static mode, using console
1409
1414
  console.error(
@@ -1421,6 +1426,7 @@ async function staticInit(config) {
1421
1426
  design: structuredClone(normalized.generatorConfig.design),
1422
1427
  preset: normalized.generatorConfig.preset,
1423
1428
  theme: resolvedTheme,
1429
+ enhancers: mergedEnhancers,
1424
1430
  });
1425
1431
 
1426
1432
  // 6) Emit ready event (unified)
@@ -1,98 +0,0 @@
1
- # ⚠️ CSS IntelliSense - Important Information
2
-
3
- ## Where CSS IntelliSense Works
4
-
5
- ✅ **CSS Files (.css)**
6
- ```css
7
- /* Full autocomplete available */
8
- .my-class {
9
- color: var(--color-primary-500); /* ← Type var(-- to see all tokens */
10
- padding: var(--spacing-4);
11
- }
12
- ```
13
-
14
- ✅ **HTML `<style>` Tags**
15
- ```html
16
- <style>
17
- .custom {
18
- /* Full autocomplete available */
19
- background: var(--color-primary-500);
20
- }
21
- </style>
22
- ```
23
-
24
- ## Where It Does NOT Work
25
-
26
- ❌ **Inline `style` Attributes**
27
- ```html
28
- <!-- NO IntelliSense here - This is a VS Code limitation -->
29
- <div style="padding: var(--)"></div>
30
- ```
31
-
32
- This is not a PDS bug - it's a VS Code limitation. The `css.customData` setting only applies to CSS files and `<style>` tags, not inline style attributes.
33
-
34
- ## Workarounds
35
-
36
- ### 1. Use `<style>` Tags
37
- ```html
38
- <style>
39
- .my-padding {
40
- padding: var(--spacing-4); /* Full IntelliSense works here */
41
- }
42
- </style>
43
- <div class="my-padding"></div>
44
- ```
45
-
46
- ### 2. Use Utility Classes
47
- PDS provides comprehensive utility classes:
48
- ```html
49
- <div class="flex gap-4 items-center">
50
- <div class="card surface-elevated">
51
- Content
52
- </div>
53
- </div>
54
- ```
55
-
56
- ### 3. Use External CSS File
57
- ```css
58
- /* styles.css - Full IntelliSense */
59
- .hero {
60
- background: var(--color-primary-500);
61
- padding: var(--spacing-8);
62
- }
63
- ```
64
-
65
- ```html
66
- <div class="hero">Content</div>
67
- ```
68
-
69
- ## Verify It's Working
70
-
71
- 1. **Create a test CSS file** (like `test.css`)
72
- 2. **Type**: `color: var(--`
73
- 3. **You should see**: All 165 CSS custom properties with descriptions
74
- 4. **Hover over a token**: See the actual color/value
75
-
76
- If this doesn't work:
77
- 1. Check `.vscode/settings.json` has `css.customData` configured
78
- 2. Reload VS Code (Ctrl+Shift+P → "Developer: Reload Window")
79
- 3. Make sure `pds.css-data.json` exists in `public/assets/pds/`
80
-
81
- ## For Class Autocomplete
82
-
83
- Class autocomplete in HTML `class` attributes also has limitations in VS Code's HTML extension. For best class discovery:
84
-
85
- 1. **Use Storybook** - Browse all available classes and components
86
- 2. **Check documentation** - See [CSS-INTELLISENSE-QUICK-REF.md](./CSS-INTELLISENSE-QUICK-REF.md)
87
- 3. **Use TypeScript** - Better autocomplete in JS/TS files
88
-
89
- ## Summary
90
-
91
- | Location | CSS Tokens | Utility Classes | Works? |
92
- |----------|-----------|----------------|---------|
93
- | `.css` files | ✅ Yes | N/A | ✅ Full Support |
94
- | `<style>` tags | ✅ Yes | N/A | ✅ Full Support |
95
- | `style=""` attribute | ❌ No | N/A | ❌ VS Code Limitation |
96
- | `class=""` attribute | N/A | ⚠️ Limited | ⚠️ VS Code Limitation |
97
-
98
- **Bottom line**: Use CSS files or `<style>` tags for the best IntelliSense experience with PDS tokens!