diff --git a/packages/core-api/src/routing/hooks.test.tsx b/packages/core-api/src/routing/hooks.test.tsx index 65c7858954..6c38a6e18a 100644 --- a/packages/core-api/src/routing/hooks.test.tsx +++ b/packages/core-api/src/routing/hooks.test.tsx @@ -38,6 +38,7 @@ const ref1 = createRouteRef(mockConfig()); const ref2 = createRouteRef(mockConfig()); const ref3 = createRouteRef(mockConfig()); const ref4 = createRouteRef(mockConfig()); +const ref5 = createRouteRef(mockConfig()); const MockRouteSource = (props: { name: string; @@ -47,7 +48,7 @@ const MockRouteSource = (props: { const routeFunc = useRouteRef(props.routeRef); return (
- Path at {props.name}: {routeFunc?.(props.params)} + Path at {props.name}: {routeFunc(props.params)}
); }; @@ -64,6 +65,9 @@ const Extension3 = plugin.provide( const Extension4 = plugin.provide( createRoutableExtension({ component: MockRouteSource, mountPoint: ref4 }), ); +const Extension5 = plugin.provide( + createRoutableExtension({ component: MockComponent, mountPoint: ref5 }), +); describe('discovery', () => { it('should handle simple routeRef path creation for routeRefs used in other parts of the app', () => { @@ -100,7 +104,7 @@ describe('discovery', () => { it('should handle routeRefs with parameters', () => { const root = ( - + { rendered.getByText('Path at outside: /foo/bar/blob'), ).toBeInTheDocument(); }); + + it('should handle relative routing within parameterized routes', () => { + const root = ( + + + + + + + + + ); + + const { routes, routeParents } = traverseElementTree({ + root, + discoverers: [childDiscoverer, routeElementDiscoverer], + collectors: { + routes: routeCollector, + routeParents: routeParentCollector, + }, + }); + + const rendered = render( + + {root} + , + ); + + expect( + rendered.getByText('Path at inside: /foo/blob/baz'), + ).toBeInTheDocument(); + }); }); diff --git a/packages/core-api/src/routing/hooks.tsx b/packages/core-api/src/routing/hooks.tsx index 739d74247c..821fd6f9de 100644 --- a/packages/core-api/src/routing/hooks.tsx +++ b/packages/core-api/src/routing/hooks.tsx @@ -16,7 +16,7 @@ import React, { createContext, ReactNode, useContext } from 'react'; import { RouteRef } from './types'; -import { generatePath } from 'react-router-dom'; +import { generatePath, useParams } from 'react-router-dom'; export type RouteFunc = (params?: Record) => string; @@ -26,7 +26,7 @@ class RouteResolver { private readonly routeParents: Map, ) {} - resolve(routeRef: RouteRef): RouteFunc { + resolve(routeRef: RouteRef, parentParams: Record): RouteFunc { let currentRouteRef: RouteRef | undefined = routeRef; let fullPath = ''; @@ -40,20 +40,21 @@ class RouteResolver { } return (params?: Record) => { - return generatePath(fullPath, params); + return generatePath(fullPath, { ...params, ...parentParams }); }; } } const RoutingContext = createContext(undefined); -export function useRouteRef(routeRef: RouteRef): RouteFunc | undefined { +export function useRouteRef(routeRef: RouteRef): RouteFunc { const resolver = useContext(RoutingContext); + const params = useParams(); if (!resolver) { throw new Error('No route resolver found in context'); } - return resolver.resolve(routeRef); + return resolver.resolve(routeRef, params); } type ProviderProps = {