Advertisement
Guest User

Untitled

a guest
Oct 18th, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.88 KB | None | 0 0
  1. import React, {Component} from 'react'
  2. import PropTypes from 'prop-types'
  3.  
  4. const MAX_INT = 2147483647
  5. const MIN_INT = -2147483648
  6.  
  7. const isNaturalNumber = input => {
  8. return typeof input === 'number' && input % 1 === 0 && Number.isInteger(input) && input >= 0 && 1 / input !== -Infinity
  9. }
  10.  
  11. const isInteger = input => {
  12. if (!Number.isInteger(input)) {
  13. return false
  14. }
  15.  
  16. if (typeof input !== 'number' || input !== Math.floor(input) || input === Infinity || isNaN(input)) {
  17. return false
  18. }
  19.  
  20. if (input > MAX_INT || input < MIN_INT) {
  21. return false
  22. }
  23. return true
  24. }
  25.  
  26. const isFloat = input => {
  27. if (typeof input !== 'number' || input !== parseFloat(input) || input === Infinity || isNaN(input)) {
  28. return false
  29. }
  30.  
  31. if (input > MAX_INT || input < MIN_INT) {
  32. return false
  33. }
  34. return true
  35. }
  36.  
  37. class InputGuard extends Component {
  38. constructor (props) {
  39. super(props)
  40. this.state = {
  41. currentValue: props.children.props.value,
  42. isFocused: false
  43. }
  44. this.handleChange = this.handleChange.bind(this, props.children.props.onChange)
  45. this.handleFocus = this.handleFocus.bind(this, props.children.props.onFocus)
  46. this.handleBlur = this.handleBlur.bind(this, props.children.props.onBlur)
  47. }
  48.  
  49. handleChange (onChange, e) {
  50. if (this.props.type === 'string' || e.target.value === '') {
  51. this.setState({currentValue: e.target.value})
  52. if (typeof onChange === 'function') {
  53. return onChange(e)
  54. }
  55. return null
  56. } else if (this.props.type === 'int' && !isInteger(Number(e.target.value))) {
  57. return null
  58. } else if (this.props.type === 'float' && !isFloat(Number(e.target.value))) {
  59. return null
  60. } else if (this.props.type === 'naturalNumber' && !isNaturalNumber(Number(e.target.value))) {
  61. return null
  62. } else if (this.props.notZero === true && Number(e.target.value) === 0) {
  63. return null
  64. }
  65.  
  66. const event = {...e, ...{target: {...e.target, value: Number(e.target.value)}}}
  67. this.setState({currentValue: event.target.value})
  68. if (typeof onChange === 'function') {
  69. return onChange(event)
  70. }
  71. }
  72.  
  73. handleFocus (onFocus, e) {
  74. this.setState({isFocused: true})
  75. if (typeof onFocus === 'function') {
  76. onFocus(e)
  77. }
  78. }
  79.  
  80. handleBlur (onBlur, e) {
  81. this.setState({isFocused: false})
  82. if (typeof onBlur === 'function') {
  83. onBlur(e)
  84. }
  85. }
  86.  
  87. static getDerivedStateFromProps (nextProps, prevState) {
  88. if (nextProps.children.props.value !== prevState.currentValue && !prevState.isFocused) {
  89. return {currentValue: nextProps.children.props.value}
  90. }
  91. return null
  92. }
  93.  
  94. render () {
  95. return React.cloneElement(this.props.children, {
  96. value: this.state.currentValue,
  97. onChange: this.handleChange,
  98. onFocus: this.handleFocus,
  99. onBlur: this.handleBlur
  100. })
  101. }
  102. }
  103.  
  104. InputGuard.defaultProps = {
  105. type: 'string',
  106. notZero: false
  107. }
  108.  
  109. InputGuard.propTypes = {
  110. children: PropTypes.element.isRequired,
  111. type: PropTypes.oneOf(['int', 'float', 'naturalNumber', 'string']),
  112. notZero: PropTypes.bool
  113. }
  114.  
  115. export default InputGuard
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement