@@ -3,6 +3,7 @@ import CheckboxInput from "./CheckboxInput.jsx";
33import ColorInput from "./ColorInput.jsx" ;
44import SelectInput from "./SelectInput.jsx" ;
55import useTranslation from "../../hooks/useTranslation.ts" ;
6+ import { useState } from "react" ;
67
78interface FieldConfig {
89 name : string ;
@@ -24,6 +25,9 @@ interface Props {
2425export default function DynamicInputs ( { config, values, onChange } : Props ) {
2526 const { t, meta } = useTranslation ( ) ;
2627 const isCompleted = meta ?. completed || false ;
28+ const [ lastValidValues , setLastValidValues ] =
29+ useState < Record < string , string | number | boolean > > ( values ) ;
30+
2731 return (
2832 < div className = { `inputs-container ${ isCompleted ? "notranslate" : "" } ` } >
2933 { config . map ( ( field ) => {
@@ -63,23 +67,33 @@ export default function DynamicInputs({ config, values, onChange }: Props) {
6367 }
6468 // Only validate, don't convert to number yet
6569 const isValidNumber = / ^ \d * \. ? \d * $ / . test ( rawValue ) ;
66-
6770 if ( isValidNumber ) {
6871 // Store as string to preserve formatting like "5.0"
6972 onChange ( field . name , rawValue ) ;
7073 }
7174 } }
7275 onBlur = { ( ) => {
73- const currentValue = val ;
76+ const currentValue = values [ field . name ] ;
77+
7478 if (
7579 typeof currentValue === "string" &&
7680 currentValue !== "" &&
7781 currentValue !== "."
7882 ) {
7983 const num = Number ( currentValue ) ;
84+
8085 if ( ! isNaN ( num ) ) {
81- onChange ( field . name , num ) ;
86+ const newValue = num ;
87+ onChange ( field . name , newValue ) ;
88+ //commit as last valid value
89+ setLastValidValues ( ( prev ) => ( {
90+ ...prev ,
91+ [ field . name ] : newValue ,
92+ } ) ) ;
8293 }
94+ } else {
95+ //revert if invalid
96+ onChange ( field . name , lastValidValues [ field . name ] ) ;
8397 }
8498 } }
8599 />
0 commit comments