Slider
An accessible range input that supports single and multi-thumb configurations, keyboard navigation, RTL, and form integration.
import * as Slider from '@gentleduck/primitives/slider'import * as Slider from '@gentleduck/primitives/slider'Anatomy
<Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root><Slider.Root>
<Slider.Track>
<Slider.Range />
</Slider.Track>
<Slider.Thumb />
</Slider.Root>Example
import * as Slider from '@gentleduck/primitives/slider'
function VolumeSlider() {
return (
<Slider.Root defaultValue={[50]} max={100} step={1} className="relative flex w-64 items-center">
<Slider.Track className="relative h-1 w-full grow rounded-full bg-gray-200">
<Slider.Range className="absolute h-full rounded-full bg-blue-500" />
</Slider.Track>
<Slider.Thumb className="block size-4 rounded-full border bg-white shadow" />
</Slider.Root>
)
}import * as Slider from '@gentleduck/primitives/slider'
function VolumeSlider() {
return (
<Slider.Root defaultValue={[50]} max={100} step={1} className="relative flex w-64 items-center">
<Slider.Track className="relative h-1 w-full grow rounded-full bg-gray-200">
<Slider.Range className="absolute h-full rounded-full bg-blue-500" />
</Slider.Track>
<Slider.Thumb className="block size-4 rounded-full border bg-white shadow" />
</Slider.Root>
)
}Range slider (multiple thumbs)
function PriceRange() {
return (
<Slider.Root defaultValue={[20, 80]} max={100} step={5} className="relative flex w-64 items-center">
<Slider.Track className="relative h-1 w-full grow rounded-full bg-gray-200">
<Slider.Range className="absolute h-full rounded-full bg-blue-500" />
</Slider.Track>
<Slider.Thumb className="block size-4 rounded-full border bg-white shadow" />
<Slider.Thumb className="block size-4 rounded-full border bg-white shadow" />
</Slider.Root>
)
}function PriceRange() {
return (
<Slider.Root defaultValue={[20, 80]} max={100} step={5} className="relative flex w-64 items-center">
<Slider.Track className="relative h-1 w-full grow rounded-full bg-gray-200">
<Slider.Range className="absolute h-full rounded-full bg-blue-500" />
</Slider.Track>
<Slider.Thumb className="block size-4 rounded-full border bg-white shadow" />
<Slider.Thumb className="block size-4 rounded-full border bg-white shadow" />
</Slider.Root>
)
}API
Slider.Root
The root component that manages slider state, drag interactions, keyboard stepping, and provides context to all children. Renders a <span>.
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | -- | Name for hidden form inputs |
disabled | boolean | false | Disables the slider |
orientation | 'horizontal' | 'vertical' | 'horizontal' | Slider orientation |
dir | 'ltr' | 'rtl' | -- | Text direction (horizontal only). Resolved with useDirection (dir prop -> DirectionProvider -> 'ltr'). |
min | number | 0 | Minimum allowed value |
max | number | 100 | Maximum allowed value |
step | number | 1 | Increment step for values |
value | number[] | -- | Controlled values array |
defaultValue | number[] | [min] | Uncontrolled initial values |
onValueChange | (value: number[]) => void | -- | Called on every value change during interaction |
onValueCommit | (value: number[]) => void | -- | Called when the user finishes an interaction (pointer up or key commit) |
inverted | boolean | false | Inverts the slider direction |
minStepsBetweenThumbs | number | 0 | Minimum number of steps required between thumbs |
form | string | -- | Associates hidden inputs with a form element by ID |
Exposes data-disabled and data-orientation attributes. Sets the CSS custom property --gentleduck-slider-thumb-transform for thumb positioning.
Slider.Track
The track area the thumbs slide along. Renders a <span>.
| Prop | Type | Description |
|---|---|---|
asChild | boolean | Render as child element |
Exposes data-disabled and data-orientation attributes.
Slider.Range
The filled portion between thumbs (or from min to a single thumb). Renders a <span>. Positioned automatically via inline styles.
| Prop | Type | Description |
|---|---|---|
asChild | boolean | Render as child element |
Exposes data-disabled and data-orientation attributes.
Slider.Thumb
A draggable thumb. The thumb index is auto-detected from render order — you do not need to pass an index prop. Renders a <span> with role="slider". Each thumb also renders a hidden <input> for form submission.
| Prop | Type | Default | Description |
|---|---|---|---|
name | string | -- | Optional name override for this thumb's hidden input |
asChild | boolean | -- | Render as child element |
Sets aria-valuemin, aria-valuenow, aria-valuemax, and aria-orientation automatically. Exposes data-disabled and data-orientation attributes.
Keyboard interactions
| Key | Action |
|---|---|
| ArrowRight | Increments by one step (horizontal LTR) |
| ArrowLeft | Decrements by one step (horizontal LTR) |
| ArrowUp | Increments by one step (vertical) |
| ArrowDown | Decrements by one step (vertical) |
| PageUp | Increments by ten steps |
| PageDown | Decrements by ten steps |
| Shift + ArrowKey | Increments/decrements by ten steps |
| Home | Sets the focused thumb to the minimum value |
| End | Sets the focused thumb to the maximum value |