1
ComponentsForm Controls

Slider

Single-value and range selection across a continuous or stepped visual scale.

Purpose

Use Slider for choosing one or more values from a continuous or stepped visual range.

Controlled slider

Storage64%
"use client";

import { useState } from "react";
import { Slider, SliderValue } from "@/components/ui/slider";

export function Example() {
  const [value, setValue] = useState(64);
  return (
    <Slider
      value={value}
      onValueChange={(next) =>
        setValue(Array.isArray(next) ? (next[0] ?? 0) : next)
      }
    >
      <div className="mb-2 flex items-center justify-between">
        <span>Storage</span>
        <SliderValue />
      </div>
    </Slider>
  );
}

Installation

With the Siteplane registry alias configured, add the component and import the installed source from your app.

CLI

pnpm dlx shadcn@4.16.1 add @siteplane/slider

Import

import { Slider, SliderValue } from "@/components/ui/slider";
import { Field, FieldLabel } from "@/components/ui/field";

Need the machine-readable source metadata? View registry JSON.

Usage

Slider adjusts a bounded numeric value. Pair it with a visible label or value when precision matters.

"use client";

import { useState } from "react";
import { Slider, SliderValue } from "@/components/ui/slider";

export function Example() {
  const [value, setValue] = useState(64);
  return (
    <Slider
      value={value}
      onValueChange={(next) =>
        setValue(Array.isArray(next) ? (next[0] ?? 0) : next)
      }
    >
      <div className="mb-2 flex items-center justify-between">
        <span>Storage</span>
        <SliderValue />
      </div>
    </Slider>
  );
}

Examples

Labels, range thumbs, sizes, orientation, steps, states and form integration are props and compositions of the same primitive.

Label and value

50
<Field>
  <Slider defaultValue={50}>
    <div className="mb-2 flex items-center justify-between gap-1">
      <FieldLabel className="font-medium text-sm">Opacity</FieldLabel>
      <SliderValue />
    </div>
  </Slider>
</Field>

Range

An array value renders one thumb per entry; minStepsBetweenValues keeps them apart.

Budget range24 - 72
<Slider
  aria-label="Budget range"
  defaultValue={[24, 72]}
  minStepsBetweenValues={4}
>
  <div className="mb-2 flex items-center justify-between gap-2">
    <span className="font-medium text-sm">Budget range</span>
    <SliderValue>
      {(_formatted, values) => `${values[0] ?? 0} - ${values[1] ?? 0}`}
    </SliderValue>
  </div>
</Slider>

Sizes

<Slider aria-label="Small slider" defaultValue={50} size="sm" />
<Slider aria-label="Default slider" defaultValue={50} />
<Slider aria-label="Large slider" defaultValue={50} size="lg" />
<Slider aria-label="Extra large slider" defaultValue={50} size="xl" />

Vertical

35 GB20 GB5 GB
<Slider
  aria-label="Storage size in GB"
  className="h-44"
  defaultValue={15}
  max={35}
  min={5}
  orientation="vertical"
/>

Stepped

Step value40
const [value, setValue] = useState(40);

<Slider
  aria-label="Step value"
  max={100}
  min={0}
  onValueChange={(next) =>
    setValue(Array.isArray(next) ? (next[0] ?? 0) : next)
  }
  step={10}
  value={value}
>
  <div className="mb-2 flex items-center justify-between gap-2">
    <span className="font-medium text-sm">Step value</span>
    <SliderValue />
  </div>
</Slider>

Disabled

<Slider aria-label="Disabled slider" defaultValue={50} disabled />

Form integration

5
0123456789101112

Value scale from 0 to 12

Value: not submitted
<Form onSubmit={onSubmit}>
  <Field name="value">
    <Slider
      aria-label="Value selector"
      max={12}
      name="value"
      onValueChange={(next) =>
        setValue(Array.isArray(next) ? (next[0] ?? 0) : next)
      }
      value={value}
    >
      <div className="mb-2 flex items-center justify-between gap-2">
        <FieldLabel className="font-medium text-sm">Scale value</FieldLabel>
        <SliderValue />
      </div>
    </Slider>
    <FieldDescription>Value scale from 0 to 12</FieldDescription>
  </Field>
  <Button loading={loading} type="submit">Submit</Button>
</Form>

API Reference

The reference lists the source-owned exports and props that are easy to miss in visual examples. Inherited Base UI props remain available unless the wrapper narrows them.

  • Slider accepts controlled or uncontrolled values, min, max, step, orientation, disabled and size="sm" | "default" | "lg" | "xl" through the Base UI root contract.
  • thumbCollisionBehavior="push" | "swap" | "none" controls how thumbs behave when a range selection reaches another thumb.
  • SliderValue displays the current value and accepts its own size override; otherwise it inherits the root or provider size.
  • A value array renders one thumb per value; keep value order and labels meaningful for range sliders.

Motion

Component motion uses the shared Siteplane motion contract. See the global motion guide for provider setup, tokens and reduced-motion behavior.

  • Track fill and thumb feedback use shared Siteplane transition tokens. Dragging disables delayed interpolation so the control follows the pointer directly.
  • The operating-system reduced-motion preference removes thumb and track transitions. The forced reducedMotionPreset shortens their shared slow duration from 320ms to 100ms without changing drag or keyboard behavior.

Accessibility

  • Provide an accessible label for every slider and distinct labels for multiple thumbs.
  • Keep keyboard increments, orientation and value limits aligned with the visible range.
  • Expose understandable value text when raw numbers do not describe the unit or meaning.

Implementation Guidance

  • Use Number Field when exact typed entry is primary, Meter for read-only measurement and Progress for task completion.
  • Choose thumbCollisionBehavior deliberately for multi-thumb sliders instead of assuming every range should push.
  • Do not rebuild track, indicator or thumbs from raw elements.

On This Page