16 KiB
16 KiB
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 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[]The controlled values of the slider. Must be used in conjunction with onChange. |
| defaultValue | number[]The value of the slider when initially rendered. Use when you do not need to control the state of the slider. |
| onChange | (value: number[]) => voidEvent handler called when the value changes. |
| onChangeEnd | (value: number[]) => voidEvent handler called when the value changes at the end of an interaction. |
| inverted | booleanWhether the slider is visually inverted. Defaults to false. |
| minValue | numberThe minimum slider value. Defaults to 0 |
| maxValue | numberThe maximum slider value. Defaults to 100 |
| step | numberThe stepping interval. Defaults to 1 |
| minStepsBetweenThumbs | numberThe minimum permitted steps between thumbs. Defaults to 0 |
| getValueLabel | (params: GetValueLabelParams) => stringA 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' |
| name | stringThe name of the slider, used when submitting an HTML form. |
| validationState | `'valid' |
| required | booleanWhether the user must check a radio group item before the owning form can be submitted. |
| disabled | booleanWhether the radio group is disabled. |
| readOnly | booleanWhether 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. |