Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
8866759
feat: update amounts/percentages split logic to match OD
ikevin127 Feb 6, 2026
29decf1
fix: prevent NaN in split amount fields when clearing input to negati…
ikevin127 Feb 6, 2026
bed3b8b
fix: split amounts do not auto redistribute after removing split
ikevin127 Feb 6, 2026
98ef3ae
fix: expense amount can be changed to higher than original and negati…
ikevin127 Feb 6, 2026
ff03d3b
chore: submodule sync - ready for review
ikevin127 Feb 6, 2026
15fa4a5
fix: agent review refactoring - ready for review
ikevin127 Feb 6, 2026
0b46b65
fix: address review comments
ikevin127 Feb 6, 2026
88dd9e9
Merge branch 'main' of https://github.com/Expensify/App into ikevin12…
ikevin127 Feb 6, 2026
069eb37
chore: prettier
ikevin127 Feb 7, 2026
cdeac7b
chore: submodule sync
ikevin127 Feb 7, 2026
0ba5f11
chore: typecheck - ready for review
ikevin127 Feb 7, 2026
104c37f
fix: split warning / error logic
ikevin127 Feb 10, 2026
247f69a
chore: submodule sync
ikevin127 Feb 10, 2026
862873c
Merge branch 'main' of https://github.com/Expensify/App into ikevin12…
ikevin127 Feb 11, 2026
627657a
chore: merge w/ main adjustments
ikevin127 Feb 11, 2026
e3d2215
chore: submodule sync
ikevin127 Feb 11, 2026
736d5fb
Merge branch 'main' of https://github.com/Expensify/App into ikevin12…
ikevin127 Feb 11, 2026
4d9f958
fix: resolve split differences
ikevin127 Feb 11, 2026
d971518
chore: submodule sync
ikevin127 Feb 11, 2026
f4b4caf
fix: isManuallyEdited edit splits
ikevin127 Feb 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/components/MoneyRequestAmountInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ type MoneyRequestAmountInputProps = {
/** Whether to allow flipping amount */
allowFlippingAmount?: boolean;

/** Whether to allow direct negative input (for split amounts where value is already negative) */
allowNegativeInput?: boolean;

/** The testID of the input. Used to locate this view in end-to-end tests. */
testID?: string;

Expand Down Expand Up @@ -162,6 +165,7 @@ function MoneyRequestAmountInput({
shouldWrapInputInContainer = true,
isNegative = false,
allowFlippingAmount = false,
allowNegativeInput = false,
toggleNegative,
clearNegative,
ref,
Expand Down Expand Up @@ -257,6 +261,7 @@ function MoneyRequestAmountInput({
autoGrowExtraSpace={autoGrowExtraSpace}
submitBehavior={submitBehavior}
allowFlippingAmount={allowFlippingAmount}
allowNegativeInput={allowNegativeInput}
toggleNegative={toggleNegative}
clearNegative={clearNegative}
onFocus={props.onFocus}
Expand Down
29 changes: 19 additions & 10 deletions src/components/NumberWithSymbolForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ type NumberWithSymbolFormProps = {
/** Whether to allow flipping amount */
allowFlippingAmount?: boolean;

/** Whether to allow direct negative input (for split amounts where value is already negative) */
allowNegativeInput?: boolean;

/** Whether the input is disabled or not */
disabled?: boolean;

Expand Down Expand Up @@ -144,6 +147,7 @@ function NumberWithSymbolForm({
shouldWrapInputInContainer = true,
isNegative = false,
allowFlippingAmount = false,
allowNegativeInput = false,
toggleNegative,
clearNegative,
ref,
Expand Down Expand Up @@ -218,11 +222,13 @@ function NumberWithSymbolForm({
const newNumberWithoutSpaces = stripSpacesFromAmount(newNumber);
const rawFinalNumber = newNumberWithoutSpaces.includes('.') ? stripCommaFromAmount(newNumberWithoutSpaces) : replaceCommasWithPeriod(newNumberWithoutSpaces);

const finalNumber = handleNegativeAmountFlipping(rawFinalNumber, allowFlippingAmount, toggleNegative);
// When allowNegativeInput is true, keep negative sign as-is (for split amounts)
// When allowFlippingAmount is true, strip the negative sign and call toggleNegative
const finalNumber = allowNegativeInput ? rawFinalNumber : handleNegativeAmountFlipping(rawFinalNumber, allowFlippingAmount, toggleNegative);

// Use a shallow copy of selection to trigger setSelection
// More info: https://github.com/Expensify/App/issues/16385
if (!validateAmount(finalNumber, decimals, maxLength)) {
if (!validateAmount(finalNumber, decimals, maxLength, allowNegativeInput)) {
setSelection((prevSelection) => ({...prevSelection}));
return;
}
Expand All @@ -242,7 +248,7 @@ function NumberWithSymbolForm({
});
onInputChange?.(strippedNumber);
},
[decimals, maxLength, onInputChange, allowFlippingAmount, toggleNegative],
[decimals, maxLength, onInputChange, allowFlippingAmount, toggleNegative, allowNegativeInput],
);

/**
Expand All @@ -253,11 +259,14 @@ function NumberWithSymbolForm({
// Remove spaces from the new number because Safari on iOS adds spaces when pasting a copied number
// More info: https://github.com/Expensify/App/issues/16974
const newNumberWithoutSpaces = stripSpacesFromAmount(text);
const replacedCommasNumber = handleNegativeAmountFlipping(replaceCommasWithPeriod(newNumberWithoutSpaces), allowFlippingAmount, toggleNegative);
// When allowNegativeInput is true, keep negative sign as-is
const replacedCommasNumber = allowNegativeInput
? replaceCommasWithPeriod(newNumberWithoutSpaces)
: handleNegativeAmountFlipping(replaceCommasWithPeriod(newNumberWithoutSpaces), allowFlippingAmount, toggleNegative);

const withLeadingZero = addLeadingZero(replacedCommasNumber);
const withLeadingZero = addLeadingZero(replacedCommasNumber, allowNegativeInput);

if (!validateAmount(withLeadingZero, decimals, maxLength)) {
if (!validateAmount(withLeadingZero, decimals, maxLength, allowNegativeInput)) {
setSelection((prevSelection) => ({...prevSelection}));
return;
}
Expand All @@ -280,7 +289,7 @@ function NumberWithSymbolForm({
// Modifies the number to match changed decimals.
useEffect(() => {
// If the number supports decimals, we can return
if (validateAmount(currentNumber, decimals, maxLength, allowFlippingAmount)) {
if (validateAmount(currentNumber, decimals, maxLength, allowNegativeInput || allowFlippingAmount)) {
return;
}

Expand All @@ -305,14 +314,14 @@ function NumberWithSymbolForm({
if (currentNumber.length > 0) {
const selectionStart = selection.start === selection.end ? selection.start - 1 : selection.start;
const newNumber = `${currentNumber.substring(0, selectionStart)}${currentNumber.substring(selection.end)}`;
setNewNumber(addLeadingZero(newNumber));
setNewNumber(addLeadingZero(newNumber, allowNegativeInput));
}
return;
}
const newNumber = addLeadingZero(`${currentNumber.substring(0, selection.start)}${key}${currentNumber.substring(selection.end)}`);
const newNumber = addLeadingZero(`${currentNumber.substring(0, selection.start)}${key}${currentNumber.substring(selection.end)}`, allowNegativeInput);
setNewNumber(newNumber);
},
[currentNumber, selection.start, selection.end, shouldUpdateSelection, setNewNumber],
[currentNumber, selection.start, selection.end, shouldUpdateSelection, setNewNumber, allowNegativeInput],
);

/**
Expand Down
12 changes: 11 additions & 1 deletion src/components/SelectionList/ListItem/SplitListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,17 @@ function SplitListItem<TItem extends ListItem>({

const formattedOriginalAmount = convertToDisplayStringWithoutCurrency(splitItem.originalAmount, splitItem.currency);

const onSplitExpenseValueChange = useCallback((value: string) => splitItem.onSplitExpenseValueChange(splitItem.transactionID, Number(value), splitItem.mode), [splitItem]);
const onSplitExpenseValueChange = useCallback(
(value: string) => {
const numericValue = Number(value);
// Skip update if value is just "-" or produces NaN (intermediate input state)
if (Number.isNaN(numericValue)) {
return;
}
splitItem.onSplitExpenseValueChange(splitItem.transactionID, numericValue, splitItem.mode);
},
[splitItem],
);

const inputRef = useRef<BaseTextInputRef | null>(null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ function SplitAmountInput({splitItem, formattedOriginalAmount, contentWidth, onS
shouldWrapInputInContainer={false}
onFocus={focusHandler}
onBlur={onInputBlur}
allowNegativeInput
/>
);
}
Expand Down
Loading
Loading