@xsolla/xui-slider 0.148.0 → 0.148.2
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 +348 -0
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# Slider
|
|
2
|
+
|
|
3
|
+
A cross-platform React slider component for selecting values within a range. Supports single value, range mode with two thumbs, and optional input fields for direct value entry.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @xsolla/xui-slider
|
|
9
|
+
# or
|
|
10
|
+
yarn add @xsolla/xui-slider
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Demo
|
|
14
|
+
|
|
15
|
+
### Basic Slider
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import * as React from 'react';
|
|
19
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
20
|
+
|
|
21
|
+
export default function BasicSlider() {
|
|
22
|
+
const [value, setValue] = React.useState(50);
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Slider
|
|
26
|
+
value={value}
|
|
27
|
+
onChange={setValue}
|
|
28
|
+
min={0}
|
|
29
|
+
max={100}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Slider with Label
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import * as React from 'react';
|
|
39
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
40
|
+
|
|
41
|
+
export default function SliderWithLabel() {
|
|
42
|
+
const [volume, setVolume] = React.useState(75);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<Slider
|
|
46
|
+
value={volume}
|
|
47
|
+
onChange={setVolume}
|
|
48
|
+
min={0}
|
|
49
|
+
max={100}
|
|
50
|
+
label={`Volume: ${volume}%`}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Range Slider
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import * as React from 'react';
|
|
60
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
61
|
+
|
|
62
|
+
export default function RangeSlider() {
|
|
63
|
+
const [minPrice, setMinPrice] = React.useState(20);
|
|
64
|
+
const [maxPrice, setMaxPrice] = React.useState(80);
|
|
65
|
+
|
|
66
|
+
return (
|
|
67
|
+
<Slider
|
|
68
|
+
range
|
|
69
|
+
minValue={minPrice}
|
|
70
|
+
maxValue={maxPrice}
|
|
71
|
+
onRangeChange={(min, max) => {
|
|
72
|
+
setMinPrice(min);
|
|
73
|
+
setMaxPrice(max);
|
|
74
|
+
}}
|
|
75
|
+
min={0}
|
|
76
|
+
max={100}
|
|
77
|
+
label="Price Range"
|
|
78
|
+
minThumbAriaLabel="Minimum price"
|
|
79
|
+
maxThumbAriaLabel="Maximum price"
|
|
80
|
+
/>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Slider with Input Fields
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import * as React from 'react';
|
|
89
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
90
|
+
|
|
91
|
+
export default function SliderWithInputs() {
|
|
92
|
+
const [value, setValue] = React.useState(50);
|
|
93
|
+
|
|
94
|
+
return (
|
|
95
|
+
<Slider
|
|
96
|
+
value={value}
|
|
97
|
+
onChange={setValue}
|
|
98
|
+
min={0}
|
|
99
|
+
max={100}
|
|
100
|
+
inputPosition="right"
|
|
101
|
+
label="Brightness"
|
|
102
|
+
/>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Range Slider with Both Inputs
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
import * as React from 'react';
|
|
111
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
112
|
+
|
|
113
|
+
export default function RangeSliderWithInputs() {
|
|
114
|
+
const [min, setMin] = React.useState(1000);
|
|
115
|
+
const [max, setMax] = React.useState(5000);
|
|
116
|
+
|
|
117
|
+
return (
|
|
118
|
+
<Slider
|
|
119
|
+
range
|
|
120
|
+
minValue={min}
|
|
121
|
+
maxValue={max}
|
|
122
|
+
onRangeChange={(minVal, maxVal) => {
|
|
123
|
+
setMin(minVal);
|
|
124
|
+
setMax(maxVal);
|
|
125
|
+
}}
|
|
126
|
+
min={0}
|
|
127
|
+
max={10000}
|
|
128
|
+
step={100}
|
|
129
|
+
inputPosition="both"
|
|
130
|
+
label="Budget Range"
|
|
131
|
+
minThumbAriaLabel="Minimum budget"
|
|
132
|
+
maxThumbAriaLabel="Maximum budget"
|
|
133
|
+
/>
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Anatomy
|
|
139
|
+
|
|
140
|
+
Import the component and use it directly:
|
|
141
|
+
|
|
142
|
+
```jsx
|
|
143
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
144
|
+
|
|
145
|
+
// Single value slider
|
|
146
|
+
<Slider
|
|
147
|
+
value={value} // Current value
|
|
148
|
+
onChange={handleChange} // Value change handler
|
|
149
|
+
min={0} // Minimum bound
|
|
150
|
+
max={100} // Maximum bound
|
|
151
|
+
step={1} // Step increment
|
|
152
|
+
label="Label" // Label above slider
|
|
153
|
+
inputPosition="none" // Input field position
|
|
154
|
+
showLabels={false} // Show min/max labels
|
|
155
|
+
disabled={false} // Disabled state
|
|
156
|
+
activeColor="brand" // Color scheme
|
|
157
|
+
/>
|
|
158
|
+
|
|
159
|
+
// Range slider
|
|
160
|
+
<Slider
|
|
161
|
+
range // Enable range mode
|
|
162
|
+
minValue={minVal} // Minimum selected value
|
|
163
|
+
maxValue={maxVal} // Maximum selected value
|
|
164
|
+
onRangeChange={handleRange} // Range change handler
|
|
165
|
+
min={0}
|
|
166
|
+
max={100}
|
|
167
|
+
/>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Examples
|
|
171
|
+
|
|
172
|
+
### Slider Sizes
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
import * as React from 'react';
|
|
176
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
177
|
+
|
|
178
|
+
export default function SliderSizes() {
|
|
179
|
+
return (
|
|
180
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
|
|
181
|
+
<Slider value={50} size="sm" label="Small" />
|
|
182
|
+
<Slider value={50} size="md" label="Medium (default)" />
|
|
183
|
+
<Slider value={50} size="lg" label="Large" />
|
|
184
|
+
<Slider value={50} size="xl" label="Extra Large" />
|
|
185
|
+
</div>
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Color Schemes
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import * as React from 'react';
|
|
194
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
195
|
+
|
|
196
|
+
export default function SliderColors() {
|
|
197
|
+
return (
|
|
198
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>
|
|
199
|
+
<Slider value={60} activeColor="brand" label="Brand" />
|
|
200
|
+
<Slider value={60} activeColor="brandExtra" label="Brand Extra" />
|
|
201
|
+
<Slider value={60} activeColor="success" label="Success" />
|
|
202
|
+
<Slider value={60} activeColor="warning" label="Warning" />
|
|
203
|
+
<Slider value={60} activeColor="alert" label="Alert" />
|
|
204
|
+
<Slider value={60} activeColor="neutral" label="Neutral" />
|
|
205
|
+
</div>
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Slider with Icons
|
|
211
|
+
|
|
212
|
+
```tsx
|
|
213
|
+
import * as React from 'react';
|
|
214
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
215
|
+
import { Volume1, Volume2 } from '@xsolla/xui-icons-base';
|
|
216
|
+
|
|
217
|
+
export default function SliderWithIcons() {
|
|
218
|
+
const [value, setValue] = React.useState(50);
|
|
219
|
+
|
|
220
|
+
return (
|
|
221
|
+
<Slider
|
|
222
|
+
value={value}
|
|
223
|
+
onChange={setValue}
|
|
224
|
+
min={0}
|
|
225
|
+
max={100}
|
|
226
|
+
iconLeft={<Volume1 />}
|
|
227
|
+
iconRight={<Volume2 />}
|
|
228
|
+
/>
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Step Slider
|
|
234
|
+
|
|
235
|
+
```tsx
|
|
236
|
+
import * as React from 'react';
|
|
237
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
238
|
+
|
|
239
|
+
export default function StepSlider() {
|
|
240
|
+
const [value, setValue] = React.useState(50);
|
|
241
|
+
|
|
242
|
+
return (
|
|
243
|
+
<Slider
|
|
244
|
+
value={value}
|
|
245
|
+
onChange={setValue}
|
|
246
|
+
min={0}
|
|
247
|
+
max={100}
|
|
248
|
+
step={10}
|
|
249
|
+
showLabels
|
|
250
|
+
label={`Value: ${value}`}
|
|
251
|
+
/>
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Disabled Slider
|
|
257
|
+
|
|
258
|
+
```tsx
|
|
259
|
+
import * as React from 'react';
|
|
260
|
+
import { Slider } from '@xsolla/xui-slider';
|
|
261
|
+
|
|
262
|
+
export default function DisabledSlider() {
|
|
263
|
+
return (
|
|
264
|
+
<Slider
|
|
265
|
+
value={50}
|
|
266
|
+
min={0}
|
|
267
|
+
max={100}
|
|
268
|
+
disabled
|
|
269
|
+
label="Disabled slider"
|
|
270
|
+
/>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## API Reference
|
|
276
|
+
|
|
277
|
+
### Slider
|
|
278
|
+
|
|
279
|
+
A slider component for value selection.
|
|
280
|
+
|
|
281
|
+
**Slider Props:**
|
|
282
|
+
|
|
283
|
+
| Prop | Type | Default | Description |
|
|
284
|
+
| :--- | :--- | :------ | :---------- |
|
|
285
|
+
| value | `number` | `0` | Current value (single slider mode). |
|
|
286
|
+
| minValue | `number` | - | Minimum value (range mode). |
|
|
287
|
+
| maxValue | `number` | - | Maximum value (range mode). |
|
|
288
|
+
| min | `number` | `0` | Minimum bound of the slider. |
|
|
289
|
+
| max | `number` | `100` | Maximum bound of the slider. |
|
|
290
|
+
| step | `number` | `1` | Step increment for value changes. |
|
|
291
|
+
| onChange | `(value: number) => void` | - | Callback for single value changes. |
|
|
292
|
+
| onRangeChange | `(min: number, max: number) => void` | - | Callback for range value changes. |
|
|
293
|
+
| size | `"sm" \| "md" \| "lg" \| "xl"` | `"md"` | Size of the slider. |
|
|
294
|
+
| disabled | `boolean` | `false` | Whether the slider is disabled. |
|
|
295
|
+
| range | `boolean` | `false` | Enable range mode with two thumbs. |
|
|
296
|
+
| inputPosition | `"left" \| "right" \| "both" \| "none"` | `"none"` | Position of input field(s). |
|
|
297
|
+
| showLabels | `boolean` | `false` | Show min/max labels. |
|
|
298
|
+
| label | `string` | - | Label displayed above the slider. |
|
|
299
|
+
| activeColor | `"brand" \| "brandExtra" \| "success" \| "warning" \| "alert" \| "neutral"` | `"brand"` | Color scheme for the active track. |
|
|
300
|
+
| iconLeft | `ReactNode` | - | Icon on the left side. |
|
|
301
|
+
| iconRight | `ReactNode` | - | Icon on the right side. |
|
|
302
|
+
| iconInside | `ReactNode` | - | Icon inside input field. |
|
|
303
|
+
| iconInsidePosition | `"left" \| "right"` | - | Position of icon inside input. |
|
|
304
|
+
| aria-label | `string` | - | Accessible label. |
|
|
305
|
+
| minThumbAriaLabel | `string` | `"Minimum value"` | Label for min thumb in range mode. |
|
|
306
|
+
| maxThumbAriaLabel | `string` | `"Maximum value"` | Label for max thumb in range mode. |
|
|
307
|
+
| testID | `string` | - | Test identifier. |
|
|
308
|
+
|
|
309
|
+
**Size Configuration:**
|
|
310
|
+
|
|
311
|
+
| Size | Height | Track Height | Thumb Size | Input Width |
|
|
312
|
+
| :--- | :----- | :----------- | :--------- | :---------- |
|
|
313
|
+
| sm | 32px | 4px | 14px | 48px |
|
|
314
|
+
| md | 40px | 6px | 16px | 56px |
|
|
315
|
+
| lg | 48px | 6px | 18px | 64px |
|
|
316
|
+
| xl | 56px | 8px | 20px | 72px |
|
|
317
|
+
|
|
318
|
+
## Keyboard Navigation
|
|
319
|
+
|
|
320
|
+
| Key | Action |
|
|
321
|
+
| :-- | :----- |
|
|
322
|
+
| Arrow Right/Up | Increase value by step |
|
|
323
|
+
| Arrow Left/Down | Decrease value by step |
|
|
324
|
+
| Shift + Arrow | Increase/decrease by 10x step |
|
|
325
|
+
| Home | Jump to minimum value |
|
|
326
|
+
| End | Jump to maximum value |
|
|
327
|
+
|
|
328
|
+
## Theming
|
|
329
|
+
|
|
330
|
+
Slider uses the design system theme for colors:
|
|
331
|
+
|
|
332
|
+
```typescript
|
|
333
|
+
// Colors accessed via theme
|
|
334
|
+
theme.colors.control.slider.track // Inactive track
|
|
335
|
+
theme.colors.control.slider.trackActive // Active track (uses activeColor)
|
|
336
|
+
theme.colors.control.slider.thumb // Thumb color
|
|
337
|
+
theme.colors.control.slider.thumbBorder // Thumb border
|
|
338
|
+
theme.colors.content.primary // Label text
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Accessibility
|
|
342
|
+
|
|
343
|
+
- Uses `role="slider"` semantic role
|
|
344
|
+
- `aria-valuenow`, `aria-valuemin`, `aria-valuemax` for current state
|
|
345
|
+
- Full keyboard navigation support
|
|
346
|
+
- Focus indicator follows WCAG guidelines
|
|
347
|
+
- Range mode has separate labels for min/max thumbs
|
|
348
|
+
- Disabled state properly announced
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-slider",
|
|
3
|
-
"version": "0.148.
|
|
3
|
+
"version": "0.148.2",
|
|
4
4
|
"main": "./web/index.js",
|
|
5
5
|
"module": "./web/index.mjs",
|
|
6
6
|
"types": "./web/index.d.ts",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"test:coverage": "vitest run --coverage"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@xsolla/xui-core": "0.148.
|
|
17
|
-
"@xsolla/xui-input": "0.148.
|
|
18
|
-
"@xsolla/xui-primitives-core": "0.148.
|
|
16
|
+
"@xsolla/xui-core": "0.148.2",
|
|
17
|
+
"@xsolla/xui-input": "0.148.2",
|
|
18
|
+
"@xsolla/xui-primitives-core": "0.148.2"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"react": ">=16.8.0",
|