@pure-ds/storybook 0.1.2 → 0.1.4

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.
@@ -2,352 +2,75 @@ import { html } from 'lit';
2
2
 
3
3
  export default {
4
4
  title: 'Primitives/Cards',
5
- tags: ['cards', 'layout', 'spacing', 'surface', 'colors'],
6
5
  parameters: {
7
- pds: {
8
- tags: ['cards', 'layout', 'spacing', 'surface', 'colors']
9
- },
10
6
  docs: {
11
7
  description: {
12
- component: 'Versatile content containers with multiple surface variants. Cards automatically adapt to your theme and support nesting for complex layouts.'
8
+ component: 'Basic UI elements - buttons, forms, cards, badges'
13
9
  }
14
10
  }
11
+ },
12
+ argTypes: {
13
+ preset: {
14
+ control: 'select',
15
+ options: ['default', 'ocean-breeze', 'midnight-steel', 'sunset-vibes', 'forest-calm', 'lavender-dream'],
16
+ description: 'Choose a design preset'
17
+ },
18
+ primaryColor: {
19
+ control: 'color',
20
+ description: 'Override primary color'
21
+ },
22
+ secondaryColor: {
23
+ control: 'color',
24
+ description: 'Override secondary color'
25
+ }
15
26
  }
16
27
  };
17
28
 
18
- const cardsStoryStyles = html`
19
- <style>
20
- .cards-story-section {
21
- padding: var(--spacing-4);
22
- }
23
- .cards-basic-grid {
24
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
25
- }
26
- .cards-surface-grid {
27
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
28
- }
29
- .cards-helper {
30
- margin-bottom: var(--spacing-4);
31
- opacity: 0.8;
32
- }
33
- .cards-inline-actions {
34
- margin-top: var(--spacing-3);
35
- }
36
- .cards-nested-shell {
37
- max-width: 37.5rem;
38
- }
39
- .cards-nested-spacing {
40
- margin-top: var(--spacing-4);
41
- }
42
- .cards-nested-deep {
43
- margin-top: var(--spacing-3);
44
- }
45
- .cards-parent-action {
46
- margin-top: var(--spacing-4);
47
- }
48
- .cards-horizontal-card {
49
- max-width: 37.5rem;
50
- margin-bottom: var(--spacing-6);
51
- }
52
- .cards-horizontal-media {
53
- flex-shrink: 0;
54
- width: 7.5rem;
55
- height: 7.5rem;
56
- background: var(--color-primary);
57
- border-radius: var(--radius-md);
58
- }
59
- .cards-horizontal-icon {
60
- color: white;
61
- opacity: 0.6;
62
- }
63
- .cards-horizontal-body {
64
- flex: 1;
65
- }
66
- .cards-grid-visuals {
67
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
68
- }
69
- .cards-visual-block {
70
- height: 100px;
71
- border-radius: var(--radius-sm);
72
- margin-bottom: var(--spacing-3);
73
- }
74
- .cards-gradient-one {
75
- background: linear-gradient(135deg, var(--color-primary), var(--color-secondary));
76
- }
77
- .cards-gradient-two {
78
- background: linear-gradient(135deg, var(--color-secondary), var(--color-primary));
79
- }
80
- .cards-gradient-three {
81
- background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
82
- }
83
- .cards-small-copy {
84
- font-size: 0.9rem;
85
- }
86
- .cards-complex-grid {
87
- grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
29
+ export const Default = {
30
+ render: (args) => {
31
+ // Apply preset if changed
32
+ if (args.preset) {
33
+ import('../../../src/js/pds.js').then(({ PDS }) => {
34
+ PDS.applyDesign({ preset: args.preset });
35
+ });
88
36
  }
89
- .cards-profile-header {
90
- margin-bottom: var(--spacing-4);
91
- }
92
- .cards-profile-avatar {
93
- width: 48px;
94
- height: 48px;
95
- background: var(--color-primary);
96
- border-radius: 50%;
97
- }
98
- .cards-profile-avatar pds-icon {
99
- color: white;
100
- }
101
- .cards-profile-title {
102
- margin: 0;
103
- }
104
- .cards-profile-meta {
105
- margin: 0;
106
- font-size: 0.85rem;
107
- opacity: 0.7;
108
- }
109
- .cards-profile-actions {
110
- margin-top: var(--spacing-4);
111
- }
112
- .cards-premium-header {
113
- margin-bottom: var(--spacing-3);
114
- }
115
- .cards-pro-badge {
116
- padding: var(--spacing-1) var(--spacing-2);
117
- background: var(--color-primary);
118
- color: white;
119
- border-radius: var(--radius-full);
120
- font-size: 0.75rem;
121
- font-weight: 600;
122
- }
123
- .cards-premium-list {
124
- margin: var(--spacing-3) 0;
125
- }
126
- .cards-stats-grid {
127
- margin: var(--spacing-4) 0;
128
- }
129
- .cards-stat-value {
130
- font-size: 2rem;
131
- font-weight: 700;
132
- }
133
- .cards-stat-value.primary {
134
- color: var(--color-primary);
135
- }
136
- .cards-stat-value.secondary {
137
- color: var(--color-secondary);
138
- }
139
- .cards-stat-label {
140
- font-size: 0.85rem;
141
- opacity: 0.7;
37
+
38
+ // Apply color overrides
39
+ if (args.primaryColor || args.secondaryColor) {
40
+ import('../../../src/js/pds.js').then(({ PDS }) => {
41
+ PDS.applyDesign({
42
+ design: {
43
+ colors: {
44
+ primary: args.primaryColor,
45
+ secondary: args.secondaryColor
46
+ }
47
+ }
48
+ });
49
+ });
142
50
  }
143
- </style>
144
- `;
51
+
52
+
145
53
 
146
- export const BasicCards = () => html`
147
- ${cardsStoryStyles}
148
- <div class="cards-story-section">
149
- <h3>Basic Cards</h3>
150
- <div class="grid gap-md cards-basic-grid">
54
+ return html`
55
+ <div class="story-container" style="padding: 2rem;">
56
+
57
+ <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem;">
151
58
  <article class="card">
152
- <h3>Default Card</h3>
153
- <p>Card content goes here. This is a basic card primitive with automatic theming.</p>
59
+ <h3>Card Title</h3>
60
+ <p>Card content goes here. This is a basic card primitive.</p>
154
61
  <button class="btn-primary">Action</button>
155
62
  </article>
156
-
157
63
  <article class="card">
158
- <h3>With Icon</h3>
159
- <div class="flex items-start gap-sm">
160
- <pds-icon icon="star" size="lg" class="icon-primary"></pds-icon>
161
- <div>
162
- <p>Cards can contain icons, buttons, forms, and any other content.</p>
163
- </div>
164
- </div>
64
+ <h3>Another Card</h3>
65
+ <p>Cards are versatile containers for content.</p>
165
66
  <button class="btn-outline">Learn More</button>
166
67
  </article>
167
-
168
- <article class="card">
169
- <h3>Interactive Card</h3>
170
- <p>With multiple actions and rich content.</p>
171
- <div class="flex gap-sm cards-inline-actions">
172
- <button class="btn-primary btn-sm">
173
- <pds-icon icon="heart" size="sm"></pds-icon>
174
- Like
175
- </button>
176
- <button class="btn-secondary btn-sm">
177
- <pds-icon icon="share" size="sm"></pds-icon>
178
- Share
179
- </button>
180
- <button class="icon-only btn-outline btn-sm">
181
- <pds-icon icon="bookmark" size="sm" label="Bookmark"></pds-icon>
182
- </button>
183
- </div>
184
- </article>
185
- </div>
186
- </div>
187
- `;
188
-
189
- BasicCards.storyName = 'Basic Cards';
190
-
191
- export const SurfaceVariants = () => html`
192
- ${cardsStoryStyles}
193
- <div class="cards-story-section">
194
- <h3>Surface Variants</h3>
195
- <p class="cards-helper">
196
- Different surface levels create visual hierarchy
197
- </p>
198
-
199
- <div class="grid gap-md cards-surface-grid">
200
- <article class="card">
201
- <h4>Default Surface</h4>
202
- <p>Standard card surface level. Use for most content containers.</p>
203
- <code>.card</code>
204
- </article>
205
-
206
- <article class="card surface-elevated">
207
- <h4>Elevated Surface</h4>
208
- <p>Appears raised above the default surface. Great for important content or hover states.</p>
209
- <code>.surface-elevated</code>
210
- </article>
211
-
212
- <article class="card surface-overlay">
213
- <h4>Overlay Surface</h4>
214
- <p>Highest surface level. Perfect for modal dialogs and floating panels.</p>
215
- <code>.surface-overlay</code>
216
- </article>
217
68
  </div>
