PriceRange.tsx
import { useState } from "react";
import "./PriceRange.scss";
export const PriceRange = () => {
let fixedMinPrice = 0;
let fixedMaxPrice = 5000000;
let priceGap = 100000;
const [minValue, setMinValue] = useState(fixedMinPrice);
const [maxValue, setMaxValue] = useState(fixedMaxPrice);
const [rangeMinPercent, setRangeMinPercent] = useState(0);
const [rangeMaxPercent, setRangeMaxPercent] = useState(0);
const minValueHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
setMinValue(parseInt(e.target.value));
};
const maxValueHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
setMaxValue(parseInt(e.target.value));
};
const twoRangeHandler = () => {
if (maxValue - minValue <= priceGap) {
if (fixedMaxPrice <= maxValue + priceGap) {
setMinValue((prev) => prev - priceGap);
setMaxValue(fixedMaxPrice);
} else if (fixedMinPrice >= minValue - priceGap) {
setMinValue(fixedMinPrice);
setMaxValue((prev) => prev + priceGap);
} else {
setMinValue((prev) => prev - priceGap);
setMaxValue((prev) => prev + priceGap);
}
} else {
setRangeMinPercent(() => (minValue / fixedMaxPrice) * 100);
setRangeMaxPercent(() => 100 - (maxValue / fixedMaxPrice) * 100);
}
};
return (
<div id="PriceRange">
<section className="text_input_wrap">
<input type={"text"} className="min_price_text" value={minValue} />
<span>~</span>
<input type={"text"} value={maxValue} />
</section>
<div className="price_slider">
<div
className="inner_range"
style={{ left: `${rangeMinPercent}%`, right: `${rangeMaxPercent}%` }}
></div>
{/* <div className="input_range_wrap"> */}
<input
className="min_price"
type={"range"}
value={minValue}
step="100000"
min={fixedMinPrice}
max={fixedMaxPrice}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
minValueHandler(e);
twoRangeHandler();
}}
/>
<input
className="max_price"
type={"range"}
step="100000"
value={maxValue}
min={fixedMinPrice}
max={fixedMaxPrice}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
maxValueHandler(e);
twoRangeHandler();
}}
/>
{/* </div> */}
</div>
</div>
);
};
PriceRange.scss
#PriceRange {
.text_input_wrap {
display: flex;
align-items: center;
span {
margin: 0 10px;
}
}
//배경
.price_slider {
margin-top: 45px;
position: relative;
height: 4px;
width: 100%;
border-radius: 10px;
background-color: #dddddd;
&::before {
content: "0";
position: absolute;
left: 0;
top: -35px;
}
&::after {
content: "500만원";
position: absolute;
right: 0;
top: -35px;
}
//현재값
.inner_range {
position: absolute;
top: 0;
// left: 30%;
// right: 30%;
height: 4px;
border-radius: 10px;
background-color: #b0b0b0;
}
input {
position: absolute;
background: none;
top: 0;
// background-color: darkgray;
height: 3px;
// color: aliceblue;
width: 100%;
--webkit-appearance: none;
pointer-events: none; //버튼 비활성화
//버튼 커스텀
&.min_price::-webkit-slider-thumb {
pointer-events: auto; //커스텀 버튼 활성화
height: 30px;
width: 30px;
border-radius: 50%;
border: 2px solid #b0b0b0;
background-color: white;
-webkit-appearance: none;
}
&.max_price::-webkit-slider-thumb {
pointer-events: auto; //커스텀 버튼 활성화
height: 30px;
width: 30px;
border-radius: 50%;
border: 2px solid #b0b0b0;
background-color: white;
-webkit-appearance: none;
}
}
}
}