From 8d72175e5116cfc11b984709c1ddbbe53132e711 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Mon, 21 Apr 2025 16:31:38 +0200 Subject: [PATCH] Improve amount input --- .../src/widgets/NewMovementWidget.tsx | 7 +-- .../src/widgets/forms/AmountInput.tsx | 52 +++++++++++++++++++ 2 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 moneymgr_web/src/widgets/forms/AmountInput.tsx diff --git a/moneymgr_web/src/widgets/NewMovementWidget.tsx b/moneymgr_web/src/widgets/NewMovementWidget.tsx index 23e714c..a10c6fc 100644 --- a/moneymgr_web/src/widgets/NewMovementWidget.tsx +++ b/moneymgr_web/src/widgets/NewMovementWidget.tsx @@ -9,6 +9,7 @@ import AddIcon from "@mui/icons-material/Add"; import { useSnackbar } from "../hooks/context_providers/SnackbarProvider"; import { useAlert } from "../hooks/context_providers/AlertDialogProvider"; import { MovementApi } from "../api/MovementsApi"; +import { AmountInput } from "./forms/AmountInput"; export function NewMovementWidget(p: { account: Account; @@ -85,13 +86,13 @@ export function NewMovementWidget(p: { size={ServerApi.Config.constraints.movement_label} />   - setAmount(a === "-" ? NaN : Number(a))} + value={amount} + onValueChange={setAmount} /> diff --git a/moneymgr_web/src/widgets/forms/AmountInput.tsx b/moneymgr_web/src/widgets/forms/AmountInput.tsx new file mode 100644 index 0000000..0c813cf --- /dev/null +++ b/moneymgr_web/src/widgets/forms/AmountInput.tsx @@ -0,0 +1,52 @@ +import React from "react"; +import { TextInput } from "./TextInput"; + +enum InputState { + Normal, + StartNeg, + StartDecimal, +} + +export function AmountInput(p: { + editable: boolean; + type: string; + placeholder: string; + style: React.CSSProperties; + value: number; + onValueChange: (val: number) => {}; +}): React.ReactElement { + const [state, setState] = React.useState(InputState.Normal); + + let value = ""; + + if (state === InputState.StartNeg) { + value = "-"; + } else if (state === InputState.StartDecimal) { + value = String(p.value) + "."; + } else if (!Number.isNaN(p.value)) { + value = String(p.value); + } + + return ( + { + if (a === "-") return setState(InputState.StartNeg); + + if (a?.endsWith(".")) { + setState(InputState.StartDecimal); + } else if (state !== InputState.Normal) { + setState(InputState.Normal); + } + const parsed = Number(a); + + // Empty field + if (a?.length === 0) p.onValueChange(NaN); + // Input number + else if ((a?.length ?? 0 > 0) && !Number.isNaN(parsed)) + p.onValueChange(parsed); + }} + /> + ); +}