@pure-ds/storybook 0.1.0

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 (129) hide show
  1. package/.storybook/addons/description/preview.js +15 -0
  2. package/.storybook/addons/description/register.js +60 -0
  3. package/.storybook/addons/html-preview/Panel.jsx +327 -0
  4. package/.storybook/addons/html-preview/constants.js +6 -0
  5. package/.storybook/addons/html-preview/preview.js +178 -0
  6. package/.storybook/addons/html-preview/register.js +16 -0
  7. package/.storybook/addons/pds-configurator/SearchTool.js +44 -0
  8. package/.storybook/addons/pds-configurator/Tool.js +30 -0
  9. package/.storybook/addons/pds-configurator/constants.js +9 -0
  10. package/.storybook/addons/pds-configurator/preview.js +159 -0
  11. package/.storybook/addons/pds-configurator/register.js +24 -0
  12. package/.storybook/docs.css +35 -0
  13. package/.storybook/htmlPreview.css +103 -0
  14. package/.storybook/htmlPreview.js +271 -0
  15. package/.storybook/main.js +160 -0
  16. package/.storybook/preview-body.html +48 -0
  17. package/.storybook/preview-head.html +11 -0
  18. package/.storybook/preview.js +1563 -0
  19. package/README.md +266 -0
  20. package/bin/index.js +40 -0
  21. package/dist/pds-reference.json +2101 -0
  22. package/package.json +45 -0
  23. package/pds.config.js +6 -0
  24. package/public/assets/css/app.css +1216 -0
  25. package/public/assets/data/auto-design-advanced.json +704 -0
  26. package/public/assets/data/auto-design-simple.json +123 -0
  27. package/public/assets/img/icon-512x512.png +0 -0
  28. package/public/assets/img/logo-trans.png +0 -0
  29. package/public/assets/img/logo.png +0 -0
  30. package/public/assets/js/app.js +15088 -0
  31. package/public/assets/js/app.js.map +7 -0
  32. package/public/assets/js/lit.js +1176 -0
  33. package/public/assets/js/lit.js.map +7 -0
  34. package/public/assets/js/pds.js +9801 -0
  35. package/public/assets/js/pds.js.map +7 -0
  36. package/public/assets/pds/components/pds-calendar.js +837 -0
  37. package/public/assets/pds/components/pds-drawer.js +857 -0
  38. package/public/assets/pds/components/pds-icon.js +338 -0
  39. package/public/assets/pds/components/pds-jsonform.js +1775 -0
  40. package/public/assets/pds/components/pds-richtext.js +1035 -0
  41. package/public/assets/pds/components/pds-scrollrow.js +331 -0
  42. package/public/assets/pds/components/pds-splitpanel.js +401 -0
  43. package/public/assets/pds/components/pds-tabstrip.js +251 -0
  44. package/public/assets/pds/components/pds-toaster.js +446 -0
  45. package/public/assets/pds/components/pds-upload.js +657 -0
  46. package/public/assets/pds/custom-elements.json +2003 -0
  47. package/public/assets/pds/icons/pds-icons.svg +498 -0
  48. package/public/assets/pds/pds-css-complete.json +1861 -0
  49. package/public/assets/pds/pds-runtime-config.json +11 -0
  50. package/public/assets/pds/pds.css-data.json +2152 -0
  51. package/public/assets/pds/styles/pds-components.css +1944 -0
  52. package/public/assets/pds/styles/pds-components.css.js +3895 -0
  53. package/public/assets/pds/styles/pds-primitives.css +352 -0
  54. package/public/assets/pds/styles/pds-primitives.css.js +711 -0
  55. package/public/assets/pds/styles/pds-styles.css +3761 -0
  56. package/public/assets/pds/styles/pds-styles.css.js +7529 -0
  57. package/public/assets/pds/styles/pds-tokens.css +699 -0
  58. package/public/assets/pds/styles/pds-tokens.css.js +1405 -0
  59. package/public/assets/pds/styles/pds-utilities.css +763 -0
  60. package/public/assets/pds/styles/pds-utilities.css.js +1533 -0
  61. package/public/assets/pds/vscode-custom-data.json +824 -0
  62. package/scripts/build-pds-reference.mjs +807 -0
  63. package/scripts/generate-stories.js +542 -0
  64. package/scripts/package-build.js +86 -0
  65. package/src/js/app.js +17 -0
  66. package/src/js/common/ask.js +208 -0
  67. package/src/js/common/common.js +20 -0
  68. package/src/js/common/font-loader.js +200 -0
  69. package/src/js/common/msg.js +90 -0
  70. package/src/js/lit.js +40 -0
  71. package/src/js/pds-core/pds-config.js +1162 -0
  72. package/src/js/pds-core/pds-enhancer-metadata.js +75 -0
  73. package/src/js/pds-core/pds-enhancers.js +357 -0
  74. package/src/js/pds-core/pds-enums.js +86 -0
  75. package/src/js/pds-core/pds-generator.js +5317 -0
  76. package/src/js/pds-core/pds-ontology.js +256 -0
  77. package/src/js/pds-core/pds-paths.js +109 -0
  78. package/src/js/pds-core/pds-query.js +571 -0
  79. package/src/js/pds-core/pds-registry.js +129 -0
  80. package/src/js/pds-core/pds.d.ts +129 -0
  81. package/src/js/pds.d.ts +408 -0
  82. package/src/js/pds.js +1579 -0
  83. package/src/pds-core/pds-api.js +105 -0
  84. package/stories/GettingStarted.md +96 -0
  85. package/stories/GettingStarted.stories.js +144 -0
  86. package/stories/WhatIsPDS.md +194 -0
  87. package/stories/WhatIsPDS.stories.js +144 -0
  88. package/stories/components/PdsCalendar.stories.js +263 -0
  89. package/stories/components/PdsDrawer.stories.js +623 -0
  90. package/stories/components/PdsIcon.stories.js +78 -0
  91. package/stories/components/PdsJsonform.stories.js +1444 -0
  92. package/stories/components/PdsRichtext.stories.js +367 -0
  93. package/stories/components/PdsScrollrow.stories.js +140 -0
  94. package/stories/components/PdsSplitpanel.stories.js +502 -0
  95. package/stories/components/PdsTabstrip.stories.js +442 -0
  96. package/stories/components/PdsToaster.stories.js +186 -0
  97. package/stories/components/PdsUpload.stories.js +66 -0
  98. package/stories/enhancements/Dropdowns.stories.js +185 -0
  99. package/stories/enhancements/InteractiveStates.stories.js +625 -0
  100. package/stories/enhancements/MeshGradients.stories.js +320 -0
  101. package/stories/enhancements/OpenGroups.stories.js +227 -0
  102. package/stories/enhancements/RangeSliders.stories.js +232 -0
  103. package/stories/enhancements/RequiredFields.stories.js +189 -0
  104. package/stories/enhancements/Toggles.stories.js +167 -0
  105. package/stories/foundations/Colors.stories.js +283 -0
  106. package/stories/foundations/Icons.stories.js +305 -0
  107. package/stories/foundations/SmartSurfaces.stories.js +367 -0
  108. package/stories/foundations/Spacing.stories.js +175 -0
  109. package/stories/foundations/Typography.stories.js +960 -0
  110. package/stories/foundations/ZIndex.stories.js +325 -0
  111. package/stories/patterns/BorderEffects.stories.js +72 -0
  112. package/stories/patterns/Layout.stories.js +99 -0
  113. package/stories/patterns/Utilities.stories.js +107 -0
  114. package/stories/primitives/Accordion.stories.js +359 -0
  115. package/stories/primitives/Alerts.stories.js +64 -0
  116. package/stories/primitives/Badges.stories.js +183 -0
  117. package/stories/primitives/Buttons.stories.js +229 -0
  118. package/stories/primitives/Cards.stories.js +353 -0
  119. package/stories/primitives/FormGroups.stories.js +569 -0
  120. package/stories/primitives/Forms.stories.js +131 -0
  121. package/stories/primitives/Media.stories.js +203 -0
  122. package/stories/primitives/Tables.stories.js +232 -0
  123. package/stories/reference/ReferenceCatalog.stories.js +28 -0
  124. package/stories/reference/reference-catalog.js +413 -0
  125. package/stories/reference/reference-docs.js +302 -0
  126. package/stories/reference/reference-helpers.js +310 -0
  127. package/stories/utilities/GridSystem.stories.js +208 -0
  128. package/stories/utils/PdsAsk.stories.js +420 -0
  129. package/stories/utils/toast-utils.js +148 -0
