@tanstack/react-router 1.167.5 → 1.168.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Match.cjs +118 -52
- package/dist/cjs/Match.cjs.map +1 -1
- package/dist/cjs/Matches.cjs +20 -20
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Scripts.cjs +36 -32
- package/dist/cjs/Scripts.cjs.map +1 -1
- package/dist/cjs/Transitioner.cjs +10 -16
- package/dist/cjs/Transitioner.cjs.map +1 -1
- package/dist/cjs/headContentUtils.cjs +147 -59
- package/dist/cjs/headContentUtils.cjs.map +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.dev.cjs +1 -1
- package/dist/cjs/link.cjs +34 -29
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/not-found.cjs +20 -2
- package/dist/cjs/not-found.cjs.map +1 -1
- package/dist/cjs/router.cjs +2 -1
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/routerStores.cjs +21 -0
- package/dist/cjs/routerStores.cjs.map +1 -0
- package/dist/cjs/routerStores.d.cts +7 -0
- package/dist/cjs/ssr/RouterClient.cjs +1 -1
- package/dist/cjs/ssr/RouterClient.cjs.map +1 -1
- package/dist/cjs/ssr/renderRouterToStream.cjs +2 -2
- package/dist/cjs/ssr/renderRouterToStream.cjs.map +1 -1
- package/dist/cjs/ssr/renderRouterToString.cjs +1 -1
- package/dist/cjs/ssr/renderRouterToString.cjs.map +1 -1
- package/dist/cjs/useCanGoBack.cjs +7 -2
- package/dist/cjs/useCanGoBack.cjs.map +1 -1
- package/dist/cjs/useLocation.cjs +21 -2
- package/dist/cjs/useLocation.cjs.map +1 -1
- package/dist/cjs/useMatch.cjs +29 -9
- package/dist/cjs/useMatch.cjs.map +1 -1
- package/dist/cjs/useRouterState.cjs +2 -2
- package/dist/cjs/useRouterState.cjs.map +1 -1
- package/dist/esm/Match.js +118 -52
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Matches.js +21 -21
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/Scripts.js +36 -32
- package/dist/esm/Scripts.js.map +1 -1
- package/dist/esm/Transitioner.js +10 -16
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/headContentUtils.js +148 -60
- package/dist/esm/headContentUtils.js.map +1 -1
- package/dist/esm/index.dev.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/link.js +34 -29
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/not-found.js +20 -2
- package/dist/esm/not-found.js.map +1 -1
- package/dist/esm/router.js +2 -1
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/routerStores.d.ts +7 -0
- package/dist/esm/routerStores.js +20 -0
- package/dist/esm/routerStores.js.map +1 -0
- package/dist/esm/ssr/RouterClient.js +1 -1
- package/dist/esm/ssr/RouterClient.js.map +1 -1
- package/dist/esm/ssr/renderRouterToStream.js +2 -2
- package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
- package/dist/esm/ssr/renderRouterToString.js +1 -1
- package/dist/esm/ssr/renderRouterToString.js.map +1 -1
- package/dist/esm/useCanGoBack.js +6 -2
- package/dist/esm/useCanGoBack.js.map +1 -1
- package/dist/esm/useLocation.js +20 -2
- package/dist/esm/useLocation.js.map +1 -1
- package/dist/esm/useMatch.js +29 -9
- package/dist/esm/useMatch.js.map +1 -1
- package/dist/esm/useRouterState.js +2 -2
- package/dist/esm/useRouterState.js.map +1 -1
- package/dist/llms/rules/api.d.ts +1 -1
- package/dist/llms/rules/api.js +3 -9
- package/package.json +2 -2
- package/src/Match.tsx +218 -78
- package/src/Matches.tsx +45 -25
- package/src/Scripts.tsx +72 -44
- package/src/Transitioner.tsx +24 -16
- package/src/headContentUtils.tsx +210 -27
- package/src/link.tsx +66 -71
- package/src/not-found.tsx +41 -4
- package/src/router.ts +2 -1
- package/src/routerStores.ts +26 -0
- package/src/ssr/RouterClient.tsx +1 -1
- package/src/ssr/renderRouterToStream.tsx +2 -2
- package/src/ssr/renderRouterToString.tsx +1 -1
- package/src/useCanGoBack.ts +14 -2
- package/src/useLocation.tsx +32 -5
- package/src/useMatch.tsx +61 -21
- package/src/useRouterState.tsx +4 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
|
|
2
2
|
const require_utils = require("./utils.cjs");
|
|
3
3
|
const require_useRouter = require("./useRouter.cjs");
|
|
4
|
-
const require_useRouterState = require("./useRouterState.cjs");
|
|
5
4
|
let _tanstack_router_core = require("@tanstack/router-core");
|
|
6
5
|
let react = require("react");
|
|
7
6
|
react = require_runtime.__toESM(react);
|
|
7
|
+
let _tanstack_react_store = require("@tanstack/react-store");
|
|
8
8
|
//#region src/Transitioner.tsx
|
|
9
9
|
function Transitioner() {
|
|
10
10
|
const router = require_useRouter.useRouter();
|
|
@@ -13,13 +13,8 @@ function Transitioner() {
|
|
|
13
13
|
mounted: false
|
|
14
14
|
});
|
|
15
15
|
const [isTransitioning, setIsTransitioning] = react.useState(false);
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
isLoading: s.isLoading,
|
|
19
|
-
hasPendingMatches: s.matches.some((d) => d.status === "pending")
|
|
20
|
-
}),
|
|
21
|
-
structuralSharing: true
|
|
22
|
-
});
|
|
16
|
+
const isLoading = (0, _tanstack_react_store.useStore)(router.stores.isLoading, (value) => value);
|
|
17
|
+
const hasPendingMatches = (0, _tanstack_react_store.useStore)(router.stores.hasPendingMatches, (value) => value);
|
|
23
18
|
const previousIsLoading = require_utils.usePrevious(isLoading);
|
|
24
19
|
const isAnyPending = isLoading || isTransitioning || hasPendingMatches;
|
|
25
20
|
const previousIsAnyPending = require_utils.usePrevious(isAnyPending);
|
|
@@ -68,7 +63,7 @@ function Transitioner() {
|
|
|
68
63
|
require_utils.useLayoutEffect(() => {
|
|
69
64
|
if (previousIsLoading && !isLoading) router.emit({
|
|
70
65
|
type: "onLoad",
|
|
71
|
-
...(0, _tanstack_router_core.getLocationChangeInfo)(router.state)
|
|
66
|
+
...(0, _tanstack_router_core.getLocationChangeInfo)(router.stores.location.state, router.stores.resolvedLocation.state)
|
|
72
67
|
});
|
|
73
68
|
}, [
|
|
74
69
|
previousIsLoading,
|
|
@@ -78,7 +73,7 @@ function Transitioner() {
|
|
|
78
73
|
require_utils.useLayoutEffect(() => {
|
|
79
74
|
if (previousIsPagePending && !isPagePending) router.emit({
|
|
80
75
|
type: "onBeforeRouteMount",
|
|
81
|
-
...(0, _tanstack_router_core.getLocationChangeInfo)(router.state)
|
|
76
|
+
...(0, _tanstack_router_core.getLocationChangeInfo)(router.stores.location.state, router.stores.resolvedLocation.state)
|
|
82
77
|
});
|
|
83
78
|
}, [
|
|
84
79
|
isPagePending,
|
|
@@ -87,16 +82,15 @@ function Transitioner() {
|
|
|
87
82
|
]);
|
|
88
83
|
require_utils.useLayoutEffect(() => {
|
|
89
84
|
if (previousIsAnyPending && !isAnyPending) {
|
|
90
|
-
const changeInfo = (0, _tanstack_router_core.getLocationChangeInfo)(router.state);
|
|
85
|
+
const changeInfo = (0, _tanstack_router_core.getLocationChangeInfo)(router.stores.location.state, router.stores.resolvedLocation.state);
|
|
91
86
|
router.emit({
|
|
92
87
|
type: "onResolved",
|
|
93
88
|
...changeInfo
|
|
94
89
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}));
|
|
90
|
+
(0, _tanstack_react_store.batch)(() => {
|
|
91
|
+
router.stores.status.setState(() => "idle");
|
|
92
|
+
router.stores.resolvedLocation.setState(() => router.stores.location.state);
|
|
93
|
+
});
|
|
100
94
|
if (changeInfo.hrefChanged) (0, _tanstack_router_core.handleHashScroll)(router);
|
|
101
95
|
}
|
|
102
96
|
}, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Transitioner.cjs","names":[],"sources":["../../src/Transitioner.tsx"],"sourcesContent":["import * as React from 'react'\nimport {\n getLocationChangeInfo,\n handleHashScroll,\n trimPathRight,\n} from '@tanstack/router-core'\nimport { useLayoutEffect, usePrevious } from './utils'\nimport { useRouter } from './useRouter'\
|
|
1
|
+
{"version":3,"file":"Transitioner.cjs","names":[],"sources":["../../src/Transitioner.tsx"],"sourcesContent":["import * as React from 'react'\nimport { batch, useStore } from '@tanstack/react-store'\nimport {\n getLocationChangeInfo,\n handleHashScroll,\n trimPathRight,\n} from '@tanstack/router-core'\nimport { useLayoutEffect, usePrevious } from './utils'\nimport { useRouter } from './useRouter'\n\nexport function Transitioner() {\n const router = useRouter()\n const mountLoadForRouter = React.useRef({ router, mounted: false })\n\n const [isTransitioning, setIsTransitioning] = React.useState(false)\n // Track pending state changes\n const isLoading = useStore(router.stores.isLoading, (value) => value)\n const hasPendingMatches = useStore(\n router.stores.hasPendingMatches,\n (value) => value,\n )\n\n const previousIsLoading = usePrevious(isLoading)\n\n const isAnyPending = isLoading || isTransitioning || hasPendingMatches\n const previousIsAnyPending = usePrevious(isAnyPending)\n\n const isPagePending = isLoading || hasPendingMatches\n const previousIsPagePending = usePrevious(isPagePending)\n\n router.startTransition = (fn: () => void) => {\n setIsTransitioning(true)\n React.startTransition(() => {\n fn()\n setIsTransitioning(false)\n })\n }\n\n // Subscribe to location changes\n // and try to load the new location\n React.useEffect(() => {\n const unsub = router.history.subscribe(router.load)\n\n const nextLocation = router.buildLocation({\n to: router.latestLocation.pathname,\n search: true,\n params: true,\n hash: true,\n state: true,\n _includeValidateSearch: true,\n })\n\n // Check if the current URL matches the canonical form.\n // Compare publicHref (browser-facing URL) for consistency with\n // the server-side redirect check in router.beforeLoad.\n if (\n trimPathRight(router.latestLocation.publicHref) !==\n trimPathRight(nextLocation.publicHref)\n ) {\n router.commitLocation({ ...nextLocation, replace: true })\n }\n\n return () => {\n unsub()\n }\n }, [router, router.history])\n\n // Try to load the initial location\n useLayoutEffect(() => {\n if (\n // if we are hydrating from SSR, loading is triggered in ssr-client\n (typeof window !== 'undefined' && router.ssr) ||\n (mountLoadForRouter.current.router === router &&\n mountLoadForRouter.current.mounted)\n ) {\n return\n }\n mountLoadForRouter.current = { router, mounted: true }\n\n const tryLoad = async () => {\n try {\n await router.load()\n } catch (err) {\n console.error(err)\n }\n }\n\n tryLoad()\n }, [router])\n\n useLayoutEffect(() => {\n // The router was loading and now it's not\n if (previousIsLoading && !isLoading) {\n router.emit({\n type: 'onLoad', // When the new URL has committed, when the new matches have been loaded into state.matches\n ...getLocationChangeInfo(\n router.stores.location.state,\n router.stores.resolvedLocation.state,\n ),\n })\n }\n }, [previousIsLoading, router, isLoading])\n\n useLayoutEffect(() => {\n // emit onBeforeRouteMount\n if (previousIsPagePending && !isPagePending) {\n router.emit({\n type: 'onBeforeRouteMount',\n ...getLocationChangeInfo(\n router.stores.location.state,\n router.stores.resolvedLocation.state,\n ),\n })\n }\n }, [isPagePending, previousIsPagePending, router])\n\n useLayoutEffect(() => {\n if (previousIsAnyPending && !isAnyPending) {\n const changeInfo = getLocationChangeInfo(\n router.stores.location.state,\n router.stores.resolvedLocation.state,\n )\n router.emit({\n type: 'onResolved',\n ...changeInfo,\n })\n\n batch(() => {\n router.stores.status.setState(() => 'idle')\n router.stores.resolvedLocation.setState(\n () => router.stores.location.state,\n )\n })\n\n if (changeInfo.hrefChanged) {\n handleHashScroll(router)\n }\n }\n }, [isAnyPending, previousIsAnyPending, router])\n\n return null\n}\n"],"mappings":";;;;;;;;AAUA,SAAgB,eAAe;CAC7B,MAAM,SAAS,kBAAA,WAAW;CAC1B,MAAM,qBAAqB,MAAM,OAAO;EAAE;EAAQ,SAAS;EAAO,CAAC;CAEnE,MAAM,CAAC,iBAAiB,sBAAsB,MAAM,SAAS,MAAM;CAEnE,MAAM,aAAA,GAAA,sBAAA,UAAqB,OAAO,OAAO,YAAY,UAAU,MAAM;CACrE,MAAM,qBAAA,GAAA,sBAAA,UACJ,OAAO,OAAO,oBACb,UAAU,MACZ;CAED,MAAM,oBAAoB,cAAA,YAAY,UAAU;CAEhD,MAAM,eAAe,aAAa,mBAAmB;CACrD,MAAM,uBAAuB,cAAA,YAAY,aAAa;CAEtD,MAAM,gBAAgB,aAAa;CACnC,MAAM,wBAAwB,cAAA,YAAY,cAAc;AAExD,QAAO,mBAAmB,OAAmB;AAC3C,qBAAmB,KAAK;AACxB,QAAM,sBAAsB;AAC1B,OAAI;AACJ,sBAAmB,MAAM;IACzB;;AAKJ,OAAM,gBAAgB;EACpB,MAAM,QAAQ,OAAO,QAAQ,UAAU,OAAO,KAAK;EAEnD,MAAM,eAAe,OAAO,cAAc;GACxC,IAAI,OAAO,eAAe;GAC1B,QAAQ;GACR,QAAQ;GACR,MAAM;GACN,OAAO;GACP,wBAAwB;GACzB,CAAC;AAKF,OAAA,GAAA,sBAAA,eACgB,OAAO,eAAe,WAAW,MAAA,GAAA,sBAAA,eACjC,aAAa,WAAW,CAEtC,QAAO,eAAe;GAAE,GAAG;GAAc,SAAS;GAAM,CAAC;AAG3D,eAAa;AACX,UAAO;;IAER,CAAC,QAAQ,OAAO,QAAQ,CAAC;AAG5B,eAAA,sBAAsB;AACpB,MAEG,OAAO,WAAW,eAAe,OAAO,OACxC,mBAAmB,QAAQ,WAAW,UACrC,mBAAmB,QAAQ,QAE7B;AAEF,qBAAmB,UAAU;GAAE;GAAQ,SAAS;GAAM;EAEtD,MAAM,UAAU,YAAY;AAC1B,OAAI;AACF,UAAM,OAAO,MAAM;YACZ,KAAK;AACZ,YAAQ,MAAM,IAAI;;;AAItB,WAAS;IACR,CAAC,OAAO,CAAC;AAEZ,eAAA,sBAAsB;AAEpB,MAAI,qBAAqB,CAAC,UACxB,QAAO,KAAK;GACV,MAAM;GACN,IAAA,GAAA,sBAAA,uBACE,OAAO,OAAO,SAAS,OACvB,OAAO,OAAO,iBAAiB,MAChC;GACF,CAAC;IAEH;EAAC;EAAmB;EAAQ;EAAU,CAAC;AAE1C,eAAA,sBAAsB;AAEpB,MAAI,yBAAyB,CAAC,cAC5B,QAAO,KAAK;GACV,MAAM;GACN,IAAA,GAAA,sBAAA,uBACE,OAAO,OAAO,SAAS,OACvB,OAAO,OAAO,iBAAiB,MAChC;GACF,CAAC;IAEH;EAAC;EAAe;EAAuB;EAAO,CAAC;AAElD,eAAA,sBAAsB;AACpB,MAAI,wBAAwB,CAAC,cAAc;GACzC,MAAM,cAAA,GAAA,sBAAA,uBACJ,OAAO,OAAO,SAAS,OACvB,OAAO,OAAO,iBAAiB,MAChC;AACD,UAAO,KAAK;IACV,MAAM;IACN,GAAG;IACJ,CAAC;AAEF,IAAA,GAAA,sBAAA,aAAY;AACV,WAAO,OAAO,OAAO,eAAe,OAAO;AAC3C,WAAO,OAAO,iBAAiB,eACvB,OAAO,OAAO,SAAS,MAC9B;KACD;AAEF,OAAI,WAAW,YACb,EAAA,GAAA,sBAAA,kBAAiB,OAAO;;IAG3B;EAAC;EAAc;EAAsB;EAAO,CAAC;AAEhD,QAAO"}
|
|
@@ -1,10 +1,109 @@
|
|
|
1
1
|
const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
|
|
2
2
|
const require_useRouter = require("./useRouter.cjs");
|
|
3
|
-
const require_useRouterState = require("./useRouterState.cjs");
|
|
4
3
|
let _tanstack_router_core = require("@tanstack/router-core");
|
|
5
4
|
let react = require("react");
|
|
6
5
|
react = require_runtime.__toESM(react);
|
|
6
|
+
let _tanstack_react_store = require("@tanstack/react-store");
|
|
7
|
+
let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
|
|
7
8
|
//#region src/headContentUtils.tsx
|
|
9
|
+
function buildTagsFromMatches(router, nonce, matches) {
|
|
10
|
+
const routeMeta = matches.map((match) => match.meta).filter(Boolean);
|
|
11
|
+
const resultMeta = [];
|
|
12
|
+
const metaByAttribute = {};
|
|
13
|
+
let title;
|
|
14
|
+
for (let i = routeMeta.length - 1; i >= 0; i--) {
|
|
15
|
+
const metas = routeMeta[i];
|
|
16
|
+
for (let j = metas.length - 1; j >= 0; j--) {
|
|
17
|
+
const m = metas[j];
|
|
18
|
+
if (!m) continue;
|
|
19
|
+
if (m.title) {
|
|
20
|
+
if (!title) title = {
|
|
21
|
+
tag: "title",
|
|
22
|
+
children: m.title
|
|
23
|
+
};
|
|
24
|
+
} else if ("script:ld+json" in m) try {
|
|
25
|
+
const json = JSON.stringify(m["script:ld+json"]);
|
|
26
|
+
resultMeta.push({
|
|
27
|
+
tag: "script",
|
|
28
|
+
attrs: { type: "application/ld+json" },
|
|
29
|
+
children: (0, _tanstack_router_core.escapeHtml)(json)
|
|
30
|
+
});
|
|
31
|
+
} catch {}
|
|
32
|
+
else {
|
|
33
|
+
const attribute = m.name ?? m.property;
|
|
34
|
+
if (attribute) if (metaByAttribute[attribute]) continue;
|
|
35
|
+
else metaByAttribute[attribute] = true;
|
|
36
|
+
resultMeta.push({
|
|
37
|
+
tag: "meta",
|
|
38
|
+
attrs: {
|
|
39
|
+
...m,
|
|
40
|
+
nonce
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (title) resultMeta.push(title);
|
|
47
|
+
if (nonce) resultMeta.push({
|
|
48
|
+
tag: "meta",
|
|
49
|
+
attrs: {
|
|
50
|
+
property: "csp-nonce",
|
|
51
|
+
content: nonce
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
resultMeta.reverse();
|
|
55
|
+
const constructedLinks = matches.map((match) => match.links).filter(Boolean).flat(1).map((link) => ({
|
|
56
|
+
tag: "link",
|
|
57
|
+
attrs: {
|
|
58
|
+
...link,
|
|
59
|
+
nonce
|
|
60
|
+
}
|
|
61
|
+
}));
|
|
62
|
+
const manifest = router.ssr?.manifest;
|
|
63
|
+
const assetLinks = matches.map((match) => manifest?.routes[match.routeId]?.assets ?? []).filter(Boolean).flat(1).filter((asset) => asset.tag === "link").map((asset) => ({
|
|
64
|
+
tag: "link",
|
|
65
|
+
attrs: {
|
|
66
|
+
...asset.attrs,
|
|
67
|
+
suppressHydrationWarning: true,
|
|
68
|
+
nonce
|
|
69
|
+
}
|
|
70
|
+
}));
|
|
71
|
+
const preloadLinks = [];
|
|
72
|
+
matches.map((match) => router.looseRoutesById[match.routeId]).forEach((route) => router.ssr?.manifest?.routes[route.id]?.preloads?.filter(Boolean).forEach((preload) => {
|
|
73
|
+
preloadLinks.push({
|
|
74
|
+
tag: "link",
|
|
75
|
+
attrs: {
|
|
76
|
+
rel: "modulepreload",
|
|
77
|
+
href: preload,
|
|
78
|
+
nonce
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}));
|
|
82
|
+
const styles = matches.map((match) => match.styles).flat(1).filter(Boolean).map(({ children, ...attrs }) => ({
|
|
83
|
+
tag: "style",
|
|
84
|
+
attrs: {
|
|
85
|
+
...attrs,
|
|
86
|
+
nonce
|
|
87
|
+
},
|
|
88
|
+
children
|
|
89
|
+
}));
|
|
90
|
+
const headScripts = matches.map((match) => match.headScripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
|
|
91
|
+
tag: "script",
|
|
92
|
+
attrs: {
|
|
93
|
+
...script,
|
|
94
|
+
nonce
|
|
95
|
+
},
|
|
96
|
+
children
|
|
97
|
+
}));
|
|
98
|
+
return uniqBy([
|
|
99
|
+
...resultMeta,
|
|
100
|
+
...preloadLinks,
|
|
101
|
+
...constructedLinks,
|
|
102
|
+
...assetLinks,
|
|
103
|
+
...styles,
|
|
104
|
+
...headScripts
|
|
105
|
+
], (d) => JSON.stringify(d));
|
|
106
|
+
}
|
|
8
107
|
/**
|
|
9
108
|
* Build the list of head/link/meta/script tags to render for active matches.
|
|
10
109
|
* Used internally by `HeadContent`.
|
|
@@ -12,9 +111,10 @@ react = require_runtime.__toESM(react);
|
|
|
12
111
|
var useTags = () => {
|
|
13
112
|
const router = require_useRouter.useRouter();
|
|
14
113
|
const nonce = router.options.ssr?.nonce;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
114
|
+
if (_tanstack_router_core_isServer.isServer ?? router.isServer) return buildTagsFromMatches(router, nonce, router.stores.activeMatchesSnapshot.state);
|
|
115
|
+
const routeMeta = (0, _tanstack_react_store.useStore)(router.stores.activeMatchesSnapshot, (matches) => {
|
|
116
|
+
return matches.map((match) => match.meta).filter(Boolean);
|
|
117
|
+
}, _tanstack_router_core.deepEqual);
|
|
18
118
|
const meta = react.useMemo(() => {
|
|
19
119
|
const resultMeta = [];
|
|
20
120
|
const metaByAttribute = {};
|
|
@@ -62,67 +162,55 @@ var useTags = () => {
|
|
|
62
162
|
resultMeta.reverse();
|
|
63
163
|
return resultMeta;
|
|
64
164
|
}, [routeMeta, nonce]);
|
|
65
|
-
const links =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
165
|
+
const links = (0, _tanstack_react_store.useStore)(router.stores.activeMatchesSnapshot, (matches) => {
|
|
166
|
+
const constructed = matches.map((match) => match.links).filter(Boolean).flat(1).map((link) => ({
|
|
167
|
+
tag: "link",
|
|
168
|
+
attrs: {
|
|
169
|
+
...link,
|
|
170
|
+
nonce
|
|
171
|
+
}
|
|
172
|
+
}));
|
|
173
|
+
const manifest = router.ssr?.manifest;
|
|
174
|
+
const assets = matches.map((match) => manifest?.routes[match.routeId]?.assets ?? []).filter(Boolean).flat(1).filter((asset) => asset.tag === "link").map((asset) => ({
|
|
175
|
+
tag: "link",
|
|
176
|
+
attrs: {
|
|
177
|
+
...asset.attrs,
|
|
178
|
+
suppressHydrationWarning: true,
|
|
179
|
+
nonce
|
|
180
|
+
}
|
|
181
|
+
}));
|
|
182
|
+
return [...constructed, ...assets];
|
|
183
|
+
}, _tanstack_router_core.deepEqual);
|
|
184
|
+
const preloadLinks = (0, _tanstack_react_store.useStore)(router.stores.activeMatchesSnapshot, (matches) => {
|
|
185
|
+
const preloadLinks = [];
|
|
186
|
+
matches.map((match) => router.looseRoutesById[match.routeId]).forEach((route) => router.ssr?.manifest?.routes[route.id]?.preloads?.filter(Boolean).forEach((preload) => {
|
|
187
|
+
preloadLinks.push({
|
|
76
188
|
tag: "link",
|
|
77
189
|
attrs: {
|
|
78
|
-
|
|
79
|
-
|
|
190
|
+
rel: "modulepreload",
|
|
191
|
+
href: preload,
|
|
80
192
|
nonce
|
|
81
193
|
}
|
|
82
|
-
})
|
|
83
|
-
|
|
194
|
+
});
|
|
195
|
+
}));
|
|
196
|
+
return preloadLinks;
|
|
197
|
+
}, _tanstack_router_core.deepEqual);
|
|
198
|
+
const styles = (0, _tanstack_react_store.useStore)(router.stores.activeMatchesSnapshot, (matches) => matches.map((match) => match.styles).flat(1).filter(Boolean).map(({ children, ...attrs }) => ({
|
|
199
|
+
tag: "style",
|
|
200
|
+
attrs: {
|
|
201
|
+
...attrs,
|
|
202
|
+
nonce
|
|
84
203
|
},
|
|
85
|
-
|
|
86
|
-
});
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
tag: "link",
|
|
93
|
-
attrs: {
|
|
94
|
-
rel: "modulepreload",
|
|
95
|
-
href: preload,
|
|
96
|
-
nonce
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
}));
|
|
100
|
-
return preloadLinks;
|
|
204
|
+
children
|
|
205
|
+
})), _tanstack_router_core.deepEqual);
|
|
206
|
+
const headScripts = (0, _tanstack_react_store.useStore)(router.stores.activeMatchesSnapshot, (matches) => matches.map((match) => match.headScripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
|
|
207
|
+
tag: "script",
|
|
208
|
+
attrs: {
|
|
209
|
+
...script,
|
|
210
|
+
nonce
|
|
101
211
|
},
|
|
102
|
-
|
|
103
|
-
});
|
|
104
|
-
const styles = require_useRouterState.useRouterState({
|
|
105
|
-
select: (state) => state.matches.map((match) => match.styles).flat(1).filter(Boolean).map(({ children, ...attrs }) => ({
|
|
106
|
-
tag: "style",
|
|
107
|
-
attrs: {
|
|
108
|
-
...attrs,
|
|
109
|
-
nonce
|
|
110
|
-
},
|
|
111
|
-
children
|
|
112
|
-
})),
|
|
113
|
-
structuralSharing: true
|
|
114
|
-
});
|
|
115
|
-
const headScripts = require_useRouterState.useRouterState({
|
|
116
|
-
select: (state) => state.matches.map((match) => match.headScripts).flat(1).filter(Boolean).map(({ children, ...script }) => ({
|
|
117
|
-
tag: "script",
|
|
118
|
-
attrs: {
|
|
119
|
-
...script,
|
|
120
|
-
nonce
|
|
121
|
-
},
|
|
122
|
-
children
|
|
123
|
-
})),
|
|
124
|
-
structuralSharing: true
|
|
125
|
-
});
|
|
212
|
+
children
|
|
213
|
+
})), _tanstack_router_core.deepEqual);
|
|
126
214
|
return uniqBy([
|
|
127
215
|
...meta,
|
|
128
216
|
...preloadLinks,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headContentUtils.cjs","names":[],"sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as React from 'react'\nimport { escapeHtml } from '@tanstack/router-core'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = () => {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n const routeMeta = useRouterState({\n select: (state) => {\n return state.matches.map((match) => match.meta!).filter(Boolean)\n },\n })\n\n const meta: Array<RouterManagedTag> = React.useMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n for (let i = routeMeta.length - 1; i >= 0; i--) {\n const metas = routeMeta[i]!\n for (let j = metas.length - 1; j >= 0; j--) {\n const m = metas[j]\n if (!m) continue\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else if ('script:ld+json' in m) {\n // Handle JSON-LD structured data\n // Content is HTML-escaped to prevent XSS when injected via dangerouslySetInnerHTML\n try {\n const json = JSON.stringify(m['script:ld+json'])\n resultMeta.push({\n tag: 'script',\n attrs: {\n type: 'application/ld+json',\n },\n children: escapeHtml(json),\n })\n } catch {\n // Skip invalid JSON-LD objects\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n continue\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n nonce,\n },\n })\n }\n }\n }\n\n if (title) {\n resultMeta.push(title)\n }\n\n if (nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n }, [routeMeta, nonce])\n\n const links = useRouterState({\n select: (state) => {\n const constructed = state.matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n nonce,\n },\n })) satisfies Array<RouterManagedTag>\n\n const manifest = router.ssr?.manifest\n\n // These are the assets extracted from the ViteManifest\n // using the `startManifestPlugin`\n const assets = state.matches\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .filter((asset) => asset.tag === 'link')\n .map(\n (asset) =>\n ({\n tag: 'link',\n attrs: {\n ...asset.attrs,\n suppressHydrationWarning: true,\n nonce,\n },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n },\n structuralSharing: true as any,\n })\n\n const preloadLinks = useRouterState({\n select: (state) => {\n const preloadLinks: Array<RouterManagedTag> = []\n\n state.matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadLinks.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadLinks\n },\n structuralSharing: true as any,\n })\n\n const styles = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...attrs }) => ({\n tag: 'style',\n attrs: {\n ...attrs,\n nonce,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n const headScripts: Array<RouterManagedTag> = useRouterState({\n select: (state) =>\n (\n state.matches\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n nonce,\n },\n children,\n })),\n structuralSharing: true as any,\n })\n\n return uniqBy(\n [\n ...meta,\n ...preloadLinks,\n ...links,\n ...styles,\n ...headScripts,\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\nexport function uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = fn(item)\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"headContentUtils.cjs","names":[],"sources":["../../src/headContentUtils.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useStore } from '@tanstack/react-store'\nimport { deepEqual, escapeHtml } from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport { useRouter } from './useRouter'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\nfunction buildTagsFromMatches(\n router: ReturnType<typeof useRouter>,\n nonce: string | undefined,\n matches: Array<any>,\n): Array<RouterManagedTag> {\n const routeMeta = matches.map((match) => match.meta!).filter(Boolean)\n\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n for (let i = routeMeta.length - 1; i >= 0; i--) {\n const metas = routeMeta[i]!\n for (let j = metas.length - 1; j >= 0; j--) {\n const m = metas[j]\n if (!m) continue\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else if ('script:ld+json' in m) {\n try {\n const json = JSON.stringify(m['script:ld+json'])\n resultMeta.push({\n tag: 'script',\n attrs: {\n type: 'application/ld+json',\n },\n children: escapeHtml(json),\n })\n } catch {\n // Skip invalid JSON-LD objects\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n continue\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n nonce,\n },\n })\n }\n }\n }\n\n if (title) {\n resultMeta.push(title)\n }\n\n if (nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: nonce,\n },\n })\n }\n resultMeta.reverse()\n\n const constructedLinks = matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n nonce,\n },\n })) satisfies Array<RouterManagedTag>\n\n const manifest = router.ssr?.manifest\n const assetLinks = matches\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .filter((asset) => asset.tag === 'link')\n .map(\n (asset) =>\n ({\n tag: 'link',\n attrs: {\n ...asset.attrs,\n suppressHydrationWarning: true,\n nonce,\n },\n }) satisfies RouterManagedTag,\n )\n\n const preloadLinks: Array<RouterManagedTag> = []\n matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadLinks.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n const styles = (\n matches\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...attrs }) => ({\n tag: 'style',\n attrs: {\n ...attrs,\n nonce,\n },\n children,\n }))\n\n const headScripts = (\n matches\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n nonce,\n },\n children,\n }))\n\n return uniqBy(\n [\n ...resultMeta,\n ...preloadLinks,\n ...constructedLinks,\n ...assetLinks,\n ...styles,\n ...headScripts,\n ] as Array<RouterManagedTag>,\n (d) => JSON.stringify(d),\n )\n}\n\n/**\n * Build the list of head/link/meta/script tags to render for active matches.\n * Used internally by `HeadContent`.\n */\nexport const useTags = () => {\n const router = useRouter()\n const nonce = router.options.ssr?.nonce\n\n if (isServer ?? router.isServer) {\n return buildTagsFromMatches(\n router,\n nonce,\n router.stores.activeMatchesSnapshot.state,\n )\n }\n\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n const routeMeta = useStore(\n router.stores.activeMatchesSnapshot,\n (matches) => {\n return matches.map((match) => match.meta!).filter(Boolean)\n },\n deepEqual,\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n const meta: Array<RouterManagedTag> = React.useMemo(() => {\n const resultMeta: Array<RouterManagedTag> = []\n const metaByAttribute: Record<string, true> = {}\n let title: RouterManagedTag | undefined\n for (let i = routeMeta.length - 1; i >= 0; i--) {\n const metas = routeMeta[i]!\n for (let j = metas.length - 1; j >= 0; j--) {\n const m = metas[j]\n if (!m) continue\n\n if (m.title) {\n if (!title) {\n title = {\n tag: 'title',\n children: m.title,\n }\n }\n } else if ('script:ld+json' in m) {\n // Handle JSON-LD structured data\n // Content is HTML-escaped to prevent XSS when injected via dangerouslySetInnerHTML\n try {\n const json = JSON.stringify(m['script:ld+json'])\n resultMeta.push({\n tag: 'script',\n attrs: {\n type: 'application/ld+json',\n },\n children: escapeHtml(json),\n })\n } catch {\n // Skip invalid JSON-LD objects\n }\n } else {\n const attribute = m.name ?? m.property\n if (attribute) {\n if (metaByAttribute[attribute]) {\n continue\n } else {\n metaByAttribute[attribute] = true\n }\n }\n\n resultMeta.push({\n tag: 'meta',\n attrs: {\n ...m,\n nonce,\n },\n })\n }\n }\n }\n\n if (title) {\n resultMeta.push(title)\n }\n\n if (nonce) {\n resultMeta.push({\n tag: 'meta',\n attrs: {\n property: 'csp-nonce',\n content: nonce,\n },\n })\n }\n resultMeta.reverse()\n\n return resultMeta\n }, [routeMeta, nonce])\n\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n const links = useStore(\n router.stores.activeMatchesSnapshot,\n (matches) => {\n const constructed = matches\n .map((match) => match.links!)\n .filter(Boolean)\n .flat(1)\n .map((link) => ({\n tag: 'link',\n attrs: {\n ...link,\n nonce,\n },\n })) satisfies Array<RouterManagedTag>\n\n const manifest = router.ssr?.manifest\n\n // These are the assets extracted from the ViteManifest\n // using the `startManifestPlugin`\n const assets = matches\n .map((match) => manifest?.routes[match.routeId]?.assets ?? [])\n .filter(Boolean)\n .flat(1)\n .filter((asset) => asset.tag === 'link')\n .map(\n (asset) =>\n ({\n tag: 'link',\n attrs: {\n ...asset.attrs,\n suppressHydrationWarning: true,\n nonce,\n },\n }) satisfies RouterManagedTag,\n )\n\n return [...constructed, ...assets]\n },\n deepEqual,\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n const preloadLinks = useStore(\n router.stores.activeMatchesSnapshot,\n (matches) => {\n const preloadLinks: Array<RouterManagedTag> = []\n\n matches\n .map((match) => router.looseRoutesById[match.routeId]!)\n .forEach((route) =>\n router.ssr?.manifest?.routes[route.id]?.preloads\n ?.filter(Boolean)\n .forEach((preload) => {\n preloadLinks.push({\n tag: 'link',\n attrs: {\n rel: 'modulepreload',\n href: preload,\n nonce,\n },\n })\n }),\n )\n\n return preloadLinks\n },\n deepEqual,\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n const styles = useStore(\n router.stores.activeMatchesSnapshot,\n (matches) =>\n (\n matches\n .map((match) => match.styles!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...attrs }) => ({\n tag: 'style',\n attrs: {\n ...attrs,\n nonce,\n },\n children,\n })),\n deepEqual,\n )\n\n // eslint-disable-next-line react-hooks/rules-of-hooks -- condition is static\n const headScripts: Array<RouterManagedTag> = useStore(\n router.stores.activeMatchesSnapshot,\n (matches) =>\n (\n matches\n .map((match) => match.headScripts!)\n .flat(1)\n .filter(Boolean) as Array<RouterManagedTag>\n ).map(({ children, ...script }) => ({\n tag: 'script',\n attrs: {\n ...script,\n nonce,\n },\n children,\n })),\n deepEqual,\n )\n\n return uniqBy(\n [\n ...meta,\n ...preloadLinks,\n ...links,\n ...styles,\n ...headScripts,\n ] as Array<RouterManagedTag>,\n (d) => {\n return JSON.stringify(d)\n },\n )\n}\n\nexport function uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {\n const seen = new Set<string>()\n return arr.filter((item) => {\n const key = fn(item)\n if (seen.has(key)) {\n return false\n }\n seen.add(key)\n return true\n })\n}\n"],"mappings":"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"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -4,7 +4,6 @@ const require_awaited = require("./awaited.cjs");
|
|
|
4
4
|
const require_CatchBoundary = require("./CatchBoundary.cjs");
|
|
5
5
|
const require_ClientOnly = require("./ClientOnly.cjs");
|
|
6
6
|
const require_useRouter = require("./useRouter.cjs");
|
|
7
|
-
const require_useRouterState = require("./useRouterState.cjs");
|
|
8
7
|
const require_useMatch = require("./useMatch.cjs");
|
|
9
8
|
const require_useLoaderData = require("./useLoaderData.cjs");
|
|
10
9
|
const require_useLoaderDeps = require("./useLoaderDeps.cjs");
|
|
@@ -24,6 +23,7 @@ const require_router = require("./router.cjs");
|
|
|
24
23
|
const require_RouterProvider = require("./RouterProvider.cjs");
|
|
25
24
|
const require_ScrollRestoration = require("./ScrollRestoration.cjs");
|
|
26
25
|
const require_useBlocker = require("./useBlocker.cjs");
|
|
26
|
+
const require_useRouterState = require("./useRouterState.cjs");
|
|
27
27
|
const require_useLocation = require("./useLocation.cjs");
|
|
28
28
|
const require_useCanGoBack = require("./useCanGoBack.cjs");
|
|
29
29
|
const require_Asset = require("./Asset.cjs");
|
package/dist/cjs/index.dev.cjs
CHANGED
|
@@ -4,7 +4,6 @@ const require_awaited = require("./awaited.cjs");
|
|
|
4
4
|
const require_CatchBoundary = require("./CatchBoundary.cjs");
|
|
5
5
|
const require_ClientOnly = require("./ClientOnly.cjs");
|
|
6
6
|
const require_useRouter = require("./useRouter.cjs");
|
|
7
|
-
const require_useRouterState = require("./useRouterState.cjs");
|
|
8
7
|
const require_useMatch = require("./useMatch.cjs");
|
|
9
8
|
const require_useLoaderData = require("./useLoaderData.cjs");
|
|
10
9
|
const require_useLoaderDeps = require("./useLoaderDeps.cjs");
|
|
@@ -24,6 +23,7 @@ const require_router = require("./router.cjs");
|
|
|
24
23
|
const require_RouterProvider = require("./RouterProvider.cjs");
|
|
25
24
|
const require_ScrollRestoration = require("./ScrollRestoration.cjs");
|
|
26
25
|
const require_useBlocker = require("./useBlocker.cjs");
|
|
26
|
+
const require_useRouterState = require("./useRouterState.cjs");
|
|
27
27
|
const require_useLocation = require("./useLocation.cjs");
|
|
28
28
|
const require_useCanGoBack = require("./useCanGoBack.cjs");
|
|
29
29
|
const require_Asset = require("./Asset.cjs");
|
package/dist/cjs/link.cjs
CHANGED
|
@@ -2,11 +2,11 @@ const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
|
|
|
2
2
|
const require_utils = require("./utils.cjs");
|
|
3
3
|
const require_ClientOnly = require("./ClientOnly.cjs");
|
|
4
4
|
const require_useRouter = require("./useRouter.cjs");
|
|
5
|
-
const require_useRouterState = require("./useRouterState.cjs");
|
|
6
5
|
let _tanstack_router_core = require("@tanstack/router-core");
|
|
7
6
|
let react = require("react");
|
|
8
7
|
react = require_runtime.__toESM(react);
|
|
9
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
|
+
let _tanstack_react_store = require("@tanstack/react-store");
|
|
10
10
|
let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
|
|
11
11
|
let react_dom = require("react-dom");
|
|
12
12
|
//#region src/link.tsx
|
|
@@ -80,7 +80,7 @@ function useLinkProps(options, forwardedRef) {
|
|
|
80
80
|
})();
|
|
81
81
|
const isActive = (() => {
|
|
82
82
|
if (externalLink) return false;
|
|
83
|
-
const currentLocation = router.
|
|
83
|
+
const currentLocation = router.stores.location.state;
|
|
84
84
|
const exact = activeOptions?.exact ?? false;
|
|
85
85
|
if (exact) {
|
|
86
86
|
if (!(0, _tanstack_router_core.exactPathTest)(currentLocation.pathname, next.pathname, router.basepath)) return false;
|
|
@@ -156,27 +156,9 @@ function useLinkProps(options, forwardedRef) {
|
|
|
156
156
|
};
|
|
157
157
|
}
|
|
158
158
|
const isHydrated = require_ClientOnly.useHydrated();
|
|
159
|
-
const
|
|
160
|
-
select: (s) => {
|
|
161
|
-
const leaf = s.matches[s.matches.length - 1];
|
|
162
|
-
return {
|
|
163
|
-
search: leaf?.search,
|
|
164
|
-
hash: s.location.hash,
|
|
165
|
-
path: leaf?.pathname
|
|
166
|
-
};
|
|
167
|
-
},
|
|
168
|
-
structuralSharing: true
|
|
169
|
-
});
|
|
170
|
-
const from = options.from;
|
|
171
|
-
const _options = react.useMemo(() => {
|
|
172
|
-
return {
|
|
173
|
-
...options,
|
|
174
|
-
from
|
|
175
|
-
};
|
|
176
|
-
}, [
|
|
159
|
+
const _options = react.useMemo(() => options, [
|
|
177
160
|
router,
|
|
178
|
-
|
|
179
|
-
from,
|
|
161
|
+
options.from,
|
|
180
162
|
options._fromLocation,
|
|
181
163
|
options.hash,
|
|
182
164
|
options.to,
|
|
@@ -186,7 +168,18 @@ function useLinkProps(options, forwardedRef) {
|
|
|
186
168
|
options.mask,
|
|
187
169
|
options.unsafeRelative
|
|
188
170
|
]);
|
|
189
|
-
const
|
|
171
|
+
const currentLocation = (0, _tanstack_react_store.useStore)(router.stores.location, (l) => l, (prev, next) => prev.href === next.href);
|
|
172
|
+
const next = react.useMemo(() => {
|
|
173
|
+
const opts = {
|
|
174
|
+
_fromLocation: currentLocation,
|
|
175
|
+
..._options
|
|
176
|
+
};
|
|
177
|
+
return router.buildLocation(opts);
|
|
178
|
+
}, [
|
|
179
|
+
router,
|
|
180
|
+
currentLocation,
|
|
181
|
+
_options
|
|
182
|
+
]);
|
|
190
183
|
const hrefOptionPublicHref = next.maskedLocation ? next.maskedLocation.publicHref : next.publicHref;
|
|
191
184
|
const hrefOptionExternal = next.maskedLocation ? next.maskedLocation.external : next.external;
|
|
192
185
|
const hrefOption = react.useMemo(() => getHrefOption(hrefOptionPublicHref, hrefOptionExternal, router.history, disabled), [
|
|
@@ -218,24 +211,36 @@ function useLinkProps(options, forwardedRef) {
|
|
|
218
211
|
hrefOption,
|
|
219
212
|
router.protocolAllowlist
|
|
220
213
|
]);
|
|
221
|
-
const isActive =
|
|
214
|
+
const isActive = react.useMemo(() => {
|
|
222
215
|
if (externalLink) return false;
|
|
223
216
|
if (activeOptions?.exact) {
|
|
224
|
-
if (!(0, _tanstack_router_core.exactPathTest)(
|
|
217
|
+
if (!(0, _tanstack_router_core.exactPathTest)(currentLocation.pathname, next.pathname, router.basepath)) return false;
|
|
225
218
|
} else {
|
|
226
|
-
const currentPathSplit = (0, _tanstack_router_core.removeTrailingSlash)(
|
|
219
|
+
const currentPathSplit = (0, _tanstack_router_core.removeTrailingSlash)(currentLocation.pathname, router.basepath);
|
|
227
220
|
const nextPathSplit = (0, _tanstack_router_core.removeTrailingSlash)(next.pathname, router.basepath);
|
|
228
221
|
if (!(currentPathSplit.startsWith(nextPathSplit) && (currentPathSplit.length === nextPathSplit.length || currentPathSplit[nextPathSplit.length] === "/"))) return false;
|
|
229
222
|
}
|
|
230
223
|
if (activeOptions?.includeSearch ?? true) {
|
|
231
|
-
if (!(0, _tanstack_router_core.deepEqual)(
|
|
224
|
+
if (!(0, _tanstack_router_core.deepEqual)(currentLocation.search, next.search, {
|
|
232
225
|
partial: !activeOptions?.exact,
|
|
233
226
|
ignoreUndefined: !activeOptions?.explicitUndefined
|
|
234
227
|
})) return false;
|
|
235
228
|
}
|
|
236
|
-
if (activeOptions?.includeHash) return isHydrated &&
|
|
229
|
+
if (activeOptions?.includeHash) return isHydrated && currentLocation.hash === next.hash;
|
|
237
230
|
return true;
|
|
238
|
-
}
|
|
231
|
+
}, [
|
|
232
|
+
activeOptions?.exact,
|
|
233
|
+
activeOptions?.explicitUndefined,
|
|
234
|
+
activeOptions?.includeHash,
|
|
235
|
+
activeOptions?.includeSearch,
|
|
236
|
+
currentLocation,
|
|
237
|
+
externalLink,
|
|
238
|
+
isHydrated,
|
|
239
|
+
next.hash,
|
|
240
|
+
next.pathname,
|
|
241
|
+
next.search,
|
|
242
|
+
router.basepath
|
|
243
|
+
]);
|
|
239
244
|
const resolvedActiveProps = isActive ? (0, _tanstack_router_core.functionalUpdate)(activeProps, {}) ?? STATIC_ACTIVE_OBJECT : STATIC_EMPTY_OBJECT;
|
|
240
245
|
const resolvedInactiveProps = isActive ? STATIC_EMPTY_OBJECT : (0, _tanstack_router_core.functionalUpdate)(inactiveProps, {}) ?? STATIC_EMPTY_OBJECT;
|
|
241
246
|
const resolvedClassName = [
|