Slider allow users to make selections from a range of values.
Last Updated:JSXimport { useRef, useState } from 'react'; const clamp = ({ value, min, max }) => { return Math.min(Math.max(value, min), max); }; export default function Slider(props) { const { min = 0, max = 100 } = props; const sliderRef = useRef(); const [isDragging, setIsDragging] = useState(false); const [progress, setProgress] = useState(0); const onMouseMove = (event) => { event.stopPropagation(); if (isDragging) { const { left, width } = sliderRef?.current?.getBoundingClientRect(); const _x = clamp({ value: (event.clientX - left) / width, min: 0, max: 1 }); let value = (_x * 100).toFixed(1); if (value < min) value = min; if (value > max) value = max; setProgress(value); } }; const onMouseDown = (event) => { setIsDragging(true); event.stopPropagation(); }; const onMouseUp = (event) => { setIsDragging(false); event.stopPropagation(); }; return ( <div className="relative w-full"> <div ref={sliderRef} className="h-1 overflow-hidden rounded-full bg-zinc-600"> <div className="absolute inset-0 rounded-full bg-gradient-to-r from-sky-700 via-sky-500 to-sky-800" style={{ width: `${progress}%` }} /> </div> <button onMouseLeave={() => setIsDragging(false)} onMouseUp={onMouseUp} onMouseDown={onMouseDown} onMouseMove={onMouseMove} className="absolute -bottom-2.5 -translate-x-1/2 transform" style={{ left: `${progress}%` }} > <svg viewBox="0 0 26 38" fill="none" className="h-10 w-7 fill-sky-500 active:fill-sky-600"> <g> <path d="M7.264 20.625L13 28l5.736-7.375A6 6 0 0020 16.941V6a4 4 0 00-4-4h-6a4 4 0 00-4 4v10.941a6 6 0 001.264 3.684z"></path> </g> </svg> <span className="absolute -left-2">{`${progress}%`}</span> </button> </div> ); }