Slider
A control for selecting a value or range from within a given range.
Installation
$
Usage
import { Slider } from "@/components/ui/slider"Examples
Default
Range
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultValue | number[] | - | Initial value when uncontrolled. One thumb renders per entry, so [25, 75] creates a range slider. |
| value | number[] | - | Controlled value. Use with onValueChange. |
| onValueChange | (value: number[]) => void | - | Called with the new value as a thumb is dragged. |
| onValueCommit | (value: number[]) => void | - | Called once the user finishes an interaction, useful for skipping updates on every tick of a drag. |
| min | number | 0 | The minimum value of the range. |
| max | number | 100 | The maximum value of the range. |
| step | number | 1 | The granularity each thumb snaps to. |
| minStepsBetweenThumbs | number | 0 | Minimum gap (in steps) enforced between thumbs in a range slider. |
| orientation | "horizontal" | "vertical" | "horizontal" | Layout direction. Vertical sliders get an 11rem minimum height. |
| inverted | boolean | false | Reverses the slider's direction so the range fills from the opposite end. |
| disabled | boolean | false | Disables interaction and dims the slider. |
| name | string | - | Name submitted with its owning form, via a hidden input per thumb. |
"use client"
import * as React from "react"
import { Slider as SliderPrimitive } from "@base-ui/react/slider"
import { cn } from "@/registry/lib/utils"
function Slider({
className,
defaultValue,
value,
min = 0,
max = 100,
...props
}: React.ComponentProps<typeof SliderPrimitive.Root>) {
const _values = React.useMemo(
() =>
Array.isArray(value)
? value
: Array.isArray(defaultValue)
? defaultValue
: [min, max],
[value, defaultValue, min, max]
)
return (
<SliderPrimitive.Root
data-slot="slider"
defaultValue={defaultValue}
value={value}
min={min}
max={max}
className={cn(
"relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col",
className
)}
{...props}
>
<SliderPrimitive.Control
data-slot="slider-control"
className={cn(
"relative flex w-full grow items-center data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col"
)}
>
<SliderPrimitive.Track
data-slot="slider-track"
className={cn(
"bg-neutral-200 dark:bg-neutral-800 relative grow rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
)}
>
<SliderPrimitive.Indicator
data-slot="slider-range"
className={cn(
"bg-accent absolute rounded-full data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
)}
/>
{Array.from({ length: _values.length }, (_, index) => (
<SliderPrimitive.Thumb
data-slot="slider-thumb"
key={index}
index={index}
className="border-accent bg-background ring-ring-accent tap-target block size-4 shrink-0 cursor-grab rounded-full border shadow-sm transition-[color,box-shadow] duration-150 ease-out outline-none hover:ring-3 focus-visible:ring-3 active:cursor-grabbing"
/>
))}
</SliderPrimitive.Track>
</SliderPrimitive.Control>
</SliderPrimitive.Root>
)
}
export { Slider }