import Slider from "@registry/components/ui/slider";
export function SliderExample() {
return (
<div className="flex flex-wrap items-center gap-4">
<Slider aria-label="Volume" defaultValue={40} />
</div>
);
} Examples
Range
Pass an array to defaultValue to render a range slider with multiple thumbs.
import Slider from "@registry/components/ui/slider";
export function RangeSliderExample() {
return (
<div className="flex flex-wrap items-center gap-4">
<Slider aria-label="Price range" defaultValue={[25, 75]} />
</div>
);
} Step
Use step to control the increment between values.
import Slider from "@registry/components/ui/slider";
export function SteppedSliderExample() {
return (
<div className="flex flex-wrap items-center gap-4">
<Slider aria-label="Brightness" defaultValue={50} step={10} />
</div>
);
} Disabled
Use the disabled prop to prevent interaction.
import Slider from "@registry/components/ui/slider";
export function DisabledSliderExample() {
return (
<div className="flex flex-wrap items-center gap-4">
<Slider aria-label="Disabled volume" defaultValue={40} disabled />
</div>
);
} Controlled
Manage the slider value with React state using value and onValueChange.
import { useState } from "react";
import Slider from "@registry/components/ui/slider";
export function ControlledSliderExample() {
const [value, setValue] = useState(40);
return (
<div className="flex flex-col gap-4">
<Slider
aria-label="Volume"
value={value}
onValueChange={(nextValue) => {
setValue(Array.isArray(nextValue) ? (nextValue[0] ?? 0) : nextValue);
}}
/>
<span className="text-sm text-gray-600 dark:text-gray-400">Volume: {value}</span>
</div>
);
} Installation
Copy the source code below into your project:
import { cn } from "@registry/lib/utils";
import { Slider as BaseSlider } from "@base-ui/react";
import React from "react";
export default function Slider({
className,
value,
defaultValue,
min,
max,
...props
}: BaseSlider.Root.Props) {
const _values = React.useMemo(
() =>
Array.isArray(value)
? value
: typeof value === "number"
? [value]
: Array.isArray(defaultValue)
? defaultValue
: typeof defaultValue === "number"
? [defaultValue]
: [min ?? 0],
[value, defaultValue, min],
);
return (
<BaseSlider.Root
data-slot="slider"
defaultValue={defaultValue}
value={value}
min={min}
max={max}
thumbAlignment="edge"
{...props}
>
<BaseSlider.Control
className={cn("flex w-32 touch-none items-center select-none", className)}
data-slot="slider-control"
>
<BaseSlider.Track
className={cn("h-1 w-full rounded-full bg-muted inset-ring inset-ring-input select-none")}
data-slot="slider-track"
>
<BaseSlider.Indicator
className={cn(
"bg-accent select-none data-disabled:opacity-50",
_values.length === 1 ? "rounded-l-full" : "",
)}
data-slot="slider-indicator"
/>
{Array.from({ length: _values.length }).map((_, index) => (
<BaseSlider.Thumb
key={index}
className={(state) =>
cn(
"size-4 rounded-full bg-white shadow-xs ring ring-input transition-transform select-none before:hidden data-disabled:cursor-not-allowed data-disabled:bg-muted",
state.dragging && state.activeThumbIndex === index && "scale-110",
)
}
data-slot="slider-thumb"
index={index}
/>
))}
</BaseSlider.Track>
</BaseSlider.Control>
</BaseSlider.Root>
);
} API Reference
This component does not add any props on top of Base UI Slider.Root . See the Base UI docs for the full API reference.