JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="app"></div>
Babel + JSX
class Range extends React.Component {
state = {
value: this.props.steps[0],
inputValue: this.props.steps[0],
updateId: null,
}
onChange = ({ target: { value } }) => {
if (this.state.updateId) {
return;
}
const oldVal = this.state.value;
const newVal = this.props.steps.reduce((closest, n) =>
Math.abs(closest - value) < Math.abs(n - value) ? closest : n
);
const step = (newVal - oldVal) / 25;
this.setState({
value: newVal,
updateId: setInterval(() => this.setState(prevState => {
const { inputValue } = prevState;
if (inputValue === newVal) {
clearInterval(prevState.updateId);
return {
updateId: null,
};
} else {
return {
inputValue: Math.abs(inputValue - newVal) < Math.abs(step) ? newVal : inputValue + step,
};
}
}), 10),
});
}
render() {
const { steps } = this.props;
const min = steps[0];
const max = steps[steps.length - 1];
return (
<div>
<input
type="range"
min={min}
max={max}
step={(max - min) / 100}
value={this.state.inputValue}
onChange={this.onChange}
/>
<p>{this.state.value}</p>
</div>
);
}
}
ReactDOM.render(
<div>
<Range steps={[ 0, 500, 1000, 5000, 10000 ]} />
<Range steps={[ -5, 10, 100, 150, 187, 211 ]} />
<Range steps={[ 0, 2, 4, 10 ]} />
</div>,
document.getElementById('app')
);