The Slider component is used to select a value or range of values from a range of values.
export const Example = () => {
return <Slider defaultValue={[50]} />;
};
If you haven't included Piksel UI in your project, include it first. You can check the installation page.
Copy the following source code and add it to your project.
import React, { ComponentPropsWithRef, forwardRef } from "react";
import { tv, VariantProps } from "tailwind-variants";
import * as SliderPrimitive from "@radix-ui/react-slider";
export const sliderDisplayName = "Slider";
export type SliderProps = ComponentPropsWithRef<typeof SliderPrimitive.Root> &
VariantProps<typeof sliderStyles>;
/**
* @name Slider
* @description The Slider component is used to select a value or range of values from a range of values.
*/
export const Slider = forwardRef<HTMLDivElement, SliderProps>((props, ref) => {
const { color, size, radius, className, defaultValue, value, ...rest } =
props;
const thumbCount = value?.length ?? defaultValue?.length ?? 1;
const { root, range, thumb, track } = sliderStyles({
color,
size,
radius,
});
return (
<SliderPrimitive.Root
value={value}
defaultValue={defaultValue}
className={root()}
{...rest}
ref={ref}
>
<SliderPrimitive.Track className={track()}>
<SliderPrimitive.Range className={range()} />
</SliderPrimitive.Track>
{Array.from({ length: thumbCount }).map((_, i) => (
<SliderPrimitive.Thumb key={i} className={thumb()} />
))}
</SliderPrimitive.Root>
);
});
Slider.displayName = sliderDisplayName;
export const sliderStyles = tv({
slots: {
root: "relative flex items-center select-none touch-none w-full",
track: "bg-zinc-100 relative grow rounded-full",
range: "absolute rounded-full h-full",
thumb:
"block bg-white shadow rounded-full outline-none ring-1 transition-all",
},
variants: {
color: {
blue: {
range: "bg-blue-600",
thumb: "ring-blue-200 active:ring-blue-400",
},
red: {
range: "bg-red-600",
thumb: "ring-red-200 active:ring-red-400",
},
indigo: {
range: "bg-indigo-600",
thumb: "ring-indigo-200 active:ring-indigo-400",
},
green: {
range: "bg-green-600",
thumb: "ring-green-200 active:ring-green-400",
},
yellow: {
range: "bg-yellow-600",
thumb: "ring-yellow-200 active:ring-yellow-400",
},
zinc: {
range: "bg-zinc-600",
thumb: "ring-zinc-200 active:ring-zinc-400",
},
white: {
range: "bg-white",
thumb: "ring-zinc-200 active:ring-zinc-400",
},
black: {
range: "bg-black",
thumb: "ring-zinc-200 active:ring-zinc-400",
},
},
size: {
sm: {
root: "h-4",
track: "h-1",
thumb: "w-3 h-3",
},
md: {
root: "h-5",
track: "h-1.5",
thumb: "w-4 h-4",
},
lg: {
root: "h-6",
track: "h-2",
thumb: "w-5 h-5",
},
},
radius: {
none: {
track: "rounded-none",
range: "rounded-none",
thumb: "rounded-none",
},
sm: {
track: "rounded-sm",
range: "rounded-sm",
thumb: "rounded-sm",
},
md: {
track: "rounded-md",
range: "rounded-md",
thumb: "rounded-md",
},
lg: {
track: "rounded-lg",
range: "rounded-lg",
thumb: "rounded-lg",
},
xl: {
track: "rounded-xl",
range: "rounded-xl",
thumb: "rounded-xl",
},
full: {
track: "rounded-full",
range: "rounded-full",
thumb: "rounded-full",
},
},
},
defaultVariants: {
color: "black",
size: "md",
radius: "full",
},
});