Skip to content

Commit ff749cc

Browse files
authored
feat(deposit): fix android dob input; improve autofill UX (#17001)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until the template has been completely filled out, and PR status checks have passed at least once. --> ## **Description** - Fixes android DOB - Adds next-input focusing when using autofill https://github.com/user-attachments/assets/42c6b82d-2991-4d0a-91d4-fa3324db49a5 https://github.com/user-attachments/assets/07628bc0-15df-4351-9431-b82ae6f9a228 https://github.com/user-attachments/assets/659c36d5-6ee6-4f75-b8f0-110977be646e https://github.com/user-attachments/assets/54b1b442-da31-4d70-b6af-0c1b4523915b <!-- Write a short description of the changes included in this pull request, also include relevant motivation and context. Have in mind the following questions: 1. What is the reason for the change? 2. What is the improvement/solution? --> ## **Changelog** <!-- If this PR is not End-User-Facing and should not show up in the CHANGELOG, you can choose to either: 1. Write `CHANGELOG entry: null` 2. Label with `no-changelog` If this PR is End-User-Facing, please write a short User-Facing description in the past tense like: `CHANGELOG entry: Added a new tab for users to see their NFTs` `CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker` (This helps the Release Engineer do their job more quickly and accurately) --> CHANGELOG entry: ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I’ve followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] I’ve applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.
1 parent 75f4426 commit ff749cc

File tree

6 files changed

+65
-12
lines changed

6 files changed

+65
-12
lines changed

app/components/UI/Ramp/Deposit/Views/BasicInfo/BasicInfo.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ describe('BasicInfo Component', () => {
9999
screen.getByPlaceholderText('XXX-XX-XXXX'),
100100
'123456789',
101101
);
102+
fireEvent.changeText(screen.getByTestId('ssn-input'), '123456789');
102103
expect(screen.toJSON()).toMatchSnapshot();
103104
fireEvent.press(screen.getByRole('button', { name: 'Continue' }));
104105

app/components/UI/Ramp/Deposit/Views/BasicInfo/BasicInfo.tsx

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,28 @@ const BasicInfo = (): JSX.Element => {
127127
}
128128
}, [navigation, validateFormData, formData, quote, kycUrl]);
129129

