@ivds/core 0.1.1

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 (154) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +215 -0
  3. package/lib/all.css +6802 -0
  4. package/lib/all.min.css +1 -0
  5. package/lib/base/base.css +215 -0
  6. package/lib/base/base.min.css +1 -0
  7. package/lib/components/_breadcrumb-mixins.scss +173 -0
  8. package/lib/components/_button-mixin.scss +120 -0
  9. package/lib/components/_card-mixin.scss +196 -0
  10. package/lib/components/_checkbox-mixin.scss +208 -0
  11. package/lib/components/_footer-mixin.scss +385 -0
  12. package/lib/components/_header-mixin.scss +275 -0
  13. package/lib/components/_navigation-mixins.scss +270 -0
  14. package/lib/components/_notification-mixin.scss +239 -0
  15. package/lib/components/_pagination-mixins.scss +280 -0
  16. package/lib/components/_radio-button-mixin.scss +207 -0
  17. package/lib/components/_tag-mixin.scss +261 -0
  18. package/lib/components/_text-input-mixin.scss +203 -0
  19. package/lib/components/all.css +3005 -0
  20. package/lib/components/all.min.css +1 -0
  21. package/lib/components/breadcrumb/breadcrumb.css +141 -0
  22. package/lib/components/breadcrumb/breadcrumb.min.css +1 -0
  23. package/lib/components/button/button.css +221 -0
  24. package/lib/components/button/button.min.css +1 -0
  25. package/lib/components/card/card.css +236 -0
  26. package/lib/components/card/card.min.css +1 -0
  27. package/lib/components/checkbox/checkbox.css +305 -0
  28. package/lib/components/checkbox/checkbox.min.css +1 -0
  29. package/lib/components/footer/footer.css +466 -0
  30. package/lib/components/footer/footer.min.css +1 -0
  31. package/lib/components/header/header.css +274 -0
  32. package/lib/components/header/header.min.css +1 -0
  33. package/lib/components/navigation/navigation.css +214 -0
  34. package/lib/components/navigation/navigation.min.css +1 -0
  35. package/lib/components/notification/notification.css +253 -0
  36. package/lib/components/notification/notification.min.css +1 -0
  37. package/lib/components/pagination/pagination.css +221 -0
  38. package/lib/components/pagination/pagination.min.css +1 -0
  39. package/lib/components/radio-button/radio-button.css +326 -0
  40. package/lib/components/radio-button/radio-button.min.css +1 -0
  41. package/lib/components/tag/tag.css +367 -0
  42. package/lib/components/tag/tag.min.css +1 -0
  43. package/lib/components/text-input/text-input.css +243 -0
  44. package/lib/components/text-input/text-input.min.css +1 -0
  45. package/lib/icons/icon-arrow-left.css +139 -0
  46. package/lib/icons/icon-arrow-left.min.css +1 -0
  47. package/lib/icons/icon-arrow-right.css +139 -0
  48. package/lib/icons/icon-arrow-right.min.css +1 -0
  49. package/lib/icons/icon-check.css +139 -0
  50. package/lib/icons/icon-check.min.css +1 -0
  51. package/lib/icons/icon-close.css +140 -0
  52. package/lib/icons/icon-close.min.css +1 -0
  53. package/lib/icons/icon-error.css +140 -0
  54. package/lib/icons/icon-error.min.css +1 -0
  55. package/lib/icons/icon-info.css +140 -0
  56. package/lib/icons/icon-info.min.css +1 -0
  57. package/lib/icons/icon-success.css +139 -0
  58. package/lib/icons/icon-success.min.css +1 -0
  59. package/lib/icons/icon-warning.css +139 -0
  60. package/lib/icons/icon-warning.min.css +1 -0
  61. package/lib/icons/icons.css +1158 -0
  62. package/lib/icons/icons.min.css +1 -0
  63. package/lib/utils/_flex.scss +200 -0
  64. package/lib/utils/_grid.scss +211 -0
  65. package/lib/utils/_layout.scss +253 -0
  66. package/lib/utils/_spacing.scss +260 -0
  67. package/lib/utils/_typography.scss +111 -0
  68. package/lib/utils/utils.css +2434 -0
  69. package/lib/utils/utils.min.css +1 -0
  70. package/lib/utils-only.css +2801 -0
  71. package/lib/utils-only.min.css +1 -0
  72. package/lib/variables/variables.css +2 -0
  73. package/lib/variables/variables.min.css +0 -0
  74. package/package.json +194 -0
  75. package/src/__tests__/example.test.scss +12 -0
  76. package/src/accessibility.stories.js +416 -0
  77. package/src/all.scss +9 -0
  78. package/src/base/_layout.scss +97 -0
  79. package/src/base/_reset.scss +85 -0
  80. package/src/base/_typography.scss +105 -0
  81. package/src/base/base.scss +6 -0
  82. package/src/components/all.scss +22 -0
  83. package/src/components/breadcrumb/_breadcrumb-mixins.scss +173 -0
  84. package/src/components/breadcrumb/breadcrumb.scss +68 -0
  85. package/src/components/breadcrumb/breadcrumb.stories.js +483 -0
  86. package/src/components/button/__tests__/button-mixins.test.scss +35 -0
  87. package/src/components/button/_button-mixin.scss +120 -0
  88. package/src/components/button/button.scss +126 -0
  89. package/src/components/button/button.stories.js +364 -0
  90. package/src/components/card/__tests__/card-mixins.test.scss +36 -0
  91. package/src/components/card/_card-mixin.scss +196 -0
  92. package/src/components/card/card.scss +193 -0
  93. package/src/components/card/card.stories.js +635 -0
  94. package/src/components/checkbox/_checkbox-mixin.scss +208 -0
  95. package/src/components/checkbox/checkbox.scss +141 -0
  96. package/src/components/checkbox/checkbox.stories.js +303 -0
  97. package/src/components/footer/_footer-mixin.scss +385 -0
  98. package/src/components/footer/footer.scss +86 -0
  99. package/src/components/footer/footer.stories.js +740 -0
  100. package/src/components/header/_header-mixin.scss +275 -0
  101. package/src/components/header/header.scss +84 -0
  102. package/src/components/header/header.stories.js +450 -0
  103. package/src/components/navigation/_navigation-mixins.scss +270 -0
  104. package/src/components/navigation/navigation.scss +64 -0
  105. package/src/components/navigation/navigation.stories.js +410 -0
  106. package/src/components/notification/_notification-mixin.scss +239 -0
  107. package/src/components/notification/notification.scss +118 -0
  108. package/src/components/notification/notification.stories.js +378 -0
  109. package/src/components/overview.stories.js +473 -0
  110. package/src/components/pagination/_pagination-mixins.scss +280 -0
  111. package/src/components/pagination/pagination.scss +76 -0
  112. package/src/components/pagination/pagination.stories.js +729 -0
  113. package/src/components/radio-button/_radio-button-mixin.scss +207 -0
  114. package/src/components/radio-button/radio-button.scss +178 -0
  115. package/src/components/radio-button/radio-button.stories.js +379 -0
  116. package/src/components/tag/_tag-mixin.scss +261 -0
  117. package/src/components/tag/tag.scss +244 -0
  118. package/src/components/tag/tag.stories.js +482 -0
  119. package/src/components/text-input/_text-input-mixin.scss +203 -0
  120. package/src/components/text-input/text-input.scss +150 -0
  121. package/src/components/text-input/text-input.stories.js +723 -0
  122. package/src/icons/_icon.scss +121 -0
  123. package/src/icons/icon-arrow-left.scss +23 -0
  124. package/src/icons/icon-arrow-right.scss +23 -0
  125. package/src/icons/icon-check.scss +23 -0
  126. package/src/icons/icon-close.scss +24 -0
  127. package/src/icons/icon-error.scss +24 -0
  128. package/src/icons/icon-info.scss +24 -0
  129. package/src/icons/icon-success.scss +23 -0
  130. package/src/icons/icon-warning.scss +23 -0
  131. package/src/icons/icons.scss +12 -0
  132. package/src/icons/icons.stories.js +249 -0
  133. package/src/icons/svg/arrow-left.svg +3 -0
  134. package/src/icons/svg/arrow-right.svg +3 -0
  135. package/src/icons/svg/check.svg +3 -0
  136. package/src/icons/svg/close.svg +4 -0
  137. package/src/icons/svg/error.svg +5 -0
  138. package/src/icons/svg/info.svg +5 -0
  139. package/src/icons/svg/success.svg +4 -0
  140. package/src/icons/svg/warning.svg +5 -0
  141. package/src/utils/__tests__/utilities.test.scss +37 -0
  142. package/src/utils/_flex.scss +200 -0
  143. package/src/utils/_grid.scss +211 -0
  144. package/src/utils/_layout.scss +253 -0
  145. package/src/utils/_spacing.scss +260 -0
  146. package/src/utils/_typography.scss +111 -0
  147. package/src/utils/utils.scss +8 -0
  148. package/src/variables/_borders.scss +15 -0
  149. package/src/variables/_breakpoints.scss +11 -0
  150. package/src/variables/_colors.scss +97 -0
  151. package/src/variables/_shadows.scss +14 -0
  152. package/src/variables/_spacing.scss +24 -0
  153. package/src/variables/_typography.scss +47 -0
  154. package/src/variables/variables.scss +9 -0
@@ -0,0 +1,723 @@
1
+ // Text Input component stories for Storybook
2
+ // Showcases all text input variants, sizes, states, and features
3
+
4
+ export default {
5
+ title: 'Core/Text Input',
6
+ parameters: {
7
+ docs: {
8
+ description: {
9
+ component: 'CSS-only text input component using IVDS design tokens. Provides multiple variants, sizes, states, and features for form inputs.'
10
+ }
11
+ },
12
+ a11y: {
13
+ config: {
14
+ rules: [
15
+ {
16
+ id: 'color-contrast',
17
+ enabled: true
18
+ },
19
+ {
20
+ id: 'label-title-only',
21
+ enabled: true
22
+ }
23
+ ]
24
+ }
25
+ }
26
+ }
27
+ };
28
+
29
+ // Basic text input
30
+ export const Default = () => `
31
+ <div class="ivds-text-input-wrapper">
32
+ <label class="ivds-text-input__label" for="default-input">
33
+ Default Input
34
+ </label>
35
+ <input
36
+ type="text"
37
+ id="default-input"
38
+ class="ivds-text-input"
39
+ placeholder="Enter text here..."
40
+ />
41
+ </div>
42
+ `;
43
+
44
+ // Text input with helper text
45
+ export const WithHelperText = () => `
46
+ <div class="ivds-text-input-wrapper">
47
+ <label class="ivds-text-input__label" for="helper-input">
48
+ Email Address
49
+ </label>
50
+ <input
51
+ type="email"
52
+ id="helper-input"
53
+ class="ivds-text-input"
54
+ placeholder="you@example.com"
55
+ />
56
+ <div class="ivds-text-input__helper">
57
+ We'll never share your email with anyone else.
58
+ </div>
59
+ </div>
60
+ `;
61
+
62
+ // Required field
63
+ export const Required = () => `
64
+ <div class="ivds-text-input-wrapper">
65
+ <label class="ivds-text-input__label ivds-text-input__label--required" for="required-input">
66
+ Full Name
67
+ </label>
68
+ <input
69
+ type="text"
70
+ id="required-input"
71
+ class="ivds-text-input"
72
+ placeholder="John Doe"
73
+ required
74
+ />
75
+ <div class="ivds-text-input__helper">
76
+ This field is required.
77
+ </div>
78
+ </div>
79
+ `;
80
+
81
+ // Input sizes
82
+ export const Sizes = () => `
83
+ <div style="display: flex; flex-direction: column; gap: 1.5rem;">
84
+ <div class="ivds-text-input-wrapper">
85
+ <label class="ivds-text-input__label" for="small-input">
86
+ Small Input
87
+ </label>
88
+ <input
89
+ type="text"
90
+ id="small-input"
91
+ class="ivds-text-input ivds-text-input--small"
92
+ placeholder="Small size"
93
+ />
94
+ </div>
95
+
96
+ <div class="ivds-text-input-wrapper">
97
+ <label class="ivds-text-input__label" for="default-size-input">
98
+ Default Input
99
+ </label>
100
+ <input
101
+ type="text"
102
+ id="default-size-input"
103
+ class="ivds-text-input"
104
+ placeholder="Default size"
105
+ />
106
+ </div>
107
+
108
+ <div class="ivds-text-input-wrapper">
109
+ <label class="ivds-text-input__label" for="large-input">
110
+ Large Input
111
+ </label>
112
+ <input
113
+ type="text"
114
+ id="large-input"
115
+ class="ivds-text-input ivds-text-input--large"
116
+ placeholder="Large size"
117
+ />
118
+ </div>
119
+ </div>
120
+ `;
121
+
122
+ // Input states
123
+ export const States = () => `
124
+ <div style="display: flex; flex-direction: column; gap: 1.5rem;">
125
+ <div class="ivds-text-input-wrapper">
126
+ <label class="ivds-text-input__label" for="error-input">
127
+ Error State
128
+ </label>
129
+ <input
130
+ type="text"
131
+ id="error-input"
132
+ class="ivds-text-input ivds-text-input--error"
133
+ placeholder="Invalid input"
134
+ value="invalid@email"
135
+ />
136
+ <div class="ivds-text-input__error">
137
+ Please enter a valid email address.
138
+ </div>
139
+ </div>
140
+
141
+ <div class="ivds-text-input-wrapper">
142
+ <label class="ivds-text-input__label" for="success-input">
143
+ Success State
144
+ </label>
145
+ <input
146
+ type="text"
147
+ id="success-input"
148
+ class="ivds-text-input ivds-text-input--success"
149
+ placeholder="Valid input"
150
+ value="user@example.com"
151
+ />
152
+ <div class="ivds-text-input__helper" style="color: var(--color-semantic-success-600, #059669);">
153
+ Email address is valid.
154
+ </div>
155
+ </div>
156
+
157
+ <div class="ivds-text-input-wrapper">
158
+ <label class="ivds-text-input__label" for="warning-input">
159
+ Warning State
160
+ </label>
161
+ <input
162
+ type="text"
163
+ id="warning-input"
164
+ class="ivds-text-input ivds-text-input--warning"
165
+ placeholder="Warning input"
166
+ value="user@tempmail.com"
167
+ />
168
+ <div class="ivds-text-input__helper" style="color: var(--color-semantic-warning-600, #d97706);">
169
+ This email domain might be temporary.
170
+ </div>
171
+ </div>
172
+ </div>
173
+ `;
174
+
175
+ // Disabled and readonly states
176
+ export const DisabledAndReadonly = () => `
177
+ <div style="display: flex; flex-direction: column; gap: 1.5rem;">
178
+ <div class="ivds-text-input-wrapper">
179
+ <label class="ivds-text-input__label" for="disabled-input">
180
+ Disabled Input
181
+ </label>
182
+ <input
183
+ type="text"
184
+ id="disabled-input"
185
+ class="ivds-text-input"
186
+ placeholder="This input is disabled"
187
+ disabled
188
+ />
189
+ <div class="ivds-text-input__helper">
190
+ This field is currently disabled.
191
+ </div>
192
+ </div>
193
+
194
+ <div class="ivds-text-input-wrapper">
195
+ <label class="ivds-text-input__label" for="readonly-input">
196
+ Readonly Input
197
+ </label>
198
+ <input
199
+ type="text"
200
+ id="readonly-input"
201
+ class="ivds-text-input"
202
+ value="This value cannot be changed"
203
+ readonly
204
+ />
205
+ <div class="ivds-text-input__helper">
206
+ This field is read-only.
207
+ </div>
208
+ </div>
209
+ </div>
210
+ `;
211
+
212
+ // Input with icons
213
+ export const WithIcons = () => `
214
+ <div style="display: flex; flex-direction: column; gap: 1.5rem;">
215
+ <div class="ivds-text-input-wrapper ivds-text-input-wrapper--icon-left">
216
+ <label class="ivds-text-input__label" for="icon-left-input">
217
+ Search
218
+ </label>
219
+ <div style="position: relative;">
220
+ <input
221
+ type="text"
222
+ id="icon-left-input"
223
+ class="ivds-text-input"
224
+ placeholder="Search for anything..."
225
+ />
226
+ <div class="ivds-text-input__icon">
227
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
228
+ <path d="M21 21L16.514 16.506M19 10.5A8.5 8.5 0 1 1 10.5 2A8.5 8.5 0 0 1 19 10.5Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
229
+ </svg>
230
+ </div>
231
+ </div>
232
+ </div>
233
+
234
+ <div class="ivds-text-input-wrapper ivds-text-input-wrapper--icon-right">
235
+ <label class="ivds-text-input__label" for="icon-right-input">
236
+ Password
237
+ </label>
238
+ <div style="position: relative;">
239
+ <input
240
+ type="password"
241
+ id="icon-right-input"
242
+ class="ivds-text-input"
243
+ placeholder="Enter your password"
244
+ />
245
+ <div class="ivds-text-input__icon">
246
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
247
+ <path d="M2 12S7 5 12 5S22 12 22 12S17 19 12 19S2 12 2 12Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
248
+ <circle cx="12" cy="12" r="3" stroke="currentColor" stroke-width="2"/>
249
+ </svg>
250
+ </div>
251
+ </div>
252
+ </div>
253
+ </div>
254
+ `;
255
+
256
+ // Input variants
257
+ export const Variants = () => `
258
+ <div style="display: flex; flex-direction: column; gap: 1.5rem;">
259
+ <div class="ivds-text-input-wrapper">
260
+ <label class="ivds-text-input__label" for="default-variant">
261
+ Default Variant
262
+ </label>
263
+ <input
264
+ type="text"
265
+ id="default-variant"
266
+ class="ivds-text-input"
267
+ placeholder="Default input style"
268
+ />
269
+ </div>
270
+
271
+ <div class="ivds-text-input-wrapper">
272
+ <label class="ivds-text-input__label" for="filled-variant">
273
+ Filled Variant
274
+ </label>
275
+ <input
276
+ type="text"
277
+ id="filled-variant"
278
+ class="ivds-text-input ivds-text-input--filled"
279
+ placeholder="Filled input style"
280
+ />
281
+ </div>
282
+
283
+ <div class="ivds-text-input-wrapper">
284
+ <label class="ivds-text-input__label" for="borderless-variant">
285
+ Borderless Variant
286
+ </label>
287
+ <input
288
+ type="text"
289
+ id="borderless-variant"
290
+ class="ivds-text-input ivds-text-input--borderless"
291
+ placeholder="Borderless input style"
292
+ />
293
+ </div>
294
+ </div>
295
+ `;
296
+
297
+ // Textarea
298
+ export const Textarea = () => `
299
+ <div style="display: flex; flex-direction: column; gap: 1.5rem;">
300
+ <div class="ivds-text-input-wrapper">
301
+ <label class="ivds-text-input__label" for="textarea-default">
302
+ Message
303
+ </label>
304
+ <textarea
305
+ id="textarea-default"
306
+ class="ivds-text-input ivds-text-input--textarea"
307
+ placeholder="Enter your message here..."
308
+ rows="4"
309
+ ></textarea>
310
+ <div class="ivds-text-input__helper">
311
+ Maximum 500 characters.
312
+ </div>
313
+ </div>
314
+
315
+ <div class="ivds-text-input-wrapper">
316
+ <label class="ivds-text-input__label" for="textarea-no-resize">
317
+ Fixed Size Textarea
318
+ </label>
319
+ <textarea
320
+ id="textarea-no-resize"
321
+ class="ivds-text-input ivds-text-input--textarea ivds-text-input--textarea--no-resize"
322
+ placeholder="This textarea cannot be resized..."
323
+ rows="3"
324
+ ></textarea>
325
+ </div>
326
+ </div>
327
+ `;
328
+
329
+ // Input groups with addons
330
+ export const InputGroups = () => `
331
+ <div style="display: flex; flex-direction: column; gap: 1.5rem;">
332
+ <div class="ivds-text-input-wrapper">
333
+ <label class="ivds-text-input__label" for="url-input">
334
+ Website URL
335
+ </label>
336
+ <div class="ivds-text-input-group">
337
+ <div class="ivds-text-input__addon">https://</div>
338
+ <input
339
+ type="text"
340
+ id="url-input"
341
+ class="ivds-text-input"
342
+ placeholder="example.com"
343
+ />
344
+ </div>
345
+ </div>
346
+
347
+ <div class="ivds-text-input-wrapper">
348
+ <label class="ivds-text-input__label" for="price-input">
349
+ Price
350
+ </label>
351
+ <div class="ivds-text-input-group">
352
+ <div class="ivds-text-input__addon">$</div>
353
+ <input
354
+ type="number"
355
+ id="price-input"
356
+ class="ivds-text-input"
357
+ placeholder="0.00"
358
+ />
359
+ <div class="ivds-text-input__addon">USD</div>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ `;
364
+
365
+ // Different input types
366
+ export const InputTypes = () => `
367
+ <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem;">
368
+ <div class="ivds-text-input-wrapper">
369
+ <label class="ivds-text-input__label" for="text-type">
370
+ Text
371
+ </label>
372
+ <input
373
+ type="text"
374
+ id="text-type"
375
+ class="ivds-text-input"
376
+ placeholder="Enter text"
377
+ />
378
+ </div>
379
+
380
+ <div class="ivds-text-input-wrapper">
381
+ <label class="ivds-text-input__label" for="email-type">
382
+ Email
383
+ </label>
384
+ <input
385
+ type="email"
386
+ id="email-type"
387
+ class="ivds-text-input"
388
+ placeholder="you@example.com"
389
+ />
390
+ </div>
391
+
392
+ <div class="ivds-text-input-wrapper">
393
+ <label class="ivds-text-input__label" for="password-type">
394
+ Password
395
+ </label>
396
+ <input
397
+ type="password"
398
+ id="password-type"
399
+ class="ivds-text-input"
400
+ placeholder="Enter password"
401
+ />
402
+ </div>
403
+
404
+ <div class="ivds-text-input-wrapper">
405
+ <label class="ivds-text-input__label" for="number-type">
406
+ Number
407
+ </label>
408
+ <input
409
+ type="number"
410
+ id="number-type"
411
+ class="ivds-text-input"
412
+ placeholder="123"
413
+ />
414
+ </div>
415
+
416
+ <div class="ivds-text-input-wrapper">
417
+ <label class="ivds-text-input__label" for="tel-type">
418
+ Phone
419
+ </label>
420
+ <input
421
+ type="tel"
422
+ id="tel-type"
423
+ class="ivds-text-input"
424
+ placeholder="+1 (555) 123-4567"
425
+ />
426
+ </div>
427
+
428
+ <div class="ivds-text-input-wrapper">
429
+ <label class="ivds-text-input__label" for="url-type">
430
+ URL
431
+ </label>
432
+ <input
433
+ type="url"
434
+ id="url-type"
435
+ class="ivds-text-input"
436
+ placeholder="https://example.com"
437
+ />
438
+ </div>
439
+
440
+ <div class="ivds-text-input-wrapper">
441
+ <label class="ivds-text-input__label" for="date-type">
442
+ Date
443
+ </label>
444
+ <input
445
+ type="date"
446
+ id="date-type"
447
+ class="ivds-text-input"
448
+ />
449
+ </div>
450
+
451
+ <div class="ivds-text-input-wrapper">
452
+ <label class="ivds-text-input__label" for="time-type">
453
+ Time
454
+ </label>
455
+ <input
456
+ type="time"
457
+ id="time-type"
458
+ class="ivds-text-input"
459
+ />
460
+ </div>
461
+ </div>
462
+ `;
463
+
464
+ // Accessibility example
465
+ export const AccessibilityFeatures = () => `
466
+ <div style="display: flex; flex-direction: column; gap: 1.5rem; max-width: 400px;">
467
+ <div class="ivds-text-input-wrapper">
468
+ <label class="ivds-text-input__label ivds-text-input__label--required" for="accessible-input">
469
+ Full Name
470
+ </label>
471
+ <input
472
+ type="text"
473
+ id="accessible-input"
474
+ class="ivds-text-input"
475
+ placeholder="John Doe"
476
+ aria-describedby="name-help name-error"
477
+ aria-required="true"
478
+ aria-invalid="false"
479
+ />
480
+ <div id="name-help" class="ivds-text-input__helper">
481
+ Enter your first and last name as they appear on official documents.
482
+ </div>
483
+ </div>
484
+
485
+ <div class="ivds-text-input-wrapper">
486
+ <label class="ivds-text-input__label" for="error-accessible">
487
+ Email Address
488
+ </label>
489
+ <input
490
+ type="email"
491
+ id="error-accessible"
492
+ class="ivds-text-input ivds-text-input--error"
493
+ placeholder="you@example.com"
494
+ value="invalid-email"
495
+ aria-describedby="email-error"
496
+ aria-invalid="true"
497
+ />
498
+ <div id="email-error" class="ivds-text-input__error" role="alert">
499
+ Please enter a valid email address.
500
+ </div>
501
+ </div>
502
+ </div>
503
+ `;
504
+
505
+ // HTML code examples
506
+ export const HTMLCodeExamples = () => `
507
+ <div style="display: flex; flex-direction: column; gap: 2rem; max-width: 800px;">
508
+ <div>
509
+ <h3 style="margin-bottom: 1rem;">Basic Text Input HTML</h3>
510
+ <div style="margin-bottom: 1rem;">
511
+ <div class="ivds-text-input-wrapper">
512
+ <label class="ivds-text-input__label" for="example-basic">
513
+ Email Address
514
+ </label>
515
+ <input
516
+ type="email"
517
+ id="example-basic"
518
+ class="ivds-text-input"
519
+ placeholder="you@example.com"
520
+ />
521
+ </div>
522
+ </div>
523
+ <pre style="background: #f8fafc; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; font-size: 0.875rem;"><code>&lt;div class="ivds-text-input-wrapper"&gt;
524
+ &lt;label class="ivds-text-input__label" for="email"&gt;
525
+ Email Address
526
+ &lt;/label&gt;
527
+ &lt;input
528
+ type="email"
529
+ id="email"
530
+ class="ivds-text-input"
531
+ placeholder="you@example.com"
532
+ /&gt;
533
+ &lt;/div&gt;</code></pre>
534
+ </div>
535
+
536
+ <div>
537
+ <h3 style="margin-bottom: 1rem;">Input with Helper Text HTML</h3>
538
+ <div style="margin-bottom: 1rem;">
539
+ <div class="ivds-text-input-wrapper">
540
+ <label class="ivds-text-input__label" for="example-helper">
541
+ Password
542
+ </label>
543
+ <input
544
+ type="password"
545
+ id="example-helper"
546
+ class="ivds-text-input"
547
+ placeholder="Enter your password"
548
+ />
549
+ <div class="ivds-text-input__helper">
550
+ Must be at least 8 characters long.
551
+ </div>
552
+ </div>
553
+ </div>
554
+ <pre style="background: #f8fafc; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; font-size: 0.875rem;"><code>&lt;div class="ivds-text-input-wrapper"&gt;
555
+ &lt;label class="ivds-text-input__label" for="password"&gt;
556
+ Password
557
+ &lt;/label&gt;
558
+ &lt;input
559
+ type="password"
560
+ id="password"
561
+ class="ivds-text-input"
562
+ placeholder="Enter your password"
563
+ /&gt;
564
+ &lt;div class="ivds-text-input__helper"&gt;
565
+ Must be at least 8 characters long.
566
+ &lt;/div&gt;
567
+ &lt;/div&gt;</code></pre>
568
+ </div>
569
+
570
+ <div>
571
+ <h3 style="margin-bottom: 1rem;">Input with Error State HTML</h3>
572
+ <div style="margin-bottom: 1rem;">
573
+ <div class="ivds-text-input-wrapper">
574
+ <label class="ivds-text-input__label" for="example-error">
575
+ Email Address
576
+ </label>
577
+ <input
578
+ type="email"
579
+ id="example-error"
580
+ class="ivds-text-input ivds-text-input--error"
581
+ value="invalid-email"
582
+ aria-invalid="true"
583
+ aria-describedby="email-error"
584
+ />
585
+ <div id="email-error" class="ivds-text-input__error" role="alert">
586
+ Please enter a valid email address.
587
+ </div>
588
+ </div>
589
+ </div>
590
+ <pre style="background: #f8fafc; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; font-size: 0.875rem;"><code>&lt;div class="ivds-text-input-wrapper"&gt;
591
+ &lt;label class="ivds-text-input__label" for="email"&gt;
592
+ Email Address
593
+ &lt;/label&gt;
594
+ &lt;input
595
+ type="email"
596
+ id="email"
597
+ class="ivds-text-input ivds-text-input--error"
598
+ value="invalid-email"
599
+ aria-invalid="true"
600
+ aria-describedby="email-error"
601
+ /&gt;
602
+ &lt;div id="email-error" class="ivds-text-input__error" role="alert"&gt;
603
+ Please enter a valid email address.
604
+ &lt;/div&gt;
605
+ &lt;/div&gt;</code></pre>
606
+ </div>
607
+
608
+ <div>
609
+ <h3 style="margin-bottom: 1rem;">Textarea HTML</h3>
610
+ <div style="margin-bottom: 1rem;">
611
+ <div class="ivds-text-input-wrapper">
612
+ <label class="ivds-text-input__label" for="example-textarea">
613
+ Message
614
+ </label>
615
+ <textarea
616
+ id="example-textarea"
617
+ class="ivds-text-input ivds-text-input--textarea"
618
+ placeholder="Enter your message here..."
619
+ rows="4"
620
+ ></textarea>
621
+ </div>
622
+ </div>
623
+ <pre style="background: #f8fafc; padding: 1rem; border-radius: 0.5rem; overflow-x: auto; font-size: 0.875rem;"><code>&lt;div class="ivds-text-input-wrapper"&gt;
624
+ &lt;label class="ivds-text-input__label" for="message"&gt;
625
+ Message
626
+ &lt;/label&gt;
627
+ &lt;textarea
628
+ id="message"
629
+ class="ivds-text-input ivds-text-input--textarea"
630
+ placeholder="Enter your message here..."
631
+ rows="4"
632
+ &gt;&lt;/textarea&gt;
633
+ &lt;/div&gt;</code></pre>
634
+ </div>
635
+ </div>
636
+ `;
637
+
638
+ // Form validation examples
639
+ export const FormValidationExamples = () => `
640
+ <div style="max-width: 600px; display: flex; flex-direction: column; gap: 2rem;">
641
+ <div class="ivds-card">
642
+ <div class="ivds-card__header">
643
+ <h3 class="ivds-card__title">Form Validation Example</h3>
644
+ </div>
645
+ <div class="ivds-card__body">
646
+ <form style="display: flex; flex-direction: column; gap: 1.5rem;">
647
+ <div class="ivds-text-input-wrapper">
648
+ <label class="ivds-text-input__label ivds-text-input__label--required" for="validation-name">
649
+ Full Name
650
+ </label>
651
+ <input
652
+ type="text"
653
+ id="validation-name"
654
+ class="ivds-text-input"
655
+ placeholder="Enter your full name"
656
+ required
657
+ aria-describedby="name-help"
658
+ />
659
+ <div id="name-help" class="ivds-text-input__helper">
660
+ Enter your first and last name.
661
+ </div>
662
+ </div>
663
+
664
+ <div class="ivds-text-input-wrapper">
665
+ <label class="ivds-text-input__label ivds-text-input__label--required" for="validation-email">
666
+ Email Address
667
+ </label>
668
+ <input
669
+ type="email"
670
+ id="validation-email"
671
+ class="ivds-text-input ivds-text-input--error"
672
+ value="invalid@"
673
+ required
674
+ aria-invalid="true"
675
+ aria-describedby="email-error"
676
+ />
677
+ <div id="email-error" class="ivds-text-input__error" role="alert">
678
+ Please enter a valid email address.
679
+ </div>
680
+ </div>
681
+
682
+ <div class="ivds-text-input-wrapper">
683
+ <label class="ivds-text-input__label" for="validation-phone">
684
+ Phone Number
685
+ </label>
686
+ <input
687
+ type="tel"
688
+ id="validation-phone"
689
+ class="ivds-text-input ivds-text-input--success"
690
+ value="+1 (555) 123-4567"
691
+ aria-describedby="phone-success"
692
+ />
693
+ <div id="phone-success" class="ivds-text-input__helper" style="color: var(--color-semantic-success-600, #059669);">
694
+ Phone number format is valid.
695
+ </div>
696
+ </div>
697
+
698
+ <div class="ivds-text-input-wrapper">
699
+ <label class="ivds-text-input__label" for="validation-message">
700
+ Additional Comments
701
+ </label>
702
+ <textarea
703
+ id="validation-message"
704
+ class="ivds-text-input ivds-text-input--textarea"
705
+ placeholder="Any additional information..."
706
+ rows="3"
707
+ maxlength="500"
708
+ aria-describedby="message-count"
709
+ ></textarea>
710
+ <div id="message-count" class="ivds-text-input__helper">
711
+ 0 / 500 characters
712
+ </div>
713
+ </div>
714
+
715
+ <div style="display: flex; gap: 1rem;">
716
+ <button type="submit" class="ivds-button ivds-button--primary">Submit</button>
717
+ <button type="reset" class="ivds-button ivds-button--secondary">Reset</button>
718
+ </div>
719
+ </form>
720
+ </div>
721
+ </div>
722
+ </div>
723
+ `;