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.
- package/README.md +90 -41
- package/dist/components/accordion/snice-accordion-item.js +1 -1
- package/dist/components/accordion/snice-accordion-item.js.map +1 -1
- package/dist/components/accordion/snice-accordion.js +1 -1
- package/dist/components/accordion/snice-accordion.js.map +1 -1
- package/dist/components/alert/snice-alert.js +1 -1
- package/dist/components/alert/snice-alert.js.map +1 -1
- package/dist/components/avatar/snice-avatar.js +1 -1
- package/dist/components/avatar/snice-avatar.js.map +1 -1
- package/dist/components/badge/snice-badge.js +1 -1
- package/dist/components/badge/snice-badge.js.map +1 -1
- package/dist/components/banner/snice-banner.d.ts +22 -0
- package/dist/components/banner/snice-banner.js +180 -0
- package/dist/components/banner/snice-banner.js.map +1 -0
- package/dist/components/banner/snice-banner.types.d.ts +14 -0
- package/dist/components/breadcrumbs/snice-breadcrumbs.js +1 -1
- package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +1 -1
- package/dist/components/button/snice-button.js +1 -1
- package/dist/components/button/snice-button.js.map +1 -1
- package/dist/components/card/snice-card.js +1 -1
- package/dist/components/card/snice-card.js.map +1 -1
- package/dist/components/checkbox/snice-checkbox.js +1 -1
- package/dist/components/checkbox/snice-checkbox.js.map +1 -1
- package/dist/components/chip/snice-chip.js +1 -1
- package/dist/components/chip/snice-chip.js.map +1 -1
- package/dist/components/color-display/snice-color-display.d.ts +14 -0
- package/dist/components/color-display/snice-color-display.js +151 -0
- package/dist/components/color-display/snice-color-display.js.map +1 -0
- package/dist/components/color-display/snice-color-display.types.d.ts +10 -0
- package/dist/components/color-picker/snice-color-picker.d.ts +50 -0
- package/dist/components/color-picker/snice-color-picker.js +489 -0
- package/dist/components/color-picker/snice-color-picker.js.map +1 -0
- package/dist/components/color-picker/snice-color-picker.types.d.ts +19 -0
- package/dist/components/date-picker/snice-date-picker.js +1 -1
- package/dist/components/date-picker/snice-date-picker.js.map +1 -1
- package/dist/components/divider/snice-divider.js +1 -1
- package/dist/components/divider/snice-divider.js.map +1 -1
- package/dist/components/drawer/snice-drawer.js +1 -1
- package/dist/components/drawer/snice-drawer.js.map +1 -1
- package/dist/components/empty-state/snice-empty-state.d.ts +13 -0
- package/dist/components/empty-state/snice-empty-state.js +121 -0
- package/dist/components/empty-state/snice-empty-state.js.map +1 -0
- package/dist/components/empty-state/snice-empty-state.types.d.ts +9 -0
- package/dist/components/file-upload/snice-file-upload.d.ts +45 -0
- package/dist/components/file-upload/snice-file-upload.js +394 -0
- package/dist/components/file-upload/snice-file-upload.js.map +1 -0
- package/dist/components/file-upload/snice-file-upload.types.d.ts +22 -0
- package/dist/components/image/snice-image.d.ts +22 -0
- package/dist/components/image/snice-image.js +201 -0
- package/dist/components/image/snice-image.js.map +1 -0
- package/dist/components/image/snice-image.types.d.ts +17 -0
- package/dist/components/input/snice-input.js +1 -1
- package/dist/components/input/snice-input.js.map +1 -1
- package/dist/components/kpi/snice-kpi.d.ts +16 -0
- package/dist/components/kpi/snice-kpi.js +162 -0
- package/dist/components/kpi/snice-kpi.js.map +1 -0
- package/dist/components/kpi/snice-kpi.types.d.ts +12 -0
- package/dist/components/layout/snice-layout-blog.js +1 -1
- package/dist/components/layout/snice-layout-blog.js.map +1 -1
- package/dist/components/layout/snice-layout-card.js +1 -1
- package/dist/components/layout/snice-layout-card.js.map +1 -1
- package/dist/components/layout/snice-layout-centered.js +1 -1
- package/dist/components/layout/snice-layout-centered.js.map +1 -1
- package/dist/components/layout/snice-layout-dashboard.js +1 -1
- package/dist/components/layout/snice-layout-dashboard.js.map +1 -1
- package/dist/components/layout/snice-layout-fullscreen.js +1 -1
- package/dist/components/layout/snice-layout-fullscreen.js.map +1 -1
- package/dist/components/layout/snice-layout-landing.js +1 -1
- package/dist/components/layout/snice-layout-landing.js.map +1 -1
- package/dist/components/layout/snice-layout-minimal.js +1 -1
- package/dist/components/layout/snice-layout-minimal.js.map +1 -1
- package/dist/components/layout/snice-layout-sidebar.js +1 -1
- package/dist/components/layout/snice-layout-sidebar.js.map +1 -1
- package/dist/components/layout/snice-layout-split.js +1 -1
- package/dist/components/layout/snice-layout-split.js.map +1 -1
- package/dist/components/layout/snice-layout.js +1 -1
- package/dist/components/layout/snice-layout.js.map +1 -1
- package/dist/components/link/snice-link.d.ts +13 -0
- package/dist/components/link/snice-link.js +137 -0
- package/dist/components/link/snice-link.js.map +1 -0
- package/dist/components/link/snice-link.types.d.ts +11 -0
- package/dist/components/login/snice-login.js +1 -1
- package/dist/components/login/snice-login.js.map +1 -1
- package/dist/components/modal/snice-modal.js +1 -1
- package/dist/components/modal/snice-modal.js.map +1 -1
- package/dist/components/nav/snice-nav.js +1 -1
- package/dist/components/nav/snice-nav.js.map +1 -1
- package/dist/components/progress/snice-progress.js +1 -1
- package/dist/components/progress/snice-progress.js.map +1 -1
- package/dist/components/radio/snice-radio.js +1 -1
- package/dist/components/radio/snice-radio.js.map +1 -1
- package/dist/components/select/snice-select.js +1 -1
- package/dist/components/select/snice-select.js.map +1 -1
- package/dist/components/skeleton/snice-skeleton.js +1 -1
- package/dist/components/skeleton/snice-skeleton.js.map +1 -1
- package/dist/components/slider/snice-slider.d.ts +53 -0
- package/dist/components/slider/snice-slider.js +479 -0
- package/dist/components/slider/snice-slider.js.map +1 -0
- package/dist/components/slider/snice-slider.types.d.ts +26 -0
- package/dist/components/snice-cell-C0slgOpe.js +4 -0
- package/dist/components/snice-cell-C0slgOpe.js.map +1 -0
- package/dist/components/sparkline/snice-sparkline.d.ts +21 -0
- package/dist/components/sparkline/snice-sparkline.js +228 -0
- package/dist/components/sparkline/snice-sparkline.js.map +1 -0
- package/dist/components/sparkline/snice-sparkline.types.d.ts +16 -0
- package/dist/components/spinner/snice-spinner.d.ts +10 -0
- package/dist/components/spinner/snice-spinner.js +109 -0
- package/dist/components/spinner/snice-spinner.js.map +1 -0
- package/dist/components/spinner/snice-spinner.types.d.ts +8 -0
- package/dist/components/stepper/snice-stepper-panel.d.ts +8 -0
- package/dist/components/stepper/snice-stepper-panel.js +70 -0
- package/dist/components/stepper/snice-stepper-panel.js.map +1 -0
- package/dist/components/stepper/snice-stepper-panel.types.d.ts +4 -0
- package/dist/components/stepper/snice-stepper.d.ts +15 -0
- package/dist/components/stepper/snice-stepper.js +163 -0
- package/dist/components/stepper/snice-stepper.js.map +1 -0
- package/dist/components/stepper/snice-stepper.types.d.ts +13 -0
- package/dist/components/switch/snice-switch.js +1 -1
- package/dist/components/switch/snice-switch.js.map +1 -1
- package/dist/components/table/snice-cell-actions.js +1 -1
- package/dist/components/table/snice-cell-actions.js.map +1 -1
- package/dist/components/table/snice-cell-boolean.js +1 -1
- package/dist/components/table/snice-cell-color.js +1 -1
- package/dist/components/table/snice-cell-color.js.map +1 -1
- package/dist/components/table/snice-cell-currency.js +1 -1
- package/dist/components/table/snice-cell-date.js +1 -1
- package/dist/components/table/snice-cell-duration.js +1 -1
- package/dist/components/table/snice-cell-email.js +1 -1
- package/dist/components/table/snice-cell-email.js.map +1 -1
- package/dist/components/table/snice-cell-filesize.js +1 -1
- package/dist/components/table/snice-cell-image.js +1 -1
- package/dist/components/table/snice-cell-image.js.map +1 -1
- package/dist/components/table/snice-cell-json.js +1 -1
- package/dist/components/table/snice-cell-json.js.map +1 -1
- package/dist/components/table/snice-cell-link.js +1 -1
- package/dist/components/table/snice-cell-link.js.map +1 -1
- package/dist/components/table/snice-cell-location.js +1 -1
- package/dist/components/table/snice-cell-location.js.map +1 -1
- package/dist/components/table/snice-cell-number.js +1 -1
- package/dist/components/table/snice-cell-percentage.js +1 -1
- package/dist/components/table/snice-cell-percentage.js.map +1 -1
- package/dist/components/table/snice-cell-phone.js +1 -1
- package/dist/components/table/snice-cell-phone.js.map +1 -1
- package/dist/components/table/snice-cell-progress.js +1 -1
- package/dist/components/table/snice-cell-rating.js +1 -1
- package/dist/components/table/snice-cell-sparkline.js +1 -1
- package/dist/components/table/snice-cell-status.js +1 -1
- package/dist/components/table/snice-cell-status.js.map +1 -1
- package/dist/components/table/snice-cell-tag.js +1 -1
- package/dist/components/table/snice-cell-tag.js.map +1 -1
- package/dist/components/table/snice-cell-text.js +1 -1
- package/dist/components/table/snice-cell.js +1 -1
- package/dist/components/table/snice-header.js +1 -1
- package/dist/components/table/snice-header.js.map +1 -1
- package/dist/components/table/snice-row.js +2 -2
- package/dist/components/table/snice-row.js.map +1 -1
- package/dist/components/table/snice-table.js +1 -1
- package/dist/components/tabs/snice-tab-panel.js +1 -1
- package/dist/components/tabs/snice-tab-panel.js.map +1 -1
- package/dist/components/tabs/snice-tab.js +1 -1
- package/dist/components/tabs/snice-tab.js.map +1 -1
- package/dist/components/tabs/snice-tabs.js +1 -1
- package/dist/components/tabs/snice-tabs.js.map +1 -1
- package/dist/components/textarea/snice-textarea.d.ts +52 -0
- package/dist/components/textarea/snice-textarea.js +407 -0
- package/dist/components/textarea/snice-textarea.js.map +1 -0
- package/dist/components/textarea/snice-textarea.types.d.ts +30 -0
- package/dist/components/timeline/snice-timeline.d.ts +11 -0
- package/dist/components/timeline/snice-timeline.js +112 -0
- package/dist/components/timeline/snice-timeline.js.map +1 -0
- package/dist/components/timeline/snice-timeline.types.d.ts +16 -0
- package/dist/components/tooltip/snice-tooltip.js +2 -2
- package/dist/components/tooltip/snice-tooltip.js.map +1 -1
- package/dist/index.cjs +125 -158
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +125 -158
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +125 -158
- package/dist/index.iife.js.map +1 -1
- package/dist/parts.d.ts +13 -16
- package/dist/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/template.d.ts +0 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/docs/ai/README.md +10 -1
- package/docs/ai/components/banner.md +84 -0
- package/docs/ai/components/color-display.md +48 -0
- package/docs/ai/components/color-picker.md +75 -0
- package/docs/ai/components/empty-state.md +72 -0
- package/docs/ai/components/file-upload.md +93 -0
- package/docs/ai/components/image.md +60 -0
- package/docs/ai/components/kpi.md +158 -0
- package/docs/ai/components/link.md +77 -0
- package/docs/ai/components/slider.md +87 -0
- package/docs/ai/components/sparkline.md +168 -0
- package/docs/ai/components/spinner.md +47 -0
- package/docs/ai/components/stepper.md +216 -0
- package/docs/ai/components/textarea.md +87 -0
- package/docs/ai/components/timeline.md +77 -0
- package/docs/components/banner.md +106 -0
- package/docs/components/color-display.md +96 -0
- package/docs/components/color-picker.md +81 -0
- package/docs/components/empty-state.md +79 -0
- package/docs/components/file-upload.md +263 -0
- package/docs/components/image.md +110 -0
- package/docs/components/kpi.md +251 -0
- package/docs/components/link.md +229 -0
- package/docs/components/slider.md +297 -0
- package/docs/components/sparkline.md +293 -0
- package/docs/components/spinner.md +63 -0
- package/docs/components/stepper.md +410 -0
- package/docs/components/textarea.md +235 -0
- package/docs/components/timeline.md +192 -0
- package/package.json +2 -1
- package/dist/components/snice-cell-BLFVdxPp.js +0 -4
- 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
|
+
```
|