218
- </div>
219
- `;
220
-
221
- SurfaceVariants.storyName = 'Surface Variants';
222
-
223
- export const NestedCards = () => html`
224
- ${cardsStoryStyles}
225
- <div class="cards-story-section">
226
- <h3>Nested Cards</h3>
227
- <p class="cards-helper">
228
- Surface variants enable natural nesting without visual confusion
229
- </p>
230
-
231
- <article class="card cards-nested-shell">
232
- <h3>Parent Card (Default Surface)</h3>
233
- <p>This is the outer container using the default card surface.</p>
234
-
235
- <div class="cards-nested-spacing">
236
- <article class="card surface-elevated">
237
- <h4>Nested Card (Elevated)</h4>
238
- <p>This card is nested inside the parent and uses the elevated surface for clear visual separation.</p>
239
-
240
- <div class="cards-nested-deep">
241
- <article class="card surface-overlay">
242
- <h5>Deeply Nested (Overlay)</h5>
243
- <p class="cards-small-copy">Even deeper nesting maintains readability with the overlay surface.</p>
244
- </article>
245
- </div>
246
- </article>
247
- </div>
248
-
249
- <button class="btn-primary cards-parent-action">Parent Action</button>
250
- </article>
251
- </div>
252
- `;
253
-
254
- NestedCards.storyName = 'Nested Cards';
255
-
256
- export const CardLayouts = () => html`
257
- ${cardsStoryStyles}
258
- <div class="cards-story-section">
259
- <h3>Horizontal Card</h3>
260
- <article class="card flex gap-md cards-horizontal-card">
261
- <div class="flex items-center justify-center cards-horizontal-media">
262
- <pds-icon icon="image" size="xl" class="cards-horizontal-icon"></pds-icon>
263
- </div>
264
- <div class="cards-horizontal-body">
265
- <h4>Horizontal Layout</h4>
266
- <p>Cards work great with flexbox for horizontal layouts.</p>
267
- <button class="btn-outline btn-sm">View Details</button>
69
+
268
70
  </div>
