Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, {Component} from 'react'
- import PropTypes from 'prop-types'
- const MAX_INT = 2147483647
- const MIN_INT = -2147483648
- const isNaturalNumber = input => {
- return typeof input === 'number' && input % 1 === 0 && Number.isInteger(input) && input >= 0 && 1 / input !== -Infinity
- }
- const isInteger = input => {
- if (!Number.isInteger(input)) {
- return false
- }
- if (typeof input !== 'number' || input !== Math.floor(input) || input === Infinity || isNaN(input)) {
- return false
- }
- if (input > MAX_INT || input < MIN_INT) {
- return false
- }
- return true
- }
- const isFloat = input => {
- if (typeof input !== 'number' || input !== parseFloat(input) || input === Infinity || isNaN(input)) {
- return false
- }
- if (input > MAX_INT || input < MIN_INT) {
- return false
- }
- return true
- }
- class InputGuard extends Component {
- constructor (props) {
- super(props)
- this.state = {
- currentValue: props.children.props.value,
- isFocused: false
- }
- this.handleChange = this.handleChange.bind(this, props.children.props.onChange)
- this.handleFocus = this.handleFocus.bind(this, props.children.props.onFocus)
- this.handleBlur = this.handleBlur.bind(this, props.children.props.onBlur)
- }
- handleChange (onChange, e) {
- if (this.props.type === 'string' || e.target.value === '') {
- this.setState({currentValue: e.target.value})
- if (typeof onChange === 'function') {
- return onChange(e)
- }
- return null
- } else if (this.props.type === 'int' && !isInteger(Number(e.target.value))) {
- return null
- } else if (this.props.type === 'float' && !isFloat(Number(e.target.value))) {
- return null
- } else if (this.props.type === 'naturalNumber' && !isNaturalNumber(Number(e.target.value))) {
- return null
- } else if (this.props.notZero === true && Number(e.target.value) === 0) {
- return null
- }
- const event = {...e, ...{target: {...e.target, value: Number(e.target.value)}}}
- this.setState({currentValue: event.target.value})
- if (typeof onChange === 'function') {
- return onChange(event)
- }
- }
- handleFocus (onFocus, e) {
- this.setState({isFocused: true})
- if (typeof onFocus === 'function') {
- onFocus(e)
- }
- }
- handleBlur (onBlur, e) {
- this.setState({isFocused: false})
- if (typeof onBlur === 'function') {
- onBlur(e)
- }
- }
- static getDerivedStateFromProps (nextProps, prevState) {
- if (nextProps.children.props.value !== prevState.currentValue && !prevState.isFocused) {
- return {currentValue: nextProps.children.props.value}
- }
- return null
- }
- render () {
- return React.cloneElement(this.props.children, {
- value: this.state.currentValue,
- onChange: this.handleChange,
- onFocus: this.handleFocus,
- onBlur: this.handleBlur
- })
- }
- }
- InputGuard.defaultProps = {
- type: 'string',
- notZero: false
- }
- InputGuard.propTypes = {
- children: PropTypes.element.isRequired,
- type: PropTypes.oneOf(['int', 'float', 'naturalNumber', 'string']),
- notZero: PropTypes.bool
- }
- export default InputGuard
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement