Skip to content

Commit bb15712

Browse files
authored
feat: import SRP continue button and keyboard changes added (#24693)
<!-- 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** * Shift Continue button at the bottom of the screen. * Remove autoFocus when importSrp screen opens * Change checkmark icon to done in the keyboard and add keyboard dismiss event. * Jira: https://consensyssoftware.atlassian.net/browse/SL-454 <!-- 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: Import SRP screen UX improvements 1) **Existing Behaviour**: When the Import SRP screen opens, the keyboard opens automatically and focus is set on the SRPInputGrid. **New Behaviour**: When the Import SRP screen opens, the user sees the SRPInputGrid and the Continue button, and the keyboard opens only when the SRPInputGrid is tapped. 2) **Existing Behaviour**: Tapping the checkmark icon on the keyboard moves focus from one cell to the next in SRPInput. **New Behaviour**: The checkmark icon is replaced with a Done button, and tapping it dismisses the keyboard. ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Import SRP screen UX improvements Scenario: Keyboard does not auto-open on screen load Given the user navigates to Import from Secret Recovery Phrase screen Then the SRP input grid and Continue button should be visible And the keyboard should not be visible Scenario: Keyboard opens only when user taps SRP input Given the user is on the Import SRP screen with keyboard hidden When the user taps on a word input field Then the keyboard should open Scenario: Done button dismisses keyboard Given the user is entering words with keyboard visible When the user taps the Done button on keyboard Then the keyboard should be dismissed ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="327" height="681" alt="Screenshot 2026-01-16 at 12 01 27 PM" src="https://github.com/user-attachments/assets/c4481dd5-403b-4e64-a178-3b29c88c8e58" /> <!-- [screenshots/recordings] --> ### **After** https://github.com/user-attachments/assets/5315cb1c-733c-4236-989d-3aa52a62ef01 <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [x] 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). - [x] I've completed the PR template to the best of my ability - [x] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] 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. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > Updates SRP input UX and CTA placement. > > - Adds `autoFocus` prop to `SrpInputGrid` (default `true`); consuming screens pass `autoFocus={false}` > - Changes submit behavior: `onSubmitEditing` now dismisses the keyboard instead of creating/moving to a new input; removes enter-key advance logic > - Normalizes text input props (`returnKeyType="done"`, `blurOnSubmit={false}`, `enablesReturnKeyAutomatically={false}`) and adds submit handlers to textarea > - Moves “Continue”/“Import” buttons to a fixed bottom container with optional inline error text; updates styles and snapshots > - Adjusts tests to reflect keyboard dismissal, fixed footer CTA, and error rendering via `getAllByText` > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 45381fe. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent ebb48c4 commit bb15712

11 files changed

Lines changed: 180 additions & 118 deletions

File tree

app/components/UI/SrpInputGrid/SrpInputGrid.types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,10 @@ export interface SrpInputGridProps {
4848
* Callback when the current input word changes
4949
*/
5050
onCurrentWordChange?: (word: string) => void;
51+
52+
/**
53+
* Whether to auto focus the first input on mount
54+
* @default true
55+
*/
56+
autoFocus?: boolean;
5157
}

app/components/UI/SrpInputGrid/__snapshots__/index.test.tsx.snap

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ exports[`SrpInputGrid renders with custom uniqueId 1`] = `
9393
autoComplete="off"
9494
autoCorrect={false}
9595
autoFocus={false}
96+
blurOnSubmit={false}
9697
editable={true}
98+
enablesReturnKeyAutomatically={false}
9799
importantForAutofill="no"
98100
keyboardType="visible-password"
99101
onBlur={[Function]}
@@ -104,6 +106,7 @@ exports[`SrpInputGrid renders with custom uniqueId 1`] = `
104106
onSubmitEditing={[Function]}
105107
placeholder=""
106108
placeholderTextColor="#b7bbc8"
109+
returnKeyType="done"
107110
showSoftInputOnFocus={true}
108111
spellCheck={false}
109112
style={
@@ -187,7 +190,9 @@ exports[`SrpInputGrid renders with custom uniqueId 1`] = `
187190
autoComplete="off"
188191
autoCorrect={false}
189192
autoFocus={true}
193+
blurOnSubmit={false}
190194
editable={true}
195+
enablesReturnKeyAutomatically={false}
191196
importantForAutofill="no"
192197
keyboardType="visible-password"
193198
multiline={true}
@@ -196,8 +201,10 @@ exports[`SrpInputGrid renders with custom uniqueId 1`] = `
196201
onFocus={[Function]}
197202
onKeyPress={[Function]}
198203
onSelectionChange={[Function]}
204+
onSubmitEditing={[Function]}
199205
placeholder="Enter your Secret Recovery Phrase"
200206
placeholderTextColor="#686e7d"
207+
returnKeyType="done"
201208
showSoftInputOnFocus={true}
202209
spellCheck={false}
203210
style={
@@ -345,7 +352,9 @@ exports[`SrpInputGrid renders with disabled state 1`] = `
345352
autoComplete="off"
346353
autoCorrect={false}
347354
autoFocus={false}
355+
blurOnSubmit={false}
348356
editable={false}
357+
enablesReturnKeyAutomatically={false}
349358
importantForAutofill="no"
350359
keyboardType="visible-password"
351360
onBlur={[Function]}
@@ -356,6 +365,7 @@ exports[`SrpInputGrid renders with disabled state 1`] = `
356365
onSubmitEditing={[Function]}
357366
placeholder=""
358367
placeholderTextColor="#b7bbc8"
368+
returnKeyType="done"
359369
showSoftInputOnFocus={true}
360370
spellCheck={false}
361371
style={
@@ -439,7 +449,9 @@ exports[`SrpInputGrid renders with disabled state 1`] = `
439449
autoComplete="off"
440450
autoCorrect={false}
441451
autoFocus={true}
452+
blurOnSubmit={false}
442453
editable={false}
454+
enablesReturnKeyAutomatically={false}
443455
importantForAutofill="no"
444456
keyboardType="visible-password"
445457
multiline={true}
@@ -448,8 +460,10 @@ exports[`SrpInputGrid renders with disabled state 1`] = `
448460
onFocus={[Function]}
449461
onKeyPress={[Function]}
450462
onSelectionChange={[Function]}
463+
onSubmitEditing={[Function]}
451464
placeholder="Enter your Secret Recovery Phrase"
452465
placeholderTextColor="#686e7d"
466+
returnKeyType="done"
453467
showSoftInputOnFocus={true}
454468
spellCheck={false}
455469
style={
@@ -597,7 +611,9 @@ exports[`SrpInputGrid renders with empty seed phrase 1`] = `
597611
autoComplete="off"
598612
autoCorrect={false}
599613
autoFocus={false}
614+
blurOnSubmit={false}
600615
editable={true}
616+
enablesReturnKeyAutomatically={false}
601617
importantForAutofill="no"
602618
keyboardType="visible-password"
603619
onBlur={[Function]}
@@ -608,6 +624,7 @@ exports[`SrpInputGrid renders with empty seed phrase 1`] = `
608624
onSubmitEditing={[Function]}
609625
placeholder=""
610626
placeholderTextColor="#b7bbc8"
627+
returnKeyType="done"
611628
showSoftInputOnFocus={true}
612629
spellCheck={false}
613630
style={
@@ -691,7 +708,9 @@ exports[`SrpInputGrid renders with empty seed phrase 1`] = `
691708
autoComplete="off"
692709
autoCorrect={false}
693710
autoFocus={true}
711+
blurOnSubmit={false}
694712
editable={true}
713+
enablesReturnKeyAutomatically={false}
695714
importantForAutofill="no"
696715
keyboardType="visible-password"
697716
multiline={true}
@@ -700,8 +719,10 @@ exports[`SrpInputGrid renders with empty seed phrase 1`] = `
700719
onFocus={[Function]}
701720
onKeyPress={[Function]}
702721
onSelectionChange={[Function]}
722+
onSubmitEditing={[Function]}
703723
placeholder="Enter your Secret Recovery Phrase"
704724
placeholderTextColor="#686e7d"
725+
returnKeyType="done"
705726
showSoftInputOnFocus={true}
706727
spellCheck={false}
707728
style={
@@ -884,7 +905,9 @@ exports[`SrpInputGrid renders with multiple words 1`] = `
884905
autoComplete="off"
885906
autoCorrect={false}
886907
autoFocus={false}
908+
blurOnSubmit={false}
887909
editable={true}
910+
enablesReturnKeyAutomatically={false}
888911
importantForAutofill="no"
889912
keyboardType="visible-password"
890913
onBlur={[Function]}
@@ -895,6 +918,7 @@ exports[`SrpInputGrid renders with multiple words 1`] = `
895918
onSubmitEditing={[Function]}
896919
placeholder=""
897920
placeholderTextColor="#b7bbc8"
921+
returnKeyType="done"
898922
showSoftInputOnFocus={true}
899923
spellCheck={false}
900924
style={
@@ -1014,7 +1038,9 @@ exports[`SrpInputGrid renders with multiple words 1`] = `
10141038
autoComplete="off"
10151039
autoCorrect={false}
10161040
autoFocus={false}
1041+
blurOnSubmit={false}
10171042
editable={true}
1043+
enablesReturnKeyAutomatically={false}
10181044
importantForAutofill="no"
10191045
keyboardType="visible-password"
10201046
onBlur={[Function]}
@@ -1025,6 +1051,7 @@ exports[`SrpInputGrid renders with multiple words 1`] = `
10251051
onSubmitEditing={[Function]}
10261052
placeholder=""
10271053
placeholderTextColor="#b7bbc8"
1054+
returnKeyType="done"
10281055
showSoftInputOnFocus={true}
10291056
spellCheck={false}
10301057
style={
@@ -1144,7 +1171,9 @@ exports[`SrpInputGrid renders with multiple words 1`] = `
11441171
autoComplete="off"
11451172
autoCorrect={false}
11461173
autoFocus={false}
1174+
blurOnSubmit={false}
11471175
editable={true}
1176+
enablesReturnKeyAutomatically={false}
11481177
importantForAutofill="no"
11491178
keyboardType="visible-password"
11501179
onBlur={[Function]}
@@ -1155,6 +1184,7 @@ exports[`SrpInputGrid renders with multiple words 1`] = `
11551184
onSubmitEditing={[Function]}
11561185
placeholder=""
11571186
placeholderTextColor="#b7bbc8"
1187+
returnKeyType="done"
11581188
showSoftInputOnFocus={true}
11591189
spellCheck={false}
11601190
style={
@@ -1239,7 +1269,9 @@ exports[`SrpInputGrid renders with multiple words 1`] = `
12391269
autoComplete="off"
12401270
autoCorrect={false}
12411271
autoFocus={false}
1272+
blurOnSubmit={false}
12421273
editable={true}
1274+
enablesReturnKeyAutomatically={false}
12431275
importantForAutofill="no"
12441276
keyboardType="visible-password"
12451277
multiline={true}
@@ -1248,8 +1280,10 @@ exports[`SrpInputGrid renders with multiple words 1`] = `
12481280
onFocus={[Function]}
12491281
onKeyPress={[Function]}
12501282
onSelectionChange={[Function]}
1283+
onSubmitEditing={[Function]}
12511284
placeholder="Enter your Secret Recovery Phrase"
12521285
placeholderTextColor="#686e7d"
1286+
returnKeyType="done"
12531287
showSoftInputOnFocus={true}
12541288
spellCheck={false}
12551289
style={

app/components/UI/SrpInputGrid/index.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ describe('SrpInputGrid', () => {
133133
expect(mockOnSeedPhraseChange).toHaveBeenCalled();
134134
});
135135

136-
it('handles enter key press to move to next input', () => {
136+
it('dismisses keyboard on submit editing', () => {
137137
const seedPhrase = ['wallet', ''];
138138
const { getByTestId } = renderWithProvider(
139139
<SrpInputGrid {...defaultProps} seedPhrase={seedPhrase} />,

app/components/UI/SrpInputGrid/index.tsx

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ const SrpInputGrid = React.forwardRef<SrpInputGridRef, SrpInputGridProps>(
5858
uniqueId = uuidv4(),
5959
disabled = false,
6060
onCurrentWordChange,
61+
autoFocus: autoFocusProp = true,
6162
},
6263
ref,
6364
) => {
@@ -279,16 +280,6 @@ const SrpInputGrid = React.forwardRef<SrpInputGridRef, SrpInputGridProps>(
279280
[seedPhrase, onSeedPhraseChange],
280281
);
281282

282-
const handleEnterKeyPress = useCallback(
283-
(index: number) => {
284-
handleSeedPhraseChangeAtIndexRef.current(
285-
`${seedPhrase[index]}${SPACE_CHAR}`,
286-
index,
287-
);
288-
},
289-
[seedPhrase],
290-
);
291-
292283
// Validate seed phrase and show errors
293284
const error = useMemo(() => {
294285
const hasWordErrors = Object.values(errorWordIndexes).some(Boolean);
@@ -406,9 +397,7 @@ const SrpInputGrid = React.forwardRef<SrpInputGridRef, SrpInputGridProps>(
406397
? handleSeedPhraseChange(text)
407398
: handleSeedPhraseChangeAtIndex(text, index);
408399
}}
409-
onSubmitEditing={() => {
410-
handleEnterKeyPress(index);
411-
}}
400+
onSubmitEditing={() => Keyboard.dismiss()}
412401
placeholder=""
413402
placeholderTextColor={colors.text.muted}
414403
size={TextFieldSize.Md}
@@ -433,11 +422,17 @@ const SrpInputGrid = React.forwardRef<SrpInputGridRef, SrpInputGridProps>(
433422
autoCapitalize="none"
434423
testID={`${testIdPrefix}_${index}`}
435424
keyboardType="visible-password"
425+
returnKeyType="done"
426+
blurOnSubmit={false}
427+
enablesReturnKeyAutomatically={false}
436428
autoCorrect={false}
437429
textContentType="none"
438430
spellCheck={false}
439431
importantForAutofill="no"
440-
autoFocus={index === nextSeedPhraseInputFocusedIndex}
432+
autoFocus={
433+
index === nextSeedPhraseInputFocusedIndex &&
434+
(autoFocusProp || index > 0)
435+
}
441436
onKeyPress={(e) => handleKeyPress(e, index)}
442437
isDisabled={disabled}
443438
/>
@@ -472,11 +467,15 @@ const SrpInputGrid = React.forwardRef<SrpInputGridRef, SrpInputGridProps>(
472467
autoCapitalize="none"
473468
testID={testIdPrefix}
474469
keyboardType="visible-password"
470+
returnKeyType="done"
471+
blurOnSubmit={false}
472+
enablesReturnKeyAutomatically={false}
473+
onSubmitEditing={() => Keyboard.dismiss()}
475474
autoCorrect={false}
476475
textContentType="none"
477476
spellCheck={false}
478477
importantForAutofill="no"
479-
autoFocus={isFirstInput}
478+
autoFocus={autoFocusProp && isFirstInput}
480479
multiline
481480
onKeyPress={(e) => handleKeyPress(e, 0)}
482481
isDisabled={disabled}

0 commit comments

Comments
 (0)