@tanstack/router-devtools 1.7.1 → 1.8.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 (70) hide show
  1. package/dist/cjs/Explorer.cjs +246 -0
  2. package/dist/cjs/Explorer.cjs.map +1 -0
  3. package/dist/cjs/devtools.cjs +1150 -0
  4. package/dist/cjs/devtools.cjs.map +1 -0
  5. package/dist/cjs/index.cjs +6 -0
  6. package/dist/cjs/index.cjs.map +1 -0
  7. package/dist/cjs/styledComponents.cjs +93 -0
  8. package/dist/cjs/styledComponents.cjs.map +1 -0
  9. package/dist/cjs/theme.cjs +28 -0
  10. package/dist/cjs/theme.cjs.map +1 -0
  11. package/dist/cjs/useLocalStorage.cjs +45 -0
  12. package/dist/cjs/useLocalStorage.cjs.map +1 -0
  13. package/dist/cjs/useMediaQuery.cjs +27 -0
  14. package/dist/cjs/useMediaQuery.cjs.map +1 -0
  15. package/dist/cjs/utils.cjs +110 -0
  16. package/dist/cjs/utils.cjs.map +1 -0
  17. package/dist/esm/Explorer.d.ts +53 -0
  18. package/dist/esm/Explorer.js +229 -0
  19. package/dist/esm/Explorer.js.map +1 -0
  20. package/dist/esm/devtools.d.ts +65 -0
  21. package/dist/esm/devtools.js +1150 -0
  22. package/{build/cjs → dist/esm}/devtools.js.map +1 -1
  23. package/dist/esm/index.d.ts +1 -0
  24. package/dist/esm/index.js +6 -0
  25. package/{build/cjs → dist/esm}/index.js.map +1 -1
  26. package/dist/esm/styledComponents.d.ts +7 -0
  27. package/dist/esm/styledComponents.js +93 -0
  28. package/{build/cjs → dist/esm}/styledComponents.js.map +1 -1
  29. package/dist/esm/theme.d.ts +34 -0
  30. package/dist/esm/theme.js +28 -0
  31. package/dist/esm/theme.js.map +1 -0
  32. package/dist/esm/useLocalStorage.d.ts +1 -0
  33. package/dist/esm/useLocalStorage.js +46 -0
  34. package/dist/esm/useLocalStorage.js.map +1 -0
  35. package/dist/esm/useMediaQuery.d.ts +1 -0
  36. package/dist/esm/useMediaQuery.js +28 -0
  37. package/{build/cjs → dist/esm}/useMediaQuery.js.map +1 -1
  38. package/dist/esm/utils.d.ts +23 -0
  39. package/dist/esm/utils.js +110 -0
  40. package/{build/cjs → dist/esm}/utils.js.map +1 -1
  41. package/package.json +40 -21
  42. package/build/cjs/Explorer.js +0 -218
  43. package/build/cjs/Explorer.js.map +0 -1
  44. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -29
  45. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  46. package/build/cjs/devtools.js +0 -828
  47. package/build/cjs/index.js +0 -19
  48. package/build/cjs/styledComponents.js +0 -76
  49. package/build/cjs/theme.js +0 -45
  50. package/build/cjs/theme.js.map +0 -1
  51. package/build/cjs/useLocalStorage.js +0 -54
  52. package/build/cjs/useLocalStorage.js.map +0 -1
  53. package/build/cjs/useMediaQuery.js +0 -54
  54. package/build/cjs/utils.js +0 -131
  55. package/build/esm/index.js +0 -1265
  56. package/build/esm/index.js.map +0 -1
  57. package/build/stats-html.html +0 -4838
  58. package/build/stats-react.json +0 -706
  59. package/build/umd/index.development.js +0 -1598
  60. package/build/umd/index.development.js.map +0 -1
  61. package/build/umd/index.production.js +0 -22
  62. package/build/umd/index.production.js.map +0 -1
  63. /package/{build/types/Explorer.d.ts → dist/cjs/Explorer.d.cts} +0 -0
  64. /package/{build/types/devtools.d.ts → dist/cjs/devtools.d.cts} +0 -0
  65. /package/{build/types/index.d.ts → dist/cjs/index.d.cts} +0 -0
  66. /package/{build/types/styledComponents.d.ts → dist/cjs/styledComponents.d.cts} +0 -0
  67. /package/{build/types/theme.d.ts → dist/cjs/theme.d.cts} +0 -0
  68. /package/{build/types/useLocalStorage.d.ts → dist/cjs/useLocalStorage.d.cts} +0 -0
  69. /package/{build/types/useMediaQuery.d.ts → dist/cjs/useMediaQuery.d.cts} +0 -0
  70. /package/{build/types/utils.d.ts → dist/cjs/utils.d.cts} +0 -0
