@tanstack/vue-router 1.167.4 → 1.168.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/Match.js +55 -61
- package/dist/esm/Match.js.map +1 -1
- package/dist/esm/Matches.js +8 -15
- package/dist/esm/Matches.js.map +1 -1
- package/dist/esm/Scripts.js +7 -6
- package/dist/esm/Scripts.js.map +1 -1
- package/dist/esm/Transitioner.js +18 -24
- package/dist/esm/Transitioner.js.map +1 -1
- package/dist/esm/headContentUtils.js +13 -15
- package/dist/esm/headContentUtils.js.map +1 -1
- package/dist/esm/index.dev.js +6 -6
- package/dist/esm/index.js +6 -6
- package/dist/esm/link.js +242 -178
- package/dist/esm/link.js.map +1 -1
- package/dist/esm/matchContext.d.ts +8 -14
- package/dist/esm/matchContext.js +11 -9
- package/dist/esm/matchContext.js.map +1 -1
- package/dist/esm/not-found.js +6 -3
- package/dist/esm/not-found.js.map +1 -1
- package/dist/esm/router.js +2 -1
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/routerStores.d.ts +13 -0
- package/dist/esm/routerStores.js +33 -0
- package/dist/esm/routerStores.js.map +1 -0
- package/dist/esm/ssr/RouterClient.js +1 -1
- package/dist/esm/ssr/RouterClient.js.map +1 -1
- package/dist/esm/ssr/renderRouterToStream.js +2 -2
- package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
- package/dist/esm/ssr/renderRouterToString.js +1 -1
- package/dist/esm/ssr/renderRouterToString.js.map +1 -1
- package/dist/esm/useCanGoBack.d.ts +1 -1
- package/dist/esm/useCanGoBack.js +3 -2
- package/dist/esm/useCanGoBack.js.map +1 -1
- package/dist/esm/useLocation.js +3 -2
- package/dist/esm/useLocation.js.map +1 -1
- package/dist/esm/useMatch.js +29 -19
- package/dist/esm/useMatch.js.map +1 -1
- package/dist/esm/useRouterState.js +4 -4
- package/dist/esm/useRouterState.js.map +1 -1
- package/dist/source/Match.jsx +121 -159
- package/dist/source/Match.jsx.map +1 -1
- package/dist/source/Matches.jsx +11 -28
- package/dist/source/Matches.jsx.map +1 -1
- package/dist/source/Scripts.jsx +32 -35
- package/dist/source/Scripts.jsx.map +1 -1
- package/dist/source/Transitioner.jsx +19 -21
- package/dist/source/Transitioner.jsx.map +1 -1
- package/dist/source/headContentUtils.jsx +51 -61
- package/dist/source/headContentUtils.jsx.map +1 -1
- package/dist/source/link.jsx +298 -249
- package/dist/source/link.jsx.map +1 -1
- package/dist/source/matchContext.d.ts +8 -14
- package/dist/source/matchContext.jsx +17 -23
- package/dist/source/matchContext.jsx.map +1 -1
- package/dist/source/not-found.jsx +6 -5
- package/dist/source/not-found.jsx.map +1 -1
- package/dist/source/router.js +2 -1
- package/dist/source/router.js.map +1 -1
- package/dist/source/routerStores.d.ts +13 -0
- package/dist/source/routerStores.js +37 -0
- package/dist/source/routerStores.js.map +1 -0
- package/dist/source/ssr/RouterClient.jsx +1 -1
- package/dist/source/ssr/RouterClient.jsx.map +1 -1
- package/dist/source/ssr/renderRouterToStream.jsx +2 -2
- package/dist/source/ssr/renderRouterToStream.jsx.map +1 -1
- package/dist/source/ssr/renderRouterToString.jsx +1 -1
- package/dist/source/ssr/renderRouterToString.jsx.map +1 -1
- package/dist/source/useCanGoBack.d.ts +1 -1
- package/dist/source/useCanGoBack.js +4 -2
- package/dist/source/useCanGoBack.js.map +1 -1
- package/dist/source/useLocation.jsx +4 -4
- package/dist/source/useLocation.jsx.map +1 -1
- package/dist/source/useMatch.jsx +60 -38
- package/dist/source/useMatch.jsx.map +1 -1
- package/dist/source/useRouterState.jsx +4 -4
- package/dist/source/useRouterState.jsx.map +1 -1
- package/package.json +2 -2
- package/skills/vue-router/SKILL.md +3 -0
- package/src/Match.tsx +168 -180
- package/src/Matches.tsx +18 -31
- package/src/Scripts.tsx +40 -40
- package/src/Transitioner.tsx +35 -23
- package/src/headContentUtils.tsx +101 -107
- package/src/link.tsx +445 -300
- package/src/matchContext.tsx +23 -25
- package/src/not-found.tsx +9 -5
- package/src/router.ts +2 -1
- package/src/routerStores.ts +54 -0
- package/src/ssr/RouterClient.tsx +1 -1
- package/src/ssr/renderRouterToStream.tsx +2 -2
- package/src/ssr/renderRouterToString.tsx +1 -1
- package/src/useCanGoBack.ts +7 -2
- package/src/useLocation.tsx +8 -5
- package/src/useMatch.tsx +95 -49
- package/src/useRouterState.tsx +6 -4
package/dist/esm/link.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { useRouter } from "./useRouter.js";
|
|
2
|
-
import { useRouterState } from "./useRouterState.js";
|
|
3
2
|
import { useIntersectionObserver } from "./utils.js";
|
|
4
|
-
import { useMatches } from "./Matches.js";
|
|
5
3
|
import { deepEqual, exactPathTest, isDangerousProtocol, preloadWarning, removeTrailingSlash } from "@tanstack/router-core";
|
|
6
4
|
import * as Vue from "vue";
|
|
5
|
+
import { isServer } from "@tanstack/router-core/isServer";
|
|
6
|
+
import { useStore } from "@tanstack/vue-store";
|
|
7
7
|
//#region src/link.tsx
|
|
8
8
|
var timeoutMap = /* @__PURE__ */ new WeakMap();
|
|
9
9
|
function useLinkProps(options) {
|
|
@@ -22,107 +22,13 @@ function useLinkProps(options) {
|
|
|
22
22
|
return "internal";
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
|
-
const buildLocationKey = useRouterState({ select: (s) => {
|
|
26
|
-
const leaf = s.matches[s.matches.length - 1];
|
|
27
|
-
return {
|
|
28
|
-
search: leaf?.search,
|
|
29
|
-
hash: s.location.hash,
|
|
30
|
-
path: leaf?.pathname
|
|
31
|
-
};
|
|
32
|
-
} });
|
|
33
|
-
const from = useMatches({ select: (matches) => options.from ?? matches[matches.length - 1]?.fullPath });
|
|
34
|
-
const _options = Vue.computed(() => ({
|
|
35
|
-
...options,
|
|
36
|
-
from: from.value
|
|
37
|
-
}));
|
|
38
|
-
const next = Vue.computed(() => {
|
|
39
|
-
buildLocationKey.value;
|
|
40
|
-
return router.buildLocation(_options.value);
|
|
41
|
-
});
|
|
42
|
-
const preload = Vue.computed(() => {
|
|
43
|
-
if (_options.value.reloadDocument) return false;
|
|
44
|
-
return options.preload ?? router.options.defaultPreload;
|
|
45
|
-
});
|
|
46
|
-
const preloadDelay = Vue.computed(() => options.preloadDelay ?? router.options.defaultPreloadDelay ?? 0);
|
|
47
|
-
const isActive = useRouterState({ select: (s) => {
|
|
48
|
-
const activeOptions = options.activeOptions;
|
|
49
|
-
if (activeOptions?.exact) {
|
|
50
|
-
if (!exactPathTest(s.location.pathname, next.value.pathname, router.basepath)) return false;
|
|
51
|
-
} else {
|
|
52
|
-
const currentPathSplit = removeTrailingSlash(s.location.pathname, router.basepath).split("/");
|
|
53
|
-
if (!(removeTrailingSlash(next.value?.pathname, router.basepath)?.split("/"))?.every((d, i) => d === currentPathSplit[i])) return false;
|
|
54
|
-
}
|
|
55
|
-
if (activeOptions?.includeSearch ?? true) {
|
|
56
|
-
if (!deepEqual(s.location.search, next.value.search, {
|
|
57
|
-
partial: !activeOptions?.exact,
|
|
58
|
-
ignoreUndefined: !activeOptions?.explicitUndefined
|
|
59
|
-
})) return false;
|
|
60
|
-
}
|
|
61
|
-
if (activeOptions?.includeHash) return s.location.hash === next.value.hash;
|
|
62
|
-
return true;
|
|
63
|
-
} });
|
|
64
|
-
const doPreload = () => router.preloadRoute(_options.value).catch((err) => {
|
|
65
|
-
console.warn(err);
|
|
66
|
-
console.warn(preloadWarning);
|
|
67
|
-
});
|
|
68
|
-
const preloadViewportIoCallback = (entry) => {
|
|
69
|
-
if (entry?.isIntersecting) doPreload();
|
|
70
|
-
};
|
|
71
25
|
const ref = Vue.ref(null);
|
|
72
|
-
|
|
73
|
-
Vue.effect(() => {
|
|
74
|
-
if (hasRenderFetched) return;
|
|
75
|
-
if (!options.disabled && preload.value === "render") {
|
|
76
|
-
doPreload();
|
|
77
|
-
hasRenderFetched = true;
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
const getPropsSafeToSpread = () => {
|
|
81
|
-
const result = {};
|
|
82
|
-
const optionRecord = options;
|
|
83
|
-
for (const key in options) if (![
|
|
84
|
-
"activeProps",
|
|
85
|
-
"inactiveProps",
|
|
86
|
-
"activeOptions",
|
|
87
|
-
"to",
|
|
88
|
-
"preload",
|
|
89
|
-
"preloadDelay",
|
|
90
|
-
"hashScrollIntoView",
|
|
91
|
-
"replace",
|
|
92
|
-
"startTransition",
|
|
93
|
-
"resetScroll",
|
|
94
|
-
"viewTransition",
|
|
95
|
-
"children",
|
|
96
|
-
"target",
|
|
97
|
-
"disabled",
|
|
98
|
-
"style",
|
|
99
|
-
"class",
|
|
100
|
-
"onClick",
|
|
101
|
-
"onBlur",
|
|
102
|
-
"onFocus",
|
|
103
|
-
"onMouseEnter",
|
|
104
|
-
"onMouseLeave",
|
|
105
|
-
"onMouseOver",
|
|
106
|
-
"onMouseOut",
|
|
107
|
-
"onTouchStart",
|
|
108
|
-
"ignoreBlocker",
|
|
109
|
-
"params",
|
|
110
|
-
"search",
|
|
111
|
-
"hash",
|
|
112
|
-
"state",
|
|
113
|
-
"mask",
|
|
114
|
-
"reloadDocument",
|
|
115
|
-
"_asChild",
|
|
116
|
-
"from",
|
|
117
|
-
"additionalProps"
|
|
118
|
-
].includes(key)) result[key] = optionRecord[key];
|
|
119
|
-
return result;
|
|
120
|
-
};
|
|
26
|
+
const eventHandlers = getLinkEventHandlers(options);
|
|
121
27
|
if (type.value === "external") {
|
|
122
28
|
if (isDangerousProtocol(options.to, router.protocolAllowlist)) {
|
|
123
29
|
if (process.env.NODE_ENV !== "production") console.warn(`Blocked Link with dangerous protocol: ${options.to}`);
|
|
124
30
|
const safeProps = {
|
|
125
|
-
...getPropsSafeToSpread(),
|
|
31
|
+
...getPropsSafeToSpread(options),
|
|
126
32
|
ref,
|
|
127
33
|
target: options.target,
|
|
128
34
|
disabled: options.disabled,
|
|
@@ -131,11 +37,11 @@ function useLinkProps(options) {
|
|
|
131
37
|
onClick: options.onClick,
|
|
132
38
|
onBlur: options.onBlur,
|
|
133
39
|
onFocus: options.onFocus,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
40
|
+
onMouseenter: eventHandlers.onMouseenter,
|
|
41
|
+
onMouseleave: eventHandlers.onMouseleave,
|
|
42
|
+
onMouseover: eventHandlers.onMouseover,
|
|
43
|
+
onMouseout: eventHandlers.onMouseout,
|
|
44
|
+
onTouchstart: eventHandlers.onTouchstart
|
|
139
45
|
};
|
|
140
46
|
Object.keys(safeProps).forEach((key) => {
|
|
141
47
|
if (safeProps[key] === void 0) delete safeProps[key];
|
|
@@ -143,7 +49,7 @@ function useLinkProps(options) {
|
|
|
143
49
|
return Vue.computed(() => safeProps);
|
|
144
50
|
}
|
|
145
51
|
const externalProps = {
|
|
146
|
-
...getPropsSafeToSpread(),
|
|
52
|
+
...getPropsSafeToSpread(options),
|
|
147
53
|
ref,
|
|
148
54
|
href: options.to,
|
|
149
55
|
target: options.target,
|
|
@@ -153,22 +59,88 @@ function useLinkProps(options) {
|
|
|
153
59
|
onClick: options.onClick,
|
|
154
60
|
onBlur: options.onBlur,
|
|
155
61
|
onFocus: options.onFocus,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
62
|
+
onMouseenter: eventHandlers.onMouseenter,
|
|
63
|
+
onMouseleave: eventHandlers.onMouseleave,
|
|
64
|
+
onMouseover: eventHandlers.onMouseover,
|
|
65
|
+
onMouseout: eventHandlers.onMouseout,
|
|
66
|
+
onTouchstart: eventHandlers.onTouchstart
|
|
161
67
|
};
|
|
162
68
|
Object.keys(externalProps).forEach((key) => {
|
|
163
69
|
if (externalProps[key] === void 0) delete externalProps[key];
|
|
164
70
|
});
|
|
165
71
|
return Vue.computed(() => externalProps);
|
|
166
72
|
}
|
|
73
|
+
if (isServer ?? router.isServer) {
|
|
74
|
+
const next = router.buildLocation(options);
|
|
75
|
+
const href = getHref({
|
|
76
|
+
options,
|
|
77
|
+
router,
|
|
78
|
+
nextLocation: next
|
|
79
|
+
});
|
|
80
|
+
const isActive = getIsActive({
|
|
81
|
+
loc: router.stores.location.state,
|
|
82
|
+
nextLoc: next,
|
|
83
|
+
activeOptions: options.activeOptions,
|
|
84
|
+
router
|
|
85
|
+
});
|
|
86
|
+
const { resolvedActiveProps, resolvedInactiveProps, resolvedClassName, resolvedStyle } = resolveStyleProps({
|
|
87
|
+
options,
|
|
88
|
+
isActive
|
|
89
|
+
});
|
|
90
|
+
const result = combineResultProps({
|
|
91
|
+
href,
|
|
92
|
+
options,
|
|
93
|
+
isActive,
|
|
94
|
+
isTransitioning: false,
|
|
95
|
+
resolvedActiveProps,
|
|
96
|
+
resolvedInactiveProps,
|
|
97
|
+
resolvedClassName,
|
|
98
|
+
resolvedStyle
|
|
99
|
+
});
|
|
100
|
+
return Vue.ref(result);
|
|
101
|
+
}
|
|
102
|
+
const currentLocation = useStore(router.stores.location, (l) => l, { equal: (prev, next) => prev.href === next.href });
|
|
103
|
+
const next = Vue.computed(() => {
|
|
104
|
+
const opts = {
|
|
105
|
+
_fromLocation: currentLocation.value,
|
|
106
|
+
...options
|
|
107
|
+
};
|
|
108
|
+
return router.buildLocation(opts);
|
|
109
|
+
});
|
|
110
|
+
const preload = Vue.computed(() => {
|
|
111
|
+
if (options.reloadDocument) return false;
|
|
112
|
+
return options.preload ?? router.options.defaultPreload;
|
|
113
|
+
});
|
|
114
|
+
const preloadDelay = Vue.computed(() => options.preloadDelay ?? router.options.defaultPreloadDelay ?? 0);
|
|
115
|
+
const isActive = Vue.computed(() => getIsActive({
|
|
116
|
+
activeOptions: options.activeOptions,
|
|
117
|
+
loc: currentLocation.value,
|
|
118
|
+
nextLoc: next.value,
|
|
119
|
+
router
|
|
120
|
+
}));
|
|
121
|
+
const doPreload = () => router.preloadRoute({
|
|
122
|
+
...options,
|
|
123
|
+
_builtLocation: next.value
|
|
124
|
+
}).catch((err) => {
|
|
125
|
+
console.warn(err);
|
|
126
|
+
console.warn(preloadWarning);
|
|
127
|
+
});
|
|
128
|
+
const preloadViewportIoCallback = (entry) => {
|
|
129
|
+
if (entry?.isIntersecting) doPreload();
|
|
130
|
+
};
|
|
131
|
+
useIntersectionObserver(ref, preloadViewportIoCallback, { rootMargin: "100px" }, { disabled: () => !!options.disabled || !(preload.value === "viewport") });
|
|
132
|
+
Vue.effect(() => {
|
|
133
|
+
if (hasRenderFetched) return;
|
|
134
|
+
if (!options.disabled && preload.value === "render") {
|
|
135
|
+
doPreload();
|
|
136
|
+
hasRenderFetched = true;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
167
139
|
const handleClick = (e) => {
|
|
168
140
|
const elementTarget = e.currentTarget?.getAttribute("target");
|
|
169
141
|
const effectiveTarget = options.target !== void 0 ? options.target : elementTarget;
|
|
170
142
|
if (!options.disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!effectiveTarget || effectiveTarget === "_self") && e.button === 0) {
|
|
171
|
-
if (
|
|
143
|
+
if (options.reloadDocument) return;
|
|
172
144
|
e.preventDefault();
|
|
173
145
|
isTransitioning.value = true;
|
|
174
146
|
const unsub = router.subscribe("onResolved", () => {
|
|
@@ -176,7 +148,7 @@ function useLinkProps(options) {
|
|
|
176
148
|
isTransitioning.value = false;
|
|
177
149
|
});
|
|
178
150
|
router.navigate({
|
|
179
|
-
...
|
|
151
|
+
...options,
|
|
180
152
|
replace: options.replace,
|
|
181
153
|
resetScroll: options.resetScroll,
|
|
182
154
|
hashScrollIntoView: options.hashScrollIntoView,
|
|
@@ -217,81 +189,173 @@ function useLinkProps(options) {
|
|
|
217
189
|
for (const handler of handlers) if (handler) handler(event);
|
|
218
190
|
};
|
|
219
191
|
}
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
return (isActive.value ? {} : typeof inactiveProps === "function" ? inactiveProps() : inactiveProps) || {
|
|
230
|
-
class: void 0,
|
|
231
|
-
style: void 0
|
|
232
|
-
};
|
|
233
|
-
});
|
|
234
|
-
const resolvedClassName = Vue.computed(() => {
|
|
235
|
-
const classes = [
|
|
236
|
-
options.class,
|
|
237
|
-
resolvedActiveProps.value?.class,
|
|
238
|
-
resolvedInactiveProps.value?.class
|
|
239
|
-
].filter(Boolean);
|
|
240
|
-
return classes.length ? classes.join(" ") : void 0;
|
|
241
|
-
});
|
|
242
|
-
const resolvedStyle = Vue.computed(() => {
|
|
243
|
-
const result = {};
|
|
244
|
-
if (options.style) Object.assign(result, options.style);
|
|
245
|
-
if (resolvedActiveProps.value?.style) Object.assign(result, resolvedActiveProps.value.style);
|
|
246
|
-
if (resolvedInactiveProps.value?.style) Object.assign(result, resolvedInactiveProps.value.style);
|
|
247
|
-
return Object.keys(result).length > 0 ? result : void 0;
|
|
248
|
-
});
|
|
249
|
-
const href = Vue.computed(() => {
|
|
250
|
-
if (options.disabled) return;
|
|
251
|
-
const nextLocation = next.value;
|
|
252
|
-
const location = nextLocation?.maskedLocation ?? nextLocation;
|
|
253
|
-
const publicHref = location?.publicHref;
|
|
254
|
-
if (!publicHref) return void 0;
|
|
255
|
-
if (location?.external) return publicHref;
|
|
256
|
-
return router.history.createHref(publicHref) || "/";
|
|
257
|
-
});
|
|
192
|
+
const resolvedStyleProps = Vue.computed(() => resolveStyleProps({
|
|
193
|
+
options,
|
|
194
|
+
isActive: isActive.value
|
|
195
|
+
}));
|
|
196
|
+
const href = Vue.computed(() => getHref({
|
|
197
|
+
options,
|
|
198
|
+
router,
|
|
199
|
+
nextLocation: next.value
|
|
200
|
+
}));
|
|
258
201
|
const staticEventHandlers = {
|
|
259
202
|
onClick: composeEventHandlers([options.onClick, handleClick]),
|
|
260
203
|
onBlur: composeEventHandlers([options.onBlur, handleLeave]),
|
|
261
204
|
onFocus: composeEventHandlers([options.onFocus, enqueueIntentPreload]),
|
|
262
|
-
onMouseenter: composeEventHandlers([
|
|
263
|
-
onMouseover: composeEventHandlers([
|
|
264
|
-
onMouseleave: composeEventHandlers([
|
|
265
|
-
onMouseout: composeEventHandlers([
|
|
266
|
-
onTouchstart: composeEventHandlers([
|
|
205
|
+
onMouseenter: composeEventHandlers([eventHandlers.onMouseenter, enqueueIntentPreload]),
|
|
206
|
+
onMouseover: composeEventHandlers([eventHandlers.onMouseover, enqueueIntentPreload]),
|
|
207
|
+
onMouseleave: composeEventHandlers([eventHandlers.onMouseleave, handleLeave]),
|
|
208
|
+
onMouseout: composeEventHandlers([eventHandlers.onMouseout, handleLeave]),
|
|
209
|
+
onTouchstart: composeEventHandlers([eventHandlers.onTouchstart, handleTouchStart])
|
|
267
210
|
};
|
|
268
211
|
return Vue.computed(() => {
|
|
269
|
-
const
|
|
270
|
-
|
|
212
|
+
const { resolvedActiveProps, resolvedInactiveProps, resolvedClassName, resolvedStyle } = resolvedStyleProps.value;
|
|
213
|
+
return combineResultProps({
|
|
271
214
|
href: href.value,
|
|
215
|
+
options,
|
|
272
216
|
ref,
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
result["aria-disabled"] = true;
|
|
282
|
-
}
|
|
283
|
-
if (isActive.value) {
|
|
284
|
-
result["data-status"] = "active";
|
|
285
|
-
result["aria-current"] = "page";
|
|
286
|
-
}
|
|
287
|
-
if (isTransitioning.value) result["data-transitioning"] = "transitioning";
|
|
288
|
-
const activeP = resolvedActiveProps.value;
|
|
289
|
-
const inactiveP = resolvedInactiveProps.value;
|
|
290
|
-
for (const key of Object.keys(activeP)) if (key !== "class" && key !== "style") result[key] = activeP[key];
|
|
291
|
-
for (const key of Object.keys(inactiveP)) if (key !== "class" && key !== "style") result[key] = inactiveP[key];
|
|
292
|
-
return result;
|
|
217
|
+
staticEventHandlers,
|
|
218
|
+
isActive: isActive.value,
|
|
219
|
+
isTransitioning: isTransitioning.value,
|
|
220
|
+
resolvedActiveProps,
|
|
221
|
+
resolvedInactiveProps,
|
|
222
|
+
resolvedClassName,
|
|
223
|
+
resolvedStyle
|
|
224
|
+
});
|
|
293
225
|
});
|
|
294
226
|
}
|
|
227
|
+
function resolveStyleProps({ options, isActive }) {
|
|
228
|
+
const activeProps = options.activeProps || (() => ({ class: "active" }));
|
|
229
|
+
const resolvedActiveProps = (isActive ? typeof activeProps === "function" ? activeProps() : activeProps : {}) || {
|
|
230
|
+
class: void 0,
|
|
231
|
+
style: void 0
|
|
232
|
+
};
|
|
233
|
+
const inactiveProps = options.inactiveProps || (() => ({}));
|
|
234
|
+
const resolvedInactiveProps = (isActive ? {} : typeof inactiveProps === "function" ? inactiveProps() : inactiveProps) || {
|
|
235
|
+
class: void 0,
|
|
236
|
+
style: void 0
|
|
237
|
+
};
|
|
238
|
+
const classes = [
|
|
239
|
+
options.class,
|
|
240
|
+
resolvedActiveProps?.class,
|
|
241
|
+
resolvedInactiveProps?.class
|
|
242
|
+
].filter(Boolean);
|
|
243
|
+
const resolvedClassName = classes.length ? classes.join(" ") : void 0;
|
|
244
|
+
const result = {};
|
|
245
|
+
if (options.style) Object.assign(result, options.style);
|
|
246
|
+
if (resolvedActiveProps?.style) Object.assign(result, resolvedActiveProps.style);
|
|
247
|
+
if (resolvedInactiveProps?.style) Object.assign(result, resolvedInactiveProps.style);
|
|
248
|
+
return {
|
|
249
|
+
resolvedActiveProps,
|
|
250
|
+
resolvedInactiveProps,
|
|
251
|
+
resolvedClassName,
|
|
252
|
+
resolvedStyle: Object.keys(result).length > 0 ? result : void 0
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function combineResultProps({ href, options, isActive, isTransitioning, resolvedActiveProps, resolvedInactiveProps, resolvedClassName, resolvedStyle, ref, staticEventHandlers }) {
|
|
256
|
+
const result = {
|
|
257
|
+
...getPropsSafeToSpread(options),
|
|
258
|
+
ref,
|
|
259
|
+
...staticEventHandlers,
|
|
260
|
+
href,
|
|
261
|
+
disabled: !!options.disabled,
|
|
262
|
+
target: options.target
|
|
263
|
+
};
|
|
264
|
+
if (resolvedStyle) result.style = resolvedStyle;
|
|
265
|
+
if (resolvedClassName) result.class = resolvedClassName;
|
|
266
|
+
if (options.disabled) {
|
|
267
|
+
result.role = "link";
|
|
268
|
+
result["aria-disabled"] = true;
|
|
269
|
+
}
|
|
270
|
+
if (isActive) {
|
|
271
|
+
result["data-status"] = "active";
|
|
272
|
+
result["aria-current"] = "page";
|
|
273
|
+
}
|
|
274
|
+
if (isTransitioning) result["data-transitioning"] = "transitioning";
|
|
275
|
+
for (const key of Object.keys(resolvedActiveProps)) if (key !== "class" && key !== "style") result[key] = resolvedActiveProps[key];
|
|
276
|
+
for (const key of Object.keys(resolvedInactiveProps)) if (key !== "class" && key !== "style") result[key] = resolvedInactiveProps[key];
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
function getLinkEventHandlers(options) {
|
|
280
|
+
return {
|
|
281
|
+
onMouseenter: options.onMouseEnter ?? options.onMouseenter,
|
|
282
|
+
onMouseleave: options.onMouseLeave ?? options.onMouseleave,
|
|
283
|
+
onMouseover: options.onMouseOver ?? options.onMouseover,
|
|
284
|
+
onMouseout: options.onMouseOut ?? options.onMouseout,
|
|
285
|
+
onTouchstart: options.onTouchStart ?? options.onTouchstart
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
var propsUnsafeToSpread = new Set([
|
|
289
|
+
"activeProps",
|
|
290
|
+
"inactiveProps",
|
|
291
|
+
"activeOptions",
|
|
292
|
+
"to",
|
|
293
|
+
"preload",
|
|
294
|
+
"preloadDelay",
|
|
295
|
+
"hashScrollIntoView",
|
|
296
|
+
"replace",
|
|
297
|
+
"startTransition",
|
|
298
|
+
"resetScroll",
|
|
299
|
+
"viewTransition",
|
|
300
|
+
"children",
|
|
301
|
+
"target",
|
|
302
|
+
"disabled",
|
|
303
|
+
"style",
|
|
304
|
+
"class",
|
|
305
|
+
"onClick",
|
|
306
|
+
"onBlur",
|
|
307
|
+
"onFocus",
|
|
308
|
+
"onMouseEnter",
|
|
309
|
+
"onMouseenter",
|
|
310
|
+
"onMouseLeave",
|
|
311
|
+
"onMouseleave",
|
|
312
|
+
"onMouseOver",
|
|
313
|
+
"onMouseover",
|
|
314
|
+
"onMouseOut",
|
|
315
|
+
"onMouseout",
|
|
316
|
+
"onTouchStart",
|
|
317
|
+
"onTouchstart",
|
|
318
|
+
"ignoreBlocker",
|
|
319
|
+
"params",
|
|
320
|
+
"search",
|
|
321
|
+
"hash",
|
|
322
|
+
"state",
|
|
323
|
+
"mask",
|
|
324
|
+
"reloadDocument",
|
|
325
|
+
"_asChild",
|
|
326
|
+
"from",
|
|
327
|
+
"additionalProps"
|
|
328
|
+
]);
|
|
329
|
+
var getPropsSafeToSpread = (options) => {
|
|
330
|
+
const result = {};
|
|
331
|
+
for (const key in options) if (!propsUnsafeToSpread.has(key)) result[key] = options[key];
|
|
332
|
+
return result;
|
|
333
|
+
};
|
|
334
|
+
function getIsActive({ activeOptions, loc, nextLoc, router }) {
|
|
335
|
+
if (activeOptions?.exact) {
|
|
336
|
+
if (!exactPathTest(loc.pathname, nextLoc.pathname, router.basepath)) return false;
|
|
337
|
+
} else {
|
|
338
|
+
const currentPath = removeTrailingSlash(loc.pathname, router.basepath);
|
|
339
|
+
const nextPath = removeTrailingSlash(nextLoc.pathname, router.basepath);
|
|
340
|
+
if (!(currentPath.startsWith(nextPath) && (currentPath.length === nextPath.length || currentPath[nextPath.length] === "/"))) return false;
|
|
341
|
+
}
|
|
342
|
+
if (activeOptions?.includeSearch ?? true) {
|
|
343
|
+
if (!deepEqual(loc.search, nextLoc.search, {
|
|
344
|
+
partial: !activeOptions?.exact,
|
|
345
|
+
ignoreUndefined: !activeOptions?.explicitUndefined
|
|
346
|
+
})) return false;
|
|
347
|
+
}
|
|
348
|
+
if (activeOptions?.includeHash) return loc.hash === nextLoc.hash;
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
function getHref({ options, router, nextLocation }) {
|
|
352
|
+
if (options.disabled) return;
|
|
353
|
+
const location = nextLocation?.maskedLocation ?? nextLocation;
|
|
354
|
+
const publicHref = location?.publicHref;
|
|
355
|
+
if (!publicHref) return void 0;
|
|
356
|
+
if (location?.external) return publicHref;
|
|
357
|
+
return router.history.createHref(publicHref) || "/";
|
|
358
|
+
}
|
|
295
359
|
function createLink(Comp) {
|
|
296
360
|
return Vue.defineComponent({
|
|
297
361
|
name: "CreatedLink",
|
|
@@ -333,13 +397,13 @@ var LinkImpl = Vue.defineComponent({
|
|
|
333
397
|
"target"
|
|
334
398
|
],
|
|
335
399
|
setup(props, { attrs, slots }) {
|
|
336
|
-
const
|
|
400
|
+
const linkPropsSource = useLinkProps({
|
|
337
401
|
...props,
|
|
338
402
|
...attrs
|
|
339
403
|
});
|
|
340
404
|
return () => {
|
|
341
405
|
const Component = props._asChild || "a";
|
|
342
|
-
const linkProps =
|
|
406
|
+
const linkProps = Vue.unref(linkPropsSource);
|
|
343
407
|
const isActive = linkProps["data-status"] === "active";
|
|
344
408
|
const isTransitioning = linkProps["data-transitioning"] === "transitioning";
|
|
345
409
|
const slotContent = slots.default ? slots.default({
|