Skip to content

Commit 8c73d92

Browse files
authored
refactor(perps): migrate perps modal routes to native stack (MetaMask#30486)
<!-- Please submit this PR as a draft initially. Do not mark it as "Ready for review" until this PR meets the canonical Definition of Ready For Review in `docs/readme/ready-for-review.md`. In short: the template must be materially complete (not just section titles present), all status checks must be currently passing, and the only expected follow-up commits must be reviewer-driven. --> ## **Description** Migrates the Perps modal navigators (`PerpsModalStack` and `PerpsClosePositionBottomSheetStack`) from `@react-navigation/stack` (JS stack) to `@react-navigation/native-stack`, matching the existing native `PerpsScreenStack`. **Why:** The Perps screen stack is already native — the nested modal stacks were the last JS-stack holdouts inside `app/components/UI/Perps/routes/index.tsx`. Native stack uses platform navigators, which gives better performance, gesture handling, and a single consistent navigator API across the Perps surface. This also removes a few JS-stack-only workarounds (the zero-opacity `cardStyleInterpolator` trick on the tooltip stack, redundant per-screen `cardStyle` transparency). **What:** - `ModalStack = createStackNavigator()` → `createNativeStackNavigator()` - Navigator screen options swap `clearStackNavigatorOptions` + `presentation: 'transparentModal'` for `clearNativeStackNavigatorOptions` + `transparentModalScreenOptions` - `PerpsClosePositionBottomSheetStack` drops its `presentation: 'modal'` + `cardStyleInterpolator` overlay-clear hack in favor of the same native presets (semantically equivalent: transparent, non-dimming overlay) - Removes per-screen `cardStyle: { backgroundColor: 'transparent' }` (navigator-level `contentStyle` now covers it) - Drops the `@react-navigation/stack` import from this file `MainNavigator`'s outer registration of `Routes.PERPS.MODALS.ROOT` is unchanged — the parent stack there is still JS-stack and continues to mount `PerpsModalStackWithErrorGate` via `transparentModal`. ## **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:null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: Perps modal navigation on native stack Scenario: user opens the GTM modal from the wallet Given the Perps feature flag is enabled And the `@MetaMask:perpsGTMModalShown` storage flag is cleared When user opens the Wallet tab Then the Perps "What's new" modal appears full screen And tapping "Not now" returns to the wallet without errors And tapping "Try now" navigates to the Perps tutorial Scenario: user closes all open positions Given the user is on Wallet → Perps tab And the user has at least one open position When user taps "Close all" in the Positions header Then the Close All Positions bottom sheet opens And dismissing it returns to the Perps tab with no leftover backdrop Scenario: user cancels all open orders Given the user is on Wallet → Perps tab And the user has at least one pending order When user taps "Cancel all" in the Open orders header Then the Cancel All Orders bottom sheet opens and dismisses correctly Scenario: user opens a close-position tooltip Given the user has an open position When user opens Close position from market details And user taps the info icon next to "Fees" or "You'll receive" Then the tooltip bottom sheet (PerpsClosePositionModals → PerpsTooltip) appears And tapping outside or the close button dismisses it without dimming the parent screen Scenario: user opens the provider selector (multi-provider builds) Given multi-provider is enabled When user taps the provider badge in Perps Then the Select Provider modal opens with a transparent background Scenario: user triggers cross-margin warning Given the user has a cross-margin position on the underlying exchange When user attempts to place an order on that market Then the Cross Margin Warning modal appears Scenario: user enters deposit / trade confirmation Given the user is on the Perps trade flow When the Redesigned Confirmations screen mounts inside the Perps stack Then the header / transparent overlay behavior is unchanged from main ``` ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <img width="350" height="720" alt="perps modal before" src="https://github.com/user-attachments/assets/f8856292-435a-4f29-b289-b5c2efefd8dc" /> <!-- [screenshots/recordings] --> ### **After** <img width="350" height="720" alt="perps modal after" src="https://github.com/user-attachments/assets/9d7f3ff4-856a-4415-82c9-ce50bc25f284" /> <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** <!-- Every checklist item must be consciously assessed before marking this PR as "Ready for review". A checked box means you deliberately considered that responsibility, not that you literally performed every action listed. Unchecked boxes are ambiguous: they are not an implicit "N/A" and they are not a silent "skip". See `docs/readme/ready-for-review.md` for the full checklist semantics. --> - [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. #### 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](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/edit-v2/401401446401?draftShareId=9d77e1e1-4bdc-4be1-9ebb-ccd916988d93) to import wallets with many accounts and tokens - [ ] I've instrumented key operations with Sentry traces for production performance metrics - See [`trace()`](/app/util/trace.ts) for usage and [`addToken`](/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx#L274) for an example For performance guidelines and tooling, see the [Performance Guide](https://consensyssoftware.atlassian.net/wiki/spaces/TL1/pages/400085549067/Performance+Guide+for+Engineers). ## **Pre-merge reviewer checklist** <!-- Reviewer checklist items follow the same semantics as the author checklist: an unchecked box is ambiguous, a checked box means the reviewer consciously assessed that responsibility. See `docs/readme/ready-for-review.md`. --> - [x] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [x] 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] > **Medium Risk** > Moderate risk because it changes navigation stack implementation and screen options for Perps modals, which could affect modal presentation/gestures and overlay behavior across key trading flows. > > **Overview** > Migrates the Perps modal navigators in `app/components/UI/Perps/routes/index.tsx` from the JS stack (`@react-navigation/stack`) to `createNativeStackNavigator`, aligning them with the existing native Perps screen stack. > > Updates modal/tooltip navigator `screenOptions` to use `clearNativeStackNavigatorOptions` + `transparentModalScreenOptions`, and removes JS-stack-only transparency/overlay workarounds (per-screen transparent `cardStyle` and the tooltip stack’s zero-opacity overlay interpolator). > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit 2e6c012. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 92435a2 commit 8c73d92

1 file changed

Lines changed: 5 additions & 25 deletions

File tree

app/components/UI/Perps/routes/index.tsx

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { createStackNavigator } from '@react-navigation/stack';
21
import {
32
createNativeStackNavigator,
43
type NativeStackNavigationOptions,
@@ -51,12 +50,11 @@ import { NavigationContext } from '@react-navigation/core';
5150
import { CONFIRMATION_HEADER_CONFIG } from '../constants/perpsConfig';
5251
import {
5352
clearNativeStackNavigatorOptions,
54-
clearStackNavigatorOptions,
5553
transparentModalScreenOptions,
5654
} from '../../../../constants/navigation/clearStackNavigatorOptions';
5755

5856
const Stack = createNativeStackNavigator<PerpsNavigationParamList>();
59-
const ModalStack = createStackNavigator();
57+
const ModalStack = createNativeStackNavigator();
6058

6159
const styles = StyleSheet.create({
6260
container: {
@@ -139,8 +137,8 @@ const PerpsModalStack = () => {
139137
<PerpsStreamProvider>
140138
<ModalStack.Navigator
141139
screenOptions={{
142-
...clearStackNavigatorOptions,
143-
presentation: 'transparentModal',
140+
...clearNativeStackNavigatorOptions,
141+
...transparentModalScreenOptions,
144142
}}
145143
>
146144
<ModalStack.Screen
@@ -177,30 +175,20 @@ const PerpsModalStack = () => {
177175
component={PerpsSelectProviderView}
178176
options={{
179177
title: strings('perps.provider_selector.title'),
180-
cardStyle: { backgroundColor: 'transparent' },
181178
}}
182179
/>
183180
{/* Action Selection Modals */}
184181
<ModalStack.Screen
185182
name={Routes.PERPS.SELECT_MODIFY_ACTION}
186183
component={PerpsSelectModifyActionView}
187-
options={{
188-
cardStyle: { backgroundColor: 'transparent' },
189-
}}
190184
/>
191185
<ModalStack.Screen
192186
name={Routes.PERPS.SELECT_ADJUST_MARGIN_ACTION}
193187
component={PerpsSelectAdjustMarginActionView}
194-
options={{
195-
cardStyle: { backgroundColor: 'transparent' },
196-
}}
197188
/>
198189
<ModalStack.Screen
199190
name={Routes.PERPS.SELECT_ORDER_TYPE}
200191
component={PerpsSelectOrderTypeView}
201-
options={{
202-
cardStyle: { backgroundColor: 'transparent' },
203-
}}
204192
/>
205193
</ModalStack.Navigator>
206194
</PerpsStreamProvider>
@@ -229,16 +217,8 @@ const PerpsClosePositionBottomSheetStack = () => {
229217
<PerpsStreamProvider>
230218
<ModalStack.Navigator
231219
screenOptions={{
232-
headerShown: false,
233-
presentation: 'modal',
234-
cardStyle: {
235-
backgroundColor: 'transparent',
236-
},
237-
cardStyleInterpolator: () => ({
238-
overlayStyle: {
239-
opacity: 0,
240-
},
241-
}),
220+
...clearNativeStackNavigatorOptions,
221+
...transparentModalScreenOptions,
242222
}}
243223
>
244224
<ModalStack.Screen

0 commit comments

Comments
 (0)