solid-tom-ui 1.0.11 → 1.0.15
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 +246 -246
- package/dist/README.md +246 -246
- package/dist/components/avatar/avatar.js.map +1 -1
- package/dist/components/badge/badge.js.map +1 -1
- package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/components/button/button.js.map +1 -1
- package/dist/components/carousel/carousel.js.map +1 -1
- package/dist/components/chat-bubble/chatBubble.js.map +1 -1
- package/dist/components/checkbox/checkbox.js.map +1 -1
- package/dist/components/collapse/collapse.js.map +1 -1
- package/dist/components/context-menu/context-menu.js.map +1 -1
- package/dist/components/context-menu/context-menu.store.js.map +1 -1
- package/dist/components/divider/divider.js.map +1 -1
- package/dist/components/dropdown/dropdown.js.map +1 -1
- package/dist/components/dropdown/dropdown.store.js.map +1 -1
- package/dist/components/float-button/float-button.js.map +1 -1
- package/dist/components/hover-3d-image/hover-3d-image.js.map +1 -1
- package/dist/components/image-preview/image-preview.js.map +1 -1
- package/dist/components/input/input.js.map +1 -1
- package/dist/components/input/input.utils.js.map +1 -1
- package/dist/components/input/variants/input-color.js.map +1 -1
- package/dist/components/input/variants/input-date.js.map +1 -1
- package/dist/components/input/variants/input-number.d.ts.map +1 -1
- package/dist/components/input/variants/input-number.js +1 -1
- package/dist/components/input/variants/input-number.js.map +1 -1
- package/dist/components/input/variants/input-otp.js.map +1 -1
- package/dist/components/input/variants/input-password.js.map +1 -1
- package/dist/components/input/variants/input-radio.js.map +1 -1
- package/dist/components/input/variants/input-range.js.map +1 -1
- package/dist/components/input/variants/input-text.d.ts.map +1 -1
- package/dist/components/input/variants/input-text.js +1 -1
- package/dist/components/input/variants/input-text.js.map +1 -1
- package/dist/components/input/variants/input-textarea.js.map +1 -1
- package/dist/components/loading/loading.js.map +1 -1
- package/dist/components/mansory/mansory.js.map +1 -1
- package/dist/components/menu/menu.js.map +1 -1
- package/dist/components/modal/modal.js.map +1 -1
- package/dist/components/modal/modalContext.js.map +1 -1
- package/dist/components/pagination/pagination.js.map +1 -1
- package/dist/components/progress-bar/progress-bar.js.map +1 -1
- package/dist/components/qr-code/qr-code.js.map +1 -1
- package/dist/components/select/select.js +1 -1
- package/dist/components/select/select.js.map +1 -1
- package/dist/components/select-zone/select-zone.js.map +1 -1
- package/dist/components/skeleton/skeleton.js.map +1 -1
- package/dist/components/slider/slider.js.map +1 -1
- package/dist/components/splitter/splitter.js.map +1 -1
- package/dist/components/steps/steps.js.map +1 -1
- package/dist/components/swap/swap.js.map +1 -1
- package/dist/components/switch/switch.js.map +1 -1
- package/dist/components/tab/tab.js.map +1 -1
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/timeline/timeline.js.map +1 -1
- package/dist/components/toast/icons/ErrorIcon.js.map +1 -1
- package/dist/components/toast/icons/IconCircle.js.map +1 -1
- package/dist/components/toast/icons/InfoIcon.js.map +1 -1
- package/dist/components/toast/icons/LoaderIcon.js.map +1 -1
- package/dist/components/toast/icons/SuccessIcon.js.map +1 -1
- package/dist/components/toast/icons/WarningIcon.js.map +1 -1
- package/dist/components/toast/toast.js.map +1 -1
- package/dist/components/toast/toast.store.js.map +1 -1
- package/dist/components/tooltip/tooltip.js.map +1 -1
- package/dist/components/tour/tour.js.map +1 -1
- package/dist/components/upload/upload.js.map +1 -1
- package/dist/components/z-index/z-index.context.js.map +1 -1
- package/dist/components/z-index/z-index.js.map +1 -1
- package/dist/components/z-index/z-index.store.js.map +1 -1
- package/dist/components/z-index/z-index.types.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/skill/avatar.skill.md.txt +255 -255
- package/dist/skill/badge.skill.md.txt +223 -223
- package/dist/skill/breadcrumb.skill.md.txt +177 -177
- package/dist/skill/button.skill.md.txt +198 -198
- package/dist/skill/carousel.skill.md.txt +406 -406
- package/dist/skill/chat-bubble.skill.md.txt +342 -342
- package/dist/skill/checkbox.skill.md.txt +326 -326
- package/dist/skill/code-preview.skill.md.txt +240 -240
- package/dist/skill/collapse.skill.md.txt +329 -329
- package/dist/skill/context-menu.skill.md.txt +233 -233
- package/dist/skill/diff.skill.md.txt +244 -244
- package/dist/skill/divider.skill.md.txt +151 -151
- package/dist/skill/doc.skill.md.txt +191 -191
- package/dist/skill/drawer.skill.md.txt +157 -157
- package/dist/skill/dropdown.skill.md.txt +198 -198
- package/dist/skill/float-button.skill.md.txt +315 -315
- package/dist/skill/hover-3d-image.skill.md.txt +120 -120
- package/dist/skill/iframe.skill.md.txt +114 -114
- package/dist/skill/image-preview.skill.md.txt +162 -162
- package/dist/skill/indicator.skill.md.txt +60 -60
- package/dist/skill/input.skill.md.txt +489 -489
- package/dist/skill/loading.skill.md.txt +127 -127
- package/dist/skill/menu.skill.md.txt +476 -476
- package/dist/skill/modal.skill.md.txt +359 -359
- package/dist/skill/pagination.skill.md.txt +405 -405
- package/dist/skill/progress-bar.skill.md.txt +207 -207
- package/dist/skill/qr-code.skill.md.txt +136 -136
- package/dist/skill/rating.skill.md.txt +167 -167
- package/dist/skill/select-zone.skill.md.txt +93 -93
- package/dist/skill/select.skill.md.txt +663 -663
- package/dist/skill/skeleton.skill.md.txt +192 -192
- package/dist/skill/slider.skill.md.txt +404 -404
- package/dist/skill/splitter.skill.md.txt +411 -411
- package/dist/skill/steps.skill.md.txt +264 -264
- package/dist/skill/swap.skill.md.txt +139 -139
- package/dist/skill/switch.skill.md.txt +191 -191
- package/dist/skill/tab.skill.md.txt +484 -484
- package/dist/skill/table.example.header.md.txt +666 -666
- package/dist/skill/table.skill.md.txt +1407 -1407
- package/dist/skill/text-rotate.skill.md.txt +186 -186
- package/dist/skill/timeline.skill.md.txt +247 -247
- package/dist/skill/toast.skill.md.txt +531 -531
- package/dist/skill/tooltip.skill.md.txt +222 -222
- package/dist/skill/tour.skill.md.txt +156 -156
- package/dist/skill/upload.skill.md.txt +358 -358
- package/dist/utils/cn.js.map +1 -1
- package/dist/utils/element-tracker.js.map +1 -1
- package/dist/utils/helper.js.map +1 -1
- package/dist/utils/hoc.js.map +1 -1
- package/package.json +132 -133
|
@@ -1,264 +1,264 @@
|
|
|
1
|
-
## COMPONENT IDENTITY
|
|
2
|
-
- **Import**: `import { Steps } from 'solid-tom-ui';`
|
|
3
|
-
- **Export**: `Steps` (named export), `StepsProps`, `StepItem` (type exports)
|
|
4
|
-
- **Framework**: SolidJS
|
|
5
|
-
- **Purpose**: Multi-step progress indicator — three visual types, two orientations, full color theming, disabled steps; always controlled (parent owns step index)
|
|
6
|
-
|
|
7
|
-
## Props
|
|
8
|
-
|
|
9
|
-
| Prop | Type | Default | Description |
|
|
10
|
-
| ------------- | --------------------------------------------- | -------------- | ------------------------------------------------------------------------ |
|
|
11
|
-
| `type` | `'default' \| 'navigation' \| 'dot'` | `'default'` | Visual style of the steps |
|
|
12
|
-
| `color` | `BaseColorProps` | `'primary'` | Accent color for active/done steps and connectors |
|
|
13
|
-
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout direction |
|
|
14
|
-
| `items` | `StepItem[]` | `[]` | Step definitions. Takes priority over `total` |
|
|
15
|
-
| `total` | `number` | — | Auto-generates `total` numbered steps (`Step 1`, `Step 2`, …). Used only when `items` is empty |
|
|
16
|
-
| `current` | `Accessor<number>` | — | **Signal getter** for the active step index (0-based) |
|
|
17
|
-
| `setCurrent` | `Setter<number>` | — | **Signal setter** — called when a step is clicked |
|
|
18
|
-
| `onChange` | `(index: number) => void` | — | Additional callback fired on step click, after `setCurrent` |
|
|
19
|
-
| `disabled` | `number[]` | `[]` | Indices of steps that cannot be clicked |
|
|
20
|
-
| `activeIndex` | `number[]` | — | Force specific step indices to `active` status, regardless of `current` |
|
|
21
|
-
| `class` | `{ root?, step?, icon?, title?, description?, connector? }` | — | Per-element class overrides (see below) |
|
|
22
|
-
|
|
23
|
-
### `StepItem`
|
|
24
|
-
|
|
25
|
-
```ts
|
|
26
|
-
type StepItem = {
|
|
27
|
-
title?: JSX.Element; // Step label
|
|
28
|
-
description?: JSX.Element; // Subtitle/detail text
|
|
29
|
-
icon?: JSX.Element; // Custom icon (replaces the number; checkmark still shows for done)
|
|
30
|
-
};
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### `class` Object
|
|
34
|
-
|
|
35
|
-
All keys are optional strings appended via `cn()`:
|
|
36
|
-
|
|
37
|
-
| Key | Target element |
|
|
38
|
-
| ------------- | ------------------------------------------- |
|
|
39
|
-
| `root` | The outermost container `<div>` |
|
|
40
|
-
| `step` | Each individual step `<div>` |
|
|
41
|
-
| `icon` | The icon circle / dot element |
|
|
42
|
-
| `title` | The step title `<div>` |
|
|
43
|
-
| `description` | The step description `<div>` |
|
|
44
|
-
| `connector` | The connector line between steps |
|
|
45
|
-
|
|
46
|
-
## Step Status
|
|
47
|
-
|
|
48
|
-
Each step's appearance is determined by its `StepStatus`:
|
|
49
|
-
|
|
50
|
-
| Status | Condition |
|
|
51
|
-
| ---------- | ------------------------------------------------------------------------- |
|
|
52
|
-
| `active` | Index equals `current`, or index is in `activeIndex` |
|
|
53
|
-
| `done` | Index is less than `current` (and not disabled / not in `activeIndex`) |
|
|
54
|
-
| `upcoming` | Index is greater than `current` |
|
|
55
|
-
| `disabled` | Index is in `disabled[]` — overrides all other statuses |
|
|
56
|
-
|
|
57
|
-
## Visual Types
|
|
58
|
-
|
|
59
|
-
### `type="default"` (Default)
|
|
60
|
-
|
|
61
|
-
Classic step indicator with circular icon badges and connecting lines.
|
|
62
|
-
|
|
63
|
-
- **Horizontal**: icons in a row, connectors are flex siblings between them, content labels appear below via `position: absolute`
|
|
64
|
-
- **Vertical**: icons in a left column with vertical connectors, content to the right
|
|
65
|
-
- Icon states: upcoming = outline circle with number; done = filled circle with checkmark; active = outline circle with color ring
|
|
66
|
-
- Provides a custom `icon` in `StepItem` to replace the number (checkmark still appears for `done` steps without a custom icon)
|
|
67
|
-
|
|
68
|
-
### `type="navigation"`
|
|
69
|
-
|
|
70
|
-
Pill-breadcrumb strip, suitable for page-level navigation headers.
|
|
71
|
-
|
|
72
|
-
- **Horizontal**: pills in a row separated by `›` arrow icons
|
|
73
|
-
- **Vertical**: a stacked list with a colored left-border rail on the active item
|
|
74
|
-
- Active step gets a white card with a subtle shadow; done steps show colored text
|
|
75
|
-
- More compact icon badge (24px vs 32px in `default`)
|
|
76
|
-
|
|
77
|
-
### `type="dot"`
|
|
78
|
-
|
|
79
|
-
Minimal dot indicators with optional labels, ideal for carousels or simple progress.
|
|
80
|
-
|
|
81
|
-
- **Horizontal**: small dots connected by thin lines, content below via `position: absolute`
|
|
82
|
-
- **Vertical**: dots in a left column with connectors, content to the right
|
|
83
|
-
- Active dot scales up (`1.6×`) with a color ring; done dot fills solid
|
|
84
|
-
|
|
85
|
-
## Usage Examples
|
|
86
|
-
|
|
87
|
-
### Basic controlled steps
|
|
88
|
-
|
|
89
|
-
```tsx
|
|
90
|
-
import { createSignal } from 'solid-js';
|
|
91
|
-
import { Steps } from 'solid-tom-ui';
|
|
92
|
-
|
|
93
|
-
const [current, setCurrent] = createSignal(0);
|
|
94
|
-
|
|
95
|
-
const items = [
|
|
96
|
-
{ title: 'Cart', description: 'Review items' },
|
|
97
|
-
{ title: 'Shipping', description: 'Enter address' },
|
|
98
|
-
{ title: 'Payment', description: 'Choose method' },
|
|
99
|
-
{ title: 'Confirm', description: 'Complete order' },
|
|
100
|
-
];
|
|
101
|
-
|
|
102
|
-
<Steps
|
|
103
|
-
type="default"
|
|
104
|
-
color="primary"
|
|
105
|
-
items={items}
|
|
106
|
-
current={current} // signal getter — NOT current()
|
|
107
|
-
setCurrent={setCurrent} // signal setter
|
|
108
|
-
/>
|
|
109
|
-
|
|
110
|
-
{/* External navigation */}
|
|
111
|
-
<button onClick={() => setCurrent(v => v - 1)} disabled={current() === 0}>Back</button>
|
|
112
|
-
<button onClick={() => setCurrent(v => v + 1)} disabled={current() === items.length - 1}>Next</button>
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Navigation type
|
|
116
|
-
|
|
117
|
-
```tsx
|
|
118
|
-
<Steps
|
|
119
|
-
type="navigation"
|
|
120
|
-
color="success"
|
|
121
|
-
orientation="horizontal"
|
|
122
|
-
items={items}
|
|
123
|
-
current={current}
|
|
124
|
-
setCurrent={setCurrent}
|
|
125
|
-
/>
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Dot type, vertical
|
|
129
|
-
|
|
130
|
-
```tsx
|
|
131
|
-
<Steps
|
|
132
|
-
type="dot"
|
|
133
|
-
color="info"
|
|
134
|
-
orientation="vertical"
|
|
135
|
-
items={items}
|
|
136
|
-
current={current}
|
|
137
|
-
setCurrent={setCurrent}
|
|
138
|
-
/>
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### Using `total` instead of `items`
|
|
142
|
-
|
|
143
|
-
Generates numbered steps automatically (`Step 1`, `Step 2`, …):
|
|
144
|
-
|
|
145
|
-
```tsx
|
|
146
|
-
<Steps
|
|
147
|
-
type="default"
|
|
148
|
-
color="accent"
|
|
149
|
-
total={5}
|
|
150
|
-
current={current}
|
|
151
|
-
setCurrent={setCurrent}
|
|
152
|
-
/>
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Disabled steps
|
|
156
|
-
|
|
157
|
-
```tsx
|
|
158
|
-
{/* Steps at index 1 and 2 cannot be clicked */}
|
|
159
|
-
<Steps
|
|
160
|
-
type="default"
|
|
161
|
-
color="error"
|
|
162
|
-
items={items}
|
|
163
|
-
current={current}
|
|
164
|
-
setCurrent={setCurrent}
|
|
165
|
-
disabled={[1, 2]}
|
|
166
|
-
/>
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Custom icon per step
|
|
170
|
-
|
|
171
|
-
```tsx
|
|
172
|
-
import UserIcon from 'lucide-solid/icons/user';
|
|
173
|
-
import CreditCardIcon from 'lucide-solid/icons/credit-card';
|
|
174
|
-
|
|
175
|
-
const items = [
|
|
176
|
-
{ title: 'Profile', icon: <UserIcon size={16} /> },
|
|
177
|
-
{ title: 'Billing', icon: <CreditCardIcon size={16} /> },
|
|
178
|
-
{ title: 'Confirm' },
|
|
179
|
-
];
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
> When a step has a custom `icon`, the icon always renders (even when `done`). Only steps **without** a custom icon show the checkmark when `done`.
|
|
183
|
-
|
|
184
|
-
### `activeIndex` — force steps to active
|
|
185
|
-
|
|
186
|
-
```tsx
|
|
187
|
-
{/* Steps 0 and 2 are always shown as active, regardless of current */}
|
|
188
|
-
<Steps
|
|
189
|
-
items={items}
|
|
190
|
-
current={current}
|
|
191
|
-
setCurrent={setCurrent}
|
|
192
|
-
activeIndex={[0, 2]}
|
|
193
|
-
/>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### `onChange` callback
|
|
197
|
-
|
|
198
|
-
```tsx
|
|
199
|
-
<Steps
|
|
200
|
-
items={items}
|
|
201
|
-
current={current}
|
|
202
|
-
setCurrent={setCurrent}
|
|
203
|
-
onChange={index => console.log('Navigated to step', index)}
|
|
204
|
-
/>
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Class customization
|
|
208
|
-
|
|
209
|
-
```tsx
|
|
210
|
-
<Steps
|
|
211
|
-
type="default"
|
|
212
|
-
color="primary"
|
|
213
|
-
items={items}
|
|
214
|
-
current={current}
|
|
215
|
-
setCurrent={setCurrent}
|
|
216
|
-
class={{
|
|
217
|
-
root: 'bg-base-200 rounded-xl p-4',
|
|
218
|
-
step: 'opacity-80 hover:opacity-100 transition-opacity',
|
|
219
|
-
title: 'text-xs uppercase tracking-wide',
|
|
220
|
-
icon: 'shadow-md',
|
|
221
|
-
connector: 'opacity-50',
|
|
222
|
-
}}
|
|
223
|
-
/>
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
## Critical: `current` Must Be a Signal Getter
|
|
227
|
-
|
|
228
|
-
The `current` prop is typed as `Accessor<number>` — it must be the signal **getter function**, not the evaluated value:
|
|
229
|
-
|
|
230
|
-
```tsx
|
|
231
|
-
const [step, setStep] = createSignal(0);
|
|
232
|
-
|
|
233
|
-
// ✅ Correct
|
|
234
|
-
<Steps current={step} setCurrent={setStep} ... />
|
|
235
|
-
|
|
236
|
-
// ❌ Wrong — passes a static number, component won't react to changes
|
|
237
|
-
<Steps current={step()} setCurrent={setStep} ... />
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
## Connector Animation
|
|
241
|
-
|
|
242
|
-
Both `default` and `dot` types animate their connectors:
|
|
243
|
-
|
|
244
|
-
- **Horizontal**: connector is a `flex` sibling element (not a child of the step). Its `::after` pseudo-element scales from 0 to 1 on the X axis when the connector element has `sui-step-done` or `sui-step-active` class.
|
|
245
|
-
- **Vertical**: connector is a child inside the icon column. Its `::after` pseudo-element scales from 0 to 1 on the Y axis via a descendant selector on the parent step's status class.
|
|
246
|
-
|
|
247
|
-
This is relevant when using `class.connector` overrides — only target the connector's base style, not `::after`.
|
|
248
|
-
|
|
249
|
-
## Common Mistakes
|
|
250
|
-
|
|
251
|
-
| Mistake | Fix |
|
|
252
|
-
| --- | --- |
|
|
253
|
-
| `current={step()}` | Pass the getter: `current={step}` |
|
|
254
|
-
| Expecting `items` and `total` to merge | `items` takes full priority when non-empty — use one or the other |
|
|
255
|
-
| Passing `class="..."` as a string | `class` is an object: `class={{ root: '...' }}` |
|
|
256
|
-
| Custom `icon` not showing for `done` steps | Custom icons always render for done steps — only icon-less steps show a checkmark |
|
|
257
|
-
| `disabled` not blocking navigation | `disabled` blocks `onClick` on the step itself, but not external `setCurrent` calls — validate in your own handler if needed |
|
|
258
|
-
---
|
|
259
|
-
|
|
260
|
-
## Component Conventions
|
|
261
|
-
|
|
262
|
-
> **CSS encoding**: internal CSS classes use short encoded names (e.g. `st01`, `st02`) per project convention.
|
|
263
|
-
|
|
264
|
-
> **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.
|
|
1
|
+
## COMPONENT IDENTITY
|
|
2
|
+
- **Import**: `import { Steps } from 'solid-tom-ui';`
|
|
3
|
+
- **Export**: `Steps` (named export), `StepsProps`, `StepItem` (type exports)
|
|
4
|
+
- **Framework**: SolidJS
|
|
5
|
+
- **Purpose**: Multi-step progress indicator — three visual types, two orientations, full color theming, disabled steps; always controlled (parent owns step index)
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Default | Description |
|
|
10
|
+
| ------------- | --------------------------------------------- | -------------- | ------------------------------------------------------------------------ |
|
|
11
|
+
| `type` | `'default' \| 'navigation' \| 'dot'` | `'default'` | Visual style of the steps |
|
|
12
|
+
| `color` | `BaseColorProps` | `'primary'` | Accent color for active/done steps and connectors |
|
|
13
|
+
| `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | Layout direction |
|
|
14
|
+
| `items` | `StepItem[]` | `[]` | Step definitions. Takes priority over `total` |
|
|
15
|
+
| `total` | `number` | — | Auto-generates `total` numbered steps (`Step 1`, `Step 2`, …). Used only when `items` is empty |
|
|
16
|
+
| `current` | `Accessor<number>` | — | **Signal getter** for the active step index (0-based) |
|
|
17
|
+
| `setCurrent` | `Setter<number>` | — | **Signal setter** — called when a step is clicked |
|
|
18
|
+
| `onChange` | `(index: number) => void` | — | Additional callback fired on step click, after `setCurrent` |
|
|
19
|
+
| `disabled` | `number[]` | `[]` | Indices of steps that cannot be clicked |
|
|
20
|
+
| `activeIndex` | `number[]` | — | Force specific step indices to `active` status, regardless of `current` |
|
|
21
|
+
| `class` | `{ root?, step?, icon?, title?, description?, connector? }` | — | Per-element class overrides (see below) |
|
|
22
|
+
|
|
23
|
+
### `StepItem`
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
type StepItem = {
|
|
27
|
+
title?: JSX.Element; // Step label
|
|
28
|
+
description?: JSX.Element; // Subtitle/detail text
|
|
29
|
+
icon?: JSX.Element; // Custom icon (replaces the number; checkmark still shows for done)
|
|
30
|
+
};
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### `class` Object
|
|
34
|
+
|
|
35
|
+
All keys are optional strings appended via `cn()`:
|
|
36
|
+
|
|
37
|
+
| Key | Target element |
|
|
38
|
+
| ------------- | ------------------------------------------- |
|
|
39
|
+
| `root` | The outermost container `<div>` |
|
|
40
|
+
| `step` | Each individual step `<div>` |
|
|
41
|
+
| `icon` | The icon circle / dot element |
|
|
42
|
+
| `title` | The step title `<div>` |
|
|
43
|
+
| `description` | The step description `<div>` |
|
|
44
|
+
| `connector` | The connector line between steps |
|
|
45
|
+
|
|
46
|
+
## Step Status
|
|
47
|
+
|
|
48
|
+
Each step's appearance is determined by its `StepStatus`:
|
|
49
|
+
|
|
50
|
+
| Status | Condition |
|
|
51
|
+
| ---------- | ------------------------------------------------------------------------- |
|
|
52
|
+
| `active` | Index equals `current`, or index is in `activeIndex` |
|
|
53
|
+
| `done` | Index is less than `current` (and not disabled / not in `activeIndex`) |
|
|
54
|
+
| `upcoming` | Index is greater than `current` |
|
|
55
|
+
| `disabled` | Index is in `disabled[]` — overrides all other statuses |
|
|
56
|
+
|
|
57
|
+
## Visual Types
|
|
58
|
+
|
|
59
|
+
### `type="default"` (Default)
|
|
60
|
+
|
|
61
|
+
Classic step indicator with circular icon badges and connecting lines.
|
|
62
|
+
|
|
63
|
+
- **Horizontal**: icons in a row, connectors are flex siblings between them, content labels appear below via `position: absolute`
|
|
64
|
+
- **Vertical**: icons in a left column with vertical connectors, content to the right
|
|
65
|
+
- Icon states: upcoming = outline circle with number; done = filled circle with checkmark; active = outline circle with color ring
|
|
66
|
+
- Provides a custom `icon` in `StepItem` to replace the number (checkmark still appears for `done` steps without a custom icon)
|
|
67
|
+
|
|
68
|
+
### `type="navigation"`
|
|
69
|
+
|
|
70
|
+
Pill-breadcrumb strip, suitable for page-level navigation headers.
|
|
71
|
+
|
|
72
|
+
- **Horizontal**: pills in a row separated by `›` arrow icons
|
|
73
|
+
- **Vertical**: a stacked list with a colored left-border rail on the active item
|
|
74
|
+
- Active step gets a white card with a subtle shadow; done steps show colored text
|
|
75
|
+
- More compact icon badge (24px vs 32px in `default`)
|
|
76
|
+
|
|
77
|
+
### `type="dot"`
|
|
78
|
+
|
|
79
|
+
Minimal dot indicators with optional labels, ideal for carousels or simple progress.
|
|
80
|
+
|
|
81
|
+
- **Horizontal**: small dots connected by thin lines, content below via `position: absolute`
|
|
82
|
+
- **Vertical**: dots in a left column with connectors, content to the right
|
|
83
|
+
- Active dot scales up (`1.6×`) with a color ring; done dot fills solid
|
|
84
|
+
|
|
85
|
+
## Usage Examples
|
|
86
|
+
|
|
87
|
+
### Basic controlled steps
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { createSignal } from 'solid-js';
|
|
91
|
+
import { Steps } from 'solid-tom-ui';
|
|
92
|
+
|
|
93
|
+
const [current, setCurrent] = createSignal(0);
|
|
94
|
+
|
|
95
|
+
const items = [
|
|
96
|
+
{ title: 'Cart', description: 'Review items' },
|
|
97
|
+
{ title: 'Shipping', description: 'Enter address' },
|
|
98
|
+
{ title: 'Payment', description: 'Choose method' },
|
|
99
|
+
{ title: 'Confirm', description: 'Complete order' },
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
<Steps
|
|
103
|
+
type="default"
|
|
104
|
+
color="primary"
|
|
105
|
+
items={items}
|
|
106
|
+
current={current} // signal getter — NOT current()
|
|
107
|
+
setCurrent={setCurrent} // signal setter
|
|
108
|
+
/>
|
|
109
|
+
|
|
110
|
+
{/* External navigation */}
|
|
111
|
+
<button onClick={() => setCurrent(v => v - 1)} disabled={current() === 0}>Back</button>
|
|
112
|
+
<button onClick={() => setCurrent(v => v + 1)} disabled={current() === items.length - 1}>Next</button>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Navigation type
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
<Steps
|
|
119
|
+
type="navigation"
|
|
120
|
+
color="success"
|
|
121
|
+
orientation="horizontal"
|
|
122
|
+
items={items}
|
|
123
|
+
current={current}
|
|
124
|
+
setCurrent={setCurrent}
|
|
125
|
+
/>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Dot type, vertical
|
|
129
|
+
|
|
130
|
+
```tsx
|
|
131
|
+
<Steps
|
|
132
|
+
type="dot"
|
|
133
|
+
color="info"
|
|
134
|
+
orientation="vertical"
|
|
135
|
+
items={items}
|
|
136
|
+
current={current}
|
|
137
|
+
setCurrent={setCurrent}
|
|
138
|
+
/>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Using `total` instead of `items`
|
|
142
|
+
|
|
143
|
+
Generates numbered steps automatically (`Step 1`, `Step 2`, …):
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
<Steps
|
|
147
|
+
type="default"
|
|
148
|
+
color="accent"
|
|
149
|
+
total={5}
|
|
150
|
+
current={current}
|
|
151
|
+
setCurrent={setCurrent}
|
|
152
|
+
/>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Disabled steps
|
|
156
|
+
|
|
157
|
+
```tsx
|
|
158
|
+
{/* Steps at index 1 and 2 cannot be clicked */}
|
|
159
|
+
<Steps
|
|
160
|
+
type="default"
|
|
161
|
+
color="error"
|
|
162
|
+
items={items}
|
|
163
|
+
current={current}
|
|
164
|
+
setCurrent={setCurrent}
|
|
165
|
+
disabled={[1, 2]}
|
|
166
|
+
/>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Custom icon per step
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import UserIcon from 'lucide-solid/icons/user';
|
|
173
|
+
import CreditCardIcon from 'lucide-solid/icons/credit-card';
|
|
174
|
+
|
|
175
|
+
const items = [
|
|
176
|
+
{ title: 'Profile', icon: <UserIcon size={16} /> },
|
|
177
|
+
{ title: 'Billing', icon: <CreditCardIcon size={16} /> },
|
|
178
|
+
{ title: 'Confirm' },
|
|
179
|
+
];
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
> When a step has a custom `icon`, the icon always renders (even when `done`). Only steps **without** a custom icon show the checkmark when `done`.
|
|
183
|
+
|
|
184
|
+
### `activeIndex` — force steps to active
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
{/* Steps 0 and 2 are always shown as active, regardless of current */}
|
|
188
|
+
<Steps
|
|
189
|
+
items={items}
|
|
190
|
+
current={current}
|
|
191
|
+
setCurrent={setCurrent}
|
|
192
|
+
activeIndex={[0, 2]}
|
|
193
|
+
/>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### `onChange` callback
|
|
197
|
+
|
|
198
|
+
```tsx
|
|
199
|
+
<Steps
|
|
200
|
+
items={items}
|
|
201
|
+
current={current}
|
|
202
|
+
setCurrent={setCurrent}
|
|
203
|
+
onChange={index => console.log('Navigated to step', index)}
|
|
204
|
+
/>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Class customization
|
|
208
|
+
|
|
209
|
+
```tsx
|
|
210
|
+
<Steps
|
|
211
|
+
type="default"
|
|
212
|
+
color="primary"
|
|
213
|
+
items={items}
|
|
214
|
+
current={current}
|
|
215
|
+
setCurrent={setCurrent}
|
|
216
|
+
class={{
|
|
217
|
+
root: 'bg-base-200 rounded-xl p-4',
|
|
218
|
+
step: 'opacity-80 hover:opacity-100 transition-opacity',
|
|
219
|
+
title: 'text-xs uppercase tracking-wide',
|
|
220
|
+
icon: 'shadow-md',
|
|
221
|
+
connector: 'opacity-50',
|
|
222
|
+
}}
|
|
223
|
+
/>
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Critical: `current` Must Be a Signal Getter
|
|
227
|
+
|
|
228
|
+
The `current` prop is typed as `Accessor<number>` — it must be the signal **getter function**, not the evaluated value:
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
const [step, setStep] = createSignal(0);
|
|
232
|
+
|
|
233
|
+
// ✅ Correct
|
|
234
|
+
<Steps current={step} setCurrent={setStep} ... />
|
|
235
|
+
|
|
236
|
+
// ❌ Wrong — passes a static number, component won't react to changes
|
|
237
|
+
<Steps current={step()} setCurrent={setStep} ... />
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Connector Animation
|
|
241
|
+
|
|
242
|
+
Both `default` and `dot` types animate their connectors:
|
|
243
|
+
|
|
244
|
+
- **Horizontal**: connector is a `flex` sibling element (not a child of the step). Its `::after` pseudo-element scales from 0 to 1 on the X axis when the connector element has `sui-step-done` or `sui-step-active` class.
|
|
245
|
+
- **Vertical**: connector is a child inside the icon column. Its `::after` pseudo-element scales from 0 to 1 on the Y axis via a descendant selector on the parent step's status class.
|
|
246
|
+
|
|
247
|
+
This is relevant when using `class.connector` overrides — only target the connector's base style, not `::after`.
|
|
248
|
+
|
|
249
|
+
## Common Mistakes
|
|
250
|
+
|
|
251
|
+
| Mistake | Fix |
|
|
252
|
+
| --- | --- |
|
|
253
|
+
| `current={step()}` | Pass the getter: `current={step}` |
|
|
254
|
+
| Expecting `items` and `total` to merge | `items` takes full priority when non-empty — use one or the other |
|
|
255
|
+
| Passing `class="..."` as a string | `class` is an object: `class={{ root: '...' }}` |
|
|
256
|
+
| Custom `icon` not showing for `done` steps | Custom icons always render for done steps — only icon-less steps show a checkmark |
|
|
257
|
+
| `disabled` not blocking navigation | `disabled` blocks `onClick` on the step itself, but not external `setCurrent` calls — validate in your own handler if needed |
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Component Conventions
|
|
261
|
+
|
|
262
|
+
> **CSS encoding**: internal CSS classes use short encoded names (e.g. `st01`, `st02`) per project convention.
|
|
263
|
+
|
|
264
|
+
> **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.
|