Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"i18next": "^24.2.3",
"lottie-react": "^2.4.1",
"motion": "^12.0.3",
"numora-react": "^3.0.2",
"qrcode.react": "^4.2.0",
"react": "=19.2.0",
"react-dom": "=19.2.0",
Expand Down
88 changes: 0 additions & 88 deletions apps/frontend/src/components/NumericInput/helpers.ts

This file was deleted.

32 changes: 14 additions & 18 deletions apps/frontend/src/components/NumericInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NumoraInput } from "numora-react";
import { ChangeEvent, useEffect, useRef } from "react";
import { UseFormRegisterReturn, useFormContext, useWatch } from "react-hook-form";
import { cn } from "../../helpers/cn";
import { handleOnChangeNumericInput, handleOnPasteNumericInput, trimToMaxDecimals } from "./helpers";

interface NumericInputProps {
register: UseFormRegisterReturn;
Expand All @@ -15,6 +15,11 @@ interface NumericInputProps {
onChange?: (e: ChangeEvent) => void;
}

function trimToMaxDecimals(value: string, maxDecimals: number): string {
const [integer, decimal] = value.split(".");
return decimal ? `${integer}.${decimal.slice(0, maxDecimals)}` : value;
}

export const NumericInput = ({
register,
readOnly = false,
Expand All @@ -30,21 +35,19 @@ export const NumericInput = ({
const inputValue = useWatch({ name: fieldName });
const prevMaxDecimals = useRef(maxDecimals);

function handleOnChange(e: ChangeEvent<HTMLInputElement>): void {
handleOnChangeNumericInput(e, maxDecimals);
function handleChange(e: ChangeEvent<HTMLInputElement>): void {
const value = e.target.value;
setValue(fieldName, value, { shouldDirty: true, shouldValidate: true });
if (onChange) onChange(e);
register.onChange(e);
if (onChange) onChange(e);
}

// Watch for maxDecimals changes and trim value if needed
useEffect(() => {
if (prevMaxDecimals.current > maxDecimals) {
if (prevMaxDecimals.current > maxDecimals && inputValue) {
const trimmed = trimToMaxDecimals(inputValue, maxDecimals);
if (trimmed !== inputValue) {
setValue(fieldName, trimmed, { shouldDirty: true, shouldValidate: true });
// Create a synthetic event for register.onChange
const syntheticEvent = { target: { value: trimmed } } as ChangeEvent<HTMLInputElement>;
register.onChange(syntheticEvent);
}
Expand All @@ -54,8 +57,7 @@ export const NumericInput = ({

return (
<div className="relative flex-grow">
<input
{...register}
<NumoraInput
autoCapitalize="none"
autoComplete="off"
autoCorrect="off"
Expand All @@ -66,21 +68,15 @@ export const NumericInput = ({
disabled && "opacity-0"
)}
disabled={disabled}
inputMode="decimal"
minLength={1}
onChange={handleOnChange}
onPaste={event => handleOnPasteNumericInput(event, maxDecimals)}
pattern="^[0-9]*[.,]?[0-9]*$"
maxDecimals={maxDecimals}
name={fieldName}
onChange={handleChange}
placeholder="0.0"
readOnly={readOnly}
spellCheck={false}
step="any"
type="text"
value={inputValue ?? ""}
/>
{loading && (
<span className="-translate-y-1/2 loading loading-bars loading-sm absolute top-1/2 right-3 text-primary"></span>
)}
{loading && <span className="-translate-y-1/2 loading loading-bars loading-sm absolute top-1/2 right-3 text-primary" />}
</div>
);
};
3 changes: 3 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading