@tanstack/react-router
Version:
Modern and scalable routing for React applications
260 lines (259 loc) • 10.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const invariant = require("tiny-invariant");
const warning = require("tiny-warning");
const routerCore = require("@tanstack/router-core");
const CatchBoundary = require("./CatchBoundary.cjs");
const useRouterState = require("./useRouterState.cjs");
const useRouter = require("./useRouter.cjs");
const notFound = require("./not-found.cjs");
const matchContext = require("./matchContext.cjs");
const SafeFragment = require("./SafeFragment.cjs");
const renderRouteNotFound = require("./renderRouteNotFound.cjs");
const scrollRestoration = require("./scroll-restoration.cjs");
const ClientOnly = require("./ClientOnly.cjs");
function _interopNamespaceDefault(e) {
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
if (e) {
for (const k in e) {
if (k !== "default") {
const d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: () => e[k]
});
}
}
}
n.default = e;
return Object.freeze(n);
}
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
const Match = React__namespace.memo(function MatchImpl({
matchId
}) {
const router = useRouter.useRouter();
const matchState = useRouterState.useRouterState({
select: (s) => {
const match = s.matches.find((d) => d.id === matchId);
invariant(
match,
`Could not find match for matchId "${matchId}". Please file an issue!`
);
return {
routeId: match.routeId,
ssr: match.ssr,
_displayPending: match._displayPending
};
},
structuralSharing: true
});
const route = router.routesById[matchState.routeId];
const PendingComponent = route.options.pendingComponent ?? router.options.defaultPendingComponent;
const pendingElement = PendingComponent ? /* @__PURE__ */ jsxRuntime.jsx(PendingComponent, {}) : null;
const routeErrorComponent = route.options.errorComponent ?? router.options.defaultErrorComponent;
const routeOnCatch = route.options.onCatch ?? router.options.defaultOnCatch;
const routeNotFoundComponent = route.isRoot ? (
// If it's the root route, use the globalNotFound option, with fallback to the notFoundRoute's component
route.options.notFoundComponent ?? router.options.notFoundRoute?.options.component
) : route.options.notFoundComponent;
const resolvedNoSsr = matchState.ssr === false || matchState.ssr === "data-only";
const ResolvedSuspenseBoundary = (
// If we're on the root route, allow forcefully wrapping in suspense
(!route.isRoot || route.options.wrapInSuspense || resolvedNoSsr) && (route.options.wrapInSuspense ?? PendingComponent ?? (route.options.errorComponent?.preload || resolvedNoSsr)) ? React__namespace.Suspense : SafeFragment.SafeFragment
);
const ResolvedCatchBoundary = routeErrorComponent ? CatchBoundary.CatchBoundary : SafeFragment.SafeFragment;
const ResolvedNotFoundBoundary = routeNotFoundComponent ? notFound.CatchNotFound : SafeFragment.SafeFragment;
const resetKey = useRouterState.useRouterState({
select: (s) => s.loadedAt
});
const parentRouteId = useRouterState.useRouterState({
select: (s) => {
const index = s.matches.findIndex((d) => d.id === matchId);
return s.matches[index - 1]?.routeId;
}
});
const ShellComponent = route.isRoot ? route.options.shellComponent ?? SafeFragment.SafeFragment : SafeFragment.SafeFragment;
return /* @__PURE__ */ jsxRuntime.jsxs(ShellComponent, { children: [
/* @__PURE__ */ jsxRuntime.jsx(matchContext.matchContext.Provider, { value: matchId, children: /* @__PURE__ */ jsxRuntime.jsx(ResolvedSuspenseBoundary, { fallback: pendingElement, children: /* @__PURE__ */ jsxRuntime.jsx(
ResolvedCatchBoundary,
{
getResetKey: () => resetKey,
errorComponent: routeErrorComponent || CatchBoundary.ErrorComponent,
onCatch: (error, errorInfo) => {
if (routerCore.isNotFound(error)) throw error;
warning(false, `Error in route match: ${matchId}`);
routeOnCatch?.(error, errorInfo);
},
children: /* @__PURE__ */ jsxRuntime.jsx(
ResolvedNotFoundBoundary,
{
fallback: (error) => {
if (!routeNotFoundComponent || error.routeId && error.routeId !== matchState.routeId || !error.routeId && !route.isRoot)
throw error;
return React__namespace.createElement(routeNotFoundComponent, error);
},
children: resolvedNoSsr || matchState._displayPending ? /* @__PURE__ */ jsxRuntime.jsx(ClientOnly.ClientOnly, { fallback: pendingElement, children: /* @__PURE__ */ jsxRuntime.jsx(MatchInner, { matchId }) }) : /* @__PURE__ */ jsxRuntime.jsx(MatchInner, { matchId })
}
)
}
) }) }),
parentRouteId === routerCore.rootRouteId && router.options.scrollRestoration ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(OnRendered, {}),
/* @__PURE__ */ jsxRuntime.jsx(scrollRestoration.ScrollRestoration, {})
] }) : null
] });
});
function OnRendered() {
const router = useRouter.useRouter();
const prevLocationRef = React__namespace.useRef(
void 0
);
return /* @__PURE__ */ jsxRuntime.jsx(
"script",
{
suppressHydrationWarning: true,
ref: (el) => {
if (el && (prevLocationRef.current === void 0 || prevLocationRef.current.href !== router.latestLocation.href)) {
router.emit({
type: "onRendered",
...routerCore.getLocationChangeInfo(router.state)
});
prevLocationRef.current = router.latestLocation;
}
}
},
router.latestLocation.state.__TSR_key
);
}
const MatchInner = React__namespace.memo(function MatchInnerImpl({
matchId
}) {
const router = useRouter.useRouter();
const { match, key, routeId } = useRouterState.useRouterState({
select: (s) => {
const match2 = s.matches.find((d) => d.id === matchId);
const routeId2 = match2.routeId;
const remountFn = router.routesById[routeId2].options.remountDeps ?? router.options.defaultRemountDeps;
const remountDeps = remountFn?.({
routeId: routeId2,
loaderDeps: match2.loaderDeps,
params: match2._strictParams,
search: match2._strictSearch
});
const key2 = remountDeps ? JSON.stringify(remountDeps) : void 0;
return {
key: key2,
routeId: routeId2,
match: {
id: match2.id,
status: match2.status,
error: match2.error,
_forcePending: match2._forcePending,
_displayPending: match2._displayPending
}
};
},
structuralSharing: true
});
const route = router.routesById[routeId];
const out = React__namespace.useMemo(() => {
const Comp = route.options.component ?? router.options.defaultComponent;
if (Comp) {
return /* @__PURE__ */ jsxRuntime.jsx(Comp, {}, key);
}
return /* @__PURE__ */ jsxRuntime.jsx(Outlet, {});
}, [key, route.options.component, router.options.defaultComponent]);
if (match._displayPending) {
throw router.getMatch(match.id)?._nonReactive.displayPendingPromise;
}
if (match._forcePending) {
throw router.getMatch(match.id)?._nonReactive.minPendingPromise;
}
if (match.status === "pending") {
const pendingMinMs = route.options.pendingMinMs ?? router.options.defaultPendingMinMs;
if (pendingMinMs) {
const routerMatch = router.getMatch(match.id);
if (routerMatch && !routerMatch._nonReactive.minPendingPromise) {
if (!router.isServer) {
const minPendingPromise = routerCore.createControlledPromise();
routerMatch._nonReactive.minPendingPromise = minPendingPromise;
setTimeout(() => {
minPendingPromise.resolve();
routerMatch._nonReactive.minPendingPromise = void 0;
}, pendingMinMs);
}
}
}
throw router.getMatch(match.id)?._nonReactive.loadPromise;
}
if (match.status === "notFound") {
invariant(routerCore.isNotFound(match.error), "Expected a notFound error");
return renderRouteNotFound.renderRouteNotFound(router, route, match.error);
}
if (match.status === "redirected") {
invariant(routerCore.isRedirect(match.error), "Expected a redirect error");
throw router.getMatch(match.id)?._nonReactive.loadPromise;
}
if (match.status === "error") {
if (router.isServer) {
const RouteErrorComponent = (route.options.errorComponent ?? router.options.defaultErrorComponent) || CatchBoundary.ErrorComponent;
return /* @__PURE__ */ jsxRuntime.jsx(
RouteErrorComponent,
{
error: match.error,
reset: void 0,
info: {
componentStack: ""
}
}
);
}
throw match.error;
}
return out;
});
const Outlet = React__namespace.memo(function OutletImpl() {
const router = useRouter.useRouter();
const matchId = React__namespace.useContext(matchContext.matchContext);
const routeId = useRouterState.useRouterState({
select: (s) => s.matches.find((d) => d.id === matchId)?.routeId
});
const route = router.routesById[routeId];
const parentGlobalNotFound = useRouterState.useRouterState({
select: (s) => {
const matches = s.matches;
const parentMatch = matches.find((d) => d.id === matchId);
invariant(
parentMatch,
`Could not find parent match for matchId "${matchId}"`
);
return parentMatch.globalNotFound;
}
});
const childMatchId = useRouterState.useRouterState({
select: (s) => {
const matches = s.matches;
const index = matches.findIndex((d) => d.id === matchId);
return matches[index + 1]?.id;
}
});
const pendingElement = router.options.defaultPendingComponent ? /* @__PURE__ */ jsxRuntime.jsx(router.options.defaultPendingComponent, {}) : null;
if (parentGlobalNotFound) {
return renderRouteNotFound.renderRouteNotFound(router, route, void 0);
}
if (!childMatchId) {
return null;
}
const nextMatch = /* @__PURE__ */ jsxRuntime.jsx(Match, { matchId: childMatchId });
if (matchId === routerCore.rootRouteId) {
return /* @__PURE__ */ jsxRuntime.jsx(React__namespace.Suspense, { fallback: pendingElement, children: nextMatch });
}
return nextMatch;
});
exports.Match = Match;
exports.MatchInner = MatchInner;
exports.Outlet = Outlet;
//# sourceMappingURL=Match.cjs.map