From fd6baaceda9de587f2af759ebf7b4ee91b08387f Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 19 May 2025 14:01:54 -0700 Subject: [PATCH] chore(StackManager): more upgrades for rr6 --- .../src/ReactRouter/StackManager.tsx | 53 ++++++++++++------- .../src/ReactRouter/utils/findRoutesNode.ts | 19 +++++++ 2 files changed, 54 insertions(+), 18 deletions(-) create mode 100644 packages/react-router/src/ReactRouter/utils/findRoutesNode.ts diff --git a/packages/react-router/src/ReactRouter/StackManager.tsx b/packages/react-router/src/ReactRouter/StackManager.tsx index fc8309f579..2d7384eadf 100644 --- a/packages/react-router/src/ReactRouter/StackManager.tsx +++ b/packages/react-router/src/ReactRouter/StackManager.tsx @@ -1,8 +1,10 @@ import type { RouteInfo, StackContextState, ViewItem } from '@ionic/react'; import { RouteManagerContext, StackContext, generateId, getConfig } from '@ionic/react'; import React from 'react'; +import { Route } from 'react-router'; import { clonePageElement } from './clonePageElement'; +import { findRoutesNode } from './utils/findRoutesNode'; import { matchPath } from './utils/matchPath'; // TODO(FW-2959): types @@ -135,16 +137,16 @@ export class StackManager extends React.PureComponent` node matching the current route info. + * If no `` can be matched, a fallback node is returned. + */ +function findRouteByRouteInfo(node: React.ReactNode, routeInfo: RouteInfo) { let matchedNode: React.ReactNode; - for (const child of React.Children.toArray(node) as React.ReactElement[]) { - const match = matchPath({ - pathname: routeInfo.pathname, - componentProps: child.props, - }); + let fallbackNode: React.ReactNode; - if (match) { - matchedNode = child; - break; + // `` nodes are rendered inside of a node + const routesNode = findRoutesNode(node) ?? node; + + for (const child of React.Children.toArray(routesNode) as React.ReactElement[]) { + // Check if the child is a `` node + if (child.type === Route) { + const match = matchPath({ + pathname: routeInfo.pathname, + componentProps: child.props, + }); + + if (match) { + matchedNode = child; + break; + } } } if (matchedNode) { return matchedNode; } + // If we haven't found a node - // try to find one that doesn't have a path or from prop, that will be our not found route - for (const child of React.Children.toArray(node) as React.ReactElement[]) { - if (!(child.props.path || child.props.from)) { - matchedNode = child; - break; + // try to find one that doesn't have a path prop, that will be our not found route + for (const child of React.Children.toArray(routesNode) as React.ReactElement[]) { + if (child.type === Route) { + if (!child.props.path) { + fallbackNode = child; + break; + } } } - return matchedNode; + return matchedNode ?? fallbackNode; } function matchComponent(node: React.ReactElement, pathname: string, forceExact?: boolean) { diff --git a/packages/react-router/src/ReactRouter/utils/findRoutesNode.ts b/packages/react-router/src/ReactRouter/utils/findRoutesNode.ts new file mode 100644 index 0000000000..269c974856 --- /dev/null +++ b/packages/react-router/src/ReactRouter/utils/findRoutesNode.ts @@ -0,0 +1,19 @@ +import React from 'react'; +import { Routes } from 'react-router'; + +export const findRoutesNode = (node: React.ReactNode) => { + // The use of `` is encouraged with React Router v6. + let routesNode: React.ReactNode; + React.Children.forEach(node as React.ReactElement, (child: React.ReactElement) => { + if (child.type === Routes) { + routesNode = child; + } + }); + + if (routesNode) { + // The childern of the `` component are most likely + // (and should be) the `` components. + return (routesNode as React.ReactElement).props.children; + } + return undefined; +};