diff --git a/packages/frontend/core/src/hooks/use-navigate-helper.ts b/packages/frontend/core/src/hooks/use-navigate-helper.ts index 64f19b3d7b..6f04fbe273 100644 --- a/packages/frontend/core/src/hooks/use-navigate-helper.ts +++ b/packages/frontend/core/src/hooks/use-navigate-helper.ts @@ -1,6 +1,11 @@ import type { WorkspaceSubPath } from '@affine/core/shared'; -import { useCallback, useMemo } from 'react'; -import { type NavigateOptions, type To, useLocation } from 'react-router-dom'; +import { createContext, useCallback, useContext, useMemo } from 'react'; +import { + type NavigateFunction, + type NavigateOptions, + type To, + useLocation, +} from 'react-router-dom'; import { router } from '../router'; @@ -9,16 +14,20 @@ export enum RouteLogic { PUSH = 'push', } -function navigate(to: To, option?: { replace?: boolean }) { +function defaultNavigate(to: To, option?: { replace?: boolean }) { router.navigate(to, option).catch(err => { console.error('Failed to navigate', err); }); } +export const NavigateContext = createContext(null); + // todo: add a name -> path helper in the results export function useNavigateHelper() { const location = useLocation(); + const navigate = useContext(NavigateContext) ?? defaultNavigate; + const jumpToPage = useCallback( ( workspaceId: string, @@ -29,7 +38,7 @@ export function useNavigateHelper() { replace: logic === RouteLogic.REPLACE, }); }, - [] + [navigate] ); const jumpToPageBlock = useCallback( ( @@ -42,7 +51,7 @@ export function useNavigateHelper() { replace: logic === RouteLogic.REPLACE, }); }, - [] + [navigate] ); const jumpToCollections = useCallback( (workspaceId: string, logic: RouteLogic = RouteLogic.PUSH) => { @@ -50,7 +59,7 @@ export function useNavigateHelper() { replace: logic === RouteLogic.REPLACE, }); }, - [] + [navigate] ); const jumpToTags = useCallback( (workspaceId: string, logic: RouteLogic = RouteLogic.PUSH) => { @@ -58,7 +67,7 @@ export function useNavigateHelper() { replace: logic === RouteLogic.REPLACE, }); }, - [] + [navigate] ); const jumpToTag = useCallback( ( @@ -70,7 +79,7 @@ export function useNavigateHelper() { replace: logic === RouteLogic.REPLACE, }); }, - [] + [navigate] ); const jumpToCollection = useCallback( ( @@ -82,7 +91,7 @@ export function useNavigateHelper() { replace: logic === RouteLogic.REPLACE, }); }, - [] + [navigate] ); const jumpToPublicWorkspacePage = useCallback( ( @@ -94,7 +103,7 @@ export function useNavigateHelper() { replace: logic === RouteLogic.REPLACE, }); }, - [] + [navigate] ); const jumpToSubPath = useCallback( ( @@ -106,7 +115,7 @@ export function useNavigateHelper() { replace: logic === RouteLogic.REPLACE, }); }, - [] + [navigate] ); const isPublicWorkspace = useMemo(() => { @@ -124,22 +133,31 @@ export function useNavigateHelper() { [jumpToPage, jumpToPublicWorkspacePage, isPublicWorkspace] ); - const jumpToIndex = useCallback((logic: RouteLogic = RouteLogic.PUSH) => { - return navigate('/', { - replace: logic === RouteLogic.REPLACE, - }); - }, []); + const jumpToIndex = useCallback( + (logic: RouteLogic = RouteLogic.PUSH) => { + return navigate('/', { + replace: logic === RouteLogic.REPLACE, + }); + }, + [navigate] + ); - const jumpTo404 = useCallback((logic: RouteLogic = RouteLogic.PUSH) => { - return navigate('/404', { - replace: logic === RouteLogic.REPLACE, - }); - }, []); - const jumpToExpired = useCallback((logic: RouteLogic = RouteLogic.PUSH) => { - return navigate('/expired', { - replace: logic === RouteLogic.REPLACE, - }); - }, []); + const jumpTo404 = useCallback( + (logic: RouteLogic = RouteLogic.PUSH) => { + return navigate('/404', { + replace: logic === RouteLogic.REPLACE, + }); + }, + [navigate] + ); + const jumpToExpired = useCallback( + (logic: RouteLogic = RouteLogic.PUSH) => { + return navigate('/expired', { + replace: logic === RouteLogic.REPLACE, + }); + }, + [navigate] + ); const jumpToSignIn = useCallback( ( logic: RouteLogic = RouteLogic.PUSH, @@ -150,7 +168,7 @@ export function useNavigateHelper() { ...otherOptions, }); }, - [] + [navigate] ); return useMemo( diff --git a/tests/storybook/src/stories/core.stories.tsx b/tests/storybook/src/stories/core.stories.tsx index 9f2c6dc705..1fde586bd1 100644 --- a/tests/storybook/src/stories/core.stories.tsx +++ b/tests/storybook/src/stories/core.stories.tsx @@ -1,8 +1,9 @@ +import { NavigateContext } from '@affine/core/hooks/use-navigate-helper'; import { workbenchRoutes } from '@affine/core/router'; import { assertExists } from '@blocksuite/global/utils'; import type { StoryFn } from '@storybook/react'; import { screen, userEvent, waitFor, within } from '@storybook/testing-library'; -import { Outlet, useLocation } from 'react-router-dom'; +import { Outlet, useLocation, useNavigate } from 'react-router-dom'; import { reactRouterOutlets, reactRouterParameters, @@ -11,8 +12,13 @@ import { const FakeApp = () => { const location = useLocation(); + const navigate = useNavigate(); // fixme: `key` is a hack to force the storybook to re-render the outlet - return ; + return ( + + + + ); }; export default {