@@ -0,0 +1,569 @@
1
+ import { html } from 'lit';
2
+ import { toastFormData } from '../utils/toast-utils.js';
3
+
4
+ export default {
5
+ title: "Primitives/Form Groups",
6
+ tags: ['grouping'],
7
+ parameters: {
8
+ pds: {
9
+ tags: ['forms', 'grouping']
10
+ },
11
+ docs: {
12
+ description: {
13
+ component: `Accessible radio groups and checkbox groups with proper ARIA attributes and semantic HTML.
14
+
15
+ ## Unified Styling
16
+
17
+ Radio groups (\`role="radiogroup"\`) and checkbox groups (\`role="group"\`) share the same consolidated styling rules:
18
+
19
+ ### Default Style
20
+ Both display with visible native controls in a vertical column layout:
21
+ - Column layout with reduced spacing (\`gap: var(--spacing-2)\`)
22
+ - Visible native radio buttons or checkboxes with primary accent color
23
+ - Clean hover states that highlight text
24
+ - Proper focus outlines for accessibility
25
+ - Users can override layout with standard flex utilities
26
+
27
+ ### Button Style
28
+ Add the \`.buttons\` class to either type for outlined button-style controls:
29
+ - Horizontal flex wrap layout
30
+ - Outlined style with transparent background
31
+ - Selected state: subtle primary tint (8%) with thicker border (2px)
32
+ - Compact/dense sizing (75% of regular button height)
33
+ - Never looks like filled primary buttons - always outlined
34
+ - Works identically for both radio and checkbox groups`,
35
+ },
36
+ },
37
+ },
38
+ };
39
+
40
+ const formGroupsStoryStyles = html`
41
+ <style>
42
+ .form-groups-section {
43
+ padding: var(--spacing-4);
44
+ }
45
+ .form-groups-helper {
46
+ margin-bottom: var(--spacing-4);
47
+ opacity: 0.8;
48
+ }
49
+ .form-groups-helper-lg {
50
+ margin-bottom: var(--spacing-6);
51
+ opacity: 0.8;
52
+ }
53
+ .form-groups-comparison {
54
+ display: grid;
55
+ grid-template-columns: 1fr 1fr;
56
+ gap: var(--spacing-8);
57
+ }
58
+ .form-groups-subheading {
59
+ margin-bottom: var(--spacing-4);
60
+ }
61
+ .form-groups-fieldset-spacing {
62
+ margin-bottom: var(--spacing-6);
63
+ }
64
+ .form-groups-card {
65
+ padding: var(--spacing-4);
66
+ }
67
+ .form-groups-horizontal {
68
+ display: flex;
69
+ flex-wrap: wrap;
70
+ gap: var(--spacing-3);
71
+ }
72
+ .form-groups-grid {
73
+ display: grid;
74
+ gap: var(--spacing-6);
75
+ max-width: 50rem;
76
+ }
77
+ .form-groups-accessible-card {
78
+ padding: var(--spacing-6);
79
+ max-width: 37.5rem;
80
+ }
81
+ .form-groups-accessible-form {
82
+ display: flex;
83
+ flex-direction: column;
84
+ gap: var(--spacing-6);
85
+ }
86
+ .form-groups-topics-helper {
87
+ font-size: 0.9rem;
88
+ opacity: 0.8;
89
+ margin-bottom: var(--spacing-3);
90
+ }
91
+ .form-groups-actions {
92
+ margin-top: var(--spacing-6);
93
+ display: flex;
94
+ gap: var(--spacing-2);
95
+ }
96
+ </style>
97
+ `;
98
+
99
+ export const RadioGroupDefault = () => html`
100
+ ${formGroupsStoryStyles}
101
+ <div class="form-groups-section">
102
+ <h3>Radio Group - Default Style</h3>
103
+ <p class="form-groups-helper">
104
+ Default radio group with visible radio buttons, vertical layout
105
+ </p>
106
+ <fieldset role="radiogroup">
107
+ <legend>Select your plan</legend>
108
+ <label>
109
+ <input type="radio" name="plan-default" value="free" checked />
110
+ <span>Free - $0/month</span>
111
+ </label>
112
+ <label>
113
+ <input type="radio" name="plan-default" value="pro" />
114
+ <span>Pro - $29/month</span>
115
+ </label>
116
+ <label>
117
+ <input type="radio" name="plan-default" value="enterprise" />
118
+ <span>Enterprise - $99/month</span>
119
+ </label>
120
+ </fieldset>
121
+ </div>
122
+ `;
123
+
124
+ RadioGroupDefault.storyName = "Radio Group - Default";
125
+
126
+ export const RadioGroupButtons = () => html`
127
+ ${formGroupsStoryStyles}
128
+ <div class="form-groups-section">
129
+ <h3>Radio Group - Button Style</h3>
130
+ <p class="form-groups-helper">
131
+ Add <code>class="buttons"</code> for outlined button-style radio controls
132
+ </p>
133
+ <fieldset role="radiogroup" class="buttons">
134
+ <legend>Select your plan</legend>
135
+ <label>
136
+ <input type="radio" name="plan-buttons" value="free" checked />
137
+ <span>Free</span>
138
+ </label>
139
+ <label>
140
+ <input type="radio" name="plan-buttons" value="pro" />
141
+ <span>Pro</span>
142
+ </label>
143
+ <label>
144
+ <input type="radio" name="plan-buttons" value="enterprise" />
145
+ <span>Enterprise</span>
146
+ </label>
147
+ </fieldset>
148
+ </div>
149
+ `;
150
+
151
+ RadioGroupButtons.storyName = "Radio Group - Buttons";
152
+
153
+ export const CheckboxGroupDefault = () => html`
154
+ ${formGroupsStoryStyles}
155
+ <div class="form-groups-section">
156
+ <h3>Checkbox Group - Default Style</h3>
157
+ <p class="form-groups-helper">
158
+ Default checkbox group with visible checkboxes, vertical layout
159
+ </p>
160
+ <fieldset role="group">
161
+ <legend>Select features</legend>
162
+ <label>
163
+ <input type="checkbox" name="features-default" value="api" checked />
164
+ <span>API Access</span>
165
+ </label>
166
+ <label>
167
+ <input
168
+ type="checkbox"
169
+ name="features-default"
170
+ value="analytics"
171
+ checked
172
+ />
173
+ <span>Advanced Analytics</span>
174
+ </label>
175
+ <label>
176
+ <input type="checkbox" name="features-default" value="support" />
177
+ <span>Priority Support</span>
178
+ </label>
179
+ <label>
180
+ <input type="checkbox" name="features-default" value="sso" />
181
+ <span>Single Sign-On</span>
182
+ </label>
183
+ </fieldset>
184
+ </div>
185
+ `;
186
+
187
+ CheckboxGroupDefault.storyName = "Checkbox Group - Default";
188
+
189
+ export const CheckboxGroupButtons = () => html`
190
+ ${formGroupsStoryStyles}
191
+ <div class="form-groups-section">
192
+ <h3>Checkbox Group - Button Style</h3>
193
+ <p class="form-groups-helper">
194
+ Add <code>class="buttons"</code> for outlined button-style checkboxes
195
+ </p>
196
+ <fieldset role="group" class="buttons">
197
+ <legend>Select features</legend>
198
+ <label>
199
+ <input type="checkbox" name="features-buttons" value="api" checked />
200
+ <span>API Access</span>
201
+ </label>
202
+ <label>
203
+ <input
204
+ type="checkbox"
205
+ name="features-buttons"
206
+ value="analytics"
207
+ checked
208
+ />
209
+ <span>Analytics</span>
210
+ </label>
211
+ <label>
212
+ <input type="checkbox" name="features-buttons" value="support" />
213
+ <span>Support</span>
214
+ </label>
215
+ <label>
216
+ <input type="checkbox" name="features-buttons" value="sso" />
217
+ <span>SSO</span>
218
+ </label>
219
+ </fieldset>
220
+ </div>
221
+ `;
222
+
223
+ CheckboxGroupButtons.storyName = "Checkbox Group - Buttons";
224
+
225
+ export const StyleComparison = () => html`
226
+ ${formGroupsStoryStyles}
227
+ <div class="form-groups-section">
228
+ <h3>Side-by-Side Comparison</h3>
229
+ <p class="form-groups-helper-lg">
230
+ Compare default vs button styles for both radio and checkbox groups
231
+ </p>
232
+
233
+ <div class="form-groups-comparison">
234
+ <div>
235
+ <h4 class="form-groups-subheading">Default Style</h4>
236
+
237
+ <fieldset role="radiogroup" class="form-groups-fieldset-spacing">
238
+ <legend>Billing Cycle</legend>
239
+ <label>
240
+ <input
241
+ type="radio"
242
+ name="billing-default"
243
+ value="monthly"
244
+ checked
245
+ />
246
+ <span>Monthly</span>
247
+ </label>
248
+ <label>
249
+ <input type="radio" name="billing-default" value="annual" />
250
+ <span>Annual (Save 20%)</span>
251
+ </label>
252
+ </fieldset>
253
+
254
+ <fieldset role="group">
255
+ <legend>Add-ons</legend>
256
+ <label>
257
+ <input type="checkbox" name="addons-default" value="backup" />
258
+ <span>Daily Backups (+$5/mo)</span>
259
+ </label>
260
+ <label>
261
+ <input type="checkbox" name="addons-default" value="cdn" />
262
+ <span>Global CDN (+$10/mo)</span>
263
+ </label>
264
+ <label>
265
+ <input
266
+ type="checkbox"
267
+ name="addons-default"
268
+ value="monitoring"
269
+ checked
270
+ />
271
+ <span>24/7 Monitoring (+$15/mo)</span>
272
+ </label>
273
+ </fieldset>
274
+ </div>
275
+
276
+ <div>
277
+ <h4 class="form-groups-subheading">Button Style</h4>
278
+
279
+ <fieldset
280
+ role="radiogroup"
281
+ class="buttons form-groups-fieldset-spacing"
282
+ >
283
+ <legend>Billing Cycle</legend>
284
+ <label>
285
+ <input
286
+ type="radio"
287
+ name="billing-buttons"
288
+ value="monthly"
289
+ checked
290
+ />
291
+ <span>Monthly</span>
292
+ </label>
293
+ <label>
294
+ <input type="radio" name="billing-buttons" value="annual" />
295
+ <span>Annual</span>
296
+ </label>
297
+ </fieldset>
298
+
299
+ <fieldset role="group" class="buttons">
300
+ <legend>Add-ons</legend>
301
+ <label>
302
+ <input type="checkbox" name="addons-buttons" value="backup" />
303
+ <span>Backups</span>
304
+ </label>
305
+ <label>
306
+ <input type="checkbox" name="addons-buttons" value="cdn" />
307
+ <span>CDN</span>
308
+ </label>
309
+ <label>
310
+ <input
311
+ type="checkbox"
312
+ name="addons-buttons"
313
+ value="monitoring"
314
+ checked
315
+ />
316
+ <span>Monitoring</span>
317
+ </label>
318
+ </fieldset>
319
+ </div>
320
+ </div>
321
+ </div>
322
+ `;
323
+
324
+ StyleComparison.storyName = "Style Comparison";
325
+
326
+ export const ToggleSwitches = () => html`
327
+ ${formGroupsStoryStyles}
328
+ <div class="form-groups-section">
329
+ <h3>Toggle Switches</h3>
330
+ <p class="form-groups-helper">
331
+ Uses <code>data-toggle</code> attribute for enhanced toggle switch styling
332
+ </p>
333
+
334
+ <section class="card form-groups-card">
335
+ <fieldset class="card" role="group">
336
+ <legend>Preferences</legend>
337
+
338
+ <label data-toggle>
339
+ <input type="checkbox" name="prefs" value="notifications" checked />
340
+ <span>Enable notifications</span>
341
+ </label>
342
+
343
+ <label data-toggle>
344
+ <input type="checkbox" name="prefs" value="dark" />
345
+ <span>Dark mode</span>
346
+
347
+ </label>
348
+ </fieldset>
349
+ </section>
350
+
351
+ <section class="card form-groups-card">
352
+ <fieldset class="card" role="group">
353
+ <legend>Left-aligned knob</legend>
354
+ <label data-toggle>
355
+ <input type="checkbox" name="prefs" value="autosave" checked />
356
+ <span>Auto-save</span>
357
+ </label>
358
+
359
+ <label data-toggle>
360
+ <input type="checkbox" name="prefs" value="tooltips" />
361
+ <span>Show tooltips</span>
362
+ </label>
363
+ </fieldset>
364
+ </section>
365
+ </div>
366
+ `;
367
+
368
+ ToggleSwitches.storyName = "Toggle Switches";
369
+
370
+ export const CustomLayout = () => html`
371
+ ${formGroupsStoryStyles}
372
+ <div class="card form-groups-card">
373
+ <h3>Custom Layout with Flex Utilities</h3>
374
+ <p class="alert alert-info">
375
+ Override default column layout using standard CSS flex properties
376
+ </p>
377
+
378
+ <fieldset role="radiogroup" class="form-groups-horizontal">
379
+ <legend>Horizontal Radio Group (flex-direction: row)</legend>
380
+ <label>
381
+ <input type="radio" name="horizontal-radio" value="1" checked />
382
+ <span>Option 1</span>
383
+ </label>
384
+ <label>
385
+ <input type="radio" name="horizontal-radio" value="2" />
386
+ <span>Option 2</span>
387
+ </label>
388
+ <label>
389
+ <input type="radio" name="horizontal-radio" value="3" />
390
+ <span>Option 3</span>
391
+ </label>
392
+ </fieldset>
393
+
394
+ <fieldset role="group" class="form-groups-horizontal">
395
+ <legend>Horizontal Checkbox Group (flex-direction: row)</legend>
396
+ <label>
397
+ <input type="checkbox" name="horizontal-check" value="1" checked />
398
+ <span>Feature 1</span>
399
+ </label>
400
+ <label>
401
+ <input type="checkbox" name="horizontal-check" value="2" />
402
+ <span>Feature 2</span>
403
+ </label>
404
+ <label>
405
+ <input type="checkbox" name="horizontal-check" value="3" checked />
406
+ <span>Feature 3</span>
407
+ </label>
408
+ </fieldset>
409
+ </div>
410
+ `;
411
+
412
+ CustomLayout.storyName = "Custom Layout";
413
+
414
+ export const ButtonStyleVariants = () => html`
415
+ ${formGroupsStoryStyles}
416
+ <div class="form-groups-section">
417
+ <h3>Button Style Variants</h3>
418
+ <p class="form-groups-helper-lg">
419
+ Examples of button-style groups in different contexts
420
+ </p>
421
+
422
+ <div class="form-groups-grid">
423
+ <fieldset role="radiogroup" class="buttons">
424
+ <legend>Subscription Tier</legend>
425
+ <label>
426
+ <input type="radio" name="tier" value="starter" checked />
427
+ <span>Starter</span>
428
+ </label>
429
+ <label>
430
+ <input type="radio" name="tier" value="professional" />
431
+ <span>Professional</span>
432
+ </label>
433
+ <label>
434
+ <input type="radio" name="tier" value="business" />
435
+ <span>Business</span>
436
+ </label>
437
+ <label>
438
+ <input type="radio" name="tier" value="enterprise" />
439
+ <span>Enterprise</span>
440
+ </label>
441
+ </fieldset>
442
+
443
+ <fieldset role="group" class="buttons">
444
+ <legend>Available Integrations</legend>
445
+ <label>
446
+ <input type="checkbox" name="integrations" value="slack" checked />
447
+ <span>Slack</span>
448
+ </label>
449
+ <label>
450
+ <input type="checkbox" name="integrations" value="github" checked />
451
+ <span>GitHub</span>
452
+ </label>
453
+ <label>
454
+ <input type="checkbox" name="integrations" value="jira" />
455
+ <span>Jira</span>
456
+ </label>
457
+ <label>
458
+ <input type="checkbox" name="integrations" value="salesforce" />
459
+ <span>Salesforce</span>
460
+ </label>
461
+ <label>
462
+ <input type="checkbox" name="integrations" value="zapier" />
463
+ <span>Zapier</span>
464
+ </label>
465
+ </fieldset>
466
+
467
+ <fieldset role="radiogroup" class="buttons">
468
+ <legend>Payment Method</legend>
469
+ <label>
470
+ <input type="radio" name="payment" value="card" checked />
471
+ <span>💳 Credit Card</span>
472
+ </label>
473
+ <label>
474
+ <input type="radio" name="payment" value="paypal" />
475
+ <span>PayPal</span>
476
+ </label>
477
+ <label>
478
+ <input type="radio" name="payment" value="crypto" />
479
+ <span>â‚¿ Crypto</span>
480
+ </label>
481
+ </fieldset>
482
+ </div>
483
+ </div>
484
+ `;
485
+
486
+ ButtonStyleVariants.storyName = "Button Style Variants";
487
+
488
+ export const AccessibleFormGroups = {
489
+ render: () => {
490
+ const handleSubmit = (event) => {
491
+ event.preventDefault();
492
+ toastFormData(new FormData(event.target));
493
+ };
494
+
495
+ return html`
496
+ ${formGroupsStoryStyles}
497
+ <div class="form-groups-section">
498
+ <h2>Accessibility Features</h2>
499
+ <p class="form-groups-helper-lg">
500
+ Form groups include proper ARIA attributes, semantic HTML, and keyboard
501
+ navigation support.
502
+ </p>
503
+
504
+ <div class="card form-groups-accessible-card">
505
+ <form class="form-groups-accessible-form" @submit=${handleSubmit}>
506
+ <fieldset
507
+ role="radiogroup"
508
+ class="buttons"
509
+ aria-describedby="notification-help"
510
+ >
511
+ <legend>Notification Preferences</legend>
512
+
513
+ <p>Choose how you'd like to receive notifications</p>
514
+
515
+ <fieldset role="group" class="flex flex-row">
516
+ <label>
517
+ <input type="radio" name="notification" value="email" checked />
518
+ <span>Email only</span>
519
+ </label>
520
+ <label>
521
+ <input type="radio" name="notification" value="sms" />
522
+ <span>SMS only</span>
523
+ </label>
524
+ <label>
525
+ <input type="radio" name="notification" value="both" />
526
+ <span>Both</span>
527
+ </label>
528
+ <label>
529
+ <input type="radio" name="notification" value="none" />
530
+ <span>None</span>
531
+ </label>
532
+ </fieldset>
533
+ </fieldset>
534
+
535
+ <fieldset
536
+ role="group"
537
+ class="form-groups-fieldset-spacing"
538
+ aria-describedby="topics-help"
539
+ >
540
+ <legend>Topics to Follow</legend>
541
+ <p id="topics-help" class="form-groups-topics-helper">
542
+ Select all topics you're interested in
543
+ </p>
544
+ <label data-toggle>
545
+ <input type="checkbox" name="topics" value="product" checked />
546
+ <span>Product Updates</span>
547
+ </label>
548
+ <label data-toggle>
549
+ <input type="checkbox" name="topics" value="security" checked />
550
+ <span>Security Alerts</span>
551
+ </label>
552
+ <label data-toggle>
553
+ <input type="checkbox" name="topics" value="marketing" />
554
+ <span>Marketing & Promotions</span>
555
+ </label>
556
+ </fieldset>
557
+
558
+ <div class="form-groups-actions">
559
+ <button type="submit" class="btn-primary">Save Preferences</button>
560
+ <button type="reset" class="btn-secondary">Reset</button>
561
+ </div>
562
+ </form>
563
+ </div>
564
+ </div>
565
+ `;
566
+ }
567
+ };
568
+
569
+ AccessibleFormGroups.storyName = "Accessible Form Groups";
@@ -0,0 +1,131 @@
1
+ import { html } from 'lit';
2
+ import { toastFormData } from '../utils/toast-utils.js';
3
+
4
+ export default {
5
+ title: 'Primitives/Forms',
6
+ tags: ['buttons', 'forms'],
7
+ parameters: {
8
+ pds: {
9
+ tags: ['buttons', 'forms']
10
+ },
11
+ docs: {
12
+ description: {
13
+ component: `Standard HTML form controls styled by PDS.
14
+
15
+ **💡 For modern apps, consider using [pds-jsonform](/story/components-pds-jsonform--simple-form)** - a powerful web component that automatically generates forms from JSON Schema with built-in validation, conditional logic, and data binding.
16
+
17
+ These primitive form controls provide the foundation for manual form building when you need full control over the markup.`
18
+ }
19
+ }
20
+ },
21
+ argTypes: {
22
+ preset: {
23
+ control: 'select',
24
+ options: ['default', 'ocean-breeze', 'midnight-steel', 'sunset-vibes', 'forest-calm', 'lavender-dream'],
25
+ description: 'Choose a design preset'
26
+ },
27
+ primaryColor: {
28
+ control: 'color',
29
+ description: 'Override primary color'
30
+ },
31
+ secondaryColor: {
32
+ control: 'color',
33
+ description: 'Override secondary color'
34
+ }
35
+ }
36
+ };
37
+
38
+ export const Default = {
39
+ render: (args) => {
40
+ // Preset changes are handled by toolbar in preview.js
41
+ const handleSubmit = (event) => {
42
+ event.preventDefault();
43
+ toastFormData(new FormData(event.target));
44
+ };
45
+
46
+ return html`
47
+ <style>
48
+ .forms-default-form {
49
+ max-width: 25rem;
50
+ }
51
+ </style>
52
+ <div class="card">
53
+
54
+ <form class="forms-default-form" @submit=${handleSubmit}>
55
+ <label>
56
+ <span>Text Input</span>
57
+ <input type="text" name="text" placeholder="Enter text...">
58
+ </label>
59
+ <label>
60
+ <span>Email</span>
61
+ <div class="input-icon">
62
+ <pds-icon icon="envelope"></pds-icon>
63
+ <input type="email" name="email" required placeholder="email@example.com">
64
+ </div>
65
+ </label>
66
+ <label>
67
+ <span>Select</span>
68
+ <select name="select">
69
+ <option>Option 1</option>
70
+ <option>Option 2</option>
71
+ <option>Option 3</option>
72
+ </select>
73
+ </label>
74
+ <label>
75
+ <span>Textarea</span>
76
+ <textarea name="textarea" rows="4" placeholder="Enter longer text..."></textarea>
77
+ </label>
78
+ <button type="submit" class="btn-primary">Submit</button>
79
+ </form>
80
+
81
+ </div>
82
+ `;
83
+ },
84
+ args: {
85
+ preset: 'default'
86
+ }
87
+ };
88
+
89
+ export const InputsWithIcons = {
90
+ render: (args) => {
91
+ return html`
92
+ <style>
93
+ .forms-inputs-demo {
94
+ max-width: 25rem;
95
+ }
96
+ </style>
97
+ <div class="card">
98
+ <h3>Inputs with Icons</h3>
99
+ <p>Enhance inputs with icons for better UX. Icons can be positioned at the start or end of the input.</p>
100
+
101
+ <div class="flex flex-col gap-lg forms-inputs-demo">
102
+ <label>
103
+ <span>Search (Icon Start)</span>
104
+ <div class="input-icon">
105
+ <pds-icon icon="magnifying-glass"></pds-icon>
106
+ <input type="search" placeholder="Search..." />
107
+ </div>
108
+ </label>
109
+
110
+ <label>
111
+ <span>Username (Icon End)</span>
112
+ <div class="input-icon input-icon-end">
113
+ <input type="text" placeholder="Username" />
114
+ <pds-icon icon="user"></pds-icon>
115
+ </div>
116
+ </label>
117
+ </div>
118
+ </div>
119
+ `;
120
+ },
121
+ args: {
122
+ preset: 'default'
123
+ },
124
+ parameters: {
125
+ docs: {
126
+ description: {
127
+ story: 'Input fields can be enhanced with icons to provide visual context. Use the `input-icon` class wrapper and position icons at the start (default) or end (`input-icon-end`) of the input.'
128
+ }
129
+ }
130
+ }
131
+ };