UNPKG

@embrace-io/web-sdk

Version:
45 lines (44 loc) 2.19 kB
import { page } from "../../../../../api-page/pageAPI.js"; import { createElement } from "react"; import hoistNonReactStatics from "hoist-non-react-statics"; //#region src/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Declarative/withEmbraceRouting.ts const getLastRoute = (matchedComponent, lastRoute) => { if (!matchedComponent.props.match?.route) return null; const childPath = matchedComponent.props.match.route.path; const path = lastRoute && !childPath.startsWith("/") ? `${lastRoute.path}/${childPath}` : childPath; if (matchedComponent.props.routeContext?.outlet) return getLastRoute(matchedComponent.props.routeContext.outlet, { path, url: matchedComponent.props.match.pathname }); return { path, url: matchedComponent.props.match.pathname }; }; const withEmbraceRouting = (WrappedComponent) => { const RoutesWithEmbraceRouting = (props) => { /** * React-router v6+ implementation is very different from v5 * It doesn't have a <Switch> component that injects props into <Route> * Instead, it has <Routes> which internally calculates the matched route * and returns it as a children, <Route> cannot be wrapped since it requires all children to be a <Route> component * here we rely on that matching to get the current route. * It's not ideal to rely on internal implementation details, but it's the easier way of getting the current route * without having to manually match it or using hooks on each children component * * See: https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/hooks.tsx#L553 */ const matchedComponent = WrappedComponent(props); if (matchedComponent.props.match?.route) { const lastRoute = getLastRoute(matchedComponent, null); if (lastRoute) page.setCurrentRoute(lastRoute); } return createElement(WrappedComponent, props); }; RoutesWithEmbraceRouting.displayName = `withEmbraceRouting(${WrappedComponent.displayName || WrappedComponent.name || "Component"})`; hoistNonReactStatics(RoutesWithEmbraceRouting, WrappedComponent); return RoutesWithEmbraceRouting; }; //#endregion export { withEmbraceRouting }; //# sourceMappingURL=withEmbraceRouting.js.map