refactor: migrate onboarding screens to design system with Tailwind CSS (Part 1)#26673
Conversation
Replace StyleSheet.create() and raw View/Text components with design-system-react-native Box/Text and useTailwind() in Onboarding, OnboardingSheet, OnboardingSuccess, and OnboardingSuccessEndAnimation. Delete the now-unused .styles.ts files. Made-with: Cursor
|
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. |
Made-with: Cursor
…ilwind migration Made-with: Cursor
MMSans-Regular is not registered in the TWRNC config, so font-["MMSans-Regular"] was silently ignored and the DisplayMD variant's Geist-Bold took precedence. Pass it via a style object to tw.style() so the override applies correctly. Made-with: Cursor
Pressable has no built-in opacity change on press unlike TouchableOpacity. Add a function-style style prop that applies opacity-60 when pressed to preserve the visual feedback. Made-with: Cursor
Revert the settings action from Pressable back to TouchableOpacity to preserve the native pressed-state opacity feedback and match previous onboarding behavior. Made-with: Cursor
Update OnboardingSuccess to accept route props with a default successFlow fallback and sync test/snapshot expectations with current main branch behavior to prevent merge-CI snapshot mismatches.
Resolve OnboardingSheet snapshot conflict by regenerating snapshots from merged code. Made-with: Cursor
Remove deprecated component-library Text usage from onboarding and onboarding sheet, and update snapshots for the new text component output. Made-with: Cursor
Cover new onboarding Tailwind migration branches and route fallbacks to satisfy Sonar new-code coverage, and update OnboardingSuccess snapshots to match current design token output. Made-with: Cursor
Made-with: Cursor
Address Cursor bot review comments: - Add missing variant prop to loading message Text in renderLoader - Replace toBeTruthy() with toBeOnTheScreen() in loader test assertion Made-with: Cursor
…ior tests Address Cursor Bugbot review feedback by splitting combined tests into isolated tests that each verify one behavior with specific assertions, per unit testing guidelines. Made-with: Cursor
The showNotification setTimeout was never cleared when the component unmounted, causing Animated.timing to fire after Jest tears down the environment and crash CI with exit code 1. Made-with: Cursor
Made-with: Cursor
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
…ailwind-migration-part1
Made-with: Cursor
| variant={TextVariant.DisplayMd} | ||
| fontFamily={FontFamily.Accent} | ||
| style={tw.style('mt-[25px] mb-4 mx-4 text-center font-thin')} | ||
| > |
There was a problem hiding this comment.
font-thin is fontWeight 100, but the old code used fontFamily: 'MMSans-Regular' which is regular (400) weight. This looks like a visual regression — please verify against the design spec.
Made-with: Cursor
isInverse on ButtonVariant.Secondary introduces a white borderColor. Add borderColor: 'transparent' via tw.style() to match the old appearance. Made-with: Cursor
…m migration - OnboardingSuccess title: use FontWeight.Regular + fontWeight override to match old MMSans-Regular appearance (DisplayMd bakes in fontWeight 700) - OnboardingSheet "or" divider: restore 20px fontSize lost in variant switch - OnboardingSheet legal text: use FontWeight.Medium to match old Geist-Medium Made-with: Cursor
…ailwind-migration-part1
…25px] with mt-6 Made-with: Cursor
🔍 Smart E2E Test Selection
click to see 🤖 AI reasoning detailsE2E Test Selection: SmokeWalletPlatform is required because it covers wallet lifecycle events such as new wallet creation and SRP import, which depend on the onboarding flow functioning correctly. Any UI or flow regression here could break wallet creation, analytics tracking, or navigation into the main wallet. SmokeAccounts is selected as onboarding culminates in account creation tied to the initial SRP. While the PR does not modify account controllers directly, onboarding regressions could impact account initialization and visibility, which are validated under SmokeAccounts. No changes affect network management, confirmations, trade flows, card, perps, predictions, ramps, multi-chain APIs, or snaps. Therefore, related tags are not required. Performance Test Selection: |
|
| fontFamily={FontFamily.Accent} | ||
| fontWeight={FontWeight.Regular} | ||
| style={tw.style('mt-6 mb-4 mx-4 text-center', { | ||
| fontWeight: '400', |
There was a problem hiding this comment.
fontWeight: '400' in the style object is redundant, FontWeight.Regular already resolves that thing.
There was a problem hiding this comment.
here's the reply from AI:
However, as we discovered during our earlier debugging, the fontWeight: '400' override is not redundant — it's needed because TextVariant.DisplayMd via twrnc bakes in fontWeight: '700', and the FontWeight.Regular prop alone doesn't override that baked-in value from the Tailwind class. Without the explicit '400' in the style object, the title renders bold instead of matching the old MMSans-Regular appearance.
There was a problem hiding this comment.
and also i tested visually, only by applying what suggested by AI it looks 100% the same as before
…SS (Part 2) (#26736) ## **Description** Replace StyleSheet.create() and raw View/Text components with design-system-react-native Box/Text and useTailwind() in ImportFromSecretRecoveryPhrase and ImportNewSecretRecoveryPhrase. Delete the now-unused .styles.ts files. Part 2 of 2. Part 1: #26673 ## **Changelog** CHANGELOG entry: null ## **Related issues** Refs: [TO-554 - Migrate @MetaMask/web3auth onboarding screens to Design System with Tailwind CSS](https://consensyssoftware.atlassian.net/browse/TO-554) ## **Manual testing steps** No functional changes. Visual regression only — verify import SRP screens render correctly. ```gherkin Feature: Import SRP screens styling Scenario: user imports wallet using SRP Given app is freshly installed When user taps "I already have a wallet" and enters SRP Then import screens render identically to before ``` ## **Screenshots/Recordings** ### **Before left, after right** <img width="500" height="1066" alt="Screenshot 2026-03-02 at 11 16 46 AM" src="https://github.com/user-attachments/assets/4ef5ca42-5c71-42d2-b16e-5bbd8ec77f16" /> <img width="500" height="1059" alt="Screenshot 2026-03-02 at 11 16 59 AM" src="https://github.com/user-attachments/assets/3e8b276e-937e-429d-b962-ecbc3b001bbb" /> ## **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 - [x] 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. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Primarily a UI refactor, but it touches the wallet import/onboarding SRP flows where styling/layout regressions could block users or break keyboard/safe-area behavior across iOS/Android. > > **Overview** > Migrates `ImportFromSecretRecoveryPhrase` and `ImportNewSecretRecoveryPhrase` from `StyleSheet.create()` and raw `View`/library `Text` components to design-system `Box`/`Text`/`Label` with `useTailwind()` styling, including minor platform-specific spacing tweaks. > > Deletes the now-unused `styles.ts` files and updates the Jest snapshot to reflect the new component/styling output. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 2c5e19c. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
The design system ButtonSecondary hardcodes numberOfLines: 1 and ButtonBase uses a fixed h-12, so long strings like "Import using Secret Recovery Phrase" get clipped on narrower devices. Override with min-h-12 h-auto py-3 and numberOfLines: 0 so the button expands to fit its content. Made-with: Cursor
Same numberOfLines: 1 and fixed-height issue as OnboardingSheet. Apply min-h h-auto py-3 and numberOfLines: 0 to both "Create a new wallet" and "I have an existing wallet" buttons. Made-with: Cursor
|
✅ E2E Fixture Validation — Schema is up to date |
## **Description** Users who set their system font size to maximum scale experience button text clipping on the Onboarding and OnboardingSheet screens. The design system `ButtonPrimary` and `ButtonSecondary` both hardcode `numberOfLines: 1` with `ellipsizeMode: 'clip'`, and `ButtonBase` uses a fixed height (`h-12` for Lg, `h-10` for Md). This means longer strings like "Import using Secret Recovery Phrase" and "I have an existing wallet" get cut off instead of wrapping. This fix overrides the button containers to use `min-h h-auto py-3` and sets `numberOfLines: 0` so buttons expand to fit their content at any font scale. > **Depends on** #26673 being merged first — this branch is based on `refactor/onboarding-tailwind-migration-part1`. ### Screens fixed | Screen | Buttons | |--------|---------| | `Onboarding/index.tsx` | "Create a new wallet", "I have an existing wallet" | | `OnboardingSheet/index.tsx` | "Import using Secret Recovery Phrase" / "Continue with Secret Recovery Phrase" | ### Root cause Two constraints in `@metamask/design-system-react-native`: 1. `ButtonPrimary` and `ButtonSecondary` both pass `numberOfLines: 1, ellipsizeMode: 'clip'` to `ButtonBase` text props 2. `ButtonBase` applies a fixed height class (`h-12` for Lg, `h-10` for Md) via `TWCLASSMAP_BUTTONBASE_SIZE_DIMENSION` Both are overridable from the consumer side via `textProps` and `twClassName`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Depends on: #26673 ## **Manual testing steps** ```gherkin Feature: Onboarding button text wrapping at max font scale Scenario: user views onboarding with system font set to maximum Given app is freshly installed And user's system font size is set to largest/maximum When user reaches the onboarding screen Then "Create a new wallet" and "I have an existing wallet" buttons display full text without clipping Scenario: user views onboarding sheet with large font Given user taps "Create a new wallet" or "I already have a wallet" When the onboarding sheet appears Then the "Import using Secret Recovery Phrase" button text wraps to multiple lines instead of being clipped ``` ## **Screenshots/Recordings** ### **Before** Button text is clipped to one line on devices with max font scale: <img width="300" height="1280" alt="Screenshot_1773224200" src="https://github.com/user-attachments/assets/855a3bad-c6b7-4f1a-8341-3f513ad0ebde" /> <img width="300" alt="Screenshot_1773222833" src="https://github.com/user-attachments/assets/2dccc4cd-5a4f-4ed9-bf8b-1246b2f17136" /> ### **After** Buttons expand to fit the full text: <img width="300" height="1280" alt="Screenshot_1773224472" src="https://github.com/user-attachments/assets/41930a9c-bfca-4b7c-a10c-bd32cc388a1c" /> <img width="300" alt="Screenshot_1773222827" src="https://github.com/user-attachments/assets/6dc37a93-4fbc-4797-ad9f-809537465e82" /> ## **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 - [x] 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.




Description
Replace StyleSheet.create() and raw View/Text components with design-system-react-native Box/Text and useTailwind() in Onboarding, OnboardingSheet, OnboardingSuccess, and OnboardingSuccessEndAnimation. Delete the now-unused .styles.ts files.
Part 1 of 2. Part 2 will cover ImportFromSecretRecoveryPhrase and ImportNewSecretRecoveryPhrase.
Changelog
CHANGELOG entry: null
Related issues
Refs: TO-555 - Migrate Onboarding screen to Design System (Box/Text + Tailwind)
Refs: TO-556 - Migrate OnboardingSuccess screen to Design System (Box/Text + Tailwind)
Refs: TO-557 - Migrate OnboardingSuccessEndAnimation to Design System (Box/Text + Tailwind)
Manual testing steps
No functional changes. Visual regression only — verify onboarding screens render correctly.
Screenshots/Recordings
Before (left) vs After (right)
Pre-merge author checklist
Pre-merge reviewer checklist
Made with Cursor
Note
Medium Risk
Mostly a UI refactor, but it touches the app’s onboarding entry screens, loading overlay, and toast timing/padding, so visual/layout regressions or missed edge cases could impact first-run flow.
Overview
Migrates
Onboarding,OnboardingSheet, andOnboardingSuccessEndAnimationoffStyleSheet/rawView/component-library buttons onto@metamask/design-system-react-native(Box,Button,Text,TextButton) with Tailwind (useTailwind) styling, and removes the now-unusedstyles.tsfiles.Tweaks onboarding toast behavior by tracking the hide
setTimeoutin a ref and clearing it on unmount, and updates notification bottom padding to explicitly vary for iPhone X vs non–iPhone X.Expands and updates Jest tests/snapshots to cover medium vs non-medium device spacing/button sizing, loading overlay messaging, iPhone X notification padding, and safe handling when
OnboardingSheetroute params areundefined.Written by Cursor Bugbot for commit 7775d2b. This will update automatically on new commits. Configure here.