Disable autocorrect on international bank account form inputs#89533
Conversation
… text inputs
iOS autocorrect silently modifies structured financial data (account numbers,
IFSC codes, SWIFT codes) in the international deposit account forms. This adds
autoCorrect={false} and spellCheck={false} to TextInput fields across all five
affected bank form pages, applied conditionally so non-text components
(ValuePicker, AddressSearch, PushRowWithModal) are unaffected.
Co-authored-by: truph01 <truph01@users.noreply.github.com>
…l props Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
Fixed the failing ESLint check: replaced prop spreading ( Note: The |
Codecov Report✅ Changes either increased or maintained existing code coverage, great job!
|
|
The failing ESLint check is unrelated to this PR's changes. Failure: Evidence: This PR only modifies bank account form pages ( The other failing check ( |
|
@MelvinBot Merge main and mark this PR as ready for review |
…isableAutocorrectOnBankForms Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
Merged main and marked this PR as ready for review. |
|
@codex review |
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@MelvinBot Please update the test steps in your checklist: |
|
Updated the Tests and QA Steps sections with the provided test steps. |
Reviewer Checklist
Screenshots/VideosAndroid: HybridAppScreen.Recording.2026-05-08.at.15.32.05.movAndroid: mWeb ChromeScreen.Recording.2026-05-08.at.15.33.02.moviOS: HybridAppScreen.Recording.2026-05-08.at.15.02.08.moviOS: mWeb SafariScreen.Recording.2026-05-08.at.15.06.22.movMacOS: Chrome / Safari |
|
@MelvinBot Please merge main |
…rectOnBankForms Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
🤖 Merged |
| country: '', | ||
| }} | ||
| forwardedFSClass={CONST.FULLSTORY.CLASS.MASK} | ||
| autoCorrect={InputComponent === TextInput ? false : undefined} |
There was a problem hiding this comment.
❌ CONSISTENCY-3 (docs)
Same duplicated block of autoCorrect, spellCheck, autoComplete, autoCapitalize props as in the other 4 files in this PR. Extract into a shared helper to avoid maintaining the same logic in 5 places. See the comment on AccountHolderDetails.tsx for a suggested approach.
Reviewed at: e7efd62 | Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
There was a problem hiding this comment.
Done — now uses the shared getTextInputAutocorrectProps helper.
| lng: '', | ||
| }} | ||
| forwardedFSClass={CONST.FULLSTORY.CLASS.MASK} | ||
| autoCorrect={InputComponent === TextInput ? false : undefined} |
There was a problem hiding this comment.
❌ CONSISTENCY-3 (docs)
Same duplicated block of autoCorrect, spellCheck, autoComplete, autoCapitalize props as in the other 4 files in this PR. Extract into a shared helper to avoid maintaining the same logic in 5 places. See the comment on AccountHolderDetails.tsx for a suggested approach.
Reviewed at: e7efd62 | Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
There was a problem hiding this comment.
Done — now uses the shared getTextInputAutocorrectProps helper.
| items={(field.valueSet ?? []).map(({id, text}) => ({value: id, label: text}))} | ||
| shouldSaveDraft={!isEditing} | ||
| forwardedFSClass={CONST.FULLSTORY.CLASS.MASK} | ||
| autoCorrect={!isValuePicker ? false : undefined} |
There was a problem hiding this comment.
❌ CONSISTENCY-3 (docs)
Same duplicated block of autoCorrect, spellCheck, autoComplete, autoCapitalize props as in the other 4 files in this PR. Extract into a shared helper to avoid maintaining the same logic in 5 places. Note that this file uses !isValuePicker instead of InputComponent === TextInput, but the intent is identical. See the comment on AccountHolderDetails.tsx for a suggested approach.
Reviewed at: e7efd62 | Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
There was a problem hiding this comment.
Done — now uses the shared getTextInputAutocorrectProps helper.
| lng: '', | ||
| }} | ||
| forwardedFSClass={CONST.FULLSTORY.CLASS.MASK} | ||
| autoCorrect={InputComponent === TextInput ? false : undefined} |
There was a problem hiding this comment.
❌ CONSISTENCY-3 (docs)
Same duplicated block of autoCorrect, spellCheck, autoComplete, autoCapitalize props as in the other 4 files in this PR. Extract into a shared helper to avoid maintaining the same logic in 5 places. See the comment on AccountHolderDetails.tsx for a suggested approach.
Reviewed at: e7efd62 | Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.
There was a problem hiding this comment.
Done — now uses the shared getTextInputAutocorrectProps helper.
|
@MelvinBot Please resolve the above comments |
Create getTextInputAutocorrectProps utility to eliminate duplication of autoCorrect, spellCheck, autoComplete, and autoCapitalize props across 5 form files. Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
| */ | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| function getTextInputAutocorrectProps(InputComponent: React.ComponentType<any>): Record<string, unknown> { | ||
| if (InputComponent !== TextInput) { |
There was a problem hiding this comment.
| if (InputComponent !== TextInput) { | |
| if (inputComponent !== TextInput) { |
There was a problem hiding this comment.
Done — renamed to inputComponent (lowercase).
| ); | ||
| } | ||
|
|
||
| const InputComponent = getInputComponent(field); |
There was a problem hiding this comment.
| const InputComponent = getInputComponent(field); | |
| const inputComponent = getInputComponent(field); |
| return getInputForValueSet(field, SafeString(defaultValues[field.id as keyof typeof defaultValues]), isEditing, styles); | ||
| } | ||
|
|
||
| const InputComponent = getInputComponent(field); |
There was a problem hiding this comment.
| const InputComponent = getInputComponent(field); | |
| const inputComponent = getInputComponent(field); |
| </View> | ||
| ))} | ||
| .map((field, index) => { | ||
| const InputComponent = getInputComponent(field); |
There was a problem hiding this comment.
| const InputComponent = getInputComponent(field); | |
| const inputComponent = getInputComponent(field); |
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| function getTextInputAutocorrectProps(InputComponent: React.ComponentType<any>): Record<string, unknown> { |
There was a problem hiding this comment.
Can we make the type a TextInput here so we get compile time errors if we pass anything else, and get rid of the if below?
Then in src/pages/settings/Wallet/InternationalDepositAccount/subPages/BankAccountDetails.tsx we can do something like
{...isValuePicker ? {} : getTextInputAutocorrectProps(TextInput)}There was a problem hiding this comment.
Done — changed the parameter type to typeof TextInput, removed the if guard, and moved the conditional to call sites. In BankAccountDetails.tsx (wallet) it's now {...isValuePicker ? {} : getTextInputAutocorrectProps(TextInput)} as you suggested.
|
@MelvinBot Please resolve all above comments |
…elCase - Accept only typeof TextInput and remove runtime if-check - Move conditional logic to call sites - Rename InputComponent to inputComponent Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
@MelvinBot Please fix the eslint check |
…rops Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
Fixed the ESLint failure: changed |
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| function getTextInputAutocorrectProps(inputComponent: typeof TextInput) { |
There was a problem hiding this comment.
@truph01 did you review these latest changes Melvin made? I don't think we want this
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | |
| function getTextInputAutocorrectProps(inputComponent: typeof TextInput) { | |
| function getTextInputAutocorrectProps() { |
There was a problem hiding this comment.
@MelvinBot I think we don't need this comment:
The typed parameter ensures compile-time errors if a
* non-TextInput component is passed.
There was a problem hiding this comment.
Done — removed that sentence from the JSDoc.
There was a problem hiding this comment.
If so, we need to removed inputComponent: typeof TextInput as well @MelvinBot
There was a problem hiding this comment.
Done — removed the inputComponent: typeof TextInput parameter (along with the unused-vars eslint-disable and TextInput type import in the helper). Updated all 5 call sites to call getTextInputAutocorrectProps() with no argument.
Co-authored-by: truph01 <truph01@users.noreply.github.com>
Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
🚧 @cead22 has triggered a test Expensify/App build. You can view the workflow run here. |
|
🧪🧪 Use the links below to test this adhoc build on Android, iOS, and Web. Happy testing! 🧪🧪
|
|
🚀 Deployed to staging by https://github.com/cead22 in version: 9.3.90-0 🚀
Bundle Size Analysis (Sentry): |
|
🤖 No help site changes are required for this PR, so I have not created a docs draft PR. Why: This change is a behind-the-scenes input fix — it disables native autocorrect, spellcheck, autocomplete, and autocapitalize on the Help articles under @truph01, please confirm you agree no help site updates are needed. If you believe a specific article should call out this behavior, point me to it and I'll draft the update. |
|
🚀 Deployed to production by https://github.com/lakchote in version: 9.3.90-3 🚀
|
Explanation of Change
iOS autocorrect is enabled by default on native
TextInputfields. For structured financial data like account numbers, IFSC codes, and SWIFT/BIC codes, autocorrect silently modifies values (e.g., "Whats" → "What's") after step-level validation has passed. The corrupted values then reach the Corpay API, which rejects them with no clear indication of what went wrong.This PR adds
autoCorrect={false}andspellCheck={false}toTextInputfields in all five international bank account form pages. The props are applied conditionally so that non-text-input components (ValuePicker,AddressSearch,PushRowWithModal) are unaffected.Affected pages:
BankAccountDetails.tsx(personal wallet flow)BankInformation.tsx(personal wallet flow)AccountHolderInformation.tsx(personal wallet flow)NonUSD/BankInfo/subSteps/BankAccountDetails.tsx(workspace flow)NonUSD/BankInfo/subSteps/AccountHolderDetails.tsx(workspace flow)Fixed Issues
$ #84811
PROPOSAL: #84811 (comment)
Tests
Offline tests
N/A — this change only disables iOS autocorrect/spellcheck on input fields and does not affect network behavior.
QA Steps
PR Author Checklist
### Fixed Issuessection aboveTestssectionOffline stepssectionQA stepssectiontoggleReportand notonIconClick)src/languages/*files and using the translation methodSTYLE.md) were followedAvatar, I verified the components usingAvatarare working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG))npm run compress-svg)Avataris modified, I verified thatAvataris working as expected in all cases)Designlabel and/or tagged@Expensify/designso the design team can review the changes.ScrollViewcomponent to make it scrollable when more elements are added to the page.mainbranch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTeststeps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari