labyrinth-frontend/src/app/validating-input-bigint-field.tsx

60 lines
2.6 KiB
TypeScript

import React, {ChangeEventHandler, useState} from 'react';
export default function ValidatingInputBigIntField({
id,
label,
value = 0n,
constraints = undefined,
validatorFn = (value) => {
return {valid: true, value: BigInt(value)};
},
disabled = false,
onChange = () => {
}
}:
{
id: string;
label: string;
value?: bigint;
constraints?: { min?: bigint; max?: bigint; };
validatorFn: ValidatorFunction<string, bigint>;
disabled: boolean;
onChange: (v: bigint) => void;
}) {
const [error, setError] = useState<string>();
const handleValueChange: ChangeEventHandler<HTMLInputElement> = (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 (
<>
<label htmlFor={id}>{label}: </label>
<input id={id}
type={"number"}
onChange={handleValueChange}
value={value?.toString() || ""}
min={constraints?.min?.toString()}
max={constraints?.max?.toString()}
disabled={disabled}
/>
<span>{error}</span>
</>
);
}
export interface Validation<T> {
valid: boolean;
message?: string;
value?: T;
}
export type ValidatorFunction<I, T> = (v: I) => Validation<T>;