Browse Source

adding logic to handle when shift key is pressed

namnguyen 11 months ago
parent
commit
a6c8464adf
2 changed files with 66 additions and 3 deletions
  1. 54 3
      frontend/taipy-gui/src/components/Taipy/Input.tsx
  2. 12 0
      taipy/gui/viselements.json

+ 54 - 3
frontend/taipy-gui/src/components/Taipy/Input.tsx

@@ -11,9 +11,11 @@
  * specific language governing permissions and limitations under the License.
  */
 
-import React, {useState, useEffect, useCallback, useRef, KeyboardEvent} from "react";
+import React, {useState, useEffect, useCallback, useRef, KeyboardEvent, useMemo} from "react";
 import TextField from "@mui/material/TextField";
 import Tooltip from "@mui/material/Tooltip";
+import {styled} from '@mui/material/styles';
+import IconButton from "@mui/material/IconButton";
 
 import {createSendActionNameAction, createSendUpdateAction} from "../../context/taipyReducers";
 import {TaipyInputProps} from "./utils";
@@ -21,6 +23,15 @@ import {useClassNames, useDispatch, useDynamicProperty, useModule} from "../../u
 
 const AUTHORIZED_KEYS = ["Enter", "Escape", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12"];
 
+const StyledTextField = styled(TextField)({
+    '& input[type=number]::-webkit-outer-spin-button, & input[type=number]::-webkit-inner-spin-button': {
+        display: 'none',
+    },
+    '& input[type=number]': {
+        '-moz-appearance': 'textfield',
+    },
+});
+
 const getActionKeys = (keys?: string): string[] => {
     const ak = (
         keys
@@ -101,6 +112,29 @@ const Input = (props: TaipyInputProps) => {
         [actionKeys, props.step, props.stepMultiplier, changeDelay, onAction, dispatch, id, module, updateVarName, onChange, propagate]
     );
 
+    const roundBasedOnStep = useMemo(() => {
+        const stepString = (props.step || 1).toString();
+        const decimalPlaces = stepString.includes('.') ? stepString.split('.')[1].length : 0;
+        const multiplier = Math.pow(10, decimalPlaces);
+        return (value: number) => Math.round(value * multiplier) / multiplier;
+    }, [props.step]);
+
+    const handleUpStepperMouseDown = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
+        if (event.shiftKey) {
+            setValue(prevValue => roundBasedOnStep(Number(prevValue) + (props.step || 1) * (props.stepMultiplier || 10)).toString());
+        } else {
+            setValue(prevValue => roundBasedOnStep(Number(prevValue) + (props.step || 1)).toString())
+        }
+    }, [props.step, props.stepMultiplier, roundBasedOnStep])
+
+    const handleDownStepperMouseDown = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {
+        if (event.shiftKey) {
+            setValue(prevValue => roundBasedOnStep(Number(prevValue) - (props.step || 1) * (props.stepMultiplier || 10)).toString());
+        } else {
+            setValue(prevValue => roundBasedOnStep(Number(prevValue) - (props.step || 1)).toString())
+        }
+    }, [props.step, props.stepMultiplier, roundBasedOnStep])
+
     useEffect(() => {
         if (props.value !== undefined) {
             setValue(props.value);
@@ -109,7 +143,7 @@ const Input = (props: TaipyInputProps) => {
 
     return (
         <Tooltip title={hover || ""}>
-            <TextField
+            <StyledTextField
                 margin="dense"
                 hiddenLabel
                 value={value}
@@ -119,9 +153,26 @@ const Input = (props: TaipyInputProps) => {
                 inputProps={{
                     step: props.step ? props.step : 1,
                 }}
+                InputProps={{
+                    endAdornment: (
+                        <>
+                            <IconButton
+                                size="small"
+                                onMouseDown={handleUpStepperMouseDown}
+                            >
+                                ▲
+                            </IconButton>
+                            <IconButton
+                                size="small"
+                                onMouseDown={handleDownStepperMouseDown}
+                            >
+                                ▼
+                            </IconButton>
+                        </>
+                    ),
+                }}
                 label={props.label}
                 onChange={handleInput}
-                onClick={handleClick}
                 disabled={!active}
                 onKeyDown={handleAction}
                 multiline={multiline}

+ 12 - 0
taipy/gui/viselements.json

@@ -133,6 +133,18 @@
                         "type": "str",
                         "default_value": "None",
                         "doc": "The label associated with the input."
+                    },
+                    {
+                        "name": "step",
+                        "type": "int|float",
+                        "default_value": "1",
+                        "doc": "The amount that the value changes on each increment or decrement."
+                    },
+                    {
+                        "name": "step_multiplier",
+                        "type": "int|float",
+                        "default_value": "10",
+                        "doc": "The amount that the value changes on each increment or decrement when the shift key is pressed."
                     }
                 ]
             }