Skip to content

Commit 95e4db3

Browse files
committed
fix a user experience issue in max validation of
Positive number input
1 parent 815c579 commit 95e4db3

File tree

1 file changed

+30
-21
lines changed

1 file changed

+30
-21
lines changed

src/components/PositiveNumberInput/PositiveNumberInput.jsx

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ class PositiveNumberInput extends React.PureComponent {
77
super(props)
88

99
this.isInputValid = true
10+
this.previousValue = props.value || ''
1011

1112
this.onKeyDown = this.onKeyDown.bind(this)
1213
this.onPaste = this.onPaste.bind(this)
1314
this.onKeyUp = this.onKeyUp.bind(this)
15+
this.onChange = this.onChange.bind(this)
1416
}
1517

1618
onKeyDown(evt) {
@@ -21,7 +23,6 @@ class PositiveNumberInput extends React.PureComponent {
2123
if (isPrintableKey && !digitPattern.test(evt.key)) {
2224
evt.preventDefault()
2325
}
24-
isPrintableKey && this.enforceInputBelowMax(evt)
2526
this.props.onKeyDown(evt)
2627
}
2728

@@ -33,7 +34,6 @@ class PositiveNumberInput extends React.PureComponent {
3334
if (!digitsPattern.test(text)) {
3435
evt.preventDefault()
3536
}
36-
this.enforceInputBelowMax(evt)
3737
this.props.onPaste(evt)
3838
}
3939

@@ -46,24 +46,23 @@ class PositiveNumberInput extends React.PureComponent {
4646
this.props.onKeyUp(evt)
4747
}
4848

49+
onChange(evt) {
50+
const { onChange } = this.props
51+
52+
this.enforceInputBelowMax(evt)
53+
onChange(evt)
54+
}
55+
4956
/**
5057
* Makes sure the input value is kept below the max value
51-
* @param {Event} evt The keydown or paste event
58+
* @param {Event} evt The change event
5259
*/
5360
enforceInputBelowMax(evt) {
54-
const { onChange } = this.props
55-
const previousValue = evt.target.value
56-
if (this.isBelowMaxLimit(previousValue)) {
57-
// persists the synthetic event. So that we can use it inside setTimeout
58-
evt.persist()
59-
60-
// setTimeout to let the input element set the actual value after the keydown/paste
61-
setTimeout(() => {
62-
if (!this.isBelowMaxLimit(evt.target.value)) {
63-
evt.target.value = previousValue
64-
onChange && onChange(evt)
65-
}
66-
})
61+
const value = evt.target.value
62+
if (this.isBelowMaxLimit(value)) {
63+
this.previousValue = value
64+
} else {
65+
evt.target.value = this.previousValue
6766
}
6867
}
6968

@@ -74,25 +73,35 @@ class PositiveNumberInput extends React.PureComponent {
7473

7574
render() {
7675
const props = omit(this.props, ['onValidityChange'])
77-
return <input type="number" min={0} {...props} onKeyDown={this.onKeyDown} onPaste={this.onPaste} onKeyUp={this.onKeyUp} />
76+
return (
77+
<input
78+
type="number"
79+
min={0}
80+
{...props}
81+
onKeyDown={this.onKeyDown}
82+
onPaste={this.onPaste}
83+
onKeyUp={this.onKeyUp}
84+
onChange={this.onChange}
85+
/>
86+
)
7887
}
7988
}
8089

8190
PositiveNumberInput.defaultProps = {
8291
onKeyDown: noop,
8392
onPaste: noop,
8493
onKeyUp: noop,
85-
onValidityChange: noop
86-
94+
onValidityChange: noop,
95+
onChange: noop,
8796
}
8897

8998
PositiveNumberInput.propTypes = {
9099
max: PT.number,
91100
onKeyDown: PT.func,
92101
onPaste: PT.func,
93102
onKeyUp: PT.func,
94-
onValidityChange: PT.func
103+
onValidityChange: PT.func,
104+
onChange: PT.func,
95105
}
96106

97-
98107
export default PositiveNumberInput

0 commit comments

Comments
 (0)