Repository navigation
NumberForm foundation 3: BigNumberPad primitive and layout composition #98171
Description
Sub-issue of #97970.
Migration plan: jmgraa comment.
Last foundation issue. It adds the number pad primitive, composes every primitive through NumberForm across all four layout combinations, and rewires NumberWithSymbolForm to delegate to that composition.
Scope
- Step: 3 of the migration plan
- Scope: 1 new primitive, layout composition,
NumberWithSymbolFormbecomes an adapter
Target API
<NumberForm value={amount} onInputChange={handleAmount}>
<NumberForm.Input symbol="$" position="prefix" />
<NumberForm.FlipButton />
<NumberForm.CurrencyButton currency="USD" onPress={handleCurrency} />
<NumberForm.BigNumberPad onNumberPressed={handleNumber} />
</NumberForm>NumberForm.BigNumberPad wraps the existing src/components/BigNumberPad.tsx rather than reimplementing it.
Layouts to cover
Four combinations, currently spread across three early return paths in src/components/NumberWithSymbolForm.tsx:
- portrait, touch
- portrait, non touch
- landscape, touch
- landscape, non touch
Duplication being collapsed:
BigNumberPadis rendered twice, at lines 686 (landscape) and 785 (portrait), with identical props. The landscape branch also has a redundant doubleshouldShowBigNumberPad ?check at lines 680 and 685.- The ref fanout closure is duplicated verbatim at lines 551-559 and 587-595.
- Lines 581 to 635 build a shared
textInputComponentwith roughly 35 props, used by the landscape and portrait paths but not bydisplayAsTextInput.
Correction to step 3 of the migration plan
The plan says step 3 should "Remove the remaining duplicated layout/button paths from the old component". Do not do that literally. NumberWithSymbolForm stays in use until the cleanup issue #98178, and roughly 30 files depend on it transitively through AmountForm, MoneyRequestAmountInput and MoneyRequestAmountForm. Gutting its layout paths here breaks all of them.
Instead: rewrite NumberWithSymbolForm as a thin adapter that renders the NumberForm composition internally. Its public props and its ref keep working unchanged, the duplicated layout and button code disappears, and no call site has to move yet. Deletion happens in #98178, after every consumer migrates.
Out of scope
- Marking anything
@deprecated, and the migration guide — #98172 - Any call site change
- Deleting
NumberWithSymbolForm, its props types or its story — #98178
Acceptance criteria
-
NumberForm.BigNumberPadwrapssrc/components/BigNumberPad.tsx -
NumberFormcomposes correctly in portrait and landscape, touch and non touch -
NumberWithSymbolFormrenders theNumberFormcomposition internally and keeps its current public props and ref - No duplicated pad, button,
FormHelpMessageor ref fanout code remains inNumberWithSymbolForm - Pad and layout tests ship with this PR
- The tests from #98168 still pass with no edits, which is the proof the adapter is behaviour preserving
- Spot check the three heaviest screens by hand: the IOU amount page, the manual distance page and the confirmation list amount field, in both orientations
- Verify that no errors appear in the JS console
Activity
melvin-bot commentedon Sep 2, 2026
This issue has not been updated in over 15 days. @mountiny, @bernhardoj, @jmgraa eroding to Monthly issue.
P.S. Is everyone reading this sure this is really a near-term priority? Be brave: if you disagree, go ahead and close it out. If someone disagrees, they'll reopen it, and if they don't: one less thing to do!
melvin-bot commentedon Oct 15, 2026
@bernhardoj
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.9-4 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue:
melvin-bot commentedon Oct 23, 2026
@bernhardoj
The solution for this issue has been 🚀 deployed to production 🚀 in version 9.5.18-1 and is now subject to a 7-day regression period 📆. Here is the list of pull requests that resolve this issue: