From f98f33442a737150cabffd6b968610e7fcaba91a Mon Sep 17 00:00:00 2001 From: weinibuliu Date: Sat, 21 Feb 2026 20:24:47 +0800 Subject: [PATCH] feat: number input --- .gitignore | 3 +++ src/components/FormControls.tsx | 28 ++++++++++++++++++++++++++-- src/components/OptionEditor.tsx | 4 ++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a547bf3..cc042f4 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ dist-ssr *.njsproj *.sln *.sw? + +# maafw +interface.json \ No newline at end of file diff --git a/src/components/FormControls.tsx b/src/components/FormControls.tsx index 0232a8d..6597c83 100644 --- a/src/components/FormControls.tsx +++ b/src/components/FormControls.tsx @@ -71,6 +71,10 @@ interface TextInputProps { disabled?: boolean; hasError?: boolean; className?: string; + type?: 'text' | 'number'; + inputMode?: React.HTMLAttributes['inputMode']; + step?: number; + integerOnly?: boolean; } export function TextInput({ @@ -80,14 +84,34 @@ export function TextInput({ disabled, hasError, className, + type = 'text', + inputMode, + step, + integerOnly, }: TextInputProps) { return ( onChange(e.target.value)} + onChange={(e) => { + if (!integerOnly) { + onChange(e.target.value); + return; + } + const raw = e.target.value; + if (raw === '' || raw === '-') { + onChange(raw); + return; + } + const cleaned = raw.replace(/[^\d-]/g, ''); + const hasLeadingMinus = cleaned.startsWith('-'); + const normalized = `${hasLeadingMinus ? '-' : ''}${cleaned.replace(/-/g, '')}`; + onChange(normalized); + }} placeholder={placeholder} disabled={disabled} + inputMode={inputMode} + step={step} className={clsx( 'px-3 py-1.5 text-sm rounded-md border', 'bg-bg-secondary text-text-primary', diff --git a/src/components/OptionEditor.tsx b/src/components/OptionEditor.tsx index 70f01f1..0cff63c 100644 --- a/src/components/OptionEditor.tsx +++ b/src/components/OptionEditor.tsx @@ -263,6 +263,10 @@ function InputField({ disabled={disabled} hasError={!!validationError} className="flex-1" + type={input.pipeline_type === 'int' ? 'number' : 'text'} + inputMode={input.pipeline_type === 'int' ? 'numeric' : undefined} + step={input.pipeline_type === 'int' ? 1 : undefined} + integerOnly={input.pipeline_type === 'int'} /> )}