83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import { useState, useRef, useEffect } from "react";
|
|
import RangeSlider from "react-range-slider-input";
|
|
// import "react-range-slider-input/dist/style.css";
|
|
import "./multiRamgeSlider.css";
|
|
|
|
interface MultiRangeSliderProps {
|
|
onChange?: () => void;
|
|
min: number;
|
|
max: number;
|
|
}
|
|
|
|
const MultiRangeSlider = ({ min, max, onChange }: MultiRangeSliderProps) => {
|
|
const [firstValue, setFirstValue] = useState(min);
|
|
const [secondValue, setSecondValue] = useState(max);
|
|
const firstInputRef = useRef(null);
|
|
const secondInputRef = useRef(null);
|
|
|
|
const handleOnRangeInputChange = (e: [a: number, b: number]) => {
|
|
setFirstValue(e[0]);
|
|
setSecondValue(e[1]);
|
|
};
|
|
|
|
const handleOnFirstInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const value = Number(e.target.value);
|
|
if (value >= min && value <= max) {
|
|
setFirstValue(value);
|
|
}
|
|
};
|
|
|
|
const handleOnSecondInputChange = (
|
|
e: React.ChangeEvent<HTMLInputElement>
|
|
) => {
|
|
const value = Number(e.target.value);
|
|
if (value >= min && value <= max) {
|
|
setSecondValue(value);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (!firstInputRef.current) return;
|
|
(firstInputRef.current as HTMLInputElement).focus();
|
|
}, [firstValue]);
|
|
|
|
useEffect(() => {
|
|
if (!secondInputRef.current) return;
|
|
(secondInputRef.current as HTMLInputElement).focus();
|
|
}, [secondValue]);
|
|
|
|
return (
|
|
<div className="px-2">
|
|
<div className="flex justify-between p-3 bg-white rounded-2xl relative flex-col">
|
|
<div className="flex justify-between">
|
|
<input
|
|
ref={firstInputRef}
|
|
key={firstValue}
|
|
type="number"
|
|
onChange={handleOnFirstInputChange}
|
|
defaultValue={firstValue}
|
|
className="focus:outline-none input_number"
|
|
/>
|
|
<input
|
|
ref={secondInputRef}
|
|
onChange={handleOnSecondInputChange}
|
|
key={secondValue}
|
|
type="number"
|
|
defaultValue={secondValue}
|
|
className="focus:outline-none appearance-none input_number text-right"
|
|
/>
|
|
</div>
|
|
<RangeSlider
|
|
min={min}
|
|
max={max}
|
|
value={[firstValue, secondValue]}
|
|
className="absolute -bottom-3 left-0 w-[calc(100%-16px)] z-20"
|
|
onInput={handleOnRangeInputChange}
|
|
/>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MultiRangeSlider;
|