@tanstack/solid-router 1.108.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/LICENSE +21 -0
- package/README.md +29 -0
- package/dist/cjs/Asset.cjs +59 -0
- package/dist/cjs/Asset.cjs.map +1 -0
- package/dist/cjs/Asset.d.cts +2 -0
- package/dist/cjs/CatchBoundary.cjs +92 -0
- package/dist/cjs/CatchBoundary.cjs.map +1 -0
- package/dist/cjs/CatchBoundary.d.cts +11 -0
- package/dist/cjs/HeadContent.cjs +129 -0
- package/dist/cjs/HeadContent.cjs.map +1 -0
- package/dist/cjs/HeadContent.d.cts +8 -0
- package/dist/cjs/Match.cjs +340 -0
- package/dist/cjs/Match.cjs.map +1 -0
- package/dist/cjs/Match.d.cts +8 -0
- package/dist/cjs/Matches.cjs +151 -0
- package/dist/cjs/Matches.cjs.map +1 -0
- package/dist/cjs/Matches.d.cts +69 -0
- package/dist/cjs/RouterProvider.cjs +45 -0
- package/dist/cjs/RouterProvider.cjs.map +1 -0
- package/dist/cjs/RouterProvider.d.cts +35 -0
- package/dist/cjs/SafeFragment.cjs +8 -0
- package/dist/cjs/SafeFragment.cjs.map +1 -0
- package/dist/cjs/SafeFragment.d.cts +1 -0
- package/dist/cjs/ScriptOnce.cjs +23 -0
- package/dist/cjs/ScriptOnce.cjs.map +1 -0
- package/dist/cjs/ScriptOnce.d.cts +5 -0
- package/dist/cjs/Scripts.cjs +48 -0
- package/dist/cjs/Scripts.cjs.map +1 -0
- package/dist/cjs/Scripts.d.cts +1 -0
- package/dist/cjs/ScrollRestoration.cjs +37 -0
- package/dist/cjs/ScrollRestoration.cjs.map +1 -0
- package/dist/cjs/ScrollRestoration.d.cts +15 -0
- package/dist/cjs/Transitioner.cjs +132 -0
- package/dist/cjs/Transitioner.cjs.map +1 -0
- package/dist/cjs/Transitioner.d.cts +1 -0
- package/dist/cjs/awaited.cjs +53 -0
- package/dist/cjs/awaited.cjs.map +1 -0
- package/dist/cjs/awaited.d.cts +11 -0
- package/dist/cjs/fileRoute.cjs +90 -0
- package/dist/cjs/fileRoute.cjs.map +1 -0
- package/dist/cjs/fileRoute.d.cts +58 -0
- package/dist/cjs/history.d.cts +8 -0
- package/dist/cjs/index.cjs +260 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +53 -0
- package/dist/cjs/lazyRouteComponent.cjs +74 -0
- package/dist/cjs/lazyRouteComponent.cjs.map +1 -0
- package/dist/cjs/lazyRouteComponent.d.cts +7 -0
- package/dist/cjs/link.cjs +279 -0
- package/dist/cjs/link.cjs.map +1 -0
- package/dist/cjs/link.d.cts +113 -0
- package/dist/cjs/matchContext.cjs +25 -0
- package/dist/cjs/matchContext.cjs.map +1 -0
- package/dist/cjs/matchContext.d.cts +3 -0
- package/dist/cjs/not-found.cjs +51 -0
- package/dist/cjs/not-found.cjs.map +1 -0
- package/dist/cjs/not-found.d.cts +27 -0
- package/dist/cjs/redirects.cjs +29 -0
- package/dist/cjs/redirects.cjs.map +1 -0
- package/dist/cjs/redirects.d.cts +21 -0
- package/dist/cjs/renderRouteNotFound.cjs +23 -0
- package/dist/cjs/renderRouteNotFound.cjs.map +1 -0
- package/dist/cjs/renderRouteNotFound.d.cts +3 -0
- package/dist/cjs/route.cjs +233 -0
- package/dist/cjs/route.cjs.map +1 -0
- package/dist/cjs/route.d.cts +297 -0
- package/dist/cjs/routeInfo.d.cts +53 -0
- package/dist/cjs/router.cjs +1687 -0
- package/dist/cjs/router.cjs.map +1 -0
- package/dist/cjs/router.d.cts +555 -0
- package/dist/cjs/routerContext.cjs +33 -0
- package/dist/cjs/routerContext.cjs.map +1 -0
- package/dist/cjs/routerContext.d.cts +8 -0
- package/dist/cjs/scroll-restoration.cjs +183 -0
- package/dist/cjs/scroll-restoration.cjs.map +1 -0
- package/dist/cjs/scroll-restoration.d.cts +29 -0
- package/dist/cjs/typePrimitives.d.cts +66 -0
- package/dist/cjs/useBlocker.cjs +165 -0
- package/dist/cjs/useBlocker.cjs.map +1 -0
- package/dist/cjs/useBlocker.d.cts +68 -0
- package/dist/cjs/useCanGoBack.cjs +8 -0
- package/dist/cjs/useCanGoBack.cjs.map +1 -0
- package/dist/cjs/useCanGoBack.d.cts +1 -0
- package/dist/cjs/useLoaderData.cjs +14 -0
- package/dist/cjs/useLoaderData.cjs.map +1 -0
- package/dist/cjs/useLoaderData.d.cts +13 -0
- package/dist/cjs/useLoaderDeps.cjs +17 -0
- package/dist/cjs/useLoaderDeps.cjs.map +1 -0
- package/dist/cjs/useLoaderDeps.d.cts +12 -0
- package/dist/cjs/useLocation.cjs +10 -0
- package/dist/cjs/useLocation.cjs.map +1 -0
- package/dist/cjs/useLocation.d.cts +7 -0
- package/dist/cjs/useMatch.cjs +39 -0
- package/dist/cjs/useMatch.cjs.map +1 -0
- package/dist/cjs/useMatch.d.cts +14 -0
- package/dist/cjs/useNavigate.cjs +45 -0
- package/dist/cjs/useNavigate.cjs.map +1 -0
- package/dist/cjs/useNavigate.d.cts +7 -0
- package/dist/cjs/useParams.cjs +15 -0
- package/dist/cjs/useParams.cjs.map +1 -0
- package/dist/cjs/useParams.d.cts +15 -0
- package/dist/cjs/useRouteContext.cjs +11 -0
- package/dist/cjs/useRouteContext.cjs.map +1 -0
- package/dist/cjs/useRouteContext.d.cts +13 -0
- package/dist/cjs/useRouter.cjs +29 -0
- package/dist/cjs/useRouter.cjs.map +1 -0
- package/dist/cjs/useRouter.d.cts +4 -0
- package/dist/cjs/useRouterState.cjs +16 -0
- package/dist/cjs/useRouterState.cjs.map +1 -0
- package/dist/cjs/useRouterState.d.cts +8 -0
- package/dist/cjs/useSearch.cjs +15 -0
- package/dist/cjs/useSearch.cjs.map +1 -0
- package/dist/cjs/useSearch.d.cts +15 -0
- package/dist/cjs/utils.cjs +58 -0
- package/dist/cjs/utils.cjs.map +1 -0
- package/dist/cjs/utils.d.cts +44 -0
- package/dist/esm/Asset.d.ts +2 -0
- package/dist/esm/Asset.js +59 -0
- package/dist/esm/Asset.js.map +1 -0
- package/dist/esm/CatchBoundary.d.ts +11 -0
- package/dist/esm/CatchBoundary.js +75 -0
- package/dist/esm/CatchBoundary.js.map +1 -0
- package/dist/esm/HeadContent.d.ts +8 -0
- package/dist/esm/HeadContent.js +112 -0
- package/dist/esm/HeadContent.js.map +1 -0
- package/dist/esm/Match.d.ts +8 -0
- package/dist/esm/Match.js +323 -0
- package/dist/esm/Match.js.map +1 -0
- package/dist/esm/Matches.d.ts +69 -0
- package/dist/esm/Matches.js +134 -0
- package/dist/esm/Matches.js.map +1 -0
- package/dist/esm/RouterProvider.d.ts +35 -0
- package/dist/esm/RouterProvider.js +45 -0
- package/dist/esm/RouterProvider.js.map +1 -0
- package/dist/esm/SafeFragment.d.ts +1 -0
- package/dist/esm/SafeFragment.js +8 -0
- package/dist/esm/SafeFragment.js.map +1 -0
- package/dist/esm/ScriptOnce.d.ts +5 -0
- package/dist/esm/ScriptOnce.js +23 -0
- package/dist/esm/ScriptOnce.js.map +1 -0
- package/dist/esm/Scripts.d.ts +1 -0
- package/dist/esm/Scripts.js +48 -0
- package/dist/esm/Scripts.js.map +1 -0
- package/dist/esm/ScrollRestoration.d.ts +15 -0
- package/dist/esm/ScrollRestoration.js +37 -0
- package/dist/esm/ScrollRestoration.js.map +1 -0
- package/dist/esm/Transitioner.d.ts +1 -0
- package/dist/esm/Transitioner.js +115 -0
- package/dist/esm/Transitioner.js.map +1 -0
- package/dist/esm/awaited.d.ts +11 -0
- package/dist/esm/awaited.js +36 -0
- package/dist/esm/awaited.js.map +1 -0
- package/dist/esm/fileRoute.d.ts +58 -0
- package/dist/esm/fileRoute.js +90 -0
- package/dist/esm/fileRoute.js.map +1 -0
- package/dist/esm/history.d.ts +8 -0
- package/dist/esm/index.d.ts +53 -0
- package/dist/esm/index.js +149 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lazyRouteComponent.d.ts +7 -0
- package/dist/esm/lazyRouteComponent.js +74 -0
- package/dist/esm/lazyRouteComponent.js.map +1 -0
- package/dist/esm/link.d.ts +113 -0
- package/dist/esm/link.js +262 -0
- package/dist/esm/link.js.map +1 -0
- package/dist/esm/matchContext.d.ts +3 -0
- package/dist/esm/matchContext.js +8 -0
- package/dist/esm/matchContext.js.map +1 -0
- package/dist/esm/not-found.d.ts +27 -0
- package/dist/esm/not-found.js +51 -0
- package/dist/esm/not-found.js.map +1 -0
- package/dist/esm/redirects.d.ts +21 -0
- package/dist/esm/redirects.js +29 -0
- package/dist/esm/redirects.js.map +1 -0
- package/dist/esm/renderRouteNotFound.d.ts +3 -0
- package/dist/esm/renderRouteNotFound.js +23 -0
- package/dist/esm/renderRouteNotFound.js.map +1 -0
- package/dist/esm/route.d.ts +297 -0
- package/dist/esm/route.js +233 -0
- package/dist/esm/route.js.map +1 -0
- package/dist/esm/routeInfo.d.ts +53 -0
- package/dist/esm/router.d.ts +555 -0
- package/dist/esm/router.js +1687 -0
- package/dist/esm/router.js.map +1 -0
- package/dist/esm/routerContext.d.ts +8 -0
- package/dist/esm/routerContext.js +16 -0
- package/dist/esm/routerContext.js.map +1 -0
- package/dist/esm/scroll-restoration.d.ts +29 -0
- package/dist/esm/scroll-restoration.js +183 -0
- package/dist/esm/scroll-restoration.js.map +1 -0
- package/dist/esm/typePrimitives.d.ts +66 -0
- package/dist/esm/useBlocker.d.ts +68 -0
- package/dist/esm/useBlocker.js +148 -0
- package/dist/esm/useBlocker.js.map +1 -0
- package/dist/esm/useCanGoBack.d.ts +1 -0
- package/dist/esm/useCanGoBack.js +8 -0
- package/dist/esm/useCanGoBack.js.map +1 -0
- package/dist/esm/useLoaderData.d.ts +13 -0
- package/dist/esm/useLoaderData.js +14 -0
- package/dist/esm/useLoaderData.js.map +1 -0
- package/dist/esm/useLoaderDeps.d.ts +12 -0
- package/dist/esm/useLoaderDeps.js +17 -0
- package/dist/esm/useLoaderDeps.js.map +1 -0
- package/dist/esm/useLocation.d.ts +7 -0
- package/dist/esm/useLocation.js +10 -0
- package/dist/esm/useLocation.js.map +1 -0
- package/dist/esm/useMatch.d.ts +14 -0
- package/dist/esm/useMatch.js +22 -0
- package/dist/esm/useMatch.js.map +1 -0
- package/dist/esm/useNavigate.d.ts +7 -0
- package/dist/esm/useNavigate.js +28 -0
- package/dist/esm/useNavigate.js.map +1 -0
- package/dist/esm/useParams.d.ts +15 -0
- package/dist/esm/useParams.js +15 -0
- package/dist/esm/useParams.js.map +1 -0
- package/dist/esm/useRouteContext.d.ts +13 -0
- package/dist/esm/useRouteContext.js +11 -0
- package/dist/esm/useRouteContext.js.map +1 -0
- package/dist/esm/useRouter.d.ts +4 -0
- package/dist/esm/useRouter.js +12 -0
- package/dist/esm/useRouter.js.map +1 -0
- package/dist/esm/useRouterState.d.ts +8 -0
- package/dist/esm/useRouterState.js +16 -0
- package/dist/esm/useRouterState.js.map +1 -0
- package/dist/esm/useSearch.d.ts +15 -0
- package/dist/esm/useSearch.js +15 -0
- package/dist/esm/useSearch.js.map +1 -0
- package/dist/esm/utils.d.ts +44 -0
- package/dist/esm/utils.js +41 -0
- package/dist/esm/utils.js.map +1 -0
- package/package.json +75 -0
- package/src/Asset.tsx +23 -0
- package/src/CatchBoundary.tsx +78 -0
- package/src/HeadContent.tsx +146 -0
- package/src/Match.tsx +356 -0
- package/src/Matches.tsx +348 -0
- package/src/RouterProvider.tsx +130 -0
- package/src/SafeFragment.tsx +3 -0
- package/src/ScriptOnce.tsx +30 -0
- package/src/Scripts.tsx +65 -0
- package/src/ScrollRestoration.tsx +65 -0
- package/src/Transitioner.tsx +152 -0
- package/src/awaited.tsx +49 -0
- package/src/fileRoute.ts +274 -0
- package/src/history.ts +9 -0
- package/src/index.tsx +359 -0
- package/src/lazyRouteComponent.tsx +114 -0
- package/src/link.tsx +1002 -0
- package/src/matchContext.tsx +10 -0
- package/src/not-found.tsx +69 -0
- package/src/redirects.ts +71 -0
- package/src/renderRouteNotFound.tsx +27 -0
- package/src/route.ts +1477 -0
- package/src/routeInfo.ts +239 -0
- package/src/router.ts +3066 -0
- package/src/routerContext.tsx +26 -0
- package/src/scroll-restoration.tsx +337 -0
- package/src/typePrimitives.ts +195 -0
- package/src/useBlocker.tsx +298 -0
- package/src/useCanGoBack.ts +5 -0
- package/src/useLoaderData.tsx +64 -0
- package/src/useLoaderDeps.tsx +52 -0
- package/src/useLocation.tsx +26 -0
- package/src/useMatch.tsx +96 -0
- package/src/useNavigate.tsx +61 -0
- package/src/useParams.tsx +83 -0
- package/src/useRouteContext.ts +62 -0
- package/src/useRouter.tsx +15 -0
- package/src/useRouterState.tsx +32 -0
- package/src/useSearch.tsx +84 -0
- package/src/utils.ts +96 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as Solid from "solid-js";
|
|
2
|
+
import warning from "tiny-warning";
|
|
3
|
+
import { getRouterContext } from "./routerContext.js";
|
|
4
|
+
function useRouter(opts) {
|
|
5
|
+
const value = Solid.useContext(getRouterContext());
|
|
6
|
+
warning(!(((opts == null ? void 0 : opts.warn) ?? true) && !value), "useRouter must be used inside a <RouterProvider> component!");
|
|
7
|
+
return value;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
useRouter
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=useRouter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRouter.js","sources":["../../src/useRouter.tsx"],"sourcesContent":["import * as Solid from 'solid-js'\nimport warning from 'tiny-warning'\nimport { getRouterContext } from './routerContext'\nimport type { AnyRouter, RegisteredRouter } from './router'\n\nexport function useRouter<TRouter extends AnyRouter = RegisteredRouter>(opts?: {\n warn?: boolean\n}): TRouter {\n const value = Solid.useContext(getRouterContext() as any)\n warning(\n !((opts?.warn ?? true) && !value),\n 'useRouter must be used inside a <RouterProvider> component!',\n )\n return value as any\n}\n"],"names":["useRouter","opts","value","Solid","useContext","getRouterContext","warning","warn"],"mappings":";;;AAKO,SAASA,UAAwDC,MAE5D;AACV,QAAMC,QAAQC,MAAMC,WAAWC,iBAAAA,CAAyB;AACxDC,UACE,IAAGL,6BAAMM,SAAQ,SAAS,CAACL,QAC3B,6DACF;AACOA,SAAAA;AACT;"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AnyRouter, RegisteredRouter, RouterState } from './router.js';
|
|
2
|
+
import { Accessor } from 'solid-js';
|
|
3
|
+
export type UseRouterStateOptions<TRouter extends AnyRouter, TSelected> = {
|
|
4
|
+
router?: TRouter;
|
|
5
|
+
select?: (state: RouterState<TRouter['routeTree']>) => TSelected;
|
|
6
|
+
};
|
|
7
|
+
export type UseRouterStateResult<TRouter extends AnyRouter, TSelected> = unknown extends TSelected ? RouterState<TRouter['routeTree']> : TSelected;
|
|
8
|
+
export declare function useRouterState<TRouter extends AnyRouter = RegisteredRouter, TSelected = unknown>(opts?: UseRouterStateOptions<TRouter, TSelected>): Accessor<UseRouterStateResult<TRouter, TSelected>>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useStore } from "@tanstack/solid-store";
|
|
2
|
+
import { useRouter } from "./useRouter.js";
|
|
3
|
+
function useRouterState(opts) {
|
|
4
|
+
const contextRouter = useRouter({
|
|
5
|
+
warn: (opts == null ? void 0 : opts.router) === void 0
|
|
6
|
+
});
|
|
7
|
+
const router = (opts == null ? void 0 : opts.router) || contextRouter;
|
|
8
|
+
return useStore(router.__store, (state) => {
|
|
9
|
+
if (opts == null ? void 0 : opts.select) return opts.select(state);
|
|
10
|
+
return state;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
useRouterState
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=useRouterState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRouterState.js","sources":["../../src/useRouterState.tsx"],"sourcesContent":["import { useStore } from '@tanstack/solid-store'\nimport { useRouter } from './useRouter'\nimport type { AnyRouter, RegisteredRouter, RouterState } from './router'\nimport type { Accessor } from 'solid-js'\n\nexport type UseRouterStateOptions<TRouter extends AnyRouter, TSelected> = {\n router?: TRouter\n select?: (state: RouterState<TRouter['routeTree']>) => TSelected\n}\n\nexport type UseRouterStateResult<\n TRouter extends AnyRouter,\n TSelected,\n> = unknown extends TSelected ? RouterState<TRouter['routeTree']> : TSelected\n\nexport function useRouterState<\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n>(\n opts?: UseRouterStateOptions<TRouter, TSelected>,\n): Accessor<UseRouterStateResult<TRouter, TSelected>> {\n const contextRouter = useRouter<TRouter>({\n warn: opts?.router === undefined,\n })\n const router = opts?.router || contextRouter\n\n return useStore(router.__store, (state) => {\n if (opts?.select) return opts.select(state)\n\n return state\n }) as Accessor<UseRouterStateResult<TRouter, TSelected>>\n}\n"],"names":["useRouterState","opts","contextRouter","useRouter","warn","router","undefined","useStore","__store","state","select"],"mappings":";;AAeO,SAASA,eAIdC,MACoD;AACpD,QAAMC,gBAAgBC,UAAmB;AAAA,IACvCC,OAAMH,6BAAMI,YAAWC;AAAAA,EAAAA,CACxB;AACKD,QAAAA,UAASJ,6BAAMI,WAAUH;AAExBK,SAAAA,SAASF,OAAOG,SAAUC,CAAU,UAAA;AACzC,QAAIR,6BAAMS,OAAeT,QAAAA,KAAKS,OAAOD,KAAK;AAEnCA,WAAAA;AAAAA,EAAAA,CACR;AACH;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ThrowConstraint } from './useMatch.js';
|
|
2
|
+
import { Accessor } from 'solid-js';
|
|
3
|
+
import { FullSearchSchema, RouteById } from './routeInfo.js';
|
|
4
|
+
import { AnyRouter, RegisteredRouter } from './router.js';
|
|
5
|
+
import { StrictOrFrom } from './utils.js';
|
|
6
|
+
import { Expand, ThrowOrOptional } from '@tanstack/router-core';
|
|
7
|
+
export interface UseSearchBaseOptions<TRouter extends AnyRouter, TFrom, TStrict extends boolean, TThrow extends boolean, TSelected> {
|
|
8
|
+
select?: (state: ResolveSearch<TRouter, TFrom, TStrict>) => TSelected;
|
|
9
|
+
shouldThrow?: TThrow;
|
|
10
|
+
}
|
|
11
|
+
export type UseSearchOptions<TRouter extends AnyRouter, TFrom, TStrict extends boolean, TThrow extends boolean, TSelected> = StrictOrFrom<TRouter, TFrom, TStrict> & UseSearchBaseOptions<TRouter, TFrom, TStrict, TThrow, TSelected>;
|
|
12
|
+
export type UseSearchResult<TRouter extends AnyRouter, TFrom, TStrict extends boolean, TSelected> = unknown extends TSelected ? ResolveSearch<TRouter, TFrom, TStrict> : TSelected;
|
|
13
|
+
export type ResolveSearch<TRouter extends AnyRouter, TFrom, TStrict extends boolean> = TStrict extends false ? FullSearchSchema<TRouter['routeTree']> : Expand<RouteById<TRouter['routeTree'], TFrom>['types']['fullSearchSchema']>;
|
|
14
|
+
export type UseSearchRoute<out TFrom> = <TRouter extends AnyRouter = RegisteredRouter, TSelected = unknown>(opts?: UseSearchBaseOptions<TRouter, TFrom, true, true, TSelected>) => Accessor<UseSearchResult<TRouter, TFrom, true, TSelected>>;
|
|
15
|
+
export declare function useSearch<TRouter extends AnyRouter = RegisteredRouter, const TFrom extends string | undefined = undefined, TStrict extends boolean = true, TThrow extends boolean = true, TSelected = unknown>(opts: UseSearchOptions<TRouter, TFrom, TStrict, ThrowConstraint<TStrict, TThrow>, TSelected>): Accessor<ThrowOrOptional<UseSearchResult<TRouter, TFrom, TStrict, TSelected>, TThrow>>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useMatch } from "./useMatch.js";
|
|
2
|
+
function useSearch(opts) {
|
|
3
|
+
return useMatch({
|
|
4
|
+
from: opts.from,
|
|
5
|
+
strict: opts.strict,
|
|
6
|
+
shouldThrow: opts.shouldThrow,
|
|
7
|
+
select: (match) => {
|
|
8
|
+
return opts.select ? opts.select(match.search) : match.search;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
useSearch
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useSearch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSearch.js","sources":["../../src/useSearch.tsx"],"sourcesContent":["import { useMatch } from './useMatch'\nimport type { ThrowConstraint } from './useMatch'\nimport type { Accessor } from 'solid-js'\nimport type { FullSearchSchema, RouteById } from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type { StrictOrFrom } from './utils'\nimport type { Expand, ThrowOrOptional } from '@tanstack/router-core'\n\nexport interface UseSearchBaseOptions<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TThrow extends boolean,\n TSelected,\n> {\n select?: (state: ResolveSearch<TRouter, TFrom, TStrict>) => TSelected\n shouldThrow?: TThrow\n}\n\nexport type UseSearchOptions<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TThrow extends boolean,\n TSelected,\n> = StrictOrFrom<TRouter, TFrom, TStrict> &\n UseSearchBaseOptions<TRouter, TFrom, TStrict, TThrow, TSelected>\n\nexport type UseSearchResult<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n TSelected,\n> = unknown extends TSelected\n ? ResolveSearch<TRouter, TFrom, TStrict>\n : TSelected\n\nexport type ResolveSearch<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean,\n> = TStrict extends false\n ? FullSearchSchema<TRouter['routeTree']>\n : Expand<RouteById<TRouter['routeTree'], TFrom>['types']['fullSearchSchema']>\n\nexport type UseSearchRoute<out TFrom> = <\n TRouter extends AnyRouter = RegisteredRouter,\n TSelected = unknown,\n>(\n opts?: UseSearchBaseOptions<\n TRouter,\n TFrom,\n /* TStrict */ true,\n /* TThrow */ true,\n TSelected\n >,\n) => Accessor<UseSearchResult<TRouter, TFrom, true, TSelected>>\n\nexport function useSearch<\n TRouter extends AnyRouter = RegisteredRouter,\n const TFrom extends string | undefined = undefined,\n TStrict extends boolean = true,\n TThrow extends boolean = true,\n TSelected = unknown,\n>(\n opts: UseSearchOptions<\n TRouter,\n TFrom,\n TStrict,\n ThrowConstraint<TStrict, TThrow>,\n TSelected\n >,\n): Accessor<\n ThrowOrOptional<UseSearchResult<TRouter, TFrom, TStrict, TSelected>, TThrow>\n> {\n return useMatch({\n from: opts.from!,\n strict: opts.strict,\n shouldThrow: opts.shouldThrow,\n select: (match: any) => {\n return opts.select ? opts.select(match.search) : match.search\n },\n }) as any\n}\n"],"names":["useSearch","opts","useMatch","from","strict","shouldThrow","select","match","search"],"mappings":";AA0DO,SAASA,UAOdC,MASA;AACA,SAAOC,SAAS;AAAA,IACdC,MAAMF,KAAKE;AAAAA,IACXC,QAAQH,KAAKG;AAAAA,IACbC,aAAaJ,KAAKI;AAAAA,IAClBC,QAAQA,CAACC,UAAe;AACtB,aAAON,KAAKK,SAASL,KAAKK,OAAOC,MAAMC,MAAM,IAAID,MAAMC;AAAAA,IAAAA;AAAAA,EACzD,CACD;AACH;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { RouteIds } from './routeInfo.js';
|
|
2
|
+
import { AnyRouter } from './router.js';
|
|
3
|
+
import { ConstrainLiteral } from '@tanstack/router-core';
|
|
4
|
+
import * as Solid from 'solid-js';
|
|
5
|
+
export type StrictOrFrom<TRouter extends AnyRouter, TFrom, TStrict extends boolean = true> = TStrict extends false ? {
|
|
6
|
+
from?: never;
|
|
7
|
+
strict: TStrict;
|
|
8
|
+
} : {
|
|
9
|
+
from: ConstrainLiteral<TFrom, RouteIds<TRouter['routeTree']>>;
|
|
10
|
+
strict?: TStrict;
|
|
11
|
+
};
|
|
12
|
+
export declare const useLayoutEffect: typeof Solid.createRenderEffect;
|
|
13
|
+
export declare const usePrevious: (fn: () => boolean) => Solid.Accessor<{
|
|
14
|
+
current: boolean | null;
|
|
15
|
+
previous: boolean | null;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* React hook to wrap `IntersectionObserver`.
|
|
19
|
+
*
|
|
20
|
+
* This hook will create an `IntersectionObserver` and observe the ref passed to it.
|
|
21
|
+
*
|
|
22
|
+
* When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.
|
|
23
|
+
*
|
|
24
|
+
* @param ref - The ref to observe
|
|
25
|
+
* @param intersectionObserverOptions - The options to pass to the IntersectionObserver
|
|
26
|
+
* @param options - The options to pass to the hook
|
|
27
|
+
* @param callback - The callback to call when the intersection changes
|
|
28
|
+
* @returns The IntersectionObserver instance
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* const MyComponent = () => {
|
|
32
|
+
* const ref = React.useRef<HTMLDivElement>(null)
|
|
33
|
+
* useIntersectionObserver(
|
|
34
|
+
* ref,
|
|
35
|
+
* (entry) => { doSomething(entry) },
|
|
36
|
+
* { rootMargin: '10px' },
|
|
37
|
+
* { disabled: false }
|
|
38
|
+
* )
|
|
39
|
+
* return <div ref={ref} />
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function useIntersectionObserver<T extends Element>(ref: Solid.Accessor<T | null>, callback: (entry: IntersectionObserverEntry | undefined) => void, intersectionObserverOptions?: IntersectionObserverInit, options?: {
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
}): Solid.Accessor<IntersectionObserver | null>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as Solid from "solid-js";
|
|
2
|
+
const useLayoutEffect = typeof window !== "undefined" ? Solid.createRenderEffect : Solid.createEffect;
|
|
3
|
+
const usePrevious = (fn) => {
|
|
4
|
+
return Solid.createMemo(
|
|
5
|
+
(prev = {
|
|
6
|
+
current: null,
|
|
7
|
+
previous: null
|
|
8
|
+
}) => {
|
|
9
|
+
const current = fn();
|
|
10
|
+
if (prev.current !== current) {
|
|
11
|
+
prev.previous = prev.current;
|
|
12
|
+
prev.current = current;
|
|
13
|
+
}
|
|
14
|
+
return prev;
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
};
|
|
18
|
+
function useIntersectionObserver(ref, callback, intersectionObserverOptions = {}, options = {}) {
|
|
19
|
+
const isIntersectionObserverAvailable = typeof IntersectionObserver === "function";
|
|
20
|
+
let observerRef = null;
|
|
21
|
+
Solid.createEffect(() => {
|
|
22
|
+
const r = ref();
|
|
23
|
+
if (!r || !isIntersectionObserverAvailable || options.disabled) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
observerRef = new IntersectionObserver(([entry]) => {
|
|
27
|
+
callback(entry);
|
|
28
|
+
}, intersectionObserverOptions);
|
|
29
|
+
observerRef.observe(r);
|
|
30
|
+
Solid.onCleanup(() => {
|
|
31
|
+
observerRef == null ? void 0 : observerRef.disconnect();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
return () => observerRef;
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
useIntersectionObserver,
|
|
38
|
+
useLayoutEffect,
|
|
39
|
+
usePrevious
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../src/utils.ts"],"sourcesContent":["import * as Solid from 'solid-js'\nimport type { RouteIds } from './routeInfo'\nimport type { AnyRouter } from './router'\nimport type { ConstrainLiteral } from '@tanstack/router-core'\n\nexport type StrictOrFrom<\n TRouter extends AnyRouter,\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: ConstrainLiteral<TFrom, RouteIds<TRouter['routeTree']>>\n strict?: TStrict\n }\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? Solid.createRenderEffect : Solid.createEffect\n\nexport const usePrevious = (fn: () => boolean) => {\n return Solid.createMemo(\n (\n prev: { current: boolean | null; previous: boolean | null } = {\n current: null,\n previous: null,\n },\n ) => {\n const current = fn()\n\n if (prev.current !== current) {\n prev.previous = prev.current\n prev.current = current\n }\n\n return prev\n },\n )\n}\n\n/**\n * React hook to wrap `IntersectionObserver`.\n *\n * This hook will create an `IntersectionObserver` and observe the ref passed to it.\n *\n * When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.\n *\n * @param ref - The ref to observe\n * @param intersectionObserverOptions - The options to pass to the IntersectionObserver\n * @param options - The options to pass to the hook\n * @param callback - The callback to call when the intersection changes\n * @returns The IntersectionObserver instance\n * @example\n * ```tsx\n * const MyComponent = () => {\n * const ref = React.useRef<HTMLDivElement>(null)\n * useIntersectionObserver(\n * ref,\n * (entry) => { doSomething(entry) },\n * { rootMargin: '10px' },\n * { disabled: false }\n * )\n * return <div ref={ref} />\n * ```\n */\nexport function useIntersectionObserver<T extends Element>(\n ref: Solid.Accessor<T | null>,\n callback: (entry: IntersectionObserverEntry | undefined) => void,\n intersectionObserverOptions: IntersectionObserverInit = {},\n options: { disabled?: boolean } = {},\n): Solid.Accessor<IntersectionObserver | null> {\n const isIntersectionObserverAvailable =\n typeof IntersectionObserver === 'function'\n let observerRef: IntersectionObserver | null = null\n\n Solid.createEffect(() => {\n const r = ref()\n if (!r || !isIntersectionObserverAvailable || options.disabled) {\n return\n }\n\n observerRef = new IntersectionObserver(([entry]) => {\n callback(entry)\n }, intersectionObserverOptions)\n\n observerRef.observe(r)\n\n Solid.onCleanup(() => {\n observerRef?.disconnect()\n })\n })\n\n return () => observerRef\n}\n"],"names":[],"mappings":";AAmBO,MAAM,kBACX,OAAO,WAAW,cAAc,MAAM,qBAAqB,MAAM;AAEtD,MAAA,cAAc,CAAC,OAAsB;AAChD,SAAO,MAAM;AAAA,IACX,CACE,OAA8D;AAAA,MAC5D,SAAS;AAAA,MACT,UAAU;AAAA,IAAA,MAET;AACH,YAAM,UAAU,GAAG;AAEf,UAAA,KAAK,YAAY,SAAS;AAC5B,aAAK,WAAW,KAAK;AACrB,aAAK,UAAU;AAAA,MAAA;AAGV,aAAA;AAAA,IAAA;AAAA,EAEX;AACF;AA2BgB,SAAA,wBACd,KACA,UACA,8BAAwD,CACxD,GAAA,UAAkC,IACW;AACvC,QAAA,kCACJ,OAAO,yBAAyB;AAClC,MAAI,cAA2C;AAE/C,QAAM,aAAa,MAAM;AACvB,UAAM,IAAI,IAAI;AACd,QAAI,CAAC,KAAK,CAAC,mCAAmC,QAAQ,UAAU;AAC9D;AAAA,IAAA;AAGF,kBAAc,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AAClD,eAAS,KAAK;AAAA,OACb,2BAA2B;AAE9B,gBAAY,QAAQ,CAAC;AAErB,UAAM,UAAU,MAAM;AACpB,iDAAa;AAAA,IAAW,CACzB;AAAA,EAAA,CACF;AAED,SAAO,MAAM;AACf;"}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tanstack/solid-router",
|
|
3
|
+
"version": "1.108.0",
|
|
4
|
+
"description": "Modern and scalable routing for Solid applications",
|
|
5
|
+
"author": "Tanner Linsley",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/TanStack/router.git",
|
|
10
|
+
"directory": "packages/solid-router"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://tanstack.com/router",
|
|
13
|
+
"funding": {
|
|
14
|
+
"type": "github",
|
|
15
|
+
"url": "https://github.com/sponsors/tannerlinsley"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"solidjs",
|
|
19
|
+
"location",
|
|
20
|
+
"router",
|
|
21
|
+
"routing",
|
|
22
|
+
"async",
|
|
23
|
+
"async router",
|
|
24
|
+
"typescript"
|
|
25
|
+
],
|
|
26
|
+
"type": "module",
|
|
27
|
+
"types": "dist/esm/index.d.ts",
|
|
28
|
+
"main": "dist/cjs/index.cjs",
|
|
29
|
+
"module": "dist/esm/index.js",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"import": {
|
|
33
|
+
"types": "./dist/esm/index.d.ts",
|
|
34
|
+
"default": "./dist/esm/index.js"
|
|
35
|
+
},
|
|
36
|
+
"require": {
|
|
37
|
+
"types": "./dist/cjs/index.d.cts",
|
|
38
|
+
"default": "./dist/cjs/index.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"./package.json": "./package.json"
|
|
42
|
+
},
|
|
43
|
+
"sideEffects": false,
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"src"
|
|
47
|
+
],
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=12"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@solid-devtools/logger": "^0.9.4",
|
|
53
|
+
"@solid-primitives/refs": "^1.0.8",
|
|
54
|
+
"@tanstack/solid-store": "^0.7.0",
|
|
55
|
+
"jsesc": "^3.0.2",
|
|
56
|
+
"tiny-invariant": "^1.3.3",
|
|
57
|
+
"tiny-warning": "^1.0.3",
|
|
58
|
+
"@tanstack/history": "1.99.13",
|
|
59
|
+
"@tanstack/router-core": "1.108.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@solidjs/testing-library": "^0.8.10",
|
|
63
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
64
|
+
"@types/jsesc": "^3.0.3",
|
|
65
|
+
"combinate": "^1.1.11",
|
|
66
|
+
"eslint-plugin-solid": "^0.14.5",
|
|
67
|
+
"solid-js": "^1",
|
|
68
|
+
"vite-plugin-solid": "^2.11.2",
|
|
69
|
+
"zod": "^3.23.8"
|
|
70
|
+
},
|
|
71
|
+
"peerDependencies": {
|
|
72
|
+
"solid-js": "^1"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {}
|
|
75
|
+
}
|
package/src/Asset.tsx
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RouterManagedTag } from '@tanstack/router-core'
|
|
2
|
+
|
|
3
|
+
export function Asset({ tag, attrs, children }: RouterManagedTag): any {
|
|
4
|
+
switch (tag) {
|
|
5
|
+
case 'title':
|
|
6
|
+
return <title {...attrs}>{children}</title>
|
|
7
|
+
case 'meta':
|
|
8
|
+
return <meta {...attrs} />
|
|
9
|
+
case 'link':
|
|
10
|
+
return <link {...attrs} />
|
|
11
|
+
case 'style':
|
|
12
|
+
return <style {...attrs} innerHTML={children} />
|
|
13
|
+
case 'script':
|
|
14
|
+
if ((attrs as any) && (attrs as any).src) {
|
|
15
|
+
return <script {...attrs} />
|
|
16
|
+
}
|
|
17
|
+
if (typeof children === 'string')
|
|
18
|
+
return <script {...attrs} innerHTML={children} />
|
|
19
|
+
return null
|
|
20
|
+
default:
|
|
21
|
+
return null
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import * as Solid from 'solid-js'
|
|
2
|
+
import { Dynamic } from 'solid-js/web'
|
|
3
|
+
import type { ErrorRouteComponent } from './route'
|
|
4
|
+
|
|
5
|
+
export function CatchBoundary(
|
|
6
|
+
props: {
|
|
7
|
+
getResetKey: () => number | string
|
|
8
|
+
children: Solid.JSX.Element
|
|
9
|
+
errorComponent?: ErrorRouteComponent
|
|
10
|
+
onCatch?: (error: Error) => void
|
|
11
|
+
} & Solid.ParentProps,
|
|
12
|
+
) {
|
|
13
|
+
return (
|
|
14
|
+
<Solid.ErrorBoundary
|
|
15
|
+
fallback={(error, reset) => {
|
|
16
|
+
props.onCatch?.(error)
|
|
17
|
+
|
|
18
|
+
Solid.createEffect(
|
|
19
|
+
Solid.on([props.getResetKey], () => reset(), { defer: true }),
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<Dynamic
|
|
24
|
+
component={props.errorComponent ?? ErrorComponent}
|
|
25
|
+
error={error}
|
|
26
|
+
reset={reset}
|
|
27
|
+
/>
|
|
28
|
+
)
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
{props.children}
|
|
32
|
+
</Solid.ErrorBoundary>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function ErrorComponent({ error }: { error: any }) {
|
|
37
|
+
const [show, setShow] = Solid.createSignal(
|
|
38
|
+
process.env.NODE_ENV !== 'production',
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div style={{ padding: '.5rem', 'max-width': '100%' }}>
|
|
43
|
+
<div style={{ display: 'flex', 'align-items': 'center', gap: '.5rem' }}>
|
|
44
|
+
<strong style={{ 'font-size': '1rem' }}>Something went wrong!</strong>
|
|
45
|
+
<button
|
|
46
|
+
style={{
|
|
47
|
+
appearance: 'none',
|
|
48
|
+
'font-size': '.6em',
|
|
49
|
+
border: '1px solid currentColor',
|
|
50
|
+
padding: '.1rem .2rem',
|
|
51
|
+
'font-weight': 'bold',
|
|
52
|
+
'border-radius': '.25rem',
|
|
53
|
+
}}
|
|
54
|
+
onClick={() => setShow((d) => !d)}
|
|
55
|
+
>
|
|
56
|
+
{show() ? 'Hide Error' : 'Show Error'}
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
<div style={{ height: '.25rem' }} />
|
|
60
|
+
{show() ? (
|
|
61
|
+
<div>
|
|
62
|
+
<pre
|
|
63
|
+
style={{
|
|
64
|
+
'font-size': '.7em',
|
|
65
|
+
border: '1px solid red',
|
|
66
|
+
'border-radius': '.25rem',
|
|
67
|
+
padding: '.3rem',
|
|
68
|
+
color: 'red',
|
|
69
|
+
overflow: 'auto',
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
{error.message ? <code>{error.message}</code> : null}
|
|
73
|
+
</pre>
|
|
74
|
+
</div>
|
|
75
|
+
) : null}
|
|
76
|
+
</div>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import * as Solid from 'solid-js'
|
|
2
|
+
import { Asset } from './Asset'
|
|
3
|
+
import { useRouter } from './useRouter'
|
|
4
|
+
import { useRouterState } from './useRouterState'
|
|
5
|
+
import type { RouterManagedTag } from '@tanstack/router-core'
|
|
6
|
+
|
|
7
|
+
export const useTags = () => {
|
|
8
|
+
const router = useRouter()
|
|
9
|
+
|
|
10
|
+
const routeMeta = useRouterState({
|
|
11
|
+
select: (state) => {
|
|
12
|
+
return state.matches.map((match) => match.meta!).filter(Boolean)
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const meta: Solid.Accessor<Array<RouterManagedTag>> = Solid.createMemo(() => {
|
|
17
|
+
const resultMeta: Array<RouterManagedTag> = []
|
|
18
|
+
const metaByAttribute: Record<string, true> = {}
|
|
19
|
+
let title: RouterManagedTag | undefined
|
|
20
|
+
;[...routeMeta()].reverse().forEach((metas) => {
|
|
21
|
+
;[...metas].reverse().forEach((m) => {
|
|
22
|
+
if (!m) return
|
|
23
|
+
|
|
24
|
+
if (m.title) {
|
|
25
|
+
if (!title) {
|
|
26
|
+
title = {
|
|
27
|
+
tag: 'title',
|
|
28
|
+
children: m.title,
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
} else {
|
|
32
|
+
const attribute = m.name ?? m.property
|
|
33
|
+
if (attribute) {
|
|
34
|
+
if (metaByAttribute[attribute]) {
|
|
35
|
+
return
|
|
36
|
+
} else {
|
|
37
|
+
metaByAttribute[attribute] = true
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
resultMeta.push({
|
|
42
|
+
tag: 'meta',
|
|
43
|
+
attrs: {
|
|
44
|
+
...m,
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
if (title) {
|
|
52
|
+
resultMeta.push(title)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
resultMeta.reverse()
|
|
56
|
+
|
|
57
|
+
return resultMeta
|
|
58
|
+
}, [routeMeta])
|
|
59
|
+
|
|
60
|
+
const links = useRouterState({
|
|
61
|
+
select: (state) =>
|
|
62
|
+
state.matches
|
|
63
|
+
.map((match) => match.links!)
|
|
64
|
+
.filter(Boolean)
|
|
65
|
+
.flat(1)
|
|
66
|
+
.map((link) => ({
|
|
67
|
+
tag: 'link',
|
|
68
|
+
attrs: {
|
|
69
|
+
...link,
|
|
70
|
+
},
|
|
71
|
+
})) as Array<RouterManagedTag>,
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
const preloadMeta = useRouterState({
|
|
75
|
+
select: (state) => {
|
|
76
|
+
const preloadMeta: Array<RouterManagedTag> = []
|
|
77
|
+
|
|
78
|
+
state.matches
|
|
79
|
+
.map((match) => router.looseRoutesById[match.routeId]!)
|
|
80
|
+
.forEach((route) =>
|
|
81
|
+
router.ssr?.manifest?.routes[route.id]?.preloads
|
|
82
|
+
?.filter(Boolean)
|
|
83
|
+
.forEach((preload) => {
|
|
84
|
+
preloadMeta.push({
|
|
85
|
+
tag: 'link',
|
|
86
|
+
attrs: {
|
|
87
|
+
rel: 'modulepreload',
|
|
88
|
+
href: preload,
|
|
89
|
+
},
|
|
90
|
+
})
|
|
91
|
+
}),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
return preloadMeta
|
|
95
|
+
},
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const headScripts = useRouterState({
|
|
99
|
+
select: (state) =>
|
|
100
|
+
(
|
|
101
|
+
state.matches
|
|
102
|
+
.map((match) => match.headScripts!)
|
|
103
|
+
.flat(1)
|
|
104
|
+
.filter(Boolean) as Array<RouterManagedTag>
|
|
105
|
+
).map(({ children, ...script }) => ({
|
|
106
|
+
tag: 'script',
|
|
107
|
+
attrs: {
|
|
108
|
+
...script,
|
|
109
|
+
},
|
|
110
|
+
children,
|
|
111
|
+
})),
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
return uniqBy(
|
|
115
|
+
[
|
|
116
|
+
...meta(),
|
|
117
|
+
...preloadMeta(),
|
|
118
|
+
...links(),
|
|
119
|
+
...headScripts(),
|
|
120
|
+
] as Array<RouterManagedTag>,
|
|
121
|
+
(d) => {
|
|
122
|
+
return JSON.stringify(d)
|
|
123
|
+
},
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.
|
|
129
|
+
* It should be rendered in the `<head>` of your document.
|
|
130
|
+
*/
|
|
131
|
+
export function HeadContent() {
|
|
132
|
+
const tags = useTags()
|
|
133
|
+
return tags.map((tag) => <Asset {...tag} />)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {
|
|
137
|
+
const seen = new Set<string>()
|
|
138
|
+
return arr.filter((item) => {
|
|
139
|
+
const key = fn(item)
|
|
140
|
+
if (seen.has(key)) {
|
|
141
|
+
return false
|
|
142
|
+
}
|
|
143
|
+
seen.add(key)
|
|
144
|
+
return true
|
|
145
|
+
})
|
|
146
|
+
}
|