diff --git a/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx b/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx index e09e5c2563ebdf7c0cadfc684ff18917abdee86a..62593477e15141ac8874fb9e0b26b1d7ec39cbf4 100644 --- a/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx +++ b/packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx @@ -342,7 +342,7 @@ const ChildTransactionEdit = forwardRef( value={amountToInteger(transaction.amount)} zeroSign={amountSign} style={{ marginRight: 8 }} - textStyle={{ ...styles.smallText, textAlign: 'right' }} + inputStyle={{ ...styles.smallText, textAlign: 'right' }} onFocus={() => onRequestActiveEdit(getFieldName(transaction.id, 'amount')) } diff --git a/packages/desktop-client/src/components/modals/HoldBufferModal.tsx b/packages/desktop-client/src/components/modals/HoldBufferModal.tsx index 93304923ad7028f8f2366601136a24a349a992ab..976f1948e6956d7cc95030e14e1a52a06d7bc31d 100644 --- a/packages/desktop-client/src/components/modals/HoldBufferModal.tsx +++ b/packages/desktop-client/src/components/modals/HoldBufferModal.tsx @@ -1,17 +1,16 @@ import React, { useState } from 'react'; import { rolloverBudget } from 'loot-core/client/queries'; -import { evalArithmetic } from 'loot-core/shared/arithmetic'; -import { amountToInteger, integerToCurrency } from 'loot-core/shared/util'; import { styles } from '../../style'; import { Button } from '../common/Button'; import { InitialFocus } from '../common/InitialFocus'; import { Modal } from '../common/Modal'; import { View } from '../common/View'; -import { FieldLabel, InputField } from '../mobile/MobileForms'; +import { FieldLabel } from '../mobile/MobileForms'; import { type CommonModalProps } from '../Modals'; import { useSheetValue } from '../spreadsheet/useSheetValue'; +import { AmountInput } from '../util/AmountInput'; type HoldBufferModalProps = { modalProps: CommonModalProps; @@ -24,13 +23,11 @@ export function HoldBufferModal({ onSubmit, }: HoldBufferModalProps) { const available = useSheetValue(rolloverBudget.toBudget); - const initialAmount = integerToCurrency(Math.max(available, 0)); - const [amount, setAmount] = useState<string | null>(null); + const [amount, setAmount] = useState<number>(0); - const _onSubmit = (newAmount: string | null) => { - const parsedAmount = evalArithmetic(newAmount || ''); - if (parsedAmount) { - onSubmit?.(amountToInteger(parsedAmount)); + const _onSubmit = (newAmount: number) => { + if (newAmount) { + onSubmit?.(newAmount); } modalProps.onClose(); @@ -46,10 +43,17 @@ export function HoldBufferModal({ <View> <FieldLabel title="Hold this amount:" /> <InitialFocus> - <InputField - inputMode="decimal" - defaultValue={initialAmount} - onUpdate={value => setAmount(value)} + <AmountInput + value={available} + autoDecimals={true} + style={{ + marginLeft: styles.mobileEditingPadding, + marginRight: styles.mobileEditingPadding, + }} + inputStyle={{ + height: styles.mobileMinHeight, + }} + onUpdate={setAmount} onEnter={() => _onSubmit(amount)} /> </InitialFocus> diff --git a/packages/desktop-client/src/components/modals/TransferModal.tsx b/packages/desktop-client/src/components/modals/TransferModal.tsx index 8b19a5dd5a4b82c68cf98e3239d3a464c4890ec5..5af37bb8b1204b4f750b814aeca458148e0da02d 100644 --- a/packages/desktop-client/src/components/modals/TransferModal.tsx +++ b/packages/desktop-client/src/components/modals/TransferModal.tsx @@ -2,8 +2,6 @@ import React, { useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; import { pushModal } from 'loot-core/client/actions'; -import { evalArithmetic } from 'loot-core/shared/arithmetic'; -import { amountToInteger, integerToCurrency } from 'loot-core/shared/util'; import { useCategories } from '../../hooks/useCategories'; import { styles } from '../../style'; @@ -12,8 +10,9 @@ import { Button } from '../common/Button'; import { InitialFocus } from '../common/InitialFocus'; import { Modal } from '../common/Modal'; import { View } from '../common/View'; -import { FieldLabel, InputField, TapField } from '../mobile/MobileForms'; +import { FieldLabel, TapField } from '../mobile/MobileForms'; import { type CommonModalProps } from '../Modals'; +import { AmountInput } from '../util/AmountInput'; type TransferModalProps = { modalProps: CommonModalProps; @@ -42,8 +41,7 @@ export function TransferModal({ return [expenseGroups, expenseCategories]; }, [originalCategoryGroups, showToBeBudgeted]); - const _initialAmount = integerToCurrency(Math.max(initialAmount, 0)); - const [amount, setAmount] = useState<string | null>(null); + const [amount, setAmount] = useState<number>(0); const [toCategoryId, setToCategoryId] = useState<string | null>(null); const dispatch = useDispatch(); @@ -60,10 +58,9 @@ export function TransferModal({ ); }; - const _onSubmit = (newAmount: string | null, categoryId: string | null) => { - const parsedAmount = evalArithmetic(newAmount || ''); - if (parsedAmount && categoryId) { - onSubmit?.(amountToInteger(parsedAmount), categoryId); + const _onSubmit = (newAmount: number, categoryId: string | null) => { + if (newAmount && categoryId) { + onSubmit?.(newAmount, categoryId); } modalProps.onClose(); @@ -77,10 +74,16 @@ export function TransferModal({ <View> <FieldLabel title="Transfer this amount:" /> <InitialFocus> - <InputField - inputMode="decimal" - tabIndex={0} - defaultValue={_initialAmount} + <AmountInput + value={initialAmount} + autoDecimals={true} + style={{ + marginLeft: styles.mobileEditingPadding, + marginRight: styles.mobileEditingPadding, + }} + inputStyle={{ + height: styles.mobileMinHeight, + }} onUpdate={setAmount} onEnter={() => { if (!toCategoryId) { diff --git a/packages/desktop-client/src/components/util/AmountInput.tsx b/packages/desktop-client/src/components/util/AmountInput.tsx index cde149e0c60e2c5f9e6829463162fc79e4f4a419..ae385f28fd901abe54f1a028ee36a7048331f539 100644 --- a/packages/desktop-client/src/components/util/AmountInput.tsx +++ b/packages/desktop-client/src/components/util/AmountInput.tsx @@ -5,6 +5,7 @@ import React, { useState, useEffect, type FocusEventHandler, + type KeyboardEventHandler, } from 'react'; import { evalArithmetic } from 'loot-core/src/shared/arithmetic'; @@ -27,9 +28,10 @@ type AmountInputProps = { onChangeValue?: (value: string) => void; onFocus?: FocusEventHandler<HTMLInputElement>; onBlur?: FocusEventHandler<HTMLInputElement>; + onEnter?: KeyboardEventHandler<HTMLInputElement>; onUpdate?: (amount: number) => void; style?: CSSProperties; - textStyle?: CSSProperties; + inputStyle?: CSSProperties; focused?: boolean; disabled?: boolean; autoDecimals?: boolean; @@ -44,8 +46,9 @@ export function AmountInput({ onBlur, onChangeValue, onUpdate, + onEnter, style, - textStyle, + inputStyle, focused, disabled = false, autoDecimals = false, @@ -120,7 +123,7 @@ export function AmountInput({ disabled={disabled} focused={focused} style={{ flex: 1, alignItems: 'stretch', ...style }} - inputStyle={{ paddingLeft: 0, ...textStyle }} + inputStyle={inputStyle} onKeyUp={e => { if (e.key === 'Enter') { fireUpdate(negative); @@ -129,6 +132,7 @@ export function AmountInput({ onChangeValue={onInputTextChange} onBlur={onInputAmountBlur} onFocus={onFocus} + onEnter={onEnter} /> ); } diff --git a/upcoming-release-notes/2837.md b/upcoming-release-notes/2837.md new file mode 100644 index 0000000000000000000000000000000000000000..1b50a27270fa6c078eea658e692fa892d0a9e919 --- /dev/null +++ b/upcoming-release-notes/2837.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [joel-jeremy] +--- + +Use AmountInput on mobile balance transfer and hold buffer modals to allow auto insertion of decimals in their amounts.