@embrace-io/web-sdk
Version:
45 lines (44 loc) • 2.19 kB
JavaScript
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