@pure-ds/storybook 0.7.25 → 0.7.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.
Files changed (73) hide show
  1. package/.storybook/addons/html-preview/Panel.jsx +128 -7
  2. package/.storybook/addons/html-preview/preview.js +112 -2
  3. package/.storybook/preview.js +5 -4
  4. package/dist/pds-reference.json +2468 -1018
  5. package/package.json +2 -2
  6. package/public/assets/js/app.js +1 -1
  7. package/public/assets/js/pds-ask.js +6 -6
  8. package/public/assets/js/pds-manager.js +194 -79
  9. package/public/assets/pds/components/pds-calendar.js +91 -159
  10. package/public/assets/pds/components/pds-daterange.js +683 -0
  11. package/public/assets/pds/components/pds-form.js +123 -21
  12. package/public/assets/pds/components/pds-omnibox.js +70 -3
  13. package/public/assets/pds/components/pds-rating.js +648 -0
  14. package/public/assets/pds/components/pds-tags.js +840 -0
  15. package/public/assets/pds/core/pds-ask.js +6 -6
  16. package/public/assets/pds/core/pds-manager.js +194 -79
  17. package/public/assets/pds/custom-elements.json +1340 -141
  18. package/public/assets/pds/pds-css-complete.json +7 -2
  19. package/public/assets/pds/pds-runtime-config.json +1 -1
  20. package/public/assets/pds/pds.css-data.json +4 -4
  21. package/public/assets/pds/styles/pds-components.css +96 -24
  22. package/public/assets/pds/styles/pds-components.css.js +192 -48
  23. package/public/assets/pds/styles/pds-primitives.css +6 -3
  24. package/public/assets/pds/styles/pds-primitives.css.js +12 -6
  25. package/public/assets/pds/styles/pds-styles.css +160 -45
  26. package/public/assets/pds/styles/pds-styles.css.js +320 -90
  27. package/public/assets/pds/styles/pds-utilities.css +58 -18
  28. package/public/assets/pds/styles/pds-utilities.css.js +116 -36
  29. package/public/assets/pds/vscode-custom-data.json +129 -0
  30. package/src/js/common/ask.js +257 -19
  31. package/src/js/pds-core/pds-generator.js +178 -45
  32. package/src/js/pds-core/pds-ontology.js +2 -2
  33. package/src/js/pds.d.ts +55 -1
  34. package/stories/components/PdsCalendar.stories.js +650 -168
  35. package/stories/components/PdsDaterange.stories.js +85 -0
  36. package/stories/components/PdsForm.Basics.stories.js +16 -0
  37. package/stories/components/PdsForm.ConditionalAndCalculated.stories.js +16 -0
  38. package/stories/components/PdsForm.CustomContent.stories.js +10 -0
  39. package/stories/components/PdsForm.Dialogs.stories.js +7 -0
  40. package/stories/components/PdsForm.Layout.stories.js +16 -0
  41. package/stories/components/PdsForm.SelectionAndArrays.stories.js +12 -0
  42. package/stories/components/PdsForm.stories.js +179 -219
  43. package/stories/components/PdsIcon.stories.js +17 -7
  44. package/stories/components/PdsOmnibox.stories.js +1 -60
  45. package/stories/components/PdsRating.stories.js +126 -0
  46. package/stories/components/PdsTags.stories.js +488 -0
  47. package/stories/components/PdsToaster.stories.js +1 -1
  48. package/stories/components/omnibox-countries-api-settings.js +63 -0
  49. package/stories/foundations/Colors.stories.js +6 -1
  50. package/stories/foundations/HTMLDefaults.stories.js +6 -6
  51. package/stories/foundations/Icons.stories.js +4 -4
  52. package/stories/foundations/MeshGradients.stories.js +13 -3
  53. package/stories/foundations/SmartSurfaces.stories.js +43 -31
  54. package/stories/foundations/Typography.stories.js +30 -108
  55. package/stories/foundations/ZIndex.stories.js +3 -3
  56. package/stories/layout/LayoutOverview.stories.js +3 -3
  57. package/stories/layout/LayoutSystem.stories.js +24 -18
  58. package/stories/patterns/BorderEffects.stories.js +28 -16
  59. package/stories/patterns/InteractiveStates.stories.js +39 -24
  60. package/stories/patterns/Utilities.stories.js +45 -23
  61. package/stories/primitives/ArticleLayout.stories.js +176 -0
  62. package/stories/primitives/Badges.stories.js +24 -8
  63. package/stories/primitives/Buttons.stories.js +51 -12
  64. package/stories/primitives/Callouts.stories.js +8 -7
  65. package/stories/primitives/Cards.stories.js +4 -1
  66. package/stories/primitives/FormElements.stories.js +8 -2
  67. package/stories/primitives/HtmlFormElements.stories.js +8 -2
  68. package/stories/primitives/HtmlFormGroups.stories.js +5 -2
  69. package/stories/primitives/Media.stories.js +44 -30
  70. package/stories/primitives/Tables.stories.js +25 -7
  71. package/stories/utils/PdsAsk.stories.js +218 -14
  72. package/stories/utils/PdsObjectApi.stories.js +16 -4
  73. package/stories/utils/PdsToast.stories.js +43 -3
