Skip to content

Commit

Permalink
refactor: integer input
Browse files Browse the repository at this point in the history
  • Loading branch information
tien committed Nov 30, 2024
1 parent c6b5778 commit d1732d4
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 129 deletions.
51 changes: 51 additions & 0 deletions src/components/param/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,54 @@ export type ParamInput<T> = T | typeof INCOMPLETE | typeof INVALID;
export type ParamProps<T> = {
onChangeValue: (value: ParamInput<T>) => void;
};

export const integerPrimitives = {
i8: {
min: -128,
max: 127,
},
u8: {
min: 0,
max: 255,
},
i16: {
min: -32768,
max: 32767,
},
u16: {
min: 0,
max: 65535,
},
i32: {
min: -2147483648,
max: 2147483647,
},
u32: {
min: 0,
max: 4294967295,
},
i64: {
min: -9223372036854775808n,
max: 9223372036854775807n,
},
u64: {
min: 0,
max: 18446744073709551615n,
},
i128: {
min: -170141183460469231731687303715884105728n,
max: 170141183460469231731687303715884105727n,
},
u128: {
min: 0,
max: 340282366920938463463374607431768211455n,
},
i256: {
min: -57896044618658097711785492504343953926634992332820282019728792003956564819968n,
max: 57896044618658097711785492504343953926634992332820282019728792003956564819967n,
},
u256: {
min: 0,
max: 115792089237316195423570985008687907853269984665640564039457584007913129639935n,
},
} as const;
85 changes: 67 additions & 18 deletions src/components/param/compact.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Input } from "../ui/input";
import type { ParamProps } from "./common";
import { useEffect, useState } from "react";
import { Field } from "../ui/field";
import {
INCOMPLETE,
INVALID,
integerPrimitives,
type ParamProps,
} from "./common";
import { useEffect, useMemo, useState } from "react";

export type CompactParamProps = ParamProps<number | bigint> & {
compact: { codec: "compactNumber" | "compactBn" };
Expand All @@ -16,27 +21,71 @@ export function CompactParam({

const isBig = compact.codec === "compactBn";

const parsedValue = useMemo(() => {
if (value.trim() === "") {
return INCOMPLETE;
}

if (!isBig) {
const number = Number(value);

if (
Number.isNaN(number) ||
!Number.isFinite(number) ||
number < SMALL.min ||
number > SMALL.max
) {
return INVALID;
}

return number;
}

try {
const bn = BigInt(value);

if (bn < BIG.min || bn > BIG.max) {
return INVALID;
}

return bn;
} catch {
return INVALID;
}
}, [isBig, value]);

useEffect(
() => {
onChangeValue(isBig ? BigInt(value) : Number(value));
onChangeValue(parsedValue);
},
// eslint-disable-next-line react-hooks/exhaustive-deps
[value],
[parsedValue],
);

return (
<Input
type="number"
inputMode="numeric"
placeholder="Compact"
value={value}
min={
isBig
? "-57896044618658097711785492504343953926634992332820282019728792003956564819968"
: -2147483648
}
max={isBig ? "170141183460469231731687303715884105727" : 4294967295}
onChange={(event) => setValue(event.target.value)}
/>
<Field.Root
required={parsedValue === INCOMPLETE}
invalid={parsedValue === INVALID}
>
<Field.Input
type="number"
inputMode="numeric"
placeholder="Compact"
value={value}
min={isBig ? BIG.min.toString() : SMALL.min}
max={isBig ? BIG.max.toString() : SMALL.max}
onChange={(event) => setValue(event.target.value)}
/>
</Field.Root>
);
}

const SMALL = {
min: integerPrimitives.i32.min,
max: integerPrimitives.u32.max,
};

const BIG = {
min: integerPrimitives.i128.min,
max: integerPrimitives.u128.max,
};
Loading

0 comments on commit d1732d4

Please sign in to comment.