Skip to main content

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>.

PropTypeDefaultDescription
namestring--Name for hidden form inputs
disabledbooleanfalseDisables the slider
orientation'horizontal' | 'vertical''horizontal'Slider orientation
dir'ltr' | 'rtl'--Text direction (horizontal only). Resolved with useDirection (dir prop -> DirectionProvider -> 'ltr').
minnumber0Minimum allowed value
maxnumber100Maximum allowed value
stepnumber1Increment step for values
valuenumber[]--Controlled values array
defaultValuenumber[][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)
invertedbooleanfalseInverts the slider direction
minStepsBetweenThumbsnumber0Minimum number of steps required between thumbs
formstring--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>.

PropTypeDescription
asChildbooleanRender 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.

PropTypeDescription
asChildbooleanRender 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.

PropTypeDefaultDescription
namestring--Optional name override for this thumb's hidden input
asChildboolean--Render as child element

Sets aria-valuemin, aria-valuenow, aria-valuemax, and aria-orientation automatically. Exposes data-disabled and data-orientation attributes.


Keyboard interactions

KeyAction
ArrowRightIncrements by one step (horizontal LTR)
ArrowLeftDecrements by one step (horizontal LTR)
ArrowUpIncrements by one step (vertical)
ArrowDownDecrements by one step (vertical)
PageUpIncrements by ten steps
PageDownDecrements by ten steps
Shift + ArrowKeyIncrements/decrements by ten steps
HomeSets the focused thumb to the minimum value
EndSets the focused thumb to the maximum value