Docs
Slider
Slider
An input where the user selects a value from within a given range.
This is a form component.
Make sure you installed the Form Base Components. and the Form Library.
Loading...
Installation
Install dependent components
See installation instructions for the Bar Indicator component.
Copy and paste the following code into your project.
"use client";
import { Fragment } from "react";
import {
Slider as RaSlider,
SliderOutput,
SliderThumb,
SliderTrack,
} from "react-aria-components";
import {
BarIndicatorLabels,
BarIndicatorProgress,
barIndicatorVariants,
} from "@/components/ui/bar-indicator";
import type { FormComponentBaseProps } from "@/components/ui/form";
import { Description, ErrorMessage } from "@/components/ui/form";
import { autoRef, cn, withRenderProps } from "@/lib/utils";
export type SliderProps = FormComponentBaseProps &
React.ComponentPropsWithRef<typeof RaSlider> & {
thumbLabels?: string[];
};
export const Slider = autoRef(
({
className,
label,
thumbLabels,
description,
errorMessage,
...props
}: SliderProps) => {
return (
<RaSlider
className={(values) =>
cn(barIndicatorVariants.root(), withRenderProps(className)(values))
}
{...props}
>
<BarIndicatorLabels
label={label}
value={
<SliderOutput>
{({ state }) =>
state.values
.map((_, i) => state.getThumbValueLabel(i))
.join(" – ")
}
</SliderOutput>
}
/>
<SliderTrack className={barIndicatorVariants.meter()}>
{({ state }) => (
<>
{state.values.length === 1 && (
<BarIndicatorProgress
style={{ width: state.getThumbPercent(0) * 100 + "%" }}
/>
)}
{state.values.length > 1 && (
<BarIndicatorProgress
style={{
width: `${
state.getThumbPercent(state.values.length - 1) * 100 -
state.getThumbPercent(0) * 100
}%`,
left: `${state.getThumbPercent(0) * 100}%`,
}}
/>
)}
{state.values.map((_, i) => (
<Fragment key={i}>
<SliderThumb
className={cn(
"dragging:bg-muted top-[50%] h-5 w-5 rounded-full border-2 border-solid border-primary bg-white outline-none ring-primary transition focus-visible:ring-2",
)}
key={i}
index={i}
aria-label={thumbLabels?.[i]}
/>
</Fragment>
))}
</>
)}
</SliderTrack>
<Description>{description}</Description>
<ErrorMessage>{errorMessage}</ErrorMessage>
</RaSlider>
);
},
);