@tanstack/solid-router 2.0.0-alpha.1 → 2.0.0-alpha.3

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 (207) hide show
  1. package/dist/cjs/Asset.cjs +124 -167
  2. package/dist/cjs/Asset.cjs.map +1 -1
  3. package/dist/cjs/CatchBoundary.cjs +52 -68
  4. package/dist/cjs/CatchBoundary.cjs.map +1 -1
  5. package/dist/cjs/ClientOnly.cjs +61 -39
  6. package/dist/cjs/ClientOnly.cjs.map +1 -1
  7. package/dist/cjs/HeadContent.cjs +35 -27
  8. package/dist/cjs/HeadContent.cjs.map +1 -1
  9. package/dist/cjs/HeadContent.dev.cjs +48 -41
  10. package/dist/cjs/HeadContent.dev.cjs.map +1 -1
  11. package/dist/cjs/Match.cjs +367 -442
  12. package/dist/cjs/Match.cjs.map +1 -1
  13. package/dist/cjs/Matches.cjs +114 -158
  14. package/dist/cjs/Matches.cjs.map +1 -1
  15. package/dist/cjs/RouterProvider.cjs +29 -41
  16. package/dist/cjs/RouterProvider.cjs.map +1 -1
  17. package/dist/cjs/SafeFragment.cjs +7 -5
  18. package/dist/cjs/SafeFragment.cjs.map +1 -1
  19. package/dist/cjs/ScriptOnce.cjs +20 -22
  20. package/dist/cjs/ScriptOnce.cjs.map +1 -1
  21. package/dist/cjs/Scripts.cjs +43 -58
  22. package/dist/cjs/Scripts.cjs.map +1 -1
  23. package/dist/cjs/ScrollRestoration.cjs +26 -28
  24. package/dist/cjs/ScrollRestoration.cjs.map +1 -1
  25. package/dist/cjs/Transitioner.cjs +91 -124
  26. package/dist/cjs/Transitioner.cjs.map +1 -1
  27. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  28. package/dist/cjs/awaited.cjs +31 -53
  29. package/dist/cjs/awaited.cjs.map +1 -1
  30. package/dist/cjs/fileRoute.cjs +96 -91
  31. package/dist/cjs/fileRoute.cjs.map +1 -1
  32. package/dist/cjs/fileRoute.d.cts +2 -2
  33. package/dist/cjs/headContentUtils.cjs +132 -170
  34. package/dist/cjs/headContentUtils.cjs.map +1 -1
  35. package/dist/cjs/index.cjs +245 -176
  36. package/dist/cjs/index.dev.cjs +245 -176
  37. package/dist/cjs/lazyRouteComponent.cjs +48 -54
  38. package/dist/cjs/lazyRouteComponent.cjs.map +1 -1
  39. package/dist/cjs/link.cjs +310 -345
  40. package/dist/cjs/link.cjs.map +1 -1
  41. package/dist/cjs/matchContext.cjs +9 -23
  42. package/dist/cjs/matchContext.cjs.map +1 -1
  43. package/dist/cjs/not-found.cjs +26 -34
  44. package/dist/cjs/not-found.cjs.map +1 -1
  45. package/dist/cjs/renderRouteNotFound.cjs +23 -16
  46. package/dist/cjs/renderRouteNotFound.cjs.map +1 -1
  47. package/dist/cjs/route.cjs +200 -215
  48. package/dist/cjs/route.cjs.map +1 -1
  49. package/dist/cjs/router.cjs +18 -16
  50. package/dist/cjs/router.cjs.map +1 -1
  51. package/dist/cjs/routerContext.cjs +8 -22
  52. package/dist/cjs/routerContext.cjs.map +1 -1
  53. package/dist/cjs/scroll-restoration.cjs +25 -35
  54. package/dist/cjs/scroll-restoration.cjs.map +1 -1
  55. package/dist/cjs/ssr/RouterClient.cjs +18 -23
  56. package/dist/cjs/ssr/RouterClient.cjs.map +1 -1
  57. package/dist/cjs/ssr/RouterServer.cjs +10 -10
  58. package/dist/cjs/ssr/RouterServer.cjs.map +1 -1
  59. package/dist/cjs/ssr/client.cjs +2 -4
  60. package/dist/cjs/ssr/defaultRenderHandler.cjs +12 -16
  61. package/dist/cjs/ssr/defaultRenderHandler.cjs.map +1 -1
  62. package/dist/cjs/ssr/defaultStreamHandler.cjs +13 -18
  63. package/dist/cjs/ssr/defaultStreamHandler.cjs.map +1 -1
  64. package/dist/cjs/ssr/renderRouterToStream.cjs +26 -54
  65. package/dist/cjs/ssr/renderRouterToStream.cjs.map +1 -1
  66. package/dist/cjs/ssr/renderRouterToString.cjs +33 -57
  67. package/dist/cjs/ssr/renderRouterToString.cjs.map +1 -1
  68. package/dist/cjs/ssr/server.cjs +18 -18
  69. package/dist/cjs/useBlocker.cjs +140 -177
  70. package/dist/cjs/useBlocker.cjs.map +1 -1
  71. package/dist/cjs/useBlocker.d.cts +8 -5
  72. package/dist/cjs/useCanGoBack.cjs +6 -5
  73. package/dist/cjs/useCanGoBack.cjs.map +1 -1
  74. package/dist/cjs/useLoaderData.cjs +12 -11
  75. package/dist/cjs/useLoaderData.cjs.map +1 -1
  76. package/dist/cjs/useLoaderDeps.cjs +12 -14
  77. package/dist/cjs/useLoaderDeps.cjs.map +1 -1
  78. package/dist/cjs/useLocation.cjs +6 -7
  79. package/dist/cjs/useLocation.cjs.map +1 -1
  80. package/dist/cjs/useMatch.cjs +25 -46
  81. package/dist/cjs/useMatch.cjs.map +1 -1
  82. package/dist/cjs/useNavigate.cjs +20 -38
  83. package/dist/cjs/useNavigate.cjs.map +1 -1
  84. package/dist/cjs/useParams.cjs +14 -13
  85. package/dist/cjs/useParams.cjs.map +1 -1
  86. package/dist/cjs/useRouteContext.cjs +9 -8
  87. package/dist/cjs/useRouteContext.cjs.map +1 -1
  88. package/dist/cjs/useRouter.cjs +13 -26
  89. package/dist/cjs/useRouter.cjs.map +1 -1
  90. package/dist/cjs/useRouterState.cjs +40 -43
  91. package/dist/cjs/useRouterState.cjs.map +1 -1
  92. package/dist/cjs/useSearch.cjs +13 -12
  93. package/dist/cjs/useSearch.cjs.map +1 -1
  94. package/dist/cjs/utils.cjs +57 -49
  95. package/dist/cjs/utils.cjs.map +1 -1
  96. package/dist/esm/Asset.js +122 -166
  97. package/dist/esm/Asset.js.map +1 -1
  98. package/dist/esm/CatchBoundary.js +48 -50
  99. package/dist/esm/CatchBoundary.js.map +1 -1
  100. package/dist/esm/ClientOnly.js +58 -22
  101. package/dist/esm/ClientOnly.js.map +1 -1
  102. package/dist/esm/HeadContent.dev.js +46 -40
  103. package/dist/esm/HeadContent.dev.js.map +1 -1
  104. package/dist/esm/HeadContent.js +33 -26
  105. package/dist/esm/HeadContent.js.map +1 -1
  106. package/dist/esm/Match.js +359 -422
  107. package/dist/esm/Match.js.map +1 -1
  108. package/dist/esm/Matches.js +107 -142
  109. package/dist/esm/Matches.js.map +1 -1
  110. package/dist/esm/RouterProvider.js +26 -40
  111. package/dist/esm/RouterProvider.js.map +1 -1
  112. package/dist/esm/SafeFragment.js +6 -5
  113. package/dist/esm/SafeFragment.js.map +1 -1
  114. package/dist/esm/ScriptOnce.js +18 -21
  115. package/dist/esm/ScriptOnce.js.map +1 -1
  116. package/dist/esm/Scripts.js +42 -58
  117. package/dist/esm/Scripts.js.map +1 -1
  118. package/dist/esm/ScrollRestoration.js +25 -29
  119. package/dist/esm/ScrollRestoration.js.map +1 -1
  120. package/dist/esm/Transitioner.js +87 -105
  121. package/dist/esm/Transitioner.js.map +1 -1
  122. package/dist/esm/awaited.js +28 -36
  123. package/dist/esm/awaited.js.map +1 -1
  124. package/dist/esm/fileRoute.d.ts +2 -2
  125. package/dist/esm/fileRoute.js +90 -92
  126. package/dist/esm/fileRoute.js.map +1 -1
  127. package/dist/esm/headContentUtils.js +129 -152
  128. package/dist/esm/headContentUtils.js.map +1 -1
  129. package/dist/esm/index.dev.js +15 -115
  130. package/dist/esm/index.js +17 -116
  131. package/dist/esm/lazyRouteComponent.js +46 -53
  132. package/dist/esm/lazyRouteComponent.js.map +1 -1
  133. package/dist/esm/link.js +306 -329
  134. package/dist/esm/link.js.map +1 -1
  135. package/dist/esm/matchContext.js +7 -7
  136. package/dist/esm/matchContext.js.map +1 -1
  137. package/dist/esm/not-found.js +23 -33
  138. package/dist/esm/not-found.js.map +1 -1
  139. package/dist/esm/renderRouteNotFound.js +20 -15
  140. package/dist/esm/renderRouteNotFound.js.map +1 -1
  141. package/dist/esm/route.js +193 -218
  142. package/dist/esm/route.js.map +1 -1
  143. package/dist/esm/router.js +17 -17
  144. package/dist/esm/router.js.map +1 -1
  145. package/dist/esm/routerContext.js +6 -5
  146. package/dist/esm/routerContext.js.map +1 -1
  147. package/dist/esm/scroll-restoration.js +23 -34
  148. package/dist/esm/scroll-restoration.js.map +1 -1
  149. package/dist/esm/ssr/RouterClient.js +16 -22
  150. package/dist/esm/ssr/RouterClient.js.map +1 -1
  151. package/dist/esm/ssr/RouterServer.js +9 -10
  152. package/dist/esm/ssr/RouterServer.js.map +1 -1
  153. package/dist/esm/ssr/client.js +1 -4
  154. package/dist/esm/ssr/defaultRenderHandler.js +11 -15
  155. package/dist/esm/ssr/defaultRenderHandler.js.map +1 -1
  156. package/dist/esm/ssr/defaultStreamHandler.js +12 -17
  157. package/dist/esm/ssr/defaultStreamHandler.js.map +1 -1
  158. package/dist/esm/ssr/renderRouterToStream.js +23 -36
  159. package/dist/esm/ssr/renderRouterToStream.js.map +1 -1
  160. package/dist/esm/ssr/renderRouterToString.js +31 -40
  161. package/dist/esm/ssr/renderRouterToString.js.map +1 -1
  162. package/dist/esm/ssr/server.js +3 -10
  163. package/dist/esm/useBlocker.d.ts +8 -5
  164. package/dist/esm/useBlocker.js +136 -159
  165. package/dist/esm/useBlocker.js.map +1 -1
  166. package/dist/esm/useCanGoBack.js +6 -5
  167. package/dist/esm/useCanGoBack.js.map +1 -1
  168. package/dist/esm/useLoaderData.js +12 -11
  169. package/dist/esm/useLoaderData.js.map +1 -1
  170. package/dist/esm/useLoaderDeps.js +12 -14
  171. package/dist/esm/useLoaderDeps.js.map +1 -1
  172. package/dist/esm/useLocation.js +6 -7
  173. package/dist/esm/useLocation.js.map +1 -1
  174. package/dist/esm/useMatch.js +21 -28
  175. package/dist/esm/useMatch.js.map +1 -1
  176. package/dist/esm/useNavigate.js +18 -22
  177. package/dist/esm/useNavigate.js.map +1 -1
  178. package/dist/esm/useParams.js +14 -13
  179. package/dist/esm/useParams.js.map +1 -1
  180. package/dist/esm/useRouteContext.js +9 -8
  181. package/dist/esm/useRouteContext.js.map +1 -1
  182. package/dist/esm/useRouter.js +9 -8
  183. package/dist/esm/useRouter.js.map +1 -1
  184. package/dist/esm/useRouterState.js +38 -42
  185. package/dist/esm/useRouterState.js.map +1 -1
  186. package/dist/esm/useSearch.js +13 -12
  187. package/dist/esm/useSearch.js.map +1 -1
  188. package/dist/esm/utils.js +55 -33
  189. package/dist/esm/utils.js.map +1 -1
  190. package/dist/source/fileRoute.d.ts +2 -2
  191. package/dist/source/useBlocker.d.ts +8 -5
  192. package/dist/source/useBlocker.jsx +2 -2
  193. package/dist/source/useBlocker.jsx.map +1 -1
  194. package/dist/source/useRouterState.jsx +7 -0
  195. package/dist/source/useRouterState.jsx.map +1 -1
  196. package/package.json +3 -3
  197. package/src/fileRoute.ts +2 -2
  198. package/src/useBlocker.tsx +15 -10
  199. package/src/useRouterState.tsx +10 -0
  200. package/dist/cjs/index.cjs.map +0 -1
  201. package/dist/cjs/index.dev.cjs.map +0 -1
  202. package/dist/cjs/ssr/client.cjs.map +0 -1
  203. package/dist/cjs/ssr/server.cjs.map +0 -1
  204. package/dist/esm/index.dev.js.map +0 -1
  205. package/dist/esm/index.js.map +0 -1
  206. package/dist/esm/ssr/client.js.map +0 -1
  207. package/dist/esm/ssr/server.js.map +0 -1
package/dist/esm/link.js CHANGED
@@ -1,344 +1,321 @@
1
- import { createComponent, mergeProps, template, spread, insert, Dynamic, memo } from "@solidjs/web";
2
- import * as Solid from "solid-js";
3
- import { isDangerousProtocol, exactPathTest, removeTrailingSlash, deepEqual, functionalUpdate, preloadWarning } from "@tanstack/router-core";
4
- import { isServer } from "@tanstack/router-core/isServer";
5
- import { useRouterState } from "./useRouterState.js";
1
+ import { useHydrated } from "./ClientOnly.js";
6
2
  import { useRouter } from "./useRouter.js";
3
+ import { useRouterState } from "./useRouterState.js";
7
4
  import { useIntersectionObserver } from "./utils.js";
8
- import { useHydrated } from "./ClientOnly.js";
5
+ import { deepEqual, exactPathTest, functionalUpdate, isDangerousProtocol, preloadWarning, removeTrailingSlash } from "@tanstack/router-core";
6
+ import { Dynamic, createComponent, insert, memo, mergeProps, spread, template } from "@solidjs/web";
7
+ import * as Solid from "solid-js";
8
+ import { isServer } from "@tanstack/router-core/isServer";
9
+ //#region src/link.tsx
9
10
  var _tmpl$ = /* @__PURE__ */ template(`<svg><a>`);
