@tanstack/router-devtools 1.20.1 → 1.20.3-alpha.1

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