From 4c5f8a6aa55f52e70f3181b06967e5351695c731 Mon Sep 17 00:00:00 2001 From: Jan T Date: Wed, 28 Feb 2024 17:57:55 +0200 Subject: [PATCH] Fix decimal separator issue in numeric form fields (#115) * Revert 5b65b8f, fix comma issue with type="text" and onChange * Fix comma issue in "paid for" input * Run prettier autoformat * Allow only digits and dots in currency inputs * Fix behaviour in paidFor field * Fix duplicated onChange prop --------- Co-authored-by: Sebastien Castiel --- src/components/expense-form.tsx | 25 +++++++++++++++++++++---- src/lib/schemas.ts | 3 +-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/components/expense-form.tsx b/src/components/expense-form.tsx index a13498d..84fe7c5 100644 --- a/src/components/expense-form.tsx +++ b/src/components/expense-form.tsx @@ -56,6 +56,17 @@ export type Props = { runtimeFeatureFlags: RuntimeFeatureFlags } +const enforceCurrencyPattern = (value: string) => + value + // replace first comma with # + .replace(/[.,]/, '#') + // remove all other commas + .replace(/[.,]/g, '') + // change back # to dot + .replace(/#/, '.') + // remove all non-numeric and non-dot characters + .replace(/[^\d.]/g, '') + export function ExpenseForm({ group, expense, @@ -210,18 +221,22 @@ export function ExpenseForm({ ( + render={({ field: { onChange, ...field } }) => ( Amount
{group.currency} + onChange(enforceCurrencyPattern(event.target.value)) + } onClick={(e) => e.currentTarget.select()} {...field} /> @@ -428,7 +443,7 @@ export function ExpenseForm({ ), )} className="text-base w-[80px] -my-2" - type="number" + type="text" disabled={ !field.value?.some( ({ participant }) => @@ -448,7 +463,9 @@ export function ExpenseForm({ ? { participant: id, shares: - event.target.value, + enforceCurrencyPattern( + event.target.value, + ), } : p, ), diff --git a/src/lib/schemas.ts b/src/lib/schemas.ts index d68adf4..52b0d0d 100644 --- a/src/lib/schemas.ts +++ b/src/lib/schemas.ts @@ -51,8 +51,7 @@ export const expenseFormSchema = z [ z.number(), z.string().transform((value, ctx) => { - const normalizedValue = value.replace(/,/g, '.') - const valueAsNumber = Number(normalizedValue) + const valueAsNumber = Number(value) if (Number.isNaN(valueAsNumber)) ctx.addIssue({ code: z.ZodIssueCode.custom,