@reliability-design/web 1.0.2

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 (60) hide show
  1. package/dist/components/rel-accordion/rel-accordion.stories.ts +313 -0
  2. package/dist/components/rel-accordion/rel-accordion.ts +114 -0
  3. package/dist/components/rel-alert/rel-alert.stories.ts +412 -0
  4. package/dist/components/rel-alert/rel-alert.ts +194 -0
  5. package/dist/components/rel-avatar/rel-avatar.stories.ts +327 -0
  6. package/dist/components/rel-avatar/rel-avatar.ts +100 -0
  7. package/dist/components/rel-badge/rel-badge.stories.ts +350 -0
  8. package/dist/components/rel-badge/rel-badge.ts +70 -0
  9. package/dist/components/rel-breadcrumb/rel-breadcrumb.stories.ts +306 -0
  10. package/dist/components/rel-breadcrumb/rel-breadcrumb.ts +97 -0
  11. package/dist/components/rel-button/rel-button.stories.ts +356 -0
  12. package/dist/components/rel-button/rel-button.ts +204 -0
  13. package/dist/components/rel-card/rel-card.stories.ts +299 -0
  14. package/dist/components/rel-card/rel-card.ts +33 -0
  15. package/dist/components/rel-cardmedia/rel-cardmedia.stories.ts +368 -0
  16. package/dist/components/rel-cardmedia/rel-cardmedia.ts +80 -0
  17. package/dist/components/rel-checkbox/rel-checkbox.stories.ts +414 -0
  18. package/dist/components/rel-checkbox/rel-checkbox.ts +164 -0
  19. package/dist/components/rel-chip/rel-chip.stories.ts +552 -0
  20. package/dist/components/rel-chip/rel-chip.ts +261 -0
  21. package/dist/components/rel-container/rel-container.stories.ts +239 -0
  22. package/dist/components/rel-container/rel-container.ts +74 -0
  23. package/dist/components/rel-divider/rel-divider.stories.ts +229 -0
  24. package/dist/components/rel-divider/rel-divider.ts +44 -0
  25. package/dist/components/rel-layout/rel-layout.stories.ts +713 -0
  26. package/dist/components/rel-layout/rel-layout.ts +60 -0
  27. package/dist/components/rel-menu/rel-menu.stories.ts +910 -0
  28. package/dist/components/rel-menu/rel-menu.ts +319 -0
  29. package/dist/components/rel-progress/rel-progress.stories.ts +817 -0
  30. package/dist/components/rel-progress/rel-progress.ts +182 -0
  31. package/dist/components/rel-radio/rel-radio.stories.ts +1048 -0
  32. package/dist/components/rel-radio/rel-radio.ts +187 -0
  33. package/dist/components/rel-segmented-button/rel-segmented-button.stories.ts +1079 -0
  34. package/dist/components/rel-segmented-button/rel-segmented-button.ts +150 -0
  35. package/dist/components/rel-select/rel-select.stories.ts +1201 -0
  36. package/dist/components/rel-select/rel-select.ts +261 -0
  37. package/dist/components/rel-slider/rel-slider.stories.ts +730 -0
  38. package/dist/components/rel-slider/rel-slider.ts +440 -0
  39. package/dist/components/rel-snackbar/rel-snackbar.stories.ts +808 -0
  40. package/dist/components/rel-snackbar/rel-snackbar.ts +212 -0
  41. package/dist/components/rel-stepper/rel-stepper.stories.ts +752 -0
  42. package/dist/components/rel-stepper/rel-stepper.ts +425 -0
  43. package/dist/components/rel-switch/rel-switch.stories.ts +441 -0
  44. package/dist/components/rel-switch/rel-switch.ts +161 -0
  45. package/dist/components/rel-tab/rel-tab.stories.ts +492 -0
  46. package/dist/components/rel-tab/rel-tab.ts +145 -0
  47. package/dist/components/rel-textfield/rel-textfield.stories.ts +710 -0
  48. package/dist/components/rel-textfield/rel-textfield.ts +224 -0
  49. package/dist/components/rel-toast/rel-toast.stories.ts +394 -0
  50. package/dist/components/rel-toast/rel-toast.ts +154 -0
  51. package/dist/components/rel-tooltip/rel-tooltip.stories.ts +364 -0
  52. package/dist/components/rel-tooltip/rel-tooltip.ts +80 -0
  53. package/dist/index.d.mts +372 -0
  54. package/dist/index.d.ts +372 -0
  55. package/dist/index.js +4593 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/index.mjs +4544 -0
  58. package/dist/index.mjs.map +1 -0
  59. package/dist/styles/vars.css +184 -0
  60. package/package.json +32 -0
@@ -0,0 +1,710 @@
1
+ import type { Meta, StoryObj } from '@storybook/web-components-vite';
2
+ import { html } from 'lit';
3
+ import './rel-textfield';
4
+
5
+ /**
6
+ * The TextField component is a versatile input element that supports multiple states,
7
+ * sizes, input types, and icon configurations. Built with Lit web components.
8
+ *
9
+ * ## Features
10
+ * - **4 States**: default, focused, error, disabled
11
+ * - **3 Sizes**: small, medium, large
12
+ * - **Icon Support**: Left icon, right icon, or both
13
+ * - **Input Types**: text, password, email, number, search, tel, url
14
+ * - **Supporting Text**: Helper text and error messages
15
+ * - **Labels**: Optional field labels
16
+ * - **Accessibility**: Full ARIA support and keyboard navigation
17
+ */
18
+ const meta: Meta = {
19
+ title: 'Components/TextField',
20
+ tags: ['autodocs'],
21
+ component: 'rel-textfield',
22
+ argTypes: {
23
+ label: {
24
+ control: 'text',
25
+ description: 'Label text for the input field',
26
+ table: {
27
+ type: { summary: 'string' },
28
+ },
29
+ },
30
+ placeholder: {
31
+ control: 'text',
32
+ description: 'Placeholder text',
33
+ table: {
34
+ defaultValue: { summary: '""' },
35
+ type: { summary: 'string' },
36
+ },
37
+ },
38
+ type: {
39
+ control: { type: 'select' },
40
+ options: ['text', 'password', 'email', 'number', 'search', 'tel', 'url'],
41
+ description: 'HTML input type',
42
+ table: {
43
+ defaultValue: { summary: 'text' },
44
+ type: { summary: 'string' },
45
+ },
46
+ },
47
+ value: {
48
+ control: 'text',
49
+ description: 'Current value of the input',
50
+ table: {
51
+ defaultValue: { summary: '""' },
52
+ type: { summary: 'string' },
53
+ },
54
+ },
55
+ state: {
56
+ control: { type: 'select' },
57
+ options: ['default', 'focused', 'error', 'disabled'],
58
+ description: 'Visual state of the input',
59
+ table: {
60
+ defaultValue: { summary: 'default' },
61
+ type: { summary: 'string' },
62
+ },
63
+ },
64
+ size: {
65
+ control: { type: 'select' },
66
+ options: ['small', 'medium', 'large'],
67
+ description: 'Input field size',
68
+ table: {
69
+ defaultValue: { summary: 'medium' },
70
+ type: { summary: 'string' },
71
+ },
72
+ },
73
+ supportingText: {
74
+ control: 'text',
75
+ description: 'Helper or error message text',
76
+ table: {
77
+ type: { summary: 'string' },
78
+ },
79
+ },
80
+ leftIcon: {
81
+ control: 'text',
82
+ description: 'Icon to display on the left (SVG or emoji)',
83
+ table: {
84
+ type: { summary: 'string' },
85
+ },
86
+ },
87
+ rightIcon: {
88
+ control: 'text',
89
+ description: 'Icon to display on the right (SVG or emoji)',
90
+ table: {
91
+ type: { summary: 'string' },
92
+ },
93
+ },
94
+ },
95
+ render: (args) => html`
96
+ <rel-textfield
97
+ label="${args.label || ''}"
98
+ placeholder="${args.placeholder || ''}"
99
+ type="${args.type || 'text'}"
100
+ value="${args.value || ''}"
101
+ state="${args.state || 'default'}"
102
+ size="${args.size || 'medium'}"
103
+ supportingText="${args.supportingText || ''}"
104
+ leftIcon="${args.leftIcon || ''}"
105
+ rightIcon="${args.rightIcon || ''}"
106
+ ></rel-textfield>
107
+ `,
108
+ };
109
+
110
+ export default meta;
111
+ type Story = StoryObj;
112
+
113
+ /**
114
+ * Default text field - basic input with label
115
+ */
116
+ export const Default: Story = {
117
+ args: {
118
+ label: 'Username',
119
+ placeholder: 'Enter your username',
120
+ },
121
+ };
122
+
123
+ /**
124
+ * Medium size (default) - standard input height
125
+ */
126
+ export const MediumSize: Story = {
127
+ args: {
128
+ label: 'Email Address',
129
+ placeholder: 'you@example.com',
130
+ size: 'medium',
131
+ },
132
+ };
133
+
134
+ /**
135
+ * Small size - compact input for tight layouts
136
+ */
137
+ export const SmallSize: Story = {
138
+ args: {
139
+ label: 'Search',
140
+ placeholder: 'Search...',
141
+ size: 'small',
142
+ },
143
+ };
144
+
145
+ /**
146
+ * Large size - prominent input for important fields
147
+ */
148
+ export const LargeSize: Story = {
149
+ args: {
150
+ label: 'Full Name',
151
+ placeholder: 'John Doe',
152
+ size: 'large',
153
+ },
154
+ };
155
+
156
+ /**
157
+ * With left icon - visual indicator on the left
158
+ */
159
+ export const WithLeftIcon: Story = {
160
+ args: {
161
+ label: 'Email',
162
+ placeholder: 'Enter email',
163
+ leftIcon: '📧',
164
+ },
165
+ };
166
+
167
+ /**
168
+ * With right icon - visual indicator on the right
169
+ */
170
+ export const WithRightIcon: Story = {
171
+ args: {
172
+ label: 'Search',
173
+ placeholder: 'Search products...',
174
+ rightIcon: '🔍',
175
+ },
176
+ };
177
+
178
+ /**
179
+ * With both icons - icons on both sides
180
+ */
181
+ export const WithBothIcons: Story = {
182
+ args: {
183
+ label: 'Amount',
184
+ placeholder: '0.00',
185
+ leftIcon: '💲',
186
+ rightIcon: '✓',
187
+ },
188
+ };
189
+
190
+ /**
191
+ * With supporting text - helper text below input
192
+ */
193
+ export const WithSupportingText: Story = {
194
+ args: {
195
+ label: 'Password',
196
+ type: 'password',
197
+ placeholder: 'Enter password',
198
+ supportingText: 'Must be at least 8 characters',
199
+ },
200
+ };
201
+
202
+ /**
203
+ * Error state - shows validation error
204
+ */
205
+ export const ErrorState: Story = {
206
+ args: {
207
+ label: 'Email',
208
+ placeholder: 'you@example.com',
209
+ value: 'invalid-email',
210
+ state: 'error',
211
+ supportingText: 'Please enter a valid email address',
212
+ },
213
+ };
214
+
215
+ /**
216
+ * Error with icon - error state with visual indicator
217
+ */
218
+ export const ErrorWithIcon: Story = {
219
+ args: {
220
+ label: 'Phone Number',
221
+ placeholder: '+1 (555) 000-0000',
222
+ value: '123',
223
+ state: 'error',
224
+ leftIcon: '📱',
225
+ supportingText: 'Phone number is too short',
226
+ },
227
+ };
228
+
229
+ /**
230
+ * Disabled state - non-interactive input
231
+ */
232
+ export const Disabled: Story = {
233
+ args: {
234
+ label: 'Account ID',
235
+ value: 'ACC-12345',
236
+ state: 'disabled',
237
+ supportingText: 'This field cannot be edited',
238
+ },
239
+ };
240
+
241
+ /**
242
+ * Disabled with icon - disabled input with icon
243
+ */
244
+ export const DisabledWithIcon: Story = {
245
+ args: {
246
+ label: 'User ID',
247
+ value: 'USER-98765',
248
+ state: 'disabled',
249
+ leftIcon: '👤',
250
+ },
251
+ };
252
+
253
+ /**
254
+ * Password input - secure password field
255
+ */
256
+ export const PasswordInput: Story = {
257
+ args: {
258
+ label: 'Password',
259
+ type: 'password',
260
+ placeholder: 'Enter your password',
261
+ leftIcon: '🔒',
262
+ },
263
+ };
264
+
265
+ /**
266
+ * Email input - email type with validation
267
+ */
268
+ export const EmailInput: Story = {
269
+ args: {
270
+ label: 'Email Address',
271
+ type: 'email',
272
+ placeholder: 'name@company.com',
273
+ leftIcon: '✉️',
274
+ },
275
+ };
276
+
277
+ /**
278
+ * Number input - numeric input field
279
+ */
280
+ export const NumberInput: Story = {
281
+ args: {
282
+ label: 'Age',
283
+ type: 'number',
284
+ placeholder: '18',
285
+ },
286
+ };
287
+
288
+ /**
289
+ * Search input - search field with icon
290
+ */
291
+ export const SearchInput: Story = {
292
+ args: {
293
+ label: 'Search',
294
+ type: 'search',
295
+ placeholder: 'Search products, orders, customers...',
296
+ leftIcon: '🔍',
297
+ },
298
+ };
299
+
300
+ /**
301
+ * Tel input - telephone number field
302
+ */
303
+ export const TelInput: Story = {
304
+ args: {
305
+ label: 'Phone Number',
306
+ type: 'tel',
307
+ placeholder: '+1 (555) 000-0000',
308
+ leftIcon: '📞',
309
+ },
310
+ };
311
+
312
+ /**
313
+ * URL input - website URL field
314
+ */
315
+ export const URLInput: Story = {
316
+ args: {
317
+ label: 'Website',
318
+ type: 'url',
319
+ placeholder: 'https://example.com',
320
+ leftIcon: '🌐',
321
+ },
322
+ };
323
+
324
+ /**
325
+ * Without label - input without label text
326
+ */
327
+ export const WithoutLabel: Story = {
328
+ args: {
329
+ placeholder: 'Quick search...',
330
+ leftIcon: '🔍',
331
+ },
332
+ };
333
+
334
+ /**
335
+ * Pre-filled value - input with existing value
336
+ */
337
+ export const PrefilledValue: Story = {
338
+ args: {
339
+ label: 'Full Name',
340
+ value: 'John Doe',
341
+ },
342
+ };
343
+
344
+ /**
345
+ * All sizes comparison - shows all three sizes
346
+ */
347
+ export const AllSizes: Story = {
348
+ render: () => html`
349
+ <div style="display: flex; flex-direction: column; gap: 24px; padding: 24px; max-width: 400px;">
350
+ <rel-textfield
351
+ label="Small Size"
352
+ placeholder="Small input"
353
+ size="small"
354
+ ></rel-textfield>
355
+ <rel-textfield
356
+ label="Medium Size"
357
+ placeholder="Medium input"
358
+ size="medium"
359
+ ></rel-textfield>
360
+ <rel-textfield
361
+ label="Large Size"
362
+ placeholder="Large input"
363
+ size="large"
364
+ ></rel-textfield>
365
+ </div>
366
+ `,
367
+ };
368
+
369
+ /**
370
+ * All states comparison - shows all four states
371
+ */
372
+ export const AllStates: Story = {
373
+ render: () => html`
374
+ <div style="display: flex; flex-direction: column; gap: 24px; padding: 24px; max-width: 400px;">
375
+ <rel-textfield
376
+ label="Default State"
377
+ placeholder="Default input"
378
+ state="default"
379
+ ></rel-textfield>
380
+ <rel-textfield
381
+ label="Focused State"
382
+ placeholder="Focused input"
383
+ state="focused"
384
+ supportingText="This field is currently focused"
385
+ ></rel-textfield>
386
+ <rel-textfield
387
+ label="Error State"
388
+ value="invalid@"
389
+ state="error"
390
+ supportingText="Please enter a valid value"
391
+ ></rel-textfield>
392
+ <rel-textfield
393
+ label="Disabled State"
394
+ value="Cannot edit this"
395
+ state="disabled"
396
+ supportingText="This field is disabled"
397
+ ></rel-textfield>
398
+ </div>
399
+ `,
400
+ };
401
+
402
+ /**
403
+ * Icon variations - different icon positions
404
+ */
405
+ export const IconVariations: Story = {
406
+ render: () => html`
407
+ <div style="display: flex; flex-direction: column; gap: 24px; padding: 24px; max-width: 400px;">
408
+ <rel-textfield
409
+ label="No Icons"
410
+ placeholder="Plain input"
411
+ ></rel-textfield>
412
+ <rel-textfield
413
+ label="Left Icon"
414
+ placeholder="Search..."
415
+ leftIcon="🔍"
416
+ ></rel-textfield>
417
+ <rel-textfield
418
+ label="Right Icon"
419
+ placeholder="Enter text"
420
+ rightIcon="✓"
421
+ ></rel-textfield>
422
+ <rel-textfield
423
+ label="Both Icons"
424
+ placeholder="Amount"
425
+ leftIcon="💲"
426
+ rightIcon="✓"
427
+ ></rel-textfield>
428
+ </div>
429
+ `,
430
+ };
431
+
432
+ /**
433
+ * Input types showcase - different input types
434
+ */
435
+ export const InputTypes: Story = {
436
+ render: () => html`
437
+ <div style="display: flex; flex-direction: column; gap: 24px; padding: 24px; max-width: 400px;">
438
+ <rel-textfield
439
+ label="Text"
440
+ type="text"
441
+ placeholder="Enter text"
442
+ ></rel-textfield>
443
+ <rel-textfield
444
+ label="Password"
445
+ type="password"
446
+ placeholder="Enter password"
447
+ leftIcon="🔒"
448
+ ></rel-textfield>
449
+ <rel-textfield
450
+ label="Email"
451
+ type="email"
452
+ placeholder="you@example.com"
453
+ leftIcon="📧"
454
+ ></rel-textfield>
455
+ <rel-textfield
456
+ label="Number"
457
+ type="number"
458
+ placeholder="123"
459
+ ></rel-textfield>
460
+ <rel-textfield
461
+ label="Search"
462
+ type="search"
463
+ placeholder="Search..."
464
+ leftIcon="🔍"
465
+ ></rel-textfield>
466
+ <rel-textfield
467
+ label="Phone"
468
+ type="tel"
469
+ placeholder="+1 (555) 000-0000"
470
+ leftIcon="📱"
471
+ ></rel-textfield>
472
+ <rel-textfield
473
+ label="Website"
474
+ type="url"
475
+ placeholder="https://example.com"
476
+ leftIcon="🌐"
477
+ ></rel-textfield>
478
+ </div>
479
+ `,
480
+ };
481
+
482
+ /**
483
+ * Form example - realistic form layout
484
+ */
485
+ export const FormExample: Story = {
486
+ render: () => html`
487
+ <div style="display: flex; flex-direction: column; gap: 20px; padding: 24px; max-width: 500px; background: #f5f5f5; border-radius: 8px;">
488
+ <h3 style="margin: 0 0 8px 0; font-size: 1.5rem;">Create Account</h3>
489
+ <rel-textfield
490
+ label="Full Name"
491
+ placeholder="John Doe"
492
+ leftIcon="👤"
493
+ ></rel-textfield>
494
+ <rel-textfield
495
+ label="Email Address"
496
+ type="email"
497
+ placeholder="you@example.com"
498
+ leftIcon="📧"
499
+ supportingText="We'll never share your email"
500
+ ></rel-textfield>
501
+ <rel-textfield
502
+ label="Password"
503
+ type="password"
504
+ placeholder="Min. 8 characters"
505
+ leftIcon="🔒"
506
+ supportingText="Must include letters and numbers"
507
+ ></rel-textfield>
508
+ <rel-textfield
509
+ label="Phone Number (Optional)"
510
+ type="tel"
511
+ placeholder="+1 (555) 000-0000"
512
+ leftIcon="📱"
513
+ ></rel-textfield>
514
+ </div>
515
+ `,
516
+ };
517
+
518
+ /**
519
+ * Small size variations - all states in small size
520
+ */
521
+ export const SmallSizeAllStates: Story = {
522
+ render: () => html`
523
+ <div style="display: flex; flex-direction: column; gap: 20px; padding: 24px; max-width: 400px;">
524
+ <rel-textfield
525
+ size="small"
526
+ label="Default"
527
+ placeholder="Default small"
528
+ ></rel-textfield>
529
+ <rel-textfield
530
+ size="small"
531
+ label="With Icon"
532
+ placeholder="Small with icon"
533
+ leftIcon="🔍"
534
+ ></rel-textfield>
535
+ <rel-textfield
536
+ size="small"
537
+ label="Error"
538
+ value="invalid"
539
+ state="error"
540
+ supportingText="Error in small size"
541
+ ></rel-textfield>
542
+ <rel-textfield
543
+ size="small"
544
+ label="Disabled"
545
+ value="Disabled small"
546
+ state="disabled"
547
+ ></rel-textfield>
548
+ </div>
549
+ `,
550
+ };
551
+
552
+ /**
553
+ * Large size variations - all states in large size
554
+ */
555
+ export const LargeSizeAllStates: Story = {
556
+ render: () => html`
557
+ <div style="display: flex; flex-direction: column; gap: 20px; padding: 24px; max-width: 500px;">
558
+ <rel-textfield
559
+ size="large"
560
+ label="Default"
561
+ placeholder="Default large"
562
+ ></rel-textfield>
563
+ <rel-textfield
564
+ size="large"
565
+ label="With Icon"
566
+ placeholder="Large with icon"
567
+ leftIcon="🔍"
568
+ ></rel-textfield>
569
+ <rel-textfield
570
+ size="large"
571
+ label="Error"
572
+ value="invalid"
573
+ state="error"
574
+ supportingText="Error in large size"
575
+ ></rel-textfield>
576
+ <rel-textfield
577
+ size="large"
578
+ label="Disabled"
579
+ value="Disabled large"
580
+ state="disabled"
581
+ ></rel-textfield>
582
+ </div>
583
+ `,
584
+ };
585
+
586
+ /**
587
+ * Login form - realistic login example
588
+ */
589
+ export const LoginForm: Story = {
590
+ render: () => html`
591
+ <div style="display: flex; flex-direction: column; gap: 20px; padding: 32px; max-width: 400px; background: white; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">
592
+ <h2 style="margin: 0 0 8px 0;">Sign In</h2>
593
+ <rel-textfield
594
+ label="Email"
595
+ type="email"
596
+ placeholder="Enter your email"
597
+ leftIcon="📧"
598
+ size="large"
599
+ ></rel-textfield>
600
+ <rel-textfield
601
+ label="Password"
602
+ type="password"
603
+ placeholder="Enter your password"
604
+ leftIcon="🔒"
605
+ size="large"
606
+ ></rel-textfield>
607
+ </div>
608
+ `,
609
+ };
610
+
611
+ /**
612
+ * Search variations - different search field styles
613
+ */
614
+ export const SearchVariations: Story = {
615
+ render: () => html`
616
+ <div style="display: flex; flex-direction: column; gap: 20px; padding: 24px; max-width: 500px;">
617
+ <rel-textfield
618
+ placeholder="Quick search"
619
+ type="search"
620
+ leftIcon="🔍"
621
+ size="small"
622
+ ></rel-textfield>
623
+ <rel-textfield
624
+ label="Search Products"
625
+ type="search"
626
+ placeholder="Search by name, SKU, or category..."
627
+ leftIcon="🔍"
628
+ size="medium"
629
+ ></rel-textfield>
630
+ <rel-textfield
631
+ type="search"
632
+ placeholder="What are you looking for?"
633
+ leftIcon="🔍"
634
+ rightIcon="✕"
635
+ size="large"
636
+ ></rel-textfield>
637
+ </div>
638
+ `,
639
+ };
640
+
641
+ /**
642
+ * Error variations - different error scenarios
643
+ */
644
+ export const ErrorVariations: Story = {
645
+ render: () => html`
646
+ <div style="display: flex; flex-direction: column; gap: 20px; padding: 24px; max-width: 400px;">
647
+ <rel-textfield
648
+ label="Email"
649
+ value="invalid-email"
650
+ state="error"
651
+ supportingText="Please enter a valid email address"
652
+ ></rel-textfield>
653
+ <rel-textfield
654
+ label="Password"
655
+ type="password"
656
+ value="123"
657
+ state="error"
658
+ leftIcon="🔒"
659
+ supportingText="Password must be at least 8 characters"
660
+ ></rel-textfield>
661
+ <rel-textfield
662
+ label="Phone"
663
+ value="+1 555"
664
+ state="error"
665
+ leftIcon="📱"
666
+ supportingText="Phone number is incomplete"
667
+ size="small"
668
+ ></rel-textfield>
669
+ <rel-textfield
670
+ label="Amount"
671
+ value="-50"
672
+ state="error"
673
+ leftIcon="💲"
674
+ supportingText="Amount must be positive"
675
+ size="large"
676
+ ></rel-textfield>
677
+ </div>
678
+ `,
679
+ };
680
+
681
+ /**
682
+ * Disabled variations - different disabled scenarios
683
+ */
684
+ export const DisabledVariations: Story = {
685
+ render: () => html`
686
+ <div style="display: flex; flex-direction: column; gap: 20px; padding: 24px; max-width: 400px;">
687
+ <rel-textfield
688
+ label="User ID"
689
+ value="USER-12345"
690
+ state="disabled"
691
+ size="small"
692
+ ></rel-textfield>
693
+ <rel-textfield
694
+ label="Account Type"
695
+ value="Premium Account"
696
+ state="disabled"
697
+ leftIcon="⭐"
698
+ size="medium"
699
+ ></rel-textfield>
700
+ <rel-textfield
701
+ label="Registration Date"
702
+ value="January 15, 2024"
703
+ state="disabled"
704
+ leftIcon="📅"
705
+ rightIcon="🔒"
706
+ size="large"
707
+ ></rel-textfield>
708
+ </div>
709
+ `,
710
+ };