@@ -2,7 +2,7 @@ import * as React from '@theia/core/shared/react';
2
2
import classnames from 'classnames' ;
3
3
4
4
interface SettingsStepInputProps {
5
- value : number ;
5
+ initialValue : number ;
6
6
setSettingsStateValue : ( value : number ) => void ;
7
7
step : number ;
8
8
maxValue : number ;
@@ -15,7 +15,7 @@ const SettingsStepInput: React.FC<SettingsStepInputProps> = (
15
15
props : SettingsStepInputProps
16
16
) => {
17
17
const {
18
- value ,
18
+ initialValue ,
19
19
setSettingsStateValue,
20
20
step,
21
21
maxValue,
@@ -24,7 +24,14 @@ const SettingsStepInput: React.FC<SettingsStepInputProps> = (
24
24
classNames,
25
25
} = props ;
26
26
27
- const [ tempValue , setTempValue ] = React . useState < string > ( String ( value ) ) ;
27
+ const [ valueState , setValueState ] = React . useState < {
28
+ currentValue : number ;
29
+ isEmptyString : boolean ;
30
+ } > ( {
31
+ currentValue : initialValue ,
32
+ isEmptyString : false ,
33
+ } ) ;
34
+ const { currentValue, isEmptyString } = valueState ;
28
35
29
36
const clamp = ( value : number , min : number , max : number ) : number => {
30
37
return Math . min ( Math . max ( value , min ) , max ) ;
@@ -34,10 +41,11 @@ const SettingsStepInput: React.FC<SettingsStepInputProps> = (
34
41
roundingOperation : 'ceil' | 'floor' ,
35
42
stepOperation : ( a : number , b : number ) => number
36
43
) : void => {
37
- const valueRoundedToScale = Math [ roundingOperation ] ( value / step ) * step ;
44
+ const valueRoundedToScale =
45
+ Math [ roundingOperation ] ( currentValue / step ) * step ;
38
46
const calculatedValue =
39
- valueRoundedToScale === value
40
- ? stepOperation ( value , step )
47
+ valueRoundedToScale === currentValue
48
+ ? stepOperation ( currentValue , step )
41
49
: valueRoundedToScale ;
42
50
const newValue = clamp ( calculatedValue , minValue , maxValue ) ;
43
51
@@ -54,41 +62,54 @@ const SettingsStepInput: React.FC<SettingsStepInputProps> = (
54
62
55
63
const onUserInput = ( event : React . ChangeEvent < HTMLInputElement > ) : void => {
56
64
const { value : eventValue } = event . target ;
57
- setTempValue ( eventValue ) ;
65
+ setValueState ( {
66
+ currentValue : Number ( eventValue ) ,
67
+ isEmptyString : eventValue === '' ,
68
+ } ) ;
58
69
} ;
59
70
60
71
/* Prevent the user from entering invalid values */
61
72
const onBlur = ( ) : void => {
62
- const tempValueAsNumber = Number ( tempValue ) ;
63
-
64
- /* If the user input is not a number, reset the input to the previous value */
65
- if ( isNaN ( tempValueAsNumber ) || tempValue === '' ) {
66
- setTempValue ( String ( value ) ) ;
73
+ if ( ( currentValue === 0 && minValue > 0 ) || isNaN ( currentValue ) ) {
74
+ setValueState ( {
75
+ currentValue : initialValue ,
76
+ isEmptyString : false ,
77
+ } ) ;
67
78
return ;
68
79
}
69
- if ( tempValueAsNumber !== value ) {
80
+
81
+ if ( currentValue !== initialValue ) {
70
82
/* If the user input is a number, clamp it to the min and max values */
71
- const newValue = clamp ( tempValueAsNumber , minValue , maxValue ) ;
83
+ const newValue = clamp ( currentValue , minValue , maxValue ) ;
72
84
73
85
setSettingsStateValue ( newValue ) ;
74
- setTempValue ( String ( newValue ) ) ;
75
86
}
76
87
} ;
77
88
78
- const upDisabled = value >= maxValue ;
79
- const downDisabled = value <= minValue ;
89
+ const valueIsNotWithinRange =
90
+ currentValue < minValue || currentValue > maxValue ;
91
+ const isDisabledException =
92
+ valueIsNotWithinRange || isEmptyString || isNaN ( currentValue ) ;
93
+
94
+ const upDisabled = isDisabledException || currentValue >= maxValue ;
95
+ const downDisabled = isDisabledException || currentValue <= minValue ;
80
96
81
97
return (
82
98
< div className = "settings-step-input-container" >
83
99
< input
84
100
className = { classnames ( 'settings-step-input-element' , classNames ?. input ) }
85
- value = { tempValue . toString ( ) }
101
+ value = { isEmptyString ? '' : String ( currentValue ) }
86
102
onChange = { onUserInput }
87
103
onBlur = { onBlur }
88
104
type = "number"
89
105
pattern = "[0-9]+"
90
106
/>
91
- < div className = "settings-step-input-buttons-container" >
107
+ < div
108
+ className = { classnames (
109
+ 'settings-step-input-buttons-container' ,
110
+ classNames ?. buttonsContainer
111
+ ) }
112
+ >
92
113
< button
93
114
className = "settings-step-input-button settings-step-input-up-button"
94
115
disabled = { upDisabled }
0 commit comments