Skip to content

refactor(card): migrate card onboarding screen header to HeaderStandard#30663

Merged
Brunonascdev merged 6 commits into
mainfrom
wsun/migrate-card-to-headerstandard
May 27, 2026
Merged

refactor(card): migrate card onboarding screen header to HeaderStandard#30663
Brunonascdev merged 6 commits into
mainfrom
wsun/migrate-card-to-headerstandard

Conversation

@weitingsun
Copy link
Copy Markdown
Contributor

@weitingsun weitingsun commented May 27, 2026

Description

Migrate Card onboarding screens from navigator-rendered headers to in-screen HeaderStandard (from @metamask/design-system-react-native).

Why: This is a prerequisite for migrating the Card navigation stack from @react-navigation/stack (JS stack) to @react-navigation/native-stack. Native stack on iOS 26 / iPhone 17 Pro Max renders the system "liquid glass" navigation bar, which doesn't match the Card screens' flat bg-background-default and breaks visual consistency. By moving the header into each screen body, header styling becomes navigator-type-agnostic — the follow-up native-stack PR can then be a small, mechanical swap with no further header rework.

What changed:

  1. All 9 Card onboarding screens now hide the navigator header (headerShown: false, gestureEnabled: false) and render HeaderStandard in-screen via OnboardingStep.
  2. New useCardOnboardingNavigationHandlers hook centralizes the three header behaviors:
  • back — back arrow → goBack() (SignUp, ConfirmEmail, Complete)
  • close-with-confirmation — close (X) → exit-confirmation Alert → WALLET.HOME (SetPhoneNumber, ConfirmPhoneNumber, VerifyIdentity, PersonalDetails, PhysicalAddress)
  • close-direct — close (X) → straight to WALLET.HOME (VerifyingVeriffKYC)
  1. OnboardingNavigator simplified: removed cardDefaultNavigationOptions, PostEmailNavigationOptions, KYCStatusNavigationOptions, HeaderlessNavigationOptions factories. Replaced 11 per-screen options with a single shared screenOptions={{ headerShown: false, gestureEnabled: false }}.
  2. KYCFailed and KYCPending are unchanged — they already used the in-screen header pattern with their custom purple/dark backgrounds.
  3. The exit-onboarding-button testID is preserved on the close button (passed via closeButtonProps) so existing E2E selectors continue to work.
  4. Tests for the removed navigation-options factories were dropped; equivalent coverage now lives in useCardOnboardingNavigationHandlers.test.tsx.

Changelog

CHANGELOG entry: null

Related issues

Fixes:

Manual testing steps

Feature: Card Onboarding in-screen header
  Scenario: User taps back from SignUp / ConfirmEmail / Complete
    Given the user is on a Card Onboarding screen with a back-only header
    When user taps the back arrow in the header
    Then the user is returned to the previous screen
  
Scenario: User taps close from a post-email screen
    Given the user is on SetPhoneNumber, ConfirmPhoneNumber, VerifyIdentity, PersonalDetails, or PhysicalAddress
    When user taps the close (X) icon in the header
    Then an exit confirmation Alert is displayed
    When user taps the destructive "Exit" action in the Alert
    Then the user is navigated to Wallet Home
  
Scenario: User taps close on VerifyingVeriffKYC
    Given the user is on the VerifyingVeriffKYC screen
    When user taps the close (X) icon in the header
    Then the user is navigated directly to Wallet Home with no confirmation
  
Scenario: KYC status screens render their own header
    Given the user reaches KYCFailed or KYCPending
    Then the screen renders with its custom purple / dark header (unchanged from main)
  
Scenario: Returning user resumes onboarding
    Given the user has an in-progress onboarding session and returns to the Card flow
    When OnboardingNavigator mounts
    Then the "Keep going" modal is shown over the resolved initial route
  
Scenario: Header background matches screen background
    Given the user is on any Card Onboarding screen with HeaderStandard
    Then the header background matches the screen body (no glass / material navigation bar)
    And the back / close icons sit inside the screen body, not the navigator chrome

Screenshots/Recordings

Before

Card Before

After

Card Header After

Android test:

Screen_Recording_20260528_024042_MetaMask.mp4

Pre-merge author checklist

Performance checks (if applicable)

  • I've tested on Android
    • Ideally on a mid-range device; emulator is acceptable
  • I've tested with a power user scenario
    • Use these power-user SRPs to import wallets with many accounts and tokens
  • I've instrumented key operations with Sentry traces for production performance metrics

For performance guidelines and tooling, see the Performance Guide.

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.

Note

Low Risk
UI and navigation chrome refactor with preserved exit flows and E2E testIDs; no auth, payment, or data-model changes.