269
- </article>
270
-
271
- <h3>Card Grid</h3>
272
- <div class="grid gap-sm cards-grid-visuals">
273
- <article class="card">
274
- <div class="cards-visual-block cards-gradient-one"></div>
275
- <h4>Card 1</h4>
276
- <p class="cards-small-copy">Grid layout with cards.</p>
277
- </article>
278
- <article class="card">
279
- <div class="cards-visual-block cards-gradient-two"></div>
280
- <h4>Card 2</h4>
281
- <p class="cards-small-copy">Responsive and flexible.</p>
282
- </article>
283
- <article class="card">
284
- <div class="cards-visual-block cards-gradient-three"></div>
285
- <h4>Card 3</h4>
286
- <p class="cards-small-copy">Auto-fits to space.</p>
287
- </article>
288
- </div>
289
- </div>
290
- `;
291
-
292
- CardLayouts.storyName = 'Card Layouts';
293
-
294
- export const ComplexCards = () => html`
295
- ${cardsStoryStyles}
296
- <div class="cards-story-section">
297
- <h3>Complex Card Examples</h3>
298
- <div class="grid gap-md cards-complex-grid">
299
-
300
- <article class="card">
301
- <div class="flex items-center gap-sm cards-profile-header">
302
- <div class="flex items-center justify-center cards-profile-avatar">
303
- <pds-icon icon="user"></pds-icon>
304
- </div>
305
- <div>
306
- <h4 class="cards-profile-title">User Profile</h4>
307
- <p class="cards-profile-meta">@username</p>
308
- </div>
309
- </div>
310
- <p>Profile description goes here with some interesting details about the user.</p>
311
- <div class="flex gap-sm cards-profile-actions">
312
- <button class="btn-primary btn-sm">Follow</button>
313
- <button class="btn-outline btn-sm">Message</button>
314
- </div>
315
- </article>
316
-
317
- <article class="card surface-elevated">
318
- <div class="flex justify-between items-start cards-premium-header">
319
- <h4>Premium Feature</h4>
320
- <span class="cards-pro-badge">PRO</span>
321
- </div>
322
- <p>This elevated card highlights a premium feature with a badge and special styling.</p>
323
- <ul class="cards-premium-list">
324
- <li>Feature benefit one</li>
325
- <li>Feature benefit two</li>
326
- <li>Feature benefit three</li>
327
- </ul>
328
- <button class="btn-primary">
329
- <pds-icon icon="star"></pds-icon>
330
- Upgrade Now
331
- </button>
332
- </article>
333
-
334
- <article class="card">
335
- <h4>Stats Card</h4>
336
- <div class="grid grid-cols-2 gap-md cards-stats-grid">
337
- <div>
338
- <div class="cards-stat-value primary">1.2K</div>
339
- <div class="cards-stat-label">Followers</div>
340
- </div>
341
- <div>
342
- <div class="cards-stat-value secondary">847</div>
343
- <div class="cards-stat-label">Following</div>
344
- </div>
345
- </div>
346
- <button class="btn-outline btn-sm">View All</button>
347
- </article>
348
-
349
- </div>
350
- </div>
351
- `;
352
-
353
- ComplexCards.storyName = 'Complex Cards';
71
+ `;
72
+ },
73
+ args: {
74
+ preset: 'default'
75
+ }
76
+ };
@@ -1,20 +1,11 @@
1
1
  import { html } from 'lit';
2
- import { toastFormData } from '../utils/toast-utils.js';
3
2
 
