638 lines
16 KiB
Markdown
638 lines
16 KiB
Markdown
# Slider
|
|
|
|
An input where the user selects a value from within a given range.
|
|
|
|
## Import
|
|
|
|
```
|
|
Copyts
|
|
import { Slider } from "@kobalte/core/slider";
|
|
// or
|
|
import { Root, Track, ... } from "@kobalte/core/slider";
|
|
// or (deprecated)
|
|
import { Slider } from "@kobalte/core";
|
|
```
|
|
|
|
```
|
|
Copyts
|
|
import { Slider } from "@kobalte/core/slider";
|
|
// or
|
|
import { Root, Track, ... } from "@kobalte/core/slider";
|
|
// or (deprecated)
|
|
import { Slider } from "@kobalte/core";
|
|
```
|
|
|
|
## Features
|
|
|
|
- Follow the [WAI ARIA Slider](https://www.w3.org/WAI/ARIA/apg/patterns/slider-multithumb/) design pattern.
|
|
- Can be controlled or uncontrolled.
|
|
- Support for multiple thumbs.
|
|
- Support a minimum step between thumbs.
|
|
- Support click or touch on track to change value.
|
|
- Support right or left direction.
|
|
- Support for custom value label.
|
|
|
|
## Anatomy
|
|
|
|
The slider consists of:
|
|
|
|
- **Slider:** The root container for the slider.
|
|
- **Slider.Track:** The component that visually represents the slider track.
|
|
- **Slider.Fill:** The component that visually represents the slider value.
|
|
- **Slider.Thumb:** The thumb that is used to visually indicate a value in the slider.
|
|
- **Slider.Input:** The native html input that is visually hidden in the slider thumb.
|
|
- **Slider.Label:** The label that gives the user information on the slider.
|
|
- **Slider.ValueLabel:** The accessible label text representing the current value in a human-readable format.
|
|
- **Slider.Description**: The description that gives the user more information on the slider.
|
|
- **Slider.ErrorMessage**: The error message that gives the user information about how to fix a validation error on the slider.
|
|
|
|
```
|
|
Copytsx
|
|
<Slider>
|
|
<Slider.Label />
|
|
<Slider.ValueLabel />
|
|
<Slider.Track>
|
|
<Slider.Fill />
|
|
<Slider.Thumb>
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
<Slider.Description />
|
|
<Slider.ErrorMessage />
|
|
</Slider>
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
<Slider>
|
|
<Slider.Label />
|
|
<Slider.ValueLabel />
|
|
<Slider.Track>
|
|
<Slider.Fill />
|
|
<Slider.Thumb>
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
<Slider.Description />
|
|
<Slider.ErrorMessage />
|
|
</Slider>
|
|
```
|
|
|
|
## Example
|
|
|
|
Label
|
|
|
|
0
|
|
|
|
index.tsxstyle.css
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot">
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot">
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Multiple Thumbs
|
|
|
|
Label
|
|
|
|
0, 20
|
|
|
|
index.tsxstyle.css
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot" defaultValue={[0, 20]}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot" defaultValue={[0, 20]}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Modify step size
|
|
|
|
Step size 8
|
|
|
|
0
|
|
|
|
Step size 10
|
|
|
|
0
|
|
|
|
Step size 20
|
|
|
|
0
|
|
|
|
index.tsxstyle.css
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<>
|
|
<Slider class="SliderRoot" step={8}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Step size 8</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
<Slider class="SliderRoot" step={10}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Step size 10</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
<Slider class="SliderRoot" step={20}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Step size 20</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
</>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<>
|
|
<Slider class="SliderRoot" step={8}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Step size 8</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
<Slider class="SliderRoot" step={10}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Step size 10</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
<Slider class="SliderRoot" step={20}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Step size 20</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
</>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Steps between thumbs
|
|
|
|
Label
|
|
|
|
10, 20
|
|
|
|
index.tsxstyle.css
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot" defaultValue={[10, 20]} minStepsBetweenThumbs={10}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot" defaultValue={[10, 20]} minStepsBetweenThumbs={10}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Vertical Slider
|
|
|
|
Label
|
|
|
|
0
|
|
|
|
index.tsxstyle.css
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot" orientation="vertical">
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot" orientation="vertical">
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Custom Value Label
|
|
|
|
Money
|
|
|
|
$20 - $500
|
|
|
|
index.tsxstyle.css
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot"
|
|
minValue={10}
|
|
maxValue={2000}
|
|
defaultValue={[20, 500]}
|
|
getValueLabel={params => `$${params.values[0]} - $${params.values[1]}`}
|
|
>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Money</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
return (
|
|
<Slider class="SliderRoot"
|
|
minValue={10}
|
|
maxValue={2000}
|
|
defaultValue={[20, 500]}
|
|
getValueLabel={params => `$${params.values[0]} - $${params.values[1]}`}
|
|
>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Money</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
<Slider.Thumb class="SliderThumb SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
### Controlled Value
|
|
|
|
Label
|
|
|
|
40
|
|
|
|
index.tsxstyle.css
|
|
|
|
```
|
|
Copytsx
|
|
import { createSignal } from 'solid-js'
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
const [values, setValues] = createSignal<number[]>([40])
|
|
|
|
return (
|
|
<Slider class="SliderRoot" value={values()} onChange={setValues}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
```
|
|
Copytsx
|
|
import { createSignal } from 'solid-js'
|
|
import { Slider } from "@kobalte/core/slider";
|
|
import "./style.css";
|
|
|
|
function App() {
|
|
const [values, setValues] = createSignal<number[]>([40])
|
|
|
|
return (
|
|
<Slider class="SliderRoot" value={values()} onChange={setValues}>
|
|
<div class="SliderLabel">
|
|
<Slider.Label>Label</Slider.Label>
|
|
<Slider.ValueLabel />
|
|
</div>
|
|
<Slider.Track class="SliderTrack">
|
|
<Slider.Fill class="SliderRange" />
|
|
<Slider.Thumb class="SliderThumb">
|
|
<Slider.Input />
|
|
</Slider.Thumb>
|
|
</Slider.Track>
|
|
</Slider>
|
|
);
|
|
}
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Slider
|
|
|
|
`Slider` is equivalent to the `Root` import from `@kobalte/core/slider` (and deprecated `Slider.Root`).
|
|
|
|
| Prop | Description |
|
|
| --- | --- |
|
|
| value | `number[]`<br> The controlled values of the slider. Must be used in conjunction with `onChange`. |
|
|
| defaultValue | `number[]`<br> The value of the slider when initially rendered. Use when you do not need to control the state of the slider. |
|
|
| onChange | `(value: number[]) => void`<br> Event handler called when the value changes. |
|
|
| onChangeEnd | `(value: number[]) => void`<br> Event handler called when the value changes at the end of an interaction. |
|
|
| inverted | `boolean`<br> Whether the slider is visually inverted. Defaults to false. |
|
|
| minValue | `number`<br> The minimum slider value. Defaults to 0 |
|
|
| maxValue | `number`<br> The maximum slider value. Defaults to 100 |
|
|
| step | `number`<br> The stepping interval. Defaults to 1 |
|
|
| minStepsBetweenThumbs | `number`<br> The minimum permitted steps between thumbs. Defaults to 0 |
|
|
| getValueLabel | `(params: GetValueLabelParams) => string`<br> A function to get the accessible label text representing the current value in a human-readable format. If not provided, the value label will be read as a percentage of the max value. |
|
|
| orientation | `'horizontal' | 'vertical'`<br> The orientation of the slider. |
|
|
| name | `string`<br> The name of the slider, used when submitting an HTML form. |
|
|
| validationState | `'valid' | 'invalid'`<br> Whether the slider should display its "valid" or "invalid" visual styling. |
|
|
| required | `boolean`<br> Whether the user must check a radio group item before the owning form can be submitted. |
|
|
| disabled | `boolean`<br> Whether the radio group is disabled. |
|
|
| readOnly | `boolean`<br> Whether the radio group items can be selected but not changed by the user. |
|
|
|
|
| Data attribute | Description |
|
|
| --- | --- |
|
|
| data-orientation='horizontal' | Present when the slider has horizontal orientation. |
|
|
| data-orientation='vertical' | Present when the slider has vertical orientation. |
|
|
| data-valid | Present when the slider is valid according to the validation rules. |
|
|
| data-invalid | Present when the slider is invalid according to the validation rules. |
|
|
| data-required | Present when the user must slider an item before the owning form can be submitted. |
|
|
| data-disabled | Present when the slider is disabled. |
|
|
| data-readonly | Present when the slider is read only. |
|
|
|
|
`Slider.ValueLabel`, `Slider.Fill`, `Slider.Input`, `Slider.Thumb` and `Slider.Track` share the same data-attributes.
|
|
|
|
## Rendered elements
|
|
|
|
| Component | Default rendered element |
|
|
| --- | --- |
|
|
| `Slider` | `div` |
|
|
| `Slider.Track` | `div` |
|
|
| `Slider.Fill` | `div` |
|
|
| `Slider.Thumb` | `span` |
|
|
| `Slider.Input` | `input` |
|
|
| `Slider.ValueLabel` | `div` |
|
|
| `Slider.Description` | `div` |
|
|
| `Slider.ErrorMessage` | `div` |
|
|
|
|
## Accessibility
|
|
|
|
### Keyboard Interactions
|
|
|
|
| Key | Description |
|
|
| --- | --- |
|
|
| `PageUp` | Increases the value of the focused thumb by a larger `step`. |
|
|
| `PageDown` | Decreases the value of the focused thumb by a larger `step`. |
|
|
| `ArrowDown` | Decreases the value of the focused thumb by the `step` amount. |
|
|
| `ArrowUp` | Increases the value of the focused thumb by the `step` amount. |
|
|
| `ArrowRight` | Increments/decrements by the `step` value depending on `orientation`. |
|
|
| `ArrowLeft` | Increments/decrements by the `step` value depending on `orientation`. |
|
|
| `Home` | Sets the value of the first thumb to the minimum value. |
|
|
| `End` | Sets the value of the last thumb to the maximum value. |
|
|
|
|
Previous[←Skeleton](https://kobalte.dev/docs/core/components/skeleton)Next[Switch→](https://kobalte.dev/docs/core/components/switch) |