@@ -109,13 +109,15 @@ const CheckIcon = () => (
109
109
  );
110
110
 
111
111
  export const Panel = ({ active }) => {
112
- const [source, setSource] = useState({ markup: '', forms: [], omniboxes: [], treeviews: [], fabs: [] });
112
+ const [source, setSource] = useState({ markup: '', forms: [], omniboxes: [], treeviews: [], tags: [], fabs: [], pdsApiCalls: [] });
113
113
  const [copied, setCopied] = useState(false);
114
114
  const [highlightedMarkup, setHighlightedMarkup] = useState('');
115
115
  const [highlightedforms, setHighlightedforms] = useState([]);
116
116
  const [highlightedOmniboxes, setHighlightedOmniboxes] = useState([]);
117
117
  const [highlightedTreeviews, setHighlightedTreeviews] = useState([]);
118
+ const [highlightedTags, setHighlightedTags] = useState([]);
118
119
  const [highlightedFabs, setHighlightedFabs] = useState([]);
120
+ const [highlightedPdsApiCalls, setHighlightedPdsApiCalls] = useState([]);
119
121
  const shikiRef = useRef(null);
120
122
 
121
123
  // Get Storybook theme to detect light/dark mode
@@ -302,10 +304,79 @@ export const Panel = ({ active }) => {
302
304
  processTreeviews();
303
305
  }, [source.treeviews, shikiTheme]);
304
306
 
