@tanstack/vue-router 0.0.1 → 1.140.1
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 +66 -45
- package/dist/esm/Asset.d.ts +2 -0
- package/dist/esm/Asset.js +33 -0
- package/dist/esm/Asset.js.map +1 -0
- package/dist/esm/CatchBoundary.d.ts +19 -0
- package/dist/esm/CatchBoundary.js +135 -0
- package/dist/esm/CatchBoundary.js.map +1 -0
- package/dist/esm/ClientOnly.d.ts +67 -0
- package/dist/esm/HeadContent.d.ts +10 -0
- package/dist/esm/HeadContent.js +116 -0
- package/dist/esm/HeadContent.js.map +1 -0
- package/dist/esm/Match.d.ts +25 -0
- package/dist/esm/Match.js +262 -0
- package/dist/esm/Match.js.map +1 -0
- package/dist/esm/Matches.d.ts +39 -0
- package/dist/esm/Matches.js +186 -0
- package/dist/esm/Matches.js.map +1 -0
- package/dist/esm/RouterProvider.d.ts +33 -0
- package/dist/esm/RouterProvider.js +65 -0
- package/dist/esm/RouterProvider.js.map +1 -0
- package/dist/esm/SafeFragment.d.ts +4 -0
- package/dist/esm/ScriptOnce.d.ts +5 -0
- package/dist/esm/ScriptOnce.js +21 -0
- package/dist/esm/ScriptOnce.js.map +1 -0
- package/dist/esm/Scripts.d.ts +1 -0
- package/dist/esm/Scripts.js +46 -0
- package/dist/esm/Scripts.js.map +1 -0
- package/dist/esm/ScrollRestoration.d.ts +14 -0
- package/dist/esm/ScrollRestoration.js +36 -0
- package/dist/esm/ScrollRestoration.js.map +1 -0
- package/dist/esm/Transitioner.d.ts +2 -0
- package/dist/esm/Transitioner.js +154 -0
- package/dist/esm/Transitioner.js.map +1 -0
- package/dist/esm/awaited.d.ts +12 -0
- package/dist/esm/awaited.js +40 -0
- package/dist/esm/awaited.js.map +1 -0
- package/dist/esm/fileRoute.d.ts +54 -0
- package/dist/esm/fileRoute.js +103 -0
- package/dist/esm/fileRoute.js.map +1 -0
- package/dist/esm/history.d.ts +8 -0
- package/dist/esm/index.d.ts +51 -0
- package/dist/esm/index.js +138 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lazyRouteComponent.d.ts +8 -0
- package/dist/esm/lazyRouteComponent.js +106 -0
- package/dist/esm/lazyRouteComponent.js.map +1 -0
- package/dist/esm/link.d.ts +61 -0
- package/dist/esm/link.js +376 -0
- package/dist/esm/link.js.map +1 -0
- package/dist/esm/matchContext.d.ts +20 -0
- package/dist/esm/matchContext.js +16 -0
- package/dist/esm/matchContext.js.map +1 -0
- package/dist/esm/not-found.d.ts +12 -0
- package/dist/esm/not-found.js +45 -0
- package/dist/esm/not-found.js.map +1 -0
- package/dist/esm/renderRouteNotFound.d.ts +11 -0
- package/dist/esm/renderRouteNotFound.js +19 -0
- package/dist/esm/renderRouteNotFound.js.map +1 -0
- package/dist/esm/route.d.ts +96 -0
- package/dist/esm/route.js +176 -0
- package/dist/esm/route.js.map +1 -0
- package/dist/esm/router.d.ts +69 -0
- package/dist/esm/router.js +14 -0
- package/dist/esm/router.js.map +1 -0
- package/dist/esm/routerContext.d.ts +21 -0
- package/dist/esm/routerContext.js +21 -0
- package/dist/esm/routerContext.js.map +1 -0
- package/dist/esm/scroll-restoration.d.ts +1 -0
- package/dist/esm/scroll-restoration.js +21 -0
- package/dist/esm/scroll-restoration.js.map +1 -0
- package/dist/esm/typePrimitives.d.ts +10 -0
- package/dist/esm/useBlocker.d.ts +66 -0
- package/dist/esm/useBlocker.js +295 -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 +8 -0
- package/dist/esm/useLoaderData.js +14 -0
- package/dist/esm/useLoaderData.js.map +1 -0
- package/dist/esm/useLoaderDeps.d.ts +7 -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 +10 -0
- package/dist/esm/useMatch.js +39 -0
- package/dist/esm/useMatch.js.map +1 -0
- package/dist/esm/useNavigate.d.ts +5 -0
- package/dist/esm/useNavigate.js +29 -0
- package/dist/esm/useNavigate.js.map +1 -0
- package/dist/esm/useParams.d.ts +9 -0
- package/dist/esm/useParams.js +15 -0
- package/dist/esm/useParams.js.map +1 -0
- package/dist/esm/useRouteContext.d.ts +4 -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 +20 -0
- package/dist/esm/useRouterState.js.map +1 -0
- package/dist/esm/useSearch.d.ts +9 -0
- package/dist/esm/useSearch.js +15 -0
- package/dist/esm/useSearch.js.map +1 -0
- package/dist/esm/utils.d.ts +40 -0
- package/dist/esm/utils.js +44 -0
- package/dist/esm/utils.js.map +1 -0
- package/dist/source/Asset.d.ts +2 -0
- package/dist/source/Asset.jsx +22 -0
- package/dist/source/Asset.jsx.map +1 -0
- package/dist/source/CatchBoundary.d.ts +19 -0
- package/dist/source/CatchBoundary.jsx +134 -0
- package/dist/source/CatchBoundary.jsx.map +1 -0
- package/dist/source/ClientOnly.d.ts +67 -0
- package/dist/source/ClientOnly.jsx +63 -0
- package/dist/source/ClientOnly.jsx.map +1 -0
- package/dist/source/HeadContent.d.ts +10 -0
- package/dist/source/HeadContent.jsx +133 -0
- package/dist/source/HeadContent.jsx.map +1 -0
- package/dist/source/Match.d.ts +25 -0
- package/dist/source/Match.jsx +316 -0
- package/dist/source/Match.jsx.map +1 -0
- package/dist/source/Matches.d.ts +39 -0
- package/dist/source/Matches.jsx +191 -0
- package/dist/source/Matches.jsx.map +1 -0
- package/dist/source/RouterProvider.d.ts +33 -0
- package/dist/source/RouterProvider.jsx +63 -0
- package/dist/source/RouterProvider.jsx.map +1 -0
- package/dist/source/SafeFragment.d.ts +4 -0
- package/dist/source/SafeFragment.jsx +10 -0
- package/dist/source/SafeFragment.jsx.map +1 -0
- package/dist/source/ScriptOnce.d.ts +5 -0
- package/dist/source/ScriptOnce.jsx +17 -0
- package/dist/source/ScriptOnce.jsx.map +1 -0
- package/dist/source/Scripts.d.ts +1 -0
- package/dist/source/Scripts.jsx +49 -0
- package/dist/source/Scripts.jsx.map +1 -0
- package/dist/source/ScrollRestoration.d.ts +14 -0
- package/dist/source/ScrollRestoration.jsx +37 -0
- package/dist/source/ScrollRestoration.jsx.map +1 -0
- package/dist/source/Transitioner.d.ts +2 -0
- package/dist/source/Transitioner.jsx +181 -0
- package/dist/source/Transitioner.jsx.map +1 -0
- package/dist/source/awaited.d.ts +12 -0
- package/dist/source/awaited.jsx +38 -0
- package/dist/source/awaited.jsx.map +1 -0
- package/dist/source/fileRoute.d.ts +54 -0
- package/dist/source/fileRoute.js +98 -0
- package/dist/source/fileRoute.js.map +1 -0
- package/dist/source/history.d.ts +8 -0
- package/dist/source/history.js +2 -0
- package/dist/source/history.js.map +1 -0
- package/dist/source/index.d.ts +51 -0
- package/dist/source/index.jsx +40 -0
- package/dist/source/index.jsx.map +1 -0
- package/dist/source/lazyRouteComponent.d.ts +8 -0
- package/dist/source/lazyRouteComponent.jsx +135 -0
- package/dist/source/lazyRouteComponent.jsx.map +1 -0
- package/dist/source/link.d.ts +61 -0
- package/dist/source/link.jsx +495 -0
- package/dist/source/link.jsx.map +1 -0
- package/dist/source/matchContext.d.ts +20 -0
- package/dist/source/matchContext.jsx +32 -0
- package/dist/source/matchContext.jsx.map +1 -0
- package/dist/source/not-found.d.ts +12 -0
- package/dist/source/not-found.jsx +48 -0
- package/dist/source/not-found.jsx.map +1 -0
- package/dist/source/renderRouteNotFound.d.ts +11 -0
- package/dist/source/renderRouteNotFound.jsx +24 -0
- package/dist/source/renderRouteNotFound.jsx.map +1 -0
- package/dist/source/route.d.ts +97 -0
- package/dist/source/route.js +167 -0
- package/dist/source/route.js.map +1 -0
- package/dist/source/router.d.ts +70 -0
- package/dist/source/router.js +10 -0
- package/dist/source/router.js.map +1 -0
- package/dist/source/routerContext.d.ts +21 -0
- package/dist/source/routerContext.jsx +37 -0
- package/dist/source/routerContext.jsx.map +1 -0
- package/dist/source/scroll-restoration.d.ts +1 -0
- package/dist/source/scroll-restoration.jsx +16 -0
- package/dist/source/scroll-restoration.jsx.map +1 -0
- package/dist/source/typePrimitives.d.ts +10 -0
- package/dist/source/typePrimitives.js +2 -0
- package/dist/source/typePrimitives.js.map +1 -0
- package/dist/source/useBlocker.d.ts +66 -0
- package/dist/source/useBlocker.jsx +308 -0
- package/dist/source/useBlocker.jsx.map +1 -0
- package/dist/source/useCanGoBack.d.ts +1 -0
- package/dist/source/useCanGoBack.js +5 -0
- package/dist/source/useCanGoBack.js.map +1 -0
- package/dist/source/useLoaderData.d.ts +8 -0
- package/dist/source/useLoaderData.jsx +11 -0
- package/dist/source/useLoaderData.jsx.map +1 -0
- package/dist/source/useLoaderDeps.d.ts +7 -0
- package/dist/source/useLoaderDeps.jsx +11 -0
- package/dist/source/useLoaderDeps.jsx.map +1 -0
- package/dist/source/useLocation.d.ts +7 -0
- package/dist/source/useLocation.jsx +7 -0
- package/dist/source/useLocation.jsx.map +1 -0
- package/dist/source/useMatch.d.ts +10 -0
- package/dist/source/useMatch.jsx +46 -0
- package/dist/source/useMatch.jsx.map +1 -0
- package/dist/source/useNavigate.d.ts +5 -0
- package/dist/source/useNavigate.jsx +18 -0
- package/dist/source/useNavigate.jsx.map +1 -0
- package/dist/source/useParams.d.ts +9 -0
- package/dist/source/useParams.jsx +12 -0
- package/dist/source/useParams.jsx.map +1 -0
- package/dist/source/useRouteContext.d.ts +4 -0
- package/dist/source/useRouteContext.js +8 -0
- package/dist/source/useRouteContext.js.map +1 -0
- package/dist/source/useRouter.d.ts +4 -0
- package/dist/source/useRouter.jsx +9 -0
- package/dist/source/useRouter.jsx.map +1 -0
- package/dist/source/useRouterState.d.ts +8 -0
- package/dist/source/useRouterState.jsx +19 -0
- package/dist/source/useRouterState.jsx.map +1 -0
- package/dist/source/useSearch.d.ts +9 -0
- package/dist/source/useSearch.jsx +12 -0
- package/dist/source/useSearch.jsx.map +1 -0
- package/dist/source/utils.d.ts +40 -0
- package/dist/source/utils.js +78 -0
- package/dist/source/utils.js.map +1 -0
- package/package.json +77 -7
- package/src/Asset.tsx +23 -0
- package/src/CatchBoundary.tsx +186 -0
- package/src/ClientOnly.tsx +75 -0
- package/src/HeadContent.tsx +159 -0
- package/src/Match.tsx +415 -0
- package/src/Matches.tsx +349 -0
- package/src/RouterProvider.tsx +117 -0
- package/src/SafeFragment.tsx +10 -0
- package/src/ScriptOnce.tsx +30 -0
- package/src/Scripts.tsx +65 -0
- package/src/ScrollRestoration.tsx +69 -0
- package/src/Transitioner.tsx +213 -0
- package/src/awaited.tsx +54 -0
- package/src/fileRoute.ts +271 -0
- package/src/history.ts +9 -0
- package/src/index.tsx +346 -0
- package/src/lazyRouteComponent.tsx +173 -0
- package/src/link.tsx +765 -0
- package/src/matchContext.tsx +41 -0
- package/src/not-found.tsx +55 -0
- package/src/renderRouteNotFound.tsx +35 -0
- package/src/route.ts +658 -0
- package/src/router.ts +103 -0
- package/src/routerContext.tsx +53 -0
- package/src/scroll-restoration.tsx +29 -0
- package/src/typePrimitives.ts +74 -0
- package/src/useBlocker.tsx +501 -0
- package/src/useCanGoBack.ts +5 -0
- package/src/useLoaderData.tsx +50 -0
- package/src/useLoaderDeps.tsx +46 -0
- package/src/useLocation.tsx +30 -0
- package/src/useMatch.tsx +127 -0
- package/src/useNavigate.tsx +40 -0
- package/src/useParams.tsx +71 -0
- package/src/useRouteContext.ts +31 -0
- package/src/useRouter.tsx +15 -0
- package/src/useRouterState.tsx +43 -0
- package/src/useSearch.tsx +71 -0
- package/src/utils.ts +111 -0
package/src/useMatch.tsx
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as Vue from 'vue'
|
|
2
|
+
import { useRouterState } from './useRouterState'
|
|
3
|
+
import { injectDummyMatch, injectMatch } from './matchContext'
|
|
4
|
+
import type {
|
|
5
|
+
AnyRouter,
|
|
6
|
+
MakeRouteMatch,
|
|
7
|
+
MakeRouteMatchUnion,
|
|
8
|
+
RegisteredRouter,
|
|
9
|
+
StrictOrFrom,
|
|
10
|
+
ThrowConstraint,
|
|
11
|
+
ThrowOrOptional,
|
|
12
|
+
} from '@tanstack/router-core'
|
|
13
|
+
|
|
14
|
+
export interface UseMatchBaseOptions<
|
|
15
|
+
TRouter extends AnyRouter,
|
|
16
|
+
TFrom,
|
|
17
|
+
TStrict extends boolean,
|
|
18
|
+
TThrow extends boolean,
|
|
19
|
+
TSelected,
|
|
20
|
+
> {
|
|
21
|
+
select?: (
|
|
22
|
+
match: MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>,
|
|
23
|
+
) => TSelected
|
|
24
|
+
shouldThrow?: TThrow
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type UseMatchRoute<out TFrom> = <
|
|
28
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
29
|
+
TSelected = unknown,
|
|
30
|
+
>(
|
|
31
|
+
opts?: UseMatchBaseOptions<TRouter, TFrom, true, true, TSelected>,
|
|
32
|
+
) => Vue.Ref<UseMatchResult<TRouter, TFrom, true, TSelected>>
|
|
33
|
+
|
|
34
|
+
export type UseMatchOptions<
|
|
35
|
+
TRouter extends AnyRouter,
|
|
36
|
+
TFrom extends string | undefined,
|
|
37
|
+
TStrict extends boolean,
|
|
38
|
+
TThrow extends boolean,
|
|
39
|
+
TSelected,
|
|
40
|
+
> = StrictOrFrom<TRouter, TFrom, TStrict> &
|
|
41
|
+
UseMatchBaseOptions<TRouter, TFrom, TStrict, TThrow, TSelected>
|
|
42
|
+
|
|
43
|
+
export type UseMatchResult<
|
|
44
|
+
TRouter extends AnyRouter,
|
|
45
|
+
TFrom,
|
|
46
|
+
TStrict extends boolean,
|
|
47
|
+
TSelected,
|
|
48
|
+
> = unknown extends TSelected
|
|
49
|
+
? TStrict extends true
|
|
50
|
+
? MakeRouteMatch<TRouter['routeTree'], TFrom, TStrict>
|
|
51
|
+
: MakeRouteMatchUnion<TRouter>
|
|
52
|
+
: TSelected
|
|
53
|
+
|
|
54
|
+
export function useMatch<
|
|
55
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
56
|
+
const TFrom extends string | undefined = undefined,
|
|
57
|
+
TStrict extends boolean = true,
|
|
58
|
+
TThrow extends boolean = true,
|
|
59
|
+
TSelected = unknown,
|
|
60
|
+
>(
|
|
61
|
+
opts: UseMatchOptions<
|
|
62
|
+
TRouter,
|
|
63
|
+
TFrom,
|
|
64
|
+
TStrict,
|
|
65
|
+
ThrowConstraint<TStrict, TThrow>,
|
|
66
|
+
TSelected
|
|
67
|
+
>,
|
|
68
|
+
): Vue.Ref<
|
|
69
|
+
ThrowOrOptional<UseMatchResult<TRouter, TFrom, TStrict, TSelected>, TThrow>
|
|
70
|
+
> {
|
|
71
|
+
const nearestMatchId = opts.from ? injectDummyMatch() : injectMatch()
|
|
72
|
+
|
|
73
|
+
// Store to track pending error for deferred throwing
|
|
74
|
+
const pendingError = Vue.ref<Error | null>(null)
|
|
75
|
+
|
|
76
|
+
// Select the match from router state
|
|
77
|
+
const matchSelection = useRouterState({
|
|
78
|
+
select: (state: any) => {
|
|
79
|
+
const match = state.matches.find((d: any) =>
|
|
80
|
+
opts.from ? opts.from === d.routeId : d.id === nearestMatchId.value,
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
if (match === undefined) {
|
|
84
|
+
// During navigation transitions, check if the match exists in pendingMatches
|
|
85
|
+
const pendingMatch = state.pendingMatches?.find((d: any) =>
|
|
86
|
+
opts.from ? opts.from === d.routeId : d.id === nearestMatchId.value,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
// If there's a pending match or we're transitioning, return undefined without throwing
|
|
90
|
+
if (pendingMatch || state.isTransitioning) {
|
|
91
|
+
pendingError.value = null
|
|
92
|
+
return undefined
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Store the error to throw later if shouldThrow is enabled
|
|
96
|
+
if (opts.shouldThrow ?? true) {
|
|
97
|
+
pendingError.value = new Error(
|
|
98
|
+
`Invariant failed: Could not find ${opts.from ? `an active match from "${opts.from}"` : 'a nearest match!'}`,
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return undefined
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
pendingError.value = null
|
|
106
|
+
return opts.select ? opts.select(match) : match
|
|
107
|
+
},
|
|
108
|
+
} as any)
|
|
109
|
+
|
|
110
|
+
// Throw the error if we have one - this happens after the selector runs
|
|
111
|
+
// Using a computed so the error is thrown when the return value is accessed
|
|
112
|
+
const result = Vue.computed(() => {
|
|
113
|
+
// Check for pending error first
|
|
114
|
+
if (pendingError.value) {
|
|
115
|
+
throw pendingError.value
|
|
116
|
+
}
|
|
117
|
+
return matchSelection.value
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
// Also immediately throw if there's already an error from initial render
|
|
121
|
+
// This ensures errors are thrown even if the returned ref is never accessed
|
|
122
|
+
if (pendingError.value) {
|
|
123
|
+
throw pendingError.value
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return result as any
|
|
127
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as Vue from 'vue'
|
|
2
|
+
import { useRouter } from './useRouter'
|
|
3
|
+
import type {
|
|
4
|
+
AnyRouter,
|
|
5
|
+
FromPathOption,
|
|
6
|
+
NavigateOptions,
|
|
7
|
+
RegisteredRouter,
|
|
8
|
+
UseNavigateResult,
|
|
9
|
+
} from '@tanstack/router-core'
|
|
10
|
+
|
|
11
|
+
export function useNavigate<
|
|
12
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
13
|
+
TDefaultFrom extends string = string,
|
|
14
|
+
>(_defaultOpts?: {
|
|
15
|
+
from?: FromPathOption<TRouter, TDefaultFrom>
|
|
16
|
+
}): UseNavigateResult<TDefaultFrom> {
|
|
17
|
+
const { navigate } = useRouter()
|
|
18
|
+
|
|
19
|
+
return ((options: NavigateOptions) => {
|
|
20
|
+
return navigate({ from: _defaultOpts?.from, ...options })
|
|
21
|
+
}) as UseNavigateResult<TDefaultFrom>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function Navigate<
|
|
25
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
26
|
+
const TFrom extends string = string,
|
|
27
|
+
const TTo extends string | undefined = undefined,
|
|
28
|
+
const TMaskFrom extends string = TFrom,
|
|
29
|
+
const TMaskTo extends string = '',
|
|
30
|
+
>(props: NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): null {
|
|
31
|
+
const { navigate } = useRouter()
|
|
32
|
+
|
|
33
|
+
Vue.onMounted(() => {
|
|
34
|
+
navigate({
|
|
35
|
+
...props,
|
|
36
|
+
})
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
return null
|
|
40
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useMatch } from './useMatch'
|
|
2
|
+
import type * as Vue from 'vue'
|
|
3
|
+
import type {
|
|
4
|
+
AnyRouter,
|
|
5
|
+
RegisteredRouter,
|
|
6
|
+
ResolveUseParams,
|
|
7
|
+
StrictOrFrom,
|
|
8
|
+
ThrowConstraint,
|
|
9
|
+
ThrowOrOptional,
|
|
10
|
+
UseParamsResult,
|
|
11
|
+
} from '@tanstack/router-core'
|
|
12
|
+
|
|
13
|
+
export interface UseParamsBaseOptions<
|
|
14
|
+
TRouter extends AnyRouter,
|
|
15
|
+
TFrom,
|
|
16
|
+
TStrict extends boolean,
|
|
17
|
+
TThrow extends boolean,
|
|
18
|
+
TSelected,
|
|
19
|
+
> {
|
|
20
|
+
select?: (params: ResolveUseParams<TRouter, TFrom, TStrict>) => TSelected
|
|
21
|
+
shouldThrow?: TThrow
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type UseParamsOptions<
|
|
25
|
+
TRouter extends AnyRouter,
|
|
26
|
+
TFrom extends string | undefined,
|
|
27
|
+
TStrict extends boolean,
|
|
28
|
+
TThrow extends boolean,
|
|
29
|
+
TSelected,
|
|
30
|
+
> = StrictOrFrom<TRouter, TFrom, TStrict> &
|
|
31
|
+
UseParamsBaseOptions<TRouter, TFrom, TStrict, TThrow, TSelected>
|
|
32
|
+
|
|
33
|
+
export type UseParamsRoute<out TFrom> = <
|
|
34
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
35
|
+
TSelected = unknown,
|
|
36
|
+
>(
|
|
37
|
+
opts?: UseParamsBaseOptions<
|
|
38
|
+
TRouter,
|
|
39
|
+
TFrom,
|
|
40
|
+
/* TStrict */ true,
|
|
41
|
+
/* TThrow */ true,
|
|
42
|
+
TSelected
|
|
43
|
+
>,
|
|
44
|
+
) => Vue.Ref<UseParamsResult<TRouter, TFrom, true, TSelected>>
|
|
45
|
+
|
|
46
|
+
export function useParams<
|
|
47
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
48
|
+
const TFrom extends string | undefined = undefined,
|
|
49
|
+
TStrict extends boolean = true,
|
|
50
|
+
TThrow extends boolean = true,
|
|
51
|
+
TSelected = unknown,
|
|
52
|
+
>(
|
|
53
|
+
opts: UseParamsOptions<
|
|
54
|
+
TRouter,
|
|
55
|
+
TFrom,
|
|
56
|
+
TStrict,
|
|
57
|
+
ThrowConstraint<TStrict, TThrow>,
|
|
58
|
+
TSelected
|
|
59
|
+
>,
|
|
60
|
+
): Vue.Ref<
|
|
61
|
+
ThrowOrOptional<UseParamsResult<TRouter, TFrom, TStrict, TSelected>, TThrow>
|
|
62
|
+
> {
|
|
63
|
+
return useMatch({
|
|
64
|
+
from: opts.from!,
|
|
65
|
+
strict: opts.strict,
|
|
66
|
+
shouldThrow: opts.shouldThrow,
|
|
67
|
+
select: (match: any) => {
|
|
68
|
+
return opts.select ? opts.select(match.params) : match.params
|
|
69
|
+
},
|
|
70
|
+
} as any) as any
|
|
71
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useMatch } from './useMatch'
|
|
2
|
+
import type * as Vue from 'vue'
|
|
3
|
+
import type {
|
|
4
|
+
AnyRouter,
|
|
5
|
+
RegisteredRouter,
|
|
6
|
+
UseRouteContextBaseOptions,
|
|
7
|
+
UseRouteContextOptions,
|
|
8
|
+
UseRouteContextResult,
|
|
9
|
+
} from '@tanstack/router-core'
|
|
10
|
+
|
|
11
|
+
export type UseRouteContextRoute<out TFrom> = <
|
|
12
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
13
|
+
TSelected = unknown,
|
|
14
|
+
>(
|
|
15
|
+
opts?: UseRouteContextBaseOptions<TRouter, TFrom, true, TSelected>,
|
|
16
|
+
) => Vue.Ref<UseRouteContextResult<TRouter, TFrom, true, TSelected>>
|
|
17
|
+
|
|
18
|
+
export function useRouteContext<
|
|
19
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
20
|
+
const TFrom extends string | undefined = undefined,
|
|
21
|
+
TStrict extends boolean = true,
|
|
22
|
+
TSelected = unknown,
|
|
23
|
+
>(
|
|
24
|
+
opts: UseRouteContextOptions<TRouter, TFrom, TStrict, TSelected>,
|
|
25
|
+
): Vue.Ref<UseRouteContextResult<TRouter, TFrom, TStrict, TSelected>> {
|
|
26
|
+
return useMatch({
|
|
27
|
+
...(opts as any),
|
|
28
|
+
select: (match) =>
|
|
29
|
+
opts.select ? opts.select(match.context) : match.context,
|
|
30
|
+
}) as any
|
|
31
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as Vue from 'vue'
|
|
2
|
+
import warning from 'tiny-warning'
|
|
3
|
+
import { getRouterContext } from './routerContext'
|
|
4
|
+
import type { AnyRouter, RegisteredRouter } from '@tanstack/router-core'
|
|
5
|
+
|
|
6
|
+
export function useRouter<TRouter extends AnyRouter = RegisteredRouter>(opts?: {
|
|
7
|
+
warn?: boolean
|
|
8
|
+
}): TRouter {
|
|
9
|
+
const value = Vue.inject(getRouterContext() as any, null)
|
|
10
|
+
warning(
|
|
11
|
+
!((opts?.warn ?? true) && !value),
|
|
12
|
+
'useRouter must be used inside a <RouterProvider> component!',
|
|
13
|
+
)
|
|
14
|
+
return value as any
|
|
15
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { useStore } from '@tanstack/vue-store'
|
|
2
|
+
import * as Vue from 'vue'
|
|
3
|
+
import { useRouter } from './useRouter'
|
|
4
|
+
import type {
|
|
5
|
+
AnyRouter,
|
|
6
|
+
RegisteredRouter,
|
|
7
|
+
RouterState,
|
|
8
|
+
} from '@tanstack/router-core'
|
|
9
|
+
|
|
10
|
+
export type UseRouterStateOptions<TRouter extends AnyRouter, TSelected> = {
|
|
11
|
+
router?: TRouter
|
|
12
|
+
select?: (state: RouterState<TRouter['routeTree']>) => TSelected
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type UseRouterStateResult<
|
|
16
|
+
TRouter extends AnyRouter,
|
|
17
|
+
TSelected,
|
|
18
|
+
> = unknown extends TSelected ? RouterState<TRouter['routeTree']> : TSelected
|
|
19
|
+
|
|
20
|
+
export function useRouterState<
|
|
21
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
22
|
+
TSelected = unknown,
|
|
23
|
+
>(
|
|
24
|
+
opts?: UseRouterStateOptions<TRouter, TSelected>,
|
|
25
|
+
): Vue.Ref<UseRouterStateResult<TRouter, TSelected>> {
|
|
26
|
+
const contextRouter = useRouter<TRouter>({
|
|
27
|
+
warn: opts?.router === undefined,
|
|
28
|
+
})
|
|
29
|
+
const router = opts?.router || contextRouter
|
|
30
|
+
|
|
31
|
+
// Return a safe default if router is undefined
|
|
32
|
+
if (!router || !router.__store) {
|
|
33
|
+
return Vue.ref(undefined) as Vue.Ref<
|
|
34
|
+
UseRouterStateResult<TRouter, TSelected>
|
|
35
|
+
>
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return useStore(router.__store, (state) => {
|
|
39
|
+
if (opts?.select) return opts.select(state)
|
|
40
|
+
|
|
41
|
+
return state
|
|
42
|
+
}) as Vue.Ref<UseRouterStateResult<TRouter, TSelected>>
|
|
43
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { useMatch } from './useMatch'
|
|
2
|
+
import type * as Vue from 'vue'
|
|
3
|
+
import type {
|
|
4
|
+
AnyRouter,
|
|
5
|
+
RegisteredRouter,
|
|
6
|
+
ResolveUseSearch,
|
|
7
|
+
StrictOrFrom,
|
|
8
|
+
ThrowConstraint,
|
|
9
|
+
ThrowOrOptional,
|
|
10
|
+
UseSearchResult,
|
|
11
|
+
} from '@tanstack/router-core'
|
|
12
|
+
|
|
13
|
+
export interface UseSearchBaseOptions<
|
|
14
|
+
TRouter extends AnyRouter,
|
|
15
|
+
TFrom,
|
|
16
|
+
TStrict extends boolean,
|
|
17
|
+
TThrow extends boolean,
|
|
18
|
+
TSelected,
|
|
19
|
+
> {
|
|
20
|
+
select?: (state: ResolveUseSearch<TRouter, TFrom, TStrict>) => TSelected
|
|
21
|
+
shouldThrow?: TThrow
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type UseSearchOptions<
|
|
25
|
+
TRouter extends AnyRouter,
|
|
26
|
+
TFrom,
|
|
27
|
+
TStrict extends boolean,
|
|
28
|
+
TThrow extends boolean,
|
|
29
|
+
TSelected,
|
|
30
|
+
> = StrictOrFrom<TRouter, TFrom, TStrict> &
|
|
31
|
+
UseSearchBaseOptions<TRouter, TFrom, TStrict, TThrow, TSelected>
|
|
32
|
+
|
|
33
|
+
export type UseSearchRoute<out TFrom> = <
|
|
34
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
35
|
+
TSelected = unknown,
|
|
36
|
+
>(
|
|
37
|
+
opts?: UseSearchBaseOptions<
|
|
38
|
+
TRouter,
|
|
39
|
+
TFrom,
|
|
40
|
+
/* TStrict */ true,
|
|
41
|
+
/* TThrow */ true,
|
|
42
|
+
TSelected
|
|
43
|
+
>,
|
|
44
|
+
) => Vue.Ref<UseSearchResult<TRouter, TFrom, true, TSelected>>
|
|
45
|
+
|
|
46
|
+
export function useSearch<
|
|
47
|
+
TRouter extends AnyRouter = RegisteredRouter,
|
|
48
|
+
const TFrom extends string | undefined = undefined,
|
|
49
|
+
TStrict extends boolean = true,
|
|
50
|
+
TThrow extends boolean = true,
|
|
51
|
+
TSelected = unknown,
|
|
52
|
+
>(
|
|
53
|
+
opts: UseSearchOptions<
|
|
54
|
+
TRouter,
|
|
55
|
+
TFrom,
|
|
56
|
+
TStrict,
|
|
57
|
+
ThrowConstraint<TStrict, TThrow>,
|
|
58
|
+
TSelected
|
|
59
|
+
>,
|
|
60
|
+
): Vue.Ref<
|
|
61
|
+
ThrowOrOptional<UseSearchResult<TRouter, TFrom, TStrict, TSelected>, TThrow>
|
|
62
|
+
> {
|
|
63
|
+
return useMatch({
|
|
64
|
+
from: opts.from!,
|
|
65
|
+
strict: opts.strict,
|
|
66
|
+
shouldThrow: opts.shouldThrow,
|
|
67
|
+
select: (match: any) => {
|
|
68
|
+
return opts.select ? opts.select(match.search) : match.search
|
|
69
|
+
},
|
|
70
|
+
}) as any
|
|
71
|
+
}
|
package/src/utils.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import * as Vue from 'vue'
|
|
2
|
+
|
|
3
|
+
export const useLayoutEffect =
|
|
4
|
+
typeof window !== 'undefined' ? Vue.effect : Vue.effect
|
|
5
|
+
|
|
6
|
+
export const usePrevious = (fn: () => boolean) => {
|
|
7
|
+
return Vue.computed(
|
|
8
|
+
(
|
|
9
|
+
prev: { current: boolean | null; previous: boolean | null } = {
|
|
10
|
+
current: null,
|
|
11
|
+
previous: null,
|
|
12
|
+
},
|
|
13
|
+
) => {
|
|
14
|
+
const current = fn()
|
|
15
|
+
|
|
16
|
+
if (prev.current !== current) {
|
|
17
|
+
prev.previous = prev.current
|
|
18
|
+
prev.current = current
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return prev
|
|
22
|
+
},
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* React hook to wrap `IntersectionObserver`.
|
|
28
|
+
*
|
|
29
|
+
* This hook will create an `IntersectionObserver` and observe the ref passed to it.
|
|
30
|
+
*
|
|
31
|
+
* When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.
|
|
32
|
+
*
|
|
33
|
+
* @param ref - The ref to observe
|
|
34
|
+
* @param intersectionObserverOptions - The options to pass to the IntersectionObserver
|
|
35
|
+
* @param options - The options to pass to the hook
|
|
36
|
+
* @param callback - The callback to call when the intersection changes
|
|
37
|
+
* @returns The IntersectionObserver instance
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* const MyComponent = () => {
|
|
41
|
+
* const ref = React.useRef<HTMLDivElement>(null)
|
|
42
|
+
* useIntersectionObserver(
|
|
43
|
+
* ref,
|
|
44
|
+
* (entry) => { doSomething(entry) },
|
|
45
|
+
* { rootMargin: '10px' },
|
|
46
|
+
* { disabled: false }
|
|
47
|
+
* )
|
|
48
|
+
* return <div ref={ref} />
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export function useIntersectionObserver<T extends Element>(
|
|
52
|
+
ref: Vue.Ref<T | null>,
|
|
53
|
+
callback: (entry: IntersectionObserverEntry | undefined) => void,
|
|
54
|
+
intersectionObserverOptions: IntersectionObserverInit = {},
|
|
55
|
+
options: { disabled?: boolean | (() => boolean) } = {},
|
|
56
|
+
): Vue.Ref<IntersectionObserver | null> {
|
|
57
|
+
const isIntersectionObserverAvailable =
|
|
58
|
+
typeof IntersectionObserver === 'function'
|
|
59
|
+
const observerRef = Vue.ref<IntersectionObserver | null>(null)
|
|
60
|
+
|
|
61
|
+
// Use watchEffect with cleanup to properly manage the observer lifecycle
|
|
62
|
+
Vue.watchEffect((onCleanup) => {
|
|
63
|
+
const r = ref.value
|
|
64
|
+
// Support both static boolean and function for disabled check
|
|
65
|
+
const isDisabled =
|
|
66
|
+
typeof options.disabled === 'function'
|
|
67
|
+
? options.disabled()
|
|
68
|
+
: options.disabled
|
|
69
|
+
if (!r || !isIntersectionObserverAvailable || isDisabled) {
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const observer = new IntersectionObserver(([entry]) => {
|
|
74
|
+
callback(entry)
|
|
75
|
+
}, intersectionObserverOptions)
|
|
76
|
+
|
|
77
|
+
observerRef.value = observer
|
|
78
|
+
observer.observe(r)
|
|
79
|
+
|
|
80
|
+
onCleanup(() => {
|
|
81
|
+
observer.disconnect()
|
|
82
|
+
observerRef.value = null
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
return observerRef
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function splitProps<T extends Record<string, any>>(
|
|
90
|
+
props: T,
|
|
91
|
+
keys: Array<keyof T>,
|
|
92
|
+
) {
|
|
93
|
+
// Get the specified props
|
|
94
|
+
const selectedProps = Vue.computed(() => {
|
|
95
|
+
return Object.fromEntries(keys.map((key) => [key, props[key]]))
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
// Get remaining props as attrs
|
|
99
|
+
const remainingAttrs = Vue.computed(() => {
|
|
100
|
+
const attrs = Vue.useAttrs()
|
|
101
|
+
return Object.fromEntries(
|
|
102
|
+
Object.entries(attrs).filter(([key]) => !keys.includes(key as keyof T)),
|
|
103
|
+
)
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
return [selectedProps, remainingAttrs]
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type ParentProps<T = {}> = T & {
|
|
110
|
+
children?: Vue.VNode | Array<Vue.VNode> | string
|
|
111
|
+
}
|