Improve amount input
This commit is contained in:
parent
3fe3e20f51
commit
8d72175e51
@ -9,6 +9,7 @@ import AddIcon from "@mui/icons-material/Add";
|
|||||||
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
|
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
|
||||||
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
|
||||||
import { MovementApi } from "../api/MovementsApi";
|
import { MovementApi } from "../api/MovementsApi";
|
||||||
|
import { AmountInput } from "./forms/AmountInput";
|
||||||
|
|
||||||
export function NewMovementWidget(p: {
|
export function NewMovementWidget(p: {
|
||||||
account: Account;
|
account: Account;
|
||||||
@ -85,13 +86,13 @@ export function NewMovementWidget(p: {
|
|||||||
size={ServerApi.Config.constraints.movement_label}
|
size={ServerApi.Config.constraints.movement_label}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TextInput
|
<AmountInput
|
||||||
editable
|
editable
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Amount"
|
placeholder="Amount"
|
||||||
style={{ flex: 1, maxWidth: "110px" }}
|
style={{ flex: 1, maxWidth: "110px" }}
|
||||||
value={Number.isNaN(amount) ? "-" : String(amount)}
|
value={amount}
|
||||||
onValueChange={(a) => setAmount(a === "-" ? NaN : Number(a))}
|
onValueChange={setAmount}
|
||||||
/>
|
/>
|
||||||
<Tooltip title="Add new movement">
|
<Tooltip title="Add new movement">
|
||||||
<IconButton onClick={submit}>
|
<IconButton onClick={submit}>
|
||||||
|
52
moneymgr_web/src/widgets/forms/AmountInput.tsx
Normal file
52
moneymgr_web/src/widgets/forms/AmountInput.tsx
Normal file
@ -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 (
|
||||||
|
<TextInput
|
||||||
|
{...p}
|
||||||
|
value={value}
|
||||||
|
onValueChange={(a) => {
|
||||||
|
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);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user