Overview
Card onboarding moves header chrome from the stack navigator into each screen via OnboardingStep and design-system HeaderStandard, so headers match the flat onboarding background and are ready for a future native-stack swap.

OnboardingNavigator drops per-screen header factories (PostEmailNavigationOptions, KYCStatusNavigationOptions, etc.) in favor of shared headerShown: false / gestureEnabled: false. A new useCardOnboardingNavigationHandlers hook centralizes back, close with exit alert → wallet home, and close direct → wallet home; each step passes a headerMode. The exit-onboarding-button testID is kept on close actions. Navigator option tests were removed in favor of hook unit tests; sticky-step layout no longer sets a fixed iOS keyboardVerticalOffset.

Reviewed by Cursor Bugbot for commit f6623ab. Bugbot is set up for automated code reviews on this repo. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbotv2 metamaskbotv2 Bot added the team-mobile-platform Mobile Platform team label May 27, 2026
@weitingsun weitingsun marked this pull request as ready for review May 27, 2026 18:01
@weitingsun weitingsun requested a review from a team as a code owner May 27, 2026 18:01
style={tw.style('flex-1 bg-background-default')}
edges={['bottom']}
>
{renderHeader()}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed keyboardVerticalOffset causes iOS keyboard overlap

Medium Severity

The keyboardVerticalOffset prop was removed from KeyboardAvoidingView in the stickyActions branch, but the in-screen HeaderStandard (with includesTopInset) now occupies similar vertical space above it that the old navigator header did. The KeyboardAvoidingView defaults to offset 0, so on iOS it will over-compensate by the full header height (~90px), pushing sticky action buttons too high when the keyboard opens. Affects SetPhoneNumber, ConfirmPhoneNumber, and ConfirmEmail screens.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f270e45. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It matches the behaviour on main:
my branch
Simulator Screenshot - iPhone 16 - 2026-05-27 at 12 36 11

main
Simulator Screenshot - iPhone 16 - 2026-05-27 at 12 37 20

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f869685. Configure here.

Comment thread app/components/UI/Card/routes/OnboardingNavigator.test.tsx
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokeMoney
  • Selected Performance tags: None (no tests recommended)
  • Risk Level: medium
  • AI Confidence: 90%
click to see 🤖 AI reasoning details

E2E Test Selection:
All 15 changed files are exclusively within the MetaMask Card onboarding flow (app/components/UI/Card/). The changes represent a UI/navigation architecture refactor:

  1. OnboardingNavigator.tsx: Removed per-screen navigator-level header options (PostEmailNavigationOptions, KYCStatusNavigationOptions, HeaderlessNavigationOptions) and replaced with a single onboardingScreenOptions with headerShown: false. Headers are now owned by individual screens.

  2. OnboardingStep.tsx: Added headerMode prop and HeaderStandard component integration via the new useCardOnboardingNavigationHandlers hook. Also removed keyboardVerticalOffset from KeyboardAvoidingView.

  3. useCardOnboardingNavigationHandlers.ts: New hook centralizing navigation handlers (back, close-with-confirmation, close-direct) for Card onboarding screens.

  4. Individual onboarding screens (9 files): Each now passes a specific headerMode to OnboardingStep - e.g., SignUp/ConfirmEmail/Complete use 'back', SetPhoneNumber/ConfirmPhoneNumber/PersonalDetails/PhysicalAddress/VerifyIdentity use 'close-with-confirmation', VerifyingVeriffKYC uses 'close-direct'.

The exit-onboarding-button testID is preserved in the new hook, maintaining backward compatibility with any existing tests. The changes are scoped entirely to the Card onboarding UI and do not touch core Engine, controllers, shared navigation, or other wallet features. SmokeMoney is the appropriate tag as it covers Card flows including onboarding.

Performance Test Selection:
The changes are a UI/navigation architecture refactor within the Card onboarding flow. They move header management from navigator-level to screen-level but do not affect list rendering, data loading, state management, app startup, or any other performance-sensitive areas. No performance tests are warranted.

View GitHub Actions results

@sonarqubecloud
Copy link
Copy Markdown

@Brunonascdev Brunonascdev added this pull request to the merge queue May 27, 2026
Merged via the queue into main with commit 6797d83 May 27, 2026
186 of 189 checks passed
@Brunonascdev Brunonascdev deleted the wsun/migrate-card-to-headerstandard branch May 27, 2026 20:56
@github-actions github-actions Bot locked and limited conversation to collaborators May 27, 2026
@metamaskbotv2 metamaskbotv2 Bot added the release-7.80.0 Issue or pull request that will be included in release 7.80.0 label May 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

release-7.80.0 Issue or pull request that will be included in release 7.80.0 size-L team-mobile-platform Mobile Platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants