@tanstack/solid-router 1.121.0-alpha.27 → 1.121.0-alpha.28
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/Asset.cjs +65 -21
- package/dist/cjs/Asset.cjs.map +1 -1
- package/dist/cjs/Asset.d.cts +2 -1
- package/dist/cjs/CatchBoundary.cjs +14 -15
- package/dist/cjs/CatchBoundary.cjs.map +1 -1
- package/dist/cjs/ClientOnly.cjs +12 -14
- package/dist/cjs/ClientOnly.cjs.map +1 -1
- package/dist/cjs/ClientOnly.d.cts +0 -20
- package/dist/cjs/HeadContent.cjs +28 -23
- package/dist/cjs/HeadContent.cjs.map +1 -1
- package/dist/cjs/Match.cjs +167 -141
- package/dist/cjs/Match.cjs.map +1 -1
- package/dist/cjs/Matches.cjs +26 -24
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/cjs/Matches.d.cts +1 -0
- package/dist/cjs/RouterProvider.cjs +5 -5
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/SafeFragment.cjs +2 -2
- package/dist/cjs/SafeFragment.cjs.map +1 -1
- package/dist/cjs/ScriptOnce.cjs +4 -9
- package/dist/cjs/ScriptOnce.cjs.map +1 -1
- package/dist/cjs/ScriptOnce.d.cts +1 -1
- package/dist/cjs/Scripts.cjs +9 -13
- package/dist/cjs/Scripts.cjs.map +1 -1
- package/dist/cjs/ScrollRestoration.cjs +3 -4
- package/dist/cjs/ScrollRestoration.cjs.map +1 -1
- package/dist/cjs/Transitioner.cjs +9 -8
- package/dist/cjs/Transitioner.cjs.map +1 -1
- package/dist/cjs/awaited.cjs +2 -2
- package/dist/cjs/awaited.cjs.map +1 -1
- package/dist/cjs/fileRoute.cjs +5 -5
- package/dist/cjs/fileRoute.cjs.map +1 -1
- package/dist/cjs/index.cjs +0 -12
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +3 -6
- package/dist/cjs/lazyRouteComponent.cjs +6 -26
- package/dist/cjs/lazyRouteComponent.cjs.map +1 -1
- package/dist/cjs/lazyRouteComponent.d.cts +1 -1
- package/dist/cjs/link.cjs +37 -31
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/not-found.cjs +5 -7
- package/dist/cjs/not-found.cjs.map +1 -1
- package/dist/cjs/renderRouteNotFound.cjs +4 -4
- package/dist/cjs/renderRouteNotFound.cjs.map +1 -1
- package/dist/cjs/route.cjs +16 -16
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +14 -5
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/routerContext.cjs.map +1 -1
- package/dist/cjs/scroll-restoration.cjs +12 -6
- package/dist/cjs/scroll-restoration.cjs.map +1 -1
- package/dist/cjs/ssr/RouterClient.cjs +45 -0
- package/dist/cjs/ssr/RouterClient.cjs.map +1 -0
- package/dist/cjs/ssr/RouterClient.d.cts +4 -0
- package/dist/cjs/ssr/RouterServer.cjs +56 -0
- package/dist/cjs/ssr/RouterServer.cjs.map +1 -0
- package/dist/cjs/ssr/RouterServer.d.cts +5 -0
- package/dist/cjs/ssr/client.cjs +5 -0
- package/dist/cjs/ssr/client.cjs.map +1 -0
- package/dist/cjs/ssr/client.d.cts +1 -0
- package/dist/cjs/ssr/defaultRenderHandler.cjs +18 -0
- package/dist/cjs/ssr/defaultRenderHandler.cjs.map +1 -0
- package/dist/cjs/ssr/defaultRenderHandler.d.cts +1 -0
- package/dist/cjs/ssr/defaultStreamHandler.cjs +20 -0
- package/dist/cjs/ssr/defaultStreamHandler.cjs.map +1 -0
- package/dist/cjs/ssr/defaultStreamHandler.d.cts +1 -0
- package/dist/cjs/ssr/renderRouterToStream.cjs +45 -0
- package/dist/cjs/ssr/renderRouterToStream.cjs.map +1 -0
- package/dist/cjs/ssr/renderRouterToStream.d.cts +8 -0
- package/dist/cjs/ssr/renderRouterToString.cjs +43 -0
- package/dist/cjs/ssr/renderRouterToString.cjs.map +1 -0
- package/dist/cjs/ssr/renderRouterToString.d.cts +7 -0
- package/dist/cjs/ssr/server.cjs +20 -0
- package/dist/cjs/ssr/server.cjs.map +1 -0
- package/dist/cjs/ssr/server.d.cts +6 -0
- package/dist/cjs/useBlocker.cjs +41 -35
- package/dist/cjs/useBlocker.cjs.map +1 -1
- package/dist/cjs/useCanGoBack.cjs.map +1 -1
- package/dist/cjs/useLoaderData.cjs.map +1 -1
- package/dist/cjs/useLoaderDeps.cjs.map +1 -1
- package/dist/cjs/useLocation.cjs +1 -1
- package/dist/cjs/useLocation.cjs.map +1 -1
- package/dist/cjs/useMatch.cjs.map +1 -1
- package/dist/cjs/useNavigate.cjs +9 -3
- package/dist/cjs/useNavigate.cjs.map +1 -1
- package/dist/cjs/useParams.cjs.map +1 -1
- package/dist/cjs/useRouter.cjs +1 -1
- package/dist/cjs/useRouter.cjs.map +1 -1
- package/dist/cjs/useRouterState.cjs +3 -3
- package/dist/cjs/useRouterState.cjs.map +1 -1
- package/dist/cjs/useSearch.cjs.map +1 -1
- package/dist/cjs/utils.cjs +1 -1
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/esm/Asset.d.ts +2 -1
- package/dist/esm/Asset.js +60 -16
- package/dist/esm/Asset.js.map +1 -1
- package/dist/esm/CatchBoundary.js +1 -2
- package/dist/esm/CatchBoundary.js.map +1 -1
- package/dist/esm/ClientOnly.d.ts +0 -20
- package/dist/esm/ClientOnly.js +11 -13
- package/dist/esm/ClientOnly.js.map +1 -1
- package/dist/esm/HeadContent.js +23 -18
- package/dist/esm/HeadContent.js.map +1 -1
- package/dist/esm/Match.js +148 -122
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Matches.d.ts +1 -0
- package/dist/esm/Matches.js +18 -16
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/RouterProvider.js.map +1 -1
- package/dist/esm/SafeFragment.js.map +1 -1
- package/dist/esm/ScriptOnce.d.ts +1 -1
- package/dist/esm/ScriptOnce.js +2 -7
- package/dist/esm/ScriptOnce.js.map +1 -1
- package/dist/esm/Scripts.js +7 -11
- package/dist/esm/Scripts.js.map +1 -1
- package/dist/esm/ScrollRestoration.js +3 -4
- package/dist/esm/ScrollRestoration.js.map +1 -1
- package/dist/esm/Transitioner.js +9 -8
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/awaited.js.map +1 -1
- package/dist/esm/fileRoute.js +5 -5
- package/dist/esm/fileRoute.js.map +1 -1
- package/dist/esm/index.d.ts +3 -6
- package/dist/esm/index.js +2 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lazyRouteComponent.d.ts +1 -1
- package/dist/esm/lazyRouteComponent.js +2 -22
- package/dist/esm/lazyRouteComponent.js.map +1 -1
- package/dist/esm/link.js +34 -28
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/not-found.js +2 -4
- package/dist/esm/not-found.js.map +1 -1
- package/dist/esm/renderRouteNotFound.js.map +1 -1
- package/dist/esm/route.d.ts +14 -5
- package/dist/esm/route.js +12 -12
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/routerContext.js.map +1 -1
- package/dist/esm/scroll-restoration.js +10 -4
- package/dist/esm/scroll-restoration.js.map +1 -1
- package/dist/esm/ssr/RouterClient.d.ts +4 -0
- package/dist/esm/ssr/RouterClient.js +45 -0
- package/dist/esm/ssr/RouterClient.js.map +1 -0
- package/dist/esm/ssr/RouterServer.d.ts +5 -0
- package/dist/esm/ssr/RouterServer.js +56 -0
- package/dist/esm/ssr/RouterServer.js.map +1 -0
- package/dist/esm/ssr/client.d.ts +1 -0
- package/dist/esm/ssr/client.js +5 -0
- package/dist/esm/ssr/client.js.map +1 -0
- package/dist/esm/ssr/defaultRenderHandler.d.ts +1 -0
- package/dist/esm/ssr/defaultRenderHandler.js +18 -0
- package/dist/esm/ssr/defaultRenderHandler.js.map +1 -0
- package/dist/esm/ssr/defaultStreamHandler.d.ts +1 -0
- package/dist/esm/ssr/defaultStreamHandler.js +20 -0
- package/dist/esm/ssr/defaultStreamHandler.js.map +1 -0
- package/dist/esm/ssr/renderRouterToStream.d.ts +8 -0
- package/dist/esm/ssr/renderRouterToStream.js +28 -0
- package/dist/esm/ssr/renderRouterToStream.js.map +1 -0
- package/dist/esm/ssr/renderRouterToString.d.ts +7 -0
- package/dist/esm/ssr/renderRouterToString.js +26 -0
- package/dist/esm/ssr/renderRouterToString.js.map +1 -0
- package/dist/esm/ssr/server.d.ts +6 -0
- package/dist/esm/ssr/server.js +14 -0
- package/dist/esm/ssr/server.js.map +1 -0
- package/dist/esm/useBlocker.js +41 -35
- package/dist/esm/useBlocker.js.map +1 -1
- package/dist/esm/useCanGoBack.js.map +1 -1
- package/dist/esm/useLoaderData.js.map +1 -1
- package/dist/esm/useLoaderDeps.js.map +1 -1
- package/dist/esm/useLocation.js +1 -1
- package/dist/esm/useLocation.js.map +1 -1
- package/dist/esm/useMatch.js.map +1 -1
- package/dist/esm/useNavigate.js +9 -3
- package/dist/esm/useNavigate.js.map +1 -1
- package/dist/esm/useParams.js.map +1 -1
- package/dist/esm/useRouter.js +1 -1
- package/dist/esm/useRouter.js.map +1 -1
- package/dist/esm/useRouterState.js +3 -3
- package/dist/esm/useRouterState.js.map +1 -1
- package/dist/esm/useSearch.js.map +1 -1
- package/dist/esm/utils.js +1 -1
- package/dist/esm/utils.js.map +1 -1
- package/dist/source/Asset.d.ts +2 -1
- package/dist/source/Asset.jsx +45 -7
- package/dist/source/Asset.jsx.map +1 -1
- package/dist/source/ClientOnly.d.ts +0 -20
- package/dist/source/ClientOnly.jsx +3 -29
- package/dist/source/ClientOnly.jsx.map +1 -1
- package/dist/source/HeadContent.jsx +13 -0
- package/dist/source/HeadContent.jsx.map +1 -1
- package/dist/source/Match.jsx +74 -61
- package/dist/source/Match.jsx.map +1 -1
- package/dist/source/Matches.d.ts +1 -0
- package/dist/source/Matches.jsx +14 -11
- package/dist/source/Matches.jsx.map +1 -1
- package/dist/source/ScriptOnce.d.ts +1 -1
- package/dist/source/ScriptOnce.jsx +2 -12
- package/dist/source/ScriptOnce.jsx.map +1 -1
- package/dist/source/Transitioner.jsx +8 -8
- package/dist/source/Transitioner.jsx.map +1 -1
- package/dist/source/index.d.ts +3 -6
- package/dist/source/index.jsx +1 -4
- package/dist/source/index.jsx.map +1 -1
- package/dist/source/lazyRouteComponent.d.ts +1 -1
- package/dist/source/lazyRouteComponent.jsx +7 -21
- package/dist/source/lazyRouteComponent.jsx.map +1 -1
- package/dist/source/link.jsx +22 -17
- package/dist/source/link.jsx.map +1 -1
- package/dist/source/not-found.jsx.map +1 -1
- package/dist/source/route.d.ts +14 -5
- package/dist/source/route.jsx.map +1 -1
- package/dist/source/scroll-restoration.jsx +9 -2
- package/dist/source/scroll-restoration.jsx.map +1 -1
- package/dist/source/ssr/RouterClient.d.ts +4 -0
- package/dist/source/ssr/RouterClient.jsx +28 -0
- package/dist/source/ssr/RouterClient.jsx.map +1 -0
- package/dist/source/ssr/RouterServer.d.ts +5 -0
- package/dist/source/ssr/RouterServer.jsx +38 -0
- package/dist/source/ssr/RouterServer.jsx.map +1 -0
- package/dist/source/ssr/client.d.ts +1 -0
- package/dist/source/ssr/client.js +2 -0
- package/dist/source/ssr/client.js.map +1 -0
- package/dist/source/ssr/defaultRenderHandler.d.ts +1 -0
- package/dist/source/ssr/defaultRenderHandler.jsx +9 -0
- package/dist/source/ssr/defaultRenderHandler.jsx.map +1 -0
- package/dist/source/ssr/defaultStreamHandler.d.ts +1 -0
- package/dist/source/ssr/defaultStreamHandler.jsx +10 -0
- package/dist/source/ssr/defaultStreamHandler.jsx.map +1 -0
- package/dist/source/ssr/renderRouterToStream.d.ts +8 -0
- package/dist/source/ssr/renderRouterToStream.jsx +17 -0
- package/dist/source/ssr/renderRouterToStream.jsx.map +1 -0
- package/dist/source/ssr/renderRouterToString.d.ts +7 -0
- package/dist/source/ssr/renderRouterToString.jsx +20 -0
- package/dist/source/ssr/renderRouterToString.jsx.map +1 -0
- package/dist/source/ssr/server.d.ts +6 -0
- package/dist/source/ssr/server.js +7 -0
- package/dist/source/ssr/server.js.map +1 -0
- package/dist/source/useBlocker.jsx +44 -27
- package/dist/source/useBlocker.jsx.map +1 -1
- package/dist/source/useNavigate.jsx +12 -2
- package/dist/source/useNavigate.jsx.map +1 -1
- package/package.json +34 -7
- package/src/Asset.tsx +76 -7
- package/src/ClientOnly.tsx +5 -32
- package/src/HeadContent.tsx +17 -0
- package/src/Match.tsx +103 -81
- package/src/Matches.tsx +28 -19
- package/src/ScriptOnce.tsx +1 -13
- package/src/Transitioner.tsx +7 -7
- package/src/index.tsx +1 -18
- package/src/lazyRouteComponent.tsx +6 -26
- package/src/link.tsx +29 -21
- package/src/not-found.tsx +1 -1
- package/src/route.tsx +16 -5
- package/src/scroll-restoration.tsx +10 -3
- package/src/ssr/RouterClient.tsx +43 -0
- package/src/ssr/RouterServer.tsx +60 -0
- package/src/ssr/client.ts +1 -0
- package/src/ssr/defaultRenderHandler.tsx +12 -0
- package/src/ssr/defaultStreamHandler.tsx +13 -0
- package/src/ssr/renderRouterToStream.tsx +36 -0
- package/src/ssr/renderRouterToString.tsx +31 -0
- package/src/ssr/server.ts +6 -0
- package/src/useBlocker.tsx +48 -32
- package/src/useNavigate.tsx +14 -2
package/src/link.tsx
CHANGED
|
@@ -15,7 +15,7 @@ import { useRouter } from './useRouter'
|
|
|
15
15
|
|
|
16
16
|
import { useIntersectionObserver } from './utils'
|
|
17
17
|
|
|
18
|
-
import {
|
|
18
|
+
import { useMatch } from './useMatch'
|
|
19
19
|
import type {
|
|
20
20
|
AnyRouter,
|
|
21
21
|
Constrain,
|
|
@@ -62,7 +62,6 @@ export function useLinkProps<
|
|
|
62
62
|
'startTransition',
|
|
63
63
|
'resetScroll',
|
|
64
64
|
'viewTransition',
|
|
65
|
-
'children',
|
|
66
65
|
'target',
|
|
67
66
|
'disabled',
|
|
68
67
|
'style',
|
|
@@ -113,6 +112,7 @@ export function useLinkProps<
|
|
|
113
112
|
'state',
|
|
114
113
|
'mask',
|
|
115
114
|
'reloadDocument',
|
|
115
|
+
'unsafeRelative',
|
|
116
116
|
])
|
|
117
117
|
|
|
118
118
|
// If this link simply reloads the current route,
|
|
@@ -133,10 +133,11 @@ export function useLinkProps<
|
|
|
133
133
|
select: (s) => s.location.searchStr,
|
|
134
134
|
})
|
|
135
135
|
|
|
136
|
-
// when `from` is not supplied, use the
|
|
136
|
+
// when `from` is not supplied, use the route of the current match as the `from` location
|
|
137
137
|
// so relative routing works as expected
|
|
138
|
-
const from =
|
|
139
|
-
|
|
138
|
+
const from = useMatch({
|
|
139
|
+
strict: false,
|
|
140
|
+
select: (match) => options.from ?? match.fullPath,
|
|
140
141
|
})
|
|
141
142
|
|
|
142
143
|
const _options = () => ({
|
|
@@ -250,7 +251,6 @@ export function useLinkProps<
|
|
|
250
251
|
},
|
|
251
252
|
},
|
|
252
253
|
Solid.splitProps(local, [
|
|
253
|
-
'children',
|
|
254
254
|
'target',
|
|
255
255
|
'disabled',
|
|
256
256
|
'style',
|
|
@@ -286,7 +286,7 @@ export function useLinkProps<
|
|
|
286
286
|
|
|
287
287
|
// All is well? Navigate!
|
|
288
288
|
// N.B. we don't call `router.commitLocation(next) here because we want to run `validateSearch` before committing
|
|
289
|
-
|
|
289
|
+
router.navigate({
|
|
290
290
|
..._options(),
|
|
291
291
|
replace: local.replace,
|
|
292
292
|
resetScroll: local.resetScroll,
|
|
@@ -294,7 +294,7 @@ export function useLinkProps<
|
|
|
294
294
|
startTransition: local.startTransition,
|
|
295
295
|
viewTransition: local.viewTransition,
|
|
296
296
|
ignoreBlocker: local.ignoreBlocker,
|
|
297
|
-
}
|
|
297
|
+
})
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
300
|
|
|
@@ -545,29 +545,37 @@ export interface LinkComponentRoute<
|
|
|
545
545
|
export function createLink<const TComp>(
|
|
546
546
|
Comp: Constrain<TComp, any, (props: CreateLinkProps) => Solid.JSX.Element>,
|
|
547
547
|
): LinkComponent<TComp> {
|
|
548
|
-
return (props) => <Link {...
|
|
548
|
+
return (props) => <Link {...props} _asChild={Comp} />
|
|
549
549
|
}
|
|
550
550
|
|
|
551
|
-
export const Link: LinkComponent<'a'> = (props
|
|
552
|
-
const [local, rest] = Solid.splitProps(
|
|
551
|
+
export const Link: LinkComponent<'a'> = (props) => {
|
|
552
|
+
const [local, rest] = Solid.splitProps(
|
|
553
|
+
props as typeof props & { _asChild: any },
|
|
554
|
+
['_asChild', 'children'],
|
|
555
|
+
)
|
|
553
556
|
|
|
554
557
|
const [_, linkProps] = Solid.splitProps(
|
|
555
558
|
useLinkProps(rest as unknown as any),
|
|
556
|
-
['type'
|
|
559
|
+
['type'],
|
|
557
560
|
)
|
|
558
561
|
|
|
559
|
-
const children = () =>
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
|
|
562
|
+
const children = Solid.createMemo(() => {
|
|
563
|
+
const ch = local.children
|
|
564
|
+
if (typeof ch === 'function') {
|
|
565
|
+
return ch({
|
|
566
|
+
get isActive() {
|
|
567
|
+
return (linkProps as any)['data-status'] === 'active'
|
|
568
|
+
},
|
|
569
|
+
isTransitioning: false,
|
|
570
|
+
})
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
return ch satisfies Solid.JSX.Element
|
|
574
|
+
})
|
|
567
575
|
|
|
568
576
|
return (
|
|
569
577
|
<Dynamic component={local._asChild ? local._asChild : 'a'} {...linkProps}>
|
|
570
|
-
{children}
|
|
578
|
+
{children()}
|
|
571
579
|
</Dynamic>
|
|
572
580
|
)
|
|
573
581
|
}
|
package/src/not-found.tsx
CHANGED
package/src/route.tsx
CHANGED
|
@@ -54,6 +54,14 @@ declare module '@tanstack/router-core' {
|
|
|
54
54
|
pendingComponent?: RouteComponent
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
export interface RootRouteOptionsExtensions {
|
|
58
|
+
shellComponent?: ({
|
|
59
|
+
children,
|
|
60
|
+
}: {
|
|
61
|
+
children: Solid.JSX.Element
|
|
62
|
+
}) => Solid.JSX.Element
|
|
63
|
+
}
|
|
64
|
+
|
|
57
65
|
export interface RouteExtensions<
|
|
58
66
|
in out TId extends string,
|
|
59
67
|
in out TFullPath extends string,
|
|
@@ -480,17 +488,20 @@ export function createRouteMask<
|
|
|
480
488
|
|
|
481
489
|
export type SolidNode = Solid.JSX.Element
|
|
482
490
|
|
|
483
|
-
export
|
|
491
|
+
export interface DefaultRouteTypes<TProps> {
|
|
492
|
+
component: (props: TProps) => any
|
|
493
|
+
}
|
|
494
|
+
export interface RouteTypes<TProps> extends DefaultRouteTypes<TProps> {}
|
|
484
495
|
|
|
485
|
-
export type AsyncRouteComponent<TProps> =
|
|
496
|
+
export type AsyncRouteComponent<TProps> = RouteTypes<TProps>['component'] & {
|
|
486
497
|
preload?: () => Promise<void>
|
|
487
498
|
}
|
|
488
499
|
|
|
489
|
-
export type RouteComponent
|
|
500
|
+
export type RouteComponent = AsyncRouteComponent<{}>
|
|
490
501
|
|
|
491
|
-
export type ErrorRouteComponent =
|
|
502
|
+
export type ErrorRouteComponent = AsyncRouteComponent<ErrorComponentProps>
|
|
492
503
|
|
|
493
|
-
export type NotFoundRouteComponent =
|
|
504
|
+
export type NotFoundRouteComponent = RouteTypes<NotFoundRouteProps>['component']
|
|
494
505
|
|
|
495
506
|
export class NotFoundRoute<
|
|
496
507
|
TParentRoute extends AnyRootRoute,
|
|
@@ -14,16 +14,23 @@ export function ScrollRestoration() {
|
|
|
14
14
|
const resolvedKey =
|
|
15
15
|
userKey !== defaultGetScrollRestorationKey(router.latestLocation)
|
|
16
16
|
? userKey
|
|
17
|
-
:
|
|
17
|
+
: undefined
|
|
18
18
|
|
|
19
19
|
if (!router.isScrollRestoring || !router.isServer) {
|
|
20
20
|
return null
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
const restoreScrollOptions: Parameters<typeof restoreScroll>[0] = {
|
|
24
|
+
storageKey,
|
|
25
|
+
shouldScrollRestoration: true,
|
|
26
|
+
}
|
|
27
|
+
if (resolvedKey) {
|
|
28
|
+
restoreScrollOptions.key = resolvedKey
|
|
29
|
+
}
|
|
30
|
+
|
|
23
31
|
return (
|
|
24
32
|
<ScriptOnce
|
|
25
|
-
children={`(${restoreScroll.toString()})(${JSON.stringify(
|
|
26
|
-
log={false}
|
|
33
|
+
children={`(${restoreScroll.toString()})(${JSON.stringify(restoreScrollOptions)})`}
|
|
27
34
|
/>
|
|
28
35
|
)
|
|
29
36
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { hydrate } from '@tanstack/router-core/ssr/client'
|
|
2
|
+
import { Await } from '../awaited'
|
|
3
|
+
import { HeadContent } from '../HeadContent'
|
|
4
|
+
import { RouterProvider } from '../RouterProvider'
|
|
5
|
+
import type { AnyRouter } from '@tanstack/router-core'
|
|
6
|
+
import type { JSXElement } from 'solid-js'
|
|
7
|
+
|
|
8
|
+
let hydrationPromise: Promise<void | Array<Array<void>>> | undefined
|
|
9
|
+
|
|
10
|
+
const Dummy = (props: { children?: JSXElement }) => <>{props.children}</>
|
|
11
|
+
|
|
12
|
+
export function RouterClient(props: { router: AnyRouter }) {
|
|
13
|
+
if (!hydrationPromise) {
|
|
14
|
+
if (!props.router.state.matches.length) {
|
|
15
|
+
hydrationPromise = hydrate(props.router)
|
|
16
|
+
} else {
|
|
17
|
+
hydrationPromise = Promise.resolve()
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return (
|
|
21
|
+
<Await
|
|
22
|
+
promise={hydrationPromise}
|
|
23
|
+
children={() => (
|
|
24
|
+
<Dummy>
|
|
25
|
+
<Dummy>
|
|
26
|
+
<RouterProvider
|
|
27
|
+
router={props.router}
|
|
28
|
+
InnerWrap={(props) => (
|
|
29
|
+
<Dummy>
|
|
30
|
+
<Dummy>
|
|
31
|
+
<HeadContent />
|
|
32
|
+
{props.children}
|
|
33
|
+
</Dummy>
|
|
34
|
+
<Dummy />
|
|
35
|
+
</Dummy>
|
|
36
|
+
)}
|
|
37
|
+
/>
|
|
38
|
+
</Dummy>
|
|
39
|
+
</Dummy>
|
|
40
|
+
)}
|
|
41
|
+
/>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Hydration,
|
|
3
|
+
HydrationScript,
|
|
4
|
+
NoHydration,
|
|
5
|
+
ssr,
|
|
6
|
+
useAssets,
|
|
7
|
+
} from 'solid-js/web'
|
|
8
|
+
import { MetaProvider } from '@solidjs/meta'
|
|
9
|
+
import { Asset } from '../Asset'
|
|
10
|
+
import { useTags } from '../HeadContent'
|
|
11
|
+
import { RouterProvider } from '../RouterProvider'
|
|
12
|
+
import { Scripts } from '../Scripts'
|
|
13
|
+
import type { AnyRouter } from '@tanstack/router-core'
|
|
14
|
+
|
|
15
|
+
export function ServerHeadContent() {
|
|
16
|
+
const tags = useTags()
|
|
17
|
+
useAssets(() => {
|
|
18
|
+
return (
|
|
19
|
+
<MetaProvider>
|
|
20
|
+
{tags().map((tag) => (
|
|
21
|
+
<Asset {...tag} />
|
|
22
|
+
))}
|
|
23
|
+
</MetaProvider>
|
|
24
|
+
)
|
|
25
|
+
})
|
|
26
|
+
return null
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const docType = ssr('<!DOCTYPE html>')
|
|
30
|
+
|
|
31
|
+
export function RouterServer<TRouter extends AnyRouter>(props: {
|
|
32
|
+
router: TRouter
|
|
33
|
+
}) {
|
|
34
|
+
return (
|
|
35
|
+
<NoHydration>
|
|
36
|
+
{docType as any}
|
|
37
|
+
<html>
|
|
38
|
+
<head>
|
|
39
|
+
<HydrationScript />
|
|
40
|
+
</head>
|
|
41
|
+
<body>
|
|
42
|
+
<Hydration>
|
|
43
|
+
<RouterProvider
|
|
44
|
+
router={props.router}
|
|
45
|
+
InnerWrap={(props) => (
|
|
46
|
+
<NoHydration>
|
|
47
|
+
<MetaProvider>
|
|
48
|
+
<ServerHeadContent />
|
|
49
|
+
<Hydration>{props.children}</Hydration>
|
|
50
|
+
<Scripts />
|
|
51
|
+
</MetaProvider>
|
|
52
|
+
</NoHydration>
|
|
53
|
+
)}
|
|
54
|
+
/>
|
|
55
|
+
</Hydration>
|
|
56
|
+
</body>
|
|
57
|
+
</html>
|
|
58
|
+
</NoHydration>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { RouterClient } from './RouterClient'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { defineHandlerCallback } from '@tanstack/router-core/ssr/server'
|
|
2
|
+
import { RouterServer } from './RouterServer'
|
|
3
|
+
import { renderRouterToString } from './renderRouterToString'
|
|
4
|
+
|
|
5
|
+
export const defaultRenderHandler = defineHandlerCallback(
|
|
6
|
+
({ router, responseHeaders }) =>
|
|
7
|
+
renderRouterToString({
|
|
8
|
+
router,
|
|
9
|
+
responseHeaders,
|
|
10
|
+
children: () => <RouterServer router={router} />,
|
|
11
|
+
}),
|
|
12
|
+
)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { defineHandlerCallback } from '@tanstack/router-core/ssr/server'
|
|
2
|
+
import { RouterServer } from './RouterServer'
|
|
3
|
+
import { renderRouterToStream } from './renderRouterToStream'
|
|
4
|
+
|
|
5
|
+
export const defaultStreamHandler = defineHandlerCallback(
|
|
6
|
+
({ request, router, responseHeaders }) =>
|
|
7
|
+
renderRouterToStream({
|
|
8
|
+
request,
|
|
9
|
+
router,
|
|
10
|
+
responseHeaders,
|
|
11
|
+
children: () => <RouterServer router={router} />,
|
|
12
|
+
}),
|
|
13
|
+
)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as Solid from 'solid-js/web'
|
|
2
|
+
import { isbot } from 'isbot'
|
|
3
|
+
import { transformReadableStreamWithRouter } from '@tanstack/router-core/ssr/server'
|
|
4
|
+
import type { JSXElement } from 'solid-js'
|
|
5
|
+
import type { ReadableStream } from 'node:stream/web'
|
|
6
|
+
import type { AnyRouter } from '@tanstack/router-core'
|
|
7
|
+
|
|
8
|
+
export const renderRouterToStream = async ({
|
|
9
|
+
request,
|
|
10
|
+
router,
|
|
11
|
+
responseHeaders,
|
|
12
|
+
children,
|
|
13
|
+
}: {
|
|
14
|
+
request: Request
|
|
15
|
+
router: AnyRouter
|
|
16
|
+
responseHeaders: Headers
|
|
17
|
+
children: () => JSXElement
|
|
18
|
+
}) => {
|
|
19
|
+
const { writable, readable } = new TransformStream()
|
|
20
|
+
|
|
21
|
+
const stream = Solid.renderToStream(children)
|
|
22
|
+
|
|
23
|
+
if (isbot(request.headers.get('User-Agent'))) {
|
|
24
|
+
await stream
|
|
25
|
+
}
|
|
26
|
+
stream.pipeTo(writable)
|
|
27
|
+
|
|
28
|
+
const responseStream = transformReadableStreamWithRouter(
|
|
29
|
+
router,
|
|
30
|
+
readable as unknown as ReadableStream,
|
|
31
|
+
)
|
|
32
|
+
return new Response(responseStream as any, {
|
|
33
|
+
status: router.state.statusCode,
|
|
34
|
+
headers: responseHeaders,
|
|
35
|
+
})
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import * as Solid from 'solid-js/web'
|
|
2
|
+
import type { JSXElement } from 'solid-js'
|
|
3
|
+
import type { AnyRouter } from '@tanstack/router-core'
|
|
4
|
+
|
|
5
|
+
export const renderRouterToString = async ({
|
|
6
|
+
router,
|
|
7
|
+
responseHeaders,
|
|
8
|
+
children,
|
|
9
|
+
}: {
|
|
10
|
+
router: AnyRouter
|
|
11
|
+
responseHeaders: Headers
|
|
12
|
+
children: () => JSXElement
|
|
13
|
+
}) => {
|
|
14
|
+
try {
|
|
15
|
+
let html = Solid.renderToString(children)
|
|
16
|
+
const injectedHtml = await Promise.all(router.serverSsr!.injectedHtml).then(
|
|
17
|
+
(htmls) => htmls.join(''),
|
|
18
|
+
)
|
|
19
|
+
html = html.replace(`</body>`, `${injectedHtml}</body>`)
|
|
20
|
+
return new Response(html, {
|
|
21
|
+
status: router.state.statusCode,
|
|
22
|
+
headers: responseHeaders,
|
|
23
|
+
})
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error('Render to string error:', error)
|
|
26
|
+
return new Response('Internal Server Error', {
|
|
27
|
+
status: 500,
|
|
28
|
+
headers: responseHeaders,
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { RouterServer } from './RouterServer'
|
|
2
|
+
export { defaultRenderHandler } from './defaultRenderHandler'
|
|
3
|
+
export { defaultStreamHandler } from './defaultStreamHandler'
|
|
4
|
+
export { renderRouterToStream } from './renderRouterToStream'
|
|
5
|
+
export { renderRouterToString } from './renderRouterToString'
|
|
6
|
+
export * from '@tanstack/router-core/ssr/server'
|
package/src/useBlocker.tsx
CHANGED
|
@@ -112,20 +112,25 @@ function _resolveBlockerOpts(
|
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
const shouldBlock = Boolean(opts.condition ?? true)
|
|
116
|
-
const fn = opts.blockerFn
|
|
115
|
+
const shouldBlock = Solid.createMemo(() => Boolean(opts.condition ?? true))
|
|
117
116
|
|
|
118
117
|
const _customBlockerFn = async () => {
|
|
119
|
-
if (shouldBlock &&
|
|
120
|
-
return await
|
|
118
|
+
if (shouldBlock() && opts.blockerFn !== undefined) {
|
|
119
|
+
return await opts.blockerFn()
|
|
121
120
|
}
|
|
122
|
-
return shouldBlock
|
|
121
|
+
return shouldBlock()
|
|
123
122
|
}
|
|
124
123
|
|
|
125
124
|
return {
|
|
126
|
-
shouldBlockFn
|
|
127
|
-
|
|
128
|
-
|
|
125
|
+
get shouldBlockFn() {
|
|
126
|
+
return _customBlockerFn
|
|
127
|
+
},
|
|
128
|
+
get enableBeforeUnload() {
|
|
129
|
+
return shouldBlock()
|
|
130
|
+
},
|
|
131
|
+
get withResolver() {
|
|
132
|
+
return opts.blockerFn === undefined
|
|
133
|
+
},
|
|
129
134
|
}
|
|
130
135
|
}
|
|
131
136
|
|
|
@@ -155,15 +160,16 @@ export function useBlocker(
|
|
|
155
160
|
opts?: UseBlockerOpts | LegacyBlockerOpts | LegacyBlockerFn,
|
|
156
161
|
condition?: boolean | any,
|
|
157
162
|
): Solid.Accessor<BlockerResolver> | void {
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
const props = Solid.mergeProps(
|
|
164
|
+
{
|
|
165
|
+
enableBeforeUnload: true,
|
|
166
|
+
disabled: false,
|
|
167
|
+
withResolver: false,
|
|
168
|
+
},
|
|
169
|
+
_resolveBlockerOpts(opts, condition),
|
|
170
|
+
)
|
|
164
171
|
|
|
165
172
|
const router = useRouter()
|
|
166
|
-
const { history } = router
|
|
167
173
|
|
|
168
174
|
const [resolver, setResolver] = Solid.createSignal<BlockerResolver>({
|
|
169
175
|
status: 'idle',
|
|
@@ -199,12 +205,12 @@ export function useBlocker(
|
|
|
199
205
|
const current = getLocation(blockerFnArgs.currentLocation)
|
|
200
206
|
const next = getLocation(blockerFnArgs.nextLocation)
|
|
201
207
|
|
|
202
|
-
const shouldBlock = await shouldBlockFn({
|
|
208
|
+
const shouldBlock = await props.shouldBlockFn({
|
|
203
209
|
action: blockerFnArgs.action,
|
|
204
210
|
current,
|
|
205
211
|
next,
|
|
206
212
|
})
|
|
207
|
-
if (!withResolver) {
|
|
213
|
+
if (!props.withResolver) {
|
|
208
214
|
return shouldBlock
|
|
209
215
|
}
|
|
210
216
|
|
|
@@ -236,9 +242,14 @@ export function useBlocker(
|
|
|
236
242
|
return canNavigateAsync
|
|
237
243
|
}
|
|
238
244
|
|
|
239
|
-
|
|
245
|
+
const disposeBlock = props.disabled
|
|
240
246
|
? undefined
|
|
241
|
-
: history.block({
|
|
247
|
+
: router.history.block({
|
|
248
|
+
blockerFn: blockerFnComposed,
|
|
249
|
+
enableBeforeUnload: props.enableBeforeUnload,
|
|
250
|
+
})
|
|
251
|
+
|
|
252
|
+
Solid.onCleanup(() => disposeBlock?.())
|
|
242
253
|
})
|
|
243
254
|
|
|
244
255
|
return resolver
|
|
@@ -248,23 +259,26 @@ const _resolvePromptBlockerArgs = (
|
|
|
248
259
|
props: PromptProps | LegacyPromptProps,
|
|
249
260
|
): UseBlockerOpts => {
|
|
250
261
|
if ('shouldBlockFn' in props) {
|
|
251
|
-
return
|
|
262
|
+
return props
|
|
252
263
|
}
|
|
253
264
|
|
|
254
|
-
const shouldBlock = Boolean(props.condition ?? true)
|
|
255
|
-
const fn = props.blockerFn
|
|
265
|
+
const shouldBlock = Solid.createMemo(() => Boolean(props.condition ?? true))
|
|
256
266
|
|
|
257
267
|
const _customBlockerFn = async () => {
|
|
258
|
-
if (shouldBlock &&
|
|
259
|
-
return await
|
|
268
|
+
if (shouldBlock() && props.blockerFn !== undefined) {
|
|
269
|
+
return await props.blockerFn()
|
|
260
270
|
}
|
|
261
271
|
return shouldBlock
|
|
262
272
|
}
|
|
263
273
|
|
|
264
274
|
return {
|
|
265
275
|
shouldBlockFn: _customBlockerFn,
|
|
266
|
-
enableBeforeUnload
|
|
267
|
-
|
|
276
|
+
get enableBeforeUnload() {
|
|
277
|
+
return shouldBlock()
|
|
278
|
+
},
|
|
279
|
+
get withResolver() {
|
|
280
|
+
return props.blockerFn === undefined
|
|
281
|
+
},
|
|
268
282
|
}
|
|
269
283
|
}
|
|
270
284
|
|
|
@@ -279,15 +293,17 @@ export function Block<
|
|
|
279
293
|
export function Block(opts: LegacyPromptProps): SolidNode
|
|
280
294
|
|
|
281
295
|
export function Block(opts: PromptProps | LegacyPromptProps): SolidNode {
|
|
282
|
-
const
|
|
296
|
+
const [propsWithChildren, rest] = Solid.splitProps(opts, ['children'])
|
|
283
297
|
const args = _resolvePromptBlockerArgs(rest)
|
|
284
298
|
|
|
285
299
|
const resolver = useBlocker(args)
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
300
|
+
const children = Solid.createMemo(() => {
|
|
301
|
+
const child = propsWithChildren.children
|
|
302
|
+
if (resolver && typeof child === 'function') return child(resolver())
|
|
303
|
+
return child
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
return <>{children()}</>
|
|
291
307
|
}
|
|
292
308
|
|
|
293
309
|
type LegacyPromptProps = {
|
package/src/useNavigate.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Solid from 'solid-js'
|
|
2
2
|
import { useRouter } from './useRouter'
|
|
3
|
+
import { useMatch } from './useMatch'
|
|
3
4
|
import type {
|
|
4
5
|
AnyRouter,
|
|
5
6
|
FromPathOption,
|
|
@@ -14,10 +15,21 @@ export function useNavigate<
|
|
|
14
15
|
>(_defaultOpts?: {
|
|
15
16
|
from?: FromPathOption<TRouter, TDefaultFrom>
|
|
16
17
|
}): UseNavigateResult<TDefaultFrom> {
|
|
17
|
-
const { navigate } = useRouter()
|
|
18
|
+
const { navigate, state } = useRouter()
|
|
19
|
+
|
|
20
|
+
const matchIndex = useMatch({
|
|
21
|
+
strict: false,
|
|
22
|
+
select: (match) => match.index,
|
|
23
|
+
})
|
|
18
24
|
|
|
19
25
|
return ((options: NavigateOptions) => {
|
|
20
|
-
return navigate({
|
|
26
|
+
return navigate({
|
|
27
|
+
...options,
|
|
28
|
+
from:
|
|
29
|
+
options.from ??
|
|
30
|
+
_defaultOpts?.from ??
|
|
31
|
+
state.matches[matchIndex()]!.fullPath,
|
|
32
|
+
})
|
|
21
33
|
}) as UseNavigateResult<TDefaultFrom>
|
|
22
34
|
}
|
|
23
35
|
|