From ac9e0ec0eeef396028050d6f24b7165121db9f7c Mon Sep 17 00:00:00 2001 From: Wei Sun Date: Fri, 19 Jun 2026 11:29:07 -0700 Subject: [PATCH 1/6] chore: migrate StackNavigationProp types to native-stack equivalents --- .storybook/decorators/withNavigation.tsx | 4 ++-- app/components/Nav/Main/MainNavigator.test.tsx | 10 ---------- .../CreatePriceAlertView.tsx | 5 ++--- .../ManagePriceAlertsView.tsx | 5 ++--- .../BatchSellFinalReviewModal/index.tsx | 5 ++--- .../index.tsx | 5 ++--- .../BatchSellNetworkFeeInfoModal/index.tsx | 5 ++--- .../BatchSellQuoteDetailsModal/index.tsx | 5 ++--- .../components/MissingPriceModal/index.tsx | 5 ++--- .../components/TokenWarningModal/index.tsx | 5 ++--- .../DeFiProtocolPositionDetails.tsx | 6 +++--- .../UI/DeleteWalletModal/index.test.tsx | 4 ++-- .../EarnMusdConversionEducationView/index.tsx | 5 ++--- .../MoneyFirstTimeDepositView.tsx | 5 ++--- .../MoneyOnboardingView.tsx | 5 ++--- .../MoneyUiDeveloperOptionsSection.tsx | 1 - app/components/UI/Navbar/index.test.jsx | 6 +++--- .../hooks/usePredictBuyActions.ts | 4 ++-- .../PredictMarketDetails.test.tsx | 4 ++-- .../ErrorDetailsModal/ErrorDetailsModal.tsx | 6 +++--- .../UI/Ramp/hooks/useTransakRouting.ts | 5 ++--- .../UI/Rewards/RewardsNavigator.test.tsx | 4 ++-- .../Views/OndoCampaignRwaSelectorView.test.tsx | 4 ++-- .../Rewards/Views/RewardsSettingsView.test.tsx | 4 ++-- .../AssetOverviewContent.view.test.tsx | 4 ++-- app/components/UI/Tokens/index.test.tsx | 4 ++-- .../UI/Tokens/util/goToAddEvmToken.test.ts | 6 ++---- .../TransactionDetails/index.test.tsx | 4 ++-- .../useTokenListFilters/useTokenListFilters.ts | 5 ++--- .../UI/UrlAutocomplete/index.test.tsx | 4 ++-- .../Views/ActivityView/index.test.tsx | 4 ++-- .../AddCustomToken/AddCustomToken.tsx | 6 +++--- .../Views/Browser/Browser.components.test.tsx | 4 ++-- .../Views/Browser/Browser.functions.test.tsx | 4 ++-- .../Views/Browser/Browser.lifecycle.test.tsx | 4 ++-- .../Views/Browser/Browser.rendering.test.tsx | 4 ++-- .../Views/Browser/Browser.tabs.test.tsx | 4 ++-- .../Views/DiscoveryTab/index.test.tsx | 4 ++-- .../Sections/TopTraders/TopTradersSection.tsx | 5 ++--- .../index.test.tsx | 6 +++--- .../ManualBackupStep1.types.ts | 5 ++--- .../Views/MultiRpcModal/MultiRpcModal.test.tsx | 4 ++-- .../MultichainAccountConnect.stories.tsx | 4 ++-- .../NFTAutoDetectionModal.test.tsx | 4 ++-- .../NetworkSelector/NetworkSelector.test.tsx | 4 ++-- .../Views/Onboarding/FastOnboarding.test.tsx | 4 ++-- app/components/Views/Onboarding/index.test.tsx | 4 ++-- .../OnboardingSheet/OnboardingSheet.test.tsx | 4 ++-- .../Pna25BottomSheet/Pna25BottomSheet.test.tsx | 4 ++-- .../Views/Settings/Contacts/index.test.tsx | 4 ++-- .../ShowDisplayNFTMediaSheet.test.tsx | 4 ++-- .../TraderPositionView/TraderPositionView.tsx | 8 +++++--- .../Views/TransactionsView/index.test.tsx | 4 ++-- .../Views/TrendingView/TrendingView.test.tsx | 4 ++-- .../Views/WalletRecovery/index.test.tsx | 4 ++-- .../hooks/send/useSendNavbar.test.tsx | 4 ++-- .../ui/useClearConfirmationOnBackSwipe.ts | 5 ++--- app/core/NavigationService/types.ts | 9 +++------ app/util/test/renderWithProvider.tsx | 10 +++++----- tests/component-view/render.tsx | 4 ++-- .../renderers/marketInsights.tsx | 10 +++++----- .../renderers/perpsViewRenderer.tsx | 6 +++--- tests/component-view/renderers/ramps.tsx | 18 +++++++++--------- 63 files changed, 145 insertions(+), 175 deletions(-) diff --git a/.storybook/decorators/withNavigation.tsx b/.storybook/decorators/withNavigation.tsx index 7fc4f2e0d5d..362072096cf 100644 --- a/.storybook/decorators/withNavigation.tsx +++ b/.storybook/decorators/withNavigation.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { NavigationContainer } from '@react-navigation/native'; -const StoryBookStack = createStackNavigator(); +const StoryBookStack = createNativeStackNavigator(); const withNavigation = (story: any) => { const StorybookScreen = () => story(); diff --git a/app/components/Nav/Main/MainNavigator.test.tsx b/app/components/Nav/Main/MainNavigator.test.tsx index b595b707e41..05e5b4dbc09 100644 --- a/app/components/Nav/Main/MainNavigator.test.tsx +++ b/app/components/Nav/Main/MainNavigator.test.tsx @@ -10,16 +10,6 @@ jest.mock('react-native-device-info', () => ({ getVersion: jest.fn(() => '7.72.0'), })); -jest.mock('@react-navigation/stack', () => ({ - createStackNavigator: jest.fn().mockReturnValue({ - Navigator: 'Navigator', - Screen: 'Screen', - }), - TransitionPresets: { - ModalSlideFromBottomIOS: {}, - }, -})); - jest.mock('@react-navigation/native-stack', () => ({ createNativeStackNavigator: jest.fn().mockReturnValue({ Navigator: 'Navigator', diff --git a/app/components/UI/Assets/PriceAlerts/Views/CreatePriceAlertView/CreatePriceAlertView.tsx b/app/components/UI/Assets/PriceAlerts/Views/CreatePriceAlertView/CreatePriceAlertView.tsx index e70b618fe7d..26272822396 100644 --- a/app/components/UI/Assets/PriceAlerts/Views/CreatePriceAlertView/CreatePriceAlertView.tsx +++ b/app/components/UI/Assets/PriceAlerts/Views/CreatePriceAlertView/CreatePriceAlertView.tsx @@ -18,7 +18,7 @@ import { useRoute, type RouteProp, } from '@react-navigation/native'; -import type { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../../core/NavigationService/types'; import { SafeAreaView } from 'react-native-safe-area-context'; import { Box, @@ -107,8 +107,7 @@ const viewStyles = StyleSheet.create({ const CreatePriceAlertView: React.FC = () => { const tw = useTailwind(); const { colors, brandColors } = useTheme(); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const navigation = useNavigation>(); + const navigation = useNavigation(); const route = useRoute< RouteProp< diff --git a/app/components/UI/Assets/PriceAlerts/Views/ManagePriceAlertsView/ManagePriceAlertsView.tsx b/app/components/UI/Assets/PriceAlerts/Views/ManagePriceAlertsView/ManagePriceAlertsView.tsx index c17531e18ed..cda20ee0ee9 100644 --- a/app/components/UI/Assets/PriceAlerts/Views/ManagePriceAlertsView/ManagePriceAlertsView.tsx +++ b/app/components/UI/Assets/PriceAlerts/Views/ManagePriceAlertsView/ManagePriceAlertsView.tsx @@ -18,7 +18,7 @@ import { useRoute, type RouteProp, } from '@react-navigation/native'; -import type { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../../core/NavigationService/types'; import { SafeAreaView } from 'react-native-safe-area-context'; import { Box, @@ -62,8 +62,7 @@ const ManagePriceAlertsView: React.FC = () => { const { colors, brandColors } = useTheme(); const queryClient = useQueryClient(); const { toastRef } = useContext(ToastContext); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const navigation = useNavigation>(); + const navigation = useNavigation(); const route = useRoute< RouteProp< diff --git a/app/components/UI/Bridge/components/BatchSellFinalReviewModal/index.tsx b/app/components/UI/Bridge/components/BatchSellFinalReviewModal/index.tsx index 59d7fa9538d..7ac75a681c2 100644 --- a/app/components/UI/Bridge/components/BatchSellFinalReviewModal/index.tsx +++ b/app/components/UI/Bridge/components/BatchSellFinalReviewModal/index.tsx @@ -1,5 +1,5 @@ import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import { Pressable } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; @@ -290,8 +290,7 @@ function NetworkFeeRow({ export function BatchSellFinalReviewModal() { const dispatch = useDispatch(); - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const selectedTokens = useSelector(selectBatchSellSourceTokens); const isSubmittingTx = useSelector(selectIsSubmittingTx); const batchSellQuoteData = useBatchSellQuoteData({ diff --git a/app/components/UI/Bridge/components/BatchSellMinimumReceivedInfoModal/index.tsx b/app/components/UI/Bridge/components/BatchSellMinimumReceivedInfoModal/index.tsx index 8a400a1b0b7..a87b8de3421 100644 --- a/app/components/UI/Bridge/components/BatchSellMinimumReceivedInfoModal/index.tsx +++ b/app/components/UI/Bridge/components/BatchSellMinimumReceivedInfoModal/index.tsx @@ -1,5 +1,5 @@ import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import React from 'react'; import { BottomSheet, @@ -18,8 +18,7 @@ import { BatchSellMinimumReceivedInfoModalParams } from './BatchSellMinimumRecei import { useElevatedSurface } from '../../../../../util/theme/themeUtils'; export function BatchSellMinimumReceivedInfoModal() { - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const { sourceModal } = useParams(); const handleBack = sourceModal ? () => navigation.replace(sourceModal.screen, sourceModal.params) diff --git a/app/components/UI/Bridge/components/BatchSellNetworkFeeInfoModal/index.tsx b/app/components/UI/Bridge/components/BatchSellNetworkFeeInfoModal/index.tsx index 2e2cf253ae2..5daf5eb5b26 100644 --- a/app/components/UI/Bridge/components/BatchSellNetworkFeeInfoModal/index.tsx +++ b/app/components/UI/Bridge/components/BatchSellNetworkFeeInfoModal/index.tsx @@ -1,5 +1,5 @@ import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import React from 'react'; import { BottomSheet, @@ -18,8 +18,7 @@ import { BatchSellNetworkFeeInfoModalParams } from './BatchSellNetworkFeeInfoMod import { useElevatedSurface } from '../../../../../util/theme/themeUtils'; export function BatchSellNetworkFeeInfoModal() { - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const { sourceModal } = useParams(); const handleBack = sourceModal ? () => navigation.replace(sourceModal.screen, sourceModal.params) diff --git a/app/components/UI/Bridge/components/BatchSellQuoteDetailsModal/index.tsx b/app/components/UI/Bridge/components/BatchSellQuoteDetailsModal/index.tsx index bb7b1ca78dd..28d89c93aaa 100644 --- a/app/components/UI/Bridge/components/BatchSellQuoteDetailsModal/index.tsx +++ b/app/components/UI/Bridge/components/BatchSellQuoteDetailsModal/index.tsx @@ -1,5 +1,5 @@ import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; import { @@ -20,8 +20,7 @@ import { strings } from '../../../../../../locales/i18n'; import { useElevatedSurface } from '../../../../../util/theme/themeUtils'; export function BatchSellQuoteDetailsModal() { - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const sourceTokens = useSelector(selectBatchSellSourceTokens); const surfaceClass = useElevatedSurface(); const batchSellQuoteData = useBatchSellQuoteData({ diff --git a/app/components/UI/Bridge/components/MissingPriceModal/index.tsx b/app/components/UI/Bridge/components/MissingPriceModal/index.tsx index 39315a23034..cad6d10430e 100644 --- a/app/components/UI/Bridge/components/MissingPriceModal/index.tsx +++ b/app/components/UI/Bridge/components/MissingPriceModal/index.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useRef, useState } from 'react'; import { useSelector } from 'react-redux'; import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { MetaMetricsSwapsEventSource } from '@metamask/bridge-controller'; import { strings } from '../../../../../../locales/i18n'; import { useParams } from '../../../../../util/navigation/navUtils'; @@ -32,8 +32,7 @@ export interface MissingPriceModalParams { } export const MissingPriceModal = () => { - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const sheetRef = useRef(null); const [loading, setLoading] = useState(false); const { location } = useParams(); diff --git a/app/components/UI/Bridge/components/TokenWarningModal/index.tsx b/app/components/UI/Bridge/components/TokenWarningModal/index.tsx index 50a3f49c8b3..a6d80989f13 100644 --- a/app/components/UI/Bridge/components/TokenWarningModal/index.tsx +++ b/app/components/UI/Bridge/components/TokenWarningModal/index.tsx @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux'; // Must use this to make sure scroll works inside a bottom sheet on Android import { ScrollView } from 'react-native-gesture-handler'; import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { MetaMetricsSwapsEventSource } from '@metamask/bridge-controller'; import BottomSheet, { BottomSheetRef, @@ -90,8 +90,7 @@ export const getTokenWarningContent = ( }; export const TokenWarningModal = () => { - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const sheetRef = useRef(null); const [loading, setLoading] = useState(false); diff --git a/app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.tsx b/app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.tsx index dd23ad9449b..fe41f1e0554 100644 --- a/app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.tsx +++ b/app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.tsx @@ -2,8 +2,8 @@ import React, { useCallback } from 'react'; import { GroupedDeFiPositions } from '@metamask/assets-controllers'; import { ImageSourcePropType, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; -import { useNavigation, type ParamListBase } from '@react-navigation/native'; -import type { StackNavigationProp } from '@react-navigation/stack'; +import { useNavigation } from '@react-navigation/native'; +import type { AppNavigationProp } from '../../../core/NavigationService/types'; import { HeaderStandard } from '@metamask/design-system-react-native'; import styleSheet from './DeFiProtocolPositionDetails.styles'; import { useParams } from '../../../util/navigation/navUtils'; @@ -35,7 +35,7 @@ interface DeFiProtocolPositionDetailsParams { const DeFiProtocolPositionDetails: React.FC = () => { const { styles } = useStyles(styleSheet, undefined); - const navigation = useNavigation>(); + const navigation = useNavigation(); const { protocolAggregate, networkIconAvatar } = useParams(); diff --git a/app/components/UI/DeleteWalletModal/index.test.tsx b/app/components/UI/DeleteWalletModal/index.test.tsx index ba3ee80e140..bdeed13f00c 100644 --- a/app/components/UI/DeleteWalletModal/index.test.tsx +++ b/app/components/UI/DeleteWalletModal/index.test.tsx @@ -5,7 +5,7 @@ import { fireEvent } from '@testing-library/react-native'; import renderWithProvider, { DeepPartial, } from '../../../util/test/renderWithProvider'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { RootState } from '../../../reducers'; import { strings } from '../../../../locales/i18n'; import { ForgotPasswordModalSelectorsIDs } from '../../../util/ForgotPasswordModal.testIds'; @@ -72,7 +72,7 @@ jest.mock('../../../core/Authentication/Authentication', () => ({ }, })); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const renderComponent = ( state: DeepPartial = {}, diff --git a/app/components/UI/Earn/Views/EarnMusdConversionEducationView/index.tsx b/app/components/UI/Earn/Views/EarnMusdConversionEducationView/index.tsx index d1962df3147..8ad4ba2f0a3 100644 --- a/app/components/UI/Earn/Views/EarnMusdConversionEducationView/index.tsx +++ b/app/components/UI/Earn/Views/EarnMusdConversionEducationView/index.tsx @@ -10,7 +10,7 @@ import { SafeAreaView } from 'react-native-safe-area-context'; import { useMusdConversion } from '../../hooks/useMusdConversion'; import { useParams } from '../../../../../util/navigation/navUtils'; import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { Box, BoxFlexDirection, @@ -122,8 +122,7 @@ const EarnMusdConversionEducationView = () => { conversionTokens, } = useMusdConversionFlowData(); - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const colorScheme = useColorScheme(); diff --git a/app/components/UI/Money/Views/MoneyFirstTimeDepositView/MoneyFirstTimeDepositView.tsx b/app/components/UI/Money/Views/MoneyFirstTimeDepositView/MoneyFirstTimeDepositView.tsx index 9d09c96b108..35b7eeb71d9 100644 --- a/app/components/UI/Money/Views/MoneyFirstTimeDepositView/MoneyFirstTimeDepositView.tsx +++ b/app/components/UI/Money/Views/MoneyFirstTimeDepositView/MoneyFirstTimeDepositView.tsx @@ -1,7 +1,7 @@ import React, { useCallback, useEffect, useRef } from 'react'; import { BackHandler, Platform } from 'react-native'; import { useNavigation } from '@react-navigation/native'; -import { type StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { Accelerometer } from 'expo-sensors'; import Rive, { AutoBind, @@ -115,8 +115,7 @@ function gForceToParallax(gForce: number): number { } const MoneyFirstTimeDepositView = () => { - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const { trackScreenViewed } = useMoneyAnalytics({ screen_name: SCREEN_NAMES.MONEY_FIRST_TIME_DEPOSIT, diff --git a/app/components/UI/Money/Views/MoneyOnboardingView/MoneyOnboardingView.tsx b/app/components/UI/Money/Views/MoneyOnboardingView/MoneyOnboardingView.tsx index 07d8e01d867..565cea39b9f 100644 --- a/app/components/UI/Money/Views/MoneyOnboardingView/MoneyOnboardingView.tsx +++ b/app/components/UI/Money/Views/MoneyOnboardingView/MoneyOnboardingView.tsx @@ -1,6 +1,6 @@ import React, { useCallback, useEffect, useMemo, useRef } from 'react'; import { useNavigation } from '@react-navigation/native'; -import { type StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { useDispatch, useSelector } from 'react-redux'; import { strings } from '../../../../../../locales/i18n'; import Routes from '../../../../../constants/navigation/Routes'; @@ -58,8 +58,7 @@ const RIVE_STATE_TO_STEP_INDEX: Record = { const TOTAL_ONBOARDING_STEPS = Object.keys(RIVE_STATE_TO_STEP_INDEX).length; const MoneyOnboardingView = () => { - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const isUsUnauthenticatedNonCardholder = useSelector( selectIsUsUnauthenticatedNonCardholder, diff --git a/app/components/UI/Money/components/MoneyUiDeveloperOptionsSection.tsx b/app/components/UI/Money/components/MoneyUiDeveloperOptionsSection.tsx index 8200891eec9..5dddbdfd236 100644 --- a/app/components/UI/Money/components/MoneyUiDeveloperOptionsSection.tsx +++ b/app/components/UI/Money/components/MoneyUiDeveloperOptionsSection.tsx @@ -1,7 +1,6 @@ import React, { useCallback } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useNavigation } from '@react-navigation/native'; -import { type StackNavigationProp } from '@react-navigation/stack'; import { useTheme } from '../../../../util/theme'; import { diff --git a/app/components/UI/Navbar/index.test.jsx b/app/components/UI/Navbar/index.test.jsx index 4bbb8aa48ca..c76a0e82241 100644 --- a/app/components/UI/Navbar/index.test.jsx +++ b/app/components/UI/Navbar/index.test.jsx @@ -1,6 +1,6 @@ /* eslint-disable react/prop-types */ import React from 'react'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { fireEvent } from '@testing-library/react-native'; import renderWithProvider from '../../../util/test/renderWithProvider'; import { backgroundState } from '../../../util/test/initial-root-state'; @@ -140,7 +140,7 @@ jest.mock('../AddressCopy', () => { }); describe('getNetworkNavbarOptions', () => { - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); const mockNavigation = { pop: jest.fn(), @@ -407,7 +407,7 @@ describe('getStakingNavbar', () => { }); describe('getNavigationOptionsTitle', () => { - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); const mockNavigation = { goBack: jest.fn(), diff --git a/app/components/UI/Predict/views/PredictBuyWithAnyToken/hooks/usePredictBuyActions.ts b/app/components/UI/Predict/views/PredictBuyWithAnyToken/hooks/usePredictBuyActions.ts index a726b1d3331..9e7e9a10a0e 100644 --- a/app/components/UI/Predict/views/PredictBuyWithAnyToken/hooks/usePredictBuyActions.ts +++ b/app/components/UI/Predict/views/PredictBuyWithAnyToken/hooks/usePredictBuyActions.ts @@ -1,5 +1,5 @@ import { StackActions, useNavigation } from '@react-navigation/native'; -import type { StackNavigationProp } from '@react-navigation/stack'; +import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; import type { PredictNavigationParamList } from '../../../types/navigation'; import { useCallback, useEffect, useMemo, useRef } from 'react'; import { @@ -70,7 +70,7 @@ export const usePredictBuyActions = ({ transactionActiveAbTests, }: UsePredictBuyActionsParams) => { const navigation = - useNavigation>(); + useNavigation>(); const { onConfirm: onApprovalConfirm, approvalRequest } = useApprovalRequest(); const { onReject } = useConfirmActions(); diff --git a/app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.test.tsx b/app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.test.tsx index 618cd41fbcb..ecba2467569 100644 --- a/app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.test.tsx +++ b/app/components/UI/Predict/views/PredictMarketDetails/PredictMarketDetails.test.tsx @@ -64,8 +64,8 @@ jest.mock('../../hooks/usePredictActiveOrder', () => ({ }), })); -jest.mock('@react-navigation/stack', () => ({ - createStackNavigator: () => ({ +jest.mock('@react-navigation/native-stack', () => ({ + createNativeStackNavigator: () => ({ Navigator: ({ children }: { children: React.ReactNode }) => children, Screen: ({ children }: { children: React.ReactNode }) => children, }), diff --git a/app/components/UI/Ramp/Views/Modals/ErrorDetailsModal/ErrorDetailsModal.tsx b/app/components/UI/Ramp/Views/Modals/ErrorDetailsModal/ErrorDetailsModal.tsx index b661da85573..496c23ed8a3 100644 --- a/app/components/UI/Ramp/Views/Modals/ErrorDetailsModal/ErrorDetailsModal.tsx +++ b/app/components/UI/Ramp/Views/Modals/ErrorDetailsModal/ErrorDetailsModal.tsx @@ -1,8 +1,8 @@ import React, { useCallback, useRef } from 'react'; import { View, ScrollView, useWindowDimensions } from 'react-native'; import InAppBrowser from 'react-native-inappbrowser-reborn'; -import { useNavigation, type ParamListBase } from '@react-navigation/native'; -import type { StackNavigationProp } from '@react-navigation/stack'; +import { useNavigation } from '@react-navigation/native'; +import type { AppNavigationProp } from '../../../../../../core/NavigationService/types'; import { BottomSheet, Button, @@ -45,7 +45,7 @@ export const createErrorDetailsModalNavDetails = function ErrorDetailsModal() { const sheetRef = useRef(null); - const navigation = useNavigation>(); + const navigation = useNavigation(); const { height: screenHeight } = useWindowDimensions(); const { styles } = useStyles(styleSheet, { screenHeight, diff --git a/app/components/UI/Ramp/hooks/useTransakRouting.ts b/app/components/UI/Ramp/hooks/useTransakRouting.ts index e1f81134081..86840dc7aec 100644 --- a/app/components/UI/Ramp/hooks/useTransakRouting.ts +++ b/app/components/UI/Ramp/hooks/useTransakRouting.ts @@ -1,6 +1,5 @@ import { useCallback, useRef } from 'react'; -import { useNavigation } from '@react-navigation/native'; -import type { StackNavigationProp } from '@react-navigation/stack'; +import { useNavigation, type NavigationProp } from '@react-navigation/native'; import { useSelector } from 'react-redux'; import type { CaipChainId } from '@metamask/utils'; import { strings } from '../../../../../locales/i18n'; @@ -143,7 +142,7 @@ export const useTransakRouting = (config?: UseTransakRoutingConfig) => { }, [baseRoute, baseRouteParams], ); - const navigation = useNavigation>(); + const navigation = useNavigation>(); const { themeAppearance, colors } = useTheme(); const trackEvent = useAnalytics(); const processingOrderIdRef = useRef(null); diff --git a/app/components/UI/Rewards/RewardsNavigator.test.tsx b/app/components/UI/Rewards/RewardsNavigator.test.tsx index b3334ec85ad..b6c7a4b2907 100644 --- a/app/components/UI/Rewards/RewardsNavigator.test.tsx +++ b/app/components/UI/Rewards/RewardsNavigator.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { act, render, waitFor } from '@testing-library/react-native'; import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { configureStore } from '@reduxjs/toolkit'; import RewardsNavigator from './RewardsNavigator'; import Routes from '../../../constants/navigation/Routes'; @@ -374,7 +374,7 @@ const mockUseRewardsVersionGuard = describe('RewardsNavigator', () => { let store: ReturnType; - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); beforeEach(() => { jest.clearAllMocks(); diff --git a/app/components/UI/Rewards/Views/OndoCampaignRwaSelectorView.test.tsx b/app/components/UI/Rewards/Views/OndoCampaignRwaSelectorView.test.tsx index 3b10a620b30..20d5d379738 100644 --- a/app/components/UI/Rewards/Views/OndoCampaignRwaSelectorView.test.tsx +++ b/app/components/UI/Rewards/Views/OndoCampaignRwaSelectorView.test.tsx @@ -45,8 +45,8 @@ jest.mock('@react-navigation/native', () => ({ StackActions: { push: jest.fn() }, })); -jest.mock('@react-navigation/stack', () => ({ - ...jest.requireActual('@react-navigation/stack'), +jest.mock('@react-navigation/native-stack', () => ({ + ...jest.requireActual('@react-navigation/native-stack'), })); jest.mock('@metamask/design-system-react-native', () => { diff --git a/app/components/UI/Rewards/Views/RewardsSettingsView.test.tsx b/app/components/UI/Rewards/Views/RewardsSettingsView.test.tsx index 50ddcad1dbf..a2a90908c25 100644 --- a/app/components/UI/Rewards/Views/RewardsSettingsView.test.tsx +++ b/app/components/UI/Rewards/Views/RewardsSettingsView.test.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { render, fireEvent, act } from '@testing-library/react-native'; import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { configureStore } from '@reduxjs/toolkit'; import RewardsSettingsView, { REWARDS_SETTINGS_SAFE_AREA_TEST_ID, @@ -191,7 +191,7 @@ jest.mock('../components/Settings/LinkedOffDeviceAccountsSheet', () => { describe('RewardsSettingsView', () => { let store: ReturnType; - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); // Helper function to create mock store const createMockStore = () => diff --git a/app/components/UI/TokenDetails/components/AssetOverviewContent.view.test.tsx b/app/components/UI/TokenDetails/components/AssetOverviewContent.view.test.tsx index 0c3bc858d9e..cb970c8115e 100644 --- a/app/components/UI/TokenDetails/components/AssetOverviewContent.view.test.tsx +++ b/app/components/UI/TokenDetails/components/AssetOverviewContent.view.test.tsx @@ -1,7 +1,7 @@ import '../../../../../tests/component-view/mocks'; import React from 'react'; import { Text } from 'react-native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { merge } from 'lodash'; import { fireEvent, screen, waitFor } from '@testing-library/react-native'; @@ -80,7 +80,7 @@ function renderAssetOverviewMarketInsightsStack( }[], providerValues: ProviderValues, ) { - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); const DefaultRouteProbe = (routeName: string): React.FC => diff --git a/app/components/UI/Tokens/index.test.tsx b/app/components/UI/Tokens/index.test.tsx index 46e71a25cb2..947a3f8a895 100644 --- a/app/components/UI/Tokens/index.test.tsx +++ b/app/components/UI/Tokens/index.test.tsx @@ -12,7 +12,7 @@ import { clone } from 'lodash'; import { fireEvent, waitFor, userEvent } from '@testing-library/react-native'; import Tokens from './'; import renderWithProvider from '../../../util/test/renderWithProvider'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import initialRootState from '../../../util/test/initial-root-state'; import { WalletViewSelectorsIDs } from '../../Views/Wallet/WalletView.testIds'; import { TokenList } from './TokenList/TokenList'; @@ -180,7 +180,7 @@ const arrangeMockInteractionManager = () => { const arrangeMockState = () => clone(initialRootState); const initialState = arrangeMockState(); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const renderComponent = ( state = initialState, isFullView: boolean = false, diff --git a/app/components/UI/Tokens/util/goToAddEvmToken.test.ts b/app/components/UI/Tokens/util/goToAddEvmToken.test.ts index 9ba4bb2e585..252aee03e12 100644 --- a/app/components/UI/Tokens/util/goToAddEvmToken.test.ts +++ b/app/components/UI/Tokens/util/goToAddEvmToken.test.ts @@ -1,8 +1,7 @@ import { goToAddEvmToken } from './goToAddEvmToken'; import { MetaMetricsEvents } from '../../../../core/Analytics'; import { AnalyticsEventBuilder } from '../../../../util/analytics/AnalyticsEventBuilder'; -import { StackNavigationProp } from '@react-navigation/stack'; -import { RootStackParamList } from '../../../../core/NavigationService/types'; +import { AppNavigationProp } from '../../../../core/NavigationService/types'; jest.mock('../../../../core/Analytics', () => ({ MetaMetricsEvents: { @@ -27,8 +26,7 @@ describe('goToAddEvmToken', () => { ); const mockProps = { - navigation: - mockNavigation as unknown as StackNavigationProp, + navigation: mockNavigation as unknown as AppNavigationProp, trackEvent: mockTrackEvent, createEventBuilder: mockCreateEventBuilder as unknown as typeof AnalyticsEventBuilder.createEventBuilder, diff --git a/app/components/UI/TransactionElement/TransactionDetails/index.test.tsx b/app/components/UI/TransactionElement/TransactionDetails/index.test.tsx index 2b8ea49b41d..c9aabe3029b 100644 --- a/app/components/UI/TransactionElement/TransactionDetails/index.test.tsx +++ b/app/components/UI/TransactionElement/TransactionDetails/index.test.tsx @@ -5,7 +5,7 @@ import TransactionDetails from './'; import { backgroundState } from '../../../../util/test/initial-root-state'; import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../../util/test/accountsControllerTestUtils'; import renderWithProvider from '../../../../util/test/renderWithProvider'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { mockNetworkState } from '../../../../util/test/network'; import type { NetworkState } from '@metamask/network-controller'; import { isHardwareAccount } from '../../../../util/address'; @@ -18,7 +18,7 @@ jest.mock('../../../../util/analytics/analytics', () => ({ }, })); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const mockEthQuery = { getBalance: jest.fn(), }; diff --git a/app/components/UI/Trending/hooks/useTokenListFilters/useTokenListFilters.ts b/app/components/UI/Trending/hooks/useTokenListFilters/useTokenListFilters.ts index e5b72b58f7b..6ec4976349a 100644 --- a/app/components/UI/Trending/hooks/useTokenListFilters/useTokenListFilters.ts +++ b/app/components/UI/Trending/hooks/useTokenListFilters/useTokenListFilters.ts @@ -1,6 +1,6 @@ import { useCallback, useMemo, useState } from 'react'; import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { CaipChainId } from '@metamask/utils'; import { strings } from '../../../../../../locales/i18n'; import { @@ -73,8 +73,7 @@ export const useTokenListFilters = ( ): TokenListFilters => { const { timeOption } = options; - const navigation = - useNavigation>>(); + const navigation = useNavigation(); const sessionManager = TrendingFeedSessionManager.getInstance(); const [selectedNetwork, setSelectedNetwork] = useState( diff --git a/app/components/UI/UrlAutocomplete/index.test.tsx b/app/components/UI/UrlAutocomplete/index.test.tsx index 3b43cee2db0..f40c6d973cf 100644 --- a/app/components/UI/UrlAutocomplete/index.test.tsx +++ b/app/components/UI/UrlAutocomplete/index.test.tsx @@ -150,7 +150,7 @@ import renderWithProvider, { } from '../../../util/test/renderWithProvider'; import { removeBookmark } from '../../../actions/bookmarks'; import { noop } from 'lodash'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { RpcEndpointType } from '@metamask/network-controller'; import { RootState } from '../../../reducers'; import { selectBasicFunctionalityEnabled } from '../../../selectors/settings'; @@ -207,7 +207,7 @@ const defaultState: DeepPartial = { type RenderWithProviderParams = Parameters; -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const render = (...args: RenderWithProviderParams) => { const Component = () => args[0]; return renderWithProvider( diff --git a/app/components/Views/ActivityView/index.test.tsx b/app/components/Views/ActivityView/index.test.tsx index 5b68eb3456c..6d0228d1a66 100644 --- a/app/components/Views/ActivityView/index.test.tsx +++ b/app/components/Views/ActivityView/index.test.tsx @@ -3,7 +3,7 @@ import ActivityView from '.'; import { BackHandler } from 'react-native'; import { backgroundState } from '../../../util/test/initial-root-state'; import renderWithProvider from '../../../util/test/renderWithProvider'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { cleanup, fireEvent, waitFor } from '@testing-library/react-native'; // eslint-disable-next-line import-x/no-namespace import * as networkManagerUtils from '../../UI/NetworkManager'; @@ -103,7 +103,7 @@ jest.mock('../../../component-library/components-temp/Tabs', () => { return { TabsList }; }); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const mockNavigation = { navigate: jest.fn(), diff --git a/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx b/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx index 42ffb201b4a..d66f1fda44a 100644 --- a/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx +++ b/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx @@ -20,8 +20,8 @@ import { import type { Hex } from '@metamask/utils'; import { SupportedCaipChainId } from '@metamask/multichain-network-controller'; import { formatChainIdToCaip } from '@metamask/bridge-controller'; -import { useNavigation, type ParamListBase } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import { useNavigation } from '@react-navigation/native'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { useSelector } from 'react-redux'; import Engine from '../../../../../core/Engine'; import { strings } from '../../../../../../locales/i18n'; @@ -193,7 +193,7 @@ const AddCustomToken = ({ const symbolInputRef = useRef(null); const decimalsInputRef = useRef(null); - const navigation = useNavigation>(); + const navigation = useNavigation(); const { colors, themeAppearance } = useTheme(); const { trackEvent, createEventBuilder } = useAnalytics(); const tw = useTailwind(); diff --git a/app/components/Views/Browser/Browser.components.test.tsx b/app/components/Views/Browser/Browser.components.test.tsx index c02153533ec..0c6f1dc975a 100644 --- a/app/components/Views/Browser/Browser.components.test.tsx +++ b/app/components/Views/Browser/Browser.components.test.tsx @@ -14,7 +14,7 @@ import { backgroundState } from '../../../util/test/initial-root-state'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { isTokenDiscoveryBrowserEnabled } from '../../../util/browser'; import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils'; import { captureScreen } from 'react-native-view-shot'; @@ -154,7 +154,7 @@ jest.mock('../../../util/Logger', () => ({ error: jest.fn(), })); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const mockStore = configureMockStore(); const routeMock = { diff --git a/app/components/Views/Browser/Browser.functions.test.tsx b/app/components/Views/Browser/Browser.functions.test.tsx index 33d2466bc4b..3300171b20b 100644 --- a/app/components/Views/Browser/Browser.functions.test.tsx +++ b/app/components/Views/Browser/Browser.functions.test.tsx @@ -11,7 +11,7 @@ import { backgroundState } from '../../../util/test/initial-root-state'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { act } from '@testing-library/react-native'; import { isTokenDiscoveryBrowserEnabled } from '../../../util/browser'; import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils'; @@ -139,7 +139,7 @@ jest.mock('../../../util/Logger', () => ({ error: jest.fn(), })); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const mockStore = configureMockStore(); const routeMock = { diff --git a/app/components/Views/Browser/Browser.lifecycle.test.tsx b/app/components/Views/Browser/Browser.lifecycle.test.tsx index 0fb4c953803..82bffa1fd22 100644 --- a/app/components/Views/Browser/Browser.lifecycle.test.tsx +++ b/app/components/Views/Browser/Browser.lifecycle.test.tsx @@ -14,7 +14,7 @@ import { backgroundState } from '../../../util/test/initial-root-state'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils'; import { MetaMetricsEvents } from '../../../core/Analytics'; // eslint-disable-next-line import-x/no-restricted-paths -- TODO(ADR-0020): route-isolation backlog @@ -152,7 +152,7 @@ jest.mock('../../../util/Logger', () => ({ error: jest.fn(), })); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const mockStore = configureMockStore(); const routeMock = { diff --git a/app/components/Views/Browser/Browser.rendering.test.tsx b/app/components/Views/Browser/Browser.rendering.test.tsx index e1f558d2884..2f17c8272fd 100644 --- a/app/components/Views/Browser/Browser.rendering.test.tsx +++ b/app/components/Views/Browser/Browser.rendering.test.tsx @@ -13,7 +13,7 @@ import { backgroundState } from '../../../util/test/initial-root-state'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { ThemeContext, mockTheme } from '../../../util/theme'; import { isTokenDiscoveryBrowserEnabled } from '../../../util/browser'; import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils'; @@ -161,7 +161,7 @@ jest.mock('../../../util/Logger', () => ({ error: jest.fn(), })); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const mockStore = configureMockStore(); const routeMock = { diff --git a/app/components/Views/Browser/Browser.tabs.test.tsx b/app/components/Views/Browser/Browser.tabs.test.tsx index 9e00c5d69cd..6b158a5ae5b 100644 --- a/app/components/Views/Browser/Browser.tabs.test.tsx +++ b/app/components/Views/Browser/Browser.tabs.test.tsx @@ -14,7 +14,7 @@ import { backgroundState } from '../../../util/test/initial-root-state'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { act } from '@testing-library/react-native'; import { isTokenDiscoveryBrowserEnabled } from '../../../util/browser'; import { MOCK_ACCOUNTS_CONTROLLER_STATE } from '../../../util/test/accountsControllerTestUtils'; @@ -154,7 +154,7 @@ jest.mock('../../../util/Logger', () => ({ error: jest.fn(), })); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const mockStore = configureMockStore(); const routeMock = { diff --git a/app/components/Views/DiscoveryTab/index.test.tsx b/app/components/Views/DiscoveryTab/index.test.tsx index 60d1ef3298a..720a1089101 100644 --- a/app/components/Views/DiscoveryTab/index.test.tsx +++ b/app/components/Views/DiscoveryTab/index.test.tsx @@ -7,7 +7,7 @@ import UrlAutocomplete, { UrlAutocompleteCategory, } from '../../UI/UrlAutocomplete'; import { screen, waitFor } from '@testing-library/react-native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { NavigationContainer } from '@react-navigation/native'; const mockNavigation = { @@ -66,7 +66,7 @@ const mockProps = { newTab: jest.fn(), }; -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); describe('DiscoveryTab', () => { it('should render correctly', async () => { diff --git a/app/components/Views/Homepage/Sections/TopTraders/TopTradersSection.tsx b/app/components/Views/Homepage/Sections/TopTraders/TopTradersSection.tsx index 929b2d804a8..fd0aabbeae4 100644 --- a/app/components/Views/Homepage/Sections/TopTraders/TopTradersSection.tsx +++ b/app/components/Views/Homepage/Sections/TopTraders/TopTradersSection.tsx @@ -5,7 +5,6 @@ import { } from '@metamask/design-system-react-native'; import { useTailwind } from '@metamask/design-system-twrnc-preset'; import { useNavigation } from '@react-navigation/native'; -import type { StackNavigationProp } from '@react-navigation/stack'; import React, { forwardRef, useCallback, @@ -18,7 +17,7 @@ import { ScrollView } from 'react-native-gesture-handler'; import { useSelector } from 'react-redux'; import { strings } from '../../../../../../locales/i18n'; import Routes from '../../../../../constants/navigation/Routes'; -import type { RootStackParamList } from '../../../../../core/NavigationService/types'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { selectSocialLeaderboardEnabled } from '../../../../../selectors/featureFlagController/socialLeaderboard'; import ErrorState from '../../components/ErrorState'; import ViewMoreCard from '../../components/ViewMoreCard'; @@ -58,7 +57,7 @@ const TopTradersSection = forwardRef< TopTradersSectionProps >(({ sectionIndex, totalSectionsLoaded }, ref) => { const sectionViewRef = useRef(null); - const navigation = useNavigation>(); + const navigation = useNavigation(); const tw = useTailwind(); const isEnabled = useSelector(selectSocialLeaderboardEnabled); const title = strings('homepage.sections.top_traders'); diff --git a/app/components/Views/ImportFromSecretRecoveryPhrase/index.test.tsx b/app/components/Views/ImportFromSecretRecoveryPhrase/index.test.tsx index 5344c0b3a77..b9bcdf6de57 100644 --- a/app/components/Views/ImportFromSecretRecoveryPhrase/index.test.tsx +++ b/app/components/Views/ImportFromSecretRecoveryPhrase/index.test.tsx @@ -19,7 +19,7 @@ import AUTHENTICATION_TYPE from '../../../constants/userProperties'; import { Alert, InteractionManager } from 'react-native'; // eslint-disable-next-line import-x/no-restricted-paths -- TODO(ADR-0020): route-isolation backlog import { QRTabSwitcherScreens } from '../QRTabSwitcher'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { NavigationContainer } from '@react-navigation/native'; import StorageWrapper from '../../../store/storage-wrapper'; import { passcodeType } from '../../../util/authentication'; @@ -686,7 +686,7 @@ describe('ImportFromSecretRecoveryPhrase', () => { it('calls navigation.goBack when back button is pressed on step 0', () => { const mockGoBack = jest.fn(); - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); const customRender = (children: React.ReactElement) => renderWithProvider( @@ -1019,7 +1019,7 @@ describe('ImportFromSecretRecoveryPhrase', () => { let navigationSpy: jest.SpyInstance; beforeEach(() => { - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); customRender = (children: React.ReactElement) => renderWithProvider( diff --git a/app/components/Views/ManualBackupStep1/ManualBackupStep1.types.ts b/app/components/Views/ManualBackupStep1/ManualBackupStep1.types.ts index 47b068a03f6..b8b0e80c729 100644 --- a/app/components/Views/ManualBackupStep1/ManualBackupStep1.types.ts +++ b/app/components/Views/ManualBackupStep1/ManualBackupStep1.types.ts @@ -1,5 +1,4 @@ -import { RouteProp } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; +import { RouteProp, type NavigationProp } from '@react-navigation/native'; /** * Route params for ManualBackupStep1 @@ -44,7 +43,7 @@ export interface BackupFlowParamList { /** * Navigation prop type with proper typing for navigate() calls */ -export type ManualBackupStep1NavigationProp = StackNavigationProp< +export type ManualBackupStep1NavigationProp = NavigationProp< BackupFlowParamList, 'ManualBackupStep1' >; diff --git a/app/components/Views/MultiRpcModal/MultiRpcModal.test.tsx b/app/components/Views/MultiRpcModal/MultiRpcModal.test.tsx index 27a46d09023..ca2a92e46e2 100644 --- a/app/components/Views/MultiRpcModal/MultiRpcModal.test.tsx +++ b/app/components/Views/MultiRpcModal/MultiRpcModal.test.tsx @@ -3,7 +3,7 @@ import MultiRpcModal from './MultiRpcModal'; import renderWithProvider, { DeepPartial, } from '../../../util/test/renderWithProvider'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import Routes from '../../../constants/navigation/Routes'; import Engine from '../../../core/Engine'; import { fireEvent } from '@testing-library/react-native'; @@ -29,7 +29,7 @@ const initialState = { }, }; -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const renderComponent = (state: DeepPartial = {}) => renderWithProvider( diff --git a/app/components/Views/MultichainAccounts/MultichainAccountConnect/MultichainAccountConnect.stories.tsx b/app/components/Views/MultichainAccounts/MultichainAccountConnect/MultichainAccountConnect.stories.tsx index fdafec4f698..61f0ae53411 100644 --- a/app/components/Views/MultichainAccounts/MultichainAccountConnect/MultichainAccountConnect.stories.tsx +++ b/app/components/Views/MultichainAccounts/MultichainAccountConnect/MultichainAccountConnect.stories.tsx @@ -4,7 +4,7 @@ import { configureStore } from '@reduxjs/toolkit'; import { AccountGroupType, AccountGroupId } from '@metamask/account-api'; import { Box, Toaster } from '@metamask/design-system-react-native'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { Caip25EndowmentPermissionName, Caip25CaveatValue, @@ -16,7 +16,7 @@ import { AccountGroupWithInternalAccounts } from '../../../../selectors/multicha import { AccountConnectProps } from '../../MultichainAccounts/shared/AccountConnect.types'; import { createMockInternalAccount } from '../../../../util/test/accountsControllerTestUtils'; -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const createMockAccountGroupWithInternalAccounts = ( id: string, diff --git a/app/components/Views/NFTAutoDetectionModal/NFTAutoDetectionModal.test.tsx b/app/components/Views/NFTAutoDetectionModal/NFTAutoDetectionModal.test.tsx index cbe81817711..6499508305f 100644 --- a/app/components/Views/NFTAutoDetectionModal/NFTAutoDetectionModal.test.tsx +++ b/app/components/Views/NFTAutoDetectionModal/NFTAutoDetectionModal.test.tsx @@ -3,7 +3,7 @@ import NFTAutoDetectionModal from './NFTAutoDetectionModal'; import renderWithProvider, { DeepPartial, } from '../../../util/test/renderWithProvider'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import Routes from '../../../constants/navigation/Routes'; import Engine from '../../../core/Engine'; import { fireEvent } from '@testing-library/react-native'; @@ -44,7 +44,7 @@ jest.mock('../../hooks/useAnalytics/useAnalytics'); const mockTrackEvent = jest.fn(); const mockIdentify = jest.fn(); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const renderComponent = (state: DeepPartial = {}) => renderWithProvider( diff --git a/app/components/Views/NetworkSelector/NetworkSelector.test.tsx b/app/components/Views/NetworkSelector/NetworkSelector.test.tsx index ce7fcab40ac..97286b443e6 100644 --- a/app/components/Views/NetworkSelector/NetworkSelector.test.tsx +++ b/app/components/Views/NetworkSelector/NetworkSelector.test.tsx @@ -1,6 +1,6 @@ // Third party dependencies import React from 'react'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { fireEvent, waitFor, screen } from '@testing-library/react-native'; // External dependencies @@ -308,7 +308,7 @@ const initialState = { }, }; -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const createMockRoute = () => ({ params: {}, diff --git a/app/components/Views/Onboarding/FastOnboarding.test.tsx b/app/components/Views/Onboarding/FastOnboarding.test.tsx index a1f3d01b2a9..13fb7777f70 100644 --- a/app/components/Views/Onboarding/FastOnboarding.test.tsx +++ b/app/components/Views/Onboarding/FastOnboarding.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { render } from '@testing-library/react-native'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import FastOnboarding from './FastOnboarding'; // Mock navigation hooks @@ -30,7 +30,7 @@ describe('FastOnboarding Component', () => { // Helper function to render component with navigation context const renderWithNavigation = (component: React.ReactElement) => { - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); const TestComponent = () => component; return render( diff --git a/app/components/Views/Onboarding/index.test.tsx b/app/components/Views/Onboarding/index.test.tsx index cd0b72d0740..296f3a00447 100644 --- a/app/components/Views/Onboarding/index.test.tsx +++ b/app/components/Views/Onboarding/index.test.tsx @@ -299,8 +299,8 @@ const mockNav = { } }), }; -jest.mock('@react-navigation/stack', () => ({ - createStackNavigator: () => ({ +jest.mock('@react-navigation/native-stack', () => ({ + createNativeStackNavigator: () => ({ Navigator: ({ children }: { children: React.ReactNode }) => <>{children}, Screen: ({ component: ScreenComponent, diff --git a/app/components/Views/OnboardingSheet/OnboardingSheet.test.tsx b/app/components/Views/OnboardingSheet/OnboardingSheet.test.tsx index 39ee6975429..3c078d86b31 100644 --- a/app/components/Views/OnboardingSheet/OnboardingSheet.test.tsx +++ b/app/components/Views/OnboardingSheet/OnboardingSheet.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { fireEvent, render } from '@testing-library/react-native'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { ThemeContext, mockTheme } from '../../../util/theme'; import OnboardingSheet from '.'; @@ -38,7 +38,7 @@ jest.mock('@react-navigation/native', () => ({ }), })); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); function OnboardingSheetScreen() { return ; diff --git a/app/components/Views/Pna25BottomSheet/Pna25BottomSheet.test.tsx b/app/components/Views/Pna25BottomSheet/Pna25BottomSheet.test.tsx index acfb229596a..7f8a60bf058 100644 --- a/app/components/Views/Pna25BottomSheet/Pna25BottomSheet.test.tsx +++ b/app/components/Views/Pna25BottomSheet/Pna25BottomSheet.test.tsx @@ -5,7 +5,7 @@ import renderWithProvider from '../../../util/test/renderWithProvider'; import { strings } from '../../../../locales/i18n'; import Routes from '../../../constants/navigation/Routes'; import { Linking } from 'react-native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { MetaMetricsEvents } from '../../../core/Analytics'; import Engine from '../../../core/Engine'; @@ -86,7 +86,7 @@ jest.mock( }, ); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const renderComponent = (state = {}) => renderWithProvider( diff --git a/app/components/Views/Settings/Contacts/index.test.tsx b/app/components/Views/Settings/Contacts/index.test.tsx index aeabf6d57ad..94490d1b279 100644 --- a/app/components/Views/Settings/Contacts/index.test.tsx +++ b/app/components/Views/Settings/Contacts/index.test.tsx @@ -4,7 +4,7 @@ import { fireEvent } from '@testing-library/react-native'; import renderWithProvider, { renderScreen, } from '../../../../util/test/renderWithProvider'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import Contacts from './'; import { strings } from '../../../../../locales/i18n'; import { backgroundState } from '../../../../util/test/initial-root-state'; @@ -16,7 +16,7 @@ const initialState = { }, }; -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const PLACEHOLDER_SCREEN_TEST_ID = 'contacts-test-placeholder-screen'; const GO_TO_CONTACTS_TEST_ID = 'contacts-test-go-to-contacts'; diff --git a/app/components/Views/ShowDisplayMediaNFTSheet/ShowDisplayNFTMediaSheet.test.tsx b/app/components/Views/ShowDisplayMediaNFTSheet/ShowDisplayNFTMediaSheet.test.tsx index 50ccab9f97f..f8a21ac76a8 100644 --- a/app/components/Views/ShowDisplayMediaNFTSheet/ShowDisplayNFTMediaSheet.test.tsx +++ b/app/components/Views/ShowDisplayMediaNFTSheet/ShowDisplayNFTMediaSheet.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import renderWithProvider from '../../../util/test/renderWithProvider'; import { backgroundState } from '../../../util/test/initial-root-state'; @@ -39,7 +39,7 @@ jest.mocked(useAnalytics).mockReturnValue( }), ); -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); describe('ShowNftSheet', () => { beforeEach(() => { diff --git a/app/components/Views/SocialLeaderboard/TraderPositionView/TraderPositionView.tsx b/app/components/Views/SocialLeaderboard/TraderPositionView/TraderPositionView.tsx index aeb187f3ea1..1703fbed7e4 100644 --- a/app/components/Views/SocialLeaderboard/TraderPositionView/TraderPositionView.tsx +++ b/app/components/Views/SocialLeaderboard/TraderPositionView/TraderPositionView.tsx @@ -13,8 +13,10 @@ import { useRoute, type RouteProp, } from '@react-navigation/native'; -import type { StackNavigationProp } from '@react-navigation/stack'; -import type { RootStackParamList } from '../../../../core/NavigationService/types'; +import type { + AppNavigationProp, + RootStackParamList, +} from '../../../../core/NavigationService/types'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useTailwind } from '@metamask/design-system-twrnc-preset'; import { playImpact, ImpactMoment } from '../../../../util/haptics'; @@ -62,7 +64,7 @@ import { import { toAssetId } from '../../../UI/Bridge/hooks/useAssetMetadata/utils'; const TraderPositionView = () => { - const navigation = useNavigation>(); + const navigation = useNavigation(); const route = useRoute>(); const tw = useTailwind(); const { colors } = useTheme(); diff --git a/app/components/Views/TransactionsView/index.test.tsx b/app/components/Views/TransactionsView/index.test.tsx index 0a07439d3e4..a01ef4d0c94 100644 --- a/app/components/Views/TransactionsView/index.test.tsx +++ b/app/components/Views/TransactionsView/index.test.tsx @@ -4,7 +4,7 @@ import { act, render } from '@testing-library/react-native'; import configureMockStore from 'redux-mock-store'; import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { EthMethod, SolAccountType, @@ -192,7 +192,7 @@ import { selectSelectedInternalAccount } from '../../../selectors/accountsContro import { selectSortedTransactions } from '../../../selectors/transactionController'; const TRANSACTION_ID_MOCK = '123'; -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const mockStore = configureMockStore(); interface MockTransaction { diff --git a/app/components/Views/TrendingView/TrendingView.test.tsx b/app/components/Views/TrendingView/TrendingView.test.tsx index 944ec4a34ca..5a8aa998d9d 100644 --- a/app/components/Views/TrendingView/TrendingView.test.tsx +++ b/app/components/Views/TrendingView/TrendingView.test.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { render, fireEvent } from '@testing-library/react-native'; import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; const mockNavigate = jest.fn(); @@ -43,7 +43,7 @@ import { selectBasicFunctionalityEnabled } from '../../../selectors/settings'; import { useSelector } from 'react-redux'; import Routes from '../../../constants/navigation/Routes'; -const Stack = createStackNavigator(); +const Stack = createNativeStackNavigator(); const TrendingView: React.FC = () => ( ({ children, })); -jest.mock('@react-navigation/stack', () => ({ - createStackNavigator: jest.fn(() => ({ +jest.mock('@react-navigation/native-stack', () => ({ + createNativeStackNavigator: jest.fn(() => ({ Navigator: ({ children }: { children: React.ReactNode }) => children, Screen: ({ children }: { children: React.ReactNode }) => children, })), diff --git a/app/components/Views/confirmations/hooks/send/useSendNavbar.test.tsx b/app/components/Views/confirmations/hooks/send/useSendNavbar.test.tsx index 677f626e7ea..fbc3d006781 100644 --- a/app/components/Views/confirmations/hooks/send/useSendNavbar.test.tsx +++ b/app/components/Views/confirmations/hooks/send/useSendNavbar.test.tsx @@ -15,8 +15,8 @@ jest.mock('@react-navigation/native', () => ({ createNavigatorFactory: jest.fn(), })); -jest.mock('@react-navigation/stack', () => ({ - createStackNavigator: jest.fn(() => ({ +jest.mock('@react-navigation/native-stack', () => ({ + createNativeStackNavigator: jest.fn(() => ({ Navigator: ({ children }: { children: React.ReactNode }) => children, Screen: ({ children }: { children: React.ReactNode }) => children, })), diff --git a/app/components/Views/confirmations/hooks/ui/useClearConfirmationOnBackSwipe.ts b/app/components/Views/confirmations/hooks/ui/useClearConfirmationOnBackSwipe.ts index 19c771bbb3b..31ef4f8f3e5 100644 --- a/app/components/Views/confirmations/hooks/ui/useClearConfirmationOnBackSwipe.ts +++ b/app/components/Views/confirmations/hooks/ui/useClearConfirmationOnBackSwipe.ts @@ -1,15 +1,14 @@ import { useNavigation } from '@react-navigation/native'; -import { StackNavigationProp } from '@react-navigation/stack'; import { useCallback, useEffect, useRef } from 'react'; import { BackHandler } from 'react-native'; import Device from '../../../../../util/device'; import { useConfirmActions } from '../useConfirmActions'; import { useFullScreenConfirmation } from './useFullScreenConfirmation'; -import type { RootStackParamList } from '../../../../../core/NavigationService/types'; +import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; import { useConfirmationContext } from '../../context/confirmation-context'; const useClearConfirmationOnBackSwipe = () => { - const navigation = useNavigation>(); + const navigation = useNavigation(); const { isFullScreenConfirmation } = useFullScreenConfirmation(); const { onReject } = useConfirmActions(); const { isConfirmationSubmittingRef } = useConfirmationContext(); diff --git a/app/core/NavigationService/types.ts b/app/core/NavigationService/types.ts index b886756bf26..89ca70a872d 100644 --- a/app/core/NavigationService/types.ts +++ b/app/core/NavigationService/types.ts @@ -1,8 +1,5 @@ -import type { - ParamListBase, - NavigationProp, - NavigationState, -} from '@react-navigation/native'; +import type { ParamListBase, NavigationState } from '@react-navigation/native'; +import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; import type { Position } from '@metamask/social-controllers'; // ============================================================================ @@ -766,7 +763,7 @@ declare global { * Uses ReactNavigation.RootParamList to match the global declaration. */ export type AppNavigationProp = Omit< - NavigationProp, + NativeStackNavigationProp, 'getState' > & { getState(): NavigationState | undefined; diff --git a/app/util/test/renderWithProvider.tsx b/app/util/test/renderWithProvider.tsx index fe1b721096b..a535e9c977d 100644 --- a/app/util/test/renderWithProvider.tsx +++ b/app/util/test/renderWithProvider.tsx @@ -3,9 +3,9 @@ import { Provider } from 'react-redux'; import { NavigationContainer } from '@react-navigation/native'; import { - createStackNavigator, - StackNavigationOptions, -} from '@react-navigation/stack'; + createNativeStackNavigator, + NativeStackNavigationOptions, +} from '@react-navigation/native-stack'; import { render, renderHook, @@ -106,14 +106,14 @@ export function renderScreen( Component: React.ComponentType, options: { name: string; - options?: StackNavigationOptions; + options?: NativeStackNavigationOptions; }, providerValues?: ProviderValues, // TODO: Replace "any" with type // eslint-disable-next-line @typescript-eslint/no-explicit-any initialParams: Record = {}, ) { - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); return renderWithProvider( , ) { - const Stack = createStackNavigator(); + const Stack = createNativeStackNavigator(); const DefaultRouteProbe = (routeName: string): React.FC => diff --git a/tests/component-view/renderers/marketInsights.tsx b/tests/component-view/renderers/marketInsights.tsx index 0af66fe1b30..c35fbb09f70 100644 --- a/tests/component-view/renderers/marketInsights.tsx +++ b/tests/component-view/renderers/marketInsights.tsx @@ -1,7 +1,7 @@ import '../mocks'; import React from 'react'; import { Text } from 'react-native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import renderWithProvider, { type DeepPartial, } from '../../../app/util/test/renderWithProvider'; @@ -15,10 +15,10 @@ import { fiatOrdersRampRoutingSupported, } from '../presets/marketInsightsView'; -const RootStack = createStackNavigator(); -const BridgeInnerStack = createStackNavigator(); -const RampMainStack = createStackNavigator(); -const RampOuterStack = createStackNavigator(); +const RootStack = createNativeStackNavigator(); +const BridgeInnerStack = createNativeStackNavigator(); +const RampMainStack = createNativeStackNavigator(); +const RampOuterStack = createNativeStackNavigator(); const BridgeViewProbe = (): React.ReactElement => ( BridgeView diff --git a/tests/component-view/renderers/perpsViewRenderer.tsx b/tests/component-view/renderers/perpsViewRenderer.tsx index f8f970e0cb7..05308bd33a6 100644 --- a/tests/component-view/renderers/perpsViewRenderer.tsx +++ b/tests/component-view/renderers/perpsViewRenderer.tsx @@ -1,7 +1,7 @@ import '../mocks'; import React from 'react'; import { Text } from 'react-native'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import renderWithProvider, { type DeepPartial, @@ -397,8 +397,8 @@ export function renderPerpsView( }; if (extraRoutes?.length) { - const Stack = createStackNavigator(); - const InnerStack = createStackNavigator(); + const Stack = createNativeStackNavigator(); + const InnerStack = createNativeStackNavigator(); const nestedPerpsRoutes = extraRoutes.filter( ({ mount }) => mount === 'perps-root', ); diff --git a/tests/component-view/renderers/ramps.tsx b/tests/component-view/renderers/ramps.tsx index f6e68be0df6..996306a647b 100644 --- a/tests/component-view/renderers/ramps.tsx +++ b/tests/component-view/renderers/ramps.tsx @@ -1,7 +1,7 @@ import '../mocks'; import React from 'react'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { createStackNavigator } from '@react-navigation/stack'; +import { createNativeStackNavigator } from '@react-navigation/native-stack'; import type { CryptoCurrency, FiatCurrency, @@ -210,7 +210,7 @@ interface RootModalFlowProps { const RootModalFlow = ({ route }: RootModalFlowProps) => { const initialScreen = route.params?.screen ?? Routes.SHEET.ACCOUNT_SELECTOR; - const ModalStack = createStackNavigator(); + const ModalStack = createNativeStackNavigator(); return ( ( @@ -538,9 +538,9 @@ export function renderV2BuildQuoteWithRoutes( } const state = stateOverride ?? builder.build(); - const RootStack = createStackNavigator(); - const MainStack = createStackNavigator(); - const ModalsStack = createStackNavigator(); + const RootStack = createNativeStackNavigator(); + const MainStack = createNativeStackNavigator(); + const ModalsStack = createNativeStackNavigator(); const MainRoutes = () => ( Date: Fri, 19 Jun 2026 12:16:51 -0700 Subject: [PATCH 2/6] fix type error --- .../CreatePriceAlertView.tsx | 4 ++-- .../ManagePriceAlertsView.tsx | 4 ++-- .../BatchSellFinalReviewModal/index.tsx | 4 ++-- .../index.tsx | 4 ++-- .../BatchSellNetworkFeeInfoModal/index.tsx | 4 ++-- .../BatchSellQuoteDetailsModal/index.tsx | 4 ++-- .../components/TokenWarningModal/index.tsx | 4 ++-- .../Views/CardHome/hooks/useCardHomeActions.ts | 3 ++- .../DeFiProtocolPositionDetails.tsx | 4 ++-- .../ErrorDetailsModal/ErrorDetailsModal.tsx | 4 ++-- .../AddCustomToken/AddCustomToken.tsx | 4 ++-- app/core/NavigationService/types.ts | 18 +++++++++++++++++- 12 files changed, 39 insertions(+), 22 deletions(-) diff --git a/app/components/UI/Assets/PriceAlerts/Views/CreatePriceAlertView/CreatePriceAlertView.tsx b/app/components/UI/Assets/PriceAlerts/Views/CreatePriceAlertView/CreatePriceAlertView.tsx index 26272822396..8c98dbb1c69 100644 --- a/app/components/UI/Assets/PriceAlerts/Views/CreatePriceAlertView/CreatePriceAlertView.tsx +++ b/app/components/UI/Assets/PriceAlerts/Views/CreatePriceAlertView/CreatePriceAlertView.tsx @@ -18,7 +18,7 @@ import { useRoute, type RouteProp, } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../../core/NavigationService/types'; import { SafeAreaView } from 'react-native-safe-area-context'; import { Box, @@ -107,7 +107,7 @@ const viewStyles = StyleSheet.create({ const CreatePriceAlertView: React.FC = () => { const tw = useTailwind(); const { colors, brandColors } = useTheme(); - const navigation = useNavigation(); + const navigation = useNavigation(); const route = useRoute< RouteProp< diff --git a/app/components/UI/Assets/PriceAlerts/Views/ManagePriceAlertsView/ManagePriceAlertsView.tsx b/app/components/UI/Assets/PriceAlerts/Views/ManagePriceAlertsView/ManagePriceAlertsView.tsx index cda20ee0ee9..ea9c234d32a 100644 --- a/app/components/UI/Assets/PriceAlerts/Views/ManagePriceAlertsView/ManagePriceAlertsView.tsx +++ b/app/components/UI/Assets/PriceAlerts/Views/ManagePriceAlertsView/ManagePriceAlertsView.tsx @@ -18,7 +18,7 @@ import { useRoute, type RouteProp, } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../../core/NavigationService/types'; import { SafeAreaView } from 'react-native-safe-area-context'; import { Box, @@ -62,7 +62,7 @@ const ManagePriceAlertsView: React.FC = () => { const { colors, brandColors } = useTheme(); const queryClient = useQueryClient(); const { toastRef } = useContext(ToastContext); - const navigation = useNavigation(); + const navigation = useNavigation(); const route = useRoute< RouteProp< diff --git a/app/components/UI/Bridge/components/BatchSellFinalReviewModal/index.tsx b/app/components/UI/Bridge/components/BatchSellFinalReviewModal/index.tsx index 7ac75a681c2..f0eafd15384 100644 --- a/app/components/UI/Bridge/components/BatchSellFinalReviewModal/index.tsx +++ b/app/components/UI/Bridge/components/BatchSellFinalReviewModal/index.tsx @@ -1,5 +1,5 @@ import { useNavigation } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../core/NavigationService/types'; import React, { useCallback, useMemo, useRef, useState } from 'react'; import { Pressable } from 'react-native'; import { useDispatch, useSelector } from 'react-redux'; @@ -290,7 +290,7 @@ function NetworkFeeRow({ export function BatchSellFinalReviewModal() { const dispatch = useDispatch(); - const navigation = useNavigation(); + const navigation = useNavigation(); const selectedTokens = useSelector(selectBatchSellSourceTokens); const isSubmittingTx = useSelector(selectIsSubmittingTx); const batchSellQuoteData = useBatchSellQuoteData({ diff --git a/app/components/UI/Bridge/components/BatchSellMinimumReceivedInfoModal/index.tsx b/app/components/UI/Bridge/components/BatchSellMinimumReceivedInfoModal/index.tsx index a87b8de3421..06834dc14c3 100644 --- a/app/components/UI/Bridge/components/BatchSellMinimumReceivedInfoModal/index.tsx +++ b/app/components/UI/Bridge/components/BatchSellMinimumReceivedInfoModal/index.tsx @@ -1,5 +1,5 @@ import { useNavigation } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../core/NavigationService/types'; import React from 'react'; import { BottomSheet, @@ -18,7 +18,7 @@ import { BatchSellMinimumReceivedInfoModalParams } from './BatchSellMinimumRecei import { useElevatedSurface } from '../../../../../util/theme/themeUtils'; export function BatchSellMinimumReceivedInfoModal() { - const navigation = useNavigation(); + const navigation = useNavigation(); const { sourceModal } = useParams(); const handleBack = sourceModal ? () => navigation.replace(sourceModal.screen, sourceModal.params) diff --git a/app/components/UI/Bridge/components/BatchSellNetworkFeeInfoModal/index.tsx b/app/components/UI/Bridge/components/BatchSellNetworkFeeInfoModal/index.tsx index 5daf5eb5b26..8893d42bb5e 100644 --- a/app/components/UI/Bridge/components/BatchSellNetworkFeeInfoModal/index.tsx +++ b/app/components/UI/Bridge/components/BatchSellNetworkFeeInfoModal/index.tsx @@ -1,5 +1,5 @@ import { useNavigation } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../core/NavigationService/types'; import React from 'react'; import { BottomSheet, @@ -18,7 +18,7 @@ import { BatchSellNetworkFeeInfoModalParams } from './BatchSellNetworkFeeInfoMod import { useElevatedSurface } from '../../../../../util/theme/themeUtils'; export function BatchSellNetworkFeeInfoModal() { - const navigation = useNavigation(); + const navigation = useNavigation(); const { sourceModal } = useParams(); const handleBack = sourceModal ? () => navigation.replace(sourceModal.screen, sourceModal.params) diff --git a/app/components/UI/Bridge/components/BatchSellQuoteDetailsModal/index.tsx b/app/components/UI/Bridge/components/BatchSellQuoteDetailsModal/index.tsx index 28d89c93aaa..2dd9a803088 100644 --- a/app/components/UI/Bridge/components/BatchSellQuoteDetailsModal/index.tsx +++ b/app/components/UI/Bridge/components/BatchSellQuoteDetailsModal/index.tsx @@ -1,5 +1,5 @@ import { useNavigation } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../core/NavigationService/types'; import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; import { @@ -20,7 +20,7 @@ import { strings } from '../../../../../../locales/i18n'; import { useElevatedSurface } from '../../../../../util/theme/themeUtils'; export function BatchSellQuoteDetailsModal() { - const navigation = useNavigation(); + const navigation = useNavigation(); const sourceTokens = useSelector(selectBatchSellSourceTokens); const surfaceClass = useElevatedSurface(); const batchSellQuoteData = useBatchSellQuoteData({ diff --git a/app/components/UI/Bridge/components/TokenWarningModal/index.tsx b/app/components/UI/Bridge/components/TokenWarningModal/index.tsx index a6d80989f13..32d459fe412 100644 --- a/app/components/UI/Bridge/components/TokenWarningModal/index.tsx +++ b/app/components/UI/Bridge/components/TokenWarningModal/index.tsx @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux'; // Must use this to make sure scroll works inside a bottom sheet on Android import { ScrollView } from 'react-native-gesture-handler'; import { useNavigation } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../core/NavigationService/types'; import { MetaMetricsSwapsEventSource } from '@metamask/bridge-controller'; import BottomSheet, { BottomSheetRef, @@ -90,7 +90,7 @@ export const getTokenWarningContent = ( }; export const TokenWarningModal = () => { - const navigation = useNavigation(); + const navigation = useNavigation(); const sheetRef = useRef(null); const [loading, setLoading] = useState(false); diff --git a/app/components/UI/Card/Views/CardHome/hooks/useCardHomeActions.ts b/app/components/UI/Card/Views/CardHome/hooks/useCardHomeActions.ts index c9758b859f5..8dacea59d8d 100644 --- a/app/components/UI/Card/Views/CardHome/hooks/useCardHomeActions.ts +++ b/app/components/UI/Card/Views/CardHome/hooks/useCardHomeActions.ts @@ -1,6 +1,7 @@ import { useCallback, useContext } from 'react'; import { Alert } from 'react-native'; import { useNavigation } from '@react-navigation/native'; +import type { AppNavigationProp } from '../../../../../../core/NavigationService/types'; import { useSelector } from 'react-redux'; import Engine from '../../../../../../core/Engine'; import { useTheme } from '../../../../../../util/theme'; @@ -42,7 +43,7 @@ export function useCardHomeActions({ primaryToken, isFrozen, }: UseCardHomeActionsParams) { - const navigation = useNavigation(); + const navigation = useNavigation(); const isAuthenticated = useSelector(selectIsCardAuthenticated); const { trackEvent, createEventBuilder } = useAnalytics(); const theme = useTheme(); diff --git a/app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.tsx b/app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.tsx index fe41f1e0554..3c9d44166f9 100644 --- a/app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.tsx +++ b/app/components/UI/DeFiPositions/DeFiProtocolPositionDetails.tsx @@ -3,7 +3,7 @@ import { GroupedDeFiPositions } from '@metamask/assets-controllers'; import { ImageSourcePropType, View } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { useNavigation } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../core/NavigationService/types'; import { HeaderStandard } from '@metamask/design-system-react-native'; import styleSheet from './DeFiProtocolPositionDetails.styles'; import { useParams } from '../../../util/navigation/navUtils'; @@ -35,7 +35,7 @@ interface DeFiProtocolPositionDetailsParams { const DeFiProtocolPositionDetails: React.FC = () => { const { styles } = useStyles(styleSheet, undefined); - const navigation = useNavigation(); + const navigation = useNavigation(); const { protocolAggregate, networkIconAvatar } = useParams(); diff --git a/app/components/UI/Ramp/Views/Modals/ErrorDetailsModal/ErrorDetailsModal.tsx b/app/components/UI/Ramp/Views/Modals/ErrorDetailsModal/ErrorDetailsModal.tsx index 496c23ed8a3..f6474db7c9e 100644 --- a/app/components/UI/Ramp/Views/Modals/ErrorDetailsModal/ErrorDetailsModal.tsx +++ b/app/components/UI/Ramp/Views/Modals/ErrorDetailsModal/ErrorDetailsModal.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useRef } from 'react'; import { View, ScrollView, useWindowDimensions } from 'react-native'; import InAppBrowser from 'react-native-inappbrowser-reborn'; import { useNavigation } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../../core/NavigationService/types'; import { BottomSheet, Button, @@ -45,7 +45,7 @@ export const createErrorDetailsModalNavDetails = function ErrorDetailsModal() { const sheetRef = useRef(null); - const navigation = useNavigation(); + const navigation = useNavigation(); const { height: screenHeight } = useWindowDimensions(); const { styles } = useStyles(styleSheet, { screenHeight, diff --git a/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx b/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx index d66f1fda44a..a69d42cd4f0 100644 --- a/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx +++ b/app/components/Views/AddAsset/components/AddCustomToken/AddCustomToken.tsx @@ -21,7 +21,7 @@ import type { Hex } from '@metamask/utils'; import { SupportedCaipChainId } from '@metamask/multichain-network-controller'; import { formatChainIdToCaip } from '@metamask/bridge-controller'; import { useNavigation } from '@react-navigation/native'; -import type { AppNavigationProp } from '../../../../../core/NavigationService/types'; +import type { AppStackNavigationProp } from '../../../../../core/NavigationService/types'; import { useSelector } from 'react-redux'; import Engine from '../../../../../core/Engine'; import { strings } from '../../../../../../locales/i18n'; @@ -193,7 +193,7 @@ const AddCustomToken = ({ const symbolInputRef = useRef(null); const decimalsInputRef = useRef(null); - const navigation = useNavigation(); + const navigation = useNavigation(); const { colors, themeAppearance } = useTheme(); const { trackEvent, createEventBuilder } = useAnalytics(); const tw = useTailwind(); diff --git a/app/core/NavigationService/types.ts b/app/core/NavigationService/types.ts index 89ca70a872d..388d64aa2c7 100644 --- a/app/core/NavigationService/types.ts +++ b/app/core/NavigationService/types.ts @@ -1,4 +1,8 @@ -import type { ParamListBase, NavigationState } from '@react-navigation/native'; +import type { + ParamListBase, + NavigationProp, + NavigationState, +} from '@react-navigation/native'; import type { NativeStackNavigationProp } from '@react-navigation/native-stack'; import type { Position } from '@metamask/social-controllers'; @@ -763,6 +767,18 @@ declare global { * Uses ReactNavigation.RootParamList to match the global declaration. */ export type AppNavigationProp = Omit< + NavigationProp, + 'getState' +> & { + getState(): NavigationState | undefined; +}; + +/** + * Use when calling stack-only APIs (`replace`, `push`, `pop`, `popToTop`). + * Mirrors {@link AppNavigationProp}'s `getState()` override, which accounts for + * `getState()` potentially returning undefined when the navigator is not mounted. + */ +export type AppStackNavigationProp = Omit< NativeStackNavigationProp, 'getState' > & { From bd365c9e19205acb7f05f197ff06afec9abd7988 Mon Sep 17 00:00:00 2001 From: Wei Sun Date: Fri, 19 Jun 2026 13:10:50 -0700 Subject: [PATCH 3/6] add react-native-screens mock --- app/util/test/testSetup.js | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/app/util/test/testSetup.js b/app/util/test/testSetup.js index 6835aa4489e..b39d384585e 100644 --- a/app/util/test/testSetup.js +++ b/app/util/test/testSetup.js @@ -819,6 +819,37 @@ if (typeof Reanimated.useAnimatedGestureHandler !== 'function') { global.__DEV__ = false; +// Mock react-native-screens so @react-navigation/native-stack renders plain +// views in Jest. The real Screen components attach Animated listeners that +// throw "Cannot read properties of undefined (reading 'remove')" during unmount +// under fake timers. Rendering them as Views keeps native-stack navigators +// (used by renderScreen and migrated test files) working in jsdom. +jest.mock('react-native-screens', () => { + const React = require('react'); + const { View } = require('react-native'); + const actual = jest.requireActual('react-native-screens'); + + const asView = (displayName) => { + const Component = React.forwardRef((props, ref) => + React.createElement(View, { ...props, ref }), + ); + Component.displayName = displayName; + return Component; + }; + + return { + ...actual, + enableScreens: jest.fn(), + enableFreeze: jest.fn(), + screensEnabled: jest.fn(() => false), + Screen: asView('Screen'), + ScreenContainer: asView('ScreenContainer'), + ScreenStack: asView('ScreenStack'), + ScreenStackHeaderConfig: asView('ScreenStackHeaderConfig'), + ScreenStackHeaderSubview: asView('ScreenStackHeaderSubview'), + }; +}); + // Custom snapshot serializer to handle Reanimated shared value proxies. expect.addSnapshotSerializer({ test: (val) => From bb4b8e41bc9fa6a8d06ac2a41120bba75bc792e7 Mon Sep 17 00:00:00 2001 From: Wei Sun Date: Fri, 19 Jun 2026 18:16:31 -0700 Subject: [PATCH 4/6] fix component view test --- .../Views/Modals/SettingsModal/SettingsModal.tsx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/components/UI/Ramp/Views/Modals/SettingsModal/SettingsModal.tsx b/app/components/UI/Ramp/Views/Modals/SettingsModal/SettingsModal.tsx index ca73b015fc5..4ce0f138896 100644 --- a/app/components/UI/Ramp/Views/Modals/SettingsModal/SettingsModal.tsx +++ b/app/components/UI/Ramp/Views/Modals/SettingsModal/SettingsModal.tsx @@ -107,12 +107,13 @@ function SettingsModal() { }) .build(), ); - sheetRef.current?.onCloseBottomSheet(); - navigation.navigate(Routes.TRANSACTIONS_VIEW, { - screen: Routes.TRANSACTIONS_VIEW, - params: { - redirectToOrders: true, - }, + sheetRef.current?.onCloseBottomSheet(() => { + navigation.navigate(Routes.TRANSACTIONS_VIEW, { + screen: Routes.TRANSACTIONS_VIEW, + params: { + redirectToOrders: true, + }, + }); }); }, [navigation, trackEvent, createEventBuilder]); From 2b15cad6c252db42716b5542e0ba6d5dc2e40b18 Mon Sep 17 00:00:00 2001 From: Wei Sun Date: Mon, 22 Jun 2026 15:01:33 -0700 Subject: [PATCH 5/6] fix unit test --- .../EarnWithdrawInputView/EarnWithdrawInputView.test.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/components/UI/Earn/Views/EarnWithdrawInputView/EarnWithdrawInputView.test.tsx b/app/components/UI/Earn/Views/EarnWithdrawInputView/EarnWithdrawInputView.test.tsx index 0747184b7fb..2eda090225c 100644 --- a/app/components/UI/Earn/Views/EarnWithdrawInputView/EarnWithdrawInputView.test.tsx +++ b/app/components/UI/Earn/Views/EarnWithdrawInputView/EarnWithdrawInputView.test.tsx @@ -973,6 +973,12 @@ describe('EarnWithdrawInputView', () => { await act(async () => { fireEvent.press(screen.getByText('1')); }); + + // Reveal the TRON unstake preview, which renders the "Unstake" button. + await act(async () => { + fireEvent.press(screen.getByText('Done')); + }); + await waitFor(() => { expect(screen.getAllByText('Unstake')[0]).toBeOnTheScreen(); }); From efd6a3f67f2bf6be837d0de84bf4a304b5c8b47d Mon Sep 17 00:00:00 2001 From: Wei Sun Date: Tue, 23 Jun 2026 12:43:44 -0700 Subject: [PATCH 6/6] remove @react-native/stack --- .../navigation/clearStackNavigatorOptions.ts | 26 +------------------ package.json | 1 - yarn.lock | 19 -------------- 3 files changed, 1 insertion(+), 45 deletions(-) diff --git a/app/constants/navigation/clearStackNavigatorOptions.ts b/app/constants/navigation/clearStackNavigatorOptions.ts index 71cb50b852f..1d55ea0c513 100644 --- a/app/constants/navigation/clearStackNavigatorOptions.ts +++ b/app/constants/navigation/clearStackNavigatorOptions.ts @@ -1,31 +1,7 @@ import type { NativeStackNavigationOptions } from '@react-navigation/native-stack'; -import type { StackNavigationOptions } from '@react-navigation/stack'; - -/** Transparent stack with no transition animation; used for modal-style flows. */ -export const clearStackNavigatorOptions: StackNavigationOptions = { - headerShown: false, - cardStyle: { - backgroundColor: 'transparent', - }, - animationEnabled: false, -}; -/** Transparent stack with no transition animation; used for modal-style flows. */ -export const clearStackNavigatorOptionsWithTransitionAnimation: StackNavigationOptions = - { - headerShown: false, - cardStyle: { - backgroundColor: 'transparent', - }, - cardStyleInterpolator: () => ({ - overlayStyle: { - opacity: 0, - }, - }), - animationEnabled: false, - }; /** - * Native-stack counterpart to {@link clearStackNavigatorOptions}. + * Transparent native stack with no transition animation; used for modal-style flows. * Use with `createNativeStackNavigator` only (`contentStyle` / `animation`, not `cardStyle` / `animationEnabled`). * * Includes `animation: 'none'` — omit this preset on screens where you want the default push/modal animation. diff --git a/package.json b/package.json index f652de60493..3d9b39db3ab 100644 --- a/package.json +++ b/package.json @@ -377,7 +377,6 @@ "@react-navigation/bottom-tabs": "^6.5.0", "@react-navigation/native": "^6.1.0", "@react-navigation/native-stack": "^6.0.0", - "@react-navigation/stack": "^6.3.0", "@reduxjs/toolkit": "^1.9.7", "@reown/walletkit": "^1.4.1", "@segment/analytics-react-native": "^2.21.4", diff --git a/yarn.lock b/yarn.lock index 1ead16e13a3..5018dbd7ec3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13098,24 +13098,6 @@ __metadata: languageName: node linkType: hard -"@react-navigation/stack@npm:^6.3.0": - version: 6.4.1 - resolution: "@react-navigation/stack@npm:6.4.1" - dependencies: - "@react-navigation/elements": "npm:^1.3.31" - color: "npm:^4.2.3" - warn-once: "npm:^0.1.0" - peerDependencies: - "@react-navigation/native": ^6.0.0 - react: "*" - react-native: "*" - react-native-gesture-handler: ">= 1.0.0" - react-native-safe-area-context: ">= 3.0.0" - react-native-screens: ">= 3.0.0" - checksum: 10/8eb7ae7cfffae1963ed4b386165f08517c42ff05a00f9c6d3d28827016810135dd96033f36916e1b58ddd73bf7d8a6f38f3afc782e5f0f84c1d722d3d296968c - languageName: node - linkType: hard - "@redux-devtools/core@npm:^4.1.1": version: 4.1.1 resolution: "@redux-devtools/core@npm:4.1.1" @@ -35539,7 +35521,6 @@ __metadata: "@react-navigation/bottom-tabs": "npm:^6.5.0" "@react-navigation/native": "npm:^6.1.0" "@react-navigation/native-stack": "npm:^6.0.0" - "@react-navigation/stack": "npm:^6.3.0" "@reduxjs/toolkit": "npm:^1.9.7" "@reown/walletkit": "npm:^1.4.1" "@segment/analytics-react-native": "npm:^2.21.4"