import React from 'react'; import { clsx } from 'clsx'; export interface SliderProps extends Omit< React.InputHTMLAttributes, 'type' | 'onChange' > { value?: number; onChange?: (value: number) => void; min?: number; max?: number; step?: number; showValue?: boolean; label?: string; className?: string; } /** * Slider/Range input component */ export const Slider = React.forwardRef( ( { value = 0, onChange, min = 0, max = 100, step = 1, showValue = false, label, className, disabled, ...props }, ref ) => { const percentage = ((value - min) / (max - min)) * 100; return (
{label && (
{showValue && {value}}
)}
onChange?.(Number(e.target.value))} min={min} max={max} step={step} disabled={disabled} className={clsx( 'w-full h-2 bg-muted rounded-lg appearance-none cursor-pointer', 'accent-primary', { 'opacity-50 cursor-not-allowed': disabled, }, '[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:cursor-pointer', '[&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:rounded-full [&::-moz-range-thumb]:bg-primary [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:cursor-pointer', '[&::-moz-range-thumb]:disabled:cursor-not-allowed', '[&::-webkit-slider-thumb]:disabled:cursor-not-allowed' )} style={{ background: `linear-gradient(to right, hsl(var(--primary)) 0%, hsl(var(--primary)) ${percentage}%, hsl(var(--muted)) ${percentage}%, hsl(var(--muted)) 100%)`, }} {...props} />
{!label && showValue && (
{min} {max}
)}
); } ); Slider.displayName = 'Slider';