10
11
  function mergeRefs(...refs) {
11
- return (el) => {
12
- for (const ref of refs) {
13
- if (typeof ref === "function") {
14
- ref(el);
15
- }
16
- }
17
- };
12
+ return (el) => {
13
+ for (const ref of refs) if (typeof ref === "function") ref(el);
14
+ };
18
15
  }
19
16
  function splitProps(props, keys) {
20
- return [props, Solid.omit(props, ...keys)];
17
+ return [props, Solid.omit(props, ...keys)];
21
18
  }
22
- const timeoutMap = /* @__PURE__ */ new WeakMap();
19
+ var timeoutMap = /* @__PURE__ */ new WeakMap();
23
20
  function useLinkProps(options) {
24
- const router = useRouter();
25
- const [isTransitioning, setIsTransitioning] = Solid.createSignal(false);
26
- const shouldHydrateHash = !isServer && !!router.options.ssr;
27
- const hasHydrated = useHydrated();
28
- let hasRenderFetched = false;
29
- const [local, rest] = splitProps(Solid.merge({
30
- activeProps: () => ({
31
- class: "active"
32
- }),
33
- inactiveProps: () => ({})
34
- }, options), ["activeProps", "inactiveProps", "activeOptions", "to", "preload", "preloadDelay", "hashScrollIntoView", "replace", "startTransition", "resetScroll", "viewTransition", "target", "disabled", "style", "class", "onClick", "onBlur", "onFocus", "onMouseEnter", "onMouseLeave", "onMouseOver", "onMouseOut", "onTouchStart", "ignoreBlocker"]);
35
- const [_, propsSafeToSpread] = splitProps(rest, ["params", "search", "hash", "state", "mask", "reloadDocument", "unsafeRelative"]);
36
- const currentLocation = useRouterState({
37
- select: (s) => s.location
38
- });
39
- const buildLocationKey = useRouterState({
40
- select: (s) => {
41
- const leaf = s.matches[s.matches.length - 1];
42
- return {
43
- search: leaf?.search,
44
- hash: s.location.hash,
45
- path: leaf?.pathname
46
- // path + params
47
- };
48
- }
49
- });
50
- const from = options.from;
51
- const _options = () => {
52
- const result = {
53
- ...options,
54
- from
55
- };
56
- return result;
57
- };
58
- const next = Solid.createMemo(() => {
59
- buildLocationKey();
60
- return router.buildLocation(_options());
61
- });
62
- const hrefOption = Solid.createMemo(() => {
63
- if (_options().disabled) return void 0;
64
- const location = next().maskedLocation ?? next();
65
- const publicHref = location.publicHref;
66
- const external = location.external;
67
- if (external) {
68
- return {
69
- href: publicHref,
70
- external: true
71
- };
72
- }
73
- return {
74
- href: router.history.createHref(publicHref) || "/",
75
- external: false
76
- };
77
- });
78
- const externalLink = Solid.createMemo(() => {
79
- const _href = hrefOption();
80
- if (_href?.external) {
81
- if (isDangerousProtocol(_href.href, router.protocolAllowlist)) {
82
- if (process.env.NODE_ENV !== "production") {
83
- console.warn(`Blocked Link with dangerous protocol: ${_href.href}`);
84
- }
85
- return void 0;
86
- }
87
- return _href.href;
88
- }
89
- const to = _options().to;
90
- const isSafeInternal = typeof to === "string" && to.charCodeAt(0) === 47 && // '/'
91
- to.charCodeAt(1) !== 47;
92
- if (isSafeInternal) return void 0;
93
- try {
94
- new URL(to);
95
- if (isDangerousProtocol(to, router.protocolAllowlist)) {
96
- if (process.env.NODE_ENV !== "production") {
97
- console.warn(`Blocked Link with dangerous protocol: ${to}`);
98
- }
99
- return void 0;
100
- }
101
- return to;
102
- } catch {
103
- }
104
- return void 0;
105
- });
106
- const preload = Solid.createMemo(() => {
107
- if (_options().reloadDocument || externalLink()) {
108
- return false;
109
- }
110
- return local.preload ?? router.options.defaultPreload;
111
- });
112
- const preloadDelay = () => local.preloadDelay ?? router.options.defaultPreloadDelay ?? 0;
113
- const isActive = Solid.createMemo(() => {
114
- if (externalLink()) return false;
115
- if (local.activeOptions?.exact) {
116
- const testExact = exactPathTest(currentLocation().pathname, next().pathname, router.basepath);
117
- if (!testExact) {
118
- return false;
119
- }
120
- } else {
121
- const currentPathSplit = removeTrailingSlash(currentLocation().pathname, router.basepath).split("/");
122
- const nextPathSplit = removeTrailingSlash(next()?.pathname, router.basepath)?.split("/");
123
- const pathIsFuzzyEqual = nextPathSplit?.every((d, i) => d === currentPathSplit[i]);
124
- if (!pathIsFuzzyEqual) {
125
- return false;
126
- }
127
- }
128
- if (local.activeOptions?.includeSearch ?? true) {
129
- const searchTest = deepEqual(currentLocation().search, next().search, {
130
- partial: !local.activeOptions?.exact,
131
- ignoreUndefined: !local.activeOptions?.explicitUndefined
132
- });
133
- if (!searchTest) {
134
- return false;
135
- }
136
- }
137
- if (local.activeOptions?.includeHash) {
138
- const currentHash = shouldHydrateHash && !hasHydrated() ? "" : currentLocation().hash;
139
- return currentHash === next().hash;
140
- }
141
- return true;
142
- });
143
- const doPreload = () => router.preloadRoute(_options()).catch((err) => {
144
- console.warn(err);
145
- console.warn(preloadWarning);
146
- });
147
- const preloadViewportIoCallback = (entry) => {
148
- if (entry?.isIntersecting) {
149
- doPreload();
150
- }
151
- };
152
- const [ref, setRefSignal] = Solid.createSignal(null);
153
- const setRef = (el) => {
154
- Solid.runWithOwner(null, () => {
155
- setRefSignal(el);
156
- });
157
- };
158
- useIntersectionObserver(ref, preloadViewportIoCallback, {
159
- rootMargin: "100px"
160
- }, {
161
- disabled: !!local.disabled || !(Solid.untrack(preload) === "viewport")
162
- });
163
- Solid.createEffect(preload, (preloadValue) => {
164
- if (hasRenderFetched) {
165
- return;
166
- }
167
- if (!local.disabled && preloadValue === "render") {
168
- doPreload();
169
- hasRenderFetched = true;
170
- }
171
- });
172
- if (Solid.untrack(externalLink)) {
173
- return Solid.merge(propsSafeToSpread, {
174
- // ref: mergeRefs(setRef, _options().ref),
175
- href: externalLink()
176
- }, splitProps(local, ["target", "disabled", "style", "class", "onClick", "onBlur", "onFocus", "onMouseEnter", "onMouseLeave", "onMouseOut", "onMouseOver", "onTouchStart"])[0]);
177
- }
178
- const handleClick = (e) => {
179
- const elementTarget = e.currentTarget.getAttribute("target");
180
- const effectiveTarget = local.target !== void 0 ? local.target : elementTarget;
181
- if (!local.disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!effectiveTarget || effectiveTarget === "_self") && e.button === 0) {
182
- e.preventDefault();
183
- setIsTransitioning(true);
184
- const unsub = router.subscribe("onResolved", () => {
185
- unsub();
186
- setIsTransitioning(false);
187
- });
188
- router.navigate({
189
- ..._options(),
190
- replace: local.replace,
191
- resetScroll: local.resetScroll,
192
- hashScrollIntoView: local.hashScrollIntoView,
193
- startTransition: local.startTransition,
194
- viewTransition: local.viewTransition,
195
- ignoreBlocker: local.ignoreBlocker
196
- });
197
- }
198
- };
199
- const enqueueIntentPreload = (e) => {
200
- if (local.disabled || preload() !== "intent") return;
201
- if (!preloadDelay()) {
202
- doPreload();
203
- return;
204
- }
205
- const eventTarget = e.currentTarget || e.target;
206
- if (!eventTarget || timeoutMap.has(eventTarget)) return;
207
- timeoutMap.set(eventTarget, setTimeout(() => {
208
- timeoutMap.delete(eventTarget);
209
- doPreload();
210
- }, preloadDelay()));
211
- };
212
- const handleTouchStart = (_2) => {
213
- if (local.disabled || preload() !== "intent") return;
214
- doPreload();
215
- };
216
- const handleLeave = (e) => {
217
- if (local.disabled) return;
218
- const eventTarget = e.currentTarget || e.target;
219
- if (eventTarget) {
220
- const id = timeoutMap.get(eventTarget);
221
- clearTimeout(id);
222
- timeoutMap.delete(eventTarget);
223
- }
224
- };
225
- function callHandler(event, handler) {
226
- if (handler) {
227
- if (typeof handler === "function") {
228
- handler(event);
229
- } else {
230
- handler[0](handler[1], event);
231
- }
232
- }
233
- return event.defaultPrevented;
234
- }
235
- function composeEventHandlers(handlers) {
236
- return (event) => {
237
- for (const handler of handlers) {
238
- callHandler(event, handler);
239
- }
240
- };
241
- }
242
- const resolvedActiveProps = () => isActive() ? functionalUpdate(local.activeProps, {}) ?? {} : {};
243
- const resolvedInactiveProps = () => isActive() ? {} : functionalUpdate(local.inactiveProps, {});
244
- const resolvedClassName = () => [local.class, resolvedActiveProps().class, resolvedInactiveProps().class].filter(Boolean).join(" ");
245
- const resolvedStyle = () => ({
246
- ...local.style,
247
- ...resolvedActiveProps().style,
248
- ...resolvedInactiveProps().style
249
- });
250
- return Solid.merge(propsSafeToSpread, resolvedActiveProps, resolvedInactiveProps, () => {
251
- return {
252
- href: hrefOption()?.href,
253
- ref: mergeRefs(setRef, _options().ref),
254
- onClick: composeEventHandlers([local.onClick, handleClick]),
255
- onBlur: composeEventHandlers([local.onBlur, handleLeave]),
256
- onFocus: composeEventHandlers([local.onFocus, enqueueIntentPreload]),
257
- onMouseEnter: composeEventHandlers([local.onMouseEnter, enqueueIntentPreload]),
258
- onMouseOver: composeEventHandlers([local.onMouseOver, enqueueIntentPreload]),
259
- onMouseLeave: composeEventHandlers([local.onMouseLeave, handleLeave]),
260
- onMouseOut: composeEventHandlers([local.onMouseOut, handleLeave]),
261
- onTouchStart: composeEventHandlers([local.onTouchStart, handleTouchStart]),
262
- disabled: !!local.disabled,
263
- target: local.target,
264
- ...(() => {
265
- const s = resolvedStyle();
266
- return Object.keys(s).length ? {
267
- style: s
268
- } : {};
269
- })(),
270
- ...(() => {
271
- const c = resolvedClassName();
272
- return c ? {
273
- class: c
274
- } : {};
275
- })(),
276
- ...local.disabled && {
277
- role: "link",
278
- "aria-disabled": "true"
279
- },
280
- ...isActive() && {
281
- "data-status": "active",
282
- "aria-current": "page"
283
- },
284
- ...isTransitioning() && {
285
- "data-transitioning": "transitioning"
286
- }
287
- };
288
- });
21
+ const router = useRouter();
22
+ const [isTransitioning, setIsTransitioning] = Solid.createSignal(false);
23
+ const shouldHydrateHash = !isServer && !!router.options.ssr;
24
+ const hasHydrated = useHydrated();
25
+ let hasRenderFetched = false;
26
+ const [local, rest] = splitProps(Solid.merge({
27
+ activeProps: () => ({ class: "active" }),
28
+ inactiveProps: () => ({})
29
+ }, options), [
30
+ "activeProps",
31
+ "inactiveProps",
32
+ "activeOptions",
33
+ "to",
34
+ "preload",
35
+ "preloadDelay",
36
+ "hashScrollIntoView",
37
+ "replace",
38
+ "startTransition",
39
+ "resetScroll",
40
+ "viewTransition",
41
+ "target",
42
+ "disabled",
43
+ "style",
44
+ "class",
45
+ "onClick",
46
+ "onBlur",
47
+ "onFocus",
48
+ "onMouseEnter",
49
+ "onMouseLeave",
50
+ "onMouseOver",
51
+ "onMouseOut",
52
+ "onTouchStart",
53
+ "ignoreBlocker"
54
+ ]);
55
+ const [_, propsSafeToSpread] = splitProps(rest, [
56
+ "params",
57
+ "search",
58
+ "hash",
59
+ "state",
60
+ "mask",
61
+ "reloadDocument",
62
+ "unsafeRelative"
63
+ ]);
64
+ const currentLocation = useRouterState({ select: (s) => s.location });
65
+ const buildLocationKey = useRouterState({ select: (s) => {
66
+ const leaf = s.matches[s.matches.length - 1];
67
+ return {
68
+ search: leaf?.search,
69
+ hash: s.location.hash,
70
+ path: leaf?.pathname
71
+ };
72
+ } });
73
+ const from = options.from;
74
+ const _options = () => {
75
+ return {
76
+ ...options,
77
+ from
78
+ };
79
+ };
80
+ const next = Solid.createMemo(() => {
81
+ buildLocationKey();
82
+ return router.buildLocation(_options());
83
+ });
84
+ const hrefOption = Solid.createMemo(() => {
85
+ if (_options().disabled) return void 0;
86
+ const location = next().maskedLocation ?? next();
87
+ const publicHref = location.publicHref;
88
+ if (location.external) return {
89
+ href: publicHref,
90
+ external: true
91
+ };
92
+ return {
93
+ href: router.history.createHref(publicHref) || "/",
94
+ external: false
95
+ };
96
+ });
97
+ const externalLink = Solid.createMemo(() => {
98
+ const _href = hrefOption();
99
+ if (_href?.external) {
100
+ if (isDangerousProtocol(_href.href, router.protocolAllowlist)) {
101
+ if (process.env.NODE_ENV !== "production") console.warn(`Blocked Link with dangerous protocol: ${_href.href}`);
102
+ return;
103
+ }
104
+ return _href.href;
105
+ }
106
+ const to = _options().to;
107
+ if (typeof to === "string" && to.charCodeAt(0) === 47 && to.charCodeAt(1) !== 47) return void 0;
108
+ try {
109
+ new URL(to);
110
+ if (isDangerousProtocol(to, router.protocolAllowlist)) {
111
+ if (process.env.NODE_ENV !== "production") console.warn(`Blocked Link with dangerous protocol: ${to}`);
112
+ return;
113
+ }
114
+ return to;
115
+ } catch {}
116
+ });
117
+ const preload = Solid.createMemo(() => {
118
+ if (_options().reloadDocument || externalLink()) return false;
119
+ return local.preload ?? router.options.defaultPreload;
120
+ });
121
+ const preloadDelay = () => local.preloadDelay ?? router.options.defaultPreloadDelay ?? 0;
122
+ const isActive = Solid.createMemo(() => {
123
+ if (externalLink()) return false;
124
+ if (local.activeOptions?.exact) {
125
+ if (!exactPathTest(currentLocation().pathname, next().pathname, router.basepath)) return false;
126
+ } else {
127
+ const currentPathSplit = removeTrailingSlash(currentLocation().pathname, router.basepath).split("/");
128
+ if (!(removeTrailingSlash(next()?.pathname, router.basepath)?.split("/"))?.every((d, i) => d === currentPathSplit[i])) return false;
129
+ }
130
+ if (local.activeOptions?.includeSearch ?? true) {
131
+ if (!deepEqual(currentLocation().search, next().search, {
132
+ partial: !local.activeOptions?.exact,
133
+ ignoreUndefined: !local.activeOptions?.explicitUndefined
134
+ })) return false;
135
+ }
136
+ if (local.activeOptions?.includeHash) return (shouldHydrateHash && !hasHydrated() ? "" : currentLocation().hash) === next().hash;
137
+ return true;
138
+ });
139
+ const doPreload = () => router.preloadRoute(_options()).catch((err) => {
140
+ console.warn(err);
141
+ console.warn(preloadWarning);
142
+ });
143
+ const preloadViewportIoCallback = (entry) => {
144
+ if (entry?.isIntersecting) doPreload();
145
+ };
146
+ const [ref, setRefSignal] = Solid.createSignal(null);
147
+ const setRef = (el) => {
148
+ Solid.runWithOwner(null, () => {
149
+ setRefSignal(el);
150
+ });
151
+ };
152
+ useIntersectionObserver(ref, preloadViewportIoCallback, { rootMargin: "100px" }, { disabled: !!local.disabled || !(Solid.untrack(preload) === "viewport") });
153
+ Solid.createEffect(preload, (preloadValue) => {
154
+ if (hasRenderFetched) return;
155
+ if (!local.disabled && preloadValue === "render") {
156
+ doPreload();
157
+ hasRenderFetched = true;
158
+ }
159
+ });
160
+ if (Solid.untrack(externalLink)) return Solid.merge(propsSafeToSpread, { href: externalLink() }, splitProps(local, [
161
+ "target",
162
+ "disabled",
163
+ "style",
164
+ "class",
165
+ "onClick",
166
+ "onBlur",
167
+ "onFocus",
168
+ "onMouseEnter",
169
+ "onMouseLeave",
170
+ "onMouseOut",
171
+ "onMouseOver",
172
+ "onTouchStart"
173
+ ])[0]);
174
+ const handleClick = (e) => {
175
+ const elementTarget = e.currentTarget.getAttribute("target");
176
+ const effectiveTarget = local.target !== void 0 ? local.target : elementTarget;
177
+ if (!local.disabled && !isCtrlEvent(e) && !e.defaultPrevented && (!effectiveTarget || effectiveTarget === "_self") && e.button === 0) {
178
+ e.preventDefault();
179
+ setIsTransitioning(true);
180
+ const unsub = router.subscribe("onResolved", () => {
181
+ unsub();
182
+ setIsTransitioning(false);
183
+ });
184
+ router.navigate({
185
+ ..._options(),
186
+ replace: local.replace,
187
+ resetScroll: local.resetScroll,
188
+ hashScrollIntoView: local.hashScrollIntoView,
189
+ startTransition: local.startTransition,
190
+ viewTransition: local.viewTransition,
191
+ ignoreBlocker: local.ignoreBlocker
192
+ });
193
+ }
194
+ };
195
+ const enqueueIntentPreload = (e) => {
196
+ if (local.disabled || preload() !== "intent") return;
197
+ if (!preloadDelay()) {
198
+ doPreload();
199
+ return;
200
+ }
201
+ const eventTarget = e.currentTarget || e.target;
202
+ if (!eventTarget || timeoutMap.has(eventTarget)) return;
203
+ timeoutMap.set(eventTarget, setTimeout(() => {
204
+ timeoutMap.delete(eventTarget);
205
+ doPreload();
206
+ }, preloadDelay()));
207
+ };
208
+ const handleTouchStart = (_) => {
209
+ if (local.disabled || preload() !== "intent") return;
210
+ doPreload();
211
+ };
212
+ const handleLeave = (e) => {
213
+ if (local.disabled) return;
214
+ const eventTarget = e.currentTarget || e.target;
215
+ if (eventTarget) {
216
+ const id = timeoutMap.get(eventTarget);
217
+ clearTimeout(id);
218
+ timeoutMap.delete(eventTarget);
219
+ }
220
+ };
221
+ /** Call a JSX.EventHandlerUnion with the event. */
222
+ function callHandler(event, handler) {
223
+ if (handler) if (typeof handler === "function") handler(event);
224
+ else handler[0](handler[1], event);
225
+ return event.defaultPrevented;
226
+ }
227
+ function composeEventHandlers(handlers) {
228
+ return (event) => {
229
+ for (const handler of handlers) callHandler(event, handler);
230
+ };
231
+ }
232
+ const resolvedActiveProps = () => isActive() ? functionalUpdate(local.activeProps, {}) ?? {} : {};
233
+ const resolvedInactiveProps = () => isActive() ? {} : functionalUpdate(local.inactiveProps, {});
234
+ const resolvedClassName = () => [
235
+ local.class,
236
+ resolvedActiveProps().class,
237
+ resolvedInactiveProps().class
238
+ ].filter(Boolean).join(" ");
239
+ const resolvedStyle = () => ({
240
+ ...local.style,
241
+ ...resolvedActiveProps().style,
242
+ ...resolvedInactiveProps().style
243
+ });
244
+ return Solid.merge(propsSafeToSpread, resolvedActiveProps, resolvedInactiveProps, () => {
245
+ return {
246
+ href: hrefOption()?.href,
247
+ ref: mergeRefs(setRef, _options().ref),
248
+ onClick: composeEventHandlers([local.onClick, handleClick]),
249
+ onBlur: composeEventHandlers([local.onBlur, handleLeave]),
250
+ onFocus: composeEventHandlers([local.onFocus, enqueueIntentPreload]),
251
+ onMouseEnter: composeEventHandlers([local.onMouseEnter, enqueueIntentPreload]),
252
+ onMouseOver: composeEventHandlers([local.onMouseOver, enqueueIntentPreload]),
253
+ onMouseLeave: composeEventHandlers([local.onMouseLeave, handleLeave]),
254
+ onMouseOut: composeEventHandlers([local.onMouseOut, handleLeave]),
255
+ onTouchStart: composeEventHandlers([local.onTouchStart, handleTouchStart]),
256
+ disabled: !!local.disabled,
257
+ target: local.target,
258
+ ...(() => {
259
+ const s = resolvedStyle();
260
+ return Object.keys(s).length ? { style: s } : {};
261
+ })(),
262
+ ...(() => {
263
+ const c = resolvedClassName();
264
+ return c ? { class: c } : {};
265
+ })(),
266
+ ...local.disabled && {
267
+ role: "link",
268
+ "aria-disabled": "true"
269
+ },
270
+ ...isActive() && {
271
+ "data-status": "active",
272
+ "aria-current": "page"
273
+ },
274
+ ...isTransitioning() && { "data-transitioning": "transitioning" }
275
+ };
276
+ });
289
277
  }
