From 0dc5c280604acbcf613750ba491c0ecb0902f76a Mon Sep 17 00:00:00 2001 From: Manuel Friedli Date: Sat, 11 Jan 2025 01:11:46 +0100 Subject: [PATCH] #11: Fix ID input. --- src/app/input-form.tsx | 12 ++--- src/app/validating-input-bigint-field.tsx | 60 +++++++++++++++++++++++ tsconfig.json | 2 +- 3 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 src/app/validating-input-bigint-field.tsx diff --git a/src/app/input-form.tsx b/src/app/input-form.tsx index bed9b76..ef2729e 100644 --- a/src/app/input-form.tsx +++ b/src/app/input-form.tsx @@ -10,6 +10,7 @@ import { import styles from "./input-form.module.css"; import "./input-form.css"; import {State} from "@/app/state/state.ts"; +import ValidatingInputBigIntField from "@/app/validating-input-bigint-field.tsx"; export default function InputForm({state, dispatch}: { state: State, @@ -17,7 +18,7 @@ export default function InputForm({state, dispatch}: { }) { const [width, setWidth] = useState(10); const [height, setHeight] = useState(10); - const [id, setId] = useState(); + const [id, setId] = useState(); const [algorithm, setAlgorithm] = useState('wilson'); const handleSubmit = (e: FormEvent) => { @@ -54,15 +55,14 @@ export default function InputForm({state, dispatch}: { value: numberValue }; }; - const validateIdInput: ValidatorFunction = value => { + const validateIdInput: ValidatorFunction = value => { if ("" === value) { return { valid: true }; } - const numberValue = Number(value); - // FIXME doesn't handle strings with characters correctly (e.g. "asdf" yields an empty value, due to "type=number"). - if (isNaN(numberValue) || Math.floor(numberValue) !== numberValue) { + const numberValue = BigInt(value); + if (numberValue.toString() !== value.trim()) { return { valid: false, message: "Must be empty or an integer" @@ -96,7 +96,7 @@ export default function InputForm({state, dispatch}: { disabled={state.loading} onChange={setHeight} /> - { + return {valid: true, value: BigInt(value)}; + }, + disabled = false, + onChange = () => { + } + }: + { + id: string; + label: string; + value?: bigint; + constraints?: { min?: bigint; max?: bigint; }; + validatorFn: ValidatorFunction; + disabled: boolean; + onChange: (v: bigint) => void; + }) { + const [error, setError] = useState(); + + const handleValueChange: ChangeEventHandler = (e) => { + const value = e.target.value; + const validation = validatorFn(value); + if (!validation.valid) { + setError(validation.message); + } else { + setError(undefined); + } + if (validation.value !== undefined) { + onChange(validation.value); + } + }; + return ( + <> + + + {error} + + ); +} + +export interface Validation { + valid: boolean; + message?: string; + value?: T; +} + +export type ValidatorFunction = (v: I) => Validation; diff --git a/tsconfig.json b/tsconfig.json index ef36eec..b953079 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2017", + "target": "ES2020", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "allowImportingTsExtensions": true, -- 2.45.2