From 4c5f8a6aa55f52e70f3181b06967e5351695c731 Mon Sep 17 00:00:00 2001
From: Jan T <jans.tuomi@gmail.com>
Date: Wed, 28 Feb 2024 17:57:55 +0200
Subject: 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 <sebastien@castiel.me>
---
 src/components/expense-form.tsx | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

(limited to 'src/components/expense-form.tsx')

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({
             <FormField
               control={form.control}
               name="amount"
-              render={({ field }) => (
+              render={({ field: { onChange, ...field } }) => (
                 <FormItem className="sm:order-3">
                   <FormLabel>Amount</FormLabel>
                   <div className="flex items-baseline gap-2">
                     <span>{group.currency}</span>
                     <FormControl>
                       <Input
+                        {...field}
                         className="text-base max-w-[120px]"
-                        type="number"
+                        type="text"
                         inputMode="decimal"
                         step={0.01}
                         placeholder="0.00"
+                        onChange={(event) =>
+                          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,
                                                 ),
-- 
cgit v1.3

