Disable autocorrect on international bank account form inputs#89533
Disable autocorrect on international bank account form inputs#89533MelvinBot wants to merge 10 commits into
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 |
|
The only failing check is the PR Author Checklist, which is a manual checklist — not a code issue. All other checks are either passing or still pending (tests, typecheck, perf tests, Storybook, builds). There are no code-related check failures to fix. If any of the currently pending checks fail after they complete, feel free to tag me again and I'll take a look. |
@MelvinBot In android native and android chrome, I am still able to see the autocorrect |
…pression
autoCorrect={false} alone is insufficient on Android:
- Android Chrome ignores the non-standard HTML autocorrect attribute;
autoComplete='off' targets the standard HTML autocomplete attribute
that Chrome respects.
- Android keyboards (Gboard) tie text prediction to capitalization;
autoCapitalize='none' helps suppress suggestions on native Android.
Co-authored-by: truph01 <truph01@users.noreply.github.com>
|
The
Please re-test on Android native and Android Chrome.
|
|
MelvinBot has made 5 consecutive commits trying to fix CI failures. Automatic CI fix dispatches are now paused for this PR. Next steps: A human should review the recent commits and resolve the conflicting CI errors manually. |
|
@MelvinBot Please update test case to include this note:
|
|
🤖 Updated the PR description — added the Android keyboard note to both the Tests and QA Steps sections. |
| }} | ||
| hint={field.id === ACCOUNT_HOLDER_NAME ? translate('bankInfoStep.accountHolderNameDescription') : undefined} | ||
| forwardedFSClass={CONST.FULLSTORY.CLASS.MASK} | ||
| autoCorrect={InputComponent === TextInput ? false : undefined} |
There was a problem hiding this comment.
❌ CONSISTENCY-3 (docs)
The same block of 4 props (autoCorrect, spellCheck, autoComplete, autoCapitalize) with identical conditional logic (InputComponent === TextInput ? value : undefined) is duplicated across 5 files in this PR. This duplicated pattern should be extracted into a shared helper.
Consider creating a utility function that returns these props conditionally:
// e.g., in a shared utils file
function getTextInputAutoProps(InputComponent: React.ComponentType) {
if (InputComponent !== TextInput) {
return {};
}
return {
autoCorrect: false,
spellCheck: false,
autoComplete: 'off' as const,
autoCapitalize: 'none' as const,
};
}Then spread it in each usage:
{...getTextInputAutoProps(InputComponent)}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 — extracted into a shared getTextInputAutocorrectProps helper in src/libs/getTextInputAutocorrectProps.ts. All 5 files now spread the result of this helper instead of duplicating the 4 props inline.
| 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>
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