snice 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. package/README.md +90 -41
  2. package/dist/components/accordion/snice-accordion-item.js +1 -1
  3. package/dist/components/accordion/snice-accordion-item.js.map +1 -1
  4. package/dist/components/accordion/snice-accordion.js +1 -1
  5. package/dist/components/accordion/snice-accordion.js.map +1 -1
  6. package/dist/components/alert/snice-alert.js +1 -1
  7. package/dist/components/alert/snice-alert.js.map +1 -1
  8. package/dist/components/avatar/snice-avatar.js +1 -1
  9. package/dist/components/avatar/snice-avatar.js.map +1 -1
  10. package/dist/components/badge/snice-badge.js +1 -1
  11. package/dist/components/badge/snice-badge.js.map +1 -1
  12. package/dist/components/banner/snice-banner.d.ts +22 -0
  13. package/dist/components/banner/snice-banner.js +180 -0
  14. package/dist/components/banner/snice-banner.js.map +1 -0
  15. package/dist/components/banner/snice-banner.types.d.ts +14 -0
  16. package/dist/components/breadcrumbs/snice-breadcrumbs.js +1 -1
  17. package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +1 -1
  18. package/dist/components/button/snice-button.js +1 -1
  19. package/dist/components/button/snice-button.js.map +1 -1
  20. package/dist/components/card/snice-card.js +1 -1
  21. package/dist/components/card/snice-card.js.map +1 -1
  22. package/dist/components/checkbox/snice-checkbox.js +1 -1
  23. package/dist/components/checkbox/snice-checkbox.js.map +1 -1
  24. package/dist/components/chip/snice-chip.js +1 -1
  25. package/dist/components/chip/snice-chip.js.map +1 -1
  26. package/dist/components/color-display/snice-color-display.d.ts +14 -0
  27. package/dist/components/color-display/snice-color-display.js +151 -0
  28. package/dist/components/color-display/snice-color-display.js.map +1 -0
  29. package/dist/components/color-display/snice-color-display.types.d.ts +10 -0
  30. package/dist/components/color-picker/snice-color-picker.d.ts +50 -0
  31. package/dist/components/color-picker/snice-color-picker.js +489 -0
  32. package/dist/components/color-picker/snice-color-picker.js.map +1 -0
  33. package/dist/components/color-picker/snice-color-picker.types.d.ts +19 -0
  34. package/dist/components/date-picker/snice-date-picker.js +1 -1
  35. package/dist/components/date-picker/snice-date-picker.js.map +1 -1
  36. package/dist/components/divider/snice-divider.js +1 -1
  37. package/dist/components/divider/snice-divider.js.map +1 -1
  38. package/dist/components/drawer/snice-drawer.js +1 -1
  39. package/dist/components/drawer/snice-drawer.js.map +1 -1
  40. package/dist/components/empty-state/snice-empty-state.d.ts +13 -0
  41. package/dist/components/empty-state/snice-empty-state.js +121 -0
  42. package/dist/components/empty-state/snice-empty-state.js.map +1 -0
  43. package/dist/components/empty-state/snice-empty-state.types.d.ts +9 -0
  44. package/dist/components/file-upload/snice-file-upload.d.ts +45 -0
  45. package/dist/components/file-upload/snice-file-upload.js +394 -0
  46. package/dist/components/file-upload/snice-file-upload.js.map +1 -0
  47. package/dist/components/file-upload/snice-file-upload.types.d.ts +22 -0
  48. package/dist/components/image/snice-image.d.ts +22 -0
  49. package/dist/components/image/snice-image.js +201 -0
  50. package/dist/components/image/snice-image.js.map +1 -0
  51. package/dist/components/image/snice-image.types.d.ts +17 -0
  52. package/dist/components/input/snice-input.js +1 -1
  53. package/dist/components/input/snice-input.js.map +1 -1
  54. package/dist/components/kpi/snice-kpi.d.ts +16 -0
  55. package/dist/components/kpi/snice-kpi.js +162 -0
  56. package/dist/components/kpi/snice-kpi.js.map +1 -0
  57. package/dist/components/kpi/snice-kpi.types.d.ts +12 -0
  58. package/dist/components/layout/snice-layout-blog.js +1 -1
  59. package/dist/components/layout/snice-layout-blog.js.map +1 -1
  60. package/dist/components/layout/snice-layout-card.js +1 -1
  61. package/dist/components/layout/snice-layout-card.js.map +1 -1
  62. package/dist/components/layout/snice-layout-centered.js +1 -1
  63. package/dist/components/layout/snice-layout-centered.js.map +1 -1
  64. package/dist/components/layout/snice-layout-dashboard.js +1 -1
  65. package/dist/components/layout/snice-layout-dashboard.js.map +1 -1
  66. package/dist/components/layout/snice-layout-fullscreen.js +1 -1
  67. package/dist/components/layout/snice-layout-fullscreen.js.map +1 -1
  68. package/dist/components/layout/snice-layout-landing.js +1 -1
  69. package/dist/components/layout/snice-layout-landing.js.map +1 -1
  70. package/dist/components/layout/snice-layout-minimal.js +1 -1
  71. package/dist/components/layout/snice-layout-minimal.js.map +1 -1
  72. package/dist/components/layout/snice-layout-sidebar.js +1 -1
  73. package/dist/components/layout/snice-layout-sidebar.js.map +1 -1
  74. package/dist/components/layout/snice-layout-split.js +1 -1
  75. package/dist/components/layout/snice-layout-split.js.map +1 -1
  76. package/dist/components/layout/snice-layout.js +1 -1
  77. package/dist/components/layout/snice-layout.js.map +1 -1
  78. package/dist/components/link/snice-link.d.ts +13 -0
  79. package/dist/components/link/snice-link.js +137 -0
  80. package/dist/components/link/snice-link.js.map +1 -0
  81. package/dist/components/link/snice-link.types.d.ts +11 -0
  82. package/dist/components/login/snice-login.js +1 -1
  83. package/dist/components/login/snice-login.js.map +1 -1
  84. package/dist/components/modal/snice-modal.js +1 -1
  85. package/dist/components/modal/snice-modal.js.map +1 -1
  86. package/dist/components/nav/snice-nav.js +1 -1
  87. package/dist/components/nav/snice-nav.js.map +1 -1
  88. package/dist/components/progress/snice-progress.js +1 -1
  89. package/dist/components/progress/snice-progress.js.map +1 -1
  90. package/dist/components/radio/snice-radio.js +1 -1
  91. package/dist/components/radio/snice-radio.js.map +1 -1
  92. package/dist/components/select/snice-select.js +1 -1
  93. package/dist/components/select/snice-select.js.map +1 -1
  94. package/dist/components/skeleton/snice-skeleton.js +1 -1
  95. package/dist/components/skeleton/snice-skeleton.js.map +1 -1
  96. package/dist/components/slider/snice-slider.d.ts +53 -0
  97. package/dist/components/slider/snice-slider.js +479 -0
  98. package/dist/components/slider/snice-slider.js.map +1 -0
  99. package/dist/components/slider/snice-slider.types.d.ts +26 -0
  100. package/dist/components/snice-cell-C0slgOpe.js +4 -0
  101. package/dist/components/snice-cell-C0slgOpe.js.map +1 -0
  102. package/dist/components/sparkline/snice-sparkline.d.ts +21 -0
  103. package/dist/components/sparkline/snice-sparkline.js +228 -0
  104. package/dist/components/sparkline/snice-sparkline.js.map +1 -0
  105. package/dist/components/sparkline/snice-sparkline.types.d.ts +16 -0
  106. package/dist/components/spinner/snice-spinner.d.ts +10 -0
  107. package/dist/components/spinner/snice-spinner.js +109 -0
  108. package/dist/components/spinner/snice-spinner.js.map +1 -0
  109. package/dist/components/spinner/snice-spinner.types.d.ts +8 -0
  110. package/dist/components/stepper/snice-stepper-panel.d.ts +8 -0
  111. package/dist/components/stepper/snice-stepper-panel.js +70 -0
  112. package/dist/components/stepper/snice-stepper-panel.js.map +1 -0
  113. package/dist/components/stepper/snice-stepper-panel.types.d.ts +4 -0
  114. package/dist/components/stepper/snice-stepper.d.ts +15 -0
  115. package/dist/components/stepper/snice-stepper.js +163 -0
  116. package/dist/components/stepper/snice-stepper.js.map +1 -0
  117. package/dist/components/stepper/snice-stepper.types.d.ts +13 -0
  118. package/dist/components/switch/snice-switch.js +1 -1
  119. package/dist/components/switch/snice-switch.js.map +1 -1
  120. package/dist/components/table/snice-cell-actions.js +1 -1
  121. package/dist/components/table/snice-cell-actions.js.map +1 -1
  122. package/dist/components/table/snice-cell-boolean.js +1 -1
  123. package/dist/components/table/snice-cell-color.js +1 -1
  124. package/dist/components/table/snice-cell-color.js.map +1 -1
  125. package/dist/components/table/snice-cell-currency.js +1 -1
  126. package/dist/components/table/snice-cell-date.js +1 -1
  127. package/dist/components/table/snice-cell-duration.js +1 -1
  128. package/dist/components/table/snice-cell-email.js +1 -1
  129. package/dist/components/table/snice-cell-email.js.map +1 -1
  130. package/dist/components/table/snice-cell-filesize.js +1 -1
  131. package/dist/components/table/snice-cell-image.js +1 -1
  132. package/dist/components/table/snice-cell-image.js.map +1 -1
  133. package/dist/components/table/snice-cell-json.js +1 -1
  134. package/dist/components/table/snice-cell-json.js.map +1 -1
  135. package/dist/components/table/snice-cell-link.js +1 -1
  136. package/dist/components/table/snice-cell-link.js.map +1 -1
  137. package/dist/components/table/snice-cell-location.js +1 -1
  138. package/dist/components/table/snice-cell-location.js.map +1 -1
  139. package/dist/components/table/snice-cell-number.js +1 -1
  140. package/dist/components/table/snice-cell-percentage.js +1 -1
  141. package/dist/components/table/snice-cell-percentage.js.map +1 -1
  142. package/dist/components/table/snice-cell-phone.js +1 -1
  143. package/dist/components/table/snice-cell-phone.js.map +1 -1
  144. package/dist/components/table/snice-cell-progress.js +1 -1
  145. package/dist/components/table/snice-cell-rating.js +1 -1
  146. package/dist/components/table/snice-cell-sparkline.js +1 -1
  147. package/dist/components/table/snice-cell-status.js +1 -1
  148. package/dist/components/table/snice-cell-status.js.map +1 -1
  149. package/dist/components/table/snice-cell-tag.js +1 -1
  150. package/dist/components/table/snice-cell-tag.js.map +1 -1
  151. package/dist/components/table/snice-cell-text.js +1 -1
  152. package/dist/components/table/snice-cell.js +1 -1
  153. package/dist/components/table/snice-header.js +1 -1
  154. package/dist/components/table/snice-header.js.map +1 -1
  155. package/dist/components/table/snice-row.js +2 -2
  156. package/dist/components/table/snice-row.js.map +1 -1
  157. package/dist/components/table/snice-table.js +1 -1
  158. package/dist/components/tabs/snice-tab-panel.js +1 -1
  159. package/dist/components/tabs/snice-tab-panel.js.map +1 -1
  160. package/dist/components/tabs/snice-tab.js +1 -1
  161. package/dist/components/tabs/snice-tab.js.map +1 -1
  162. package/dist/components/tabs/snice-tabs.js +1 -1
  163. package/dist/components/tabs/snice-tabs.js.map +1 -1
  164. package/dist/components/textarea/snice-textarea.d.ts +52 -0
  165. package/dist/components/textarea/snice-textarea.js +407 -0
  166. package/dist/components/textarea/snice-textarea.js.map +1 -0
  167. package/dist/components/textarea/snice-textarea.types.d.ts +30 -0
  168. package/dist/components/timeline/snice-timeline.d.ts +11 -0
  169. package/dist/components/timeline/snice-timeline.js +112 -0
  170. package/dist/components/timeline/snice-timeline.js.map +1 -0
  171. package/dist/components/timeline/snice-timeline.types.d.ts +16 -0
  172. package/dist/components/tooltip/snice-tooltip.js +2 -2
  173. package/dist/components/tooltip/snice-tooltip.js.map +1 -1
  174. package/dist/index.cjs +125 -158
  175. package/dist/index.cjs.map +1 -1
  176. package/dist/index.esm.js +125 -158
  177. package/dist/index.esm.js.map +1 -1
  178. package/dist/index.iife.js +125 -158
  179. package/dist/index.iife.js.map +1 -1
  180. package/dist/parts.d.ts +13 -16
  181. package/dist/symbols.cjs +1 -1
  182. package/dist/symbols.esm.js +1 -1
  183. package/dist/template.d.ts +0 -1
  184. package/dist/transitions.cjs +1 -1
  185. package/dist/transitions.esm.js +1 -1
  186. package/docs/ai/README.md +10 -1
  187. package/docs/ai/components/banner.md +84 -0
  188. package/docs/ai/components/color-display.md +48 -0
  189. package/docs/ai/components/color-picker.md +75 -0
  190. package/docs/ai/components/empty-state.md +72 -0
  191. package/docs/ai/components/file-upload.md +93 -0
  192. package/docs/ai/components/image.md +60 -0
  193. package/docs/ai/components/kpi.md +158 -0
  194. package/docs/ai/components/link.md +77 -0
  195. package/docs/ai/components/slider.md +87 -0
  196. package/docs/ai/components/sparkline.md +168 -0
  197. package/docs/ai/components/spinner.md +47 -0
  198. package/docs/ai/components/stepper.md +216 -0
  199. package/docs/ai/components/textarea.md +87 -0
  200. package/docs/ai/components/timeline.md +77 -0
  201. package/docs/components/banner.md +106 -0
  202. package/docs/components/color-display.md +96 -0
  203. package/docs/components/color-picker.md +81 -0
  204. package/docs/components/empty-state.md +79 -0
  205. package/docs/components/file-upload.md +263 -0
  206. package/docs/components/image.md +110 -0
  207. package/docs/components/kpi.md +251 -0
  208. package/docs/components/link.md +229 -0
  209. package/docs/components/slider.md +297 -0
  210. package/docs/components/sparkline.md +293 -0
  211. package/docs/components/spinner.md +63 -0
  212. package/docs/components/stepper.md +410 -0
  213. package/docs/components/textarea.md +235 -0
  214. package/docs/components/timeline.md +192 -0
  215. package/package.json +2 -1
  216. package/dist/components/snice-cell-BLFVdxPp.js +0 -4
  217. package/dist/components/snice-cell-BLFVdxPp.js.map +0 -1
@@ -0,0 +1,410 @@
1
+ # Stepper Component
2
+
3
+ A step indicator component for visualizing multi-step processes, wizards, and workflows. Shows progress through a sequence of steps with clear visual states.
4
+
5
+ ## Features
6
+
7
+ - **Multiple Orientations**: Horizontal and vertical layouts
8
+ - **Status Indicators**: Pending, active, completed, and error states
9
+ - **Interactive Mode**: Optional clickable navigation
10
+ - **Step Descriptions**: Optional descriptive text for each step
11
+ - **Custom Events**: Step change events for navigation integration
12
+ - **Connector Lines**: Visual flow between steps
13
+ - **Flexible Status**: Auto-computed or manually specified step status
14
+
15
+ ## Basic Usage
16
+
17
+ ```html
18
+ <snice-stepper id="basic"></snice-stepper>
19
+
20
+ <script>
21
+ const stepper = document.getElementById('basic');
22
+ stepper.steps = [
23
+ { label: 'Step 1' },
24
+ { label: 'Step 2' },
25
+ { label: 'Step 3' }
26
+ ];
27
+ stepper.currentStep = 0;
28
+ </script>
29
+ ```
30
+
31
+ ## Properties
32
+
33
+ | Property | Type | Default | Description |
34
+ |----------|------|---------|-------------|
35
+ | `steps` | `Step[]` | `[]` | Array of step objects |
36
+ | `current-step` | `number` | `0` | Index of the currently active step |
37
+ | `orientation` | `StepperOrientation` | `'horizontal'` | Layout direction ('horizontal' or 'vertical') |
38
+ | `clickable` | `boolean` | `false` | Whether steps can be clicked for navigation |
39
+
40
+ ### Step Object
41
+
42
+ ```typescript
43
+ {
44
+ label: string; // Step label (required)
45
+ description?: string; // Optional description text
46
+ status?: StepStatus; // Override auto-computed status
47
+ }
48
+ ```
49
+
50
+ ### Step Status
51
+
52
+ - `'pending'` - Not yet reached
53
+ - `'active'` - Current step
54
+ - `'completed'` - Already completed
55
+ - `'error'` - Failed or requires attention
56
+
57
+ ## Horizontal Stepper
58
+
59
+ ```html
60
+ <snice-stepper id="checkout"></snice-stepper>
61
+
62
+ <script>
63
+ document.getElementById('checkout').steps = [
64
+ { label: 'Cart' },
65
+ { label: 'Delivery' },
66
+ { label: 'Payment' },
67
+ { label: 'Confirm' }
68
+ ];
69
+ document.getElementById('checkout').currentStep = 1;
70
+ </script>
71
+ ```
72
+
73
+ ## Vertical Stepper
74
+
75
+ ```html
76
+ <snice-stepper id="onboarding" orientation="vertical"></snice-stepper>
77
+
78
+ <script>
79
+ document.getElementById('onboarding').steps = [
80
+ { label: 'Create Account' },
81
+ { label: 'Profile Setup' },
82
+ { label: 'Preferences' },
83
+ { label: 'Complete' }
84
+ ];
85
+ document.getElementById('onboarding').currentStep = 2;
86
+ </script>
87
+ ```
88
+
89
+ ## With Descriptions
90
+
91
+ ```html
92
+ <snice-stepper id="detailed"></snice-stepper>
93
+
94
+ <script>
95
+ document.getElementById('detailed').steps = [
96
+ { label: 'Order Details', description: 'Review your items' },
97
+ { label: 'Shipping', description: 'Enter delivery address' },
98
+ { label: 'Payment', description: 'Secure checkout' },
99
+ { label: 'Confirmation', description: 'Order summary' }
100
+ ];
101
+ document.getElementById('detailed').currentStep = 1;
102
+ </script>
103
+ ```
104
+
105
+ ## Interactive Navigation
106
+
107
+ ```html
108
+ <snice-stepper id="wizard" clickable></snice-stepper>
109
+
110
+ <script>
111
+ const wizard = document.getElementById('wizard');
112
+ wizard.steps = [
113
+ { label: 'Step 1' },
114
+ { label: 'Step 2' },
115
+ { label: 'Step 3' }
116
+ ];
117
+
118
+ wizard.addEventListener('step-change', (e) => {
119
+ console.log('Previous:', e.detail.previousStep);
120
+ console.log('Current:', e.detail.currentStep);
121
+ console.log('Step:', e.detail.step);
122
+
123
+ // Prevent navigation if needed
124
+ // e.preventDefault();
125
+ });
126
+ </script>
127
+ ```
128
+
129
+ ## Error State
130
+
131
+ ```html
132
+ <snice-stepper id="validation"></snice-stepper>
133
+
134
+ <script>
135
+ document.getElementById('validation').steps = [
136
+ { label: 'Upload', status: 'completed' },
137
+ { label: 'Validate', status: 'error' },
138
+ { label: 'Process', status: 'pending' },
139
+ { label: 'Complete', status: 'pending' }
140
+ ];
141
+ document.getElementById('validation').currentStep = 1;
142
+ </script>
143
+ ```
144
+
145
+ ## Events
146
+
147
+ ### step-change
148
+
149
+ Emitted when a step is clicked (only in clickable mode).
150
+
151
+ ```javascript
152
+ stepper.addEventListener('step-change', (event) => {
153
+ const { previousStep, currentStep, step } = event.detail;
154
+
155
+ // Validate before allowing change
156
+ if (!isStepValid(previousStep)) {
157
+ event.preventDefault();
158
+ return;
159
+ }
160
+
161
+ // Handle navigation
162
+ loadStepContent(currentStep);
163
+ });
164
+ ```
165
+
166
+ ## Stepper Panels
167
+
168
+ Use `<snice-stepper-panel>` to create content that automatically shows/hides based on the active step:
169
+
170
+ ```html
171
+ <snice-stepper id="wizard" clickable></snice-stepper>
172
+
173
+ <snice-stepper-panel>
174
+ <h3>Step 1 Content</h3>
175
+ <p>This shows when step 0 is active</p>
176
+ </snice-stepper-panel>
177
+
178
+ <snice-stepper-panel>
179
+ <h3>Step 2 Content</h3>
180
+ <p>This shows when step 1 is active</p>
181
+ </snice-stepper-panel>
182
+
183
+ <snice-stepper-panel>
184
+ <h3>Step 3 Content</h3>
185
+ <p>This shows when step 2 is active</p>
186
+ </snice-stepper-panel>
187
+
188
+ <script>
189
+ document.getElementById('wizard').steps = [
190
+ { label: 'Account' },
191
+ { label: 'Profile' },
192
+ { label: 'Complete' }
193
+ ];
194
+ </script>
195
+ ```
196
+
197
+ Panels automatically sync with the stepper's `currentStep`. They must be direct children of the stepper element.
198
+
199
+ ## Programmatic Navigation
200
+
201
+ ```javascript
202
+ const stepper = document.getElementById('my-stepper');
203
+
204
+ // Go to next step
205
+ if (stepper.currentStep < stepper.steps.length - 1) {
206
+ stepper.currentStep++;
207
+ }
208
+
209
+ // Go to previous step
210
+ if (stepper.currentStep > 0) {
211
+ stepper.currentStep--;
212
+ }
213
+
214
+ // Go to specific step
215
+ stepper.currentStep = 2;
216
+
217
+ // Reset to first step
218
+ stepper.currentStep = 0;
219
+ ```
220
+
221
+ ## CSS Parts
222
+
223
+ Use `::part()` to style internal elements:
224
+
225
+ ```css
226
+ snice-stepper::part(container) {
227
+ padding: 20px;
228
+ }
229
+
230
+ snice-stepper::part(step) {
231
+ margin: 10px 0;
232
+ }
233
+
234
+ snice-stepper::part(step-indicator) {
235
+ width: 40px;
236
+ height: 40px;
237
+ font-size: 18px;
238
+ }
239
+
240
+ snice-stepper::part(step-label) {
241
+ font-weight: 600;
242
+ }
243
+
244
+ snice-stepper::part(step-description) {
245
+ font-size: 12px;
246
+ }
247
+
248
+ snice-stepper::part(step-connector) {
249
+ background: linear-gradient(to right, #ccc, #999);
250
+ }
251
+ ```
252
+
253
+ ## Theming
254
+
255
+ The component uses these CSS custom properties:
256
+
257
+ ```css
258
+ --snice-color-primary
259
+ --snice-color-success
260
+ --snice-color-danger
261
+ --snice-color-text
262
+ --snice-color-text-secondary
263
+ --snice-color-text-inverse
264
+ --snice-color-background
265
+ --snice-color-border
266
+ --snice-spacing-*
267
+ --snice-font-size-*
268
+ --snice-font-weight-*
269
+ --snice-transition-fast
270
+ ```
271
+
272
+ ## Examples
273
+
274
+ ### Checkout Process
275
+
276
+ ```html
277
+ <snice-stepper id="checkout-process" clickable></snice-stepper>
278
+
279
+ <div id="step-content"></div>
280
+
281
+ <button onclick="prevStep()">Previous</button>
282
+ <button onclick="nextStep()">Next</button>
283
+
284
+ <script>
285
+ const stepper = document.getElementById('checkout-process');
286
+ stepper.steps = [
287
+ { label: 'Cart', description: 'Review items' },
288
+ { label: 'Delivery', description: 'Shipping details' },
289
+ { label: 'Payment', description: 'Billing info' },
290
+ { label: 'Confirm', description: 'Place order' }
291
+ ];
292
+
293
+ function nextStep() {
294
+ if (stepper.currentStep < stepper.steps.length - 1) {
295
+ stepper.currentStep++;
296
+ }
297
+ }
298
+
299
+ function prevStep() {
300
+ if (stepper.currentStep > 0) {
301
+ stepper.currentStep--;
302
+ }
303
+ }
304
+
305
+ stepper.addEventListener('step-change', (e) => {
306
+ document.getElementById('step-content').innerHTML =
307
+ `<h2>${e.detail.step.label}</h2>`;
308
+ });
309
+ </script>
310
+ ```
311
+
312
+ ### Account Setup Wizard with Panels
313
+
314
+ ```html
315
+ <snice-stepper id="signup" clickable></snice-stepper>
316
+
317
+ <snice-stepper-panel>
318
+ <h2>Create Account</h2>
319
+ <input type="email" placeholder="Email">
320
+ <input type="password" placeholder="Password">
321
+ </snice-stepper-panel>
322
+
323
+ <snice-stepper-panel>
324
+ <h2>Personal Information</h2>
325
+ <input type="text" placeholder="Full Name">
326
+ <input type="text" placeholder="Company">
327
+ </snice-stepper-panel>
328
+
329
+ <snice-stepper-panel>
330
+ <h2>Preferences</h2>
331
+ <label><input type="checkbox"> Email notifications</label>
332
+ <label><input type="checkbox"> Weekly digest</label>
333
+ </snice-stepper-panel>
334
+
335
+ <snice-stepper-panel>
336
+ <h2>Complete</h2>
337
+ <p>You're all set! Click finish to start using the app.</p>
338
+ <button>Finish</button>
339
+ </snice-stepper-panel>
340
+
341
+ <script>
342
+ const signup = document.getElementById('signup');
343
+ signup.steps = [
344
+ { label: 'Account' },
345
+ { label: 'Profile' },
346
+ { label: 'Preferences' },
347
+ { label: 'Complete' }
348
+ ];
349
+ </script>
350
+ ```
351
+
352
+ ### Form Validation Flow
353
+
354
+ ```html
355
+ <snice-stepper id="form-validation"></snice-stepper>
356
+
357
+ <script>
358
+ const form = document.getElementById('form-validation');
359
+ const validationStates = {
360
+ 0: true, // Step 1 valid
361
+ 1: false, // Step 2 has error
362
+ 2: false, // Step 3 pending
363
+ };
364
+
365
+ function updateStepStatuses() {
366
+ form.steps = form.steps.map((step, index) => ({
367
+ ...step,
368
+ status: validationStates[index]
369
+ ? (index < form.currentStep ? 'completed' : index === form.currentStep ? 'active' : 'pending')
370
+ : 'error'
371
+ }));
372
+ }
373
+
374
+ form.steps = [
375
+ { label: 'Personal Info' },
376
+ { label: 'Contact Details' },
377
+ { label: 'Verification' }
378
+ ];
379
+
380
+ updateStepStatuses();
381
+ </script>
382
+ ```
383
+
384
+ ## Best Practices
385
+
386
+ 1. **Clear Labels**: Use concise, action-oriented step names
387
+ 2. **Logical Flow**: Order steps in natural progression
388
+ 3. **Visual Feedback**: Show clear status for each step
389
+ 4. **Error Handling**: Highlight steps that need attention
390
+ 5. **Save Progress**: Persist current step across sessions
391
+ 6. **Validation**: Validate before allowing step advancement
392
+ 7. **Orientation**: Use vertical for complex flows with descriptions
393
+ 8. **Descriptions**: Add descriptions for clarity in complex workflows
394
+
395
+ ## Accessibility
396
+
397
+ - Semantic HTML with proper step indicators
398
+ - Clear visual state differentiation
399
+ - Keyboard navigation in clickable mode
400
+ - Screen reader friendly labels and status
401
+ - Sufficient color contrast for all states
402
+ - Focus indicators on interactive steps
403
+
404
+ ## Performance
405
+
406
+ - Efficient rendering with minimal DOM
407
+ - CSS containment for optimized layout
408
+ - Event delegation for click handling
409
+ - No external dependencies
410
+ - Lightweight status computation
@@ -0,0 +1,235 @@
1
+ # Textarea Component
2
+
3
+ The `<snice-textarea>` component provides a multi-line text input with validation, character counting, and optional auto-grow functionality.
4
+
5
+ ## Table of Contents
6
+ - [Basic Usage](#basic-usage)
7
+ - [Properties](#properties)
8
+ - [Methods](#methods)
9
+ - [Events](#events)
10
+ - [Features](#features)
11
+ - [Examples](#examples)
12
+
13
+ ## Basic Usage
14
+
15
+ ```html
16
+ <snice-textarea
17
+ label="Comments"
18
+ placeholder="Enter your comments here"
19
+ rows="5"
20
+ ></snice-textarea>
21
+ ```
22
+
23
+ ```typescript
24
+ import 'snice/components/textarea/snice-textarea';
25
+
26
+ const textarea = document.querySelector('snice-textarea');
27
+ textarea.addEventListener('@snice/textarea-change', (e) => {
28
+ console.log('Value:', e.detail.value);
29
+ });
30
+ ```
31
+
32
+ ## Properties
33
+
34
+ | Property | Type | Default | Description |
35
+ |----------|------|---------|-------------|
36
+ | `value` | `string` | `''` | The textarea value |
37
+ | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | Size variant |
38
+ | `variant` | `'outlined' \| 'filled' \| 'underlined'` | `'outlined'` | Visual style variant |
39
+ | `resize` | `'none' \| 'vertical' \| 'horizontal' \| 'both'` | `'vertical'` | Resize behavior |
40
+ | `placeholder` | `string` | `''` | Placeholder text |
41
+ | `label` | `string` | `''` | Label text |
42
+ | `helperText` | `string` | `''` | Helper text below textarea |
43
+ | `errorText` | `string` | `''` | Error message (shown when invalid) |
44
+ | `disabled` | `boolean` | `false` | Whether textarea is disabled |
45
+ | `readonly` | `boolean` | `false` | Whether textarea is readonly |
46
+ | `required` | `boolean` | `false` | Whether textarea is required |
47
+ | `invalid` | `boolean` | `false` | Whether to show invalid state |
48
+ | `rows` | `number` | `3` | Number of visible rows |
49
+ | `cols` | `number` | `-1` | Number of visible columns |
50
+ | `maxlength` | `number` | `-1` | Maximum character count |
51
+ | `minlength` | `number` | `-1` | Minimum character count |
52
+ | `autocomplete` | `string` | `''` | Autocomplete attribute value |
53
+ | `name` | `string` | `''` | Form field name |
54
+ | `autoGrow` | `boolean` | `false` | Whether to auto-grow height |
55
+
56
+ ## Methods
57
+
58
+ ### `focus(): void`
59
+ Give focus to the textarea.
60
+
61
+ ```typescript
62
+ textarea.focus();
63
+ ```
64
+
65
+ ### `blur(): void`
66
+ Remove focus from the textarea.
67
+
68
+ ```typescript
69
+ textarea.blur();
70
+ ```
71
+
72
+ ### `select(): void`
73
+ Select all text in the textarea.
74
+
75
+ ```typescript
76
+ textarea.select();
77
+ ```
78
+
79
+ ### `checkValidity(): boolean`
80
+ Check if the textarea passes validation.
81
+
82
+ ```typescript
83
+ const isValid = textarea.checkValidity();
84
+ ```
85
+
86
+ ### `reportValidity(): boolean`
87
+ Report validation status to the user.
88
+
89
+ ```typescript
90
+ textarea.reportValidity();
91
+ ```
92
+
93
+ ### `setCustomValidity(message: string): void`
94
+ Set a custom validation message.
95
+
96
+ ```typescript
97
+ textarea.setCustomValidity('This field is required');
98
+ ```
99
+
100
+ ## Events
101
+
102
+ ### `@snice/textarea-input`
103
+ Fired when the textarea value changes during input.
104
+
105
+ **Detail**: `{ value: string, textarea: SniceTextareaElement }`
106
+
107
+ ```typescript
108
+ textarea.addEventListener('@snice/textarea-input', (e) => {
109
+ console.log('Input value:', e.detail.value);
110
+ });
111
+ ```
112
+
113
+ ### `@snice/textarea-change`
114
+ Fired when the textarea value is committed (blur or enter).
115
+
116
+ **Detail**: `{ value: string, textarea: SniceTextareaElement }`
117
+
118
+ ```typescript
119
+ textarea.addEventListener('@snice/textarea-change', (e) => {
120
+ console.log('Changed to:', e.detail.value);
121
+ });
122
+ ```
123
+
124
+ ### `@snice/textarea-focus`
125
+ Fired when the textarea receives focus.
126
+
127
+ **Detail**: `{ textarea: SniceTextareaElement }`
128
+
129
+ ### `@snice/textarea-blur`
130
+ Fired when the textarea loses focus.
131
+
132
+ **Detail**: `{ textarea: SniceTextareaElement }`
133
+
134
+ ## Features
135
+
136
+ - **Form Integration**: Fully form-associated custom element with validation support
137
+ - **Visual Variants**: Three style options (outlined, filled, underlined)
138
+ - **Auto-grow**: Automatically expand height to fit content
139
+ - **Character Counter**: Shows count when maxlength is set
140
+ - **Resize Control**: Four resize modes (none, vertical, horizontal, both)
141
+ - **Validation**: Built-in HTML5 validation with custom messages
142
+ - **Accessibility**: Full keyboard support and ARIA attributes
143
+
144
+ ## Examples
145
+
146
+ ### Basic Textarea
147
+
148
+ ```html
149
+ <snice-textarea
150
+ label="Description"
151
+ placeholder="Enter description..."
152
+ rows="4"
153
+ ></snice-textarea>
154
+ ```
155
+
156
+ ### With Character Counter
157
+
158
+ ```html
159
+ <snice-textarea
160
+ label="Bio"
161
+ maxlength="500"
162
+ helper-text="Share a brief bio"
163
+ ></snice-textarea>
164
+ ```
165
+
166
+ ### Auto-grow Textarea
167
+
168
+ ```html
169
+ <snice-textarea
170
+ label="Notes"
171
+ auto-grow
172
+ rows="3"
173
+ placeholder="Type to expand..."
174
+ ></snice-textarea>
175
+ ```
176
+
177
+ ### Error State
178
+
179
+ ```html
180
+ <snice-textarea
181
+ label="Message"
182
+ invalid
183
+ error-text="This field is required"
184
+ required
185
+ ></snice-textarea>
186
+ ```
187
+
188
+ ### Different Variants
189
+
190
+ ```html
191
+ <snice-textarea variant="outlined" label="Outlined"></snice-textarea>
192
+ <snice-textarea variant="filled" label="Filled"></snice-textarea>
193
+ <snice-textarea variant="underlined" label="Underlined"></snice-textarea>
194
+ ```
195
+
196
+ ### Different Sizes
197
+
198
+ ```html
199
+ <snice-textarea size="small" label="Small"></snice-textarea>
200
+ <snice-textarea size="medium" label="Medium"></snice-textarea>
201
+ <snice-textarea size="large" label="Large"></snice-textarea>
202
+ ```
203
+
204
+ ### Resize Control
205
+
206
+ ```html
207
+ <snice-textarea resize="none" label="No resize"></snice-textarea>
208
+ <snice-textarea resize="vertical" label="Vertical only"></snice-textarea>
209
+ <snice-textarea resize="horizontal" label="Horizontal only"></snice-textarea>
210
+ <snice-textarea resize="both" label="Both directions"></snice-textarea>
211
+ ```
212
+
213
+ ### In a Form
214
+
215
+ ```html
216
+ <form id="feedback-form">
217
+ <snice-textarea
218
+ name="feedback"
219
+ label="Your Feedback"
220
+ required
221
+ minlength="10"
222
+ maxlength="1000"
223
+ helper-text="Please provide at least 10 characters"
224
+ ></snice-textarea>
225
+ <button type="submit">Submit</button>
226
+ </form>
227
+
228
+ <script>
229
+ document.getElementById('feedback-form').addEventListener('submit', (e) => {
230
+ e.preventDefault();
231
+ const formData = new FormData(e.target);
232
+ console.log('Feedback:', formData.get('feedback'));
233
+ });
234
+ </script>
235
+ ```