Fix to allow high precision on text input and integer on range.

This commit is contained in:
orangemug 2018-11-02 08:28:51 +00:00
parent e18d304313
commit b456b59c44
2 changed files with 37 additions and 12 deletions

View file

@ -23,18 +23,13 @@ class NumberInput extends React.Component {
} }
} }
static getDerivedStateFromProps(props, state) {
return {
value: props.value
};
}
changeValue(newValue) { changeValue(newValue) {
const value = parseFloat(newValue) const value = parseFloat(newValue)
const hasChanged = this.state.value !== value const hasChanged = this.state.value !== value
if(this.isValid(value) && hasChanged) { if(this.isValid(value) && hasChanged) {
this.props.onChange(value) this.props.onChange(value)
this.setState({ value: value })
} else { } else {
this.setState({ value: newValue }) this.setState({ value: newValue })
} }
@ -73,6 +68,27 @@ class NumberInput extends React.Component {
} }
} }
onChangeRange = (e) => {
const val = parseFloat(rawValue, 10);
const step = this.props.rangeStep;
let out = val;
if(step) {
// Can't do this with the <input/> range step attribute else we won't be able to set a high precision value via the text input.
const snap = val % step;
// Round up/down to step
if (snap < step/2) {
out = val - snap;
}
else {
out = val + (step - snap);
};
}
this.changeValue(out);
}
render() { render() {
let rangeEl; let rangeEl;
@ -83,22 +99,21 @@ class NumberInput extends React.Component {
) { ) {
rangeEl = ( rangeEl = (
<input <input
style={{width: "calc(100% - 4em)", flexShrink: "0"}} className="maputnik-number-range"
key="range" key="range"
type="range" type="range"
step={this.props.rangeStep}
max={this.props.max} max={this.props.max}
min={this.props.min} min={this.props.min}
step="any"
spellCheck="false" spellCheck="false"
className="maputnik-number" value={this.state.value}
value={this.state.value || this.props.default} onChange={this.onChangeRange}
onChange={e => this.changeValue(e.target.value)}
onBlur={this.resetValue} onBlur={this.resetValue}
/> />
); );
} }
return <div style={{display: "flex"}}> return <div className="maputnik-number-container">
{rangeEl} {rangeEl}
<input <input
key="text" key="text"

View file

@ -22,6 +22,16 @@
} }
} }
.maputnik-number-container {
display: flex;
}
.maputnik-number-range {
width: calc(100% - 4.5em);
margin-right: 0.5em;
flex-shrink: 0;
}
.maputnik-number { .maputnik-number {
@extend .maputnik-input; @extend .maputnik-input;
} }