diff --git a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx index 458266fa9..8f2fd3a3c 100644 --- a/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx +++ b/arduino-ide-extension/src/browser/dialogs/settings/settings-step-input.tsx @@ -16,64 +16,30 @@ const SettingsStepInput: React.FC = ( const { value, setSettingsStateValue, step, maxValue, minValue, classNames } = props; - const [stepUpDisabled, setStepUpDisabled] = React.useState(false); - const [stepDownDisabled, setStepDownDisabled] = React.useState(false); - - const onStepUp = (): void => { - const valueRoundedToScale = Math.ceil(value / step) * step; - const calculatedValue = - valueRoundedToScale === value ? value + step : valueRoundedToScale; - const newValue = limitValueByCondition( - calculatedValue, - maxValue, - calculatedValue >= maxValue, - disableStepUp - ); - - setSettingsStateValue(newValue); + const clamp = (value: number, min: number, max: number): number => { + return Math.min(Math.max(value, min), max); }; - const onStepDown = (): void => { - const valueRoundedToScale = Math.floor(value / step) * step; + const onStep = ( + roundingOperation: 'ceil' | 'floor', + stepOperation: (a: number, b: number) => number + ): void => { + const valueRoundedToScale = Math[roundingOperation](value / step) * step; const calculatedValue = - valueRoundedToScale === value ? value - step : valueRoundedToScale; - const newValue = limitValueByCondition( - calculatedValue, - minValue, - calculatedValue <= minValue, - disableStepDown - ); + valueRoundedToScale === value + ? stepOperation(value, step) + : valueRoundedToScale; + const newValue = clamp(calculatedValue, minValue, maxValue); setSettingsStateValue(newValue); }; - const limitValueByCondition = ( - calculatedValue: number, - limitedValue: number, - condition: boolean, - onConditionTrue: () => void, - onConditionFalse = enableButtons - ): number => { - if (condition) { - onConditionTrue(); - return limitedValue; - } else { - onConditionFalse(); - return calculatedValue; - } - }; - - const enableButtons = (): void => { - setStepUpDisabled(false); - setStepDownDisabled(false); - }; - - const disableStepUp = (): void => { - setStepUpDisabled(true); + const onStepUp = (): void => { + onStep('ceil', (a: number, b: number) => a + b); }; - const disableStepDown = (): void => { - setStepDownDisabled(true); + const onStepDown = (): void => { + onStep('floor', (a: number, b: number) => a - b); }; const onUserInput = (event: React.ChangeEvent): void => { @@ -86,34 +52,14 @@ const SettingsStepInput: React.FC = ( const number = Number(eventValue); if (!isNaN(number) && number !== value) { - let newValue; - if (number > value) { - newValue = limitValueByCondition( - number, - maxValue, - number >= maxValue, - disableStepUp - ); - } else { - newValue = limitValueByCondition( - number, - minValue, - number <= minValue, - disableStepDown - ); - } + const newValue = clamp(number, minValue, maxValue); setSettingsStateValue(newValue); } }; - // the component does not unmount when we close the settings dialog - // in theia which necessitates the below useEffect - React.useEffect(() => { - if (value > minValue && value < maxValue) { - enableButtons(); - } - }, [value, minValue, maxValue]); + const upDisabled = value >= maxValue; + const downDisabled = value <= minValue; return (
@@ -127,14 +73,14 @@ const SettingsStepInput: React.FC = (