@tanstack/router-devtools 1.7.0 → 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
@@ -1,828 +0,0 @@
1
- /**
2
- * @tanstack/router-devtools/src/index.tsx
3
- *
4
- * Copyright (c) TanStack
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE.md file in the root directory of this source tree.
8
- *
9
- * @license MIT
10
- */
11
- 'use strict';
12
-
13
- var _rollupPluginBabelHelpers = require('./_virtual/_rollupPluginBabelHelpers.js');
14
- var React = require('react');
15
- var reactRouter = require('@tanstack/react-router');
16
- var useLocalStorage = require('./useLocalStorage.js');
17
- var utils = require('./utils.js');
18
- var styledComponents = require('./styledComponents.js');
19
- var theme = require('./theme.js');
20
- var Explorer = require('./Explorer.js');
21
-
22
- const isServer = typeof window === 'undefined';
23
- function Logo(props) {
24
- return /*#__PURE__*/React.createElement("div", _rollupPluginBabelHelpers.extends({}, props, {
25
- style: {
26
- ...(props.style ?? {}),
27
- display: 'flex',
28
- alignItems: 'center',
29
- flexDirection: 'column',
30
- fontSize: '0.8rem',
31
- fontWeight: 'bolder',
32
- lineHeight: '1'
33
- }
34
- }), /*#__PURE__*/React.createElement("div", {
35
- style: {
36
- letterSpacing: '-0.05rem'
37
- }
38
- }, "TANSTACK"), /*#__PURE__*/React.createElement("div", {
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
- }, "ROUTER"));
51
- }
52
- function TanStackRouterDevtools({
53
- initialIsOpen,
54
- panelProps = {},
55
- closeButtonProps = {},
56
- toggleButtonProps = {},
57
- position = 'bottom-left',
58
- containerElement: Container = 'footer',
59
- router
60
- }) {
61
- const rootRef = React.useRef(null);
62
- const panelRef = React.useRef(null);
63
- const [isOpen, setIsOpen] = useLocalStorage.default('tanstackRouterDevtoolsOpen', initialIsOpen);
64
- const [devtoolsHeight, setDevtoolsHeight] = useLocalStorage.default('tanstackRouterDevtoolsHeight', null);
65
- const [isResolvedOpen, setIsResolvedOpen] = utils.useSafeState(false);
66
- const [isResizing, setIsResizing] = utils.useSafeState(false);
67
- const isMounted = utils.useIsMounted();
68
- const handleDragStart = (panelElement, startEvent) => {
69
- if (startEvent.button !== 0) return; // Only allow left click for drag
70
-
71
- setIsResizing(true);
72
- const dragInfo = {
73
- originalHeight: panelElement?.getBoundingClientRect().height ?? 0,
74
- pageY: startEvent.pageY
75
- };
76
- const run = moveEvent => {
77
- const delta = dragInfo.pageY - moveEvent.pageY;
78
- const newHeight = dragInfo?.originalHeight + delta;
79
- setDevtoolsHeight(newHeight);
80
- if (newHeight < 70) {
81
- setIsOpen(false);
82
- } else {
83
- setIsOpen(true);
84
- }
85
- };
86
- const unsub = () => {
87
- setIsResizing(false);
88
- document.removeEventListener('mousemove', run);
89
- document.removeEventListener('mouseUp', unsub);
90
- };
91
- document.addEventListener('mousemove', run);
92
- document.addEventListener('mouseup', unsub);
93
- };
94
- React.useEffect(() => {
95
- setIsResolvedOpen(isOpen ?? false);
96
- }, [isOpen, isResolvedOpen, setIsResolvedOpen]);
97
-
98
- // Toggle panel visibility before/after transition (depending on direction).
99
- // Prevents focusing in a closed panel.
100
- React.useEffect(() => {
101
- const ref = panelRef.current;
102
- if (ref) {
103
- const handlePanelTransitionStart = () => {
104
- if (ref && isResolvedOpen) {
105
- ref.style.visibility = 'visible';
106
- }
107
- };
108
- const handlePanelTransitionEnd = () => {
109
- if (ref && !isResolvedOpen) {
110
- ref.style.visibility = 'hidden';
111
- }
112
- };
113
- ref.addEventListener('transitionstart', handlePanelTransitionStart);
114
- ref.addEventListener('transitionend', handlePanelTransitionEnd);
115
- return () => {
116
- ref.removeEventListener('transitionstart', handlePanelTransitionStart);
117
- ref.removeEventListener('transitionend', handlePanelTransitionEnd);
118
- };
119
- }
120
- return;
121
- }, [isResolvedOpen]);
122
- React[isServer ? 'useEffect' : 'useLayoutEffect'](() => {
123
- if (isResolvedOpen) {
124
- const previousValue = rootRef.current?.parentElement?.style.paddingBottom;
125
- const run = () => {
126
- const containerHeight = panelRef.current?.getBoundingClientRect().height;
127
- if (rootRef.current?.parentElement) {
128
- rootRef.current.parentElement.style.paddingBottom = `${containerHeight}px`;
129
- }
130
- };
131
- run();
132
- if (typeof window !== 'undefined') {
133
- window.addEventListener('resize', run);
134
- return () => {
135
- window.removeEventListener('resize', run);
136
- if (rootRef.current?.parentElement && typeof previousValue === 'string') {
137
- rootRef.current.parentElement.style.paddingBottom = previousValue;
138
- }
139
- };
140
- }
141
- }
142
- return;
143
- }, [isResolvedOpen]);
144
- const {
145
- style: panelStyle = {},
146
- ...otherPanelProps
147
- } = panelProps;
148
- const {
149
- style: closeButtonStyle = {},
150
- onClick: onCloseClick,
151
- ...otherCloseButtonProps
152
- } = closeButtonProps;
153
- const {
154
- style: toggleButtonStyle = {},
155
- onClick: onToggleClick,
156
- ...otherToggleButtonProps
157
- } = toggleButtonProps;
158
-
159
- // Do not render on the server
160
- if (!isMounted()) return null;
161
- return /*#__PURE__*/React.createElement(Container, {
162
- ref: rootRef,
163
- className: "TanStackRouterDevtools"
164
- }, /*#__PURE__*/React.createElement(theme.ThemeProvider, {
165
- theme: theme.defaultTheme
166
- }, /*#__PURE__*/React.createElement(TanStackRouterDevtoolsPanel, _rollupPluginBabelHelpers.extends({
167
- ref: panelRef
168
- }, otherPanelProps, {
169
- router: router,
170
- style: {
171
- position: 'fixed',
172
- bottom: '0',
173
- right: '0',
174
- zIndex: 99999,
175
- width: '100%',
176
- height: devtoolsHeight ?? 500,
177
- maxHeight: '90%',
178
- boxShadow: '0 0 20px rgba(0,0,0,.3)',
179
- borderTop: `1px solid ${theme.defaultTheme.gray}`,
180
- transformOrigin: 'top',
181
- // visibility will be toggled after transitions, but set initial state here
182
- visibility: isOpen ? 'visible' : 'hidden',
183
- ...panelStyle,
184
- ...(isResizing ? {
185
- transition: `none`
186
- } : {
187
- transition: `all .2s ease`
188
- }),
189
- ...(isResolvedOpen ? {
190
- opacity: 1,
191
- pointerEvents: 'all',
192
- transform: `translateY(0) scale(1)`
193
- } : {
194
- opacity: 0,
195
- pointerEvents: 'none',
196
- transform: `translateY(15px) scale(1.02)`
197
- })
198
- },
199
- isOpen: isResolvedOpen,
200
- setIsOpen: setIsOpen,
201
- handleDragStart: e => handleDragStart(panelRef.current, e)
202
- })), isResolvedOpen ? /*#__PURE__*/React.createElement(styledComponents.Button, _rollupPluginBabelHelpers.extends({
203
- type: "button",
204
- "aria-label": "Close TanStack Router Devtools"
205
- }, otherCloseButtonProps, {
206
- onClick: e => {
207
- setIsOpen(false);
208
- onCloseClick && onCloseClick(e);
209
- },
210
- style: {
211
- position: 'fixed',
212
- zIndex: 99999,
213
- margin: '.5em',
214
- bottom: 0,
215
- ...(position === 'top-right' ? {
216
- right: '0'
217
- } : position === 'top-left' ? {
218
- left: '0'
219
- } : position === 'bottom-right' ? {
220
- right: '0'
221
- } : {
222
- left: '0'
223
- }),
224
- ...closeButtonStyle
225
- }
226
- }), "Close") : null), !isResolvedOpen ? /*#__PURE__*/React.createElement("button", _rollupPluginBabelHelpers.extends({
227
- type: "button"
228
- }, otherToggleButtonProps, {
229
- "aria-label": "Open TanStack Router Devtools",
230
- onClick: e => {
231
- setIsOpen(true);
232
- onToggleClick && onToggleClick(e);
233
- },
234
- style: {
235
- appearance: 'none',
236
- background: 'none',
237
- border: 0,
238
- padding: 0,
239
- position: 'fixed',
240
- zIndex: 99999,
241
- display: 'inline-flex',
242
- fontSize: '1.5em',
243
- margin: '.5em',
244
- cursor: 'pointer',
245
- width: 'fit-content',
246
- ...(position === 'top-right' ? {
247
- top: '0',
248
- right: '0'
249
- } : position === 'top-left' ? {
250
- top: '0',
251
- left: '0'
252
- } : position === 'bottom-right' ? {
253
- bottom: '0',
254
- right: '0'
255
- } : {
256
- bottom: '0',
257
- left: '0'
258
- }),
259
- ...toggleButtonStyle
260
- }
261
- }), /*#__PURE__*/React.createElement(Logo, {
262
- "aria-hidden": true
263
- })) : null);
264
- }
265
- function RouteComp({
266
- route,
267
- isRoot,
268
- activeId,
269
- setActiveId
270
- }) {
271
- const routerState = reactRouter.useRouterState();
272
- const matches = routerState.status === 'pending' ? routerState.pendingMatches ?? [] : routerState.matches;
273
- const match = routerState.matches.find(d => d.routeId === route.id);
274
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
275
- role: "button",
276
- "aria-label": `Open match details for ${route.id}`,
277
- onClick: () => {
278
- if (match) {
279
- setActiveId(activeId === route.id ? '' : route.id);
280
- }
281
- },
282
- style: {
283
- display: 'flex',
284
- borderBottom: `solid 1px ${theme.defaultTheme.grayAlt}`,
285
- cursor: match ? 'pointer' : 'default',
286
- alignItems: 'center',
287
- background: route.id === activeId ? 'rgba(255,255,255,.1)' : undefined,
288
- padding: '.25rem .5rem',
289
- gap: '.5rem'
290
- }
291
- }, isRoot ? null : /*#__PURE__*/React.createElement("div", {
292
- style: {
293
- flex: '0 0 auto',
294
- width: '.7rem',
295
- height: '.7rem',
296
- alignItems: 'center',
297
- justifyContent: 'center',
298
- fontWeight: 'bold',
299
- borderRadius: '100%',
300
- transition: 'all .2s ease-out',
301
- background: utils.getRouteStatusColor(matches, route, theme.defaultTheme),
302
- opacity: match ? 1 : 0.3
303
- }
304
- }), /*#__PURE__*/React.createElement("div", {
305
- style: {
306
- flex: '1 0 auto',
307
- display: 'flex',
308
- justifyContent: 'space-between',
309
- alignItems: 'center',
310
- padding: isRoot ? '0 .25rem' : 0,
311
- opacity: match ? 1 : 0.7,
312
- fontSize: '0.7rem'
313
- }
314
- }, /*#__PURE__*/React.createElement(styledComponents.Code, null, route.path || reactRouter.trimPath(route.id), " "), /*#__PURE__*/React.createElement("div", {
315
- style: {
316
- display: 'flex',
317
- alignItems: 'center',
318
- gap: '.5rem'
319
- }
320
- }, match ? /*#__PURE__*/React.createElement(styledComponents.Code, {
321
- style: {
322
- opacity: 0.3
323
- }
324
- }, match.id) : null, /*#__PURE__*/React.createElement(AgeTicker, {
325
- match: match
326
- })))), route.children?.length ? /*#__PURE__*/React.createElement("div", {
327
- style: {
328
- marginLeft: isRoot ? 0 : '1rem',
329
- borderLeft: isRoot ? '' : `solid 1px ${theme.defaultTheme.grayAlt}`
330
- }
331
- }, [...route.children].sort((a, b) => {
332
- return a.rank - b.rank;
333
- }).map(r => /*#__PURE__*/React.createElement(RouteComp, {
334
- key: r.id,
335
- route: r,
336
- activeId: activeId,
337
- setActiveId: setActiveId
338
- }))) : null);
339
- }
340
- const TanStackRouterDevtoolsPanel = /*#__PURE__*/React.forwardRef(function TanStackRouterDevtoolsPanel(props, ref) {
341
- const {
342
- isOpen = true,
343
- setIsOpen,
344
- handleDragStart,
345
- router: userRouter,
346
- ...panelProps
347
- } = props;
348
- const router = reactRouter.useRouter();
349
- const routerState = reactRouter.useRouterState();
350
- const matches = [...(routerState.pendingMatches ?? []), ...routerState.matches, ...routerState.cachedMatches];
351
- reactRouter.invariant(router, '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.');
352
-
353
- // useStore(router.__store)
354
-
355
- const [showMatches, setShowMatches] = useLocalStorage.default('tanstackRouterDevtoolsShowMatches', true);
356
- const [activeId, setActiveId] = useLocalStorage.default('tanstackRouterDevtoolsActiveRouteId', '');
357
- const activeMatch = React.useMemo(() => matches.find(d => d.routeId === activeId || d.id === activeId), [matches, activeId]);
358
- const hasSearch = Object.keys(routerState.location.search || {}).length;
359
- const explorerState = {
360
- ...router,
361
- state: router.state
362
- };
363
- return /*#__PURE__*/React.createElement(theme.ThemeProvider, {
364
- theme: theme.defaultTheme
365
- }, /*#__PURE__*/React.createElement(styledComponents.Panel, _rollupPluginBabelHelpers.extends({
366
- ref: ref,
367
- className: "TanStackRouterDevtoolsPanel"
368
- }, panelProps), /*#__PURE__*/React.createElement("style", {
369
- dangerouslySetInnerHTML: {
370
- __html: `
371
-
372
- .TanStackRouterDevtoolsPanel * {
373
- scrollbar-color: ${theme.defaultTheme.backgroundAlt} ${theme.defaultTheme.gray};
374
- }
375
-
376
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar, .TanStackRouterDevtoolsPanel scrollbar {
377
- width: 1em;
378
- height: 1em;
379
- }
380
-
381
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-track, .TanStackRouterDevtoolsPanel scrollbar-track {
382
- background: ${theme.defaultTheme.backgroundAlt};
383
- }
384
-
385
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-thumb, .TanStackRouterDevtoolsPanel scrollbar-thumb {
386
- background: ${theme.defaultTheme.gray};
387
- border-radius: .5em;
388
- border: 3px solid ${theme.defaultTheme.backgroundAlt};
389
- }
390
-
391
- .TanStackRouterDevtoolsPanel table {
392
- width: 100%;
393
- }
394
-
395
- .TanStackRouterDevtoolsPanel table tr {
396
- border-bottom: 2px dotted rgba(255, 255, 255, .2);
397
- }
398
-
399
- .TanStackRouterDevtoolsPanel table tr:last-child {
400
- border-bottom: none
401
- }
402
-
403
- .TanStackRouterDevtoolsPanel table td {
404
- padding: .25rem .5rem;
405
- border-right: 2px dotted rgba(255, 255, 255, .05);
406
- }
407
-
408
- .TanStackRouterDevtoolsPanel table td:last-child {
409
- border-right: none
410
- }
411
-
412
- `
413
- }
414
- }), /*#__PURE__*/React.createElement("div", {
415
- style: {
416
- position: 'absolute',
417
- left: 0,
418
- top: 0,
419
- width: '100%',
420
- height: '4px',
421
- marginBottom: '-4px',
422
- cursor: 'row-resize',
423
- zIndex: 100000
424
- },
425
- onMouseDown: handleDragStart
426
- }), /*#__PURE__*/React.createElement("div", {
427
- style: {
428
- flex: '1 1 500px',
429
- minHeight: '40%',
430
- maxHeight: '100%',
431
- overflow: 'auto',
432
- borderRight: `1px solid ${theme.defaultTheme.grayAlt}`,
433
- display: 'flex',
434
- flexDirection: 'column'
435
- }
436
- }, /*#__PURE__*/React.createElement("div", {
437
- style: {
438
- display: 'flex',
439
- justifyContent: 'start',
440
- gap: '1rem',
441
- padding: '1rem',
442
- alignItems: 'center',
443
- background: theme.defaultTheme.backgroundAlt
444
- }
445
- }, /*#__PURE__*/React.createElement(Logo, {
446
- "aria-hidden": true
447
- }), /*#__PURE__*/React.createElement("div", {
448
- style: {
449
- fontSize: 'clamp(.8rem, 2vw, 1.3rem)',
450
- fontWeight: 'bold'
451
- }
452
- }, /*#__PURE__*/React.createElement("span", {
453
- style: {
454
- fontWeight: 100
455
- }
456
- }, "Devtools"))), /*#__PURE__*/React.createElement("div", {
457
- style: {
458
- overflowY: 'auto',
459
- flex: '1'
460
- }
461
- }, /*#__PURE__*/React.createElement("div", {
462
- style: {
463
- padding: '.5em'
464
- }
465
- }, /*#__PURE__*/React.createElement(Explorer.default, {
466
- label: "Router",
467
- value: Object.fromEntries(utils.multiSortBy(Object.keys(explorerState), ['state', 'routesById', 'routesByPath', 'flatRoutes', 'options'].map(d => dd => dd !== d)).map(key => [key, explorerState[key]]).filter(d => typeof d[1] !== 'function' && !['__store', 'basepath', 'injectedHtml', 'subscribers', 'latestLoadPromise', 'navigateTimeout', 'resetNextScroll', 'tempLocationKey', 'latestLocation', 'routeTree', 'history'].includes(d[0]))),
468
- defaultExpanded: {
469
- state: {},
470
- context: {},
471
- options: {}
472
- },
473
- filterSubEntries: subEntries => {
474
- return subEntries.filter(d => typeof d.value !== 'function');
475
- }
476
- })))), /*#__PURE__*/React.createElement("div", {
477
- style: {
478
- flex: '1 1 500px',
479
- minHeight: '40%',
480
- maxHeight: '100%',
481
- overflow: 'auto',
482
- borderRight: `1px solid ${theme.defaultTheme.grayAlt}`,
483
- display: 'flex',
484
- flexDirection: 'column'
485
- }
486
- }, /*#__PURE__*/React.createElement("div", {
487
- style: {
488
- flex: '1 1 auto',
489
- overflowY: 'auto'
490
- }
491
- }, /*#__PURE__*/React.createElement("div", {
492
- style: {
493
- padding: '.5em',
494
- background: theme.defaultTheme.backgroundAlt,
495
- position: 'sticky',
496
- top: 0,
497
- zIndex: 1,
498
- display: 'flex',
499
- alignItems: 'center',
500
- gap: '.5rem',
501
- fontWeight: 'bold'
502
- }
503
- }, "Pathname", ' ', routerState.location.maskedLocation ? /*#__PURE__*/React.createElement("div", {
504
- style: {
505
- padding: '.1rem .5rem',
506
- background: theme.defaultTheme.warning,
507
- color: 'black',
508
- borderRadius: '.5rem'
509
- }
510
- }, "Masked") : null), /*#__PURE__*/React.createElement("div", {
511
- style: {
512
- padding: '.5rem',
513
- display: 'flex',
514
- gap: '.5rem',
515
- alignItems: 'center'
516
- }
517
- }, /*#__PURE__*/React.createElement("code", {
518
- style: {
519
- opacity: 0.6
520
- }
521
- }, routerState.location.pathname), routerState.location.maskedLocation ? /*#__PURE__*/React.createElement("code", {
522
- style: {
523
- color: theme.defaultTheme.warning,
524
- fontWeight: 'bold'
525
- }
526
- }, routerState.location.maskedLocation.pathname) : null), /*#__PURE__*/React.createElement("div", {
527
- style: {
528
- padding: '.5em',
529
- background: theme.defaultTheme.backgroundAlt,
530
- position: 'sticky',
531
- top: 0,
532
- zIndex: 1,
533
- display: 'flex',
534
- alignItems: 'center',
535
- justifyContent: 'space-between',
536
- gap: '.5rem',
537
- fontWeight: 'bold'
538
- }
539
- }, /*#__PURE__*/React.createElement("div", {
540
- style: {
541
- display: 'flex',
542
- alignItems: 'center',
543
- gap: '.5rem'
544
- }
545
- }, /*#__PURE__*/React.createElement("button", {
546
- type: "button",
547
- onClick: () => {
548
- setShowMatches(false);
549
- },
550
- disabled: !showMatches,
551
- style: {
552
- appearance: 'none',
553
- opacity: showMatches ? 0.5 : 1,
554
- border: 0,
555
- background: 'transparent',
556
- color: 'inherit',
557
- cursor: 'pointer'
558
- }
559
- }, "Routes"), "/", /*#__PURE__*/React.createElement("button", {
560
- type: "button",
561
- onClick: () => {
562
- setShowMatches(true);
563
- },
564
- disabled: showMatches,
565
- style: {
566
- appearance: 'none',
567
- opacity: !showMatches ? 0.5 : 1,
568
- border: 0,
569
- background: 'transparent',
570
- color: 'inherit',
571
- cursor: 'pointer'
572
- }
573
- }, "Matches")), /*#__PURE__*/React.createElement("div", {
574
- style: {
575
- opacity: 0.3,
576
- fontSize: '0.7rem',
577
- fontWeight: 'normal'
578
- }
579
- }, "age / staleTime / gcTime")), !showMatches ? /*#__PURE__*/React.createElement(RouteComp, {
580
- route: router.routeTree,
581
- isRoot: true,
582
- activeId: activeId,
583
- setActiveId: setActiveId
584
- }) : /*#__PURE__*/React.createElement("div", null, (routerState.status === 'pending' ? routerState.pendingMatches ?? [] : routerState.matches).map((match, i) => {
585
- return /*#__PURE__*/React.createElement("div", {
586
- key: match.id || i,
587
- role: "button",
588
- "aria-label": `Open match details for ${match.id}`,
589
- onClick: () => setActiveId(activeId === match.id ? '' : match.id),
590
- style: {
591
- display: 'flex',
592
- borderBottom: `solid 1px ${theme.defaultTheme.grayAlt}`,
593
- cursor: 'pointer',
594
- alignItems: 'center',
595
- background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined
596
- }
597
- }, /*#__PURE__*/React.createElement("div", {
598
- style: {
599
- flex: '0 0 auto',
600
- width: '1.3rem',
601
- height: '1.3rem',
602
- marginLeft: '.25rem',
603
- background: utils.getStatusColor(match, theme.defaultTheme),
604
- alignItems: 'center',
605
- justifyContent: 'center',
606
- fontWeight: 'bold',
607
- borderRadius: '.25rem',
608
- transition: 'all .2s ease-out'
609
- }
610
- }), /*#__PURE__*/React.createElement(styledComponents.Code, {
611
- style: {
612
- padding: '.5em',
613
- fontSize: '0.7rem'
614
- }
615
- }, `${match.id}`), /*#__PURE__*/React.createElement(AgeTicker, {
616
- match: match
617
- }));
618
- }))), routerState.cachedMatches?.length ? /*#__PURE__*/React.createElement("div", {
619
- style: {
620
- flex: '1 1 auto',
621
- overflowY: 'auto',
622
- maxHeight: '50%'
623
- }
624
- }, /*#__PURE__*/React.createElement("div", {
625
- style: {
626
- padding: '.5em',
627
- background: theme.defaultTheme.backgroundAlt,
628
- position: 'sticky',
629
- top: 0,
630
- zIndex: 1,
631
- display: 'flex',
632
- alignItems: 'center',
633
- justifyContent: 'space-between',
634
- gap: '.5rem',
635
- fontWeight: 'bold'
636
- }
637
- }, /*#__PURE__*/React.createElement("div", null, "Cached Matches"), /*#__PURE__*/React.createElement("div", {
638
- style: {
639
- opacity: 0.3,
640
- fontSize: '0.7rem',
641
- fontWeight: 'normal'
642
- }
643
- }, "age / staleTime / gcTime")), /*#__PURE__*/React.createElement("div", null, routerState.cachedMatches.map(match => {
644
- return /*#__PURE__*/React.createElement("div", {
645
- key: match.id,
646
- role: "button",
647
- "aria-label": `Open match details for ${match.id}`,
648
- onClick: () => setActiveId(activeId === match.id ? '' : match.id),
649
- style: {
650
- display: 'flex',
651
- borderBottom: `solid 1px ${theme.defaultTheme.grayAlt}`,
652
- cursor: 'pointer',
653
- alignItems: 'center',
654
- background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined,
655
- fontSize: '0.7rem'
656
- }
657
- }, /*#__PURE__*/React.createElement("div", {
658
- style: {
659
- flex: '0 0 auto',
660
- width: '.75rem',
661
- height: '.75rem',
662
- marginLeft: '.25rem',
663
- background: utils.getStatusColor(match, theme.defaultTheme),
664
- alignItems: 'center',
665
- justifyContent: 'center',
666
- fontWeight: 'bold',
667
- borderRadius: '100%',
668
- transition: 'all 1s ease-out'
669
- }
670
- }), /*#__PURE__*/React.createElement(styledComponents.Code, {
671
- style: {
672
- padding: '.5em'
673
- }
674
- }, `${match.id}`), /*#__PURE__*/React.createElement("div", {
675
- style: {
676
- marginLeft: 'auto'
677
- }
678
- }, /*#__PURE__*/React.createElement(AgeTicker, {
679
- match: match
680
- })));
681
- }))) : null), activeMatch ? /*#__PURE__*/React.createElement(styledComponents.ActivePanel, null, /*#__PURE__*/React.createElement("div", {
682
- style: {
683
- padding: '.5em',
684
- background: theme.defaultTheme.backgroundAlt,
685
- position: 'sticky',
686
- top: 0,
687
- bottom: 0,
688
- zIndex: 1
689
- }
690
- }, "Match Details"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("table", {
691
- style: {
692
- fontSize: '0.8rem'
693
- }
694
- }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
695
- style: {
696
- opacity: '.5'
697
- }
698
- }, "ID"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(styledComponents.Code, {
699
- style: {
700
- lineHeight: '1.8em'
701
- }
702
- }, JSON.stringify(activeMatch.id, null, 2)))), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
703
- style: {
704
- opacity: '.5'
705
- }
706
- }, "Status"), /*#__PURE__*/React.createElement("td", null, routerState.pendingMatches?.find(d => d.id === activeMatch.id) ? 'Pending' : routerState.matches?.find(d => d.id === activeMatch.id) ? 'Active' : 'Cached', ' ', "- ", activeMatch.status)), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
707
- style: {
708
- opacity: '.5'
709
- }
710
- }, "Last Updated"), /*#__PURE__*/React.createElement("td", null, activeMatch.updatedAt ? new Date(activeMatch.updatedAt).toLocaleTimeString() : 'N/A'))))), activeMatch.loaderData ? /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
711
- style: {
712
- background: theme.defaultTheme.backgroundAlt,
713
- padding: '.5em',
714
- position: 'sticky',
715
- top: 0,
716
- bottom: 0,
717
- zIndex: 1
718
- }
719
- }, "Loader Data"), /*#__PURE__*/React.createElement("div", {
720
- style: {
721
- padding: '.5em'
722
- }
723
- }, /*#__PURE__*/React.createElement(Explorer.default, {
724
- label: "loaderData",
725
- value: activeMatch.loaderData,
726
- defaultExpanded: {}
727
- }))) : null, /*#__PURE__*/React.createElement("div", {
728
- style: {
729
- background: theme.defaultTheme.backgroundAlt,
730
- padding: '.5em',
731
- position: 'sticky',
732
- top: 0,
733
- bottom: 0,
734
- zIndex: 1
735
- }
736
- }, "Explorer"), /*#__PURE__*/React.createElement("div", {
737
- style: {
738
- padding: '.5em'
739
- }
740
- }, /*#__PURE__*/React.createElement(Explorer.default, {
741
- label: "Match",
742
- value: activeMatch,
743
- defaultExpanded: {}
744
- }))) : null, hasSearch ? /*#__PURE__*/React.createElement("div", {
745
- style: {
746
- flex: '1 1 500px',
747
- minHeight: '40%',
748
- maxHeight: '100%',
749
- overflow: 'auto',
750
- borderRight: `1px solid ${theme.defaultTheme.grayAlt}`,
751
- display: 'flex',
752
- flexDirection: 'column'
753
- }
754
- }, /*#__PURE__*/React.createElement("div", {
755
- style: {
756
- padding: '.5em',
757
- background: theme.defaultTheme.backgroundAlt,
758
- position: 'sticky',
759
- top: 0,
760
- bottom: 0,
761
- zIndex: 1,
762
- fontWeight: 'bold'
763
- }
764
- }, "Search Params"), /*#__PURE__*/React.createElement("div", {
765
- style: {
766
- padding: '.5em'
767
- }
768
- }, /*#__PURE__*/React.createElement(Explorer.default, {
769
- value: routerState.location.search || {},
770
- defaultExpanded: Object.keys(routerState.location.search || {}).reduce((obj, next) => {
771
- obj[next] = {};
772
- return obj;
773
- }, {})
774
- }))) : null));
775
- });
776
- function AgeTicker({
777
- match
778
- }) {
779
- const router = reactRouter.useRouter();
780
- const rerender = React.useReducer(() => ({}), () => ({}))[1];
781
- React.useEffect(() => {
782
- const interval = setInterval(() => {
783
- rerender();
784
- }, 1000);
785
- return () => {
786
- clearInterval(interval);
787
- };
788
- }, []);
789
- if (!match) {
790
- return null;
791
- }
792
- const route = router.looseRoutesById[match?.routeId];
793
- if (!route.options.loader) {
794
- return null;
795
- }
796
- const age = Date.now() - match?.updatedAt;
797
- const staleTime = route.options.staleTime ?? router.options.defaultStaleTime ?? 0;
798
- const gcTime = route.options.gcTime ?? router.options.defaultGcTime ?? 30 * 60 * 1000;
799
- return /*#__PURE__*/React.createElement("div", {
800
- style: {
801
- display: 'inline-flex',
802
- alignItems: 'center',
803
- gap: '.25rem',
804
- color: age > staleTime ? theme.defaultTheme.warning : undefined
805
- }
806
- }, /*#__PURE__*/React.createElement("div", {
807
- style: {}
808
- }, formatTime(age)), /*#__PURE__*/React.createElement("div", null, "/"), /*#__PURE__*/React.createElement("div", null, formatTime(staleTime)), /*#__PURE__*/React.createElement("div", null, "/"), /*#__PURE__*/React.createElement("div", null, formatTime(gcTime)));
809
- }
810
- function formatTime(ms) {
811
- const units = ['s', 'min', 'h', 'd'];
812
- const values = [ms / 1000, ms / 60000, ms / 3600000, ms / 86400000];
813
- let chosenUnitIndex = 0;
814
- for (let i = 1; i < values.length; i++) {
815
- if (values[i] < 1) break;
816
- chosenUnitIndex = i;
817
- }
818
- const formatter = new Intl.NumberFormat(navigator.language, {
819
- compactDisplay: 'short',
820
- notation: 'compact',
821
- maximumFractionDigits: 0
822
- });
823
- return formatter.format(values[chosenUnitIndex]) + units[chosenUnitIndex];
824
- }
825
-
826
- exports.TanStackRouterDevtools = TanStackRouterDevtools;
827
- exports.TanStackRouterDevtoolsPanel = TanStackRouterDevtoolsPanel;
828
- //# sourceMappingURL=devtools.js.map