307
+ // Highlight tags options when source or theme changes
308
+ useEffect(() => {
309
+ if (!source.tags || source.tags.length === 0) {
310
+ setHighlightedTags([]);
311
+ return;
312
+ }
313
+
314
+ const highlightCode = async (code) => {
315
+ if (!code) return '';
316
+ const highlighter = shikiRef.current || await loadShiki();
317
+ if (highlighter) {
318
+ try {
319
+ return highlighter.codeToHtml(code, { lang: 'javascript', theme: shikiTheme });
320
+ } catch (err) {
321
+ return `<pre><code>${escapeHtml(code)}</code></pre>`;
322
+ }
323
+ }
324
+ return `<pre><code>${escapeHtml(code)}</code></pre>`;
325
+ };
326
+
327
+ const processTags = async () => {
328
+ const highlighted = await Promise.all(
329
+ source.tags.map(async (tagEntry, index) => ({
330
+ id: tagEntry.id ?? index,
331
+ label: tagEntry.label,
332
+ options: await highlightCode(tagEntry.options)
333
+ }))
334
+ );
335
+ setHighlightedTags(highlighted);
336
+ };
337
+
338
+ processTags();
339
+ }, [source.tags, shikiTheme]);
340
+
341
+ // Highlight PDS API snippets when source or theme changes
342
+ useEffect(() => {
343
+ if (!source.pdsApiCalls || source.pdsApiCalls.length === 0) {
344
+ setHighlightedPdsApiCalls([]);
345
+ return;
346
+ }
347
+
348
+ const highlightCode = async (code) => {
349
+ if (!code) return '';
350
+ const highlighter = shikiRef.current || await loadShiki();
351
+ if (highlighter) {
352
+ try {
353
+ return highlighter.codeToHtml(code, { lang: 'javascript', theme: shikiTheme });
354
+ } catch (err) {
355
+ return `<pre><code>${escapeHtml(code)}</code></pre>`;
356
+ }
357
+ }
358
+ return `<pre><code>${escapeHtml(code)}</code></pre>`;
359
+ };
360
+
361
+ const processPdsApiCalls = async () => {
362
+ const highlighted = await Promise.all(
363
+ source.pdsApiCalls.map(async (call, index) => ({
364
+ id: call.id ?? index,
365
+ heading: call.heading,
366
+ label: call.label,
367
+ code: await highlightCode(call.code)
368
+ }))
369
+ );
370
+ setHighlightedPdsApiCalls(highlighted);
371
+ };
372
+
373
+ processPdsApiCalls();
374
+ }, [source.pdsApiCalls, shikiTheme]);
375
+
305
376
  useChannel({
306
377
  [EVENTS.UPDATE_HTML]: (payload) => {
307
378
  if (typeof payload === 'string') {
308
- setSource({ markup: payload || '', forms: [], omniboxes: [], treeviews: [], fabs: [] });
379
+ setSource({ markup: payload || '', forms: [], omniboxes: [], treeviews: [], tags: [], fabs: [], pdsApiCalls: [] });
309
380
  return;
310
381
  }
311
382
 
@@ -315,18 +386,20 @@ export const Panel = ({ active }) => {
315
386
  forms: Array.isArray(payload.forms) ? payload.forms : [],
316
387
  omniboxes: Array.isArray(payload.omniboxes) ? payload.omniboxes : [],
317
388
  treeviews: Array.isArray(payload.treeviews) ? payload.treeviews : [],
318
- fabs: Array.isArray(payload.fabs) ? payload.fabs : []
389
+ tags: Array.isArray(payload.tags) ? payload.tags : [],
390
+ fabs: Array.isArray(payload.fabs) ? payload.fabs : [],
391
+ pdsApiCalls: Array.isArray(payload.pdsApiCalls) ? payload.pdsApiCalls : []
319
392
  });
320
393
  return;
321
394
  }
322
395
 
323
- setSource({ markup: '', forms: [], omniboxes: [], treeviews: [], fabs: [] });
396
+ setSource({ markup: '', forms: [], omniboxes: [], treeviews: [], tags: [], fabs: [], pdsApiCalls: [] });
324
397
  }
325
398
  });
326
399
 
327
400
  // Request HTML update when panel becomes active
328
401
  React.useEffect(() => {
329
- if (active && !source.markup && source.forms.length === 0 && source.omniboxes.length === 0 && source.treeviews.length === 0 && source.fabs.length === 0) {
402
+ if (active && !source.markup && source.forms.length === 0 && source.omniboxes.length === 0 && source.treeviews.length === 0 && source.tags.length === 0 && source.fabs.length === 0 && source.pdsApiCalls.length === 0) {
330
403
  // Trigger a re-extraction by emitting a request event
331
404
  // The decorator will pick this up on the next render cycle
332
405
  const container = document.querySelector('#storybook-root');
@@ -338,7 +411,7 @@ export const Panel = ({ active }) => {
338
411
  }, 100);
339
412
  }
340
413
  }
341
- }, [active, source.markup, source.forms.length, source.omniboxes.length, source.treeviews.length, source.fabs.length]);
414
+ }, [active, source.markup, source.forms.length, source.omniboxes.length, source.treeviews.length, source.tags.length, source.fabs.length, source.pdsApiCalls.length]);
342
415
 
