@tanstack/router-devtools 1.7.1 → 1.8.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 (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,1598 +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
- (function (global, factory) {
12
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react'), require('use-sync-external-store/shim')) :
13
- typeof define === 'function' && define.amd ? define(['exports', 'react', 'use-sync-external-store/shim'], factory) :
14
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.TanStackRouterDevtools = {}, global.React, global.require$$1));
15
- })(this, (function (exports, React, require$$1) { 'use strict';
16
-
17
- function _interopNamespaceDefault(e) {
18
- var n = Object.create(null);
19
- if (e) {
20
- Object.keys(e).forEach(function (k) {
21
- if (k !== 'default') {
22
- var d = Object.getOwnPropertyDescriptor(e, k);
23
- Object.defineProperty(n, k, d.get ? d : {
24
- enumerable: true,
25
- get: function () { return e[k]; }
26
- });
27
- }
28
- });
29
- }
30
- n.default = e;
31
- return Object.freeze(n);
32
- }
33
-
34
- var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
35
-
36
- function _extends() {
37
- _extends = Object.assign ? Object.assign.bind() : function (target) {
38
- for (var i = 1; i < arguments.length; i++) {
39
- var source = arguments[i];
40
- for (var key in source) {
41
- if (Object.prototype.hasOwnProperty.call(source, key)) {
42
- target[key] = source[key];
43
- }
44
- }
45
- }
46
- return target;
47
- };
48
- return _extends.apply(this, arguments);
49
- }
50
-
51
- var isProduction = "development" === 'production';
52
- var prefix = 'Invariant failed';
53
- function invariant(condition, message) {
54
- if (condition) {
55
- return;
56
- }
57
- if (isProduction) {
58
- throw new Error(prefix);
59
- }
60
- var provided = typeof message === 'function' ? message() : message;
61
- var value = provided ? "".concat(prefix, ": ").concat(provided) : prefix;
62
- throw new Error(value);
63
- }
64
-
65
- function warning(condition, message) {
66
- {
67
- if (condition) {
68
- return;
69
- }
70
-
71
- var text = "Warning: " + message;
72
-
73
- if (typeof console !== 'undefined') {
74
- console.warn(text);
75
- }
76
-
77
- try {
78
- throw Error(text);
79
- } catch (x) {}
80
- }
81
- }
82
-
83
- var withSelector = {exports: {}};
84
-
85
- var withSelector_development = {};
86
-
87
- /**
88
- * @license React
89
- * use-sync-external-store-shim/with-selector.development.js
90
- *
91
- * Copyright (c) Facebook, Inc. and its affiliates.
92
- *
93
- * This source code is licensed under the MIT license found in the
94
- * LICENSE file in the root directory of this source tree.
95
- */
96
-
97
- var hasRequiredWithSelector_development;
98
-
99
- function requireWithSelector_development () {
100
- if (hasRequiredWithSelector_development) return withSelector_development;
101
- hasRequiredWithSelector_development = 1;
102
-
103
- {
104
- (function() {
105
-
106
- /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
107
- if (
108
- typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
109
- typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
110
- 'function'
111
- ) {
112
- __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
113
- }
114
- var React$1 = React;
115
- var shim = require$$1;
116
-
117
- /**
118
- * inlined Object.is polyfill to avoid requiring consumers ship their own
119
- * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
120
- */
121
- function is(x, y) {
122
- return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
123
- ;
124
- }
125
-
126
- var objectIs = typeof Object.is === 'function' ? Object.is : is;
127
-
128
- var useSyncExternalStore = shim.useSyncExternalStore;
129
-
130
- // for CommonJS interop.
131
-
132
- var useRef = React$1.useRef,
133
- useEffect = React$1.useEffect,
134
- useMemo = React$1.useMemo,
135
- useDebugValue = React$1.useDebugValue; // Same as useSyncExternalStore, but supports selector and isEqual arguments.
136
-
137
- function useSyncExternalStoreWithSelector(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
138
- // Use this to track the rendered snapshot.
139
- var instRef = useRef(null);
140
- var inst;
141
-
142
- if (instRef.current === null) {
143
- inst = {
144
- hasValue: false,
145
- value: null
146
- };
147
- instRef.current = inst;
148
- } else {
149
- inst = instRef.current;
150
- }
151
-
152
- var _useMemo = useMemo(function () {
153
- // Track the memoized state using closure variables that are local to this
154
- // memoized instance of a getSnapshot function. Intentionally not using a
155
- // useRef hook, because that state would be shared across all concurrent
156
- // copies of the hook/component.
157
- var hasMemo = false;
158
- var memoizedSnapshot;
159
- var memoizedSelection;
160
-
161
- var memoizedSelector = function (nextSnapshot) {
162
- if (!hasMemo) {
163
- // The first time the hook is called, there is no memoized result.
164
- hasMemo = true;
165
- memoizedSnapshot = nextSnapshot;
166
-
167
- var _nextSelection = selector(nextSnapshot);
168
-
169
- if (isEqual !== undefined) {
170
- // Even if the selector has changed, the currently rendered selection
171
- // may be equal to the new selection. We should attempt to reuse the
172
- // current value if possible, to preserve downstream memoizations.
173
- if (inst.hasValue) {
174
- var currentSelection = inst.value;
175
-
176
- if (isEqual(currentSelection, _nextSelection)) {
177
- memoizedSelection = currentSelection;
178
- return currentSelection;
179
- }
180
- }
181
- }
182
-
183
- memoizedSelection = _nextSelection;
184
- return _nextSelection;
185
- } // We may be able to reuse the previous invocation's result.
186
-
187
-
188
- // We may be able to reuse the previous invocation's result.
189
- var prevSnapshot = memoizedSnapshot;
190
- var prevSelection = memoizedSelection;
191
-
192
- if (objectIs(prevSnapshot, nextSnapshot)) {
193
- // The snapshot is the same as last time. Reuse the previous selection.
194
- return prevSelection;
195
- } // The snapshot has changed, so we need to compute a new selection.
196
-
197
-
198
- // The snapshot has changed, so we need to compute a new selection.
199
- var nextSelection = selector(nextSnapshot); // If a custom isEqual function is provided, use that to check if the data
200
- // has changed. If it hasn't, return the previous selection. That signals
201
- // to React that the selections are conceptually equal, and we can bail
202
- // out of rendering.
203
-
204
- // If a custom isEqual function is provided, use that to check if the data
205
- // has changed. If it hasn't, return the previous selection. That signals
206
- // to React that the selections are conceptually equal, and we can bail
207
- // out of rendering.
208
- if (isEqual !== undefined && isEqual(prevSelection, nextSelection)) {
209
- return prevSelection;
210
- }
211
-
212
- memoizedSnapshot = nextSnapshot;
213
- memoizedSelection = nextSelection;
214
- return nextSelection;
215
- }; // Assigning this to a constant so that Flow knows it can't change.
216
-
217
-
218
- // Assigning this to a constant so that Flow knows it can't change.
219
- var maybeGetServerSnapshot = getServerSnapshot === undefined ? null : getServerSnapshot;
220
-
221
- var getSnapshotWithSelector = function () {
222
- return memoizedSelector(getSnapshot());
223
- };
224
-
225
- var getServerSnapshotWithSelector = maybeGetServerSnapshot === null ? undefined : function () {
226
- return memoizedSelector(maybeGetServerSnapshot());
227
- };
228
- return [getSnapshotWithSelector, getServerSnapshotWithSelector];
229
- }, [getSnapshot, getServerSnapshot, selector, isEqual]),
230
- getSelection = _useMemo[0],
231
- getServerSelection = _useMemo[1];
232
-
233
- var value = useSyncExternalStore(subscribe, getSelection, getServerSelection);
234
- useEffect(function () {
235
- inst.hasValue = true;
236
- inst.value = value;
237
- }, [value]);
238
- useDebugValue(value);
239
- return value;
240
- }
241
-
242
- withSelector_development.useSyncExternalStoreWithSelector = useSyncExternalStoreWithSelector;
243
- /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
244
- if (
245
- typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
246
- typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
247
- 'function'
248
- ) {
249
- __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
250
- }
251
-
252
- })();
253
- }
254
- return withSelector_development;
255
- }
256
-
257
- {
258
- withSelector.exports = requireWithSelector_development();
259
- }
260
-
261
- var withSelectorExports = withSelector.exports;
262
-
263
- // src/index.ts
264
- function useStore(store, selector = (d) => d) {
265
- const slice = withSelectorExports.useSyncExternalStoreWithSelector(
266
- store.subscribe,
267
- () => store.state,
268
- () => store.state,
269
- selector,
270
- shallow
271
- );
272
- return slice;
273
- }
274
- function shallow(objA, objB) {
275
- if (Object.is(objA, objB)) {
276
- return true;
277
- }
278
- if (typeof objA !== "object" || objA === null || typeof objB !== "object" || objB === null) {
279
- return false;
280
- }
281
- const keysA = Object.keys(objA);
282
- if (keysA.length !== Object.keys(objB).length) {
283
- return false;
284
- }
285
- for (let i = 0; i < keysA.length; i++) {
286
- if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
287
- return false;
288
- }
289
- }
290
- return true;
291
- }
292
-
293
- /**
294
- * @tanstack/react-router/src/index.tsx
295
- *
296
- * Copyright (c) TanStack
297
- *
298
- * This source code is licensed under the MIT license found in the
299
- * LICENSE.md file in the root directory of this source tree.
300
- *
301
- * @license MIT
302
- */
303
-
304
- let routerContext = /*#__PURE__*/React__namespace.createContext(null);
305
- if (typeof document !== 'undefined') {
306
- if (window.__TSR_ROUTER_CONTEXT__) {
307
- routerContext = window.__TSR_ROUTER_CONTEXT__;
308
- } else {
309
- window.__TSR_ROUTER_CONTEXT__ = routerContext;
310
- }
311
- }
312
-
313
- function useRouter(opts) {
314
- const resolvedContext = typeof document !== 'undefined' ? window.__TSR_ROUTER_CONTEXT__ || routerContext : routerContext;
315
- const value = React__namespace.useContext(resolvedContext);
316
- warning(!((opts?.warn ?? true) && !value), 'useRouter must be used inside a <RouterProvider> component!');
317
- return value;
318
- }
319
-
320
- function useRouterState(opts) {
321
- const contextRouter = useRouter({
322
- warn: opts?.router === undefined
323
- });
324
- return useStore((opts?.router || contextRouter).__store, opts?.select);
325
- }
326
- function isFunction(d) {
327
- return typeof d === 'function';
328
- }
329
- function functionalUpdate(updater, previous) {
330
- if (isFunction(updater)) {
331
- return updater(previous);
332
- }
333
- return updater;
334
- }
335
- function trimPathLeft(path) {
336
- return path === '/' ? path : path.replace(/^\/{1,}/, '');
337
- }
338
- function trimPathRight(path) {
339
- return path === '/' ? path : path.replace(/\/{1,}$/, '');
340
- }
341
- function trimPath(path) {
342
- return trimPathRight(trimPathLeft(path));
343
- }
344
- const sessionsStorage = typeof window !== 'undefined' && window.sessionStorage;
345
- let cache = sessionsStorage ? (() => {
346
- const storageKey = 'tsr-scroll-restoration-v2';
347
- const state = JSON.parse(window.sessionStorage.getItem(storageKey) || 'null') || {
348
- cached: {},
349
- next: {}
350
- };
351
- return {
352
- state,
353
- set: updater => {
354
- cache.state = functionalUpdate(updater, cache.state);
355
- window.sessionStorage.setItem(storageKey, JSON.stringify(cache.state));
356
- }
357
- };
358
- })() : undefined;
359
-
360
- const getItem = key => {
361
- try {
362
- const itemValue = localStorage.getItem(key);
363
- if (typeof itemValue === 'string') {
364
- return JSON.parse(itemValue);
365
- }
366
- return undefined;
367
- } catch {
368
- return undefined;
369
- }
370
- };
371
- function useLocalStorage(key, defaultValue) {
372
- const [value, setValue] = React.useState();
373
- React.useEffect(() => {
374
- const initialValue = getItem(key);
375
- if (typeof initialValue === 'undefined' || initialValue === null) {
376
- setValue(typeof defaultValue === 'function' ? defaultValue() : defaultValue);
377
- } else {
378
- setValue(initialValue);
379
- }
380
- }, [defaultValue, key]);
381
- const setter = React.useCallback(updater => {
382
- setValue(old => {
383
- let newVal = updater;
384
- if (typeof updater == 'function') {
385
- newVal = updater(old);
386
- }
387
- try {
388
- localStorage.setItem(key, JSON.stringify(newVal));
389
- } catch {}
390
- return newVal;
391
- });
392
- }, [key]);
393
- return [value, setter];
394
- }
395
-
396
- const defaultTheme = {
397
- background: '#222222',
398
- backgroundAlt: '#292929',
399
- foreground: 'white',
400
- gray: '#444',
401
- grayAlt: '#444',
402
- inputBackgroundColor: '#fff',
403
- inputTextColor: '#000',
404
- success: '#80cb00',
405
- danger: '#ff0085',
406
- active: '#0099ff',
407
- warning: '#ffb200'
408
- };
409
- const ThemeContext = /*#__PURE__*/React.createContext(defaultTheme);
410
- function ThemeProvider({
411
- theme,
412
- ...rest
413
- }) {
414
- return /*#__PURE__*/React.createElement(ThemeContext.Provider, _extends({
415
- value: theme
416
- }, rest));
417
- }
418
- function useTheme() {
419
- return React.useContext(ThemeContext);
420
- }
421
-
422
- function useMediaQuery(query) {
423
- // Keep track of the preference in state, start with the current match
424
- const [isMatch, setIsMatch] = React.useState(() => {
425
- if (typeof window !== 'undefined') {
426
- return window.matchMedia && window.matchMedia(query).matches;
427
- }
428
- return;
429
- });
430
-
431
- // Watch for changes
432
- React.useEffect(() => {
433
- if (typeof window !== 'undefined') {
434
- if (!window.matchMedia) {
435
- return;
436
- }
437
-
438
- // Create a matcher
439
- const matcher = window.matchMedia(query);
440
-
441
- // Create our handler
442
- const onChange = ({
443
- matches
444
- }) => setIsMatch(matches);
445
-
446
- // Listen for changes
447
- matcher.addListener(onChange);
448
- return () => {
449
- // Stop listening for changes
450
- matcher.removeListener(onChange);
451
- };
452
- }
453
- return;
454
- }, [isMatch, query, setIsMatch]);
455
- return isMatch;
456
- }
457
-
458
- const isServer$1 = typeof window === 'undefined';
459
- function getStatusColor(match, theme) {
460
- return match.status === 'pending' || match.isFetching ? theme.active : match.status === 'error' ? theme.danger : match.status === 'success' ? theme.success : theme.gray;
461
- }
462
- function getRouteStatusColor(matches, route, theme) {
463
- const found = matches.find(d => d.routeId === route.id);
464
- if (!found) return theme.gray;
465
- return getStatusColor(found, theme);
466
- }
467
- function styled(type, newStyles, queries = {}) {
468
- return /*#__PURE__*/React.forwardRef(({
469
- style,
470
- ...rest
471
- }, ref) => {
472
- const theme = useTheme();
473
- const mediaStyles = Object.entries(queries).reduce((current, [key, value]) => {
474
- // eslint-disable-next-line react-hooks/rules-of-hooks
475
- return useMediaQuery(key) ? {
476
- ...current,
477
- ...(typeof value === 'function' ? value(rest, theme) : value)
478
- } : current;
479
- }, {});
480
- return /*#__PURE__*/React.createElement(type, {
481
- ...rest,
482
- style: {
483
- ...(typeof newStyles === 'function' ? newStyles(rest, theme) : newStyles),
484
- ...style,
485
- ...mediaStyles
486
- },
487
- ref
488
- });
489
- });
490
- }
491
- function useIsMounted() {
492
- const mountedRef = React.useRef(false);
493
- const isMounted = React.useCallback(() => mountedRef.current, []);
494
- React[isServer$1 ? 'useEffect' : 'useLayoutEffect'](() => {
495
- mountedRef.current = true;
496
- return () => {
497
- mountedRef.current = false;
498
- };
499
- }, []);
500
- return isMounted;
501
- }
502
-
503
- /**
504
- * Displays a string regardless the type of the data
505
- * @param {unknown} value Value to be stringified
506
- */
507
- const displayValue = value => {
508
- const name = Object.getOwnPropertyNames(Object(value));
509
- const newValue = typeof value === 'bigint' ? `${value.toString()}n` : value;
510
- try {
511
- return JSON.stringify(newValue, name);
512
- } catch (e) {
513
- return `unable to stringify`;
514
- }
515
- };
516
-
517
- /**
518
- * This hook is a safe useState version which schedules state updates in microtasks
519
- * to prevent updating a component state while React is rendering different components
520
- * or when the component is not mounted anymore.
521
- */
522
- function useSafeState(initialState) {
523
- const isMounted = useIsMounted();
524
- const [state, setState] = React.useState(initialState);
525
- const safeSetState = React.useCallback(value => {
526
- scheduleMicrotask(() => {
527
- if (isMounted()) {
528
- setState(value);
529
- }
530
- });
531
- }, [isMounted]);
532
- return [state, safeSetState];
533
- }
534
-
535
- /**
536
- * Schedules a microtask.
537
- * This can be useful to schedule state updates after rendering.
538
- */
539
- function scheduleMicrotask(callback) {
540
- Promise.resolve().then(callback).catch(error => setTimeout(() => {
541
- throw error;
542
- }));
543
- }
544
- function multiSortBy(arr, accessors = [d => d]) {
545
- return arr.map((d, i) => [d, i]).sort(([a, ai], [b, bi]) => {
546
- for (const accessor of accessors) {
547
- const ao = accessor(a);
548
- const bo = accessor(b);
549
- if (typeof ao === 'undefined') {
550
- if (typeof bo === 'undefined') {
551
- continue;
552
- }
553
- return 1;
554
- }
555
- if (ao === bo) {
556
- continue;
557
- }
558
- return ao > bo ? 1 : -1;
559
- }
560
- return ai - bi;
561
- }).map(([d]) => d);
562
- }
563
-
564
- const Panel = styled('div', (_props, theme) => ({
565
- fontSize: 'clamp(12px, 1.5vw, 14px)',
566
- fontFamily: `sans-serif`,
567
- display: 'flex',
568
- backgroundColor: theme.background,
569
- color: theme.foreground
570
- }), {
571
- '(max-width: 700px)': {
572
- flexDirection: 'column'
573
- },
574
- '(max-width: 600px)': {
575
- fontSize: '.9em'
576
- // flexDirection: 'column',
577
- }
578
- });
579
- const ActivePanel = styled('div', () => ({
580
- flex: '1 1 500px',
581
- display: 'flex',
582
- flexDirection: 'column',
583
- overflow: 'auto',
584
- height: '100%'
585
- }), {
586
- '(max-width: 700px)': (_props, theme) => ({
587
- borderTop: `2px solid ${theme.gray}`
588
- })
589
- });
590
- const Button = styled('button', (props, theme) => ({
591
- appearance: 'none',
592
- fontSize: '.9em',
593
- fontWeight: 'bold',
594
- background: theme.gray,
595
- border: '0',
596
- borderRadius: '.3em',
597
- color: 'white',
598
- padding: '.5em',
599
- opacity: props.disabled ? '.5' : undefined,
600
- cursor: 'pointer'
601
- }));
602
-
603
- // export const QueryKeys = styled('span', {
604
- // display: 'inline-block',
605
- // fontSize: '0.9em',
606
- // })
607
-
608
- // export const QueryKey = styled('span', {
609
- // display: 'inline-flex',
610
- // alignItems: 'center',
611
- // padding: '.2em .4em',
612
- // fontWeight: 'bold',
613
- // textShadow: '0 0 10px black',
614
- // borderRadius: '.2em',
615
- // })
616
-
617
- const Code = styled('code', {
618
- fontSize: '.9em'
619
- });
620
-
621
- const Entry = styled('div', {
622
- fontFamily: 'Menlo, monospace',
623
- fontSize: '.7rem',
624
- lineHeight: '1.7',
625
- outline: 'none',
626
- wordBreak: 'break-word'
627
- });
628
- const Label = styled('span', {
629
- color: 'white'
630
- });
631
- const LabelButton = styled('button', {
632
- cursor: 'pointer',
633
- color: 'white'
634
- });
635
- const ExpandButton = styled('button', {
636
- cursor: 'pointer',
637
- color: 'inherit',
638
- font: 'inherit',
639
- outline: 'inherit',
640
- background: 'transparent',
641
- border: 'none',
642
- padding: 0
643
- });
644
- const Value = styled('span', (_props, theme) => ({
645
- color: theme.danger
646
- }));
647
- const SubEntries = styled('div', {
648
- marginLeft: '.1em',
649
- paddingLeft: '1em',
650
- borderLeft: '2px solid rgba(0,0,0,.15)'
651
- });
652
- const Info = styled('span', {
653
- color: 'grey',
654
- fontSize: '.7em'
655
- });
656
- const Expander = ({
657
- expanded,
658
- style = {}
659
- }) => /*#__PURE__*/React__namespace.createElement("span", {
660
- style: {
661
- display: 'inline-block',
662
- transition: 'all .1s ease',
663
- transform: `rotate(${expanded ? 90 : 0}deg) ${style.transform || ''}`,
664
- ...style
665
- }
666
- }, "\u25B6");
667
- /**
668
- * Chunk elements in the array by size
669
- *
670
- * when the array cannot be chunked evenly by size, the last chunk will be
671
- * filled with the remaining elements
672
- *
673
- * @example
674
- * chunkArray(['a','b', 'c', 'd', 'e'], 2) // returns [['a','b'], ['c', 'd'], ['e']]
675
- */
676
- function chunkArray(array, size) {
677
- if (size < 1) return [];
678
- let i = 0;
679
- const result = [];
680
- while (i < array.length) {
681
- result.push(array.slice(i, i + size));
682
- i = i + size;
683
- }
684
- return result;
685
- }
686
- const DefaultRenderer = ({
687
- handleEntry,
688
- label,
689
- value,
690
- subEntries = [],
691
- subEntryPages = [],
692
- type,
693
- expanded = false,
694
- toggleExpanded,
695
- pageSize,
696
- renderer
697
- }) => {
698
- const [expandedPages, setExpandedPages] = React__namespace.useState([]);
699
- const [valueSnapshot, setValueSnapshot] = React__namespace.useState(undefined);
700
- const refreshValueSnapshot = () => {
701
- setValueSnapshot(value());
702
- };
703
- return /*#__PURE__*/React__namespace.createElement(Entry, null, subEntryPages.length ? /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(ExpandButton, {
704
- onClick: () => toggleExpanded()
705
- }, /*#__PURE__*/React__namespace.createElement(Expander, {
706
- expanded: expanded
707
- }), " ", label, ' ', /*#__PURE__*/React__namespace.createElement(Info, null, String(type).toLowerCase() === 'iterable' ? '(Iterable) ' : '', subEntries.length, " ", subEntries.length > 1 ? `items` : `item`)), expanded ? subEntryPages.length === 1 ? /*#__PURE__*/React__namespace.createElement(SubEntries, null, subEntries.map((entry, index) => handleEntry(entry))) : /*#__PURE__*/React__namespace.createElement(SubEntries, null, subEntryPages.map((entries, index) => /*#__PURE__*/React__namespace.createElement("div", {
708
- key: index
709
- }, /*#__PURE__*/React__namespace.createElement(Entry, null, /*#__PURE__*/React__namespace.createElement(LabelButton, {
710
- onClick: () => setExpandedPages(old => old.includes(index) ? old.filter(d => d !== index) : [...old, index])
711
- }, /*#__PURE__*/React__namespace.createElement(Expander, {
712
- expanded: expanded
713
- }), " [", index * pageSize, " ...", ' ', index * pageSize + pageSize - 1, "]"), expandedPages.includes(index) ? /*#__PURE__*/React__namespace.createElement(SubEntries, null, entries.map(entry => handleEntry(entry))) : null)))) : null) : type === 'function' ? /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Explorer, {
714
- renderer: renderer,
715
- label: /*#__PURE__*/React__namespace.createElement("button", {
716
- onClick: refreshValueSnapshot,
717
- style: {
718
- appearance: 'none',
719
- border: '0',
720
- background: 'transparent'
721
- }
722
- }, /*#__PURE__*/React__namespace.createElement(Label, null, label), " \uD83D\uDD04", ' '),
723
- value: valueSnapshot,
724
- defaultExpanded: {}
725
- })) : /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Label, null, label, ":"), " ", /*#__PURE__*/React__namespace.createElement(Value, null, displayValue(value))));
726
- };
727
- function isIterable(x) {
728
- return Symbol.iterator in x;
729
- }
730
- function Explorer({
731
- value,
732
- defaultExpanded,
733
- renderer = DefaultRenderer,
734
- pageSize = 100,
735
- filterSubEntries,
736
- ...rest
737
- }) {
738
- const [expanded, setExpanded] = React__namespace.useState(Boolean(defaultExpanded));
739
- const toggleExpanded = React__namespace.useCallback(() => setExpanded(old => !old), []);
740
- let type = typeof value;
741
- let subEntries = [];
742
- const makeProperty = sub => {
743
- const subDefaultExpanded = defaultExpanded === true ? {
744
- [sub.label]: true
745
- } : defaultExpanded?.[sub.label];
746
- return {
747
- ...sub,
748
- defaultExpanded: subDefaultExpanded
749
- };
750
- };
751
- if (Array.isArray(value)) {
752
- type = 'array';
753
- subEntries = value.map((d, i) => makeProperty({
754
- label: i.toString(),
755
- value: d
756
- }));
757
- } else if (value !== null && typeof value === 'object' && isIterable(value) && typeof value[Symbol.iterator] === 'function') {
758
- type = 'Iterable';
759
- subEntries = Array.from(value, (val, i) => makeProperty({
760
- label: i.toString(),
761
- value: val
762
- }));
763
- } else if (typeof value === 'object' && value !== null) {
764
- type = 'object';
765
- subEntries = Object.entries(value).map(([key, val]) => makeProperty({
766
- label: key,
767
- value: val
768
- }));
769
- }
770
- subEntries = filterSubEntries ? filterSubEntries(subEntries) : subEntries;
771
- const subEntryPages = chunkArray(subEntries, pageSize);
772
- return renderer({
773
- handleEntry: entry => /*#__PURE__*/React__namespace.createElement(Explorer, _extends({
774
- key: entry.label,
775
- value: value,
776
- renderer: renderer,
777
- filterSubEntries: filterSubEntries
778
- }, rest, entry)),
779
- type,
780
- subEntries,
781
- subEntryPages,
782
- value,
783
- expanded,
784
- toggleExpanded,
785
- pageSize,
786
- ...rest
787
- });
788
- }
789
-
790
- const isServer = typeof window === 'undefined';
791
- function Logo(props) {
792
- return /*#__PURE__*/React.createElement("div", _extends({}, props, {
793
- style: {
794
- ...(props.style ?? {}),
795
- display: 'flex',
796
- alignItems: 'center',
797
- flexDirection: 'column',
798
- fontSize: '0.8rem',
799
- fontWeight: 'bolder',
800
- lineHeight: '1'
801
- }
802
- }), /*#__PURE__*/React.createElement("div", {
803
- style: {
804
- letterSpacing: '-0.05rem'
805
- }
806
- }, "TANSTACK"), /*#__PURE__*/React.createElement("div", {
807
- style: {
808
- backgroundImage: 'linear-gradient(to right, var(--tw-gradient-stops))',
809
- // @ts-ignore
810
- '--tw-gradient-from': '#84cc16',
811
- '--tw-gradient-stops': 'var(--tw-gradient-from), var(--tw-gradient-to)',
812
- '--tw-gradient-to': '#10b981',
813
- WebkitBackgroundClip: 'text',
814
- color: 'transparent',
815
- letterSpacing: '0.1rem',
816
- marginRight: '-0.2rem'
817
- }
818
- }, "ROUTER"));
819
- }
820
- function TanStackRouterDevtools({
821
- initialIsOpen,
822
- panelProps = {},
823
- closeButtonProps = {},
824
- toggleButtonProps = {},
825
- position = 'bottom-left',
826
- containerElement: Container = 'footer',
827
- router
828
- }) {
829
- const rootRef = React.useRef(null);
830
- const panelRef = React.useRef(null);
831
- const [isOpen, setIsOpen] = useLocalStorage('tanstackRouterDevtoolsOpen', initialIsOpen);
832
- const [devtoolsHeight, setDevtoolsHeight] = useLocalStorage('tanstackRouterDevtoolsHeight', null);
833
- const [isResolvedOpen, setIsResolvedOpen] = useSafeState(false);
834
- const [isResizing, setIsResizing] = useSafeState(false);
835
- const isMounted = useIsMounted();
836
- const handleDragStart = (panelElement, startEvent) => {
837
- if (startEvent.button !== 0) return; // Only allow left click for drag
838
-
839
- setIsResizing(true);
840
- const dragInfo = {
841
- originalHeight: panelElement?.getBoundingClientRect().height ?? 0,
842
- pageY: startEvent.pageY
843
- };
844
- const run = moveEvent => {
845
- const delta = dragInfo.pageY - moveEvent.pageY;
846
- const newHeight = dragInfo?.originalHeight + delta;
847
- setDevtoolsHeight(newHeight);
848
- if (newHeight < 70) {
849
- setIsOpen(false);
850
- } else {
851
- setIsOpen(true);
852
- }
853
- };
854
- const unsub = () => {
855
- setIsResizing(false);
856
- document.removeEventListener('mousemove', run);
857
- document.removeEventListener('mouseUp', unsub);
858
- };
859
- document.addEventListener('mousemove', run);
860
- document.addEventListener('mouseup', unsub);
861
- };
862
- React.useEffect(() => {
863
- setIsResolvedOpen(isOpen ?? false);
864
- }, [isOpen, isResolvedOpen, setIsResolvedOpen]);
865
-
866
- // Toggle panel visibility before/after transition (depending on direction).
867
- // Prevents focusing in a closed panel.
868
- React.useEffect(() => {
869
- const ref = panelRef.current;
870
- if (ref) {
871
- const handlePanelTransitionStart = () => {
872
- if (ref && isResolvedOpen) {
873
- ref.style.visibility = 'visible';
874
- }
875
- };
876
- const handlePanelTransitionEnd = () => {
877
- if (ref && !isResolvedOpen) {
878
- ref.style.visibility = 'hidden';
879
- }
880
- };
881
- ref.addEventListener('transitionstart', handlePanelTransitionStart);
882
- ref.addEventListener('transitionend', handlePanelTransitionEnd);
883
- return () => {
884
- ref.removeEventListener('transitionstart', handlePanelTransitionStart);
885
- ref.removeEventListener('transitionend', handlePanelTransitionEnd);
886
- };
887
- }
888
- return;
889
- }, [isResolvedOpen]);
890
- React[isServer ? 'useEffect' : 'useLayoutEffect'](() => {
891
- if (isResolvedOpen) {
892
- const previousValue = rootRef.current?.parentElement?.style.paddingBottom;
893
- const run = () => {
894
- const containerHeight = panelRef.current?.getBoundingClientRect().height;
895
- if (rootRef.current?.parentElement) {
896
- rootRef.current.parentElement.style.paddingBottom = `${containerHeight}px`;
897
- }
898
- };
899
- run();
900
- if (typeof window !== 'undefined') {
901
- window.addEventListener('resize', run);
902
- return () => {
903
- window.removeEventListener('resize', run);
904
- if (rootRef.current?.parentElement && typeof previousValue === 'string') {
905
- rootRef.current.parentElement.style.paddingBottom = previousValue;
906
- }
907
- };
908
- }
909
- }
910
- return;
911
- }, [isResolvedOpen]);
912
- const {
913
- style: panelStyle = {},
914
- ...otherPanelProps
915
- } = panelProps;
916
- const {
917
- style: closeButtonStyle = {},
918
- onClick: onCloseClick,
919
- ...otherCloseButtonProps
920
- } = closeButtonProps;
921
- const {
922
- style: toggleButtonStyle = {},
923
- onClick: onToggleClick,
924
- ...otherToggleButtonProps
925
- } = toggleButtonProps;
926
-
927
- // Do not render on the server
928
- if (!isMounted()) return null;
929
- return /*#__PURE__*/React.createElement(Container, {
930
- ref: rootRef,
931
- className: "TanStackRouterDevtools"
932
- }, /*#__PURE__*/React.createElement(ThemeProvider, {
933
- theme: defaultTheme
934
- }, /*#__PURE__*/React.createElement(TanStackRouterDevtoolsPanel, _extends({
935
- ref: panelRef
936
- }, otherPanelProps, {
937
- router: router,
938
- style: {
939
- position: 'fixed',
940
- bottom: '0',
941
- right: '0',
942
- zIndex: 99999,
943
- width: '100%',
944
- height: devtoolsHeight ?? 500,
945
- maxHeight: '90%',
946
- boxShadow: '0 0 20px rgba(0,0,0,.3)',
947
- borderTop: `1px solid ${defaultTheme.gray}`,
948
- transformOrigin: 'top',
949
- // visibility will be toggled after transitions, but set initial state here
950
- visibility: isOpen ? 'visible' : 'hidden',
951
- ...panelStyle,
952
- ...(isResizing ? {
953
- transition: `none`
954
- } : {
955
- transition: `all .2s ease`
956
- }),
957
- ...(isResolvedOpen ? {
958
- opacity: 1,
959
- pointerEvents: 'all',
960
- transform: `translateY(0) scale(1)`
961
- } : {
962
- opacity: 0,
963
- pointerEvents: 'none',
964
- transform: `translateY(15px) scale(1.02)`
965
- })
966
- },
967
- isOpen: isResolvedOpen,
968
- setIsOpen: setIsOpen,
969
- handleDragStart: e => handleDragStart(panelRef.current, e)
970
- })), isResolvedOpen ? /*#__PURE__*/React.createElement(Button, _extends({
971
- type: "button",
972
- "aria-label": "Close TanStack Router Devtools"
973
- }, otherCloseButtonProps, {
974
- onClick: e => {
975
- setIsOpen(false);
976
- onCloseClick && onCloseClick(e);
977
- },
978
- style: {
979
- position: 'fixed',
980
- zIndex: 99999,
981
- margin: '.5em',
982
- bottom: 0,
983
- ...(position === 'top-right' ? {
984
- right: '0'
985
- } : position === 'top-left' ? {
986
- left: '0'
987
- } : position === 'bottom-right' ? {
988
- right: '0'
989
- } : {
990
- left: '0'
991
- }),
992
- ...closeButtonStyle
993
- }
994
- }), "Close") : null), !isResolvedOpen ? /*#__PURE__*/React.createElement("button", _extends({
995
- type: "button"
996
- }, otherToggleButtonProps, {
997
- "aria-label": "Open TanStack Router Devtools",
998
- onClick: e => {
999
- setIsOpen(true);
1000
- onToggleClick && onToggleClick(e);
1001
- },
1002
- style: {
1003
- appearance: 'none',
1004
- background: 'none',
1005
- border: 0,
1006
- padding: 0,
1007
- position: 'fixed',
1008
- zIndex: 99999,
1009
- display: 'inline-flex',
1010
- fontSize: '1.5em',
1011
- margin: '.5em',
1012
- cursor: 'pointer',
1013
- width: 'fit-content',
1014
- ...(position === 'top-right' ? {
1015
- top: '0',
1016
- right: '0'
1017
- } : position === 'top-left' ? {
1018
- top: '0',
1019
- left: '0'
1020
- } : position === 'bottom-right' ? {
1021
- bottom: '0',
1022
- right: '0'
1023
- } : {
1024
- bottom: '0',
1025
- left: '0'
1026
- }),
1027
- ...toggleButtonStyle
1028
- }
1029
- }), /*#__PURE__*/React.createElement(Logo, {
1030
- "aria-hidden": true
1031
- })) : null);
1032
- }
1033
- function RouteComp({
1034
- route,
1035
- isRoot,
1036
- activeId,
1037
- setActiveId
1038
- }) {
1039
- const routerState = useRouterState();
1040
- const matches = routerState.status === 'pending' ? routerState.pendingMatches ?? [] : routerState.matches;
1041
- const match = routerState.matches.find(d => d.routeId === route.id);
1042
- return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
1043
- role: "button",
1044
- "aria-label": `Open match details for ${route.id}`,
1045
- onClick: () => {
1046
- if (match) {
1047
- setActiveId(activeId === route.id ? '' : route.id);
1048
- }
1049
- },
1050
- style: {
1051
- display: 'flex',
1052
- borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
1053
- cursor: match ? 'pointer' : 'default',
1054
- alignItems: 'center',
1055
- background: route.id === activeId ? 'rgba(255,255,255,.1)' : undefined,
1056
- padding: '.25rem .5rem',
1057
- gap: '.5rem'
1058
- }
1059
- }, isRoot ? null : /*#__PURE__*/React.createElement("div", {
1060
- style: {
1061
- flex: '0 0 auto',
1062
- width: '.7rem',
1063
- height: '.7rem',
1064
- alignItems: 'center',
1065
- justifyContent: 'center',
1066
- fontWeight: 'bold',
1067
- borderRadius: '100%',
1068
- transition: 'all .2s ease-out',
1069
- background: getRouteStatusColor(matches, route, defaultTheme),
1070
- opacity: match ? 1 : 0.3
1071
- }
1072
- }), /*#__PURE__*/React.createElement("div", {
1073
- style: {
1074
- flex: '1 0 auto',
1075
- display: 'flex',
1076
- justifyContent: 'space-between',
1077
- alignItems: 'center',
1078
- padding: isRoot ? '0 .25rem' : 0,
1079
- opacity: match ? 1 : 0.7,
1080
- fontSize: '0.7rem'
1081
- }
1082
- }, /*#__PURE__*/React.createElement(Code, null, route.path || trimPath(route.id), " "), /*#__PURE__*/React.createElement("div", {
1083
- style: {
1084
- display: 'flex',
1085
- alignItems: 'center',
1086
- gap: '.5rem'
1087
- }
1088
- }, match ? /*#__PURE__*/React.createElement(Code, {
1089
- style: {
1090
- opacity: 0.3
1091
- }
1092
- }, match.id) : null, /*#__PURE__*/React.createElement(AgeTicker, {
1093
- match: match
1094
- })))), route.children?.length ? /*#__PURE__*/React.createElement("div", {
1095
- style: {
1096
- marginLeft: isRoot ? 0 : '1rem',
1097
- borderLeft: isRoot ? '' : `solid 1px ${defaultTheme.grayAlt}`
1098
- }
1099
- }, [...route.children].sort((a, b) => {
1100
- return a.rank - b.rank;
1101
- }).map(r => /*#__PURE__*/React.createElement(RouteComp, {
1102
- key: r.id,
1103
- route: r,
1104
- activeId: activeId,
1105
- setActiveId: setActiveId
1106
- }))) : null);
1107
- }
1108
- const TanStackRouterDevtoolsPanel = /*#__PURE__*/React.forwardRef(function TanStackRouterDevtoolsPanel(props, ref) {
1109
- const {
1110
- isOpen = true,
1111
- setIsOpen,
1112
- handleDragStart,
1113
- router: userRouter,
1114
- ...panelProps
1115
- } = props;
1116
- const router = useRouter();
1117
- const routerState = useRouterState();
1118
- const matches = [...(routerState.pendingMatches ?? []), ...routerState.matches, ...routerState.cachedMatches];
1119
- 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.');
1120
-
1121
- // useStore(router.__store)
1122
-
1123
- const [showMatches, setShowMatches] = useLocalStorage('tanstackRouterDevtoolsShowMatches', true);
1124
- const [activeId, setActiveId] = useLocalStorage('tanstackRouterDevtoolsActiveRouteId', '');
1125
- const activeMatch = React.useMemo(() => matches.find(d => d.routeId === activeId || d.id === activeId), [matches, activeId]);
1126
- const hasSearch = Object.keys(routerState.location.search || {}).length;
1127
- const explorerState = {
1128
- ...router,
1129
- state: router.state
1130
- };
1131
- return /*#__PURE__*/React.createElement(ThemeProvider, {
1132
- theme: defaultTheme
1133
- }, /*#__PURE__*/React.createElement(Panel, _extends({
1134
- ref: ref,
1135
- className: "TanStackRouterDevtoolsPanel"
1136
- }, panelProps), /*#__PURE__*/React.createElement("style", {
1137
- dangerouslySetInnerHTML: {
1138
- __html: `
1139
-
1140
- .TanStackRouterDevtoolsPanel * {
1141
- scrollbar-color: ${defaultTheme.backgroundAlt} ${defaultTheme.gray};
1142
- }
1143
-
1144
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar, .TanStackRouterDevtoolsPanel scrollbar {
1145
- width: 1em;
1146
- height: 1em;
1147
- }
1148
-
1149
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-track, .TanStackRouterDevtoolsPanel scrollbar-track {
1150
- background: ${defaultTheme.backgroundAlt};
1151
- }
1152
-
1153
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-thumb, .TanStackRouterDevtoolsPanel scrollbar-thumb {
1154
- background: ${defaultTheme.gray};
1155
- border-radius: .5em;
1156
- border: 3px solid ${defaultTheme.backgroundAlt};
1157
- }
1158
-
1159
- .TanStackRouterDevtoolsPanel table {
1160
- width: 100%;
1161
- }
1162
-
1163
- .TanStackRouterDevtoolsPanel table tr {
1164
- border-bottom: 2px dotted rgba(255, 255, 255, .2);
1165
- }
1166
-
1167
- .TanStackRouterDevtoolsPanel table tr:last-child {
1168
- border-bottom: none
1169
- }
1170
-
1171
- .TanStackRouterDevtoolsPanel table td {
1172
- padding: .25rem .5rem;
1173
- border-right: 2px dotted rgba(255, 255, 255, .05);
1174
- }
1175
-
1176
- .TanStackRouterDevtoolsPanel table td:last-child {
1177
- border-right: none
1178
- }
1179
-
1180
- `
1181
- }
1182
- }), /*#__PURE__*/React.createElement("div", {
1183
- style: {
1184
- position: 'absolute',
1185
- left: 0,
1186
- top: 0,
1187
- width: '100%',
1188
- height: '4px',
1189
- marginBottom: '-4px',
1190
- cursor: 'row-resize',
1191
- zIndex: 100000
1192
- },
1193
- onMouseDown: handleDragStart
1194
- }), /*#__PURE__*/React.createElement("div", {
1195
- style: {
1196
- flex: '1 1 500px',
1197
- minHeight: '40%',
1198
- maxHeight: '100%',
1199
- overflow: 'auto',
1200
- borderRight: `1px solid ${defaultTheme.grayAlt}`,
1201
- display: 'flex',
1202
- flexDirection: 'column'
1203
- }
1204
- }, /*#__PURE__*/React.createElement("div", {
1205
- style: {
1206
- display: 'flex',
1207
- justifyContent: 'start',
1208
- gap: '1rem',
1209
- padding: '1rem',
1210
- alignItems: 'center',
1211
- background: defaultTheme.backgroundAlt
1212
- }
1213
- }, /*#__PURE__*/React.createElement(Logo, {
1214
- "aria-hidden": true
1215
- }), /*#__PURE__*/React.createElement("div", {
1216
- style: {
1217
- fontSize: 'clamp(.8rem, 2vw, 1.3rem)',
1218
- fontWeight: 'bold'
1219
- }
1220
- }, /*#__PURE__*/React.createElement("span", {
1221
- style: {
1222
- fontWeight: 100
1223
- }
1224
- }, "Devtools"))), /*#__PURE__*/React.createElement("div", {
1225
- style: {
1226
- overflowY: 'auto',
1227
- flex: '1'
1228
- }
1229
- }, /*#__PURE__*/React.createElement("div", {
1230
- style: {
1231
- padding: '.5em'
1232
- }
1233
- }, /*#__PURE__*/React.createElement(Explorer, {
1234
- label: "Router",
1235
- value: Object.fromEntries(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]))),
1236
- defaultExpanded: {
1237
- state: {},
1238
- context: {},
1239
- options: {}
1240
- },
1241
- filterSubEntries: subEntries => {
1242
- return subEntries.filter(d => typeof d.value !== 'function');
1243
- }
1244
- })))), /*#__PURE__*/React.createElement("div", {
1245
- style: {
1246
- flex: '1 1 500px',
1247
- minHeight: '40%',
1248
- maxHeight: '100%',
1249
- overflow: 'auto',
1250
- borderRight: `1px solid ${defaultTheme.grayAlt}`,
1251
- display: 'flex',
1252
- flexDirection: 'column'
1253
- }
1254
- }, /*#__PURE__*/React.createElement("div", {
1255
- style: {
1256
- flex: '1 1 auto',
1257
- overflowY: 'auto'
1258
- }
1259
- }, /*#__PURE__*/React.createElement("div", {
1260
- style: {
1261
- padding: '.5em',
1262
- background: defaultTheme.backgroundAlt,
1263
- position: 'sticky',
1264
- top: 0,
1265
- zIndex: 1,
1266
- display: 'flex',
1267
- alignItems: 'center',
1268
- gap: '.5rem',
1269
- fontWeight: 'bold'
1270
- }
1271
- }, "Pathname", ' ', routerState.location.maskedLocation ? /*#__PURE__*/React.createElement("div", {
1272
- style: {
1273
- padding: '.1rem .5rem',
1274
- background: defaultTheme.warning,
1275
- color: 'black',
1276
- borderRadius: '.5rem'
1277
- }
1278
- }, "Masked") : null), /*#__PURE__*/React.createElement("div", {
1279
- style: {
1280
- padding: '.5rem',
1281
- display: 'flex',
1282
- gap: '.5rem',
1283
- alignItems: 'center'
1284
- }
1285
- }, /*#__PURE__*/React.createElement("code", {
1286
- style: {
1287
- opacity: 0.6
1288
- }
1289
- }, routerState.location.pathname), routerState.location.maskedLocation ? /*#__PURE__*/React.createElement("code", {
1290
- style: {
1291
- color: defaultTheme.warning,
1292
- fontWeight: 'bold'
1293
- }
1294
- }, routerState.location.maskedLocation.pathname) : null), /*#__PURE__*/React.createElement("div", {
1295
- style: {
1296
- padding: '.5em',
1297
- background: defaultTheme.backgroundAlt,
1298
- position: 'sticky',
1299
- top: 0,
1300
- zIndex: 1,
1301
- display: 'flex',
1302
- alignItems: 'center',
1303
- justifyContent: 'space-between',
1304
- gap: '.5rem',
1305
- fontWeight: 'bold'
1306
- }
1307
- }, /*#__PURE__*/React.createElement("div", {
1308
- style: {
1309
- display: 'flex',
1310
- alignItems: 'center',
1311
- gap: '.5rem'
1312
- }
1313
- }, /*#__PURE__*/React.createElement("button", {
1314
- type: "button",
1315
- onClick: () => {
1316
- setShowMatches(false);
1317
- },
1318
- disabled: !showMatches,
1319
- style: {
1320
- appearance: 'none',
1321
- opacity: showMatches ? 0.5 : 1,
1322
- border: 0,
1323
- background: 'transparent',
1324
- color: 'inherit',
1325
- cursor: 'pointer'
1326
- }
1327
- }, "Routes"), "/", /*#__PURE__*/React.createElement("button", {
1328
- type: "button",
1329
- onClick: () => {
1330
- setShowMatches(true);
1331
- },
1332
- disabled: showMatches,
1333
- style: {
1334
- appearance: 'none',
1335
- opacity: !showMatches ? 0.5 : 1,
1336
- border: 0,
1337
- background: 'transparent',
1338
- color: 'inherit',
1339
- cursor: 'pointer'
1340
- }
1341
- }, "Matches")), /*#__PURE__*/React.createElement("div", {
1342
- style: {
1343
- opacity: 0.3,
1344
- fontSize: '0.7rem',
1345
- fontWeight: 'normal'
1346
- }
1347
- }, "age / staleTime / gcTime")), !showMatches ? /*#__PURE__*/React.createElement(RouteComp, {
1348
- route: router.routeTree,
1349
- isRoot: true,
1350
- activeId: activeId,
1351
- setActiveId: setActiveId
1352
- }) : /*#__PURE__*/React.createElement("div", null, (routerState.status === 'pending' ? routerState.pendingMatches ?? [] : routerState.matches).map((match, i) => {
1353
- return /*#__PURE__*/React.createElement("div", {
1354
- key: match.id || i,
1355
- role: "button",
1356
- "aria-label": `Open match details for ${match.id}`,
1357
- onClick: () => setActiveId(activeId === match.id ? '' : match.id),
1358
- style: {
1359
- display: 'flex',
1360
- borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
1361
- cursor: 'pointer',
1362
- alignItems: 'center',
1363
- background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined
1364
- }
1365
- }, /*#__PURE__*/React.createElement("div", {
1366
- style: {
1367
- flex: '0 0 auto',
1368
- width: '1.3rem',
1369
- height: '1.3rem',
1370
- marginLeft: '.25rem',
1371
- background: getStatusColor(match, defaultTheme),
1372
- alignItems: 'center',
1373
- justifyContent: 'center',
1374
- fontWeight: 'bold',
1375
- borderRadius: '.25rem',
1376
- transition: 'all .2s ease-out'
1377
- }
1378
- }), /*#__PURE__*/React.createElement(Code, {
1379
- style: {
1380
- padding: '.5em',
1381
- fontSize: '0.7rem'
1382
- }
1383
- }, `${match.id}`), /*#__PURE__*/React.createElement(AgeTicker, {
1384
- match: match
1385
- }));
1386
- }))), routerState.cachedMatches?.length ? /*#__PURE__*/React.createElement("div", {
1387
- style: {
1388
- flex: '1 1 auto',
1389
- overflowY: 'auto',
1390
- maxHeight: '50%'
1391
- }
1392
- }, /*#__PURE__*/React.createElement("div", {
1393
- style: {
1394
- padding: '.5em',
1395
- background: defaultTheme.backgroundAlt,
1396
- position: 'sticky',
1397
- top: 0,
1398
- zIndex: 1,
1399
- display: 'flex',
1400
- alignItems: 'center',
1401
- justifyContent: 'space-between',
1402
- gap: '.5rem',
1403
- fontWeight: 'bold'
1404
- }
1405
- }, /*#__PURE__*/React.createElement("div", null, "Cached Matches"), /*#__PURE__*/React.createElement("div", {
1406
- style: {
1407
- opacity: 0.3,
1408
- fontSize: '0.7rem',
1409
- fontWeight: 'normal'
1410
- }
1411
- }, "age / staleTime / gcTime")), /*#__PURE__*/React.createElement("div", null, routerState.cachedMatches.map(match => {
1412
- return /*#__PURE__*/React.createElement("div", {
1413
- key: match.id,
1414
- role: "button",
1415
- "aria-label": `Open match details for ${match.id}`,
1416
- onClick: () => setActiveId(activeId === match.id ? '' : match.id),
1417
- style: {
1418
- display: 'flex',
1419
- borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
1420
- cursor: 'pointer',
1421
- alignItems: 'center',
1422
- background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined,
1423
- fontSize: '0.7rem'
1424
- }
1425
- }, /*#__PURE__*/React.createElement("div", {
1426
- style: {
1427
- flex: '0 0 auto',
1428
- width: '.75rem',
1429
- height: '.75rem',
1430
- marginLeft: '.25rem',
1431
- background: getStatusColor(match, defaultTheme),
1432
- alignItems: 'center',
1433
- justifyContent: 'center',
1434
- fontWeight: 'bold',
1435
- borderRadius: '100%',
1436
- transition: 'all 1s ease-out'
1437
- }
1438
- }), /*#__PURE__*/React.createElement(Code, {
1439
- style: {
1440
- padding: '.5em'
1441
- }
1442
- }, `${match.id}`), /*#__PURE__*/React.createElement("div", {
1443
- style: {
1444
- marginLeft: 'auto'
1445
- }
1446
- }, /*#__PURE__*/React.createElement(AgeTicker, {
1447
- match: match
1448
- })));
1449
- }))) : null), activeMatch ? /*#__PURE__*/React.createElement(ActivePanel, null, /*#__PURE__*/React.createElement("div", {
1450
- style: {
1451
- padding: '.5em',
1452
- background: defaultTheme.backgroundAlt,
1453
- position: 'sticky',
1454
- top: 0,
1455
- bottom: 0,
1456
- zIndex: 1
1457
- }
1458
- }, "Match Details"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("table", {
1459
- style: {
1460
- fontSize: '0.8rem'
1461
- }
1462
- }, /*#__PURE__*/React.createElement("tbody", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
1463
- style: {
1464
- opacity: '.5'
1465
- }
1466
- }, "ID"), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(Code, {
1467
- style: {
1468
- lineHeight: '1.8em'
1469
- }
1470
- }, JSON.stringify(activeMatch.id, null, 2)))), /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("td", {
1471
- style: {
1472
- opacity: '.5'
1473
- }
1474
- }, "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", {
1475
- style: {
1476
- opacity: '.5'
1477
- }
1478
- }, "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", {
1479
- style: {
1480
- background: defaultTheme.backgroundAlt,
1481
- padding: '.5em',
1482
- position: 'sticky',
1483
- top: 0,
1484
- bottom: 0,
1485
- zIndex: 1
1486
- }
1487
- }, "Loader Data"), /*#__PURE__*/React.createElement("div", {
1488
- style: {
1489
- padding: '.5em'
1490
- }
1491
- }, /*#__PURE__*/React.createElement(Explorer, {
1492
- label: "loaderData",
1493
- value: activeMatch.loaderData,
1494
- defaultExpanded: {}
1495
- }))) : null, /*#__PURE__*/React.createElement("div", {
1496
- style: {
1497
- background: defaultTheme.backgroundAlt,
1498
- padding: '.5em',
1499
- position: 'sticky',
1500
- top: 0,
1501
- bottom: 0,
1502
- zIndex: 1
1503
- }
1504
- }, "Explorer"), /*#__PURE__*/React.createElement("div", {
1505
- style: {
1506
- padding: '.5em'
1507
- }
1508
- }, /*#__PURE__*/React.createElement(Explorer, {
1509
- label: "Match",
1510
- value: activeMatch,
1511
- defaultExpanded: {}
1512
- }))) : null, hasSearch ? /*#__PURE__*/React.createElement("div", {
1513
- style: {
1514
- flex: '1 1 500px',
1515
- minHeight: '40%',
1516
- maxHeight: '100%',
1517
- overflow: 'auto',
1518
- borderRight: `1px solid ${defaultTheme.grayAlt}`,
1519
- display: 'flex',
1520
- flexDirection: 'column'
1521
- }
1522
- }, /*#__PURE__*/React.createElement("div", {
1523
- style: {
1524
- padding: '.5em',
1525
- background: defaultTheme.backgroundAlt,
1526
- position: 'sticky',
1527
- top: 0,
1528
- bottom: 0,
1529
- zIndex: 1,
1530
- fontWeight: 'bold'
1531
- }
1532
- }, "Search Params"), /*#__PURE__*/React.createElement("div", {
1533
- style: {
1534
- padding: '.5em'
1535
- }
1536
- }, /*#__PURE__*/React.createElement(Explorer, {
1537
- value: routerState.location.search || {},
1538
- defaultExpanded: Object.keys(routerState.location.search || {}).reduce((obj, next) => {
1539
- obj[next] = {};
1540
- return obj;
1541
- }, {})
1542
- }))) : null));
1543
- });
1544
- function AgeTicker({
1545
- match
1546
- }) {
1547
- const router = useRouter();
1548
- const rerender = React.useReducer(() => ({}), () => ({}))[1];
1549
- React.useEffect(() => {
1550
- const interval = setInterval(() => {
1551
- rerender();
1552
- }, 1000);
1553
- return () => {
1554
- clearInterval(interval);
1555
- };
1556
- }, []);
1557
- if (!match) {
1558
- return null;
1559
- }
1560
- const route = router.looseRoutesById[match?.routeId];
1561
- if (!route.options.loader) {
1562
- return null;
1563
- }
1564
- const age = Date.now() - match?.updatedAt;
1565
- const staleTime = route.options.staleTime ?? router.options.defaultStaleTime ?? 0;
1566
- const gcTime = route.options.gcTime ?? router.options.defaultGcTime ?? 30 * 60 * 1000;
1567
- return /*#__PURE__*/React.createElement("div", {
1568
- style: {
1569
- display: 'inline-flex',
1570
- alignItems: 'center',
1571
- gap: '.25rem',
1572
- color: age > staleTime ? defaultTheme.warning : undefined
1573
- }
1574
- }, /*#__PURE__*/React.createElement("div", {
1575
- style: {}
1576
- }, 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)));
1577
- }
1578
- function formatTime(ms) {
1579
- const units = ['s', 'min', 'h', 'd'];
1580
- const values = [ms / 1000, ms / 60000, ms / 3600000, ms / 86400000];
1581
- let chosenUnitIndex = 0;
1582
- for (let i = 1; i < values.length; i++) {
1583
- if (values[i] < 1) break;
1584
- chosenUnitIndex = i;
1585
- }
1586
- const formatter = new Intl.NumberFormat(navigator.language, {
1587
- compactDisplay: 'short',
1588
- notation: 'compact',
1589
- maximumFractionDigits: 0
1590
- });
1591
- return formatter.format(values[chosenUnitIndex]) + units[chosenUnitIndex];
1592
- }
1593
-
1594
- exports.TanStackRouterDevtools = TanStackRouterDevtools;
1595
- exports.TanStackRouterDevtoolsPanel = TanStackRouterDevtoolsPanel;
1596
-
1597
- }));
1598
- //# sourceMappingURL=index.development.js.map