@pure-ds/storybook 0.4.16 → 0.4.17

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 (51) hide show
  1. package/.storybook/addons/html-preview/Panel.jsx +71 -20
  2. package/dist/pds-reference.json +2 -7
  3. package/package.json +2 -2
  4. package/public/assets/js/app.js +617 -10565
  5. package/public/assets/js/lit.js +3 -1048
  6. package/public/assets/js/pds.js +396 -7354
  7. package/public/assets/pds/components/pds-calendar.js +1 -1
  8. package/public/assets/pds/custom-elements.json +263 -18
  9. package/public/assets/pds/pds-runtime-config.json +1 -1
  10. package/public/assets/pds/styles/pds-components.css +83 -221
  11. package/public/assets/pds/styles/pds-components.css.js +166 -442
  12. package/public/assets/pds/styles/pds-styles.css +240 -437
  13. package/public/assets/pds/styles/pds-styles.css.js +479 -881
  14. package/public/assets/pds/styles/pds-utilities.css +151 -214
  15. package/public/assets/pds/styles/pds-utilities.css.js +302 -428
  16. package/src/js/pds-core/pds-generator.js +88 -38
  17. package/src/js/pds-core/pds-ontology.js +1 -1
  18. package/stories/components/PdsCalendar.stories.js +2 -2
  19. package/stories/components/PdsDrawer.stories.js +15 -15
  20. package/stories/components/PdsJsonform.stories.js +78 -0
  21. package/stories/components/PdsRichtext.stories.js +4 -17
  22. package/stories/components/PdsScrollrow.stories.js +224 -72
  23. package/stories/components/PdsSplitpanel.stories.js +63 -28
  24. package/stories/components/PdsTabstrip.stories.js +7 -7
  25. package/stories/enhancements/Accordion.stories.js +2 -2
  26. package/stories/enhancements/Dropdowns.stories.js +13 -10
  27. package/stories/enhancements/RangeSliders.stories.js +9 -9
  28. package/stories/enhancements/RequiredFields.stories.js +8 -8
  29. package/stories/enhancements/Toggles.stories.js +45 -36
  30. package/stories/enhancements/_enhancement-header.js +2 -2
  31. package/stories/foundations/Colors.stories.js +13 -13
  32. package/stories/foundations/HTMLDefaults.stories.js +4 -4
  33. package/stories/foundations/Icons.stories.js +123 -288
  34. package/stories/foundations/MeshGradients.stories.js +161 -250
  35. package/stories/foundations/SmartSurfaces.stories.js +147 -64
  36. package/stories/foundations/Spacing.stories.js +30 -30
  37. package/stories/foundations/Typography.stories.js +352 -723
  38. package/stories/foundations/ZIndex.stories.js +124 -141
  39. package/stories/layout/LayoutOverview.stories.js +343 -250
  40. package/stories/layout/LayoutSystem.stories.js +60 -76
  41. package/stories/patterns/InteractiveStates.stories.js +29 -29
  42. package/stories/patterns/Utilities.stories.js +17 -5
  43. package/stories/primitives/Alerts.stories.js +6 -6
  44. package/stories/primitives/Cards.stories.js +22 -11
  45. package/stories/primitives/Forms.stories.js +17 -8
  46. package/stories/primitives/Media.stories.js +23 -20
  47. package/stories/utilities/Backdrop.stories.js +68 -27
  48. package/stories/utils/PdsAsk.stories.js +1 -1
  49. package/public/assets/js/app.js.map +0 -7
  50. package/public/assets/js/lit.js.map +0 -7
  51. package/public/assets/js/pds.js.map +0 -7
@@ -1149,6 +1149,8 @@ export class Generator {
1149
1149
  mesh,
1150
1150
  ].join("");
1151
1151
 
1152
+ // Dark mode selector only - .surface-inverse is handled separately in utilities
1153
+ // to avoid inheriting the full dark palette (which would override --color-surface-inverse)
1152
1154
  return `html[data-theme="dark"] {\n${body}}\n`;
1153
1155
  }
1154
1156
 
