This is an automated email from the ASF dual-hosted git repository.

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git


The following commit(s) were added to refs/heads/master by this push:
     new ac2f56b  fix(ui): allow typing decimal values in number inputs
ac2f56b is described below

commit ac2f56b45ac34401a0db49cdf3a9387d19de9261
Author: Yang Luo <[email protected]>
AuthorDate: Fri Sep 4 00:15:49 2026 +0800

    fix(ui): allow typing decimal values in number inputs
---
 web/src/components/shared/number-input.tsx | 30 +++++++++++++++++++++++++-----
 1 file changed, 25 insertions(+), 5 deletions(-)

diff --git a/web/src/components/shared/number-input.tsx 
b/web/src/components/shared/number-input.tsx
index a9c0dec..3d7c991 100644
--- a/web/src/components/shared/number-input.tsx
+++ b/web/src/components/shared/number-input.tsx
@@ -44,20 +44,40 @@ const NumberInput = React.forwardRef<HTMLInputElement, 
NumberInputProps>(functio
     return result;
   };
 
+  // Tracks the raw text so a partial value like "9." survives the keystroke
+  // instead of being reformatted back to "9" by the controlled `value` prop.
+  const [text, setText] = React.useState(value === null || value === undefined 
? "" : String(value));
+  const lastEmitted = React.useRef(value);
+  React.useEffect(() => {
+    if (value !== lastEmitted.current) {
+      setText(value === null || value === undefined ? "" : String(value));
+      lastEmitted.current = value;
+    }
+  }, [value]);
+
   const field = (
     <Input
       ref={ref}
       type="number"
+      step="any"
       min={min}
       max={max}
-      value={value ?? ""}
+      value={text}
       onChange={event => {
-        const parsed = parseInt(event.target.value, 10);
-        onChange(isNaN(parsed) ? 0 : parsed);
+        const raw = event.target.value;
+        setText(raw);
+        const parsed = parseFloat(raw);
+        if (!isNaN(parsed)) {
+          lastEmitted.current = parsed;
+          onChange(parsed);
+        }
       }}
       onBlur={event => {
-        const parsed = parseInt(event.target.value, 10);
-        onChange(clamp(isNaN(parsed) ? 0 : parsed));
+        const parsed = parseFloat(event.target.value);
+        const result = clamp(isNaN(parsed) ? 0 : parsed);
+        lastEmitted.current = result;
+        setText(String(result));
+        onChange(result);
       }}
       className={cn(
         "tabular-nums [appearance:textfield] 
[&::-webkit-inner-spin-button]:appearance-none 
[&::-webkit-outer-spin-button]:appearance-none",


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to