343
416
  const copyToClipboard = useCallback(async () => {
344
417
  try {
@@ -355,9 +428,11 @@ export const Panel = ({ active }) => {
355
428
  const hasforms = source.forms.length > 0;
356
429
  const hasOmniboxes = source.omniboxes.length > 0;
357
430
  const hasTreeviews = source.treeviews.length > 0;
431
+ const hasTags = source.tags.length > 0;
358
432
  const hasFabs = source.fabs.length > 0;
433
+ const hasPdsApiCalls = source.pdsApiCalls.length > 0;
359
434
 
360
- if (!hasMarkup && !hasforms && !hasOmniboxes && !hasTreeviews && !hasFabs) {
435
+ if (!hasMarkup && !hasforms && !hasOmniboxes && !hasTreeviews && !hasTags && !hasFabs && !hasPdsApiCalls) {
361
436
  return (
362
437
  <Container>
363
438
  <EmptyState>
@@ -498,6 +573,52 @@ export const Panel = ({ active }) => {
498
573
  );
499
574
  })}
500
575
 
576
+ {hasTags && source.tags.map((sourceTags, index) => {
577
+ const key = sourceTags.id ?? index;
578
+ const highlightedTag = highlightedTags[index];
579
+ const heading = source.tags.length > 1 ? (sourceTags.label || `Tags ${index + 1}`) : 'pds-tags';
580
+
581
+ return (
582
+ <SectionWrapper key={key}>
583
+ <SectionHeading>{heading}</SectionHeading>
584
+
585
+ {sourceTags.options && (
586
+ <>
587
+ <Subheading>options</Subheading>
588
+ <CodeBlock
589
+ $compact
590
+ dangerouslySetInnerHTML={{
591
+ __html: highlightedTag?.options || `<pre><code>${escapeHtml(sourceTags.options)}</code></pre>`
592
+ }}
593
+ />
594
+ </>
595
+ )}
596
+ </SectionWrapper>
597
+ );
598
+ })}
599
+
600
+ {hasPdsApiCalls && source.pdsApiCalls.map((sourceCall, index) => {
601
+ const key = sourceCall.id ?? index;
602
+ const highlightedCall = highlightedPdsApiCalls[index];
603
+ const heading = sourceCall.heading || 'PDS API';
604
+
605
+ return (
606
+ <SectionWrapper key={key}>
607
+ <SectionHeading>{heading}</SectionHeading>
608
+
609
+ {sourceCall.label && <Subheading>{sourceCall.label}</Subheading>}
610
+ {sourceCall.code && (
611
+ <CodeBlock
612
+ $compact
613
+ dangerouslySetInnerHTML={{
614
+ __html: highlightedCall?.code || `<pre><code>${escapeHtml(sourceCall.code)}</code></pre>`
615
+ }}
616
+ />
617
+ )}
618
+ </SectionWrapper>
619
+ );
620
+ })}
621
+
501
622
 
502
623
  {hasMarkup && (
503
624
  <CopyButton
@@ -157,6 +157,48 @@ function serializeForDisplay(value) {
157
157
  }
158
158
  }
159
159
 
160
+ function collectPdsApiCalls(container) {
161
+ if (!container) return [];
162
+
163
+ const nodes = Array.from(container.querySelectorAll('*'));
164
+
165
+ return nodes
166
+ .map((element, index) => {
167
+ const source =
168
+ element.pdsCodeSource ||
169
+ element.pdsSource ||
170
+ element.dataset?.pdsCodeSource ||
171
+ element.getAttribute?.('data-pds-code-source') ||
172
+ '';
173
+
174
+ if (!source || typeof source !== 'string' || !source.trim()) {
175
+ return null;
176
+ }
177
+
178
+ const heading =
179
+ element.pdsCodeHeading ||
180
+ element.pdsHeading ||
181
+ element.dataset?.pdsCodeHeading ||
182
+ element.getAttribute?.('data-pds-code-heading') ||
183
+ 'PDS API';
184
+
185
+ const label =
186
+ element.pdsCodeLabel ||
187
+ element.pdsLabel ||
188
+ element.dataset?.pdsCodeLabel ||
189
+ element.getAttribute?.('data-pds-code-label') ||
190
+ null;
191
+
192
+ return {
193
+ id: index,
194
+ heading,
195
+ label,
196
+ code: source,
197
+ };
198
+ })
199
+ .filter(Boolean);
200
+ }
201
+
160
202
  /**
161
203
  * Generate realistic source code for pds-form elements
162
204
  */
@@ -273,6 +315,39 @@ function generatePdsTreeviewMarkup(treeviewElement) {
273
315
  return `<pds-treeview${formattedAttrs}></pds-treeview>`;
274
316
  }
275
317
 
318
+ /**
319
+ * Generate realistic source code for pds-tags elements
320
+ */
321
+ function generatePdsTagsMarkup(tagsElement) {
322
+ const attrs = [];
323
+
324
+ const stringAttrs = ['name', 'placeholder', 'value'];
325
+ stringAttrs.forEach((attr) => {
326
+ const value = tagsElement.getAttribute(attr);
327
+ if (value !== null && value !== undefined && value !== '') {
328
+ attrs.push(`${attr}="${value}"`);
329
+ }
330
+ });
331
+
332
+ if (tagsElement.hasAttribute('required')) {
333
+ attrs.push('required');
334
+ }
335
+
336
+ if (tagsElement.hasAttribute('disabled')) {
337
+ attrs.push('disabled');
338
+ }
339
+
340
+ if (tagsElement.options || tagsElement.settings) {
341
+ attrs.push('.options=${options}');
342
+ }
343
+
344
+ const formattedAttrs = attrs.length > 0
345
+ ? '\n ' + attrs.join('\n ') + '\n'
346
+ : '';
347
+
348
+ return `<pds-tags${formattedAttrs}></pds-tags>`;
349
+ }
350
+
276
351
  /**
277
352
  * Generate realistic source code for pds-fab elements
278
353
  */
@@ -320,15 +395,17 @@ export const withHTMLExtractor = (storyFn, context) => {
320
395
  // Try to get HTML from the story container
321
396
  const container = document.querySelector('#storybook-root');
322
397
  if (container) {
323
- // Check if this story has pds-form, pds-omnibox, pds-treeview, or pds-fab elements
398
+ // Check if this story has pds-form, pds-omnibox, pds-treeview, pds-tags, or pds-fab elements
324
399
  const pdsFormElements = Array.from(container.querySelectorAll('pds-form'));
325
400
  const pdsOmniboxElements = Array.from(container.querySelectorAll('pds-omnibox'));
326
401
  const pdsTreeviewElements = Array.from(container.querySelectorAll('pds-treeview'));
402
+ const pdsTagsElements = Array.from(container.querySelectorAll('pds-tags'));
327
403
  const pdsFabElements = Array.from(container.querySelectorAll('pds-fab'));
328
404
  const hasSpecialElements =
329
405
  pdsFormElements.length > 0 ||
330
406
  pdsOmniboxElements.length > 0 ||
331
407
  pdsTreeviewElements.length > 0 ||
408
+ pdsTagsElements.length > 0 ||
332
409
  pdsFabElements.length > 0;
333
410
 
334
411
  if (hasSpecialElements) {
@@ -360,6 +437,11 @@ export const withHTMLExtractor = (storyFn, context) => {
360
437
  markup += generatePdsTreeviewMarkup(treeview);
361
438
  });
362
439
 
440
+ // Add pds-tags markup
441
+ pdsTagsElements.forEach(tags => {
442
+ markup += generatePdsTagsMarkup(tags);
443
+ });
444
+
363
445
  // Add pds-fab markup
364
446
  pdsFabElements.forEach(fab => {
365
447
  markup += generatePdsFabMarkup(fab);
@@ -442,6 +524,30 @@ export const withHTMLExtractor = (storyFn, context) => {
442
524
  };
443
525
  });
444
526
 
527
+ const tags = pdsTagsElements
528
+ .map((tagElement, index) => {
529
+ const label =
530
+ tagElement.getAttribute?.('id') ||
531
+ tagElement.getAttribute?.('name') ||
532
+ (pdsTagsElements.length > 1 ? `Tags ${index + 1}` : 'Tags');
533
+
534
+ const optionsSource =
535
+ tagElement.getAttribute?.('data-options-source') ||
536
+ tagElement.dataset?.optionsSource ||
537
+ null;
538
+
539
+ const options =
540
+ optionsSource ||
541
+ serializeForDisplay(tagElement.options || tagElement.settings) ||
542
+ 'const options = [];';
543
+
544
+ return {
545
+ id: index,
546
+ label,
547
+ options
548
+ };
549
+ });
550
+
445
551
  const fabs = pdsFabElements
446
552
  .map((fab, index) => {
447
553
  const label =
@@ -463,12 +569,16 @@ export const withHTMLExtractor = (storyFn, context) => {
463
569
  })
464
570
  .filter((entry) => entry.satellites);
465
571
 
572
+ const pdsApiCalls = collectPdsApiCalls(container);
573
+
466
574
  channel.emit(EVENTS.UPDATE_HTML, {
467
575
  markup: html || '',
468
576
  forms,
469
577
  omniboxes,
470
578
  treeviews,
471
- fabs
579
+ tags,
580
+ fabs,
581
+ pdsApiCalls
472
582
  });
473
583
  }
474
584
  };
@@ -1478,6 +1478,7 @@ const preview = {
1478
1478
  },
1479
1479
  options: {
1480
1480
  storySort: {
1481
+ method: 'alphabetical',
1481
1482
  order: [
1482
1483
  'About PDS',
1483
1484
  ['What Is PDS', 'Getting Started'],
@@ -1488,7 +1489,7 @@ const preview = {
1488
1489
  'Foundations',
1489
1490
  ['Colors', 'Typography', 'HTML Defaults', 'Icons', 'Spacing', 'Smart Surfaces'],
1490
1491
  'Primitives',
1491
- ['Buttons', 'Forms', 'Form Groups', 'Alerts', 'Badges', 'Cards', 'Tables', 'Media', 'Accordion'],
1492
+ ['Buttons', 'Forms', 'Form Groups', 'Alerts', 'Badges', 'Cards', 'Articles', 'Tables', 'Media', 'Accordion'],
1492
1493
  'Layout',
1493
1494
  ['Overview', 'System'],
1494
1495
  'Utilities',
@@ -1498,7 +1499,7 @@ const preview = {
1498
1499
  'Enhancements',
1499
1500
  ['Mesh Gradients', 'Interactive States', 'Toggles', 'Dropdowns', 'Range Sliders', 'Required Fields'],
1500
1501
  'Components',
1501
- ['pds-form', 'Pds Icon', 'Pds Drawer', 'Pds Toaster', 'Pds Tabstrip', 'Pds Splitpanel', 'Pds Scrollrow', 'Pds Richtext', 'Pds Upload'],
1502
+ ['*'],
1502
1503
  'Reference'
1503
1504
  ],
1504
1505
  'About PDS',
@@ -1506,7 +1507,7 @@ const preview = {
1506
1507
  'Foundations',
1507
1508
  ['Colors', 'Typography', 'HTML Defaults', 'Icons', 'Spacing', 'Smart Surfaces'],
1508
1509
  'Primitives',
1509
- ['Buttons', 'Forms', 'Form Groups', 'Alerts', 'Badges', 'Cards', 'Tables', 'Media', 'Accordion'],
1510
+ ['Buttons', 'Forms', 'Form Groups', 'Alerts', 'Badges', 'Cards', 'Articles', 'Tables', 'Media', 'Accordion'],
1510
1511
  'Layout',
1511
1512
  ['Overview', 'System'],
1512
1513
  'Utilities',
@@ -1516,7 +1517,7 @@ const preview = {
1516
1517
  'Enhancements',
1517
1518
  ['Mesh Gradients', 'Interactive States', 'Toggles', 'Dropdowns', 'Range Sliders', 'Required Fields'],
1518
1519
  'Components',
1519
- ['pds-form', 'Pds Icon', 'Pds Drawer', 'Pds Toaster', 'Pds Tabstrip', 'Pds Splitpanel', 'Pds Scrollrow', 'Pds Richtext', 'Pds Upload'],
1520
+ ['*'],
1520
1521
  'Reference',
1521
1522
  '*'
1522
1523
  ]