@@ -1589,12 +1591,13 @@ html[data-theme="dark"] .liquid-glass {
1589
1591
 
1590
1592
  :where(blockquote) {
1591
1593
  margin: 0 0 var(--spacing-4) 0;
1592
- padding: var(--spacing-4) var(--spacing-6);
1594
+ padding: var(--spacing-6) var(--spacing-8);
1593
1595
  border-left: 4px solid var(--color-primary-500);
1594
- background-color: var(--color-surface-subtle);
1595
- border-radius: var(--radius-md);
1596
- font-style: italic;
1597
- color: var(--color-text-secondary);
1596
+ background-color: var(--color-surface-elevated);
1597
+ border-radius: var(--radius-none);
1598
+ font-size: var(--font-size-lg);
1599
+ line-height: var(--line-height-relaxed);
1600
+ color: var(--color-text-primary);
1598
1601
 
1599
1602
  :where(p):last-child {
1600
1603
  margin-bottom: 0;
@@ -1602,14 +1605,10 @@ html[data-theme="dark"] .liquid-glass {
1602
1605
 
1603
1606
  :where(cite) {
1604
1607
  display: block;
1605
- margin-top: var(--spacing-2);
1606
- font-size: var(--font-size-sm);
1608
+ margin-top: var(--spacing-4);
1609
+ font-size: var(--font-size-base);
1607
1610
  font-style: normal;
1608
- color: var(--color-text-tertiary);
1609
-
1610
- &::before {
1611
- content: "— ";
1612
- }
1611
+ color: var(--color-primary-500);
1613
1612
  }
1614
1613
  }
1615
1614
 
@@ -4447,40 +4446,27 @@ ${this.#generateBorderGradientUtilities()}
4447
4446
  }
4448
4447
 
4449
4448
 
4450
- /* Inverse surface (dark) using PDS tokens; text/icons inherit currentColor */
4449
+ /*
4450
+ * SURFACE-INVERSE: Local Theme Context Flip
4451
+ *
4452
+ * We can't simply add .surface-inverse to the dark mode selector because that would
4453
+ * also apply the dark color PALETTE (grays, surfaces, etc.), which would override
4454
+ * --color-surface-inverse itself. Instead, we duplicate only the SEMANTIC tokens.
4455
+ *
4456
+ * Light theme .surface-inverse → dark semantic tokens
4457
+ * Dark theme .surface-inverse → light semantic tokens (flip back)
4458
+ */
4459
+
4460
+ /* Surface-inverse visual properties (shared, uses smart surface tokens) */
4451
4461
  .surface-inverse {
4452
4462
  background-color: var(--color-surface-inverse);
4453
- /* Ensure foregrounds inside use the correct smart-surface tokens */
4454
4463
  color: var(--surface-inverse-text);
4455
- --color-text-primary: var(--surface-inverse-text);
4456
- --color-text-secondary: var(--surface-inverse-text-secondary);
4457
- --color-text-muted: var(--surface-inverse-text-muted);
4458
- /* Ensure code/pre and other muted surfaces have contrast on inverse */
4459
- --color-surface-muted: rgba(255, 255, 255, 0.08);
4460
- /* Optional: adjust borders/shadows if utilities/components read these */
4461
- --color-border: var(--surface-inverse-border);
4462
4464
 
4463
4465
  pds-icon {
4464
4466
  color: var(--surface-inverse-icon);
4465
4467
  }
4466
4468
 
4467
- /* Default and secondary buttons on inverse - semi-transparent glass effect */
4468
- & button:not(.btn-primary):not(.btn-outline):not(.btn-danger):not(.btn-success):not(.btn-warning),
4469
- & .btn-secondary {
4470
- background-color: rgba(255, 255, 255, 0.12);
4471
- color: var(--surface-inverse-text);
4472
- border-color: rgba(255, 255, 255, 0.25);
4473
-
4474
- &:hover {
4475
- background-color: rgba(255, 255, 255, 0.2);
4476
- }
4477
-
4478
- &:active {
4479
- background-color: rgba(255, 255, 255, 0.28);
4480
- }
4481
- }
4482
-
4483
- /* Ensure btn-primary stays vibrant on inverse */
4469
+ /* btn-primary stays vibrant in any context */
4484
4470
  & .btn-primary {
4485
4471
  background-color: var(--color-primary-500);
4486
4472
  border-color: var(--color-primary-500);
@@ -4493,6 +4479,70 @@ ${this.#generateBorderGradientUtilities()}
4493
4479
  }
4494
4480
  }
4495
4481
 
4482
+ /* Light-mode inverse: apply dark semantic tokens */
4483
+ html:not([data-theme="dark"]) .surface-inverse {
4484
+ --color-text-primary: var(--color-gray-100);
4485
+ --color-text-secondary: var(--color-gray-300);
4486
+ --color-text-muted: var(--color-gray-400);
4487
+ --color-border: var(--color-gray-700);
4488
+ --color-input-bg: var(--color-gray-800);
4489
+ --color-input-disabled-bg: var(--color-gray-900);
4490
+ --color-input-disabled-text: var(--color-gray-600);
4491
+ --color-code-bg: var(--color-gray-800);
4492
+ --color-surface-muted: rgba(255, 255, 255, 0.08);
4493
+
4494
+ & button:not(.btn-primary):not(.btn-outline):not(.btn-danger):not(.btn-success):not(.btn-warning),
4495
+ & .btn-secondary {
4496
+ background-color: rgba(255, 255, 255, 0.12);
4497
+ color: var(--surface-inverse-text);
4498
+ border-color: rgba(255, 255, 255, 0.25);
4499
+
4500
+ &:hover { background-color: rgba(255, 255, 255, 0.2); }
4501
+ &:active { background-color: rgba(255, 255, 255, 0.28); }
4502
+ }
4503
+
4504
+ & select {
4505
+ background-color: rgba(255, 255, 255, 0.1);
4506
+ color: var(--surface-inverse-text);
4507
+ }
4508
+
4509
+ & a:not([class*="btn"]) {
4510
+ color: var(--color-primary-300, #7dd3fc);
4511
+ }
4512
+ }
4513
+
4514
+ /* Dark-mode inverse: flip back to light semantic tokens */
4515
+ html[data-theme="dark"] .surface-inverse {
4516
+ --color-text-primary: var(--color-gray-900);
4517
+ --color-text-secondary: var(--color-gray-600);
4518
+ --color-text-muted: var(--color-gray-600);
4519
+ --color-border: var(--color-gray-300);
4520
+ --color-input-bg: var(--color-surface-base);
4521
+ --color-input-disabled-bg: var(--color-gray-50);
4522
+ --color-input-disabled-text: var(--color-gray-500);
4523
+ --color-code-bg: var(--color-gray-100);
4524
+ --color-surface-muted: var(--color-gray-100);
4525
+
4526
+ & button:not(.btn-primary):not(.btn-outline):not(.btn-danger):not(.btn-success):not(.btn-warning),
4527
+ & .btn-secondary {
4528
+ background-color: rgba(0, 0, 0, 0.06);
4529
+ color: var(--surface-inverse-text);
4530
+ border-color: rgba(0, 0, 0, 0.15);
4531
+
4532
+ &:hover { background-color: rgba(0, 0, 0, 0.1); }
4533
+ &:active { background-color: rgba(0, 0, 0, 0.15); }
4534
+ }
4535
+
4536
+ & select {
4537
+ background-color: #ffffff;
4538
+ color: var(--surface-inverse-text);
4539
+ }
4540
+
4541
+ & a:not([class*="btn"]) {
4542
+ color: var(--color-primary-600, #0284c7);
4543
+ }
4544
+ }
4545
+
4496
4546
  /* Shadow utilities */
4497
4547
  .shadow-sm {
4498
4548
  box-shadow: var(--shadow-sm);
@@ -380,7 +380,7 @@ export const ontology = {
380
380
  utilities: {
381
381
  text: {
382
382
  alignment: [".text-left", ".text-center", ".text-right"],
383
- color: [".text-muted", ".text-primary", ".text-success", ".text-warning", ".text-danger", ".text-info"],
383
+ color: [".text-muted"],
384
384
  overflow: [".truncate"]
385
385
  },
386
386
  backdrop: {
@@ -173,7 +173,7 @@ export const EventTypes = {
173
173
  }, 0);
174
174
 
175
175
  return html`
176
- <div class="flex flex-col gap-lg">
176
+ <div class="stack-lg">
177
177
  <pds-calendar id="event-types-calendar"></pds-calendar>
178
178
 
179
179
  <div class="card">
@@ -234,7 +234,7 @@ export const DynamicEvents = {
234
234
  }, 0);
235
235
 
236
236
  return html`
237
- <div class="flex flex-col gap-lg">
237
+ <div class="stack-lg">
238
238
  <div class="card">
239
239
  <h3>Add Events Dynamically</h3>
240
240
  <div class="flex gap-md items-end">
@@ -61,7 +61,7 @@ export const Default = {
61
61
  <h2>Drawer from ${args.position}</h2>
62
62
  </div>
63
63
 
64
- <div slot="drawer-content" class="flex flex-col gap-md">
64
+ <div slot="drawer-content" class="stack-md">
65
65
  <article class="card">
66
66
  <h4>About this Drawer</h4>
67
67
  <p>This drawer slides from the <strong>${args.position}</strong> edge of the screen. Drawers are perfect for:</p>
@@ -75,7 +75,7 @@ export const Default = {
75
75
 
76
76
  <article class="card surface-elevated">
77
77
  <h4>Quick Actions</h4>
78
- <nav class="flex flex-col gap-sm">
78
+ <nav class="stack-sm">
79
79
  <button class="btn-outline">
80
80
  <pds-icon icon="download"></pds-icon>
81
81
  <span>Download Report</span>
@@ -145,12 +145,12 @@ export const AllPositions = () => {
145
145
  <pds-icon icon="list" size="lg"></pds-icon>
146
146
  <h2>Main Navigation</h2>
147
147
  </div>
148
- <div slot="drawer-content" class="flex flex-col gap-md">
148
+ <div slot="drawer-content" class="stack-md">
149
149
  <p>
150
150
  <strong>Use case:</strong> Primary navigation menu for web applications
151
151
  </p>
152
152
 
153
- <nav class="flex flex-col gap-sm">
153
+ <nav class="stack-sm">
154
154
  <button class="btn-outline">
155
155
  <pds-icon icon="house"></pds-icon>
156
156
  <span>Dashboard</span>
@@ -194,7 +194,7 @@ export const AllPositions = () => {
194
194
  <pds-icon icon="x" label="Close"></pds-icon>
195
195
  </button>
196
196
  </div>
197
- <div slot="drawer-content" class="flex flex-col gap-md">
197
+ <div slot="drawer-content" class="stack-md">
198
198
  <p>
199
199
  <strong>Use case:</strong> Filters, detail panels, or property inspectors
200
200
  </p>
@@ -223,7 +223,7 @@ export const AllPositions = () => {
223
223
 
224
224
  <article class="card surface-elevated">
225
225
  <label>
226
- <span>Sort By</span>
226
+ <span data-label>Sort By</span>
227
227
  <select>
228
228
  <option>Date Created (Newest)</option>
229
229
  <option>Date Created (Oldest)</option>
@@ -253,12 +253,12 @@ export const AllPositions = () => {
253
253
  <h2>Notifications</h2>
254
254
  <span class="badge badge-primary">3 new</span>
255
255
  </div>
256
- <div slot="drawer-content" class="flex flex-col gap-md">
256
+ <div slot="drawer-content" class="stack-md">
257
257
  <p>
258
258
  <strong>Use case:</strong> Notification center or announcement banners
259
259
  </p>
260
260
 
261
- <div class="flex flex-col gap-md">
261
+ <div class="stack-md">
262
262
  <article class="card surface-elevated">
263
263
  <div class="flex gap-md items-start">
264
264
  <div class="badge badge-success">
@@ -323,7 +323,7 @@ export const AllPositions = () => {
323
323
  <pds-icon icon="toolbox" size="lg"></pds-icon>
324
324
  <h2>Quick Actions</h2>
325
325
  </div>
326
- <div slot="drawer-content" class="flex flex-col gap-md">
326
+ <div slot="drawer-content" class="stack-md">
327
327
  <p>
328
328
  <strong>Use case:</strong> Command palette, quick actions, or contextual toolbars
329
329
  </p>
@@ -390,7 +390,7 @@ export const NavigationDrawer = () => {
390
390
  <h2>Navigation</h2>
391
391
  </div>
392
392
 
393
- <nav slot="drawer-content" class="flex flex-col gap-sm">
393
+ <nav slot="drawer-content" class="stack-sm">
394
394
  <button class="btn-outline">
395
395
  <pds-icon icon="house"></pds-icon>
396
396
  <span>Home</span>
@@ -458,19 +458,19 @@ export const SettingsDrawer = () => {
458
458
  <h2>Settings</h2>
459
459
  </div>
460
460
 
461
- <div slot="drawer-content" class="flex flex-col gap-md">
461
+ <div slot="drawer-content" class="stack-md">
462
462
  <article class="card">
463
463
  <fieldset>
464
464
  <legend>Profile Settings</legend>
465
465
  <label>
466
- <span>Username</span>
466
+ <span data-label>Username</span>
467
467
  <div class="input-icon">
468
468
  <pds-icon icon="user"></pds-icon>
469
469
  <input type="text" value="john_doe" placeholder="Enter your username">
470
470
  </div>
471
471
  </label>
472
472
  <label>
473
- <span>Email</span>
473
+ <span data-label>Email</span>
474
474
  <div class="input-icon">
475
475
  <pds-icon icon="envelope"></pds-icon>
476
476
  <input type="email" value="john@example.com" placeholder="your.email@example.com">
@@ -555,7 +555,7 @@ export const DetailDrawer = () => {
555
555
  </button>
556
556
  </div>
557
557
 
558
- <div slot="drawer-content" class="flex flex-col gap-md">
558
+ <div slot="drawer-content" class="stack-md">
559
559
  <div class="card border-gradient flex items-center justify-center">
560
560
  <pds-icon icon="image" size="xl"></pds-icon>
561
561
  </div>
@@ -579,7 +579,7 @@ export const DetailDrawer = () => {
579
579
 
580
580
  <article class="card surface-elevated">
581
581
  <h4>Recent Activity</h4>
582
- <div class="flex flex-col gap-md">
582
+ <div class="stack-md">
583
583
  <div class="flex gap-sm">
584
584
  <pds-icon icon="check" class="icon-primary"></pds-icon>
585
585
  <div>
@@ -1927,3 +1927,81 @@ export const RootThreeColumnGrid = {
1927
1927
  `;
1928
1928
  }
1929
1929
  };
1930
+
1931
+ export const EnumWithEnumNames = {
1932
+ name: 'Enum with enumNames',
1933
+ parameters: {
1934
+ docs: {
1935
+ description: {
1936
+ story: `Use \`enumNames\` to provide human-friendly display labels for enum values.
1937
+
1938
+ This is useful when you want to store technical values (like language codes or IDs) while showing user-friendly labels.
1939
+
1940
+ \`\`\`javascript
1941
+ const schema = {
1942
+ properties: {
1943
+ language: {
1944
+ type: 'string',
1945
+ title: 'Language',
1946
+ enum: ['en', 'es', 'fr', 'de', 'zh', 'ja'], // Values stored
1947
+ enumNames: ['English', 'Spanish', 'French', 'German', 'Chinese', 'Japanese'] // Labels shown
1948
+ }
1949
+ }
1950
+ };
1951
+ \`\`\`
1952
+
1953
+ The \`enumNames\` array must match the length and order of the \`enum\` array. Works with select dropdowns, radio buttons, and checkbox groups.`
1954
+ }
1955
+ }
1956
+ },
1957
+ render: () => {
1958
+ const schema = {
1959
+ type: 'object',
1960
+ title: 'Preferences',
1961
+ properties: {
1962
+ language: {
1963
+ type: 'string',
1964
+ title: 'Language',
1965
+ enum: ['en', 'es', 'fr', 'de', 'zh', 'ja'],
1966
+ enumNames: ['English', 'Spanish', 'French', 'German', 'Chinese', 'Japanese'],
1967
+ default: 'en'
1968
+ },
1969
+ country: {
1970
+ type: 'string',
1971
+ title: 'Country',
1972
+ enum: ['US', 'GB', 'CA', 'AU', 'DE', 'FR'],
1973
+ enumNames: ['United States', 'United Kingdom', 'Canada', 'Australia', 'Germany', 'France']
1974
+ },
1975
+ priority: {
1976
+ type: 'string',
1977
+ title: 'Priority Level',
1978
+ enum: ['p1', 'p2', 'p3', 'p4'],
1979
+ enumNames: ['🔴 Critical', '🟠 High', '🟡 Medium', '🟢 Low'],
1980
+ default: 'p3'
1981
+ },
1982
+ interests: {
1983
+ type: 'array',
1984
+ title: 'Interests (checkbox group)',
1985
+ items: {
1986
+ type: 'string',
1987
+ enum: ['dev', 'design', 'pm', 'qa', 'devops'],
1988
+ enumNames: ['Development', 'Design', 'Project Management', 'Quality Assurance', 'DevOps']
1989
+ },
1990
+ uniqueItems: true
1991
+ }
1992
+ }
1993
+ };
1994
+
1995
+ const uiSchema = {
1996
+ '/priority': { 'ui:widget': 'radio' }
1997
+ };
1998
+
1999
+ return html`
2000
+ <pds-jsonform
2001
+ .jsonSchema=${schema}
2002
+ .uiSchema=${uiSchema}
2003
+ @pw:submit=${(e) => toastFormData(e.detail)}
2004
+ ></pds-jsonform>
2005
+ `;
2006
+ }
2007
+ };
@@ -18,20 +18,7 @@ if (typeof window !== 'undefined') {
18
18
 
19
19
  // Minimal story-specific styles - only for demo-specific visuals not covered by PDS
20
20
  const richtextStoryStyles = html`
21
- <style>
22
- /* Avatar circle - demo-specific */
23
- .richtext-avatar {
24
- width: 3rem;
25
- height: 3rem;
26
- background: var(--color-primary);
27
- border-radius: var(--radius-full);
28
- display: flex;
29
- align-items: center;
30
- justify-content: center;
31
- color: var(--color-primary-contrast, #fff);
32
- flex-shrink: 0;
33
- }
34
- </style>
21
+
35
22
  `;
36
23
 
37
24
  const bindToastForms = (selector) => {
@@ -125,7 +112,7 @@ export const InForm = () => {
125
112
  ${richtextStoryStyles}
126
113
  <form class="richtext-form max-w-md stack-md">
127
114
  <label>
128
- <span>Blog Post Content</span>
115
+ <span data-label>Blog Post Content</span>
129
116
  <pds-richtext
130
117
  name="blog-content"
131
118
  value="<h3>My Blog Post</h3><p>Write your content here...</p>"
@@ -214,7 +201,7 @@ export const CommentEditor = () => {
214
201
  <div class="max-w-md stack-md">
215
202
  <article class="card surface-elevated">
216
203
  <div class="flex gap-sm">
217
- <div class="richtext-avatar">
204
+ <div class="story-richtext-avatar">
218
205
  <pds-icon icon="user"></pds-icon>
219
206
  </div>
220
207
  <div class="grow stack-sm">
@@ -259,7 +246,7 @@ export const MarkdownForm = () => {
259
246
  ${richtextStoryStyles}
260
247
  <form class="richtext-markdown-form max-w-md stack-md">
261
248
  <label>
262
- <span>Release Notes (Markdown)</span>
249
+ <span data-label>Release Notes (Markdown)</span>
263
250
  <pds-richtext
264
251
  name="release-notes"
265
252
  format="markdown"