4
3
  export default {
5
4
  title: 'Primitives/Forms',
6
- tags: ['buttons', 'forms'],
7
5
  parameters: {
8
- pds: {
9
- tags: ['buttons', 'forms']
10
- },
11
6
  docs: {
12
7
  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.`
8
+ component: 'Basic UI elements - buttons, forms, cards, badges'
18
9
  }
19
10
  }
20
11
  },
@@ -37,95 +28,173 @@ These primitive form controls provide the foundation for manual form building wh
37
28
 
38
29
  export const Default = {
39
30
  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
- };
31
+ // Apply preset if changed
32
+ if (args.preset) {
33
+ import('../../../src/js/pds.js').then(({ PDS }) => {
34
+ PDS.applyDesign({ preset: args.preset });
35
+ });
36
+ }
37
+
38
+ // Apply color overrides
39
+ if (args.primaryColor || args.secondaryColor) {
40
+ import('../../../src/js/pds.js').then(({ PDS }) => {
41
+ PDS.applyDesign({
42
+ design: {
43
+ colors: {
44
+ primary: args.primaryColor,
45
+ secondary: args.secondaryColor
46
+ }
47
+ }
48
+ });
49
+ });
50
+ }
51
+
45
52
 
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
53
 
89
- export const InputsWithIcons = {
90
- render: (args) => {
91
54
  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>
55
+ <div class="story-container" style="padding: 2rem;">
56
+ <h2>
57
+ <pds-icon
58
+ icon="note-pencil"
59
+ size="lg"
60
+ class="icon-primary"
61
+ ></pds-icon>
62
+ Form Controls
63
+ </h2>
64
+
65
+ <form
66
+ class="form-demo"
67
+ onsubmit="event.preventDefault(); console.log('Form submitted (prevented)'); return false;"
68
+ >
69
+ <fieldset>
70
+ <legend>Personal Information</legend>
71
+
72
+ <label>
73
+ <span>Full Name</span>
74
+ <input type="text" placeholder="Enter your name" required />
75
+ </label>
76
+
77
+ <label>
78
+ <span>Email</span>
79
+ <input
80
+ type="email"
81
+ placeholder="you@example.com"
82
+ autocomplete="username"
83
+ required
84
+ />
85
+ </label>
86
+
87
+ <label>
88
+ <span>Phone</span>
89
+ <input type="tel" placeholder="+1 (555) 000-0000" />
90
+ </label>
91
+
92
+ <label>
93
+ <span>Date of Birth</span>
94
+ <input type="date" />
95
+ </label>
96
+
97
+ <label>
98
+ <span>Rich Text</span>
99
+ <pds-richtext
100
+ name="richtext"
101
+ placeholder="Enter rich text"
102
+ ></pds-richtext>
103
+ </label>
104
+
105
+ <label>
106
+ <span>Password</span>
107
+ <input
108
+ type="password"
109
+ placeholder="Enter password"
110
+ autocomplete="current-password"
111
+ />
112
+ </label>
113
+
114
+ <label>
115
+ <span>Country</span>
116
+ <select>
117
+ <option>United States</option>
118
+ <option>Canada</option>
119
+ <option>United Kingdom</option>
120
+ <option>Germany</option>
121
+ <option>France</option>
122
+ <option>Other</option>
123
+ </select>
124
+ </label>
125
+
126
+ <label>
127
+ <span>Number</span>
128
+ <input type="number" min="0" max="100" value="50" />
129
+ </label>
130
+
131
+ <label>
132
+ <span>Range</span>
133
+ <input type="range" min="0" max="100" value="50" />
134
+ </label>
135
+
136
+ <label>
137
+ <span>URL</span>
138
+ <input type="url" placeholder="https://example.com" />
139
+ </label>
140
+
141
+ <label>
142
+ <span>File Upload</span>
143
+ <pds-upload name="file"></pds-upload>
144
+ </label>
145
+
146
+ <label>
147
+ <span>Message</span>
148
+ <textarea
149
+ rows="4"
150
+ placeholder="Your message here..."
151
+ ></textarea>
152
+ </label>
153
+ </fieldset>
154
+
155
+ <fieldset>
156
+ <legend>Preferences</legend>
157
+
158
+ <label data-toggle>
159
+ <input type="checkbox" checked />
160
+ Subscribe to newsletter
161
+ </label>
162
+
163
+ <label data-toggle>
164
+ <input type="checkbox" />
165
+ Receive marketing emails
166
+ </label>
167
+ </fieldset>
168
+
169
+ <fieldset>
170
+ <legend>Toggle Switches (Progressive Enhancement)</legend>
171
+
172
+ <label data-toggle>
173
+ <input type="checkbox" checked />
174
+ Enable notifications
175
+ </label>
176
+
177
+ <label data-toggle>
178
+ <input type="checkbox" />
179
+ Dark mode
180
+ </label>
181
+
182
+ <label data-toggle>
183
+ <input type="checkbox" checked />
184
+ Auto-save
185
+ </label>
186
+ </fieldset>
187
+
188
+ <div class="form-demo-actions">
189
+ <button type="submit" class="btn-primary">Submit Form</button>
190
+ <button type="reset" class="btn-secondary">Reset</button>
191
+ <button type="button" class="btn-outline">Cancel</button>
192
+ </div>
193
+ </form>
118
194
  </div>
119
195
  `;
120
196
  },
121
197
  args: {
122
198
  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
199
  }
131
200
  };