Files
Shifted/components/RangeSlider.tsx
2026-02-10 01:14:19 +00:00

60 lines
1.4 KiB
TypeScript

import { useMemo, useState } from "react";
type RangeSliderProps = {
min?: number;
max?: number;
step?: number;
initialMax?: number;
};
export function RangeSlider({
min = 0,
max = 20,
step = 1,
initialMax = 10,
}: RangeSliderProps) {
const clampedInitial = Math.min(Math.max(initialMax, min), max);
const [value, setValue] = useState<number>(clampedInitial);
const bars = useMemo(() => {
const count = Math.max(0, Math.floor((value - min) / step));
return Array.from({ length: count }, (_, i) => i);
}, [value, min, step]);
return (
<div style={{ maxWidth: 360 }}>
<label style={{ display: "block", marginBottom: 8 }}>
Max range
</label>
<input
data-testid="input-max-range"
type="number"
min={min}
max={max}
step={step}
value={value}
onChange={(e) => setValue(Number(e.target.value))}
style={{ width: "100%", marginBottom: 12 }}
/>
<div
aria-label="range-bars"
style={{ display: "grid", gridTemplateColumns: "repeat(10, 1fr)", gap: 4 }}
>
{bars.map((i) => (
<span
key={i}
data-testid="highlighted-bar"
style={{
height: 12,
background: "#4f46e5",
borderRadius: 2,
display: "block",
}}
/>
))}
</div>
</div>
);
}