130-
const handleSubmitEditing = useCallback(
130+
const focusNextField = useCallback(
131131
(nextRef: React.RefObject<TextInput>) => () => {
132132
nextRef.current?.focus();
133133
},
134134
[],
135135
);
136136

137+
const handleFieldChange = useCallback(
138+
(field: keyof BasicInfoFormData, nextAction?: () => void) =>
139+
(value: string) => {
140+
const currentValue = formData[field];
141+
const isAutofill = value.length - currentValue.length > 1;
142+
143+
handleFormDataChange(field)(value);
144+
145+
if (isAutofill && nextAction) {
146+
nextAction();
147+
}
148+
},
149+
[formData, handleFormDataChange],
150+
);
151+
137152
return (
138153
<ScreenLayout>
139154
<ScreenLayout.Body>
@@ -152,7 +167,10 @@ const BasicInfo = (): JSX.Element => {
152167
label={strings('deposit.basic_info.first_name')}
153168
placeholder="John"
154169
value={formData.firstName}
155-
onChangeText={handleFormDataChange('firstName')}
170+
onChangeText={handleFieldChange(
171+
'firstName',
172+
focusNextField(lastNameInputRef),
173+
)}
156174
error={errors.firstName}
157175
returnKeyType="next"
158176
testID="first-name-input"
@@ -161,14 +179,17 @@ const BasicInfo = (): JSX.Element => {
161179
autoComplete="given-name"
162180
textContentType="givenName"
163181
autoCapitalize="words"
164-
onSubmitEditing={handleSubmitEditing(lastNameInputRef)}
182+
onSubmitEditing={focusNextField(lastNameInputRef)}
165183
/>
166184

167185
<DepositTextField
168186
label={strings('deposit.basic_info.last_name')}
169187
placeholder="Smith"
170188
value={formData.lastName}
171-
onChangeText={handleFormDataChange('lastName')}
189+
onChangeText={handleFieldChange(
190+
'lastName',
191+
focusNextField(phoneInputRef),
192+
)}
172193
error={errors.lastName}
173194
returnKeyType="next"
174195
testID="last-name-input"
@@ -177,27 +198,36 @@ const BasicInfo = (): JSX.Element => {
177198
autoComplete="family-name"
178199
textContentType="familyName"
179200
autoCapitalize="words"
180-
onSubmitEditing={handleSubmitEditing(phoneInputRef)}
201+
onSubmitEditing={focusNextField(phoneInputRef)}
181202
/>
182203
</View>
183204

184205
<DepositPhoneField
185206
label={strings('deposit.basic_info.phone_number')}
186207
value={formData.mobileNumber}
187-
onChangeText={handleFormDataChange('mobileNumber')}
208+
onChangeText={handleFieldChange(
209+
'mobileNumber',
210+
focusNextField(dateInputRef),
211+
)}
188212
error={errors.mobileNumber}
189213
ref={phoneInputRef}
190-
onSubmitEditing={handleSubmitEditing(dateInputRef)}
214+
onSubmitEditing={focusNextField(dateInputRef)}
191215
/>
192216

193217
<DepositDateField
194218
label={strings('deposit.basic_info.date_of_birth')}
195219
value={formData.dob}
196-
onChangeText={handleFormDataChange('dob')}
220+
onChangeText={handleFieldChange('dob', () => {
221+
if (selectedRegion?.isoCode === 'US') {
222+
focusNextField(ssnInputRef)();
223+
} else {
224+
Keyboard.dismiss();
225+
}
226+
})}
197227
error={errors.dob}
198228
onSubmitEditing={() => {
199229
if (selectedRegion?.isoCode === 'US') {
200-
handleSubmitEditing(ssnInputRef)();
230+
focusNextField(ssnInputRef)();
201231
} else {
202232
Keyboard.dismiss();
203233
}
@@ -212,7 +242,7 @@ const BasicInfo = (): JSX.Element => {
212242
label={strings('deposit.basic_info.social_security_number')}
213243
placeholder="XXX-XX-XXXX"
214244
value={formData.ssn}
215-
onChangeText={handleFormDataChange('ssn')}
245+
onChangeText={handleFieldChange('ssn')}
216246
error={errors.ssn}
217247
returnKeyType="done"
218248
testID="ssn-input"
@@ -224,7 +254,6 @@ const BasicInfo = (): JSX.Element => {
224254
maxLength={11}
225255
onSubmitEditing={() => {
226256
Keyboard.dismiss();
227-
handleOnPressContinue();
228257
}}
229258
/>
230259
)}

app/components/UI/Ramp/Deposit/Views/BasicInfo/__snapshots__/BasicInfo.test.tsx.snap

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,7 @@ exports[`BasicInfo Component navigates to address page when form is valid and co
908908
}
909909
}
910910
testID="deposit-phone-field-test-id"
911+
textContentType="telephoneNumber"
911912
value="(234) 567-890"
912913
/>
913914
</View>
@@ -2220,6 +2221,7 @@ exports[`BasicInfo Component render matches snapshot 1`] = `
22202221
}
22212222
}
22222223
testID="deposit-phone-field-test-id"
2224+
textContentType="telephoneNumber"
22232225
value=""
22242226
/>
22252227
</View>
@@ -3562,6 +3564,7 @@ exports[`BasicInfo Component snapshot matches validation errors when continue is
35623564
}
35633565
}
35643566
testID="deposit-phone-field-test-id"
3567+
textContentType="telephoneNumber"
35653568
value=""
35663569
/>
35673570
</View>

app/components/UI/Ramp/Deposit/components/DepositDateField/DepositDateField.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ const formatDateForValue = (date: Date): string => {
3535
};
3636

3737
const getValidDate = (dateString: string): Date => {
38+
const dateRegex = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
39+
const match = dateString.match(dateRegex);
40+
41+
if (match) {
42+
const [, month, day, year] = match;
43+
const date = new Date(parseInt(year), parseInt(month) - 1, parseInt(day));
44+
return isNaN(date.getTime()) ? DEFAULT_DATE : date;
45+
}
46+
3847
const date = new Date(dateString);
3948
return isNaN(date.getTime()) ? DEFAULT_DATE : date;
4049
};
@@ -97,7 +106,6 @@ const DepositDateField = forwardRef<TextInput, DepositDateFieldProps>(
97106
) => {
98107
const { styles, theme } = useStyles(styleSheet, {});
99108
const [showDatePicker, setShowDatePicker] = useState(false);
100-
// staging state for iOS date selection
101109
const [pendingDateSelection, setPendingDateSelection] =
102110
useState<Date | null>(null);
103111
const fieldRef = useRef<TextInput>(null);
@@ -120,6 +128,7 @@ const DepositDateField = forwardRef<TextInput, DepositDateFieldProps>(
120128

121129
const preventModalDismissal = () => {
122130
// Prevents touch events from bubbling up to the outer TouchableWithoutFeedback
131+
// This is a workaround to prevent the modal from being dismissed when the user taps on the date picker
123132
};
124133

125134
return (

app/components/UI/Ramp/Deposit/components/DepositPhoneField/DepositPhoneField.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ const DepositPhoneField = forwardRef<TextInput, PhoneFieldProps>(
113113
strings('deposit.basic_info.enter_phone_number')
114114
}
115115
keyboardType="phone-pad"
116+
textContentType="telephoneNumber"
116117
startAccessory={countryPrefixAccessory}
117118
onSubmitEditing={onSubmitEditing}
118119
ref={ref}

app/components/UI/Ramp/Deposit/components/DepositPhoneField/__snapshots__/DepositPhoneField.test.tsx.snap

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ exports[`DepositPhoneField renders correctly after flag button press 1`] = `
127127
}
128128
}
129129
testID="deposit-phone-field-test-id"
130+
textContentType="telephoneNumber"
130131
value=""
131132
/>
132133
</View>
@@ -261,6 +262,7 @@ exports[`DepositPhoneField renders correctly after input change 1`] = `
261262
}
262263
}
263264
testID="deposit-phone-field-test-id"
265+
textContentType="telephoneNumber"
264266
value=""
265267
/>
266268
</View>
@@ -395,6 +397,7 @@ exports[`DepositPhoneField renders correctly with default props 1`] = `
395397
}
396398
}
397399
testID="deposit-phone-field-test-id"
400+
textContentType="telephoneNumber"
398401
value=""
399402
/>
400403
</View>
@@ -529,6 +532,7 @@ exports[`DepositPhoneField renders correctly with different region 1`] = `
529532
}
530533
}
531534
testID="deposit-phone-field-test-id"
535+
textContentType="telephoneNumber"
532536
value=""
533537
/>
534538
</View>
@@ -663,6 +667,7 @@ exports[`DepositPhoneField renders correctly with error message 1`] = `
663667
}
664668
}
665669
testID="deposit-phone-field-test-id"
670+
textContentType="telephoneNumber"
666671
value=""
667672
/>
668673
</View>
@@ -812,6 +817,7 @@ exports[`DepositPhoneField renders correctly with long phone number 1`] = `
812817
}
813818
}
814819
testID="deposit-phone-field-test-id"
820+
textContentType="telephoneNumber"
815821
value="155512345678901234"
816822
/>
817823
</View>
@@ -947,6 +953,7 @@ exports[`DepositPhoneField renders correctly with onSubmitEditing callback 1`] =
947953
}
948954
}
949955
testID="deposit-phone-field-test-id"
956+
textContentType="telephoneNumber"
950957
value=""
951958
/>
952959
</View>
@@ -1081,6 +1088,7 @@ exports[`DepositPhoneField renders correctly with special characters in phone nu
10811088
}
10821089
}
10831090
testID="deposit-phone-field-test-id"
1091+
textContentType="telephoneNumber"
10841092
value="15551234567"
10851093
/>
10861094
</View>
@@ -1215,6 +1223,7 @@ exports[`DepositPhoneField renders correctly with unsupported region 1`] = `
12151223
}
12161224
}
12171225
testID="deposit-phone-field-test-id"
1226+
textContentType="telephoneNumber"
12181227
value=""
12191228
/>
12201229
</View>
@@ -1349,6 +1358,7 @@ exports[`DepositPhoneField renders correctly with value 1`] = `
13491358
}
13501359
}
13511360
testID="deposit-phone-field-test-id"
1361+
textContentType="telephoneNumber"
13521362
value="(555) 123-4567"
13531363
/>
13541364
</View>

0 commit comments

Comments
 (0)