60 lines
2.6 KiB
TypeScript
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>;
|