import type { CSSProperties, Ref } from 'react'; import { Slider as SliderPrimitive } from '@base-ui/react/slider'; import { cn } from '@/lib/utils'; type SliderLabelProps = SliderPrimitive.Label.Props & { ref?: Ref; }; type SliderMarksProps = { className?: string; labelInterval?: number; max?: number; min?: number; step?: number; }; type SliderProps = SliderPrimitive.Root.Props & { getAriaLabel?: SliderPrimitive.Thumb.Props['getAriaLabel']; getAriaValueText?: SliderPrimitive.Thumb.Props['getAriaValueText']; /** Render the filled indicator. Set to `false` for sliders with a custom track (e.g. color pickers). Defaults to `true`. */ indicator?: boolean; ref?: Ref; thumbClassName?: string; trackClassName?: string; trackStyle?: CSSProperties; }; type SliderValueProps = SliderPrimitive.Value.Props & { ref?: Ref; }; function SliderLabel({ className, ref, ...props }: SliderLabelProps) { return ( ); } function SliderMarks({ className, labelInterval = 1, max = 100, min = 0, step = 1, }: SliderMarksProps) { const tickCount = Math.floor((max - min) / step) + 1; const ticks = Array.from( { length: tickCount }, (_, index) => min + index * step, ); return (
{ticks.map((tick, index) => { const showLabel = index % labelInterval === 0; return ( {tick} ); })}
); } function SliderRoot({ 'aria-describedby': ariaDescribedBy, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, children, className, defaultValue, getAriaLabel, getAriaValueText, indicator = true, max = 100, min = 0, ref, thumbClassName, trackClassName, trackStyle, value, ...props }: SliderProps) { const resolved = value ?? defaultValue; const thumbCount = Array.isArray(resolved) ? resolved.length : 1; const getThumbAriaLabel = getAriaLabel ?? (typeof ariaLabel === 'string' ? (index: number) => thumbCount > 1 ? `${ariaLabel} ${index === 0 ? 'minimum' : index === thumbCount - 1 ? 'maximum' : index + 1}` : ariaLabel : undefined); return ( {children} {indicator ? ( ) : null} {Array.from({ length: thumbCount }, (_, index) => ( ))} ); } function SliderValue({ className, ref, ...props }: SliderValueProps) { return ( ); } const Slider = Object.assign(SliderRoot, { Label: SliderLabel, Marks: SliderMarks, Value: SliderValue, }); export { Slider, SliderPrimitive }; export type { SliderLabelProps, SliderMarksProps, SliderProps, SliderValueProps, };