/* eslint-disable react-hooks/exhaustive-deps */ import clsx from "clsx"; import { useEffect, useRef, useState, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent, } from "react"; interface IMultiRangeSlider { min: number; max: number; currentMin: number; currentMax: number; offset: number; disabled?: boolean; label: string; onChangeMin: (min: number) => void; onChangeMax: (max: number) => void; } function MultiRangeSlider({ currentMax, currentMin, max, min, onChangeMin, onChangeMax, offset, label, disabled = false, }: IMultiRangeSlider) { const [current, setCurrent] = useState<"min" | "max" | null>(null); const rangeRef = useRef(null); function calculateValue(clientX: number, isMin: boolean) { if (!rangeRef.current) return; const rect = rangeRef.current.getBoundingClientRect(); const percentage = (clientX - rect.x) / rect.width; const value = min + percentage * (max - min); return isMin ? Math.max(Math.min(value, currentMax - offset), min) : Math.min(Math.max(value, currentMin + offset), max); } function handleChange( e: MouseEvent | TouchEvent | ReactMouseEvent | ReactTouchEvent ) { if (!current || disabled) return; const { clientX } = "touches" in e ? e.touches[0] : e; const value = calculateValue(clientX, current === "min"); if (value !== undefined) { if (current === "min") onChangeMin(value); else onChangeMax(value); } } function handleMouseUp() { setCurrent(null); } useEffect(() => { if (current) { document.addEventListener("mousemove", handleChange as EventListener); document.addEventListener("mouseup", handleMouseUp); document.addEventListener("mouseleave", handleMouseUp); } return () => { document.removeEventListener("mousemove", handleChange as EventListener); document.removeEventListener("mouseup", handleMouseUp); document.removeEventListener("mouseleave", handleMouseUp); }; }, [current]); const getThumbStyle = (value: number) => ({ left: `${((value - min) / (max - min)) * 100}%`, }); return (

{label}

{Intl.NumberFormat("en").format(Math.round(currentMin))}

{Intl.NumberFormat("en").format(Math.round(currentMax))}

} onTouchMove={ handleChange as React.TouchEventHandler } >
{["min", "max"].map((type) => (
setCurrent(type as "min" | "max")} onTouchStart={() => setCurrent(type as "min" | "max")} style={getThumbStyle(type === "min" ? currentMin : currentMax)} className={clsx( "rounded-full 2xl:w-[1.111vw] 2xl:h-[1.111vw] w-4 h-4 absolute bottom-0 -translate-x-1/2", current === type ? "cursor-grabbing" : "cursor-grab", disabled ? "bg-[#D2D2D2] !cursor-default" : "bg-[#00BED7]" )} /> ))}
); } export default MultiRangeSlider;