@redis-ui/components 43.0.2 → 43.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/HighlightedIcon/HighlightedIcon.cjs +26 -0
- package/dist/HighlightedIcon/HighlightedIcon.d.ts +3 -0
- package/dist/HighlightedIcon/HighlightedIcon.js +26 -0
- package/dist/HighlightedIcon/HighlightedIcon.style.cjs +49 -0
- package/dist/HighlightedIcon/HighlightedIcon.style.d.ts +5 -0
- package/dist/HighlightedIcon/HighlightedIcon.style.js +47 -0
- package/dist/HighlightedIcon/HighlightedIcon.types.d.ts +8 -0
- package/dist/HighlightedIcon/index.d.ts +3 -0
- package/dist/Stepper/Stepper.cjs +14 -5
- package/dist/Stepper/Stepper.d.ts +2 -0
- package/dist/Stepper/Stepper.js +14 -5
- package/dist/Stepper/Stepper.utils.cjs +12 -0
- package/dist/Stepper/Stepper.utils.d.ts +2 -0
- package/dist/Stepper/Stepper.utils.js +12 -0
- package/dist/Stepper/components/Compose/Compose.d.ts +1 -0
- package/dist/Stepper/components/Step/Step.cjs +2 -0
- package/dist/Stepper/components/Step/Step.d.ts +1 -0
- package/dist/Stepper/components/Step/Step.js +2 -0
- package/dist/Stepper/components/Step/components/Compose/Compose.cjs +2 -9
- package/dist/Stepper/components/Step/components/Compose/Compose.js +2 -9
- package/dist/Stepper/components/Step/components/Separator/Separator.cjs +15 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.d.ts +3 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.js +15 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.style.cjs +24 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.style.d.ts +1 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.style.js +22 -0
- package/dist/Stepper/components/Step/components/Separator/Separator.types.d.ts +5 -0
- package/dist/index.cjs +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +74 -70
- package/package.json +2 -2
- package/skills/redis-ui-components/SKILL.md +0 -2
- package/skills/redis-ui-components/references/ActionIconButton.md +96 -0
- package/skills/redis-ui-components/references/AppBar.md +161 -0
- package/skills/redis-ui-components/references/AppSelectionMenu.md +184 -0
- package/skills/redis-ui-components/references/AutoCompleteSelect.md +193 -0
- package/skills/redis-ui-components/references/Badge.md +77 -0
- package/skills/redis-ui-components/references/Banner.md +563 -0
- package/skills/redis-ui-components/references/BoxSelectionGroup.md +487 -0
- package/skills/redis-ui-components/references/Breadcrumbs.md +214 -0
- package/skills/redis-ui-components/references/ButtonGroup.md +126 -0
- package/skills/redis-ui-components/references/Card.md +56 -0
- package/skills/redis-ui-components/references/Checkbox.md +171 -0
- package/skills/redis-ui-components/references/Chip.md +154 -0
- package/skills/redis-ui-components/references/ChipList.md +307 -0
- package/skills/redis-ui-components/references/CopyToClipboardButton.md +47 -0
- package/skills/redis-ui-components/references/CountryFlag.md +57 -0
- package/skills/redis-ui-components/references/Drawer.md +298 -0
- package/skills/redis-ui-components/references/Filters.md +162 -0
- package/skills/redis-ui-components/references/FormField.md +678 -0
- package/skills/redis-ui-components/references/IconButton.md +63 -0
- package/skills/redis-ui-components/references/Input.md +295 -0
- package/skills/redis-ui-components/references/KeyValueList.md +501 -0
- package/skills/redis-ui-components/references/Label.md +238 -0
- package/skills/redis-ui-components/references/Link.md +402 -0
- package/skills/redis-ui-components/references/Loader.md +100 -0
- package/skills/redis-ui-components/references/Menu.md +988 -0
- package/skills/redis-ui-components/references/MidBar.md +358 -0
- package/skills/redis-ui-components/references/Modal.md +525 -0
- package/skills/redis-ui-components/references/MoreInfoIcon.md +119 -0
- package/skills/redis-ui-components/references/MultiSelect.md +558 -0
- package/skills/redis-ui-components/references/NumericInput.md +322 -0
- package/skills/redis-ui-components/references/Overflow.md +127 -0
- package/skills/redis-ui-components/references/Pagination.md +151 -0
- package/skills/redis-ui-components/references/PasswordInput.md +262 -0
- package/skills/redis-ui-components/references/Popover.md +868 -0
- package/skills/redis-ui-components/references/ProfileIcon.md +65 -0
- package/skills/redis-ui-components/references/ProgressBar.md +103 -0
- package/skills/redis-ui-components/references/QuantityCounter.md +555 -0
- package/skills/redis-ui-components/references/RadioGroup.md +265 -0
- package/skills/redis-ui-components/references/ScreenReaderAnnounce.md +147 -0
- package/skills/redis-ui-components/references/SearchBar.md +242 -0
- package/skills/redis-ui-components/references/SearchInput.md +213 -0
- package/skills/redis-ui-components/references/Section.md +349 -0
- package/skills/redis-ui-components/references/SideBar.md +468 -0
- package/skills/redis-ui-components/references/Slider.md +398 -0
- package/skills/redis-ui-components/references/Stepper.md +288 -0
- package/skills/redis-ui-components/references/Switch.md +193 -0
- package/skills/redis-ui-components/references/Tabs.md +383 -0
- package/skills/redis-ui-components/references/TextArea.md +139 -0
- package/skills/redis-ui-components/references/TextButton.md +217 -0
- package/skills/redis-ui-components/references/Toast.md +399 -0
- package/skills/redis-ui-components/references/ToggleButton.md +163 -0
- package/skills/redis-ui-components/references/Tooltip.md +636 -0
- package/skills/redis-ui-components/references/Typography.md +323 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
# Slider
|
|
2
|
+
|
|
3
|
+
Composable range slider with a default wrapper, track, thumb, marks, and labels. Use `Slider` for the standard layout, or `Slider.Compose` when you need to position and style the pieces manually.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
> Examples also use icons from `@redislabsdev/redis-ui-icons`:
|
|
12
|
+
> ```tsx
|
|
13
|
+
> import { PlusIcon, MinusIcon, InfoIcon } from '@redislabsdev/redis-ui-icons';
|
|
14
|
+
> ```
|
|
15
|
+
|
|
16
|
+
## Props
|
|
17
|
+
|
|
18
|
+
| Prop | Type | Default | Description |
|
|
19
|
+
|------|------|---------|-------------|
|
|
20
|
+
| value | `number[]` | - | Controlled slider value |
|
|
21
|
+
| defaultValue | `number[]` | - | Uncontrolled initial value |
|
|
22
|
+
| onChange | `(values: number[]) => void` | - | Called when the slider value changes |
|
|
23
|
+
| disabled | `boolean` | `false` | Disables interaction |
|
|
24
|
+
| min | `number` | `0` | Minimum slider value |
|
|
25
|
+
| max | `number` | *required* | Maximum slider value |
|
|
26
|
+
| step | `number` | `1` | Step increment |
|
|
27
|
+
| marks | `SliderMarks` | - | Mark and label definitions for `Slider.MarksAndLabels` |
|
|
28
|
+
|
|
29
|
+
The top-level `Slider` also inherits standard compose element props through `ComposeElementProps`, excluding `children`, `content`, `dir`, `defaultValue`, and `onChange`.
|
|
30
|
+
|
|
31
|
+
## Sub-components
|
|
32
|
+
|
|
33
|
+
- `Slider.Compose` - low-level slider root that provides slider context and renders the Radix slider container.
|
|
34
|
+
- `Slider.Track` - default track wrapper that renders `Slider.Track.Range`.
|
|
35
|
+
- `Slider.Track.Compose` - container for custom track composition.
|
|
36
|
+
- `Slider.Track.Range` - renders the filled portion of the track.
|
|
37
|
+
- `Slider.Thumb` - default thumb wrapper.
|
|
38
|
+
- `Slider.Thumb.Compose` - container for custom thumb composition.
|
|
39
|
+
- `Slider.Mark` - default mark renderer positioned by `value`.
|
|
40
|
+
- `Slider.Mark.Compose` - renders a mark at a specific value with custom children.
|
|
41
|
+
- `Slider.Label` - default label renderer positioned by `value`.
|
|
42
|
+
- `Slider.Label.Compose` - renders a label at a specific value and can set the slider value when clicked.
|
|
43
|
+
- `Slider.MarksAndLabels` - renders marks and labels from a `marks` array, with optional custom renderers.
|
|
44
|
+
|
|
45
|
+
## Examples
|
|
46
|
+
|
|
47
|
+
### Playground
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
51
|
+
|
|
52
|
+
<Slider defaultValue={[0]} max={9} aria-label="slider" />;
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Uncontrolled
|
|
56
|
+
|
|
57
|
+
> The slider can be used in uncontrolled mode with `defaultValue`.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
61
|
+
|
|
62
|
+
<Slider max={9} defaultValue={[3]} aria-label="Slider" />;
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Controlled
|
|
66
|
+
|
|
67
|
+
> Use `value` and `onChange` for controlled mode.
|
|
68
|
+
> The slider value is controlled externally - use the +/- buttons to change the value from outside the slider.
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { useState } from 'react';
|
|
72
|
+
import { Slider, ActionIconButton } from '@redislabsdev/redis-ui-components';
|
|
73
|
+
import { PlusIcon, MinusIcon } from '@redislabsdev/redis-ui-icons';
|
|
74
|
+
|
|
75
|
+
function ControlledSliderExample() {
|
|
76
|
+
const [stepIndex, setStepIndex] = useState(1);
|
|
77
|
+
|
|
78
|
+
const decrement = () => setStepIndex((prev) => Math.max(0, prev - 1));
|
|
79
|
+
const increment = () => setStepIndex((prev) => Math.min(6, prev + 1));
|
|
80
|
+
|
|
81
|
+
const handleValueChange = (value: number[]) => {
|
|
82
|
+
setStepIndex(value[0]);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<>
|
|
87
|
+
<Slider max={6} value={[stepIndex]} onChange={handleValueChange} aria-label="Slider" />
|
|
88
|
+
<p>Use the buttons to control the slider externally:</p>
|
|
89
|
+
<div>
|
|
90
|
+
<ActionIconButton
|
|
91
|
+
icon={MinusIcon}
|
|
92
|
+
onClick={decrement}
|
|
93
|
+
disabled={stepIndex === 0}
|
|
94
|
+
aria-label="Decrement"
|
|
95
|
+
/>
|
|
96
|
+
<ActionIconButton
|
|
97
|
+
icon={PlusIcon}
|
|
98
|
+
onClick={increment}
|
|
99
|
+
disabled={stepIndex === 6}
|
|
100
|
+
aria-label="Increment"
|
|
101
|
+
/>
|
|
102
|
+
</div>
|
|
103
|
+
<p>
|
|
104
|
+
Selected: <strong>{stepIndex}</strong>
|
|
105
|
+
</p>
|
|
106
|
+
</>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
<ControlledSliderExample />;
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Disabled
|
|
114
|
+
|
|
115
|
+
> Set `disabled` prop to disable the slider.
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
119
|
+
|
|
120
|
+
<Slider max={9} defaultValue={[3]} aria-label="Slider" disabled />;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### DifferentStepCounts
|
|
124
|
+
|
|
125
|
+
> The slider works with any number of steps.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
129
|
+
|
|
130
|
+
<>
|
|
131
|
+
<Slider max={2} defaultValue={[1]} aria-label="Slider" />
|
|
132
|
+
<Slider max={6} defaultValue={[3]} aria-label="Slider" />
|
|
133
|
+
</>;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### PartialLabelsAndMarks
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
140
|
+
|
|
141
|
+
<Slider
|
|
142
|
+
max={6}
|
|
143
|
+
defaultValue={[3]}
|
|
144
|
+
marks={[
|
|
145
|
+
{ value: 0, mark: true, label: 'Min' },
|
|
146
|
+
{ value: 1, mark: true },
|
|
147
|
+
{ value: 2, mark: true },
|
|
148
|
+
{ value: 3, mark: true, label: 'Medium' },
|
|
149
|
+
{ value: 4, mark: true },
|
|
150
|
+
{ value: 5, mark: true },
|
|
151
|
+
{ value: 6, mark: true, label: 'Max' }
|
|
152
|
+
]}
|
|
153
|
+
aria-label="Slider"
|
|
154
|
+
/>;
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### MinAndStep
|
|
158
|
+
|
|
159
|
+
> Use `min` and `step` props to customize the slider range and granularity.
|
|
160
|
+
> This example shows a slider from 10 to 100 with steps of 10.
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { useState } from 'react';
|
|
164
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
165
|
+
|
|
166
|
+
function MinAndStepExample() {
|
|
167
|
+
const [value, setValue] = useState([30]);
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<>
|
|
171
|
+
<Slider.Compose min={10} max={100} step={10} value={value} onChange={setValue} aria-label="Slider">
|
|
172
|
+
<Slider.Track.Compose>
|
|
173
|
+
<Slider.Track.Range />
|
|
174
|
+
</Slider.Track.Compose>
|
|
175
|
+
<Slider.MarksAndLabels
|
|
176
|
+
marks={[
|
|
177
|
+
{ value: 10, mark: true, label: '10' },
|
|
178
|
+
{ value: 30, mark: true, label: '30' },
|
|
179
|
+
{ value: 50, mark: true, label: '50' },
|
|
180
|
+
{ value: 70, mark: true, label: '70' },
|
|
181
|
+
{ value: 100, mark: true, label: '100' }
|
|
182
|
+
]}
|
|
183
|
+
/>
|
|
184
|
+
<Slider.Thumb />
|
|
185
|
+
</Slider.Compose>
|
|
186
|
+
<p>
|
|
187
|
+
Current value: <strong>{value[0]}</strong>
|
|
188
|
+
</p>
|
|
189
|
+
</>
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
<MinAndStepExample />;
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### WithMarks
|
|
197
|
+
|
|
198
|
+
> Display marks only without labels.
|
|
199
|
+
> Marks are visual indicators positioned at specific values on the slider.
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
203
|
+
|
|
204
|
+
const marks = [
|
|
205
|
+
{ value: 0, mark: true },
|
|
206
|
+
{ value: 1, mark: true },
|
|
207
|
+
{ value: 2, mark: true },
|
|
208
|
+
{ value: 3, mark: true },
|
|
209
|
+
{ value: 4, mark: true },
|
|
210
|
+
{ value: 5, mark: true },
|
|
211
|
+
{ value: 6, mark: true },
|
|
212
|
+
{ value: 7, mark: true },
|
|
213
|
+
{ value: 8, mark: true },
|
|
214
|
+
{ value: 9, mark: true }
|
|
215
|
+
];
|
|
216
|
+
|
|
217
|
+
<>
|
|
218
|
+
<Slider.Compose max={9} defaultValue={[5]} aria-label="Slider">
|
|
219
|
+
<Slider.Track.Compose>
|
|
220
|
+
<Slider.Track.Range />
|
|
221
|
+
</Slider.Track.Compose>
|
|
222
|
+
<Slider.MarksAndLabels marks={marks} />
|
|
223
|
+
<Slider.Thumb />
|
|
224
|
+
</Slider.Compose>
|
|
225
|
+
<Slider.Compose max={9} defaultValue={[5]} disabled>
|
|
226
|
+
<Slider.Track.Compose>
|
|
227
|
+
<Slider.Track.Range />
|
|
228
|
+
</Slider.Track.Compose>
|
|
229
|
+
<Slider.MarksAndLabels marks={marks} />
|
|
230
|
+
<Slider.Thumb />
|
|
231
|
+
</Slider.Compose>
|
|
232
|
+
</>;
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### CustomRenderers
|
|
236
|
+
|
|
237
|
+
> Customize the appearance of marks and labels using custom render functions.
|
|
238
|
+
> This example shows custom styling with badges, icons, and conditional formatting.
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import { FlexGroup, Badge, Typography, Slider } from '@redislabsdev/redis-ui-components';
|
|
242
|
+
import { InfoIcon } from '@redislabsdev/redis-ui-icons';
|
|
243
|
+
import { MOCK_MARKS } from './SliderStory.data';
|
|
244
|
+
import * as S from './SliderStory.style';
|
|
245
|
+
|
|
246
|
+
const CustomLabel = ({ value, label = '' }: { value: number; label?: string }) => {
|
|
247
|
+
return (
|
|
248
|
+
<FlexGroup direction="column" align="center">
|
|
249
|
+
{value === 5 && <Badge label="Middle" variant="notice" />}
|
|
250
|
+
<FlexGroup>
|
|
251
|
+
<Typography.Body variant={value === 0 || value === 10 || value === 5 ? 'italic' : 'regular'}>
|
|
252
|
+
{label}
|
|
253
|
+
</Typography.Body>
|
|
254
|
+
{value === 8 && <InfoIcon />}
|
|
255
|
+
</FlexGroup>
|
|
256
|
+
</FlexGroup>
|
|
257
|
+
);
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const CustomMark = () => <S.Mark />;
|
|
261
|
+
|
|
262
|
+
<Slider.Compose max={10} defaultValue={[5]} aria-label="Slider">
|
|
263
|
+
<Slider.Track.Compose>
|
|
264
|
+
<Slider.Track.Range />
|
|
265
|
+
</Slider.Track.Compose>
|
|
266
|
+
<Slider.MarksAndLabels marks={MOCK_MARKS} renderLabel={CustomLabel} renderMark={CustomMark} />
|
|
267
|
+
<Slider.Thumb />
|
|
268
|
+
</Slider.Compose>;
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### ComposeWithLabels
|
|
272
|
+
|
|
273
|
+
> Display labels only without marks.
|
|
274
|
+
> Labels show text at specific positions on the slider.
|
|
275
|
+
|
|
276
|
+
```tsx
|
|
277
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
278
|
+
|
|
279
|
+
<Slider.Compose max={10} defaultValue={[5]} aria-label="Slider">
|
|
280
|
+
<Slider.Track.Compose>
|
|
281
|
+
<Slider.Track.Range />
|
|
282
|
+
</Slider.Track.Compose>
|
|
283
|
+
<Slider.MarksAndLabels
|
|
284
|
+
marks={[
|
|
285
|
+
{ value: 0, mark: false, label: 'Min' },
|
|
286
|
+
{ value: 5, mark: false, label: 'Medium' },
|
|
287
|
+
{ value: 10, mark: false, label: 'Max' }
|
|
288
|
+
]}
|
|
289
|
+
/>
|
|
290
|
+
<Slider.Thumb />
|
|
291
|
+
</Slider.Compose>;
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### ComposeWithMarksAndLabels
|
|
295
|
+
|
|
296
|
+
> Display both marks and labels together.
|
|
297
|
+
> Each mark can have an optional label to describe its value.
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
301
|
+
|
|
302
|
+
<Slider.Compose max={9} defaultValue={[5]}>
|
|
303
|
+
<Slider.Track.Compose>
|
|
304
|
+
<Slider.Track.Range />
|
|
305
|
+
</Slider.Track.Compose>
|
|
306
|
+
<Slider.MarksAndLabels
|
|
307
|
+
marks={[
|
|
308
|
+
{ value: 0, mark: true, label: '0GB' },
|
|
309
|
+
{ value: 2, mark: true, label: '2GB' },
|
|
310
|
+
{ value: 5, mark: true, label: '5GB' },
|
|
311
|
+
{ value: 8, mark: true, label: '8GB' },
|
|
312
|
+
{ value: 9, mark: true, label: '10GB' }
|
|
313
|
+
]}
|
|
314
|
+
/>
|
|
315
|
+
<Slider.Thumb />
|
|
316
|
+
</Slider.Compose>;
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### DeepComposition
|
|
320
|
+
|
|
321
|
+
> Deep composition allows you to place Mark and Label components independently.
|
|
322
|
+
> This gives you full control over positioning and styling.
|
|
323
|
+
|
|
324
|
+
```tsx
|
|
325
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
326
|
+
|
|
327
|
+
<Slider.Compose max={9} defaultValue={[5]}>
|
|
328
|
+
<Slider.Track.Compose>
|
|
329
|
+
<Slider.Track.Range />
|
|
330
|
+
</Slider.Track.Compose>
|
|
331
|
+
|
|
332
|
+
<Slider.Mark value={0} />
|
|
333
|
+
<Slider.Mark value={2} />
|
|
334
|
+
<Slider.Mark value={5} />
|
|
335
|
+
<Slider.Mark value={8} />
|
|
336
|
+
<Slider.Mark value={9} />
|
|
337
|
+
|
|
338
|
+
<Slider.Label value={0}>Min</Slider.Label>
|
|
339
|
+
<Slider.Label value={4}>Medium</Slider.Label>
|
|
340
|
+
<Slider.Label value={9}>Max</Slider.Label>
|
|
341
|
+
|
|
342
|
+
<Slider.Thumb />
|
|
343
|
+
</Slider.Compose>;
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### CustomStyling
|
|
347
|
+
|
|
348
|
+
> Full composition example showing how to create custom styled slider components.
|
|
349
|
+
> You can compose your own slider with custom styling for all parts.
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
import { Fragment, useState } from 'react';
|
|
353
|
+
import { Slider } from '@redislabsdev/redis-ui-components';
|
|
354
|
+
import { PLANS_MOCK_MARKS } from './SliderStory.data';
|
|
355
|
+
import * as S from './SliderStory.style';
|
|
356
|
+
|
|
357
|
+
function CustomStylingExample() {
|
|
358
|
+
const [value, setValue] = useState([5]);
|
|
359
|
+
|
|
360
|
+
return (
|
|
361
|
+
<>
|
|
362
|
+
<Slider.Compose onChange={setValue} value={value} max={PLANS_MOCK_MARKS.length - 1}>
|
|
363
|
+
<S.CustomTrackCompose>
|
|
364
|
+
<S.CustomRange />
|
|
365
|
+
</S.CustomTrackCompose>
|
|
366
|
+
{PLANS_MOCK_MARKS.map(({ value: valueMark, label }) => (
|
|
367
|
+
<Fragment key={valueMark}>
|
|
368
|
+
<S.CustomLabel value={valueMark}>{label}</S.CustomLabel>
|
|
369
|
+
<Slider.Mark.Compose value={valueMark}>
|
|
370
|
+
<S.CustomMark />
|
|
371
|
+
</Slider.Mark.Compose>
|
|
372
|
+
</Fragment>
|
|
373
|
+
))}
|
|
374
|
+
<Slider.Thumb.Compose>
|
|
375
|
+
<S.CustomThumb />
|
|
376
|
+
</Slider.Thumb.Compose>
|
|
377
|
+
</Slider.Compose>
|
|
378
|
+
<p>
|
|
379
|
+
Current value: <strong>{value[0]}</strong>
|
|
380
|
+
</p>
|
|
381
|
+
</>
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
<CustomStylingExample />;
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## Notes
|
|
389
|
+
|
|
390
|
+
- Use `defaultValue` for uncontrolled sliders.
|
|
391
|
+
- Use `value` and `onChange` when the slider state is controlled externally.
|
|
392
|
+
- Set `disabled` to prevent interaction.
|
|
393
|
+
- `min` and `step` let you customize the value range and granularity.
|
|
394
|
+
- `marks` accepts `SliderMarks`, where each entry can include `value`, `mark`, and `label`.
|
|
395
|
+
- `Slider.MarksAndLabels` supports custom `renderMark` and `renderLabel` callbacks for fully custom mark/label rendering.
|
|
396
|
+
- `Slider.Mark.Compose` and `Slider.Label.Compose` let you place marks and labels independently.
|
|
397
|
+
- `Slider.Label.Compose` is clickable by default and can update the slider value unless `clickable={false}`.
|
|
398
|
+
- The top-level `Slider` is a convenience wrapper; use `Slider.Compose` when you need to build the slider layout manually.
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# Stepper
|
|
2
|
+
|
|
3
|
+
Composable stepper for ordered workflows with a data-driven root API, controlled navigation, and fully composable step parts for custom labels, icons, and styling.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { Stepper } from '@redislabsdev/redis-ui-components';
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
If you want to style against step state, also import `StepperStepState` from the same package.
|
|
12
|
+
|
|
13
|
+
## Props
|
|
14
|
+
|
|
15
|
+
### `Stepper`
|
|
16
|
+
|
|
17
|
+
| Prop | Type | Default | Description |
|
|
18
|
+
|------|------|---------|-------------|
|
|
19
|
+
| steps | `StepperStep[]` | required | Array of step descriptors rendered by the root stepper |
|
|
20
|
+
| currentStep | `number` | `-1` | Zero-based active step index |
|
|
21
|
+
| getIsStepInteractive | `(stepIndex: number) => boolean` | - | Optional predicate that marks specific steps interactive |
|
|
22
|
+
| onStepChange | `(stepIndex: number) => void` | - | Called when the user activates a step |
|
|
23
|
+
| compose root props | `ComposeElementProps<HTMLElement>` | - | Additional container props forwarded to `Stepper.Compose` |
|
|
24
|
+
|
|
25
|
+
`Stepper` also accepts the remaining `ComposeElementProps<HTMLElement>` props, including `className`, `style`, `id`, `data-*`, and event handlers.
|
|
26
|
+
|
|
27
|
+
### `StepperStep`
|
|
28
|
+
|
|
29
|
+
| Field | Type | Description |
|
|
30
|
+
|-------|------|-------------|
|
|
31
|
+
| label | `ReactNode` | Optional label content for the step |
|
|
32
|
+
| icon | `ReactNode` | Optional icon content for the step circle |
|
|
33
|
+
|
|
34
|
+
### `Stepper.Compose`
|
|
35
|
+
|
|
36
|
+
| Prop | Type | Default | Description |
|
|
37
|
+
|------|------|---------|-------------|
|
|
38
|
+
| children | `ReactNode` | required | Step compositions rendered inside the stepper |
|
|
39
|
+
| currentStep | `number` | `-1` | Zero-based active step index |
|
|
40
|
+
| getIsStepInteractive | `(stepIndex: number) => boolean` | - | Optional predicate that marks specific steps interactive |
|
|
41
|
+
| onStepChange | `(stepIndex: number) => void` | - | Called when the user activates a step |
|
|
42
|
+
| compose root props | `ComposeElementProps<HTMLElement>` | - | Standard container props forwarded to the compose root |
|
|
43
|
+
|
|
44
|
+
`Stepper.Compose` also accepts the remaining `ComposeElementProps<HTMLElement>` props.
|
|
45
|
+
|
|
46
|
+
### `Stepper.Step`
|
|
47
|
+
|
|
48
|
+
| Prop | Type | Default | Description |
|
|
49
|
+
|------|------|---------|-------------|
|
|
50
|
+
| children | `ReactNode` | - | Label content rendered by the default step layout |
|
|
51
|
+
| step wrapper props | `HTMLAttributes<HTMLDivElement>` | - | Additional props forwarded to the step wrapper |
|
|
52
|
+
|
|
53
|
+
`Stepper.Step` is a convenience wrapper around `Stepper.Step.Compose`, `Stepper.Step.Icon`, and `Stepper.Step.Label`.
|
|
54
|
+
|
|
55
|
+
### `Stepper.Step.Compose`
|
|
56
|
+
|
|
57
|
+
| Prop | Type | Default | Description |
|
|
58
|
+
|------|------|---------|-------------|
|
|
59
|
+
| children | `ReactNode` | required | Custom step contents |
|
|
60
|
+
| compose root props | `ComposeElementProps<HTMLElement>` | - | Standard container props forwarded to the step compose root |
|
|
61
|
+
|
|
62
|
+
### `Stepper.Step.Icon`
|
|
63
|
+
|
|
64
|
+
| Prop | Type | Default | Description |
|
|
65
|
+
|------|------|---------|-------------|
|
|
66
|
+
| children | `ReactNode` | - | Custom icon content; when omitted, the step number is shown and completed steps render a check icon |
|
|
67
|
+
| icon wrapper props | `HTMLAttributes<HTMLDivElement>` | - | Additional props forwarded to the icon container |
|
|
68
|
+
|
|
69
|
+
### `Stepper.Step.Label`
|
|
70
|
+
|
|
71
|
+
| Prop | Type | Default | Description |
|
|
72
|
+
|------|------|---------|-------------|
|
|
73
|
+
| children | `ReactNode` | - | Label content rendered next to the icon |
|
|
74
|
+
| typography body props | `TypographyBodyProps` | - | Remaining body typography props forwarded to the label |
|
|
75
|
+
|
|
76
|
+
### `Stepper.Step.useStepContext`
|
|
77
|
+
|
|
78
|
+
Hook that returns the current step `state` and `index` for custom step rendering and styling.
|
|
79
|
+
|
|
80
|
+
## Sub-components
|
|
81
|
+
|
|
82
|
+
- `Stepper.Compose` - Root composition container that provides stepper state and navigation.
|
|
83
|
+
- `Stepper.Step` - Convenience wrapper that renders the default step layout.
|
|
84
|
+
- `Stepper.Step.Compose` - Low-level step wrapper used for custom step compositions.
|
|
85
|
+
- `Stepper.Step.Icon` - Step circle content, including default index and completed state handling.
|
|
86
|
+
- `Stepper.Step.Label` - Step label rendered with body typography styling.
|
|
87
|
+
- `Stepper.Step.useStepContext` - Hook for reading the current step state and index inside custom step parts.
|
|
88
|
+
|
|
89
|
+
## Examples
|
|
90
|
+
|
|
91
|
+
### Playground
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
import { Stepper } from '@redislabsdev/redis-ui-components';
|
|
95
|
+
|
|
96
|
+
const storySteps = [
|
|
97
|
+
{ label: 'Create a subscription' },
|
|
98
|
+
{ label: 'Create a database' },
|
|
99
|
+
{ label: 'Connect & add keys' }
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
<Stepper currentStep={1} steps={storySteps} />
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Steps
|
|
106
|
+
|
|
107
|
+
> The same stepper with different `currentStep` prop.
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import { Stepper } from '@redislabsdev/redis-ui-components';
|
|
111
|
+
|
|
112
|
+
const storySteps = [
|
|
113
|
+
{ label: 'Create a subscription' },
|
|
114
|
+
{ label: 'Create a database' },
|
|
115
|
+
{ label: 'Connect & add keys' }
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
<>
|
|
119
|
+
<Stepper currentStep={-1} steps={storySteps} />
|
|
120
|
+
<Stepper currentStep={0} steps={storySteps} />
|
|
121
|
+
<Stepper currentStep={1} steps={storySteps} />
|
|
122
|
+
<Stepper currentStep={2} steps={storySteps} />
|
|
123
|
+
<Stepper currentStep={3} steps={storySteps} />
|
|
124
|
+
</>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Interactive
|
|
128
|
+
|
|
129
|
+
> `Stepper` can be interactive if `onStepChange` is defined. It allows only controlled mode.<br/>
|
|
130
|
+
> Use `ArrowLeft/Right`, `Home` and `End` keys for navigation or pointer click.
|
|
131
|
+
|
|
132
|
+
```tsx
|
|
133
|
+
import { useState } from 'react';
|
|
134
|
+
import { Stepper } from '@redislabsdev/redis-ui-components';
|
|
135
|
+
|
|
136
|
+
const storySteps = [
|
|
137
|
+
{ label: 'Create a subscription' },
|
|
138
|
+
{ label: 'Create a database' },
|
|
139
|
+
{ label: 'Connect & add keys' }
|
|
140
|
+
];
|
|
141
|
+
|
|
142
|
+
function Example() {
|
|
143
|
+
const [currentStep, setCurrentStep] = useState(1);
|
|
144
|
+
|
|
145
|
+
return <Stepper steps={storySteps} currentStep={currentStep} onStepChange={setCurrentStep} />;
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### ClickableStepLabels
|
|
150
|
+
|
|
151
|
+
> `Stepper.Step` can have any content.
|
|
152
|
+
|
|
153
|
+
```tsx
|
|
154
|
+
import { useState } from 'react';
|
|
155
|
+
import { Stepper } from '@redislabsdev/redis-ui-components';
|
|
156
|
+
import * as S from './StepperStory.style';
|
|
157
|
+
|
|
158
|
+
const storySteps = [
|
|
159
|
+
{ label: 'Create a subscription' },
|
|
160
|
+
{ label: 'Create a database' },
|
|
161
|
+
{ label: 'Connect & add keys' }
|
|
162
|
+
];
|
|
163
|
+
|
|
164
|
+
function Example() {
|
|
165
|
+
const [currentStep, setCurrentStep] = useState(1);
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<Stepper.Compose currentStep={currentStep} onStepChange={setCurrentStep}>
|
|
169
|
+
{storySteps.map(({ label: stepLabel }) => (
|
|
170
|
+
<Stepper.Step key={stepLabel}>
|
|
171
|
+
<S.AnchorLike>{stepLabel}</S.AnchorLike>
|
|
172
|
+
</Stepper.Step>
|
|
173
|
+
))}
|
|
174
|
+
</Stepper.Compose>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### StepCustomIcon
|
|
180
|
+
|
|
181
|
+
> To change custom content of the step circle, you need to compose `Step` and set necessary `Step.Icon` content.
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
import { useState } from 'react';
|
|
185
|
+
import { DatabaseIcon, LinkIcon, SubscriptionsIcon } from '@redislabsdev/redis-ui-icons';
|
|
186
|
+
import { Stepper } from '@redislabsdev/redis-ui-components';
|
|
187
|
+
|
|
188
|
+
const storySteps = [
|
|
189
|
+
{ label: 'Create a subscription' },
|
|
190
|
+
{ label: 'Create a database' },
|
|
191
|
+
{ label: 'Connect & add keys' }
|
|
192
|
+
];
|
|
193
|
+
|
|
194
|
+
function Example() {
|
|
195
|
+
const [currentStep, setCurrentStep] = useState(1);
|
|
196
|
+
|
|
197
|
+
return (
|
|
198
|
+
<>
|
|
199
|
+
<Stepper.Compose currentStep={currentStep} onStepChange={setCurrentStep}>
|
|
200
|
+
{storySteps.map(({ label: stepLabel }, index) => (
|
|
201
|
+
<Stepper.Step.Compose key={stepLabel}>
|
|
202
|
+
<Stepper.Step.Icon>{'ABC'[index]}</Stepper.Step.Icon>
|
|
203
|
+
<Stepper.Step.Label>{stepLabel}</Stepper.Step.Label>
|
|
204
|
+
</Stepper.Step.Compose>
|
|
205
|
+
))}
|
|
206
|
+
</Stepper.Compose>
|
|
207
|
+
|
|
208
|
+
<Stepper.Compose currentStep={currentStep} onStepChange={setCurrentStep}>
|
|
209
|
+
{storySteps.map(({ label: stepLabel }, index) => {
|
|
210
|
+
const StepIcon = [SubscriptionsIcon, DatabaseIcon, LinkIcon][index];
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<Stepper.Step.Compose key={stepLabel}>
|
|
214
|
+
<Stepper.Step.Icon>
|
|
215
|
+
<StepIcon customColor="currentColor" size="M" />
|
|
216
|
+
</Stepper.Step.Icon>
|
|
217
|
+
<Stepper.Step.Label>{stepLabel}</Stepper.Step.Label>
|
|
218
|
+
</Stepper.Step.Compose>
|
|
219
|
+
);
|
|
220
|
+
})}
|
|
221
|
+
</Stepper.Compose>
|
|
222
|
+
|
|
223
|
+
<Stepper
|
|
224
|
+
currentStep={currentStep}
|
|
225
|
+
onStepChange={setCurrentStep}
|
|
226
|
+
steps={[
|
|
227
|
+
{
|
|
228
|
+
label: storySteps[0].label
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
label: storySteps[1].label,
|
|
232
|
+
icon: <DatabaseIcon customColor="currentColor" size="M" />
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
label: storySteps[2].label,
|
|
236
|
+
icon: 'III'
|
|
237
|
+
},
|
|
238
|
+
{}
|
|
239
|
+
]}
|
|
240
|
+
/>
|
|
241
|
+
</>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### ComposingAndStyling
|
|
247
|
+
|
|
248
|
+
> The `Stepper` component contains `Step` items. Each `Step` has a `data-state` attribute with `\"completed\" | \"focused\" | \"idle\"`, which can be used for CSS selector styling.
|
|
249
|
+
>
|
|
250
|
+
> Each `Step` component has two parts, `Icon` and `Label`, and both share the same `data-state` attribute.
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
import { useState } from 'react';
|
|
254
|
+
import { Stepper } from '@redislabsdev/redis-ui-components';
|
|
255
|
+
import * as S from './StepperStory.style';
|
|
256
|
+
|
|
257
|
+
function Example() {
|
|
258
|
+
const [currentStep, setCurrentStep] = useState(1);
|
|
259
|
+
|
|
260
|
+
const steps = [
|
|
261
|
+
{ label: 'Item 1', icon: 'I' },
|
|
262
|
+
{ label: 'Item 2', icon: 'II' },
|
|
263
|
+
{ label: 'Item 3', icon: 'III' },
|
|
264
|
+
{ label: 'Item 4', icon: 'IV' },
|
|
265
|
+
{ label: 'Item 5', icon: 'V' }
|
|
266
|
+
];
|
|
267
|
+
|
|
268
|
+
return (
|
|
269
|
+
<S.StepperCompose currentStep={currentStep} onStepChange={setCurrentStep}>
|
|
270
|
+
{steps.map(({ label, icon }, index) => (
|
|
271
|
+
<S.StepperStepCompose key={index}>
|
|
272
|
+
<S.StepperStepLabel>{label}</S.StepperStepLabel>
|
|
273
|
+
<S.StepperStepIcon>{icon}</S.StepperStepIcon>
|
|
274
|
+
</S.StepperStepCompose>
|
|
275
|
+
))}
|
|
276
|
+
</S.StepperCompose>
|
|
277
|
+
);
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## Notes
|
|
282
|
+
|
|
283
|
+
- `Stepper` supports both data-driven steps via `steps` and custom step compositions via `Stepper.Compose`.
|
|
284
|
+
- `onStepChange` enables interactive controlled mode and keyboard navigation with `ArrowLeft/Right`, `Home`, and `End`.
|
|
285
|
+
- `Stepper.Step` can render any `ReactNode`, not just plain text labels.
|
|
286
|
+
- `Stepper.Step.Icon` falls back to the step number when no custom icon content is provided, and completed steps render a check icon.
|
|
287
|
+
- `Stepper.Step` and its parts expose `data-state` values of `idle`, `focused`, and `completed`, which are intended for custom styling.
|
|
288
|
+
- `StepperStepState` is the exported constant to target those states in styled wrappers and CSS selectors.
|