You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Lidarr/frontend/src/Components/Form/NumberInput.js

127 lines
2.3 KiB

import PropTypes from 'prop-types';
import React, { Component } from 'react';
import TextInput from './TextInput';
function parseValue(props, value) {
const {
isFloat,
min,
max
} = props;
if (value == null || value === '') {
return null;
}
let newValue = isFloat ? parseFloat(value) : parseInt(value);
if (min != null && newValue != null && newValue < min) {
newValue = min;
} else if (max != null && newValue != null && newValue > max) {
newValue = max;
}
return newValue;
}
class NumberInput extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
value: props.value == null ? '' : props.value.toString(),
isFocused: false
};
}
componentDidUpdate(prevProps, prevState) {
const { value } = this.props;
if (value !== prevProps.value && !this.state.isFocused) {
this.setState({
value: value == null ? '' : value.toString()
});
}
}
//
// Listeners
onChange = ({ name, value }) => {
this.setState({ value });
this.props.onChange({
name,
value: parseValue(this.props, value)
});
};
onFocus = () => {
this.setState({ isFocused: true });
};
onBlur = () => {
const {
name,
onChange
} = this.props;
const { value } = this.state;
const parsedValue = parseValue(this.props, value);
const stringValue = parsedValue == null ? '' : parsedValue.toString();
if (stringValue === value) {
this.setState({ isFocused: false });
} else {
this.setState({
value: stringValue,
isFocused: false
});
}
onChange({
name,
value: parsedValue
});
};
//
// Render
render() {
const value = this.state.value;
return (
<TextInput
{...this.props}
type="number"
value={value == null ? '' : value}
onChange={this.onChange}
onBlur={this.onBlur}
onFocus={this.onFocus}
/>
);
}
}
NumberInput.propTypes = {
name: PropTypes.string.isRequired,
value: PropTypes.number,
min: PropTypes.number,
max: PropTypes.number,
isFloat: PropTypes.bool.isRequired,
onChange: PropTypes.func.isRequired
};
NumberInput.defaultProps = {
value: null,
isFloat: false
};
export default NumberInput;