Slider
A control element that allows for a range of selections.
Anatomy
To set up the slider correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
Examples
Learn how to use the Slider
component in your project. Let's take a look at the most basic
example:
import { Slider } from '@ark-ui/react/slider'
export const Basic = () => {
return (
<Slider.Root>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
import { Slider } from '@ark-ui/solid/slider'
export const Basic = () => {
return (
<Slider.Root>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>
Range Slider
You can add multiple thumbs to the slider by adding multiple Slider.Thumb
import { Slider } from '@ark-ui/react/slider'
export const Range = () => {
return (
<Slider.Root defaultValue={[5, 10]}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
<Slider.Thumb index={1}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
import { Slider } from '@ark-ui/solid/slider'
export const Range = () => {
return (
<Slider.Root value={[5, 10]}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
<Slider.Thumb index={1}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root :defaultValue="[10, 20]">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
<Slider.Thumb :index="1">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>
Adding marks
You can add marks to the slider track by using the Slider.MarkerGroup
and Slider.Marker
components.
Position the Slider.Marker
components relative to the track by providing the value
prop.
import { Slider } from '@ark-ui/react/slider'
export const WithMarks = () => {
return (
<Slider.Root>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
<Slider.MarkerGroup>
<Slider.Marker value={0}>0</Slider.Marker>
<Slider.Marker value={25}>*</Slider.Marker>
<Slider.Marker value={50}>50</Slider.Marker>
<Slider.Marker value={75}>*</Slider.Marker>
</Slider.MarkerGroup>
</Slider.Root>
)
}
import { Slider } from '@ark-ui/solid/slider'
export const WithMarks = () => {
return (
<Slider.Root>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
<Slider.MarkerGroup>
<Slider.Marker value={0}>0</Slider.Marker>
<Slider.Marker value={25}>*</Slider.Marker>
<Slider.Marker value={50}>50</Slider.Marker>
<Slider.Marker value={75}>*</Slider.Marker>
</Slider.MarkerGroup>
</Slider.Root>
)
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
<Slider.MarkerGroup>
<Slider.Marker :value="0">0</Slider.Marker>
<Slider.Marker :value="25">*</Slider.Marker>
<Slider.Marker :value="50">50</Slider.Marker>
<Slider.Marker :value="75">*</Slider.Marker>
</Slider.MarkerGroup>
</Slider.Root>
</template>
Setting the initial value
To set the slider's initial value, set the defaultValue
prop to the array of numbers.
import { Slider } from '@ark-ui/react/slider'
export const InitialValue = () => (
<Slider.Root defaultValue={[42]}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
<Slider.MarkerGroup>
<Slider.Marker value={0}>*</Slider.Marker>
<Slider.Marker value={30}>*</Slider.Marker>
<Slider.Marker value={60}>*</Slider.Marker>
</Slider.MarkerGroup>
</Slider.Root>
)
import { Slider } from '@ark-ui/solid/slider'
export const InitialValue = () => (
<Slider.Root value={[42]}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
<Slider.MarkerGroup>
<Slider.Marker value={0}>*</Slider.Marker>
<Slider.Marker value={30}>*</Slider.Marker>
<Slider.Marker value={60}>*</Slider.Marker>
</Slider.MarkerGroup>
</Slider.Root>
)
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root :model-value="[42]">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
<Slider.MarkerGroup>
<Slider.Marker :value="0">*</Slider.Marker>
<Slider.Marker :value="30">*</Slider.Marker>
<Slider.Marker :value="60">*</Slider.Marker>
</Slider.MarkerGroup>
</Slider.Root>
</template>
Specifying the minimum and maximum
By default, the minimum is 0
and the maximum is 100
. If that's not what you want, you can easily
specify different bounds by changing the values of the min
and/or max
props.
For example, to ask the user for a value between -10
and 10
, you can use:
import { Slider } from '@ark-ui/react/slider'
export const MinMax = () => {
return (
<Slider.Root min={-10} max={10}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
import { Slider } from '@ark-ui/solid/slider'
export const MinMax = () => {
return (
<Slider.Root min={-10} max={10}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root :min="-10" :max="10">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>
Setting the value's granularity
By default, the granularity, is 1
, meaning that the value is always an integer. You can change the
step attribute to control the granularity.
For example, If you need a value between 5
and 10
, accurate to two decimal places, you should
set the value of step to 0.01
:
import { Slider } from '@ark-ui/react/slider'
export const Step = () => {
return (
<Slider.Root step={0.01} min={5} max={10}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
import { Slider } from '@ark-ui/solid/slider'
export const Step = () => {
return (
<Slider.Root step={0.01} min={5} max={10}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root :step="0.01" :min="5" :max="10">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>
Listening for changes
When the slider value changes, the onValueChange
and onValueChangeEnd
callbacks are invoked. You
can use this to set up custom behaviors in your app.
import { Slider } from '@ark-ui/react/slider'
export const OnEvent = () => {
return (
<Slider.Root
onValueChange={(details) => console.log(details.value)}
onValueChangeEnd={(details) => console.log(details.value)}
>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
import { Slider } from '@ark-ui/solid/slider'
export const OnEvent = () => {
return (
<Slider.Root
onValueChange={(details) => console.log(details.value)}
onValueChangeEnd={(details) => console.log(details.value)}
>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root
@value-change="(details) => console.log(details.value)"
@value-change-end="(details) => console.log(details.value)"
>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>
Changing the orientation
By default, the slider is assumed to be horizontal. To change the orientation to vertical, set the orientation property in the machine's context to vertical.
In this mode, the slider will use the arrow up and down keys to increment/decrement its value.
Don't forget to change the styles of the vertical slider by specifying its height
import { Slider } from '@ark-ui/react/slider'
export const Vertical = () => {
return (
<Slider.Root orientation="vertical">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
import { Slider } from '@ark-ui/solid/slider'
export const Vertical = () => {
return (
<Slider.Root orientation="vertical">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root orientation="vertical">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>
Changing the origin
By default, the slider's origin is at the start of the track. To change the origin to the center of
the track, set the origin
prop to center
.
import { Slider } from '@ark-ui/react/slider'
export const CenterOrigin = () => {
return (
<Slider.Root origin="center">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
import { Slider } from '@ark-ui/solid/slider'
export const CenterOrigin = () => {
return (
<Slider.Root origin="center">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
)
}
<script setup lang="ts">
import { Slider } from '@ark-ui/vue/slider'
</script>
<template>
<Slider.Root origin="center">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.Root>
</template>
Using the Root Provider
The RootProvider
component provides a context for the slider. It accepts the value of the useSlider
hook.
You can leverage it to access the component state and methods from outside the slider.
import { Slider, useSlider } from '@ark-ui/react/slider'
export const RootProvider = () => {
const slider = useSlider()
return (
<>
<button onClick={() => slider.focus()}>Focus</button>
<Slider.RootProvider value={slider}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.RootProvider>
</>
)
}
import { Slider, useSlider } from '@ark-ui/solid/slider'
export const RootProvider = () => {
const slider = useSlider()
return (
<>
<button onClick={() => slider().focus()}>Focus</button>
<Slider.RootProvider value={slider}>
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb index={0}>
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.RootProvider>
</>
)
}
<script setup lang="ts">
import { Slider, useSlider } from '@ark-ui/vue/slider'
const slider = useSlider()
</script>
<template>
<button @click="slider.focus()">Focus</button>
<Slider.RootProvider :value="slider">
<Slider.Label>Label</Slider.Label>
<Slider.ValueText />
<Slider.Control>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb :index="0">
<Slider.HiddenInput />
</Slider.Thumb>
</Slider.Control>
</Slider.RootProvider>
</template>
If you're using the
RootProvider
component, you don't need to use theRoot
component.
API Reference
Accessibility
Complies with the Slider WAI-ARIA design pattern.
Keyboard Support
Key | Description |
---|---|
ArrowRight | Increments the slider based on defined step |
ArrowLeft | Decrements the slider based on defined step |
ArrowUp | Increases the value by the step amount. |
ArrowDown | Decreases the value by the step amount. |
PageUp | Increases the value by a larger step |
PageDown | Decreases the value by a larger step |
Shift + ArrowUp | Increases the value by a larger step |
Shift + ArrowDown | Decreases the value by a larger step |
Home | Sets the value to its minimum. |
End | Sets the value to its maximum. |