Fix <NumberInput/> to allow for decimal numbers.

This commit is contained in:
orangemug 2020-04-06 09:55:07 +01:00
parent 45680151ef
commit c58ae0f895

View file

@ -31,7 +31,7 @@ class NumberInput extends React.Component {
} }
static getDerivedStateFromProps(props, state) { static getDerivedStateFromProps(props, state) {
if (!state.editing) { if (!state.editing && props.value !== state.value) {
return { return {
value: props.value, value: props.value,
dirtyValue: props.value, dirtyValue: props.value,
@ -49,12 +49,17 @@ class NumberInput extends React.Component {
if(this.isValid(value) && hasChanged) { if(this.isValid(value) && hasChanged) {
this.props.onChange(value) this.props.onChange(value)
this.setState({ this.setState({
dirtyValue: newValue, value: newValue,
});
}
else if (!this.isValid(value) && hasChanged) {
this.setState({
value: undefined,
}); });
} }
this.setState({ this.setState({
value: newValue, dirtyValue: newValue === "" ? undefined : newValue,
}) })
} }
@ -144,8 +149,14 @@ class NumberInput extends React.Component {
this.props.min !== undefined && this.props.max !== undefined && this.props.min !== undefined && this.props.max !== undefined &&
this.props.allowRange this.props.allowRange
) { ) {
const dirtyValue = this.state.dirtyValue === undefined ? this.props.default : this.state.dirtyValue const value = this.state.editing ? this.state.dirtyValue : this.state.value;
const value = this.state.value === undefined ? "" : this.state.value; let inputValue;
if (this.state.editingRange) {
inputValue = this.state.value;
}
else {
inputValue = value;
}
return <div className="maputnik-number-container"> return <div className="maputnik-number-container">
<input <input
@ -156,21 +167,26 @@ class NumberInput extends React.Component {
min={this.props.min} min={this.props.min}
step="any" step="any"
spellCheck="false" spellCheck="false"
value={dirtyValue} placeholder={this.props.default}
value={value === undefined ? "" : value}
aria-hidden="true" aria-hidden="true"
onChange={this.onChangeRange} onChange={this.onChangeRange}
onKeyDown={() => { onKeyDown={() => {
this._keyboardEvent = true; this._keyboardEvent = true;
}} }}
onPointerDown={() => { onPointerDown={() => {
this.setState({editing: true}); this.setState({editing: true, editingRange: true});
}} }}
onPointerUp={() => { onPointerUp={() => {
// Safari doesn't get onBlur event // Safari doesn't get onBlur event
this.setState({editing: false}); this.setState({editing: false, editingRange: false});
}} }}
onBlur={() => { onBlur={() => {
this.setState({editing: false}); this.setState({
editing: false,
editingRange: false,
dirtyValue: this.state.value,
});
}} }}
/> />
<input <input
@ -179,25 +195,32 @@ class NumberInput extends React.Component {
spellCheck="false" spellCheck="false"
className="maputnik-number" className="maputnik-number"
placeholder={this.props.default} placeholder={this.props.default}
value={value} value={inputValue === undefined ? "" : inputValue}
onChange={e => { onFocus={e => {
if (!this.state.editing) { this.setState({editing: true});
this.changeValue(e.target.value); }}
} onChange={e => {
this.changeValue(e.target.value);
}}
onBlur={e => {
this.setState({editing: false});
this.resetValue()
}} }}
onBlur={this.resetValue}
/> />
</div> </div>
} }
else { else {
const value = this.state.value === undefined ? "" : this.state.value; const value = this.state.editing ? this.state.dirtyValue : this.state.value;
return <input return <input
spellCheck="false" spellCheck="false"
className="maputnik-number" className="maputnik-number"
placeholder={this.props.default} placeholder={this.props.default}
value={value} value={value === undefined ? "" : value}
onChange={e => this.changeValue(e.target.value)} onChange={e => this.changeValue(e.target.value)}
onFocus={() => {
this.setState({editing: true});
}}
onBlur={this.resetValue} onBlur={this.resetValue}
required={this.props.required} required={this.props.required}
/> />