Fixes for firefox, this makes the range input only update on pointerup

This commit is contained in:
orangemug 2019-05-21 18:42:19 +01:00
parent 15cdfbc980
commit 41329ec2f8
2 changed files with 59 additions and 28 deletions

View file

@ -21,26 +21,34 @@ class NumberInput extends React.Component {
this.state = { this.state = {
editing: false, editing: false,
value: props.value, value: props.value,
dirtyValue: props.value,
} }
} }
static getDerivedStateFromProps(props, state) { static getDerivedStateFromProps(props, state) {
if (!state.editing) { if (!state.editing) {
return { return {
value: props.value value: props.value,
dirtyValue: props.value,
}; };
} }
else {
return null;
}
} }
changeValue(newValue) { changeValue(newValue) {
this.setState({editing: true}); this.setState({editing: true});
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: newValue }) this.setState({
value: newValue,
dirtyValue: newValue,
})
} }
isValid(v) { isValid(v) {
@ -78,37 +86,36 @@ class NumberInput extends React.Component {
} }
onChangeRange = (e) => { onChangeRange = (e) => {
const val = parseFloat(e.target.value, 10); const value = parseFloat(e.target.value, 10);
const step = this.props.rangeStep; const step = this.props.rangeStep;
let out = val; let dirtyValue = value;
if(step) { 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. // 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; const snap = value % step;
// Round up/down to step // Round up/down to step
if (snap < step/2) { if (snap < step/2) {
out = val - snap; dirtyValue = value - snap;
} }
else { else {
out = val + (step - snap); dirtyValue = value + (step - snap);
}; };
} }
this.changeValue(out); this.setState({editing: true, value, dirtyValue});
} }
render() { render() {
let rangeEl;
if( if(
this.props.hasOwnProperty("min") && this.props.hasOwnProperty("max") && this.props.hasOwnProperty("min") && this.props.hasOwnProperty("max") &&
this.props.min !== undefined && this.props.max !== undefined && this.props.min !== undefined && this.props.max !== undefined &&
this.props.allowRange this.props.allowRange
) { ) {
const value = this.props.value === undefined ? this.props.default : this.props.value; const value = this.state.value === undefined ? this.props.default : this.state.value;
const rangeValue = Number.isNaN(parseFloat(value, 10)) ? this.props.default : value;
rangeEl = ( return <div className="maputnik-number-container">
<input <input
className="maputnik-number-range" className="maputnik-number-range"
key="range" key="range"
@ -117,25 +124,44 @@ class NumberInput extends React.Component {
min={this.props.min} min={this.props.min}
step="any" step="any"
spellCheck="false" spellCheck="false"
value={value} value={rangeValue}
onChange={this.onChangeRange} onChange={this.onChangeRange}
onPointerUp={() => {
const {dirtyValue} = this.state;
const hasChanged = this.state.props !== dirtyValue
if(this.isValid(dirtyValue) && hasChanged) {
this.setState({editing: false}, () => {
this.props.onChange(dirtyValue);
});
}
}}
/>
<input
key="text"
spellCheck="false"
className="maputnik-number"
placeholder={this.props.default}
value={this.state.dirtyValue}
onChange={e => {
this.changeValue(e.target.value)
}}
onBlur={this.resetValue} onBlur={this.resetValue}
/> />
); </div>
}
else {
return <div className="maputnik-number-container">
<input
key="text"
spellCheck="false"
className="maputnik-number"
placeholder={this.props.default}
value={this.state.value}
onChange={e => this.changeValue(e.target.value)}
onBlur={this.resetValue}
/>
</div>
} }
return <div className="maputnik-number-container">
{rangeEl}
<input
key="text"
spellCheck="false"
className="maputnik-number"
placeholder={this.props.default}
value={this.state.value}
onChange={e => this.changeValue(e.target.value)}
onBlur={this.resetValue}
/>
</div>
} }
} }

View file

@ -183,3 +183,8 @@
margin-bottom: $margin-3; margin-bottom: $margin-3;
} }
} }
.maputnik-input-block-content {
position: relative;
overflow: hidden;
}