@tanstack/vue-router 1.167.5 → 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.
Files changed (95) hide show
  1. package/dist/esm/Match.js +55 -61
  2. package/dist/esm/Match.js.map +1 -1
  3. package/dist/esm/Matches.js +8 -15
  4. package/dist/esm/Matches.js.map +1 -1
  5. package/dist/esm/Scripts.js +7 -6
  6. package/dist/esm/Scripts.js.map +1 -1
  7. package/dist/esm/Transitioner.js +18 -24
  8. package/dist/esm/Transitioner.js.map +1 -1
  9. package/dist/esm/headContentUtils.js +13 -15
  10. package/dist/esm/headContentUtils.js.map +1 -1
  11. package/dist/esm/index.dev.js +6 -6
  12. package/dist/esm/index.js +6 -6
  13. package/dist/esm/link.js +242 -178
  14. package/dist/esm/link.js.map +1 -1
  15. package/dist/esm/matchContext.d.ts +8 -14
  16. package/dist/esm/matchContext.js +11 -9
  17. package/dist/esm/matchContext.js.map +1 -1
  18. package/dist/esm/not-found.js +6 -3
  19. package/dist/esm/not-found.js.map +1 -1
  20. package/dist/esm/router.js +2 -1
  21. package/dist/esm/router.js.map +1 -1
  22. package/dist/esm/routerStores.d.ts +13 -0
  23. package/dist/esm/routerStores.js +33 -0
  24. package/dist/esm/routerStores.js.map +1 -0
  25. package/dist/esm/ssr/RouterClient.js +1 -1
  26. package/dist/esm/ssr/RouterClient.js.map +1 -1
  27. package/dist/esm/ssr/renderRouterToStream.js +2 -2
  28. package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
  29. package/dist/esm/ssr/renderRouterToString.js +1 -1
  30. package/dist/esm/ssr/renderRouterToString.js.map +1 -1
  31. package/dist/esm/useCanGoBack.d.ts +1 -1
  32. package/dist/esm/useCanGoBack.js +3 -2
  33. package/dist/esm/useCanGoBack.js.map +1 -1
  34. package/dist/esm/useLocation.js +3 -2
  35. package/dist/esm/useLocation.js.map +1 -1
  36. package/dist/esm/useMatch.js +29 -19
  37. package/dist/esm/useMatch.js.map +1 -1
  38. package/dist/esm/useRouterState.js +4 -4
  39. package/dist/esm/useRouterState.js.map +1 -1
  40. package/dist/source/Match.jsx +121 -159
  41. package/dist/source/Match.jsx.map +1 -1
  42. package/dist/source/Matches.jsx +11 -28
  43. package/dist/source/Matches.jsx.map +1 -1
  44. package/dist/source/Scripts.jsx +32 -35
  45. package/dist/source/Scripts.jsx.map +1 -1
  46. package/dist/source/Transitioner.jsx +19 -21
  47. package/dist/source/Transitioner.jsx.map +1 -1
  48. package/dist/source/headContentUtils.jsx +51 -61
  49. package/dist/source/headContentUtils.jsx.map +1 -1
  50. package/dist/source/link.jsx +298 -249
  51. package/dist/source/link.jsx.map +1 -1
  52. package/dist/source/matchContext.d.ts +8 -14
  53. package/dist/source/matchContext.jsx +17 -23
  54. package/dist/source/matchContext.jsx.map +1 -1
  55. package/dist/source/not-found.jsx +6 -5
  56. package/dist/source/not-found.jsx.map +1 -1
  57. package/dist/source/router.js +2 -1
  58. package/dist/source/router.js.map +1 -1
  59. package/dist/source/routerStores.d.ts +13 -0
  60. package/dist/source/routerStores.js +37 -0
  61. package/dist/source/routerStores.js.map +1 -0
  62. package/dist/source/ssr/RouterClient.jsx +1 -1
  63. package/dist/source/ssr/RouterClient.jsx.map +1 -1
  64. package/dist/source/ssr/renderRouterToStream.jsx +2 -2
  65. package/dist/source/ssr/renderRouterToStream.jsx.map +1 -1
  66. package/dist/source/ssr/renderRouterToString.jsx +1 -1
  67. package/dist/source/ssr/renderRouterToString.jsx.map +1 -1
  68. package/dist/source/useCanGoBack.d.ts +1 -1
  69. package/dist/source/useCanGoBack.js +4 -2
  70. package/dist/source/useCanGoBack.js.map +1 -1
  71. package/dist/source/useLocation.jsx +4 -4
  72. package/dist/source/useLocation.jsx.map +1 -1
  73. package/dist/source/useMatch.jsx +60 -38
  74. package/dist/source/useMatch.jsx.map +1 -1
  75. package/dist/source/useRouterState.jsx +4 -4
  76. package/dist/source/useRouterState.jsx.map +1 -1
  77. package/package.json +2 -2
  78. package/skills/vue-router/SKILL.md +3 -0
  79. package/src/Match.tsx +168 -180
  80. package/src/Matches.tsx +18 -31
  81. package/src/Scripts.tsx +40 -40
  82. package/src/Transitioner.tsx +35 -23
  83. package/src/headContentUtils.tsx +101 -107
  84. package/src/link.tsx +445 -300
  85. package/src/matchContext.tsx +23 -25
  86. package/src/not-found.tsx +9 -5
  87. package/src/router.ts +2 -1
  88. package/src/routerStores.ts +54 -0
  89. package/src/ssr/RouterClient.tsx +1 -1
  90. package/src/ssr/renderRouterToStream.tsx +2 -2
  91. package/src/ssr/renderRouterToString.tsx +1 -1
  92. package/src/useCanGoBack.ts +7 -2
  93. package/src/useLocation.tsx +8 -5
  94. package/src/useMatch.tsx +95 -49
  95. 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
