From f124bd4bcad192b87dd56c8fa45aec0f102b338a Mon Sep 17 00:00:00 2001 From: Juligs Date: Fri, 29 May 2026 16:43:08 +0200 Subject: [PATCH 1/3] refactor(iota-wallet): update navigation header rules --- .../components/NavigationStackProvider.tsx | 46 ++++++ apps/wallet/src/ui/app/components/Overlay.tsx | 8 +- .../src/ui/app/components/PageTemplate.tsx | 23 ++- apps/wallet/src/ui/app/components/index.ts | 1 + .../iota-apps/ConnectedAppsCard.tsx | 2 +- .../menu/content/AutoLockAccounts.tsx | 1 - .../menu/content/NetworkSettings.tsx | 2 +- .../components/menu/content/ThemeSettings.tsx | 2 +- .../ui/app/components/navigation/index.tsx | 27 ++-- .../ui/app/pages/accounts/AddAccountPage.tsx | 8 +- .../app/pages/accounts/CreateNewPasskey.tsx | 1 - .../ui/app/pages/accounts/CreateNewWallet.tsx | 2 - .../pages/accounts/ImportExistingWallet.tsx | 2 - .../ui/app/pages/accounts/ImportKeystone.tsx | 2 +- .../app/pages/accounts/ImportPasskeyPage.tsx | 1 - .../pages/accounts/ImportPassphrasePage.tsx | 2 +- .../pages/accounts/ImportPrivateKeyPage.tsx | 2 +- .../ui/app/pages/accounts/ImportSeedPage.tsx | 2 +- .../app/pages/accounts/ProtectAccountPage.tsx | 7 +- .../accounts/manage/ManageAccountsPage.tsx | 1 - .../ui/app/pages/home/kiosk-details/index.tsx | 5 +- .../ui/app/pages/home/nft-details/index.tsx | 7 +- .../ui/app/pages/home/nft-transfer/index.tsx | 1 - .../ui/app/pages/home/transfer-coin/index.tsx | 1 - .../page-main-layout/PageMainLayout.tsx | 7 +- .../app/staking/delegation-detail/index.tsx | 7 +- .../wallet/src/ui/app/staking/stake/index.tsx | 1 - .../src/ui/app/staking/validators/index.tsx | 2 - apps/wallet/src/ui/index.tsx | 131 +++++++++--------- 29 files changed, 158 insertions(+), 146 deletions(-) create mode 100644 apps/wallet/src/ui/app/components/NavigationStackProvider.tsx diff --git a/apps/wallet/src/ui/app/components/NavigationStackProvider.tsx b/apps/wallet/src/ui/app/components/NavigationStackProvider.tsx new file mode 100644 index 0000000000..754e2c474b --- /dev/null +++ b/apps/wallet/src/ui/app/components/NavigationStackProvider.tsx @@ -0,0 +1,46 @@ +// Copyright (c) 2026 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +import { createContext, useContext, useEffect, useState, type ReactNode } from 'react'; +import { useLocation, useNavigationType } from 'react-router-dom'; +import { NAVBAR_ITEM_PATHS } from './navigation'; + +export const HOME_PATH = NAVBAR_ITEM_PATHS.home; + +const TAB_BAR_PATHS = new Set( + Object.values(NAVBAR_ITEM_PATHS).filter((p) => p !== HOME_PATH), +); + +const NavigationDepthContext = createContext(0); + +export function NavigationStackProvider({ children }: { children: ReactNode }) { + const [depth, setDepth] = useState(0); + const location = useLocation(); + const navigationType = useNavigationType(); + + useEffect(() => { + const hasMenuParam = new URLSearchParams(location.search).has('menu'); + const isHome = + !hasMenuParam && + (location.pathname === HOME_PATH || location.pathname.startsWith(HOME_PATH + '/')); + const isTabBar = !hasMenuParam && TAB_BAR_PATHS.has(location.pathname); + + if (isHome) { + setDepth(0); + } else if (isTabBar) { + setDepth(1); + } else if (navigationType === 'PUSH') { + setDepth((prev) => prev + 1); + } else if (navigationType === 'POP') { + setDepth((prev) => Math.max(0, prev - 1)); + } + }, [location.key, navigationType]); + + return ( + {children} + ); +} + +export function useNavigationDepth(): number { + return useContext(NavigationDepthContext); +} diff --git a/apps/wallet/src/ui/app/components/Overlay.tsx b/apps/wallet/src/ui/app/components/Overlay.tsx index c30dc1ba96..1a9afaa845 100644 --- a/apps/wallet/src/ui/app/components/Overlay.tsx +++ b/apps/wallet/src/ui/app/components/Overlay.tsx @@ -7,6 +7,7 @@ import type { ReactNode } from 'react'; import { Header } from '@iota/apps-ui-kit'; import { Portal } from '../shared/Portal'; import { useNavigate } from 'react-router-dom'; +import { useNavigationDepth } from './NavigationStackProvider'; interface OverlayProps { title?: string; @@ -17,7 +18,6 @@ interface OverlayProps { setShowModal?: (showModal: boolean) => void; background?: 'bg-iota-neutral-100 dark:bg-iota-neutral-6'; titleCentered?: boolean; - showBackButton?: boolean; onBack?: () => void; hideCloseIcon?: boolean; headerAction?: ReactNode; @@ -30,7 +30,6 @@ export function Overlay({ closeOverlay, setShowModal, titleCentered = true, - showBackButton, onBack, headerAction, hideCloseIcon, @@ -43,6 +42,7 @@ export function Overlay({ [closeOverlay, setShowModal], ); const navigate = useNavigate(); + const depth = useNavigationDepth(); const handleBack = useCallback(() => { if (onBack) { onBack(); @@ -56,9 +56,9 @@ export function Overlay({ {title && (
= 1 ? handleBack : undefined} title={title} - onClose={!hideCloseIcon ? closeModal : undefined} + onClose={!hideCloseIcon && depth >= 2 ? closeModal : undefined} titleCentered={titleCentered} testId="overlay-title" /> diff --git a/apps/wallet/src/ui/app/components/PageTemplate.tsx b/apps/wallet/src/ui/app/components/PageTemplate.tsx index 86ca7cd683..41b7212368 100644 --- a/apps/wallet/src/ui/app/components/PageTemplate.tsx +++ b/apps/wallet/src/ui/app/components/PageTemplate.tsx @@ -5,40 +5,39 @@ import { Header } from '@iota/apps-ui-kit'; import { useCallback } from 'react'; import type { ReactNode } from 'react'; import { useNavigate } from 'react-router-dom'; +import { HOME_PATH, useNavigationDepth } from './NavigationStackProvider'; interface PageTemplateProps { title?: string; children: ReactNode; - onClose?: () => void; isTitleCentered?: boolean; - showBackButton?: boolean; onBack?: () => void; } -export function PageTemplate({ - title, - children, - onClose, - isTitleCentered, - showBackButton, - onBack, -}: PageTemplateProps) { +export function PageTemplate({ title, children, isTitleCentered, onBack }: PageTemplateProps) { const navigate = useNavigate(); + const depth = useNavigationDepth(); + const handleBack = useCallback(() => { if (onBack) { onBack(); } else { navigate(-1); } + }, [onBack, navigate]); + + const handleClose = useCallback(() => { + navigate(HOME_PATH); }, [navigate]); + return (
{title && (
= 1 ? handleBack : undefined} + onClose={depth >= 2 ? handleClose : undefined} /> )}
diff --git a/apps/wallet/src/ui/app/components/index.ts b/apps/wallet/src/ui/app/components/index.ts index 3c161a3a03..fca97275b2 100644 --- a/apps/wallet/src/ui/app/components/index.ts +++ b/apps/wallet/src/ui/app/components/index.ts @@ -5,6 +5,7 @@ export * from './DAppInfoCard'; export * from './DAppPermissionList'; export * from './HideShowDisplayBox'; export * from './Overlay'; +export { NavigationStackProvider } from './NavigationStackProvider'; export * from './PageTemplate'; export * from './SectionHeader'; export * from './SummaryCard'; diff --git a/apps/wallet/src/ui/app/components/iota-apps/ConnectedAppsCard.tsx b/apps/wallet/src/ui/app/components/iota-apps/ConnectedAppsCard.tsx index 33148152db..12109556ac 100644 --- a/apps/wallet/src/ui/app/components/iota-apps/ConnectedAppsCard.tsx +++ b/apps/wallet/src/ui/app/components/iota-apps/ConnectedAppsCard.tsx @@ -12,7 +12,7 @@ export function ConnectedAppsCard() { const { connectedApps, loading } = useConnectedApps(); return ( - +
navigate('/tokens')} - showBackButton >
diff --git a/apps/wallet/src/ui/app/components/menu/content/NetworkSettings.tsx b/apps/wallet/src/ui/app/components/menu/content/NetworkSettings.tsx index 84fa40548c..2411a11216 100644 --- a/apps/wallet/src/ui/app/components/menu/content/NetworkSettings.tsx +++ b/apps/wallet/src/ui/app/components/menu/content/NetworkSettings.tsx @@ -8,7 +8,7 @@ import { useNavigate } from 'react-router-dom'; export function NetworkSettings() { const navigate = useNavigate(); return ( - navigate('/tokens')} showBackButton> + navigate('/tokens')}> ); diff --git a/apps/wallet/src/ui/app/components/menu/content/ThemeSettings.tsx b/apps/wallet/src/ui/app/components/menu/content/ThemeSettings.tsx index 2e9c36313b..b1bfd018c9 100644 --- a/apps/wallet/src/ui/app/components/menu/content/ThemeSettings.tsx +++ b/apps/wallet/src/ui/app/components/menu/content/ThemeSettings.tsx @@ -23,7 +23,7 @@ export function ThemeSettings() { ampli.changedTheme({ theme: value }); } return ( - navigate('/tokens')} showBackButton> + navigate('/tokens')}>
{THEME_ENTRIES.map(([label, value]) => (
diff --git a/apps/wallet/src/ui/app/components/navigation/index.tsx b/apps/wallet/src/ui/app/components/navigation/index.tsx index 324db3d4d8..daf8bebfdd 100644 --- a/apps/wallet/src/ui/app/components/navigation/index.tsx +++ b/apps/wallet/src/ui/app/components/navigation/index.tsx @@ -10,27 +10,22 @@ type NavbarItemWithPath = NavbarItemWithId & { path: string; }; +export const NAVBAR_ITEM_PATHS = { + home: '/tokens', + assets: '/nfts', + apps: '/apps', + activity: '/transactions', +} as const; + export function Navigation() { const navigate = useNavigate(); const location = useLocation(); const NAVBAR_ITEMS: NavbarItemWithPath[] = [ - { id: 'home', icon: , path: '/tokens' }, - { - id: 'assets', - icon: , - path: '/nfts', - }, - { - id: 'apps', - icon: , - path: '/apps', - }, - { - id: 'activity', - icon: , - path: '/transactions', - }, + { id: 'home', icon: , path: NAVBAR_ITEM_PATHS.home }, + { id: 'assets', icon: , path: NAVBAR_ITEM_PATHS.assets }, + { id: 'apps', icon: , path: NAVBAR_ITEM_PATHS.apps }, + { id: 'activity', icon: , path: NAVBAR_ITEM_PATHS.activity }, ]; const activeId = NAVBAR_ITEMS.find((item) => location.pathname.startsWith(item.path))?.id || ''; diff --git a/apps/wallet/src/ui/app/pages/accounts/AddAccountPage.tsx b/apps/wallet/src/ui/app/pages/accounts/AddAccountPage.tsx index effc950890..eb96237dad 100644 --- a/apps/wallet/src/ui/app/pages/accounts/AddAccountPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/AddAccountPage.tsx @@ -164,13 +164,7 @@ export function AddAccountPage() { } return ( - navigate('/')} - showBackButton - onBack={() => navigate('/')} - > +
navigate('/accounts/import-existing')} > navigate('/')} - showBackButton onBack={() => navigate('/accounts/add-account')} >
diff --git a/apps/wallet/src/ui/app/pages/accounts/ImportExistingWallet.tsx b/apps/wallet/src/ui/app/pages/accounts/ImportExistingWallet.tsx index 1da16ff407..dff20bd9a7 100644 --- a/apps/wallet/src/ui/app/pages/accounts/ImportExistingWallet.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/ImportExistingWallet.tsx @@ -102,8 +102,6 @@ export function ImportExistingWallet() { navigate('/')} - showBackButton onBack={() => navigate('/accounts/add-account')} >
diff --git a/apps/wallet/src/ui/app/pages/accounts/ImportKeystone.tsx b/apps/wallet/src/ui/app/pages/accounts/ImportKeystone.tsx index 458d2775b6..f959b754cc 100644 --- a/apps/wallet/src/ui/app/pages/accounts/ImportKeystone.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/ImportKeystone.tsx @@ -90,7 +90,7 @@ export function ImportKeystone() { const disableFinish = step.type === 'select-accounts' && step.selectedAccounts.size === 0; return ( - +
diff --git a/apps/wallet/src/ui/app/pages/accounts/ImportPasskeyPage.tsx b/apps/wallet/src/ui/app/pages/accounts/ImportPasskeyPage.tsx index 50092b6b32..f8029ee2ae 100644 --- a/apps/wallet/src/ui/app/pages/accounts/ImportPasskeyPage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/ImportPasskeyPage.tsx @@ -27,7 +27,6 @@ export function ImportPasskeyPage() { navigate('/accounts/import-existing')} > {accountID ? ( diff --git a/apps/wallet/src/ui/app/pages/accounts/ImportPassphrasePage.tsx b/apps/wallet/src/ui/app/pages/accounts/ImportPassphrasePage.tsx index fd4eb501de..db6ea0f764 100644 --- a/apps/wallet/src/ui/app/pages/accounts/ImportPassphrasePage.tsx +++ b/apps/wallet/src/ui/app/pages/accounts/ImportPassphrasePage.tsx @@ -38,7 +38,7 @@ export function ImportPassphrasePage() { const BUTTON_ICON_CLASSES = 'w-5 h-5 text-iota-neutral-10 dark:text-iota-neutral-92'; return ( - +