@tanstack/react-router 1.28.7 → 1.28.9
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/RouterProvider.cjs +55 -59
- package/dist/cjs/RouterProvider.cjs.map +1 -1
- package/dist/cjs/RouterProvider.d.cts +4 -0
- package/dist/cjs/link.cjs +22 -7
- package/dist/cjs/link.cjs.map +1 -1
- package/dist/cjs/link.d.cts +3 -0
- package/dist/cjs/router.cjs +42 -44
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/router.d.cts +5 -2
- package/dist/esm/RouterProvider.d.ts +4 -0
- package/dist/esm/RouterProvider.js +55 -59
- package/dist/esm/RouterProvider.js.map +1 -1
- package/dist/esm/link.d.ts +3 -0
- package/dist/esm/link.js +22 -7
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/router.d.ts +5 -2
- package/dist/esm/router.js +42 -44
- package/dist/esm/router.js.map +1 -1
- package/package.json +2 -2
- package/src/RouterProvider.tsx +82 -71
- package/src/link.tsx +30 -8
- package/src/router.ts +70 -56
|
@@ -24,15 +24,6 @@ function _interopNamespaceDefault(e) {
|
|
|
24
24
|
return Object.freeze(n);
|
|
25
25
|
}
|
|
26
26
|
const React__namespace = /* @__PURE__ */ _interopNamespaceDefault(React);
|
|
27
|
-
const useTransition = (
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
29
|
-
React__namespace.useTransition || (() => [
|
|
30
|
-
false,
|
|
31
|
-
(cb) => {
|
|
32
|
-
cb();
|
|
33
|
-
}
|
|
34
|
-
])
|
|
35
|
-
);
|
|
36
27
|
function RouterProvider({ router, ...rest }) {
|
|
37
28
|
router.update({
|
|
38
29
|
...router.options,
|
|
@@ -59,31 +50,20 @@ function Transitioner() {
|
|
|
59
50
|
const routerState = useRouterState.useRouterState({
|
|
60
51
|
select: (s) => utils.pick(s, ["isLoading", "location", "resolvedLocation", "isTransitioning"])
|
|
61
52
|
});
|
|
62
|
-
const [isTransitioning,
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
}, [isTransitioning, router]);
|
|
53
|
+
const [isTransitioning, startReactTransition_] = React__namespace.useTransition();
|
|
54
|
+
const hasPendingMatches = useRouterState.useRouterState({
|
|
55
|
+
select: (s) => s.matches.some((d) => d.status === "pending")
|
|
56
|
+
});
|
|
57
|
+
const previousIsLoading = usePrevious(routerState.isLoading);
|
|
58
|
+
const isAnyPending = routerState.isLoading || isTransitioning || hasPendingMatches;
|
|
59
|
+
const previousIsAnyPending = usePrevious(isAnyPending);
|
|
60
|
+
router.startReactTransition = startReactTransition_;
|
|
72
61
|
const tryLoad = () => {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
apply(() => {
|
|
81
|
-
try {
|
|
82
|
-
router.load();
|
|
83
|
-
} catch (err) {
|
|
84
|
-
console.error(err);
|
|
85
|
-
}
|
|
86
|
-
});
|
|
62
|
+
try {
|
|
63
|
+
router.load();
|
|
64
|
+
} catch (err) {
|
|
65
|
+
console.error(err);
|
|
66
|
+
}
|
|
87
67
|
};
|
|
88
68
|
utils.useLayoutEffect(() => {
|
|
89
69
|
const unsub = router.history.subscribe(() => {
|
|
@@ -107,42 +87,51 @@ function Transitioner() {
|
|
|
107
87
|
};
|
|
108
88
|
}, [router, router.history]);
|
|
109
89
|
utils.useLayoutEffect(() => {
|
|
110
|
-
if (
|
|
90
|
+
if (window.__TSR_DEHYDRATED__ || mountLoadForRouter.current.router === router && mountLoadForRouter.current.mounted) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
mountLoadForRouter.current = { router, mounted: true };
|
|
94
|
+
tryLoad();
|
|
95
|
+
}, [router]);
|
|
96
|
+
utils.useLayoutEffect(() => {
|
|
97
|
+
if (previousIsLoading && !routerState.isLoading) {
|
|
98
|
+
const toLocation = router.state.location;
|
|
99
|
+
const fromLocation = router.state.resolvedLocation;
|
|
100
|
+
const pathChanged = fromLocation.href !== toLocation.href;
|
|
101
|
+
router.emit({
|
|
102
|
+
type: "onLoad",
|
|
103
|
+
fromLocation,
|
|
104
|
+
toLocation,
|
|
105
|
+
pathChanged
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}, [previousIsLoading, router, routerState.isLoading]);
|
|
109
|
+
utils.useLayoutEffect(() => {
|
|
110
|
+
if (previousIsAnyPending && !isAnyPending) {
|
|
111
|
+
const toLocation = router.state.location;
|
|
112
|
+
const fromLocation = router.state.resolvedLocation;
|
|
113
|
+
const pathChanged = fromLocation.href !== toLocation.href;
|
|
111
114
|
router.emit({
|
|
112
115
|
type: "onResolved",
|
|
113
|
-
fromLocation
|
|
114
|
-
toLocation
|
|
115
|
-
pathChanged
|
|
116
|
+
fromLocation,
|
|
117
|
+
toLocation,
|
|
118
|
+
pathChanged
|
|
116
119
|
});
|
|
120
|
+
router.__store.setState((s) => ({
|
|
121
|
+
...s,
|
|
122
|
+
status: "idle",
|
|
123
|
+
resolvedLocation: s.location
|
|
124
|
+
}));
|
|
117
125
|
if (document.querySelector) {
|
|
118
|
-
if (
|
|
119
|
-
const el = document.getElementById(
|
|
126
|
+
if (router.state.location.hash !== "") {
|
|
127
|
+
const el = document.getElementById(router.state.location.hash);
|
|
120
128
|
if (el) {
|
|
121
129
|
el.scrollIntoView();
|
|
122
130
|
}
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
|
-
router.__store.setState((s) => ({
|
|
126
|
-
...s,
|
|
127
|
-
isTransitioning: false,
|
|
128
|
-
resolvedLocation: s.location
|
|
129
|
-
}));
|
|
130
133
|
}
|
|
131
|
-
}, [
|
|
132
|
-
routerState.isTransitioning,
|
|
133
|
-
isTransitioning,
|
|
134
|
-
routerState.isLoading,
|
|
135
|
-
routerState.resolvedLocation,
|
|
136
|
-
routerState.location,
|
|
137
|
-
router
|
|
138
|
-
]);
|
|
139
|
-
utils.useLayoutEffect(() => {
|
|
140
|
-
if (window.__TSR_DEHYDRATED__ || mountLoadForRouter.current.router === router && mountLoadForRouter.current.mounted) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
mountLoadForRouter.current = { router, mounted: true };
|
|
144
|
-
tryLoad();
|
|
145
|
-
}, [router]);
|
|
134
|
+
}, [isAnyPending, previousIsAnyPending, router]);
|
|
146
135
|
return null;
|
|
147
136
|
}
|
|
148
137
|
function getRouteMatch(state, id) {
|
|
@@ -152,6 +141,13 @@ function getRouteMatch(state, id) {
|
|
|
152
141
|
...state.matches
|
|
153
142
|
].find((d) => d.id === id);
|
|
154
143
|
}
|
|
144
|
+
function usePrevious(value) {
|
|
145
|
+
const ref = React__namespace.useRef(value);
|
|
146
|
+
React__namespace.useEffect(() => {
|
|
147
|
+
ref.current = value;
|
|
148
|
+
});
|
|
149
|
+
return ref.current;
|
|
150
|
+
}
|
|
155
151
|
exports.RouterProvider = RouterProvider;
|
|
156
152
|
exports.getRouteMatch = getRouteMatch;
|
|
157
153
|
//# sourceMappingURL=RouterProvider.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouterProvider.cjs","sources":["../../src/RouterProvider.tsx"],"sourcesContent":["import * as React from 'react'\nimport { Matches } from './Matches'\nimport { pick, useLayoutEffect } from './utils'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport { getRouterContext } from './routerContext'\nimport type { NavigateOptions, ToOptions } from './link'\nimport type { ParsedLocation } from './location'\nimport type { AnyRoute } from './route'\nimport type { RoutePaths } from './routeInfo'\nimport type {\n RegisteredRouter,\n Router,\n RouterOptions,\n RouterState,\n} from './router'\n\nimport type { RouteMatch } from './Matches'\n\nconst useTransition =\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n React.useTransition ||\n (() => [\n false,\n (cb) => {\n cb()\n },\n ])\n\nexport interface CommitLocationOptions {\n replace?: boolean\n resetScroll?: boolean\n startTransition?: boolean\n}\n\nexport interface MatchLocation {\n to?: string | number | null\n fuzzy?: boolean\n caseSensitive?: boolean\n from?: string\n}\n\nexport type NavigateFn = <\n TTo extends string,\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n opts: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => Promise<void>\n\nexport type BuildLocationFn<TRouteTree extends AnyRoute> = <\n TTo extends string,\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n opts: ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n leaveParams?: boolean\n },\n) => ParsedLocation\n\nexport type InjectedHtmlEntry = string | (() => Promise<string> | string)\n\nexport function RouterProvider<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TDehydrated extends Record<string, any> = Record<string, any>,\n>({ router, ...rest }: RouterProps<TRouteTree, TDehydrated>) {\n // Allow the router to update options on the router instance\n router.update({\n ...router.options,\n ...rest,\n context: {\n ...router.options.context,\n ...rest.context,\n },\n } as any)\n\n const matches = router.options.InnerWrap ? (\n <router.options.InnerWrap>\n <Matches />\n </router.options.InnerWrap>\n ) : (\n <Matches />\n )\n\n const routerContext = getRouterContext()\n\n const provider = (\n <React.Suspense fallback={null}>\n <routerContext.Provider value={router}>\n {matches}\n <Transitioner />\n </routerContext.Provider>\n </React.Suspense>\n )\n\n if (router.options.Wrap) {\n return <router.options.Wrap>{provider}</router.options.Wrap>\n }\n\n return provider\n}\n\nfunction Transitioner() {\n const router = useRouter()\n const mountLoadForRouter = React.useRef({ router, mounted: false })\n const routerState = useRouterState({\n select: (s) =>\n pick(s, ['isLoading', 'location', 'resolvedLocation', 'isTransitioning']),\n })\n\n const [isTransitioning, startReactTransition] = useTransition()\n\n router.startReactTransition = startReactTransition\n\n React.useEffect(() => {\n if (isTransitioning) {\n router.__store.setState((s) => ({\n ...s,\n isTransitioning,\n }))\n }\n }, [isTransitioning, router])\n\n const tryLoad = () => {\n const apply = (cb: () => void) => {\n if (!routerState.isTransitioning) {\n startReactTransition(() => cb())\n } else {\n cb()\n }\n }\n\n apply(() => {\n try {\n router.load()\n } catch (err) {\n console.error(err)\n }\n })\n }\n\n useLayoutEffect(() => {\n const unsub = router.history.subscribe(() => {\n router.latestLocation = router.parseLocation(router.latestLocation)\n if (router.state.location !== router.latestLocation) {\n tryLoad()\n }\n })\n\n const nextLocation = router.buildLocation({\n to: router.latestLocation.pathname,\n search: true,\n params: true,\n hash: true,\n state: true,\n })\n\n if (routerState.location.href !== nextLocation.href) {\n router.commitLocation({ ...nextLocation, replace: true })\n }\n\n return () => {\n unsub()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [router, router.history])\n\n useLayoutEffect(() => {\n if (\n (React.useTransition as any)\n ? routerState.isTransitioning && !isTransitioning\n : !routerState.isLoading &&\n routerState.resolvedLocation !== routerState.location\n ) {\n router.emit({\n type: 'onResolved',\n fromLocation: routerState.resolvedLocation,\n toLocation: routerState.location,\n pathChanged:\n routerState.location.href !== routerState.resolvedLocation.href,\n })\n\n if ((document as any).querySelector) {\n if (routerState.location.hash !== '') {\n const el = document.getElementById(routerState.location.hash)\n if (el) {\n el.scrollIntoView()\n }\n }\n }\n\n router.__store.setState((s) => ({\n ...s,\n isTransitioning: false,\n resolvedLocation: s.location,\n }))\n }\n }, [\n routerState.isTransitioning,\n isTransitioning,\n routerState.isLoading,\n routerState.resolvedLocation,\n routerState.location,\n router,\n ])\n\n useLayoutEffect(() => {\n if (\n window.__TSR_DEHYDRATED__ ||\n (mountLoadForRouter.current.router === router &&\n mountLoadForRouter.current.mounted)\n ) {\n return\n }\n mountLoadForRouter.current = { router, mounted: true }\n tryLoad()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [router])\n\n return null\n}\n\nexport function getRouteMatch<TRouteTree extends AnyRoute>(\n state: RouterState<TRouteTree>,\n id: string,\n): undefined | RouteMatch<TRouteTree> {\n return [\n ...state.cachedMatches,\n ...(state.pendingMatches ?? []),\n ...state.matches,\n ].find((d) => d.id === id)\n}\n\nexport type RouterProps<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TDehydrated extends Record<string, any> = Record<string, any>,\n> = Omit<RouterOptions<TRouteTree, TDehydrated>, 'context'> & {\n router: Router<TRouteTree>\n context?: Partial<RouterOptions<TRouteTree, TDehydrated>['context']>\n}\n"],"names":["React","jsx","Matches","routerContext","getRouterContext","jsxs","useRouter","useRouterState","pick","useLayoutEffect"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"RouterProvider.cjs","sources":["../../src/RouterProvider.tsx"],"sourcesContent":["import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport { Matches } from './Matches'\nimport { pick, useLayoutEffect } from './utils'\nimport { useRouter } from './useRouter'\nimport { useRouterState } from './useRouterState'\nimport { getRouterContext } from './routerContext'\nimport type { NavigateOptions, ToOptions } from './link'\nimport type { ParsedLocation } from './location'\nimport type { AnyRoute } from './route'\nimport type { RoutePaths } from './routeInfo'\nimport type {\n RegisteredRouter,\n Router,\n RouterOptions,\n RouterState,\n} from './router'\n\nimport type { RouteMatch } from './Matches'\n\nexport interface CommitLocationOptions {\n replace?: boolean\n resetScroll?: boolean\n viewTransition?: boolean\n /**\n * @deprecated All navigations use React transitions under the hood now\n **/\n startTransition?: boolean\n}\n\nexport interface MatchLocation {\n to?: string | number | null\n fuzzy?: boolean\n caseSensitive?: boolean\n from?: string\n}\n\nexport type NavigateFn = <\n TTo extends string,\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n opts: NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n) => Promise<void>\n\nexport type BuildLocationFn<TRouteTree extends AnyRoute> = <\n TTo extends string,\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n opts: ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n leaveParams?: boolean\n },\n) => ParsedLocation\n\nexport type InjectedHtmlEntry = string | (() => Promise<string> | string)\n\nexport function RouterProvider<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TDehydrated extends Record<string, any> = Record<string, any>,\n>({ router, ...rest }: RouterProps<TRouteTree, TDehydrated>) {\n // Allow the router to update options on the router instance\n router.update({\n ...router.options,\n ...rest,\n context: {\n ...router.options.context,\n ...rest.context,\n },\n } as any)\n\n const matches = router.options.InnerWrap ? (\n <router.options.InnerWrap>\n <Matches />\n </router.options.InnerWrap>\n ) : (\n <Matches />\n )\n\n const routerContext = getRouterContext()\n\n const provider = (\n <React.Suspense fallback={null}>\n <routerContext.Provider value={router}>\n {matches}\n <Transitioner />\n </routerContext.Provider>\n </React.Suspense>\n )\n\n if (router.options.Wrap) {\n return <router.options.Wrap>{provider}</router.options.Wrap>\n }\n\n return provider\n}\n\nfunction Transitioner() {\n const router = useRouter()\n const mountLoadForRouter = React.useRef({ router, mounted: false })\n const routerState = useRouterState({\n select: (s) =>\n pick(s, ['isLoading', 'location', 'resolvedLocation', 'isTransitioning']),\n })\n\n const [isTransitioning, startReactTransition_] = React.useTransition()\n // Track pending state changes\n const hasPendingMatches = useRouterState({\n select: (s) => s.matches.some((d) => d.status === 'pending'),\n })\n\n const previousIsLoading = usePrevious(routerState.isLoading)\n\n const isAnyPending =\n routerState.isLoading || isTransitioning || hasPendingMatches\n const previousIsAnyPending = usePrevious(isAnyPending)\n\n router.startReactTransition = startReactTransition_\n\n const tryLoad = () => {\n try {\n router.load()\n } catch (err) {\n console.error(err)\n }\n }\n\n // Subscribe to location changes\n // and try to load the new location\n useLayoutEffect(() => {\n const unsub = router.history.subscribe(() => {\n router.latestLocation = router.parseLocation(router.latestLocation)\n if (router.state.location !== router.latestLocation) {\n tryLoad()\n }\n })\n\n const nextLocation = router.buildLocation({\n to: router.latestLocation.pathname,\n search: true,\n params: true,\n hash: true,\n state: true,\n })\n\n if (routerState.location.href !== nextLocation.href) {\n router.commitLocation({ ...nextLocation, replace: true })\n }\n\n return () => {\n unsub()\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [router, router.history])\n\n // Try to load the initial location\n useLayoutEffect(() => {\n if (\n window.__TSR_DEHYDRATED__ ||\n (mountLoadForRouter.current.router === router &&\n mountLoadForRouter.current.mounted)\n ) {\n return\n }\n mountLoadForRouter.current = { router, mounted: true }\n tryLoad()\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [router])\n\n useLayoutEffect(() => {\n // The router was loading and now it's not\n if (previousIsLoading && !routerState.isLoading) {\n const toLocation = router.state.location\n const fromLocation = router.state.resolvedLocation\n const pathChanged = fromLocation.href !== toLocation.href\n\n router.emit({\n type: 'onLoad',\n fromLocation,\n toLocation,\n pathChanged,\n })\n\n // if (router.viewTransitionPromise) {\n // console.log('resolving view transition promise')\n // }\n\n // router.viewTransitionPromise?.resolve(true)\n }\n }, [previousIsLoading, router, routerState.isLoading])\n\n useLayoutEffect(() => {\n // The router was pending and now it's not\n if (previousIsAnyPending && !isAnyPending) {\n const toLocation = router.state.location\n const fromLocation = router.state.resolvedLocation\n const pathChanged = fromLocation.href !== toLocation.href\n\n router.emit({\n type: 'onResolved',\n fromLocation,\n toLocation,\n pathChanged,\n })\n\n router.__store.setState((s) => ({\n ...s,\n status: 'idle',\n resolvedLocation: s.location,\n }))\n\n if ((document as any).querySelector) {\n if (router.state.location.hash !== '') {\n const el = document.getElementById(router.state.location.hash)\n if (el) {\n el.scrollIntoView()\n }\n }\n }\n }\n }, [isAnyPending, previousIsAnyPending, router])\n\n return null\n}\n\nexport function getRouteMatch<TRouteTree extends AnyRoute>(\n state: RouterState<TRouteTree>,\n id: string,\n): undefined | RouteMatch<TRouteTree> {\n return [\n ...state.cachedMatches,\n ...(state.pendingMatches ?? []),\n ...state.matches,\n ].find((d) => d.id === id)\n}\n\nexport type RouterProps<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TDehydrated extends Record<string, any> = Record<string, any>,\n> = Omit<RouterOptions<TRouteTree, TDehydrated>, 'context'> & {\n router: Router<TRouteTree>\n context?: Partial<RouterOptions<TRouteTree, TDehydrated>['context']>\n}\n\nfunction usePrevious<T>(value: T) {\n const ref = React.useRef<T>(value)\n React.useEffect(() => {\n ref.current = value\n })\n return ref.current\n}\n"],"names":["jsx","Matches","routerContext","getRouterContext","React","jsxs","useRouter","useRouterState","pick","useLayoutEffect"],"mappings":"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"}
|
|
@@ -8,6 +8,10 @@ import type { RouteMatch } from './Matches.cjs';
|
|
|
8
8
|
export interface CommitLocationOptions {
|
|
9
9
|
replace?: boolean;
|
|
10
10
|
resetScroll?: boolean;
|
|
11
|
+
viewTransition?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated All navigations use React transitions under the hood now
|
|
14
|
+
**/
|
|
11
15
|
startTransition?: boolean;
|
|
12
16
|
}
|
|
13
17
|
export interface MatchLocation {
|
package/dist/cjs/link.cjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const jsxRuntime = require("react/jsx-runtime");
|
|
4
4
|
const React = require("react");
|
|
5
|
+
const reactDom = require("react-dom");
|
|
5
6
|
const Matches = require("./Matches.cjs");
|
|
6
7
|
const useRouterState = require("./useRouterState.cjs");
|
|
7
8
|
const useRouter = require("./useRouter.cjs");
|
|
@@ -30,6 +31,7 @@ function useLinkProps(options) {
|
|
|
30
31
|
strict: false,
|
|
31
32
|
select: (s) => s.pathname
|
|
32
33
|
});
|
|
34
|
+
const [isTransitioning, setIsTransitioning] = React__namespace.useState(false);
|
|
33
35
|
const {
|
|
34
36
|
// custom props
|
|
35
37
|
activeProps = () => ({ className: "active" }),
|
|
@@ -46,6 +48,7 @@ function useLinkProps(options) {
|
|
|
46
48
|
replace,
|
|
47
49
|
startTransition,
|
|
48
50
|
resetScroll,
|
|
51
|
+
viewTransition,
|
|
49
52
|
// element props
|
|
50
53
|
children,
|
|
51
54
|
target,
|
|
@@ -105,15 +108,26 @@ function useLinkProps(options) {
|
|
|
105
108
|
const handleClick = (e) => {
|
|
106
109
|
if (!disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!target || target === "_self") && e.button === 0) {
|
|
107
110
|
e.preventDefault();
|
|
108
|
-
|
|
111
|
+
reactDom.flushSync(() => {
|
|
112
|
+
setIsTransitioning(true);
|
|
113
|
+
});
|
|
114
|
+
const unsub = router.subscribe("onResolved", () => {
|
|
115
|
+
unsub();
|
|
116
|
+
setIsTransitioning(false);
|
|
117
|
+
});
|
|
118
|
+
router.commitLocation({
|
|
119
|
+
...next,
|
|
120
|
+
replace,
|
|
121
|
+
resetScroll,
|
|
122
|
+
startTransition,
|
|
123
|
+
viewTransition
|
|
124
|
+
});
|
|
109
125
|
}
|
|
110
126
|
};
|
|
111
127
|
const doPreload = () => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
console.warn(preloadWarning);
|
|
116
|
-
});
|
|
128
|
+
router.preloadRoute(dest).catch((err) => {
|
|
129
|
+
console.warn(err);
|
|
130
|
+
console.warn(preloadWarning);
|
|
117
131
|
});
|
|
118
132
|
};
|
|
119
133
|
const handleFocus = (e) => {
|
|
@@ -185,7 +199,8 @@ function useLinkProps(options) {
|
|
|
185
199
|
role: "link",
|
|
186
200
|
"aria-disabled": true
|
|
187
201
|
},
|
|
188
|
-
...isActive && { "data-status": "active", "aria-current": "page" }
|
|
202
|
+
...isActive && { "data-status": "active", "aria-current": "page" },
|
|
203
|
+
...isTransitioning && { "data-transitioning": "transitioning" }
|
|
189
204
|
};
|
|
190
205
|
}
|
|
191
206
|
function createLink(Comp) {
|
package/dist/cjs/link.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.cjs","sources":["../../src/link.tsx"],"sourcesContent":["import * as React from 'react'\nimport { useMatch } from './Matches'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport { deepEqual, exactPathTest, functionalUpdate } from './utils'\nimport type { ParsedLocation } from '.'\nimport type { HistoryState } from '@tanstack/history'\nimport type { Trim } from './fileRoute'\nimport type { AnyRoute, RootSearchSchema } from './route'\nimport type {\n RouteByPath,\n RoutePaths,\n RoutePathsAutoComplete,\n} from './routeInfo'\nimport type { RegisteredRouter } from './router'\nimport type {\n Expand,\n IsUnion,\n MakeDifferenceOptional,\n NoInfer,\n NonNullableUpdater,\n PickRequired,\n Updater,\n WithoutEmpty,\n} from './utils'\n\nexport type CleanPath<T extends string> = T extends `${infer L}//${infer R}`\n ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>\n : T extends `${infer L}//`\n ? `${CleanPath<L>}/`\n : T extends `//${infer L}`\n ? `/${CleanPath<L>}`\n : T\n\nexport type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown\n ? string extends TValue\n ? Array<string>\n : TValue extends string\n ? CleanPath<TValue> extends ''\n ? []\n : TIncludeTrailingSlash extends true\n ? CleanPath<TValue> extends `${infer T}/`\n ? [...Split<T>, '/']\n : CleanPath<TValue> extends `/${infer U}`\n ? Split<U>\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : [TValue]\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : TValue extends string\n ? [TValue]\n : never\n : never\n : never\n\nexport type ParsePathParams<T extends string> = keyof {\n [K in Trim<Split<T>[number], '_'> as K extends `$${infer L}`\n ? L extends ''\n ? '_splat'\n : L\n : never]: K\n}\n\nexport type Join<T, TDelimiter extends string = '/'> = T extends []\n ? ''\n : T extends [infer L extends string]\n ? L\n : T extends [\n infer L extends string,\n ...infer Tail extends [...Array<string>],\n ]\n ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>\n : never\n\nexport type Last<T extends Array<any>> = T extends [...infer _, infer L]\n ? L\n : never\n\nexport type RemoveTrailingSlashes<T> = T extends `${infer R}/`\n ? RemoveTrailingSlashes<R>\n : T\n\nexport type RemoveLeadingSlashes<T> = T extends `/${infer R}`\n ? RemoveLeadingSlashes<R>\n : T\n\nexport type ResolvePaths<TRouteTree extends AnyRoute, TSearchPath> =\n RouteByPath<TRouteTree, RemoveTrailingSlashes<TSearchPath>> extends never\n ? RoutePaths<TRouteTree>\n : RoutePaths<RouteByPath<TRouteTree, RemoveTrailingSlashes<TSearchPath>>>\n\nexport type SearchPaths<\n TRouteTree extends AnyRoute,\n TSearchPath extends string,\n TPaths = ResolvePaths<TRouteTree, TSearchPath>,\n> = TPaths extends `${RemoveTrailingSlashes<TSearchPath>}/${infer TRest}`\n ? TRest\n : never\n\nexport type SearchRelativePathAutoComplete<\n TRouteTree extends AnyRoute,\n TTo extends string,\n TSearchPath extends string,\n> = `${TTo}/${SearchPaths<TRouteTree, TSearchPath>}`\n\nexport type RelativeToParentPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\n> =\n | SearchRelativePathAutoComplete<TRouteTree, TTo, TResolvedPath>\n | (TResolvedPath extends '' ? never : `${TTo}/../`)\n\nexport type RelativeToCurrentPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n TRestTo extends string,\n TResolvedPath extends\n string = RemoveTrailingSlashes<`${RemoveTrailingSlashes<TFrom>}/${RemoveLeadingSlashes<TRestTo>}`>,\n> = SearchRelativePathAutoComplete<TRouteTree, TTo, TResolvedPath>\n\nexport type AbsolutePathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n> =\n | (string extends TFrom\n ? './'\n : TFrom extends `/`\n ? never\n : SearchPaths<TRouteTree, TFrom> extends ''\n ? never\n : './')\n | (string extends TFrom ? '../' : TFrom extends `/` ? never : '../')\n | RoutePaths<TRouteTree>\n | (TFrom extends '/' ? never : SearchPaths<TRouteTree, TFrom>)\n\nexport type RelativeToPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n> = TTo extends `..${string}`\n ? RelativeToParentPathAutoComplete<\n TRouteTree,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : TTo extends `./${infer TRestTTo}`\n ? RelativeToCurrentPathAutoComplete<\n TRouteTree,\n TFrom,\n RemoveTrailingSlashes<TTo>,\n TRestTTo\n >\n : AbsolutePathAutoComplete<TRouteTree, TFrom>\n\nexport type NavigateOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.\n replace?: boolean\n resetScroll?: boolean\n // If set to `true`, the link's underlying navigate() call will be wrapped in a `React.startTransition` call. Defaults to `true`.\n startTransition?: boolean\n}\n\nexport type ToOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ToSubOptions<TRouteTree, TFrom, TTo> & {\n _fromLocation?: ParsedLocation\n mask?: ToMaskOptions<TRouteTree, TMaskFrom, TMaskTo>\n}\n\nexport type ToMaskOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TMaskFrom extends RoutePaths<TRouteTree> | string = string,\n TMaskTo extends string = '',\n> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {\n unmaskOnReload?: boolean\n}\n\nexport type ToSubOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n> = {\n to?: ToPathOption<TRouteTree, TFrom, TTo> & {}\n hash?: true | Updater<string>\n state?: true | NonNullableUpdater<HistoryState>\n // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required\n from?: RoutePathsAutoComplete<TRouteTree, TFrom> & {}\n // // When using relative route paths, this option forces resolution from the current path, instead of the route API's path or `from` path\n} & SearchParamOptions<TRouteTree, TFrom, TTo> &\n PathParamOptions<TRouteTree, TFrom, TTo>\n\ntype ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)\n\ntype ParamVariant = 'PATH' | 'SEARCH'\n\ntype ExcludeRootSearchSchema<T, TExcluded = Exclude<T, RootSearchSchema>> = [\n TExcluded,\n] extends [never]\n ? {}\n : TExcluded\n\nexport type ResolveRoute<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo,\n TPath = RemoveTrailingSlashes<\n string extends TFrom\n ? TTo\n : string extends TTo\n ? TFrom\n : ResolveRelativePath<TFrom, TTo>\n >,\n> = TPath extends string\n ? RouteByPath<TRouteTree, `${TPath}/`> extends never\n ? RouteByPath<TRouteTree, TPath>\n : RouteByPath<TRouteTree, `${TPath}/`>\n : never\n\ntype PostProcessParams<\n T,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'SEARCH' ? ExcludeRootSearchSchema<T> : T\n\ntype ResolveFromParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TFromRouteType extends\n | 'allParams'\n | 'fullSearchSchema' = TParamVariant extends 'PATH'\n ? 'allParams'\n : 'fullSearchSchema',\n> = PostProcessParams<\n RouteByPath<TRouteTree, TFrom>['types'][TFromRouteType],\n TParamVariant\n>\n\ntype ResolveToParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TRoute extends AnyRoute = ResolveRoute<TRouteTree, TFrom, TTo>,\n> = PostProcessParams<\n TRoute['types'][TParamVariant extends 'PATH'\n ? 'allParams'\n : 'fullSearchSchemaInput'],\n TParamVariant\n>\n\ntype ResolveRelativeToParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TToParams = ResolveToParams<TRouteTree, TParamVariant, TFrom, TTo>,\n> = TParamVariant extends 'SEARCH'\n ? TToParams\n : string extends TFrom\n ? TToParams\n : MakeDifferenceOptional<\n ResolveFromParams<TRouteTree, TParamVariant, TFrom>,\n TToParams\n >\n\ntype MakeOptionalParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = TParamVariant extends 'SEARCH'\n ? {\n search?:\n | true\n | (ParamsReducer<\n Expand<ResolveFromParams<TRouteTree, TParamVariant, TFrom>>,\n Expand<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n > & {})\n }\n : {\n params?:\n | true\n | (ParamsReducer<\n Expand<ResolveFromParams<TRouteTree, TParamVariant, TFrom>>,\n Expand<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n > & {})\n }\n\ntype MakeRequiredParamsReducer<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TToParams,\n TFromParams = ResolveFromParams<TRouteTree, TParamVariant, TFrom>,\n> =\n | ([TFromParams] extends [WithoutEmpty<PickRequired<TToParams>>]\n ? true\n : never)\n | ParamsReducer<Expand<TFromParams>, TToParams>\n\nexport type MakeRequiredParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = TParamVariant extends 'SEARCH'\n ? {\n search: Expand<\n MakeRequiredParamsReducer<\n TRouteTree,\n TParamVariant,\n TFrom,\n Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>\n >\n > & {}\n }\n : {\n params: Expand<\n MakeRequiredParamsReducer<\n TRouteTree,\n TParamVariant,\n TFrom,\n Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>\n >\n > & {}\n }\n\nexport type IsRequiredParams<TParams> = keyof TParams extends infer K extends\n keyof TParams\n ? K extends any\n ? undefined extends TParams[K]\n ? never\n : true\n : never\n : never\n\nexport type IsRequired<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = string extends TTo\n ? string extends TFrom\n ? never\n : IsRequiredParams<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n : IsRequiredParams<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n\nexport type ParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n TParamVariant extends ParamVariant,\n> =\n IsRequired<TRouteTree, TParamVariant, TFrom, TTo> extends never\n ? MakeOptionalParams<TRouteTree, TParamVariant, TFrom, TTo>\n : MakeRequiredParams<TRouteTree, TParamVariant, TFrom, TTo>\n\nexport type SearchParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n> = ParamOptions<TRouteTree, TFrom, TTo, 'SEARCH'>\n\nexport type PathParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n> = ParamOptions<TRouteTree, TFrom, TTo, 'PATH'>\n\nexport type ToPathOption<\n TRouteTree extends AnyRoute = AnyRoute,\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = string,\n> =\n | CheckPath<TRouteTree, TTo, never, TFrom, TTo>\n | RelativeToPathAutoComplete<\n TRouteTree,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n}\n\nexport type LinkOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // The standard anchor tag target attribute\n target?: HTMLAnchorElement['target']\n // Defaults to `{ exact: false, includeHash: false }`\n activeOptions?: ActiveOptions\n // If set, will preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.\n preload?: false | 'intent'\n // Delay intent preloading by this many milliseconds. If the intent exits before this delay, the preload will be cancelled.\n preloadDelay?: number\n // If true, will render the link without the href attribute\n disabled?: boolean\n}\n\nexport type CheckPath<TRouteTree extends AnyRoute, TPass, TFail, TFrom, TTo> =\n ResolveRoute<TRouteTree, TFrom, TTo> extends never ? TFail : TPass\n\nexport type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string\n ? TTo extends string\n ? TTo extends '.'\n ? TFrom\n : TTo extends `./`\n ? Join<[TFrom, '/']>\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : TTo extends `/${infer TRest}`\n ? TTo\n : Split<TTo> extends ['..', ...infer ToRest]\n ? Split<TFrom> extends [...infer FromRest, infer FromTail]\n ? ToRest extends ['/']\n ? Join<['/', ...FromRest, '/']>\n : ResolveRelativePath<Join<FromRest>, Join<ToRest>>\n : never\n : Split<TTo> extends ['.', ...infer ToRest]\n ? ToRest extends ['/']\n ? Join<[TFrom, '/']>\n : ResolveRelativePath<TFrom, Join<ToRest>>\n : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>\n : never\n : never\n\n// type Test1 = ResolveRelativePath<'/', '/posts'>\n// // ^?\n// type Test4 = ResolveRelativePath<'/posts/1/comments', '../..'>\n// // ^?\n// type Test5 = ResolveRelativePath<'/posts/1/comments', '../../..'>\n// // ^?\n// type Test6 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test7 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n// type Test8 = ResolveRelativePath<'/posts/1/comments', '../edit'>\n// // ^?\n// type Test9 = ResolveRelativePath<'/posts/1/comments', '1'>\n// // ^?\n// type Test10 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test11 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n\ntype LinkCurrentTargetElement = {\n preloadTimeout?: null | ReturnType<typeof setTimeout>\n}\n\nconst preloadWarning = 'Error preloading route! ☝️'\n\nexport function useLinkProps<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n): React.AnchorHTMLAttributes<HTMLAnchorElement> {\n const router = useRouter()\n const matchPathname = useMatch({\n strict: false,\n select: (s) => s.pathname,\n })\n\n const {\n // custom props\n activeProps = () => ({ className: 'active' }),\n inactiveProps = () => ({}),\n activeOptions,\n hash,\n search,\n params,\n to,\n state,\n mask,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\n replace,\n startTransition,\n resetScroll,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ...rest\n } = options\n\n // If this link simply reloads the current route,\n // make sure it has a new key so it will trigger a data refresh\n\n // If this `to` is a valid external URL, return\n // null for LinkUtils\n\n const dest = {\n ...(options.to && { from: matchPathname }),\n ...options,\n }\n\n let type: 'internal' | 'external' = 'internal'\n\n try {\n new URL(`${to}`)\n type = 'external'\n } catch {}\n\n const next = router.buildLocation(dest as any)\n const preload = userPreload ?? router.options.defaultPreload\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = useRouterState({\n select: (s) => {\n // Compare path/hash for matches\n const currentPathSplit = s.location.pathname.split('/')\n const nextPathSplit = next.pathname.split('/')\n const pathIsFuzzyEqual = nextPathSplit.every(\n (d, i) => d === currentPathSplit[i],\n )\n // Combine the matches based on user router.options\n const pathTest = activeOptions?.exact\n ? exactPathTest(s.location.pathname, next.pathname)\n : pathIsFuzzyEqual\n const hashTest = activeOptions?.includeHash\n ? s.location.hash === next.hash\n : true\n const searchTest =\n activeOptions?.includeSearch ?? true\n ? deepEqual(s.location.search, next.search, !activeOptions?.exact)\n : true\n\n // The final \"active\" test\n return pathTest && hashTest && searchTest\n },\n })\n\n if (type === 'external') {\n return {\n ...rest,\n type,\n href: to,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n ...(onClick && { onClick }),\n ...(onFocus && { onFocus }),\n ...(onMouseEnter && { onMouseEnter }),\n ...(onMouseLeave && { onMouseLeave }),\n ...(onTouchStart && { onTouchStart }),\n }\n }\n\n // The click handler\n const handleClick = (e: MouseEvent) => {\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!target || target === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n // All is well? Navigate!\n router.commitLocation({ ...next, replace, resetScroll, startTransition })\n }\n }\n\n const doPreload = () => {\n React.startTransition(() => {\n router.preloadRoute(dest as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n })\n }\n\n // The click handler\n const handleFocus = (e: MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (preload) {\n if (eventTarget.preloadTimeout) {\n return\n }\n\n eventTarget.preloadTimeout = setTimeout(() => {\n eventTarget.preloadTimeout = null\n doPreload()\n }, preloadDelay)\n }\n }\n\n const handleLeave = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (eventTarget.preloadTimeout) {\n clearTimeout(eventTarget.preloadTimeout)\n eventTarget.preloadTimeout = null\n }\n }\n\n const composeHandlers =\n (handlers: Array<undefined | ((e: any) => void)>) =>\n (e: { persist?: () => void; defaultPrevented: boolean }) => {\n e.persist?.()\n handlers.filter(Boolean).forEach((handler) => {\n if (e.defaultPrevented) return\n handler!(e)\n })\n }\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? functionalUpdate(activeProps as any, {}) ?? {}\n : {}\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive ? {} : functionalUpdate(inactiveProps, {})\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n return {\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n ...rest,\n href: disabled\n ? undefined\n : next.maskedLocation\n ? router.history.createHref(next.maskedLocation.href)\n : router.history.createHref(next.href),\n onClick: composeHandlers([onClick, handleClick]),\n onFocus: composeHandlers([onFocus, handleFocus]),\n onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),\n onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),\n onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),\n target,\n ...(Object.keys(resolvedStyle).length && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive && { 'data-status': 'active', 'aria-current': 'page' }),\n }\n}\n\nexport type UseLinkPropsOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> &\n React.AnchorHTMLAttributes<HTMLAnchorElement>\n\nexport type ActiveLinkOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = LinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // A function that returns additional props for the `active` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n activeProps?:\n | React.AnchorHTMLAttributes<HTMLAnchorElement>\n | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)\n // A function that returns additional props for the `inactive` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n inactiveProps?:\n | React.AnchorHTMLAttributes<HTMLAnchorElement>\n | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)\n}\n\nexport type LinkProps<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = string,\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | React.ReactNode\n | ((state: { isActive: boolean }) => React.ReactNode)\n}\n\ntype LinkComponentProps<TComp> = React.PropsWithoutRef<\n TComp extends React.FC<infer TProps> | React.Component<infer TProps>\n ? TProps\n : TComp extends keyof JSX.IntrinsicElements\n ? Omit<React.HTMLProps<TComp>, 'children' | 'preload'>\n : never\n> &\n React.RefAttributes<\n TComp extends\n | React.FC<{ ref: infer TRef }>\n | React.Component<{ ref: infer TRef }>\n ? TRef\n : TComp extends keyof JSX.IntrinsicElements\n ? React.ComponentRef<TComp>\n : never\n >\n\nexport type LinkComponent<TComp> = <\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n props: LinkProps<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkComponentProps<TComp>,\n) => React.ReactElement\n\nexport function createLink<const TComp>(Comp: TComp): LinkComponent<TComp> {\n return React.forwardRef(function CreatedLink(props, ref) {\n return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n }) as any\n}\n\nexport const Link: LinkComponent<'a'> = React.forwardRef((props: any, ref) => {\n const { _asChild, ...rest } = props\n const { type, ...linkProps } = useLinkProps(rest)\n\n const children =\n typeof rest.children === 'function'\n ? rest.children({\n isActive: (linkProps as any)['data-status'] === 'active',\n })\n : rest.children\n\n return React.createElement(\n _asChild ? _asChild : 'a',\n {\n ...linkProps,\n ref,\n },\n children,\n )\n}) as any\n\nfunction isCtrlEvent(e: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n"],"names":["useRouter","useMatch","useRouterState","exactPathTest","deepEqual","React","functionalUpdate"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"link.cjs","sources":["../../src/link.tsx"],"sourcesContent":["import * as React from 'react'\nimport { flushSync } from 'react-dom'\nimport { useMatch } from './Matches'\nimport { useRouterState } from './useRouterState'\nimport { useRouter } from './useRouter'\nimport { deepEqual, exactPathTest, functionalUpdate } from './utils'\nimport type { ParsedLocation } from '.'\nimport type { HistoryState } from '@tanstack/history'\nimport type { Trim } from './fileRoute'\nimport type { AnyRoute, RootSearchSchema } from './route'\nimport type {\n RouteByPath,\n RoutePaths,\n RoutePathsAutoComplete,\n} from './routeInfo'\nimport type { RegisteredRouter } from './router'\nimport type {\n Expand,\n IsUnion,\n MakeDifferenceOptional,\n NoInfer,\n NonNullableUpdater,\n PickRequired,\n Updater,\n WithoutEmpty,\n} from './utils'\n\nexport type CleanPath<T extends string> = T extends `${infer L}//${infer R}`\n ? CleanPath<`${CleanPath<L>}/${CleanPath<R>}`>\n : T extends `${infer L}//`\n ? `${CleanPath<L>}/`\n : T extends `//${infer L}`\n ? `/${CleanPath<L>}`\n : T\n\nexport type Split<TValue, TIncludeTrailingSlash = true> = TValue extends unknown\n ? string extends TValue\n ? Array<string>\n : TValue extends string\n ? CleanPath<TValue> extends ''\n ? []\n : TIncludeTrailingSlash extends true\n ? CleanPath<TValue> extends `${infer T}/`\n ? [...Split<T>, '/']\n : CleanPath<TValue> extends `/${infer U}`\n ? Split<U>\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : [TValue]\n : CleanPath<TValue> extends `${infer T}/${infer U}`\n ? [...Split<T>, ...Split<U>]\n : TValue extends string\n ? [TValue]\n : never\n : never\n : never\n\nexport type ParsePathParams<T extends string> = keyof {\n [K in Trim<Split<T>[number], '_'> as K extends `$${infer L}`\n ? L extends ''\n ? '_splat'\n : L\n : never]: K\n}\n\nexport type Join<T, TDelimiter extends string = '/'> = T extends []\n ? ''\n : T extends [infer L extends string]\n ? L\n : T extends [\n infer L extends string,\n ...infer Tail extends [...Array<string>],\n ]\n ? CleanPath<`${L}${TDelimiter}${Join<Tail>}`>\n : never\n\nexport type Last<T extends Array<any>> = T extends [...infer _, infer L]\n ? L\n : never\n\nexport type RemoveTrailingSlashes<T> = T extends `${infer R}/`\n ? RemoveTrailingSlashes<R>\n : T\n\nexport type RemoveLeadingSlashes<T> = T extends `/${infer R}`\n ? RemoveLeadingSlashes<R>\n : T\n\nexport type ResolvePaths<TRouteTree extends AnyRoute, TSearchPath> =\n RouteByPath<TRouteTree, RemoveTrailingSlashes<TSearchPath>> extends never\n ? RoutePaths<TRouteTree>\n : RoutePaths<RouteByPath<TRouteTree, RemoveTrailingSlashes<TSearchPath>>>\n\nexport type SearchPaths<\n TRouteTree extends AnyRoute,\n TSearchPath extends string,\n TPaths = ResolvePaths<TRouteTree, TSearchPath>,\n> = TPaths extends `${RemoveTrailingSlashes<TSearchPath>}/${infer TRest}`\n ? TRest\n : never\n\nexport type SearchRelativePathAutoComplete<\n TRouteTree extends AnyRoute,\n TTo extends string,\n TSearchPath extends string,\n> = `${TTo}/${SearchPaths<TRouteTree, TSearchPath>}`\n\nexport type RelativeToParentPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n TResolvedPath extends string = RemoveTrailingSlashes<\n ResolveRelativePath<TFrom, TTo>\n >,\n> =\n | SearchRelativePathAutoComplete<TRouteTree, TTo, TResolvedPath>\n | (TResolvedPath extends '' ? never : `${TTo}/../`)\n\nexport type RelativeToCurrentPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n TRestTo extends string,\n TResolvedPath extends\n string = RemoveTrailingSlashes<`${RemoveTrailingSlashes<TFrom>}/${RemoveLeadingSlashes<TRestTo>}`>,\n> = SearchRelativePathAutoComplete<TRouteTree, TTo, TResolvedPath>\n\nexport type AbsolutePathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n> =\n | (string extends TFrom\n ? './'\n : TFrom extends `/`\n ? never\n : SearchPaths<TRouteTree, TFrom> extends ''\n ? never\n : './')\n | (string extends TFrom ? '../' : TFrom extends `/` ? never : '../')\n | RoutePaths<TRouteTree>\n | (TFrom extends '/' ? never : SearchPaths<TRouteTree, TFrom>)\n\nexport type RelativeToPathAutoComplete<\n TRouteTree extends AnyRoute,\n TFrom extends string,\n TTo extends string,\n> = TTo extends `..${string}`\n ? RelativeToParentPathAutoComplete<\n TRouteTree,\n TFrom,\n RemoveTrailingSlashes<TTo>\n >\n : TTo extends `./${infer TRestTTo}`\n ? RelativeToCurrentPathAutoComplete<\n TRouteTree,\n TFrom,\n RemoveTrailingSlashes<TTo>,\n TRestTTo\n >\n : AbsolutePathAutoComplete<TRouteTree, TFrom>\n\nexport type NavigateOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // `replace` is a boolean that determines whether the navigation should replace the current history entry or push a new one.\n replace?: boolean\n resetScroll?: boolean\n /** @deprecated All navigations now use startTransition under the hood */\n startTransition?: boolean\n // if set to `true`, the router will wrap the resulting navigation in a document.startViewTransition() call.\n viewTransition?: boolean\n}\n\nexport type ToOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ToSubOptions<TRouteTree, TFrom, TTo> & {\n _fromLocation?: ParsedLocation\n mask?: ToMaskOptions<TRouteTree, TMaskFrom, TMaskTo>\n}\n\nexport type ToMaskOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TMaskFrom extends RoutePaths<TRouteTree> | string = string,\n TMaskTo extends string = '',\n> = ToSubOptions<TRouteTree, TMaskFrom, TMaskTo> & {\n unmaskOnReload?: boolean\n}\n\nexport type ToSubOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n> = {\n to?: ToPathOption<TRouteTree, TFrom, TTo> & {}\n hash?: true | Updater<string>\n state?: true | NonNullableUpdater<HistoryState>\n // The source route path. This is automatically set when using route-level APIs, but for type-safe relative routing on the router itself, this is required\n from?: RoutePathsAutoComplete<TRouteTree, TFrom> & {}\n // // When using relative route paths, this option forces resolution from the current path, instead of the route API's path or `from` path\n} & SearchParamOptions<TRouteTree, TFrom, TTo> &\n PathParamOptions<TRouteTree, TFrom, TTo>\n\ntype ParamsReducer<TFrom, TTo> = TTo | ((current: TFrom) => TTo)\n\ntype ParamVariant = 'PATH' | 'SEARCH'\n\ntype ExcludeRootSearchSchema<T, TExcluded = Exclude<T, RootSearchSchema>> = [\n TExcluded,\n] extends [never]\n ? {}\n : TExcluded\n\nexport type ResolveRoute<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo,\n TPath = RemoveTrailingSlashes<\n string extends TFrom\n ? TTo\n : string extends TTo\n ? TFrom\n : ResolveRelativePath<TFrom, TTo>\n >,\n> = TPath extends string\n ? RouteByPath<TRouteTree, `${TPath}/`> extends never\n ? RouteByPath<TRouteTree, TPath>\n : RouteByPath<TRouteTree, `${TPath}/`>\n : never\n\ntype PostProcessParams<\n T,\n TParamVariant extends ParamVariant,\n> = TParamVariant extends 'SEARCH' ? ExcludeRootSearchSchema<T> : T\n\ntype ResolveFromParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TFromRouteType extends\n | 'allParams'\n | 'fullSearchSchema' = TParamVariant extends 'PATH'\n ? 'allParams'\n : 'fullSearchSchema',\n> = PostProcessParams<\n RouteByPath<TRouteTree, TFrom>['types'][TFromRouteType],\n TParamVariant\n>\n\ntype ResolveToParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TRoute extends AnyRoute = ResolveRoute<TRouteTree, TFrom, TTo>,\n> = PostProcessParams<\n TRoute['types'][TParamVariant extends 'PATH'\n ? 'allParams'\n : 'fullSearchSchemaInput'],\n TParamVariant\n>\n\ntype ResolveRelativeToParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n TToParams = ResolveToParams<TRouteTree, TParamVariant, TFrom, TTo>,\n> = TParamVariant extends 'SEARCH'\n ? TToParams\n : string extends TFrom\n ? TToParams\n : MakeDifferenceOptional<\n ResolveFromParams<TRouteTree, TParamVariant, TFrom>,\n TToParams\n >\n\ntype MakeOptionalParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = TParamVariant extends 'SEARCH'\n ? {\n search?:\n | true\n | (ParamsReducer<\n Expand<ResolveFromParams<TRouteTree, TParamVariant, TFrom>>,\n Expand<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n > & {})\n }\n : {\n params?:\n | true\n | (ParamsReducer<\n Expand<ResolveFromParams<TRouteTree, TParamVariant, TFrom>>,\n Expand<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n > & {})\n }\n\ntype MakeRequiredParamsReducer<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TToParams,\n TFromParams = ResolveFromParams<TRouteTree, TParamVariant, TFrom>,\n> =\n | ([TFromParams] extends [WithoutEmpty<PickRequired<TToParams>>]\n ? true\n : never)\n | ParamsReducer<Expand<TFromParams>, TToParams>\n\nexport type MakeRequiredParams<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = TParamVariant extends 'SEARCH'\n ? {\n search: Expand<\n MakeRequiredParamsReducer<\n TRouteTree,\n TParamVariant,\n TFrom,\n Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>\n >\n > & {}\n }\n : {\n params: Expand<\n MakeRequiredParamsReducer<\n TRouteTree,\n TParamVariant,\n TFrom,\n Expand<ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>>\n >\n > & {}\n }\n\nexport type IsRequiredParams<TParams> = keyof TParams extends infer K extends\n keyof TParams\n ? K extends any\n ? undefined extends TParams[K]\n ? never\n : true\n : never\n : never\n\nexport type IsRequired<\n TRouteTree extends AnyRoute,\n TParamVariant extends ParamVariant,\n TFrom,\n TTo,\n> = string extends TTo\n ? string extends TFrom\n ? never\n : IsRequiredParams<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n : IsRequiredParams<\n ResolveRelativeToParams<TRouteTree, TParamVariant, TFrom, TTo>\n >\n\nexport type ParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n TParamVariant extends ParamVariant,\n> =\n IsRequired<TRouteTree, TParamVariant, TFrom, TTo> extends never\n ? MakeOptionalParams<TRouteTree, TParamVariant, TFrom, TTo>\n : MakeRequiredParams<TRouteTree, TParamVariant, TFrom, TTo>\n\nexport type SearchParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n> = ParamOptions<TRouteTree, TFrom, TTo, 'SEARCH'>\n\nexport type PathParamOptions<\n TRouteTree extends AnyRoute,\n TFrom,\n TTo extends string,\n> = ParamOptions<TRouteTree, TFrom, TTo, 'PATH'>\n\nexport type ToPathOption<\n TRouteTree extends AnyRoute = AnyRoute,\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = string,\n> =\n | CheckPath<TRouteTree, TTo, never, TFrom, TTo>\n | RelativeToPathAutoComplete<\n TRouteTree,\n NoInfer<TFrom> extends string ? NoInfer<TFrom> : '',\n NoInfer<TTo> & string\n >\n\nexport interface ActiveOptions {\n exact?: boolean\n includeHash?: boolean\n includeSearch?: boolean\n}\n\nexport type LinkOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = NavigateOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // The standard anchor tag target attribute\n target?: HTMLAnchorElement['target']\n // Defaults to `{ exact: false, includeHash: false }`\n activeOptions?: ActiveOptions\n // If set, will preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.\n preload?: false | 'intent'\n // Delay intent preloading by this many milliseconds. If the intent exits before this delay, the preload will be cancelled.\n preloadDelay?: number\n // If true, will render the link without the href attribute\n disabled?: boolean\n}\n\nexport type CheckPath<TRouteTree extends AnyRoute, TPass, TFail, TFrom, TTo> =\n ResolveRoute<TRouteTree, TFrom, TTo> extends never ? TFail : TPass\n\nexport type ResolveRelativePath<TFrom, TTo = '.'> = TFrom extends string\n ? TTo extends string\n ? TTo extends '.'\n ? TFrom\n : TTo extends `./`\n ? Join<[TFrom, '/']>\n : TTo extends `./${infer TRest}`\n ? ResolveRelativePath<TFrom, TRest>\n : TTo extends `/${infer TRest}`\n ? TTo\n : Split<TTo> extends ['..', ...infer ToRest]\n ? Split<TFrom> extends [...infer FromRest, infer FromTail]\n ? ToRest extends ['/']\n ? Join<['/', ...FromRest, '/']>\n : ResolveRelativePath<Join<FromRest>, Join<ToRest>>\n : never\n : Split<TTo> extends ['.', ...infer ToRest]\n ? ToRest extends ['/']\n ? Join<[TFrom, '/']>\n : ResolveRelativePath<TFrom, Join<ToRest>>\n : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>>\n : never\n : never\n\n// type Test1 = ResolveRelativePath<'/', '/posts'>\n// // ^?\n// type Test4 = ResolveRelativePath<'/posts/1/comments', '../..'>\n// // ^?\n// type Test5 = ResolveRelativePath<'/posts/1/comments', '../../..'>\n// // ^?\n// type Test6 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test7 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n// type Test8 = ResolveRelativePath<'/posts/1/comments', '../edit'>\n// // ^?\n// type Test9 = ResolveRelativePath<'/posts/1/comments', '1'>\n// // ^?\n// type Test10 = ResolveRelativePath<'/posts/1/comments', './1'>\n// // ^?\n// type Test11 = ResolveRelativePath<'/posts/1/comments', './1/2'>\n// // ^?\n\ntype LinkCurrentTargetElement = {\n preloadTimeout?: null | ReturnType<typeof setTimeout>\n}\n\nconst preloadWarning = 'Error preloading route! ☝️'\n\nexport function useLinkProps<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n options: UseLinkPropsOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo>,\n): React.AnchorHTMLAttributes<HTMLAnchorElement> {\n const router = useRouter()\n const matchPathname = useMatch({\n strict: false,\n select: (s) => s.pathname,\n })\n const [isTransitioning, setIsTransitioning] = React.useState(false)\n\n const {\n // custom props\n activeProps = () => ({ className: 'active' }),\n inactiveProps = () => ({}),\n activeOptions,\n hash,\n search,\n params,\n to,\n state,\n mask,\n preload: userPreload,\n preloadDelay: userPreloadDelay,\n replace,\n startTransition,\n resetScroll,\n viewTransition,\n // element props\n children,\n target,\n disabled,\n style,\n className,\n onClick,\n onFocus,\n onMouseEnter,\n onMouseLeave,\n onTouchStart,\n ...rest\n } = options\n\n // If this link simply reloads the current route,\n // make sure it has a new key so it will trigger a data refresh\n\n // If this `to` is a valid external URL, return\n // null for LinkUtils\n\n const dest = {\n ...(options.to && { from: matchPathname }),\n ...options,\n }\n\n let type: 'internal' | 'external' = 'internal'\n\n try {\n new URL(`${to}`)\n type = 'external'\n } catch {}\n\n const next = router.buildLocation(dest as any)\n const preload = userPreload ?? router.options.defaultPreload\n const preloadDelay =\n userPreloadDelay ?? router.options.defaultPreloadDelay ?? 0\n\n const isActive = useRouterState({\n select: (s) => {\n // Compare path/hash for matches\n const currentPathSplit = s.location.pathname.split('/')\n const nextPathSplit = next.pathname.split('/')\n const pathIsFuzzyEqual = nextPathSplit.every(\n (d, i) => d === currentPathSplit[i],\n )\n // Combine the matches based on user router.options\n const pathTest = activeOptions?.exact\n ? exactPathTest(s.location.pathname, next.pathname)\n : pathIsFuzzyEqual\n const hashTest = activeOptions?.includeHash\n ? s.location.hash === next.hash\n : true\n const searchTest =\n activeOptions?.includeSearch ?? true\n ? deepEqual(s.location.search, next.search, !activeOptions?.exact)\n : true\n\n // The final \"active\" test\n return pathTest && hashTest && searchTest\n },\n })\n\n if (type === 'external') {\n return {\n ...rest,\n type,\n href: to,\n ...(children && { children }),\n ...(target && { target }),\n ...(disabled && { disabled }),\n ...(style && { style }),\n ...(className && { className }),\n ...(onClick && { onClick }),\n ...(onFocus && { onFocus }),\n ...(onMouseEnter && { onMouseEnter }),\n ...(onMouseLeave && { onMouseLeave }),\n ...(onTouchStart && { onTouchStart }),\n }\n }\n\n // The click handler\n const handleClick = (e: MouseEvent) => {\n if (\n !disabled &&\n !isCtrlEvent(e) &&\n !e.defaultPrevented &&\n (!target || target === '_self') &&\n e.button === 0\n ) {\n e.preventDefault()\n\n flushSync(() => {\n setIsTransitioning(true)\n })\n\n const unsub = router.subscribe('onResolved', () => {\n unsub()\n setIsTransitioning(false)\n })\n\n // All is well? Navigate!\n router.commitLocation({\n ...next,\n replace,\n resetScroll,\n startTransition,\n viewTransition,\n })\n }\n }\n\n const doPreload = () => {\n router.preloadRoute(dest as any).catch((err) => {\n console.warn(err)\n console.warn(preloadWarning)\n })\n }\n\n // The click handler\n const handleFocus = (e: MouseEvent) => {\n if (disabled) return\n if (preload) {\n doPreload()\n }\n }\n\n const handleTouchStart = handleFocus\n\n const handleEnter = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (preload) {\n if (eventTarget.preloadTimeout) {\n return\n }\n\n eventTarget.preloadTimeout = setTimeout(() => {\n eventTarget.preloadTimeout = null\n doPreload()\n }, preloadDelay)\n }\n }\n\n const handleLeave = (e: MouseEvent) => {\n if (disabled) return\n const eventTarget = (e.target || {}) as LinkCurrentTargetElement\n\n if (eventTarget.preloadTimeout) {\n clearTimeout(eventTarget.preloadTimeout)\n eventTarget.preloadTimeout = null\n }\n }\n\n const composeHandlers =\n (handlers: Array<undefined | ((e: any) => void)>) =>\n (e: { persist?: () => void; defaultPrevented: boolean }) => {\n e.persist?.()\n handlers.filter(Boolean).forEach((handler) => {\n if (e.defaultPrevented) return\n handler!(e)\n })\n }\n\n // Get the active props\n const resolvedActiveProps: React.HTMLAttributes<HTMLAnchorElement> = isActive\n ? functionalUpdate(activeProps as any, {}) ?? {}\n : {}\n\n // Get the inactive props\n const resolvedInactiveProps: React.HTMLAttributes<HTMLAnchorElement> =\n isActive ? {} : functionalUpdate(inactiveProps, {})\n\n const resolvedClassName = [\n className,\n resolvedActiveProps.className,\n resolvedInactiveProps.className,\n ]\n .filter(Boolean)\n .join(' ')\n\n const resolvedStyle = {\n ...style,\n ...resolvedActiveProps.style,\n ...resolvedInactiveProps.style,\n }\n\n return {\n ...resolvedActiveProps,\n ...resolvedInactiveProps,\n ...rest,\n href: disabled\n ? undefined\n : next.maskedLocation\n ? router.history.createHref(next.maskedLocation.href)\n : router.history.createHref(next.href),\n onClick: composeHandlers([onClick, handleClick]),\n onFocus: composeHandlers([onFocus, handleFocus]),\n onMouseEnter: composeHandlers([onMouseEnter, handleEnter]),\n onMouseLeave: composeHandlers([onMouseLeave, handleLeave]),\n onTouchStart: composeHandlers([onTouchStart, handleTouchStart]),\n target,\n ...(Object.keys(resolvedStyle).length && { style: resolvedStyle }),\n ...(resolvedClassName && { className: resolvedClassName }),\n ...(disabled && {\n role: 'link',\n 'aria-disabled': true,\n }),\n ...(isActive && { 'data-status': 'active', 'aria-current': 'page' }),\n ...(isTransitioning && { 'data-transitioning': 'transitioning' }),\n }\n}\n\nexport type UseLinkPropsOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> &\n React.AnchorHTMLAttributes<HTMLAnchorElement>\n\nexport type ActiveLinkOptions<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = LinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // A function that returns additional props for the `active` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n activeProps?:\n | React.AnchorHTMLAttributes<HTMLAnchorElement>\n | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)\n // A function that returns additional props for the `inactive` state of this link. These props override other props passed to the link (`style`'s are merged, `className`'s are concatenated)\n inactiveProps?:\n | React.AnchorHTMLAttributes<HTMLAnchorElement>\n | (() => React.AnchorHTMLAttributes<HTMLAnchorElement>)\n}\n\nexport type LinkProps<\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = string,\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {\n // If a function is passed as a child, it will be given the `isActive` boolean to aid in further styling on the element it returns\n children?:\n | React.ReactNode\n | ((state: {\n isActive: boolean\n isTransitioning: boolean\n }) => React.ReactNode)\n}\n\ntype LinkComponentProps<TComp> = React.PropsWithoutRef<\n TComp extends React.FC<infer TProps> | React.Component<infer TProps>\n ? TProps\n : TComp extends keyof JSX.IntrinsicElements\n ? Omit<React.HTMLProps<TComp>, 'children' | 'preload'>\n : never\n> &\n React.RefAttributes<\n TComp extends\n | React.FC<{ ref: infer TRef }>\n | React.Component<{ ref: infer TRef }>\n ? TRef\n : TComp extends keyof JSX.IntrinsicElements\n ? React.ComponentRef<TComp>\n : never\n >\n\nexport type LinkComponent<TComp> = <\n TRouteTree extends AnyRoute = RegisteredRouter['routeTree'],\n TFrom extends RoutePaths<TRouteTree> | string = string,\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom,\n TMaskTo extends string = '',\n>(\n props: LinkProps<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> &\n LinkComponentProps<TComp>,\n) => React.ReactElement\n\nexport function createLink<const TComp>(Comp: TComp): LinkComponent<TComp> {\n return React.forwardRef(function CreatedLink(props, ref) {\n return <Link {...(props as any)} _asChild={Comp} ref={ref} />\n }) as any\n}\n\nexport const Link: LinkComponent<'a'> = React.forwardRef((props: any, ref) => {\n const { _asChild, ...rest } = props\n const { type, ...linkProps } = useLinkProps(rest)\n\n const children =\n typeof rest.children === 'function'\n ? rest.children({\n isActive: (linkProps as any)['data-status'] === 'active',\n })\n : rest.children\n\n return React.createElement(\n _asChild ? _asChild : 'a',\n {\n ...linkProps,\n ref,\n },\n children,\n )\n}) as any\n\nfunction isCtrlEvent(e: MouseEvent) {\n return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey)\n}\n"],"names":["useRouter","useMatch","React","useRouterState","exactPathTest","deepEqual","flushSync","functionalUpdate"],"mappings":"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"}
|
package/dist/cjs/link.d.cts
CHANGED
|
@@ -28,7 +28,9 @@ export type RelativeToPathAutoComplete<TRouteTree extends AnyRoute, TFrom extend
|
|
|
28
28
|
export type NavigateOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ToOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
|
|
29
29
|
replace?: boolean;
|
|
30
30
|
resetScroll?: boolean;
|
|
31
|
+
/** @deprecated All navigations now use startTransition under the hood */
|
|
31
32
|
startTransition?: boolean;
|
|
33
|
+
viewTransition?: boolean;
|
|
32
34
|
};
|
|
33
35
|
export type ToOptions<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ToSubOptions<TRouteTree, TFrom, TTo> & {
|
|
34
36
|
_fromLocation?: ParsedLocation;
|
|
@@ -93,6 +95,7 @@ export type ActiveLinkOptions<TRouteTree extends AnyRoute = RegisteredRouter['ro
|
|
|
93
95
|
export type LinkProps<TRouteTree extends AnyRoute = RegisteredRouter['routeTree'], TFrom extends RoutePaths<TRouteTree> | string = string, TTo extends string = string, TMaskFrom extends RoutePaths<TRouteTree> | string = TFrom, TMaskTo extends string = ''> = ActiveLinkOptions<TRouteTree, TFrom, TTo, TMaskFrom, TMaskTo> & {
|
|
94
96
|
children?: React.ReactNode | ((state: {
|
|
95
97
|
isActive: boolean;
|
|
98
|
+
isTransitioning: boolean;
|
|
96
99
|
}) => React.ReactNode);
|
|
97
100
|
};
|
|
98
101
|
type LinkComponentProps<TComp> = React.PropsWithoutRef<TComp extends React.FC<infer TProps> | React.Component<infer TProps> ? TProps : TComp extends keyof JSX.IntrinsicElements ? Omit<React.HTMLProps<TComp>, 'children' | 'preload'> : never> & React.RefAttributes<TComp extends React.FC<{
|
package/dist/cjs/router.cjs
CHANGED
|
@@ -29,6 +29,7 @@ class Router {
|
|
|
29
29
|
Math.random() * 1e7
|
|
30
30
|
)}`;
|
|
31
31
|
this.resetNextScroll = true;
|
|
32
|
+
this.shouldViewTransition = void 0;
|
|
32
33
|
this.navigateTimeout = null;
|
|
33
34
|
this.latestLoadPromise = Promise.resolve();
|
|
34
35
|
this.subscribers = /* @__PURE__ */ new Set();
|
|
@@ -71,7 +72,6 @@ class Router {
|
|
|
71
72
|
onUpdate: () => {
|
|
72
73
|
this.__store.state = {
|
|
73
74
|
...this.state,
|
|
74
|
-
status: this.state.isTransitioning || this.state.isLoading ? "pending" : "idle",
|
|
75
75
|
cachedMatches: this.state.cachedMatches.filter(
|
|
76
76
|
(d) => !["redirected"].includes(d.status)
|
|
77
77
|
)
|
|
@@ -495,6 +495,7 @@ class Router {
|
|
|
495
495
|
};
|
|
496
496
|
this.commitLocation = async ({
|
|
497
497
|
startTransition,
|
|
498
|
+
viewTransition,
|
|
498
499
|
...next
|
|
499
500
|
}) => {
|
|
500
501
|
if (this.navigateTimeout)
|
|
@@ -524,17 +525,13 @@ class Router {
|
|
|
524
525
|
nextHistory.state.__tempKey = this.tempLocationKey;
|
|
525
526
|
}
|
|
526
527
|
}
|
|
527
|
-
|
|
528
|
-
this.
|
|
529
|
-
nextHistory.href,
|
|
530
|
-
nextHistory.state
|
|
531
|
-
);
|
|
532
|
-
};
|
|
533
|
-
if (startTransition ?? true) {
|
|
534
|
-
this.startReactTransition(apply);
|
|
535
|
-
} else {
|
|
536
|
-
apply();
|
|
528
|
+
if (viewTransition) {
|
|
529
|
+
this.shouldViewTransition = true;
|
|
537
530
|
}
|
|
531
|
+
this.history[next.replace ? "replace" : "push"](
|
|
532
|
+
nextHistory.href,
|
|
533
|
+
nextHistory.state
|
|
534
|
+
);
|
|
538
535
|
}
|
|
539
536
|
this.resetNextScroll = next.resetScroll ?? true;
|
|
540
537
|
return this.latestLoadPromise;
|
|
@@ -897,7 +894,8 @@ class Router {
|
|
|
897
894
|
});
|
|
898
895
|
this.latestLoadPromise = promise;
|
|
899
896
|
let latestPromise;
|
|
900
|
-
(async () => {
|
|
897
|
+
this.startReactTransition(async () => {
|
|
898
|
+
var _a, _b;
|
|
901
899
|
try {
|
|
902
900
|
const next = this.latestLocation;
|
|
903
901
|
const prevLocation = this.state.resolvedLocation;
|
|
@@ -916,6 +914,7 @@ class Router {
|
|
|
916
914
|
pendingMatches = this.matchRoutes(next.pathname, next.search);
|
|
917
915
|
this.__store.setState((s) => ({
|
|
918
916
|
...s,
|
|
917
|
+
status: "pending",
|
|
919
918
|
isLoading: true,
|
|
920
919
|
location: next,
|
|
921
920
|
pendingMatches,
|
|
@@ -954,38 +953,37 @@ class Router {
|
|
|
954
953
|
const stayingMatches = previousMatches.filter(
|
|
955
954
|
(match) => pendingMatches.find((d) => d.id === match.id)
|
|
956
955
|
);
|
|
957
|
-
this.
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
[enteringMatches, "onEnter"],
|
|
975
|
-
[stayingMatches, "onStay"]
|
|
976
|
-
].forEach(([matches, hook]) => {
|
|
977
|
-
matches.forEach((match) => {
|
|
978
|
-
var _a, _b;
|
|
979
|
-
(_b = (_a = this.looseRoutesById[match.routeId].options)[hook]) == null ? void 0 : _b.call(_a, match);
|
|
956
|
+
const shouldViewTransition = this.shouldViewTransition ?? this.options.defaultViewTransition;
|
|
957
|
+
delete this.shouldViewTransition;
|
|
958
|
+
const apply = () => {
|
|
959
|
+
this.__store.batch(() => {
|
|
960
|
+
this.__store.setState((s) => ({
|
|
961
|
+
...s,
|
|
962
|
+
isLoading: false,
|
|
963
|
+
matches: s.pendingMatches,
|
|
964
|
+
pendingMatches: void 0,
|
|
965
|
+
cachedMatches: [
|
|
966
|
+
...s.cachedMatches,
|
|
967
|
+
...exitingMatches.filter((d) => d.status !== "error")
|
|
968
|
+
],
|
|
969
|
+
statusCode: (redirect == null ? void 0 : redirect.statusCode) || notFound$1 ? 404 : s.matches.some((d) => d.status === "error") ? 500 : 200,
|
|
970
|
+
redirect
|
|
971
|
+
}));
|
|
972
|
+
this.cleanCache();
|
|
980
973
|
});
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
974
|
+
[
|
|
975
|
+
[exitingMatches, "onLeave"],
|
|
976
|
+
[enteringMatches, "onEnter"],
|
|
977
|
+
[stayingMatches, "onStay"]
|
|
978
|
+
].forEach(([matches, hook]) => {
|
|
979
|
+
matches.forEach((match) => {
|
|
980
|
+
var _a2, _b2;
|
|
981
|
+
(_b2 = (_a2 = this.looseRoutesById[match.routeId].options)[hook]) == null ? void 0 : _b2.call(_a2, match);
|
|
982
|
+
});
|
|
983
|
+
});
|
|
984
|
+
resolveLoad();
|
|
985
|
+
};
|
|
986
|
+
((_b = (_a = shouldViewTransition && typeof document !== "undefined" ? document : void 0) == null ? void 0 : _a.startViewTransition) == null ? void 0 : _b.call(_a, apply)) || apply();
|
|
989
987
|
} catch (err) {
|
|
990
988
|
if (latestPromise = this.checkLatest(promise)) {
|
|
991
989
|
return latestPromise;
|
|
@@ -993,7 +991,7 @@ class Router {
|
|
|
993
991
|
console.error("Load Error", err);
|
|
994
992
|
rejectLoad(err);
|
|
995
993
|
}
|
|
996
|
-
})
|
|
994
|
+
});
|
|
997
995
|
return this.latestLoadPromise;
|
|
998
996
|
};
|
|
999
997
|
this.resolveRedirect = (err) => {
|