@@ -0,0 +1,1150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const React = require("react");
5
+ const reactRouter = require("@tanstack/react-router");
6
+ const useLocalStorage = require("./useLocalStorage.cjs");
7
+ const utils = require("./utils.cjs");
8
+ const styledComponents = require("./styledComponents.cjs");
9
+ const theme = require("./theme.cjs");
10
+ const Explorer = require("./Explorer.cjs");
11
+ const isServer = typeof window === "undefined";
12
+ function Logo(props) {
13
+ return /* @__PURE__ */ jsxRuntime.jsxs(
14
+ "div",
15
+ {
16
+ ...props,
17
+ style: {
18
+ ...props.style ?? {},
19
+ display: "flex",
20
+ alignItems: "center",
21
+ flexDirection: "column",
22
+ fontSize: "0.8rem",
23
+ fontWeight: "bolder",
24
+ lineHeight: "1"
25
+ },
26
+ children: [
27
+ /* @__PURE__ */ jsxRuntime.jsx(
28
+ "div",
29
+ {
30
+ style: {
31
+ letterSpacing: "-0.05rem"
32
+ },
33
+ children: "TANSTACK"
34
+ }
35
+ ),
36
+ /* @__PURE__ */ jsxRuntime.jsx(
37
+ "div",
38
+ {
39
+ style: {
40
+ backgroundImage: "linear-gradient(to right, var(--tw-gradient-stops))",
41
+ // @ts-ignore
42
+ "--tw-gradient-from": "#84cc16",
43
+ "--tw-gradient-stops": "var(--tw-gradient-from), var(--tw-gradient-to)",
44
+ "--tw-gradient-to": "#10b981",
45
+ WebkitBackgroundClip: "text",
46
+ color: "transparent",
47
+ letterSpacing: "0.1rem",
48
+ marginRight: "-0.2rem"
49
+ },
50
+ children: "ROUTER"
51
+ }
52
+ )
53
+ ]
54
+ }
55
+ );
56
+ }
57
+ function TanStackRouterDevtools({
58
+ initialIsOpen,
59
+ panelProps = {},
60
+ closeButtonProps = {},
61
+ toggleButtonProps = {},
62
+ position = "bottom-left",
63
+ containerElement: Container = "footer",
64
+ router
65
+ }) {
66
+ const rootRef = React.useRef(null);
67
+ const panelRef = React.useRef(null);
68
+ const [isOpen, setIsOpen] = useLocalStorage(
69
+ "tanstackRouterDevtoolsOpen",
70
+ initialIsOpen
71
+ );
72
+ const [devtoolsHeight, setDevtoolsHeight] = useLocalStorage(
73
+ "tanstackRouterDevtoolsHeight",
74
+ null
75
+ );
76
+ const [isResolvedOpen, setIsResolvedOpen] = utils.useSafeState(false);
77
+ const [isResizing, setIsResizing] = utils.useSafeState(false);
78
+ const isMounted = utils.useIsMounted();
79
+ const handleDragStart = (panelElement, startEvent) => {
80
+ if (startEvent.button !== 0)
81
+ return;
82
+ setIsResizing(true);
83
+ const dragInfo = {
84
+ originalHeight: (panelElement == null ? void 0 : panelElement.getBoundingClientRect().height) ?? 0,
85
+ pageY: startEvent.pageY
86
+ };
87
+ const run = (moveEvent) => {
88
+ const delta = dragInfo.pageY - moveEvent.pageY;
89
+ const newHeight = (dragInfo == null ? void 0 : dragInfo.originalHeight) + delta;
90
+ setDevtoolsHeight(newHeight);
91
+ if (newHeight < 70) {
92
+ setIsOpen(false);
93
+ } else {
94
+ setIsOpen(true);
95
+ }
96
+ };
97
+ const unsub = () => {
98
+ setIsResizing(false);
99
+ document.removeEventListener("mousemove", run);
100
+ document.removeEventListener("mouseUp", unsub);
101
+ };
102
+ document.addEventListener("mousemove", run);
103
+ document.addEventListener("mouseup", unsub);
104
+ };
105
+ React.useEffect(() => {
106
+ setIsResolvedOpen(isOpen ?? false);
107
+ }, [isOpen, isResolvedOpen, setIsResolvedOpen]);
108
+ React.useEffect(() => {
109
+ const ref = panelRef.current;
110
+ if (ref) {
111
+ const handlePanelTransitionStart = () => {
112
+ if (ref && isResolvedOpen) {
113
+ ref.style.visibility = "visible";
114
+ }
115
+ };
116
+ const handlePanelTransitionEnd = () => {
117
+ if (ref && !isResolvedOpen) {
118
+ ref.style.visibility = "hidden";
119
+ }
120
+ };
121
+ ref.addEventListener("transitionstart", handlePanelTransitionStart);
122
+ ref.addEventListener("transitionend", handlePanelTransitionEnd);
123
+ return () => {
124
+ ref.removeEventListener("transitionstart", handlePanelTransitionStart);
125
+ ref.removeEventListener("transitionend", handlePanelTransitionEnd);
126
+ };
127
+ }
128
+ return;
129
+ }, [isResolvedOpen]);
130
+ React[isServer ? "useEffect" : "useLayoutEffect"](() => {
131
+ var _a, _b;
132
+ if (isResolvedOpen) {
133
+ const previousValue = (_b = (_a = rootRef.current) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.style.paddingBottom;
134
+ const run = () => {
135
+ var _a2, _b2;
136
+ const containerHeight = (_a2 = panelRef.current) == null ? void 0 : _a2.getBoundingClientRect().height;
137
+ if ((_b2 = rootRef.current) == null ? void 0 : _b2.parentElement) {
138
+ rootRef.current.parentElement.style.paddingBottom = `${containerHeight}px`;
139
+ }
140
+ };
141
+ run();
142
+ if (typeof window !== "undefined") {
143
+ window.addEventListener("resize", run);
144
+ return () => {
145
+ var _a2;
146
+ window.removeEventListener("resize", run);
147
+ if (((_a2 = rootRef.current) == null ? void 0 : _a2.parentElement) && typeof previousValue === "string") {
148
+ rootRef.current.parentElement.style.paddingBottom = previousValue;
149
+ }
150
+ };
151
+ }
152
+ }
153
+ return;
154
+ }, [isResolvedOpen]);
155
+ const { style: panelStyle = {}, ...otherPanelProps } = panelProps;
156
+ const {
157
+ style: closeButtonStyle = {},
158
+ onClick: onCloseClick,
159
+ ...otherCloseButtonProps
160
+ } = closeButtonProps;
161
+ const {
162
+ style: toggleButtonStyle = {},
163
+ onClick: onToggleClick,
164
+ ...otherToggleButtonProps
165
+ } = toggleButtonProps;
166
+ if (!isMounted())
167
+ return null;
168
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { ref: rootRef, className: "TanStackRouterDevtools", children: [
169
+ /* @__PURE__ */ jsxRuntime.jsxs(theme.ThemeProvider, { theme: theme.defaultTheme, children: [
170
+ /* @__PURE__ */ jsxRuntime.jsx(
171
+ TanStackRouterDevtoolsPanel,
172
+ {
173
+ ref: panelRef,
174
+ ...otherPanelProps,
175
+ router,
176
+ style: {
177
+ position: "fixed",
178
+ bottom: "0",
179
+ right: "0",
180
+ zIndex: 99999,
181
+ width: "100%",
182
+ height: devtoolsHeight ?? 500,
183
+ maxHeight: "90%",
184
+ boxShadow: "0 0 20px rgba(0,0,0,.3)",
185
+ borderTop: `1px solid ${theme.defaultTheme.gray}`,
186
+ transformOrigin: "top",
187
+ // visibility will be toggled after transitions, but set initial state here
188
+ visibility: isOpen ? "visible" : "hidden",
189
+ ...panelStyle,
190
+ ...isResizing ? {
191
+ transition: `none`
192
+ } : { transition: `all .2s ease` },
193
+ ...isResolvedOpen ? {
194
+ opacity: 1,
195
+ pointerEvents: "all",
196
+ transform: `translateY(0) scale(1)`
197
+ } : {
198
+ opacity: 0,
199
+ pointerEvents: "none",
200
+ transform: `translateY(15px) scale(1.02)`
201
+ }
202
+ },
203
+ isOpen: isResolvedOpen,
204
+ setIsOpen,
205
+ handleDragStart: (e) => handleDragStart(panelRef.current, e)
206
+ }
207
+ ),
208
+ isResolvedOpen ? /* @__PURE__ */ jsxRuntime.jsx(
209
+ styledComponents.Button,
210
+ {
211
+ type: "button",
212
+ "aria-label": "Close TanStack Router Devtools",
213
+ ...otherCloseButtonProps,
214
+ onClick: (e) => {
215
+ setIsOpen(false);
216
+ onCloseClick && onCloseClick(e);
217
+ },
218
+ style: {
219
+ position: "fixed",
220
+ zIndex: 99999,
221
+ margin: ".5em",
222
+ bottom: 0,
223
+ ...position === "top-right" ? {
224
+ right: "0"
225
+ } : position === "top-left" ? {
226
+ left: "0"
227
+ } : position === "bottom-right" ? {
228
+ right: "0"
229
+ } : {
230
+ left: "0"
231
+ },
232
+ ...closeButtonStyle
233
+ },
234
+ children: "Close"
235
+ }
236
+ ) : null
237
+ ] }),
238
+ !isResolvedOpen ? /* @__PURE__ */ jsxRuntime.jsx(
239
+ "button",
240
+ {
241
+ type: "button",
242
+ ...otherToggleButtonProps,
243
+ "aria-label": "Open TanStack Router Devtools",
244
+ onClick: (e) => {
245
+ setIsOpen(true);
246
+ onToggleClick && onToggleClick(e);
247
+ },
248
+ style: {
249
+ appearance: "none",
250
+ background: "none",
251
+ border: 0,
252
+ padding: 0,
253
+ position: "fixed",
254
+ zIndex: 99999,
255
+ display: "inline-flex",
256
+ fontSize: "1.5em",
257
+ margin: ".5em",
258
+ cursor: "pointer",
259
+ width: "fit-content",
260
+ ...position === "top-right" ? {
261
+ top: "0",
262
+ right: "0"
263
+ } : position === "top-left" ? {
264
+ top: "0",
265
+ left: "0"
266
+ } : position === "bottom-right" ? {
267
+ bottom: "0",
268
+ right: "0"
269
+ } : {
270
+ bottom: "0",
271
+ left: "0"
272
+ },
273
+ ...toggleButtonStyle
274
+ },
275
+ children: /* @__PURE__ */ jsxRuntime.jsx(Logo, { "aria-hidden": true })
276
+ }
277
+ ) : null
278
+ ] });
279
+ }
280
+ function RouteComp({
281
+ route,
282
+ isRoot,
283
+ activeId,
284
+ setActiveId
285
+ }) {
286
+ var _a;
287
+ const routerState = reactRouter.useRouterState();
288
+ const matches = routerState.status === "pending" ? routerState.pendingMatches ?? [] : routerState.matches;
289
+ const match = routerState.matches.find((d) => d.routeId === route.id);
290
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
291
+ /* @__PURE__ */ jsxRuntime.jsxs(
292
+ "div",
293
+ {
294
+ role: "button",
295
+ "aria-label": `Open match details for ${route.id}`,
296
+ onClick: () => {
297
+ if (match) {
298
+ setActiveId(activeId === route.id ? "" : route.id);
299
+ }
300
+ },
301
+ style: {
302
+ display: "flex",
303
+ borderBottom: `solid 1px ${theme.defaultTheme.grayAlt}`,
304
+ cursor: match ? "pointer" : "default",
305
+ alignItems: "center",
306
+ background: route.id === activeId ? "rgba(255,255,255,.1)" : void 0,
307
+ padding: ".25rem .5rem",
308
+ gap: ".5rem"
309
+ },
310
+ children: [
311
+ isRoot ? null : /* @__PURE__ */ jsxRuntime.jsx(
312
+ "div",
313
+ {
314
+ style: {
315
+ flex: "0 0 auto",
316
+ width: ".7rem",
317
+ height: ".7rem",
318
+ alignItems: "center",
319
+ justifyContent: "center",
320
+ fontWeight: "bold",
321
+ borderRadius: "100%",
322
+ transition: "all .2s ease-out",
323
+ background: utils.getRouteStatusColor(matches, route, theme.defaultTheme),
324
+ opacity: match ? 1 : 0.3
325
+ }
326
+ }
327
+ ),
328
+ /* @__PURE__ */ jsxRuntime.jsxs(
329
+ "div",
330
+ {
331
+ style: {
332
+ flex: "1 0 auto",
333
+ display: "flex",
334
+ justifyContent: "space-between",
335
+ alignItems: "center",
336
+ padding: isRoot ? "0 .25rem" : 0,
337
+ opacity: match ? 1 : 0.7,
338
+ fontSize: "0.7rem"
339
+ },
340
+ children: [
341
+ /* @__PURE__ */ jsxRuntime.jsxs(styledComponents.Code, { children: [
342
+ route.path || reactRouter.trimPath(route.id),
343
+ " "
344
+ ] }),
345
+ /* @__PURE__ */ jsxRuntime.jsxs(
346
+ "div",
347
+ {
348
+ style: {
349
+ display: "flex",
350
+ alignItems: "center",
351
+ gap: ".5rem"
352
+ },
353
+ children: [
354
+ match ? /* @__PURE__ */ jsxRuntime.jsx(styledComponents.Code, { style: { opacity: 0.3 }, children: match.id }) : null,
355
+ /* @__PURE__ */ jsxRuntime.jsx(AgeTicker, { match })
356
+ ]
357
+ }
358
+ )
359
+ ]
360
+ }
361
+ )
362
+ ]
363
+ }
364
+ ),
365
+ ((_a = route.children) == null ? void 0 : _a.length) ? /* @__PURE__ */ jsxRuntime.jsx(
366
+ "div",
367
+ {
368
+ style: {
369
+ marginLeft: isRoot ? 0 : "1rem",
370
+ borderLeft: isRoot ? "" : `solid 1px ${theme.defaultTheme.grayAlt}`
371
+ },
372
+ children: [...route.children].sort((a, b) => {
373
+ return a.rank - b.rank;
374
+ }).map((r) => /* @__PURE__ */ jsxRuntime.jsx(
375
+ RouteComp,
376
+ {
377
+ route: r,
378
+ activeId,
379
+ setActiveId
380
+ },
381
+ r.id
382
+ ))
383
+ }
384
+ ) : null
385
+ ] });
386
+ }
387
+ const TanStackRouterDevtoolsPanel = React.forwardRef(function TanStackRouterDevtoolsPanel2(props, ref) {
388
+ var _a, _b, _c;
389
+ const {
390
+ isOpen = true,
391
+ setIsOpen,
392
+ handleDragStart,
393
+ router: userRouter,
394
+ ...panelProps
395
+ } = props;
396
+ const router = reactRouter.useRouter();
397
+ const routerState = reactRouter.useRouterState();
398
+ const matches = [
399
+ ...routerState.pendingMatches ?? [],
400
+ ...routerState.matches,
401
+ ...routerState.cachedMatches
402
+ ];
403
+ reactRouter.invariant(
404
+ router,
405
+ "No router was found for the TanStack Router Devtools. Please place the devtools in the <RouterProvider> component tree or pass the router instance to the devtools manually."
406
+ );
407
+ const [showMatches, setShowMatches] = useLocalStorage(
408
+ "tanstackRouterDevtoolsShowMatches",
409
+ true
410
+ );
411
+ const [activeId, setActiveId] = useLocalStorage(
412
+ "tanstackRouterDevtoolsActiveRouteId",
413
+ ""
414
+ );
415
+ const activeMatch = React.useMemo(
416
+ () => matches.find((d) => d.routeId === activeId || d.id === activeId),
417
+ [matches, activeId]
418
+ );
419
+ const hasSearch = Object.keys(routerState.location.search || {}).length;
420
+ const explorerState = {
421
+ ...router,
422
+ state: router.state
423
+ };
424
+ return /* @__PURE__ */ jsxRuntime.jsx(theme.ThemeProvider, { theme: theme.defaultTheme, children: /* @__PURE__ */ jsxRuntime.jsxs(styledComponents.Panel, { ref, className: "TanStackRouterDevtoolsPanel", ...panelProps, children: [
425
+ /* @__PURE__ */ jsxRuntime.jsx(
426
+ "style",
427
+ {
428
+ dangerouslySetInnerHTML: {
429
+ __html: `
430
+
431
+ .TanStackRouterDevtoolsPanel * {
432
+ scrollbar-color: ${theme.defaultTheme.backgroundAlt} ${theme.defaultTheme.gray};
433
+ }
434
+
435
+ .TanStackRouterDevtoolsPanel *::-webkit-scrollbar, .TanStackRouterDevtoolsPanel scrollbar {
436
+ width: 1em;
437
+ height: 1em;
438
+ }
439
+
440
+ .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-track, .TanStackRouterDevtoolsPanel scrollbar-track {
441
+ background: ${theme.defaultTheme.backgroundAlt};
442
+ }
443
+
444
+ .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-thumb, .TanStackRouterDevtoolsPanel scrollbar-thumb {
445
+ background: ${theme.defaultTheme.gray};
446
+ border-radius: .5em;
447
+ border: 3px solid ${theme.defaultTheme.backgroundAlt};
448
+ }
449
+
450
+ .TanStackRouterDevtoolsPanel table {
451
+ width: 100%;
452
+ }
453
+
454
+ .TanStackRouterDevtoolsPanel table tr {
455
+ border-bottom: 2px dotted rgba(255, 255, 255, .2);
456
+ }
457
+
458
+ .TanStackRouterDevtoolsPanel table tr:last-child {
459
+ border-bottom: none
460
+ }
461
+
462
+ .TanStackRouterDevtoolsPanel table td {
463
+ padding: .25rem .5rem;
464
+ border-right: 2px dotted rgba(255, 255, 255, .05);
465
+ }
466
+
467
+ .TanStackRouterDevtoolsPanel table td:last-child {
468
+ border-right: none
469
+ }
470
+
471
+ `
472
+ }
473
+ }
474
+ ),
475
+ /* @__PURE__ */ jsxRuntime.jsx(
476
+ "div",
477
+ {
478
+ style: {
479
+ position: "absolute",
480
+ left: 0,
481
+ top: 0,
482
+ width: "100%",
483
+ height: "4px",
484
+ marginBottom: "-4px",
485
+ cursor: "row-resize",
486
+ zIndex: 1e5
487
+ },
488
+ onMouseDown: handleDragStart
489
+ }
490
+ ),
491
+ /* @__PURE__ */ jsxRuntime.jsxs(
492
+ "div",
493
+ {
494
+ style: {
495
+ flex: "1 1 500px",
496
+ minHeight: "40%",
497
+ maxHeight: "100%",
498
+ overflow: "auto",
499
+ borderRight: `1px solid ${theme.defaultTheme.grayAlt}`,
500
+ display: "flex",
501
+ flexDirection: "column"
502
+ },
503
+ children: [
504
+ /* @__PURE__ */ jsxRuntime.jsxs(
505
+ "div",
506
+ {
507
+ style: {
508
+ display: "flex",
509
+ justifyContent: "start",
510
+ gap: "1rem",
511
+ padding: "1rem",
512
+ alignItems: "center",
513
+ background: theme.defaultTheme.backgroundAlt
514
+ },
515
+ children: [
516
+ /* @__PURE__ */ jsxRuntime.jsx(Logo, { "aria-hidden": true }),
517
+ /* @__PURE__ */ jsxRuntime.jsx(
518
+ "div",
519
+ {
520
+ style: {
521
+ fontSize: "clamp(.8rem, 2vw, 1.3rem)",
522
+ fontWeight: "bold"
523
+ },
524
+ children: /* @__PURE__ */ jsxRuntime.jsx(
525
+ "span",
526
+ {
527
+ style: {
528
+ fontWeight: 100
529
+ },
530
+ children: "Devtools"
531
+ }
532
+ )
533
+ }
534
+ )
535
+ ]
536
+ }
537
+ ),
538
+ /* @__PURE__ */ jsxRuntime.jsx(
539
+ "div",
540
+ {
541
+ style: {
542
+ overflowY: "auto",
543
+ flex: "1"
544
+ },
545
+ children: /* @__PURE__ */ jsxRuntime.jsx(
546
+ "div",
547
+ {
548
+ style: {
549
+ padding: ".5em"
550
+ },
551
+ children: /* @__PURE__ */ jsxRuntime.jsx(
552
+ Explorer.default,
553
+ {
554
+ label: "Router",
555
+ value: Object.fromEntries(
556
+ utils.multiSortBy(
557
+ Object.keys(explorerState),
558
+ [
559
+ "state",
560
+ "routesById",
561
+ "routesByPath",
562
+ "flatRoutes",
563
+ "options"
564
+ ].map((d) => (dd) => dd !== d)
565
+ ).map((key) => [key, explorerState[key]]).filter(
566
+ (d) => typeof d[1] !== "function" && ![
567
+ "__store",
568
+ "basepath",
569
+ "injectedHtml",
570
+ "subscribers",
571
+ "latestLoadPromise",
572
+ "navigateTimeout",
573
+ "resetNextScroll",
574
+ "tempLocationKey",
575
+ "latestLocation",
576
+ "routeTree",
577
+ "history"
578
+ ].includes(d[0])
579
+ )
580
+ ),
581
+ defaultExpanded: {
582
+ state: {},
583
+ context: {},
584
+ options: {}
585
+ },
586
+ filterSubEntries: (subEntries) => {
587
+ return subEntries.filter((d) => typeof d.value !== "function");
588
+ }
589
+ }
590
+ )
591
+ }
592
+ )
593
+ }
594
+ )
595
+ ]
596
+ }
597
+ ),
598
+ /* @__PURE__ */ jsxRuntime.jsxs(
599
+ "div",
600
+ {
601
+ style: {
602
+ flex: "1 1 500px",
603
+ minHeight: "40%",
604
+ maxHeight: "100%",
605
+ overflow: "auto",
606
+ borderRight: `1px solid ${theme.defaultTheme.grayAlt}`,
607
+ display: "flex",
608
+ flexDirection: "column"
609
+ },
610
+ children: [
611
+ /* @__PURE__ */ jsxRuntime.jsxs(
612
+ "div",
613
+ {
614
+ style: {
615
+ flex: "1 1 auto",
616
+ overflowY: "auto"
617
+ },
618
+ children: [
619
+ /* @__PURE__ */ jsxRuntime.jsxs(
620
+ "div",
621
+ {
622
+ style: {
623
+ padding: ".5em",
624
+ background: theme.defaultTheme.backgroundAlt,
625
+ position: "sticky",
626
+ top: 0,
627
+ zIndex: 1,
628
+ display: "flex",
629
+ alignItems: "center",
630
+ gap: ".5rem",
631
+ fontWeight: "bold"
632
+ },
633
+ children: [
634
+ "Pathname",
635
+ " ",
636
+ routerState.location.maskedLocation ? /* @__PURE__ */ jsxRuntime.jsx(
637
+ "div",
638
+ {
639
+ style: {
640
+ padding: ".1rem .5rem",
641
+ background: theme.defaultTheme.warning,
642
+ color: "black",
643
+ borderRadius: ".5rem"
644
+ },
645
+ children: "Masked"
646
+ }
647
+ ) : null
648
+ ]
649
+ }
650
+ ),
651
+ /* @__PURE__ */ jsxRuntime.jsxs(
652
+ "div",
653
+ {
654
+ style: {
655
+ padding: ".5rem",
656
+ display: "flex",
657
+ gap: ".5rem",
658
+ alignItems: "center"
659
+ },
660
+ children: [
661
+ /* @__PURE__ */ jsxRuntime.jsx(
662
+ "code",
663
+ {
664
+ style: {
665
+ opacity: 0.6
666
+ },
667
+ children: routerState.location.pathname
668
+ }
669
+ ),
670
+ routerState.location.maskedLocation ? /* @__PURE__ */ jsxRuntime.jsx(
671
+ "code",
672
+ {
673
+ style: {
674
+ color: theme.defaultTheme.warning,
675
+ fontWeight: "bold"
676
+ },
677
+ children: routerState.location.maskedLocation.pathname
678
+ }
679
+ ) : null
680
+ ]
681
+ }
682
+ ),
683
+ /* @__PURE__ */ jsxRuntime.jsxs(
684
+ "div",
685
+ {
686
+ style: {
687
+ padding: ".5em",
688
+ background: theme.defaultTheme.backgroundAlt,
689
+ position: "sticky",
690
+ top: 0,
691
+ zIndex: 1,
692
+ display: "flex",
693
+ alignItems: "center",
694
+ justifyContent: "space-between",
695
+ gap: ".5rem",
696
+ fontWeight: "bold"
697
+ },
698
+ children: [
699
+ /* @__PURE__ */ jsxRuntime.jsxs(
700
+ "div",
701
+ {
702
+ style: {
703
+ display: "flex",
704
+ alignItems: "center",
705
+ gap: ".5rem"
706
+ },
707
+ children: [
708
+ /* @__PURE__ */ jsxRuntime.jsx(
709
+ "button",
710
+ {
711
+ type: "button",
712
+ onClick: () => {
713
+ setShowMatches(false);
714
+ },
715
+ disabled: !showMatches,
716
+ style: {
717
+ appearance: "none",
718
+ opacity: showMatches ? 0.5 : 1,
719
+ border: 0,
720
+ background: "transparent",
721
+ color: "inherit",
722
+ cursor: "pointer"
723
+ },
724
+ children: "Routes"
725
+ }
726
+ ),
727
+ "/",
728
+ /* @__PURE__ */ jsxRuntime.jsx(
729
+ "button",
730
+ {
731
+ type: "button",
732
+ onClick: () => {
733
+ setShowMatches(true);
734
+ },
735
+ disabled: showMatches,
736
+ style: {
737
+ appearance: "none",
738
+ opacity: !showMatches ? 0.5 : 1,
739
+ border: 0,
740
+ background: "transparent",
741
+ color: "inherit",
742
+ cursor: "pointer"
743
+ },
744
+ children: "Matches"
745
+ }
746
+ )
747
+ ]
748
+ }
749
+ ),
750
+ /* @__PURE__ */ jsxRuntime.jsx(
751
+ "div",
752
+ {
753
+ style: {
754
+ opacity: 0.3,
755
+ fontSize: "0.7rem",
756
+ fontWeight: "normal"
757
+ },
758
+ children: "age / staleTime / gcTime"
759
+ }
760
+ )
761
+ ]
762
+ }
763
+ ),
764
+ !showMatches ? /* @__PURE__ */ jsxRuntime.jsx(
765
+ RouteComp,
766
+ {
767
+ route: router.routeTree,
768
+ isRoot: true,
769
+ activeId,
770
+ setActiveId
771
+ }
772
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: (routerState.status === "pending" ? routerState.pendingMatches ?? [] : routerState.matches).map((match, i) => {
773
+ return /* @__PURE__ */ jsxRuntime.jsxs(
774
+ "div",
775
+ {
776
+ role: "button",
777
+ "aria-label": `Open match details for ${match.id}`,
778
+ onClick: () => setActiveId(activeId === match.id ? "" : match.id),
779
+ style: {
780
+ display: "flex",
781
+ borderBottom: `solid 1px ${theme.defaultTheme.grayAlt}`,
782
+ cursor: "pointer",
783
+ alignItems: "center",
784
+ background: match === activeMatch ? "rgba(255,255,255,.1)" : void 0
785
+ },
786
+ children: [
787
+ /* @__PURE__ */ jsxRuntime.jsx(
788
+ "div",
789
+ {
790
+ style: {
791
+ flex: "0 0 auto",
792
+ width: "1.3rem",
793
+ height: "1.3rem",
794
+ marginLeft: ".25rem",
795
+ background: utils.getStatusColor(match, theme.defaultTheme),
796
+ alignItems: "center",
797
+ justifyContent: "center",
798
+ fontWeight: "bold",
799
+ borderRadius: ".25rem",
800
+ transition: "all .2s ease-out"
801
+ }
802
+ }
803
+ ),
804
+ /* @__PURE__ */ jsxRuntime.jsx(
805
+ styledComponents.Code,
806
+ {
807
+ style: {
808
+ padding: ".5em",
809
+ fontSize: "0.7rem"
810
+ },
811
+ children: `${match.id}`
812
+ }
813
+ ),
814
+ /* @__PURE__ */ jsxRuntime.jsx(AgeTicker, { match })
815
+ ]
816
+ },
817
+ match.id || i
818
+ );
819
+ }) })
820
+ ]
821
+ }
822
+ ),
823
+ ((_a = routerState.cachedMatches) == null ? void 0 : _a.length) ? /* @__PURE__ */ jsxRuntime.jsxs(
824
+ "div",
825
+ {
826
+ style: {
827
+ flex: "1 1 auto",
828
+ overflowY: "auto",
829
+ maxHeight: "50%"
830
+ },
831
+ children: [
832
+ /* @__PURE__ */ jsxRuntime.jsxs(
833
+ "div",
834
+ {
835
+ style: {
836
+ padding: ".5em",
837
+ background: theme.defaultTheme.backgroundAlt,
838
+ position: "sticky",
839
+ top: 0,
840
+ zIndex: 1,
841
+ display: "flex",
842
+ alignItems: "center",
843
+ justifyContent: "space-between",
844
+ gap: ".5rem",
845
+ fontWeight: "bold"
846
+ },
847
+ children: [
848
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Cached Matches" }),
849
+ /* @__PURE__ */ jsxRuntime.jsx(
850
+ "div",
851
+ {
852
+ style: {
853
+ opacity: 0.3,
854
+ fontSize: "0.7rem",
855
+ fontWeight: "normal"
856
+ },
857
+ children: "age / staleTime / gcTime"
858
+ }
859
+ )
860
+ ]
861
+ }
862
+ ),
863
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: routerState.cachedMatches.map((match) => {
864
+ return /* @__PURE__ */ jsxRuntime.jsxs(
865
+ "div",
866
+ {
867
+ role: "button",
868
+ "aria-label": `Open match details for ${match.id}`,
869
+ onClick: () => setActiveId(activeId === match.id ? "" : match.id),
870
+ style: {
871
+ display: "flex",
872
+ borderBottom: `solid 1px ${theme.defaultTheme.grayAlt}`,
873
+ cursor: "pointer",
874
+ alignItems: "center",
875
+ background: match === activeMatch ? "rgba(255,255,255,.1)" : void 0,
876
+ fontSize: "0.7rem"
877
+ },
878
+ children: [
879
+ /* @__PURE__ */ jsxRuntime.jsx(
880
+ "div",
881
+ {
882
+ style: {
883
+ flex: "0 0 auto",
884
+ width: ".75rem",
885
+ height: ".75rem",
886
+ marginLeft: ".25rem",
887
+ background: utils.getStatusColor(match, theme.defaultTheme),
888
+ alignItems: "center",
889
+ justifyContent: "center",
890
+ fontWeight: "bold",
891
+ borderRadius: "100%",
892
+ transition: "all 1s ease-out"
893
+ }
894
+ }
895
+ ),
896
+ /* @__PURE__ */ jsxRuntime.jsx(
897
+ styledComponents.Code,
898
+ {
899
+ style: {
900
+ padding: ".5em"
901
+ },
902
+ children: `${match.id}`
903
+ }
904
+ ),
905
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginLeft: "auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(AgeTicker, { match }) })
906
+ ]
907
+ },
908
+ match.id
909
+ );
910
+ }) })
911
+ ]
912
+ }
913
+ ) : null
914
+ ]
915
+ }
916
+ ),
917
+ activeMatch ? /* @__PURE__ */ jsxRuntime.jsxs(styledComponents.ActivePanel, { children: [
918
+ /* @__PURE__ */ jsxRuntime.jsx(
919
+ "div",
920
+ {
921
+ style: {
922
+ padding: ".5em",
923
+ background: theme.defaultTheme.backgroundAlt,
924
+ position: "sticky",
925
+ top: 0,
926
+ bottom: 0,
927
+ zIndex: 1
928
+ },
929
+ children: "Match Details"
930
+ }
931
+ ),
932
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
933
+ "table",
934
+ {
935
+ style: {
936
+ fontSize: "0.8rem"
937
+ },
938
+ children: /* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
939
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
940
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { opacity: ".5" }, children: "ID" }),
941
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(
942
+ styledComponents.Code,
943
+ {
944
+ style: {
945
+ lineHeight: "1.8em"
946
+ },
947
+ children: JSON.stringify(activeMatch.id, null, 2)
948
+ }
949
+ ) })
950
+ ] }),
951
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
952
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { opacity: ".5" }, children: "Status" }),
953
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { children: [
954
+ ((_b = routerState.pendingMatches) == null ? void 0 : _b.find(
955
+ (d) => d.id === activeMatch.id
956
+ )) ? "Pending" : ((_c = routerState.matches) == null ? void 0 : _c.find(
957
+ (d) => d.id === activeMatch.id
958
+ )) ? "Active" : "Cached",
959
+ " ",
960
+ "- ",
961
+ activeMatch.status
962
+ ] })
963
+ ] }),
964
+ /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
965
+ /* @__PURE__ */ jsxRuntime.jsx("td", { style: { opacity: ".5" }, children: "Last Updated" }),
966
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: activeMatch.updatedAt ? new Date(
967
+ activeMatch.updatedAt
968
+ ).toLocaleTimeString() : "N/A" })
969
+ ] })
970
+ ] })
971
+ }
972
+ ) }),
973
+ activeMatch.loaderData ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
974
+ /* @__PURE__ */ jsxRuntime.jsx(
975
+ "div",
976
+ {
977
+ style: {
978
+ background: theme.defaultTheme.backgroundAlt,
979
+ padding: ".5em",
980
+ position: "sticky",
981
+ top: 0,
982
+ bottom: 0,
983
+ zIndex: 1
984
+ },
985
+ children: "Loader Data"
986
+ }
987
+ ),
988
+ /* @__PURE__ */ jsxRuntime.jsx(
989
+ "div",
990
+ {
991
+ style: {
992
+ padding: ".5em"
993
+ },
994
+ children: /* @__PURE__ */ jsxRuntime.jsx(
995
+ Explorer.default,
996
+ {
997
+ label: "loaderData",
998
+ value: activeMatch.loaderData,
999
+ defaultExpanded: {}
1000
+ }
1001
+ )
1002
+ }
1003
+ )
1004
+ ] }) : null,
1005
+ /* @__PURE__ */ jsxRuntime.jsx(
1006
+ "div",
1007
+ {
1008
+ style: {
1009
+ background: theme.defaultTheme.backgroundAlt,
1010
+ padding: ".5em",
1011
+ position: "sticky",
1012
+ top: 0,
1013
+ bottom: 0,
1014
+ zIndex: 1
1015
+ },
1016
+ children: "Explorer"
1017
+ }
1018
+ ),
1019
+ /* @__PURE__ */ jsxRuntime.jsx(
1020
+ "div",
1021
+ {
1022
+ style: {
1023
+ padding: ".5em"
1024
+ },
1025
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1026
+ Explorer.default,
1027
+ {
1028
+ label: "Match",
1029
+ value: activeMatch,
1030
+ defaultExpanded: {}
1031
+ }
1032
+ )
1033
+ }
1034
+ )
1035
+ ] }) : null,
1036
+ hasSearch ? /* @__PURE__ */ jsxRuntime.jsxs(
1037
+ "div",
1038
+ {
1039
+ style: {
1040
+ flex: "1 1 500px",
1041
+ minHeight: "40%",
1042
+ maxHeight: "100%",
1043
+ overflow: "auto",
1044
+ borderRight: `1px solid ${theme.defaultTheme.grayAlt}`,
1045
+ display: "flex",
1046
+ flexDirection: "column"
1047
+ },
1048
+ children: [
1049
+ /* @__PURE__ */ jsxRuntime.jsx(
1050
+ "div",
1051
+ {
1052
+ style: {
1053
+ padding: ".5em",
1054
+ background: theme.defaultTheme.backgroundAlt,
1055
+ position: "sticky",
1056
+ top: 0,
1057
+ bottom: 0,
1058
+ zIndex: 1,
1059
+ fontWeight: "bold"
1060
+ },
1061
+ children: "Search Params"
1062
+ }
1063
+ ),
1064
+ /* @__PURE__ */ jsxRuntime.jsx(
1065
+ "div",
1066
+ {
1067
+ style: {
1068
+ padding: ".5em"
1069
+ },
1070
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1071
+ Explorer.default,
1072
+ {
1073
+ value: routerState.location.search || {},
1074
+ defaultExpanded: Object.keys(
1075
+ routerState.location.search || {}
1076
+ ).reduce((obj, next) => {
1077
+ obj[next] = {};
1078
+ return obj;
1079
+ }, {})
1080
+ }
1081
+ )
1082
+ }
1083
+ )
1084
+ ]
1085
+ }
1086
+ ) : null
1087
+ ] }) });
1088
+ });
1089
+ function AgeTicker({ match }) {
1090
+ const router = reactRouter.useRouter();
1091
+ const rerender = React.useReducer(
1092
+ () => ({}),
1093
+ () => ({})
1094
+ )[1];
1095
+ React.useEffect(() => {
1096
+ const interval = setInterval(() => {
1097
+ rerender();
1098
+ }, 1e3);
1099
+ return () => {
1100
+ clearInterval(interval);
1101
+ };
1102
+ }, []);
1103
+ if (!match) {
1104
+ return null;
1105
+ }
1106
+ const route = router.looseRoutesById[match == null ? void 0 : match.routeId];
1107
+ if (!route.options.loader) {
1108
+ return null;
1109
+ }
1110
+ const age = Date.now() - (match == null ? void 0 : match.updatedAt);
1111
+ const staleTime = route.options.staleTime ?? router.options.defaultStaleTime ?? 0;
1112
+ const gcTime = route.options.gcTime ?? router.options.defaultGcTime ?? 30 * 60 * 1e3;
1113
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1114
+ "div",
1115
+ {
1116
+ style: {
1117
+ display: "inline-flex",
1118
+ alignItems: "center",
1119
+ gap: ".25rem",
1120
+ color: age > staleTime ? theme.defaultTheme.warning : void 0
1121
+ },
1122
+ children: [
1123
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: {}, children: formatTime(age) }),
1124
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: "/" }),
1125
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: formatTime(staleTime) }),
1126
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: "/" }),
1127
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: formatTime(gcTime) })
1128
+ ]
1129
+ }
1130
+ );
1131
+ }
1132
+ function formatTime(ms) {
1133
+ const units = ["s", "min", "h", "d"];
1134
+ const values = [ms / 1e3, ms / 6e4, ms / 36e5, ms / 864e5];
1135
+ let chosenUnitIndex = 0;
1136
+ for (let i = 1; i < values.length; i++) {
1137
+ if (values[i] < 1)
1138
+ break;
1139
+ chosenUnitIndex = i;
1140
+ }
1141
+ const formatter = new Intl.NumberFormat(navigator.language, {
1142
+ compactDisplay: "short",
1143
+ notation: "compact",
1144
+ maximumFractionDigits: 0
1145
+ });
1146
+ return formatter.format(values[chosenUnitIndex]) + units[chosenUnitIndex];
1147
+ }
1148
+ exports.TanStackRouterDevtools = TanStackRouterDevtools;
1149
+ exports.TanStackRouterDevtoolsPanel = TanStackRouterDevtoolsPanel;
1150
+ //# sourceMappingURL=devtools.cjs.map