'use client' import * as React from 'react' import * as SliderPrimitive from '@radix-ui/react-slider' import { ny } from '@/lib/utils' interface SliderProps extends React.ComponentPropsWithoutRef { showSteps?: 'none' | 'half' | 'full' formatLabel?: (value: number) => string formatLabelSide?: string } const Slider = React.forwardRef< React.ElementRef, SliderProps >(({ className, showSteps = 'none', formatLabel, formatLabelSide = 'top', ...props }, ref) => { const { min = 0, max = 100, step = 1, orientation = 'horizontal', value, defaultValue, onValueChange } = props const [hoveredThumbIndex, setHoveredThumbIndex] = React.useState(false) const numberOfSteps = Math.floor((max - min) / step) const stepLines = Array.from({ length: numberOfSteps }, (_, index) => index * step + min) const initialValue = Array.isArray(value) ? value : (Array.isArray(defaultValue) ? defaultValue : [min, max]) const [localValues, setLocalValues] = React.useState(initialValue) React.useEffect(() => { if (!isEqual(value, localValues)) setLocalValues(Array.isArray(value) ? value : (Array.isArray(defaultValue) ? defaultValue : [min, max])) }, [min, max, value]) const handleValueChange = (newValues: number[]) => { setLocalValues(newValues) if (onValueChange) onValueChange(newValues) } function isEqual(array1: number[] | undefined, array2: number[] | undefined) { array1 = array1 ?? [] array2 = array2 ?? [] if (array1.length !== array2.length) return false for (let i = 0; i < array1.length; i++) { if (array1[i] !== array2[i]) return false } return true } return ( handleValueChange(value)} {...props} onFocus={() => setHoveredThumbIndex(true)} onBlur={() => setHoveredThumbIndex(false)} > {showSteps !== undefined && showSteps !== 'none' && stepLines.map((value, index) => { if (value === min || value === max) return null const positionPercentage = ((value - min) / (max - min)) * 100 const adjustedPosition = 50 + (positionPercentage - 50) * 0.96 return (
) })} {localValues.map((numberStep, index) => ( {hoveredThumbIndex && formatLabel && (
{formatLabel(numberStep)}
)}
))} ) }) Slider.displayName = SliderPrimitive.Root.displayName export { Slider }