58 lines
2.2 KiB
TypeScript
58 lines
2.2 KiB
TypeScript
"use client"
|
|
|
|
import * as React from "react"
|
|
import * as SliderPrimitive from "@radix-ui/react-slider"
|
|
|
|
import { cn } from "@/lib/utils"
|
|
|
|
const Slider = React.forwardRef<
|
|
React.ElementRef<typeof SliderPrimitive.Root>,
|
|
React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>
|
|
>(({ className, defaultValue, value, min = 0, max = 100, ...props }, ref) => {
|
|
const normalizedValues = React.useMemo(() => {
|
|
if (Array.isArray(value) && value.length > 0) return value;
|
|
if (Array.isArray(defaultValue) && defaultValue.length > 0)
|
|
return defaultValue;
|
|
return [min, max];
|
|
}, [defaultValue, value, min, max]);
|
|
|
|
return (
|
|
<SliderPrimitive.Root
|
|
ref={ref}
|
|
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.Track
|
|
data-slot="slider-track"
|
|
className={cn(
|
|
"bg-muted relative grow overflow-hidden 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.Range
|
|
data-slot="slider-range"
|
|
className={cn(
|
|
"bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full"
|
|
)}
|
|
/>
|
|
</SliderPrimitive.Track>
|
|
{Array.from({ length: normalizedValues.length }, (_, index) => (
|
|
<SliderPrimitive.Thumb
|
|
data-slot="slider-thumb"
|
|
key={index}
|
|
className="border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50"
|
|
/>
|
|
))}
|
|
</SliderPrimitive.Root>
|
|
);
|
|
})
|
|
Slider.displayName = SliderPrimitive.Root.displayName
|
|
|
|
export { Slider }
|