- useIntersectionObserver(ref, preloadViewportIoCallback, { rootMargin: "100px" }, { disabled: () => !!options.disabled || !(preload.value === "viewport") });
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
- onMouseEnter: options.onMouseEnter,
135
- onMouseLeave: options.onMouseLeave,
136
- onMouseOver: options.onMouseOver,
137
- onMouseOut: options.onMouseOut,
138
- onTouchStart: options.onTouchStart
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
- onMouseEnter: options.onMouseEnter,
157
- onMouseLeave: options.onMouseLeave,
158
- onMouseOver: options.onMouseOver,
159
- onMouseOut: options.onMouseOut,
160
- onTouchStart: options.onTouchStart
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 (_options.value.reloadDocument) return;
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
- ..._options.value,
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 resolvedActiveProps = Vue.computed(() => {
221
- const activeProps = options.activeProps || (() => ({ class: "active" }));
222
- return (isActive.value ? typeof activeProps === "function" ? activeProps() : activeProps : {}) || {
223
- class: void 0,
224
- style: void 0
225
- };
226
- });
227
- const resolvedInactiveProps = Vue.computed(() => {
228
- const inactiveProps = options.inactiveProps || (() => ({}));
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([options.onMouseEnter, enqueueIntentPreload]),
263
- onMouseover: composeEventHandlers([options.onMouseOver, enqueueIntentPreload]),
264
- onMouseleave: composeEventHandlers([options.onMouseLeave, handleLeave]),
265
- onMouseout: composeEventHandlers([options.onMouseOut, handleLeave]),
266
- onTouchstart: composeEventHandlers([options.onTouchStart, handleTouchStart])
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 result = {
270
- ...getPropsSafeToSpread(),
212
+ const { resolvedActiveProps, resolvedInactiveProps, resolvedClassName, resolvedStyle } = resolvedStyleProps.value;
213
+ return combineResultProps({
271
214
  href: href.value,
215
+ options,
272
216
  ref,
273
- ...staticEventHandlers,
274
- disabled: !!options.disabled,
275
- target: options.target
276
- };
277
- if (resolvedStyle.value) result.style = resolvedStyle.value;
278
- if (resolvedClassName.value) result.class = resolvedClassName.value;
279
- if (options.disabled) {
280
- result.role = "link";
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 linkPropsComputed = useLinkProps({
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 = linkPropsComputed.value;
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({