@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.
- package/.storybook/addons/description/preview.js +15 -0
- package/.storybook/addons/description/register.js +60 -0
- package/.storybook/addons/html-preview/Panel.jsx +327 -0
- package/.storybook/addons/html-preview/constants.js +6 -0
- package/.storybook/addons/html-preview/preview.js +178 -0
- package/.storybook/addons/html-preview/register.js +16 -0
- package/.storybook/addons/pds-configurator/SearchTool.js +44 -0
- package/.storybook/addons/pds-configurator/Tool.js +30 -0
- package/.storybook/addons/pds-configurator/constants.js +9 -0
- package/.storybook/addons/pds-configurator/preview.js +159 -0
- package/.storybook/addons/pds-configurator/register.js +24 -0
- package/.storybook/docs.css +35 -0
- package/.storybook/htmlPreview.css +103 -0
- package/.storybook/htmlPreview.js +271 -0
- package/.storybook/main.js +160 -0
- package/.storybook/preview-body.html +48 -0
- package/.storybook/preview-head.html +11 -0
- package/.storybook/preview.js +1563 -0
- package/README.md +266 -0
- package/bin/index.js +40 -0
- package/dist/pds-reference.json +2101 -0
- package/package.json +45 -0
- package/pds.config.js +6 -0
- package/public/assets/css/app.css +1216 -0
- package/public/assets/data/auto-design-advanced.json +704 -0
- package/public/assets/data/auto-design-simple.json +123 -0
- package/public/assets/img/icon-512x512.png +0 -0
- package/public/assets/img/logo-trans.png +0 -0
- package/public/assets/img/logo.png +0 -0
- package/public/assets/js/app.js +15088 -0
- package/public/assets/js/app.js.map +7 -0
- package/public/assets/js/lit.js +1176 -0
- package/public/assets/js/lit.js.map +7 -0
- package/public/assets/js/pds.js +9801 -0
- package/public/assets/js/pds.js.map +7 -0
- package/public/assets/pds/components/pds-calendar.js +837 -0
- package/public/assets/pds/components/pds-drawer.js +857 -0
- package/public/assets/pds/components/pds-icon.js +338 -0
- package/public/assets/pds/components/pds-jsonform.js +1775 -0
- package/public/assets/pds/components/pds-richtext.js +1035 -0
- package/public/assets/pds/components/pds-scrollrow.js +331 -0
- package/public/assets/pds/components/pds-splitpanel.js +401 -0
- package/public/assets/pds/components/pds-tabstrip.js +251 -0
- package/public/assets/pds/components/pds-toaster.js +446 -0
- package/public/assets/pds/components/pds-upload.js +657 -0
- package/public/assets/pds/custom-elements.json +2003 -0
- package/public/assets/pds/icons/pds-icons.svg +498 -0
- package/public/assets/pds/pds-css-complete.json +1861 -0
- package/public/assets/pds/pds-runtime-config.json +11 -0
- package/public/assets/pds/pds.css-data.json +2152 -0
- package/public/assets/pds/styles/pds-components.css +1944 -0
- package/public/assets/pds/styles/pds-components.css.js +3895 -0
- package/public/assets/pds/styles/pds-primitives.css +352 -0
- package/public/assets/pds/styles/pds-primitives.css.js +711 -0
- package/public/assets/pds/styles/pds-styles.css +3761 -0
- package/public/assets/pds/styles/pds-styles.css.js +7529 -0
- package/public/assets/pds/styles/pds-tokens.css +699 -0
- package/public/assets/pds/styles/pds-tokens.css.js +1405 -0
- package/public/assets/pds/styles/pds-utilities.css +763 -0
- package/public/assets/pds/styles/pds-utilities.css.js +1533 -0
- package/public/assets/pds/vscode-custom-data.json +824 -0
- package/scripts/build-pds-reference.mjs +807 -0
- package/scripts/generate-stories.js +542 -0
- package/scripts/package-build.js +86 -0
- package/src/js/app.js +17 -0
- package/src/js/common/ask.js +208 -0
- package/src/js/common/common.js +20 -0
- package/src/js/common/font-loader.js +200 -0
- package/src/js/common/msg.js +90 -0
- package/src/js/lit.js +40 -0
- package/src/js/pds-core/pds-config.js +1162 -0
- package/src/js/pds-core/pds-enhancer-metadata.js +75 -0
- package/src/js/pds-core/pds-enhancers.js +357 -0
- package/src/js/pds-core/pds-enums.js +86 -0
- package/src/js/pds-core/pds-generator.js +5317 -0
- package/src/js/pds-core/pds-ontology.js +256 -0
- package/src/js/pds-core/pds-paths.js +109 -0
- package/src/js/pds-core/pds-query.js +571 -0
- package/src/js/pds-core/pds-registry.js +129 -0
- package/src/js/pds-core/pds.d.ts +129 -0
- package/src/js/pds.d.ts +408 -0
- package/src/js/pds.js +1579 -0
- package/src/pds-core/pds-api.js +105 -0
- package/stories/GettingStarted.md +96 -0
- package/stories/GettingStarted.stories.js +144 -0
- package/stories/WhatIsPDS.md +194 -0
- package/stories/WhatIsPDS.stories.js +144 -0
- package/stories/components/PdsCalendar.stories.js +263 -0
- package/stories/components/PdsDrawer.stories.js +623 -0
- package/stories/components/PdsIcon.stories.js +78 -0
- package/stories/components/PdsJsonform.stories.js +1444 -0
- package/stories/components/PdsRichtext.stories.js +367 -0
- package/stories/components/PdsScrollrow.stories.js +140 -0
- package/stories/components/PdsSplitpanel.stories.js +502 -0
- package/stories/components/PdsTabstrip.stories.js +442 -0
- package/stories/components/PdsToaster.stories.js +186 -0
- package/stories/components/PdsUpload.stories.js +66 -0
- package/stories/enhancements/Dropdowns.stories.js +185 -0
- package/stories/enhancements/InteractiveStates.stories.js +625 -0
- package/stories/enhancements/MeshGradients.stories.js +320 -0
- package/stories/enhancements/OpenGroups.stories.js +227 -0
- package/stories/enhancements/RangeSliders.stories.js +232 -0
- package/stories/enhancements/RequiredFields.stories.js +189 -0
- package/stories/enhancements/Toggles.stories.js +167 -0
- package/stories/foundations/Colors.stories.js +283 -0
- package/stories/foundations/Icons.stories.js +305 -0
- package/stories/foundations/SmartSurfaces.stories.js +367 -0
- package/stories/foundations/Spacing.stories.js +175 -0
- package/stories/foundations/Typography.stories.js +960 -0
- package/stories/foundations/ZIndex.stories.js +325 -0
- package/stories/patterns/BorderEffects.stories.js +72 -0
- package/stories/patterns/Layout.stories.js +99 -0
- package/stories/patterns/Utilities.stories.js +107 -0
- package/stories/primitives/Accordion.stories.js +359 -0
- package/stories/primitives/Alerts.stories.js +64 -0
- package/stories/primitives/Badges.stories.js +183 -0
- package/stories/primitives/Buttons.stories.js +229 -0
- package/stories/primitives/Cards.stories.js +353 -0
- package/stories/primitives/FormGroups.stories.js +569 -0
- package/stories/primitives/Forms.stories.js +131 -0
- package/stories/primitives/Media.stories.js +203 -0
- package/stories/primitives/Tables.stories.js +232 -0
- package/stories/reference/ReferenceCatalog.stories.js +28 -0
- package/stories/reference/reference-catalog.js +413 -0
- package/stories/reference/reference-docs.js +302 -0
- package/stories/reference/reference-helpers.js +310 -0
- package/stories/utilities/GridSystem.stories.js +208 -0
- package/stories/utils/PdsAsk.stories.js +420 -0
- package/stories/utils/toast-utils.js +148 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
|
|
3
|
+
const rangeSliderStoryStyles = html`
|
|
4
|
+
<style>
|
|
5
|
+
.range-slider-section {
|
|
6
|
+
max-width: 400px;
|
|
7
|
+
display: grid;
|
|
8
|
+
gap: var(--spacing-4);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.range-slider-section--wide {
|
|
12
|
+
max-width: 500px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.range-slider-section--comparison {
|
|
16
|
+
display: grid;
|
|
17
|
+
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
18
|
+
gap: var(--spacing-6);
|
|
19
|
+
max-width: 1000px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.range-slider-description {
|
|
23
|
+
color: var(--color-text-secondary);
|
|
24
|
+
font-size: 0.875rem;
|
|
25
|
+
margin: 0 0 var(--spacing-4);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.range-slider-form {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
gap: var(--spacing-4);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.range-slider-actions {
|
|
35
|
+
margin-top: var(--spacing-2);
|
|
36
|
+
align-self: flex-start;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.range-slider-card {
|
|
40
|
+
display: grid;
|
|
41
|
+
gap: var(--spacing-4);
|
|
42
|
+
}
|
|
43
|
+
</style>
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
export default {
|
|
47
|
+
title: 'Enhancements/Range Sliders',
|
|
48
|
+
tags: ['forms', 'interaction'],
|
|
49
|
+
parameters: {
|
|
50
|
+
pds: {
|
|
51
|
+
tags: ['forms', 'interaction']
|
|
52
|
+
},
|
|
53
|
+
docs: {
|
|
54
|
+
description: {
|
|
55
|
+
component: `Enhanced range inputs with two display modes:
|
|
56
|
+
|
|
57
|
+
**Standard Mode** (default): Floating bubble that appears on interaction.
|
|
58
|
+
|
|
59
|
+
**Inline Output Mode**: Add \`range-output\` class to the label for persistent inline value display using semantic \`<output>\` element.
|
|
60
|
+
|
|
61
|
+
Both modes automatically generate proper ARIA attributes and use the \`<output>\` tag for accessibility.`
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export const StandardFloatingBubble = () => html`
|
|
68
|
+
${rangeSliderStoryStyles}
|
|
69
|
+
<section class="range-slider-section">
|
|
70
|
+
<p class="range-slider-description">
|
|
71
|
+
Default behavior: A floating bubble appears when you interact with the slider.
|
|
72
|
+
</p>
|
|
73
|
+
<label>
|
|
74
|
+
<span>Volume</span>
|
|
75
|
+
<input type="range" min="0" max="100" value="50">
|
|
76
|
+
</label>
|
|
77
|
+
</section>
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
StandardFloatingBubble.storyName = 'Standard (Floating Bubble)';
|
|
81
|
+
|
|
82
|
+
export const MultipleRanges = () => html`
|
|
83
|
+
${rangeSliderStoryStyles}
|
|
84
|
+
<form
|
|
85
|
+
class="range-slider-section range-slider-form"
|
|
86
|
+
@submit="${(event) => {
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
toastFormData(new FormData(event.target));
|
|
89
|
+
}}"
|
|
90
|
+
>
|
|
91
|
+
<label>
|
|
92
|
+
<span>Brightness</span>
|
|
93
|
+
<input type="range" name="brightness" min="0" max="100" value="75">
|
|
94
|
+
</label>
|
|
95
|
+
<label>
|
|
96
|
+
<span>Contrast</span>
|
|
97
|
+
<input type="range" name="contrast" min="0" max="100" value="50">
|
|
98
|
+
</label>
|
|
99
|
+
<label>
|
|
100
|
+
<span>Saturation</span>
|
|
101
|
+
<input type="range" name="saturation" min="0" max="100" value="60">
|
|
102
|
+
</label>
|
|
103
|
+
<label>
|
|
104
|
+
<span>Temperature</span>
|
|
105
|
+
<input type="range" name="temperature" min="-100" max="100" value="0">
|
|
106
|
+
</label>
|
|
107
|
+
<button type="submit" class="btn-primary range-slider-actions">Apply Settings</button>
|
|
108
|
+
</form>
|
|
109
|
+
`;
|
|
110
|
+
|
|
111
|
+
export const CustomSteps = () => html`
|
|
112
|
+
${rangeSliderStoryStyles}
|
|
113
|
+
<form
|
|
114
|
+
class="range-slider-section range-slider-form"
|
|
115
|
+
@submit="${(event) => {
|
|
116
|
+
event.preventDefault();
|
|
117
|
+
toastFormData(new FormData(event.target));
|
|
118
|
+
}}"
|
|
119
|
+
>
|
|
120
|
+
<label>
|
|
121
|
+
<span>Opacity (10% steps)</span>
|
|
122
|
+
<input type="range" name="opacity" min="0" max="100" value="100" step="10">
|
|
123
|
+
</label>
|
|
124
|
+
<label>
|
|
125
|
+
<span>Font Size (0.25rem steps)</span>
|
|
126
|
+
<input type="range" name="fontSize" min="0.5" max="3" value="1" step="0.25">
|
|
127
|
+
</label>
|
|
128
|
+
<button type="submit" class="btn-primary range-slider-actions">Apply Settings</button>
|
|
129
|
+
</form>
|
|
130
|
+
`;
|
|
131
|
+
|
|
132
|
+
export const InlineOutputMode = () => html`
|
|
133
|
+
${rangeSliderStoryStyles}
|
|
134
|
+
<section class="range-slider-section range-slider-section--wide">
|
|
135
|
+
<p class="range-slider-description">
|
|
136
|
+
Add the <code>range-output</code> class to automatically create an inline output display.
|
|
137
|
+
</p>
|
|
138
|
+
<div class="range-slider-form">
|
|
139
|
+
<label class="range-output">
|
|
140
|
+
<span>Master Volume</span>
|
|
141
|
+
<input type="range" min="0" max="100" value="75">
|
|
142
|
+
</label>
|
|
143
|
+
<label class="range-output">
|
|
144
|
+
<span>Bass</span>
|
|
145
|
+
<input type="range" min="0" max="100" value="50">
|
|
146
|
+
</label>
|
|
147
|
+
<label class="range-output">
|
|
148
|
+
<span>Treble</span>
|
|
149
|
+
<input type="range" min="0" max="100" value="60">
|
|
150
|
+
</label>
|
|
151
|
+
</div>
|
|
152
|
+
</section>
|
|
153
|
+
`;
|
|
154
|
+
|
|
155
|
+
InlineOutputMode.storyName = 'Inline Output (range-output class)';
|
|
156
|
+
|
|
157
|
+
export const AudioControlsExample = () => html`
|
|
158
|
+
${rangeSliderStoryStyles}
|
|
159
|
+
<article class="card range-slider-section range-slider-section--wide range-slider-card">
|
|
160
|
+
<div>
|
|
161
|
+
<h3>Audio Controls</h3>
|
|
162
|
+
<p class="range-slider-description">
|
|
163
|
+
Complete example using <code>range-output</code> class for a real-world audio control interface.
|
|
164
|
+
</p>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="range-slider-form">
|
|
167
|
+
<label class="range-output">
|
|
168
|
+
<span>Master Volume</span>
|
|
169
|
+
<input type="range" min="0" max="100" value="75">
|
|
170
|
+
</label>
|
|
171
|
+
<label class="range-output">
|
|
172
|
+
<span>Bass</span>
|
|
173
|
+
<input type="range" min="0" max="100" value="50">
|
|
174
|
+
</label>
|
|
175
|
+
<label class="range-output">
|
|
176
|
+
<span>Treble</span>
|
|
177
|
+
<input type="range" min="0" max="100" value="60">
|
|
178
|
+
</label>
|
|
179
|
+
<label class="range-output">
|
|
180
|
+
<span>Balance</span>
|
|
181
|
+
<input type="range" min="-50" max="50" value="0">
|
|
182
|
+
</label>
|
|
183
|
+
</div>
|
|
184
|
+
</article>
|
|
185
|
+
`;
|
|
186
|
+
|
|
187
|
+
AudioControlsExample.storyName = 'Real-world Example (Audio Controls)';
|
|
188
|
+
|
|
189
|
+
export const ComparisonView = () => html`
|
|
190
|
+
${rangeSliderStoryStyles}
|
|
191
|
+
<div class="range-slider-section range-slider-section--comparison">
|
|
192
|
+
<article class="card range-slider-card">
|
|
193
|
+
<div>
|
|
194
|
+
<h3>Standard Mode</h3>
|
|
195
|
+
<p class="range-slider-description">
|
|
196
|
+
Floating bubble appears on hover/focus. Best for simple forms.
|
|
197
|
+
</p>
|
|
198
|
+
</div>
|
|
199
|
+
<div class="range-slider-form">
|
|
200
|
+
<label>
|
|
201
|
+
<span>Volume</span>
|
|
202
|
+
<input type="range" min="0" max="100" value="75">
|
|
203
|
+
</label>
|
|
204
|
+
<label>
|
|
205
|
+
<span>Brightness</span>
|
|
206
|
+
<input type="range" min="0" max="100" value="50">
|
|
207
|
+
</label>
|
|
208
|
+
</div>
|
|
209
|
+
</article>
|
|
210
|
+
|
|
211
|
+
<article class="card range-slider-card">
|
|
212
|
+
<div>
|
|
213
|
+
<h3>Inline Output Mode</h3>
|
|
214
|
+
<p class="range-slider-description">
|
|
215
|
+
Persistent value display. Best for settings and controls.
|
|
216
|
+
</p>
|
|
217
|
+
</div>
|
|
218
|
+
<div class="range-slider-form">
|
|
219
|
+
<label class="range-output">
|
|
220
|
+
<span>Volume</span>
|
|
221
|
+
<input type="range" min="0" max="100" value="75">
|
|
222
|
+
</label>
|
|
223
|
+
<label class="range-output">
|
|
224
|
+
<span>Brightness</span>
|
|
225
|
+
<input type="range" min="0" max="100" value="50">
|
|
226
|
+
</label>
|
|
227
|
+
</div>
|
|
228
|
+
</article>
|
|
229
|
+
</div>
|
|
230
|
+
`;
|
|
231
|
+
|
|
232
|
+
ComparisonView.storyName = 'Side-by-side Comparison';
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
|
|
3
|
+
const requiredFieldsStoryStyles = html`
|
|
4
|
+
<style>
|
|
5
|
+
.required-form {
|
|
6
|
+
max-width: 400px;
|
|
7
|
+
display: grid;
|
|
8
|
+
gap: var(--spacing-3);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.required-form--wide {
|
|
12
|
+
max-width: 500px;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.required-fieldset {
|
|
16
|
+
display: grid;
|
|
17
|
+
gap: var(--spacing-3);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.required-fieldset--spaced {
|
|
21
|
+
margin-top: var(--spacing-4);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.required-actions {
|
|
25
|
+
margin-top: var(--spacing-4);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.required-help-text {
|
|
29
|
+
color: var(--surface-text-secondary);
|
|
30
|
+
display: block;
|
|
31
|
+
margin-top: 0.25rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.required-field--spaced {
|
|
35
|
+
margin-top: var(--spacing-3);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.required-form__button {
|
|
39
|
+
justify-self: start;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
export default {
|
|
45
|
+
title: 'Enhancements/Required Fields',
|
|
46
|
+
tags: ['forms', 'interaction'],
|
|
47
|
+
parameters: {
|
|
48
|
+
pds: {
|
|
49
|
+
tags: ['forms', 'interaction']
|
|
50
|
+
},
|
|
51
|
+
docs: {
|
|
52
|
+
description: {
|
|
53
|
+
component: 'Automatic asterisk indicators for required form fields'
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export const BasicRequired = () => html`
|
|
60
|
+
${requiredFieldsStoryStyles}
|
|
61
|
+
<form
|
|
62
|
+
class="required-form"
|
|
63
|
+
@submit="${(event) => {
|
|
64
|
+
event.preventDefault();
|
|
65
|
+
toastFormData(new FormData(event.target));
|
|
66
|
+
}}"
|
|
67
|
+
>
|
|
68
|
+
<label>
|
|
69
|
+
<span>Full Name</span>
|
|
70
|
+
<input type="text" required placeholder="John Doe">
|
|
71
|
+
</label>
|
|
72
|
+
<label>
|
|
73
|
+
<span>Email</span>
|
|
74
|
+
<div class="input-icon">
|
|
75
|
+
<pds-icon icon="envelope"></pds-icon>
|
|
76
|
+
<input type="email" required placeholder="john@example.com">
|
|
77
|
+
</div>
|
|
78
|
+
</label>
|
|
79
|
+
<label>
|
|
80
|
+
<span>Phone (optional)</span>
|
|
81
|
+
<div class="input-icon">
|
|
82
|
+
<pds-icon icon="phone"></pds-icon>
|
|
83
|
+
<input type="tel" placeholder="+1 (555) 123-4567">
|
|
84
|
+
</div>
|
|
85
|
+
</label>
|
|
86
|
+
<button type="submit" class="btn-primary required-form__button">Submit</button>
|
|
87
|
+
</form>
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
export const MixedRequired = () => html`
|
|
91
|
+
${requiredFieldsStoryStyles}
|
|
92
|
+
<form
|
|
93
|
+
class="required-form required-form--wide"
|
|
94
|
+
@submit="${(event) => {
|
|
95
|
+
event.preventDefault();
|
|
96
|
+
toastFormData(new FormData(event.target));
|
|
97
|
+
}}"
|
|
98
|
+
>
|
|
99
|
+
<fieldset class="required-fieldset">
|
|
100
|
+
<legend>Account Information</legend>
|
|
101
|
+
<label>
|
|
102
|
+
<span>Username</span>
|
|
103
|
+
<div class="input-icon">
|
|
104
|
+
<pds-icon icon="user"></pds-icon>
|
|
105
|
+
<input type="text" required placeholder="username">
|
|
106
|
+
</div>
|
|
107
|
+
</label>
|
|
108
|
+
<label>
|
|
109
|
+
<span>Password</span>
|
|
110
|
+
<div class="input-icon">
|
|
111
|
+
<pds-icon icon="lock"></pds-icon>
|
|
112
|
+
<input type="password" required placeholder="••••••••">
|
|
113
|
+
</div>
|
|
114
|
+
</label>
|
|
115
|
+
<label>
|
|
116
|
+
<span>Confirm Password</span>
|
|
117
|
+
<div class="input-icon">
|
|
118
|
+
<pds-icon icon="lock"></pds-icon>
|
|
119
|
+
<input type="password" required placeholder="••••••••">
|
|
120
|
+
</div>
|
|
121
|
+
</label>
|
|
122
|
+
</fieldset>
|
|
123
|
+
|
|
124
|
+
<fieldset class="required-fieldset required-fieldset--spaced">
|
|
125
|
+
<legend>Optional Details</legend>
|
|
126
|
+
<label>
|
|
127
|
+
<span>Company</span>
|
|
128
|
+
<input type="text" placeholder="Acme Corp">
|
|
129
|
+
</label>
|
|
130
|
+
<label>
|
|
131
|
+
<span>Website</span>
|
|
132
|
+
<div class="input-icon">
|
|
133
|
+
<pds-icon icon="globe"></pds-icon>
|
|
134
|
+
<input type="url" placeholder="https://example.com">
|
|
135
|
+
</div>
|
|
136
|
+
</label>
|
|
137
|
+
</fieldset>
|
|
138
|
+
|
|
139
|
+
<div class="required-actions">
|
|
140
|
+
<button type="submit" class="btn-primary required-form__button">Create Account</button>
|
|
141
|
+
</div>
|
|
142
|
+
</form>
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
export const InlineHelp = () => html`
|
|
146
|
+
${requiredFieldsStoryStyles}
|
|
147
|
+
<form
|
|
148
|
+
class="required-form required-form--wide"
|
|
149
|
+
@submit="${(event) => {
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
toastFormData(new FormData(event.target));
|
|
152
|
+
}}"
|
|
153
|
+
>
|
|
154
|
+
<label>
|
|
155
|
+
<span>Email Address</span>
|
|
156
|
+
<div class="input-icon">
|
|
157
|
+
<pds-icon icon="envelope"></pds-icon>
|
|
158
|
+
<input type="email" required placeholder="you@example.com">
|
|
159
|
+
</div>
|
|
160
|
+
<small class="required-help-text">
|
|
161
|
+
We'll never share your email with anyone else.
|
|
162
|
+
</small>
|
|
163
|
+
</label>
|
|
164
|
+
<label class="required-field--spaced">
|
|
165
|
+
<span>Password</span>
|
|
166
|
+
<div class="input-icon">
|
|
167
|
+
<pds-icon icon="lock"></pds-icon>
|
|
168
|
+
<input type="password" required placeholder="••••••••">
|
|
169
|
+
</div>
|
|
170
|
+
<small class="required-help-text">
|
|
171
|
+
Must be at least 8 characters long.
|
|
172
|
+
</small>
|
|
173
|
+
</label>
|
|
174
|
+
<label class="required-field--spaced">
|
|
175
|
+
<span>Newsletter Frequency</span>
|
|
176
|
+
<select>
|
|
177
|
+
<option>Weekly</option>
|
|
178
|
+
<option>Monthly</option>
|
|
179
|
+
<option>Never</option>
|
|
180
|
+
</select>
|
|
181
|
+
<small class="required-help-text">
|
|
182
|
+
Optional - choose how often you want updates.
|
|
183
|
+
</small>
|
|
184
|
+
</label>
|
|
185
|
+
<div class="required-actions">
|
|
186
|
+
<button type="submit" class="btn-primary required-form__button">Sign Up</button>
|
|
187
|
+
</div>
|
|
188
|
+
</form>
|
|
189
|
+
`;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
|
|
3
|
+
const toggleStoryStyles = html`
|
|
4
|
+
<style>
|
|
5
|
+
.toggle-story-form {
|
|
6
|
+
max-width: 400px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.toggle-story-form__button {
|
|
10
|
+
margin-top: var(--spacing-3);
|
|
11
|
+
align-self: flex-start;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.toggle-story-layout {
|
|
15
|
+
max-width: 600px;
|
|
16
|
+
display: grid;
|
|
17
|
+
gap: var(--spacing-4);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.toggle-story-muted {
|
|
21
|
+
color: var(--surface-text-secondary);
|
|
22
|
+
margin-bottom: var(--spacing-4);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.toggle-story-section {
|
|
26
|
+
display: grid;
|
|
27
|
+
gap: var(--spacing-3);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.toggle-story-subheading {
|
|
31
|
+
margin-bottom: var(--spacing-2);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.toggle-story-card {
|
|
35
|
+
max-width: 500px;
|
|
36
|
+
display: grid;
|
|
37
|
+
gap: var(--spacing-4);
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
export default {
|
|
43
|
+
title: 'Enhancements/Toggles',
|
|
44
|
+
tags: ['forms', 'interaction'],
|
|
45
|
+
parameters: {
|
|
46
|
+
pds: {
|
|
47
|
+
tags: ['forms', 'interaction']
|
|
48
|
+
},
|
|
49
|
+
docs: {
|
|
50
|
+
description: {
|
|
51
|
+
component: 'Transform checkboxes into toggle switches using data-toggle attribute'
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const BasicToggle = () => html`
|
|
58
|
+
${toggleStoryStyles}
|
|
59
|
+
<label data-toggle>
|
|
60
|
+
<span data-label>Enable notifications</span>
|
|
61
|
+
<input type="checkbox">
|
|
62
|
+
</label>
|
|
63
|
+
`;
|
|
64
|
+
|
|
65
|
+
export const PreChecked = () => html`
|
|
66
|
+
${toggleStoryStyles}
|
|
67
|
+
<label data-toggle>
|
|
68
|
+
<span data-label>Dark mode</span>
|
|
69
|
+
<input type="checkbox" checked>
|
|
70
|
+
</label>
|
|
71
|
+
`;
|
|
72
|
+
|
|
73
|
+
export const MultipleToggles = () => html`
|
|
74
|
+
${toggleStoryStyles}
|
|
75
|
+
<form
|
|
76
|
+
class="flex flex-col gap-sm toggle-story-form"
|
|
77
|
+
@submit="${(event) => {
|
|
78
|
+
event.preventDefault();
|
|
79
|
+
toastFormData(new FormData(event.target));
|
|
80
|
+
}}"
|
|
81
|
+
>
|
|
82
|
+
<label data-toggle>
|
|
83
|
+
<span data-label>Email notifications</span>
|
|
84
|
+
<input type="checkbox" name="email" checked>
|
|
85
|
+
</label>
|
|
86
|
+
<label data-toggle>
|
|
87
|
+
<span data-label>Push notifications</span>
|
|
88
|
+
<input type="checkbox" name="push">
|
|
89
|
+
</label>
|
|
90
|
+
<label data-toggle>
|
|
91
|
+
<span data-label>SMS notifications</span>
|
|
92
|
+
<input type="checkbox" name="sms">
|
|
93
|
+
</label>
|
|
94
|
+
<label data-toggle>
|
|
95
|
+
<span data-label>Weekly digest</span>
|
|
96
|
+
<input type="checkbox" name="digest" checked>
|
|
97
|
+
</label>
|
|
98
|
+
<button type="submit" class="btn-primary toggle-story-form__button">Save Preferences</button>
|
|
99
|
+
</form>
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
export const TogglePositions = () => html`
|
|
103
|
+
${toggleStoryStyles}
|
|
104
|
+
<div class="toggle-story-layout">
|
|
105
|
+
<div>
|
|
106
|
+
<h3>Toggle Position Variations</h3>
|
|
107
|
+
<p class="toggle-story-muted">
|
|
108
|
+
Toggle knob position adapts based on label placement in DOM
|
|
109
|
+
</p>
|
|
110
|
+
</div>
|
|
111
|
+
<div class="flex flex-col gap-md">
|
|
112
|
+
<section class="toggle-story-section">
|
|
113
|
+
<h4 class="toggle-story-subheading">Label First (Knob on Right)</h4>
|
|
114
|
+
<div class="flex flex-col gap-sm">
|
|
115
|
+
<label data-toggle>
|
|
116
|
+
<span data-label>Email notifications</span>
|
|
117
|
+
<input type="checkbox" checked>
|
|
118
|
+
</label>
|
|
119
|
+
<label data-toggle>
|
|
120
|
+
<span data-label>Push notifications</span>
|
|
121
|
+
<input type="checkbox">
|
|
122
|
+
</label>
|
|
123
|
+
</div>
|
|
124
|
+
</section>
|
|
125
|
+
|
|
126
|
+
<section class="toggle-story-section">
|
|
127
|
+
<h4 class="toggle-story-subheading">Label Last (Knob on Left)</h4>
|
|
128
|
+
<div class="flex flex-col gap-sm">
|
|
129
|
+
<label data-toggle>
|
|
130
|
+
<input type="checkbox" checked>
|
|
131
|
+
<span data-label>Dark mode enabled</span>
|
|
132
|
+
</label>
|
|
133
|
+
<label data-toggle>
|
|
134
|
+
<input type="checkbox">
|
|
135
|
+
<span data-label>Auto-save changes</span>
|
|
136
|
+
</label>
|
|
137
|
+
</div>
|
|
138
|
+
</section>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
`;
|
|
142
|
+
|
|
143
|
+
export const InCard = () => html`
|
|
144
|
+
${toggleStoryStyles}
|
|
145
|
+
<article class="card toggle-story-card">
|
|
146
|
+
<div>
|
|
147
|
+
<h3>Privacy Settings</h3>
|
|
148
|
+
<p class="toggle-story-muted">
|
|
149
|
+
Control your privacy preferences
|
|
150
|
+
</p>
|
|
151
|
+
</div>
|
|
152
|
+
<div class="flex flex-col gap-sm">
|
|
153
|
+
<label data-toggle>
|
|
154
|
+
<span data-label>Profile visibility</span>
|
|
155
|
+
<input type="checkbox" checked>
|
|
156
|
+
</label>
|
|
157
|
+
<label data-toggle>
|
|
158
|
+
<span data-label>Show online status</span>
|
|
159
|
+
<input type="checkbox">
|
|
160
|
+
</label>
|
|
161
|
+
<label data-toggle>
|
|
162
|
+
<span data-label>Allow message requests</span>
|
|
163
|
+
<input type="checkbox" checked>
|
|
164
|
+
</label>
|
|
165
|
+
</div>
|
|
166
|
+
</article>
|
|
167
|
+
`;
|