290
278
  function createLink(Comp) {
291
- return (props) => createComponent(Link, mergeProps(props, {
292
- _asChild: Comp
293
- }));
279
+ return (props) => createComponent(Link, mergeProps(props, { _asChild: Comp }));
294
280
  }
295
- const Link = (props) => {
296
- const [local, rest] = splitProps(props, ["_asChild", "children"]);
297
- const [_, linkProps] = splitProps(useLinkProps(rest), ["type"]);
298
- const resolvedChildren = Solid.children(() => local.children);
299
- const children = () => {
300
- const ch = resolvedChildren();
301
- if (typeof ch === "function") {
302
- return ch({
303
- get isActive() {
304
- return linkProps["data-status"] === "active";
305
- },
306
- get isTransitioning() {
307
- return linkProps["data-transitioning"] === "transitioning";
308
- }
309
- });
310
- }
311
- return ch;
312
- };
313
- if (local._asChild === "svg") {
314
- const [_2, svgLinkProps] = splitProps(linkProps, ["class"]);
315
- return (() => {
316
- var _el$ = _tmpl$(), _el$2 = _el$.firstChild;
317
- spread(_el$2, svgLinkProps, false, true);
318
- insert(_el$2, children);
319
- return _el$;
320
- })();
321
- }
322
- return createComponent(Dynamic, mergeProps({
323
- get component() {
324
- return memo(() => !!local._asChild)() ? local._asChild : "a";
325
- }
326
- }, linkProps, {
327
- get children() {
328
- return children();
329
- }
330
- }));
281
+ var Link = (props) => {
282
+ const [local, rest] = splitProps(props, ["_asChild", "children"]);
283
+ const [_, linkProps] = splitProps(useLinkProps(rest), ["type"]);
284
+ const resolvedChildren = Solid.children(() => local.children);
285
+ const children = () => {
286
+ const ch = resolvedChildren();
287
+ if (typeof ch === "function") return ch({
288
+ get isActive() {
289
+ return linkProps["data-status"] === "active";
290
+ },
291
+ get isTransitioning() {
292
+ return linkProps["data-transitioning"] === "transitioning";
293
+ }
294
+ });
295
+ return ch;
296
+ };
297
+ if (local._asChild === "svg") {
298
+ const [_, svgLinkProps] = splitProps(linkProps, ["class"]);
299
+ return (() => {
300
+ var _el$ = _tmpl$(), _el$2 = _el$.firstChild;
301
+ spread(_el$2, svgLinkProps, false, true);
302
+ insert(_el$2, children);
303
+ return _el$;
304
+ })();
305
+ }
306
+ return createComponent(Dynamic, mergeProps({ get component() {
307
+ return memo(() => !!local._asChild)() ? local._asChild : "a";
308
+ } }, linkProps, { get children() {
309
+ return children();
310
+ } }));
331
311
  };
332
312
  function isCtrlEvent(e) {
333
- return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
313
+ return !!(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey);
334
314
  }
335
- const linkOptions = (options) => {
336
- return options;
337
- };
338
- export {
339
- Link,
340
- createLink,
341
- linkOptions,
342
- useLinkProps
315
+ var linkOptions = (options) => {
316
+ return options;
343
317
  };
344
- //# sourceMappingURL=link.js.map
318
+ //#endregion
319
+ export { Link, createLink, linkOptions, useLinkProps };
320
+
321
+ //# sourceMappingURL=link.js.map