@tanstack/react-router-devtools 0.0.1-beta.83 → 1.114.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 (59) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +3 -1
  3. package/dist/cjs/TanStackRouterDevtools.cjs +72 -0
  4. package/dist/cjs/TanStackRouterDevtools.cjs.map +1 -0
  5. package/dist/cjs/TanStackRouterDevtools.d.cts +41 -0
  6. package/dist/cjs/TanStackRouterDevtoolsPanel.cjs +44 -0
  7. package/dist/cjs/TanStackRouterDevtoolsPanel.cjs.map +1 -0
  8. package/dist/cjs/TanStackRouterDevtoolsPanel.d.cts +33 -0
  9. package/dist/cjs/index.cjs +17 -0
  10. package/dist/cjs/index.cjs.map +1 -0
  11. package/dist/cjs/index.d.cts +6 -0
  12. package/dist/esm/TanStackRouterDevtools.d.ts +41 -0
  13. package/dist/esm/TanStackRouterDevtools.js +72 -0
  14. package/dist/esm/TanStackRouterDevtools.js.map +1 -0
  15. package/dist/esm/TanStackRouterDevtoolsPanel.d.ts +33 -0
  16. package/dist/esm/TanStackRouterDevtoolsPanel.js +44 -0
  17. package/dist/esm/TanStackRouterDevtoolsPanel.js.map +1 -0
  18. package/dist/esm/index.d.ts +6 -0
  19. package/dist/esm/index.js +17 -0
  20. package/dist/esm/index.js.map +1 -0
  21. package/package.json +42 -26
  22. package/src/TanStackRouterDevtools.tsx +134 -0
  23. package/src/TanStackRouterDevtoolsPanel.tsx +87 -0
  24. package/src/index.ts +22 -0
  25. package/build/cjs/Explorer.js +0 -216
  26. package/build/cjs/Explorer.js.map +0 -1
  27. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -31
  28. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +0 -1
  29. package/build/cjs/devtools.js +0 -583
  30. package/build/cjs/devtools.js.map +0 -1
  31. package/build/cjs/index.js +0 -21
  32. package/build/cjs/index.js.map +0 -1
  33. package/build/cjs/styledComponents.js +0 -79
  34. package/build/cjs/styledComponents.js.map +0 -1
  35. package/build/cjs/theme.js +0 -51
  36. package/build/cjs/theme.js.map +0 -1
  37. package/build/cjs/useLocalStorage.js +0 -58
  38. package/build/cjs/useLocalStorage.js.map +0 -1
  39. package/build/cjs/useMediaQuery.js +0 -58
  40. package/build/cjs/useMediaQuery.js.map +0 -1
  41. package/build/cjs/utils.js +0 -107
  42. package/build/cjs/utils.js.map +0 -1
  43. package/build/esm/index.js +0 -984
  44. package/build/esm/index.js.map +0 -1
  45. package/build/stats-html.html +0 -4044
  46. package/build/stats-react.json +0 -504
  47. package/build/types/index.d.ts +0 -77
  48. package/build/umd/index.development.js +0 -1119
  49. package/build/umd/index.development.js.map +0 -1
  50. package/build/umd/index.production.js +0 -54
  51. package/build/umd/index.production.js.map +0 -1
  52. package/src/Explorer.tsx +0 -290
  53. package/src/devtools.tsx +0 -984
  54. package/src/index.tsx +0 -1
  55. package/src/styledComponents.ts +0 -106
  56. package/src/theme.tsx +0 -31
  57. package/src/useLocalStorage.ts +0 -52
  58. package/src/useMediaQuery.ts +0 -39
  59. package/src/utils.ts +0 -169
@@ -1,1119 +0,0 @@
1
- /**
2
- * react-router-devtools
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/with-selector')) :
13
- typeof define === 'function' && define.amd ? define(['exports', 'react', 'use-sync-external-store/shim/with-selector'], factory) :
14
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ReactRouterDevtools = {}, global.React, global.withSelector));
15
- })(this, (function (exports, React, withSelector) { 'use strict';
16
-
17
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
18
-
19
- function _interopNamespace(e) {
20
- if (e && e.__esModule) return e;
21
- var n = Object.create(null);
22
- if (e) {
23
- Object.keys(e).forEach(function (k) {
24
- if (k !== 'default') {
25
- var d = Object.getOwnPropertyDescriptor(e, k);
26
- Object.defineProperty(n, k, d.get ? d : {
27
- enumerable: true,
28
- get: function () { return e[k]; }
29
- });
30
- }
31
- });
32
- }
33
- n["default"] = e;
34
- return Object.freeze(n);
35
- }
36
-
37
- var React__namespace = /*#__PURE__*/_interopNamespace(React);
38
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
39
-
40
- function _extends() {
41
- _extends = Object.assign ? Object.assign.bind() : function (target) {
42
- for (var i = 1; i < arguments.length; i++) {
43
- var source = arguments[i];
44
- for (var key in source) {
45
- if (Object.prototype.hasOwnProperty.call(source, key)) {
46
- target[key] = source[key];
47
- }
48
- }
49
- }
50
- return target;
51
- };
52
- return _extends.apply(this, arguments);
53
- }
54
-
55
- var prefix = 'Invariant failed';
56
- function invariant(condition, message) {
57
- if (condition) {
58
- return;
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
- /**
66
- * store
67
- *
68
- * Copyright (c) TanStack
69
- *
70
- * This source code is licensed under the MIT license found in the
71
- * LICENSE.md file in the root directory of this source tree.
72
- *
73
- * @license MIT
74
- */
75
- function shallow(objA, objB) {
76
- if (Object.is(objA, objB)) {
77
- return true;
78
- }
79
- if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
80
- return false;
81
- }
82
-
83
- // if (objA instanceof Map && objB instanceof Map) {
84
- // if (objA.size !== objB.size) return false
85
-
86
- // for (const [key, value] of objA) {
87
- // if (!Object.is(value, objB.get(key))) {
88
- // return false
89
- // }
90
- // }
91
- // return true
92
- // }
93
-
94
- // if (objA instanceof Set && objB instanceof Set) {
95
- // if (objA.size !== objB.size) return false
96
-
97
- // for (const value of objA) {
98
- // if (!objB.has(value)) {
99
- // return false
100
- // }
101
- // }
102
- // return true
103
- // }
104
-
105
- const keysA = Object.keys(objA);
106
- if (keysA.length !== Object.keys(objB).length) {
107
- return false;
108
- }
109
- for (let i = 0; i < keysA.length; i++) {
110
- if (!Object.prototype.hasOwnProperty.call(objB, keysA[i]) || !Object.is(objA[keysA[i]], objB[keysA[i]])) {
111
- return false;
112
- }
113
- }
114
- return true;
115
- }
116
-
117
- /**
118
- * router
119
- *
120
- * Copyright (c) TanStack
121
- *
122
- * This source code is licensed under the MIT license found in the
123
- * LICENSE.md file in the root directory of this source tree.
124
- *
125
- * @license MIT
126
- */
127
-
128
- function last(arr) {
129
- return arr[arr.length - 1];
130
- }
131
-
132
- /**
133
- * react-store
134
- *
135
- * Copyright (c) TanStack
136
- *
137
- * This source code is licensed under the MIT license found in the
138
- * LICENSE.md file in the root directory of this source tree.
139
- *
140
- * @license MIT
141
- */
142
-
143
- function useStore(store, selector = d => d, compareShallow) {
144
- const slice = withSelector.useSyncExternalStoreWithSelector(store.subscribe, () => store.state, () => store.state, selector, compareShallow ? shallow : undefined);
145
- return slice;
146
- }
147
-
148
- /**
149
- * react-router
150
- *
151
- * Copyright (c) TanStack
152
- *
153
- * This source code is licensed under the MIT license found in the
154
- * LICENSE.md file in the root directory of this source tree.
155
- *
156
- * @license MIT
157
- */
158
- const routerContext = /*#__PURE__*/React__namespace.createContext(null);
159
-
160
- const getItem = key => {
161
- try {
162
- const itemValue = localStorage.getItem(key);
163
- if (typeof itemValue === 'string') {
164
- return JSON.parse(itemValue);
165
- }
166
- return undefined;
167
- } catch {
168
- return undefined;
169
- }
170
- };
171
- function useLocalStorage(key, defaultValue) {
172
- const [value, setValue] = React__default["default"].useState();
173
- React__default["default"].useEffect(() => {
174
- const initialValue = getItem(key);
175
- if (typeof initialValue === 'undefined' || initialValue === null) {
176
- setValue(typeof defaultValue === 'function' ? defaultValue() : defaultValue);
177
- } else {
178
- setValue(initialValue);
179
- }
180
- }, [defaultValue, key]);
181
- const setter = React__default["default"].useCallback(updater => {
182
- setValue(old => {
183
- let newVal = updater;
184
- if (typeof updater == 'function') {
185
- newVal = updater(old);
186
- }
187
- try {
188
- localStorage.setItem(key, JSON.stringify(newVal));
189
- } catch {}
190
- return newVal;
191
- });
192
- }, [key]);
193
- return [value, setter];
194
- }
195
-
196
- const defaultTheme = {
197
- background: '#0b1521',
198
- backgroundAlt: '#132337',
199
- foreground: 'white',
200
- gray: '#3f4e60',
201
- grayAlt: '#222e3e',
202
- inputBackgroundColor: '#fff',
203
- inputTextColor: '#000',
204
- success: '#00ab52',
205
- danger: '#ff0085',
206
- active: '#006bff',
207
- warning: '#ffb200'
208
- };
209
- const ThemeContext = /*#__PURE__*/React__default["default"].createContext(defaultTheme);
210
- function ThemeProvider({
211
- theme,
212
- ...rest
213
- }) {
214
- return /*#__PURE__*/React__default["default"].createElement(ThemeContext.Provider, _extends({
215
- value: theme
216
- }, rest));
217
- }
218
- function useTheme() {
219
- return React__default["default"].useContext(ThemeContext);
220
- }
221
-
222
- function useMediaQuery(query) {
223
- // Keep track of the preference in state, start with the current match
224
- const [isMatch, setIsMatch] = React__default["default"].useState(() => {
225
- if (typeof window !== 'undefined') {
226
- return window.matchMedia && window.matchMedia(query).matches;
227
- }
228
- return;
229
- });
230
-
231
- // Watch for changes
232
- React__default["default"].useEffect(() => {
233
- if (typeof window !== 'undefined') {
234
- if (!window.matchMedia) {
235
- return;
236
- }
237
-
238
- // Create a matcher
239
- const matcher = window.matchMedia(query);
240
-
241
- // Create our handler
242
- const onChange = ({
243
- matches
244
- }) => setIsMatch(matches);
245
-
246
- // Listen for changes
247
- matcher.addListener(onChange);
248
- return () => {
249
- // Stop listening for changes
250
- matcher.removeListener(onChange);
251
- };
252
- }
253
- return;
254
- }, [isMatch, query, setIsMatch]);
255
- return isMatch;
256
- }
257
-
258
- const isServer$1 = typeof window === 'undefined';
259
- function getStatusColor(match, theme) {
260
- return match.state.status === 'pending' ? theme.active : match.state.status === 'error' ? theme.danger : match.state.status === 'success' ? theme.success : theme.gray;
261
- }
262
- function styled(type, newStyles, queries = {}) {
263
- return /*#__PURE__*/React__default["default"].forwardRef(({
264
- style,
265
- ...rest
266
- }, ref) => {
267
- const theme = useTheme();
268
- const mediaStyles = Object.entries(queries).reduce((current, [key, value]) => {
269
- // eslint-disable-next-line react-hooks/rules-of-hooks
270
- return useMediaQuery(key) ? {
271
- ...current,
272
- ...(typeof value === 'function' ? value(rest, theme) : value)
273
- } : current;
274
- }, {});
275
- return /*#__PURE__*/React__default["default"].createElement(type, {
276
- ...rest,
277
- style: {
278
- ...(typeof newStyles === 'function' ? newStyles(rest, theme) : newStyles),
279
- ...style,
280
- ...mediaStyles
281
- },
282
- ref
283
- });
284
- });
285
- }
286
- function useIsMounted() {
287
- const mountedRef = React__default["default"].useRef(false);
288
- const isMounted = React__default["default"].useCallback(() => mountedRef.current, []);
289
- React__default["default"][isServer$1 ? 'useEffect' : 'useLayoutEffect'](() => {
290
- mountedRef.current = true;
291
- return () => {
292
- mountedRef.current = false;
293
- };
294
- }, []);
295
- return isMounted;
296
- }
297
-
298
- /**
299
- * Displays a string regardless the type of the data
300
- * @param {unknown} value Value to be stringified
301
- */
302
- const displayValue = value => {
303
- const name = Object.getOwnPropertyNames(Object(value));
304
- const newValue = typeof value === 'bigint' ? `${value.toString()}n` : value;
305
- return JSON.stringify(newValue, name);
306
- };
307
-
308
- /**
309
- * This hook is a safe useState version which schedules state updates in microtasks
310
- * to prevent updating a component state while React is rendering different components
311
- * or when the component is not mounted anymore.
312
- */
313
- function useSafeState(initialState) {
314
- const isMounted = useIsMounted();
315
- const [state, setState] = React__default["default"].useState(initialState);
316
- const safeSetState = React__default["default"].useCallback(value => {
317
- scheduleMicrotask(() => {
318
- if (isMounted()) {
319
- setState(value);
320
- }
321
- });
322
- }, [isMounted]);
323
- return [state, safeSetState];
324
- }
325
-
326
- /**
327
- * Schedules a microtask.
328
- * This can be useful to schedule state updates after rendering.
329
- */
330
- function scheduleMicrotask(callback) {
331
- Promise.resolve().then(callback).catch(error => setTimeout(() => {
332
- throw error;
333
- }));
334
- }
335
-
336
- const Panel = styled('div', (_props, theme) => ({
337
- fontSize: 'clamp(12px, 1.5vw, 14px)',
338
- fontFamily: `sans-serif`,
339
- display: 'flex',
340
- backgroundColor: theme.background,
341
- color: theme.foreground
342
- }), {
343
- '(max-width: 700px)': {
344
- flexDirection: 'column'
345
- },
346
- '(max-width: 600px)': {
347
- fontSize: '.9em'
348
- // flexDirection: 'column',
349
- }
350
- });
351
-
352
- const ActivePanel = styled('div', () => ({
353
- flex: '1 1 500px',
354
- display: 'flex',
355
- flexDirection: 'column',
356
- overflow: 'auto',
357
- height: '100%'
358
- }), {
359
- '(max-width: 700px)': (_props, theme) => ({
360
- borderTop: `2px solid ${theme.gray}`
361
- })
362
- });
363
- const Button = styled('button', (props, theme) => ({
364
- appearance: 'none',
365
- fontSize: '.9em',
366
- fontWeight: 'bold',
367
- background: theme.gray,
368
- border: '0',
369
- borderRadius: '.3em',
370
- color: 'white',
371
- padding: '.5em',
372
- opacity: props.disabled ? '.5' : undefined,
373
- cursor: 'pointer'
374
- }));
375
-
376
- // export const QueryKeys = styled('span', {
377
- // display: 'inline-block',
378
- // fontSize: '0.9em',
379
- // })
380
-
381
- // export const QueryKey = styled('span', {
382
- // display: 'inline-flex',
383
- // alignItems: 'center',
384
- // padding: '.2em .4em',
385
- // fontWeight: 'bold',
386
- // textShadow: '0 0 10px black',
387
- // borderRadius: '.2em',
388
- // })
389
-
390
- const Code = styled('code', {
391
- fontSize: '.9em'
392
- });
393
-
394
- const Entry = styled('div', {
395
- fontFamily: 'Menlo, monospace',
396
- fontSize: '.7rem',
397
- lineHeight: '1.7',
398
- outline: 'none',
399
- wordBreak: 'break-word'
400
- });
401
- const Label = styled('span', {
402
- color: 'white'
403
- });
404
- const LabelButton = styled('button', {
405
- cursor: 'pointer',
406
- color: 'white'
407
- });
408
- const ExpandButton = styled('button', {
409
- cursor: 'pointer',
410
- color: 'inherit',
411
- font: 'inherit',
412
- outline: 'inherit',
413
- background: 'transparent',
414
- border: 'none',
415
- padding: 0
416
- });
417
- const Value = styled('span', (_props, theme) => ({
418
- color: theme.danger
419
- }));
420
- const SubEntries = styled('div', {
421
- marginLeft: '.1em',
422
- paddingLeft: '1em',
423
- borderLeft: '2px solid rgba(0,0,0,.15)'
424
- });
425
- const Info = styled('span', {
426
- color: 'grey',
427
- fontSize: '.7em'
428
- });
429
- const Expander = ({
430
- expanded,
431
- style = {}
432
- }) => /*#__PURE__*/React__namespace.createElement("span", {
433
- style: {
434
- display: 'inline-block',
435
- transition: 'all .1s ease',
436
- transform: `rotate(${expanded ? 90 : 0}deg) ${style.transform || ''}`,
437
- ...style
438
- }
439
- }, "\u25B6");
440
- /**
441
- * Chunk elements in the array by size
442
- *
443
- * when the array cannot be chunked evenly by size, the last chunk will be
444
- * filled with the remaining elements
445
- *
446
- * @example
447
- * chunkArray(['a','b', 'c', 'd', 'e'], 2) // returns [['a','b'], ['c', 'd'], ['e']]
448
- */
449
- function chunkArray(array, size) {
450
- if (size < 1) return [];
451
- let i = 0;
452
- const result = [];
453
- while (i < array.length) {
454
- result.push(array.slice(i, i + size));
455
- i = i + size;
456
- }
457
- return result;
458
- }
459
- const DefaultRenderer = ({
460
- handleEntry,
461
- label,
462
- value,
463
- subEntries = [],
464
- subEntryPages = [],
465
- type,
466
- expanded = false,
467
- toggleExpanded,
468
- pageSize,
469
- renderer
470
- }) => {
471
- const [expandedPages, setExpandedPages] = React__namespace.useState([]);
472
- const [valueSnapshot, setValueSnapshot] = React__namespace.useState(undefined);
473
- const refreshValueSnapshot = () => {
474
- setValueSnapshot(value());
475
- };
476
- return /*#__PURE__*/React__namespace.createElement(Entry, null, subEntryPages.length ? /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(ExpandButton, {
477
- onClick: () => toggleExpanded()
478
- }, /*#__PURE__*/React__namespace.createElement(Expander, {
479
- expanded: expanded
480
- }), " ", 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", {
481
- key: index
482
- }, /*#__PURE__*/React__namespace.createElement(Entry, null, /*#__PURE__*/React__namespace.createElement(LabelButton, {
483
- onClick: () => setExpandedPages(old => old.includes(index) ? old.filter(d => d !== index) : [...old, index])
484
- }, /*#__PURE__*/React__namespace.createElement(Expander, {
485
- expanded: expanded
486
- }), " [", 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, {
487
- renderer: renderer,
488
- label: /*#__PURE__*/React__namespace.createElement("button", {
489
- onClick: refreshValueSnapshot,
490
- style: {
491
- appearance: 'none',
492
- border: '0',
493
- background: 'transparent'
494
- }
495
- }, /*#__PURE__*/React__namespace.createElement(Label, null, label), " \uD83D\uDD04", ' '),
496
- value: valueSnapshot,
497
- defaultExpanded: {}
498
- })) : /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(Label, null, label, ":"), " ", /*#__PURE__*/React__namespace.createElement(Value, null, displayValue(value))));
499
- };
500
- function isIterable(x) {
501
- return Symbol.iterator in x;
502
- }
503
- function Explorer({
504
- value,
505
- defaultExpanded,
506
- renderer = DefaultRenderer,
507
- pageSize = 100,
508
- ...rest
509
- }) {
510
- const [expanded, setExpanded] = React__namespace.useState(Boolean(defaultExpanded));
511
- const toggleExpanded = React__namespace.useCallback(() => setExpanded(old => !old), []);
512
- let type = typeof value;
513
- let subEntries = [];
514
- const makeProperty = sub => {
515
- const subDefaultExpanded = defaultExpanded === true ? {
516
- [sub.label]: true
517
- } : defaultExpanded?.[sub.label];
518
- return {
519
- ...sub,
520
- defaultExpanded: subDefaultExpanded
521
- };
522
- };
523
- if (Array.isArray(value)) {
524
- type = 'array';
525
- subEntries = value.map((d, i) => makeProperty({
526
- label: i.toString(),
527
- value: d
528
- }));
529
- } else if (value !== null && typeof value === 'object' && isIterable(value) && typeof value[Symbol.iterator] === 'function') {
530
- type = 'Iterable';
531
- subEntries = Array.from(value, (val, i) => makeProperty({
532
- label: i.toString(),
533
- value: val
534
- }));
535
- } else if (typeof value === 'object' && value !== null) {
536
- type = 'object';
537
- subEntries = Object.entries(value).map(([key, val]) => makeProperty({
538
- label: key,
539
- value: val
540
- }));
541
- }
542
- const subEntryPages = chunkArray(subEntries, pageSize);
543
- return renderer({
544
- handleEntry: entry => /*#__PURE__*/React__namespace.createElement(Explorer, _extends({
545
- key: entry.label,
546
- value: value,
547
- renderer: renderer
548
- }, rest, entry)),
549
- type,
550
- subEntries,
551
- subEntryPages,
552
- value,
553
- expanded,
554
- toggleExpanded,
555
- pageSize,
556
- ...rest
557
- });
558
- }
559
-
560
- const isServer = typeof window === 'undefined';
561
- function Logo(props) {
562
- return /*#__PURE__*/React__default["default"].createElement("div", _extends({}, props, {
563
- style: {
564
- ...(props.style ?? {}),
565
- display: 'flex',
566
- alignItems: 'center',
567
- flexDirection: 'column',
568
- fontSize: '0.8rem',
569
- fontWeight: 'bolder',
570
- lineHeight: '1'
571
- }
572
- }), /*#__PURE__*/React__default["default"].createElement("div", {
573
- style: {
574
- letterSpacing: '-0.05rem'
575
- }
576
- }, "TANSTACK"), /*#__PURE__*/React__default["default"].createElement("div", {
577
- style: {
578
- backgroundImage: 'linear-gradient(to right, var(--tw-gradient-stops))',
579
- // @ts-ignore
580
- '--tw-gradient-from': '#84cc16',
581
- '--tw-gradient-stops': 'var(--tw-gradient-from), var(--tw-gradient-to)',
582
- '--tw-gradient-to': '#10b981',
583
- WebkitBackgroundClip: 'text',
584
- color: 'transparent',
585
- letterSpacing: '0.1rem',
586
- marginRight: '-0.2rem'
587
- }
588
- }, "ROUTER"));
589
- }
590
- function TanStackRouterDevtools({
591
- initialIsOpen,
592
- panelProps = {},
593
- closeButtonProps = {},
594
- toggleButtonProps = {},
595
- position = 'bottom-left',
596
- containerElement: Container = 'footer',
597
- router
598
- }) {
599
- const rootRef = React__default["default"].useRef(null);
600
- const panelRef = React__default["default"].useRef(null);
601
- const [isOpen, setIsOpen] = useLocalStorage('tanstackRouterDevtoolsOpen', initialIsOpen);
602
- const [devtoolsHeight, setDevtoolsHeight] = useLocalStorage('tanstackRouterDevtoolsHeight', null);
603
- const [isResolvedOpen, setIsResolvedOpen] = useSafeState(false);
604
- const [isResizing, setIsResizing] = useSafeState(false);
605
- const isMounted = useIsMounted();
606
- const handleDragStart = (panelElement, startEvent) => {
607
- if (startEvent.button !== 0) return; // Only allow left click for drag
608
-
609
- setIsResizing(true);
610
- const dragInfo = {
611
- originalHeight: panelElement?.getBoundingClientRect().height ?? 0,
612
- pageY: startEvent.pageY
613
- };
614
- const run = moveEvent => {
615
- const delta = dragInfo.pageY - moveEvent.pageY;
616
- const newHeight = dragInfo?.originalHeight + delta;
617
- setDevtoolsHeight(newHeight);
618
- if (newHeight < 70) {
619
- setIsOpen(false);
620
- } else {
621
- setIsOpen(true);
622
- }
623
- };
624
- const unsub = () => {
625
- setIsResizing(false);
626
- document.removeEventListener('mousemove', run);
627
- document.removeEventListener('mouseUp', unsub);
628
- };
629
- document.addEventListener('mousemove', run);
630
- document.addEventListener('mouseup', unsub);
631
- };
632
- React__default["default"].useEffect(() => {
633
- setIsResolvedOpen(isOpen ?? false);
634
- }, [isOpen, isResolvedOpen, setIsResolvedOpen]);
635
-
636
- // Toggle panel visibility before/after transition (depending on direction).
637
- // Prevents focusing in a closed panel.
638
- React__default["default"].useEffect(() => {
639
- const ref = panelRef.current;
640
- if (ref) {
641
- const handlePanelTransitionStart = () => {
642
- if (ref && isResolvedOpen) {
643
- ref.style.visibility = 'visible';
644
- }
645
- };
646
- const handlePanelTransitionEnd = () => {
647
- if (ref && !isResolvedOpen) {
648
- ref.style.visibility = 'hidden';
649
- }
650
- };
651
- ref.addEventListener('transitionstart', handlePanelTransitionStart);
652
- ref.addEventListener('transitionend', handlePanelTransitionEnd);
653
- return () => {
654
- ref.removeEventListener('transitionstart', handlePanelTransitionStart);
655
- ref.removeEventListener('transitionend', handlePanelTransitionEnd);
656
- };
657
- }
658
- return;
659
- }, [isResolvedOpen]);
660
- React__default["default"][isServer ? 'useEffect' : 'useLayoutEffect'](() => {
661
- if (isResolvedOpen) {
662
- const previousValue = rootRef.current?.parentElement?.style.paddingBottom;
663
- const run = () => {
664
- const containerHeight = panelRef.current?.getBoundingClientRect().height;
665
- if (rootRef.current?.parentElement) {
666
- rootRef.current.parentElement.style.paddingBottom = `${containerHeight}px`;
667
- }
668
- };
669
- run();
670
- if (typeof window !== 'undefined') {
671
- window.addEventListener('resize', run);
672
- return () => {
673
- window.removeEventListener('resize', run);
674
- if (rootRef.current?.parentElement && typeof previousValue === 'string') {
675
- rootRef.current.parentElement.style.paddingBottom = previousValue;
676
- }
677
- };
678
- }
679
- }
680
- return;
681
- }, [isResolvedOpen]);
682
- const {
683
- style: panelStyle = {},
684
- ...otherPanelProps
685
- } = panelProps;
686
- const {
687
- style: closeButtonStyle = {},
688
- onClick: onCloseClick,
689
- ...otherCloseButtonProps
690
- } = closeButtonProps;
691
- const {
692
- style: toggleButtonStyle = {},
693
- onClick: onToggleClick,
694
- ...otherToggleButtonProps
695
- } = toggleButtonProps;
696
-
697
- // Do not render on the server
698
- if (!isMounted()) return null;
699
- return /*#__PURE__*/React__default["default"].createElement(Container, {
700
- ref: rootRef,
701
- className: "TanStackRouterDevtools"
702
- }, /*#__PURE__*/React__default["default"].createElement(ThemeProvider, {
703
- theme: defaultTheme
704
- }, /*#__PURE__*/React__default["default"].createElement(TanStackRouterDevtoolsPanel, _extends({
705
- ref: panelRef
706
- }, otherPanelProps, {
707
- router: router,
708
- style: {
709
- position: 'fixed',
710
- bottom: '0',
711
- right: '0',
712
- zIndex: 99999,
713
- width: '100%',
714
- height: devtoolsHeight ?? 500,
715
- maxHeight: '90%',
716
- boxShadow: '0 0 20px rgba(0,0,0,.3)',
717
- borderTop: `1px solid ${defaultTheme.gray}`,
718
- transformOrigin: 'top',
719
- // visibility will be toggled after transitions, but set initial state here
720
- visibility: isOpen ? 'visible' : 'hidden',
721
- ...panelStyle,
722
- ...(isResizing ? {
723
- transition: `none`
724
- } : {
725
- transition: `all .2s ease`
726
- }),
727
- ...(isResolvedOpen ? {
728
- opacity: 1,
729
- pointerEvents: 'all',
730
- transform: `translateY(0) scale(1)`
731
- } : {
732
- opacity: 0,
733
- pointerEvents: 'none',
734
- transform: `translateY(15px) scale(1.02)`
735
- })
736
- },
737
- isOpen: isResolvedOpen,
738
- setIsOpen: setIsOpen,
739
- handleDragStart: e => handleDragStart(panelRef.current, e)
740
- })), isResolvedOpen ? /*#__PURE__*/React__default["default"].createElement(Button, _extends({
741
- type: "button",
742
- "aria-label": "Close TanStack Router Devtools"
743
- }, otherCloseButtonProps, {
744
- onClick: e => {
745
- setIsOpen(false);
746
- onCloseClick && onCloseClick(e);
747
- },
748
- style: {
749
- position: 'fixed',
750
- zIndex: 99999,
751
- margin: '.5em',
752
- bottom: 0,
753
- ...(position === 'top-right' ? {
754
- right: '0'
755
- } : position === 'top-left' ? {
756
- left: '0'
757
- } : position === 'bottom-right' ? {
758
- right: '0'
759
- } : {
760
- left: '0'
761
- }),
762
- ...closeButtonStyle
763
- }
764
- }), "Close") : null), !isResolvedOpen ? /*#__PURE__*/React__default["default"].createElement("button", _extends({
765
- type: "button"
766
- }, otherToggleButtonProps, {
767
- "aria-label": "Open TanStack Router Devtools",
768
- onClick: e => {
769
- setIsOpen(true);
770
- onToggleClick && onToggleClick(e);
771
- },
772
- style: {
773
- appearance: 'none',
774
- background: 'none',
775
- border: 0,
776
- padding: 0,
777
- position: 'fixed',
778
- zIndex: 99999,
779
- display: 'inline-flex',
780
- fontSize: '1.5em',
781
- margin: '.5em',
782
- cursor: 'pointer',
783
- width: 'fit-content',
784
- ...(position === 'top-right' ? {
785
- top: '0',
786
- right: '0'
787
- } : position === 'top-left' ? {
788
- top: '0',
789
- left: '0'
790
- } : position === 'bottom-right' ? {
791
- bottom: '0',
792
- right: '0'
793
- } : {
794
- bottom: '0',
795
- left: '0'
796
- }),
797
- ...toggleButtonStyle
798
- }
799
- }), /*#__PURE__*/React__default["default"].createElement(Logo, {
800
- "aria-hidden": true
801
- })) : null);
802
- }
803
- const TanStackRouterDevtoolsPanel = /*#__PURE__*/React__default["default"].forwardRef(function TanStackRouterDevtoolsPanel(props, ref) {
804
- const {
805
- isOpen = true,
806
- setIsOpen,
807
- handleDragStart,
808
- router: userRouter,
809
- ...panelProps
810
- } = props;
811
- const routerContextValue = React__default["default"].useContext(routerContext);
812
- const router = userRouter ?? routerContextValue?.router;
813
- 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.');
814
- useStore(router.__store);
815
- const [activeRouteId, setActiveRouteId] = useLocalStorage('tanstackRouterDevtoolsActiveRouteId', '');
816
- const [activeMatchId, setActiveMatchId] = useLocalStorage('tanstackRouterDevtoolsActiveMatchId', '');
817
- React__default["default"].useEffect(() => {
818
- setActiveMatchId('');
819
- }, [activeRouteId]);
820
- const allMatches = React__default["default"].useMemo(() => [...Object.values(router.state.currentMatches), ...Object.values(router.state.pendingMatches ?? [])], [router.state.currentMatches, router.state.pendingMatches]);
821
- const activeMatch = allMatches?.find(d => d.id === activeMatchId) || allMatches?.find(d => d.route.id === activeRouteId);
822
- return /*#__PURE__*/React__default["default"].createElement(ThemeProvider, {
823
- theme: defaultTheme
824
- }, /*#__PURE__*/React__default["default"].createElement(Panel, _extends({
825
- ref: ref,
826
- className: "TanStackRouterDevtoolsPanel"
827
- }, panelProps), /*#__PURE__*/React__default["default"].createElement("style", {
828
- dangerouslySetInnerHTML: {
829
- __html: `
830
-
831
- .TanStackRouterDevtoolsPanel * {
832
- scrollbar-color: ${defaultTheme.backgroundAlt} ${defaultTheme.gray};
833
- }
834
-
835
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar, .TanStackRouterDevtoolsPanel scrollbar {
836
- width: 1em;
837
- height: 1em;
838
- }
839
-
840
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-track, .TanStackRouterDevtoolsPanel scrollbar-track {
841
- background: ${defaultTheme.backgroundAlt};
842
- }
843
-
844
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-thumb, .TanStackRouterDevtoolsPanel scrollbar-thumb {
845
- background: ${defaultTheme.gray};
846
- border-radius: .5em;
847
- border: 3px solid ${defaultTheme.backgroundAlt};
848
- }
849
-
850
- .TanStackRouterDevtoolsPanel table {
851
- width: 100%;
852
- }
853
-
854
- .TanStackRouterDevtoolsPanel table tr {
855
- border-bottom: 2px dotted rgba(255, 255, 255, .2);
856
- }
857
-
858
- .TanStackRouterDevtoolsPanel table tr:last-child {
859
- border-bottom: none
860
- }
861
-
862
- .TanStackRouterDevtoolsPanel table td {
863
- padding: .25rem .5rem;
864
- border-right: 2px dotted rgba(255, 255, 255, .05);
865
- }
866
-
867
- .TanStackRouterDevtoolsPanel table td:last-child {
868
- border-right: none
869
- }
870
-
871
- `
872
- }
873
- }), /*#__PURE__*/React__default["default"].createElement("div", {
874
- style: {
875
- position: 'absolute',
876
- left: 0,
877
- top: 0,
878
- width: '100%',
879
- height: '4px',
880
- marginBottom: '-4px',
881
- cursor: 'row-resize',
882
- zIndex: 100000
883
- },
884
- onMouseDown: handleDragStart
885
- }), /*#__PURE__*/React__default["default"].createElement("div", {
886
- style: {
887
- flex: '1 1 500px',
888
- minHeight: '40%',
889
- maxHeight: '100%',
890
- overflow: 'auto',
891
- borderRight: `1px solid ${defaultTheme.grayAlt}`,
892
- display: 'flex',
893
- flexDirection: 'column'
894
- }
895
- }, /*#__PURE__*/React__default["default"].createElement("div", {
896
- style: {
897
- display: 'flex',
898
- justifyContent: 'start',
899
- gap: '1rem',
900
- padding: '1rem',
901
- alignItems: 'center',
902
- background: defaultTheme.backgroundAlt
903
- }
904
- }, /*#__PURE__*/React__default["default"].createElement(Logo, {
905
- "aria-hidden": true
906
- }), /*#__PURE__*/React__default["default"].createElement("div", {
907
- style: {
908
- fontSize: 'clamp(.8rem, 2vw, 1.3rem)',
909
- fontWeight: 'bold'
910
- }
911
- }, /*#__PURE__*/React__default["default"].createElement("span", {
912
- style: {
913
- fontWeight: 100
914
- }
915
- }, "Devtools"))), /*#__PURE__*/React__default["default"].createElement("div", {
916
- style: {
917
- overflowY: 'auto',
918
- flex: '1'
919
- }
920
- }, /*#__PURE__*/React__default["default"].createElement("div", {
921
- style: {
922
- padding: '.5em'
923
- }
924
- }, /*#__PURE__*/React__default["default"].createElement(Explorer, {
925
- label: "Router",
926
- value: router,
927
- defaultExpanded: {}
928
- })))), /*#__PURE__*/React__default["default"].createElement("div", {
929
- style: {
930
- flex: '1 1 500px',
931
- minHeight: '40%',
932
- maxHeight: '100%',
933
- overflow: 'auto',
934
- borderRight: `1px solid ${defaultTheme.grayAlt}`,
935
- display: 'flex',
936
- flexDirection: 'column'
937
- }
938
- }, /*#__PURE__*/React__default["default"].createElement("div", {
939
- style: {
940
- padding: '.5em',
941
- background: defaultTheme.backgroundAlt,
942
- position: 'sticky',
943
- top: 0,
944
- zIndex: 1
945
- }
946
- }, "Active Matches"), router.state.currentMatches.map((match, i) => {
947
- return /*#__PURE__*/React__default["default"].createElement("div", {
948
- key: match.route.id || i,
949
- role: "button",
950
- "aria-label": `Open match details for ${match.route.id}`,
951
- onClick: () => setActiveRouteId(activeRouteId === match.route.id ? '' : match.route.id),
952
- style: {
953
- display: 'flex',
954
- borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
955
- cursor: 'pointer',
956
- alignItems: 'center',
957
- background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined
958
- }
959
- }, /*#__PURE__*/React__default["default"].createElement("div", {
960
- style: {
961
- flex: '0 0 auto',
962
- width: '1.3rem',
963
- height: '1.3rem',
964
- marginLeft: '.25rem',
965
- background: getStatusColor(match, defaultTheme),
966
- alignItems: 'center',
967
- justifyContent: 'center',
968
- fontWeight: 'bold',
969
- borderRadius: '.25rem',
970
- transition: 'all .2s ease-out'
971
- }
972
- }), /*#__PURE__*/React__default["default"].createElement(Code, {
973
- style: {
974
- padding: '.5em'
975
- }
976
- }, `${match.id}`));
977
- }), router.state.pendingMatches?.length ? /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement("div", {
978
- style: {
979
- marginTop: '2rem',
980
- padding: '.5em',
981
- background: defaultTheme.backgroundAlt,
982
- position: 'sticky',
983
- top: 0,
984
- zIndex: 1
985
- }
986
- }, "Pending Matches"), router.state.pendingMatches?.map((match, i) => {
987
- return /*#__PURE__*/React__default["default"].createElement("div", {
988
- key: match.route.id || i,
989
- role: "button",
990
- "aria-label": `Open match details for ${match.route.id}`,
991
- onClick: () => setActiveRouteId(activeRouteId === match.route.id ? '' : match.route.id),
992
- style: {
993
- display: 'flex',
994
- borderBottom: `solid 1px ${defaultTheme.grayAlt}`,
995
- cursor: 'pointer',
996
- background: match === activeMatch ? 'rgba(255,255,255,.1)' : undefined
997
- }
998
- }, /*#__PURE__*/React__default["default"].createElement("div", {
999
- style: {
1000
- flex: '0 0 auto',
1001
- width: '1.3rem',
1002
- height: '1.3rem',
1003
- marginLeft: '.25rem',
1004
- background: getStatusColor(match, defaultTheme),
1005
- alignItems: 'center',
1006
- justifyContent: 'center',
1007
- fontWeight: 'bold',
1008
- borderRadius: '.25rem',
1009
- transition: 'all .2s ease-out'
1010
- }
1011
- }), /*#__PURE__*/React__default["default"].createElement(Code, {
1012
- style: {
1013
- padding: '.5em'
1014
- }
1015
- }, `${match.id}`));
1016
- })) : null), activeMatch ? /*#__PURE__*/React__default["default"].createElement(ActivePanel, null, /*#__PURE__*/React__default["default"].createElement("div", {
1017
- style: {
1018
- padding: '.5em',
1019
- background: defaultTheme.backgroundAlt,
1020
- position: 'sticky',
1021
- top: 0,
1022
- bottom: 0,
1023
- zIndex: 1
1024
- }
1025
- }, "Match Details"), /*#__PURE__*/React__default["default"].createElement("div", null, /*#__PURE__*/React__default["default"].createElement("table", null, /*#__PURE__*/React__default["default"].createElement("tbody", null, /*#__PURE__*/React__default["default"].createElement("tr", null, /*#__PURE__*/React__default["default"].createElement("td", {
1026
- style: {
1027
- opacity: '.5'
1028
- }
1029
- }, "ID"), /*#__PURE__*/React__default["default"].createElement("td", null, /*#__PURE__*/React__default["default"].createElement(Code, {
1030
- style: {
1031
- lineHeight: '1.8em'
1032
- }
1033
- }, JSON.stringify(activeMatch.id, null, 2)))), /*#__PURE__*/React__default["default"].createElement("tr", null, /*#__PURE__*/React__default["default"].createElement("td", {
1034
- style: {
1035
- opacity: '.5'
1036
- }
1037
- }, "Status"), /*#__PURE__*/React__default["default"].createElement("td", null, activeMatch.state.status)), /*#__PURE__*/React__default["default"].createElement("tr", null, /*#__PURE__*/React__default["default"].createElement("td", {
1038
- style: {
1039
- opacity: '.5'
1040
- }
1041
- }, "Last Updated"), /*#__PURE__*/React__default["default"].createElement("td", null, activeMatch.state.updatedAt ? new Date(activeMatch.state.updatedAt).toLocaleTimeString() : 'N/A'))))), /*#__PURE__*/React__default["default"].createElement("div", {
1042
- style: {
1043
- background: defaultTheme.backgroundAlt,
1044
- padding: '.5em',
1045
- position: 'sticky',
1046
- top: 0,
1047
- bottom: 0,
1048
- zIndex: 1
1049
- }
1050
- }, "Actions"), /*#__PURE__*/React__default["default"].createElement("div", {
1051
- style: {
1052
- padding: '0.5em'
1053
- }
1054
- }, /*#__PURE__*/React__default["default"].createElement(Button, {
1055
- type: "button",
1056
- onClick: () => activeMatch.load(),
1057
- style: {
1058
- background: defaultTheme.gray
1059
- }
1060
- }, "Reload")), /*#__PURE__*/React__default["default"].createElement("div", {
1061
- style: {
1062
- background: defaultTheme.backgroundAlt,
1063
- padding: '.5em',
1064
- position: 'sticky',
1065
- top: 0,
1066
- bottom: 0,
1067
- zIndex: 1
1068
- }
1069
- }, "Explorer"), /*#__PURE__*/React__default["default"].createElement("div", {
1070
- style: {
1071
- padding: '.5em'
1072
- }
1073
- }, /*#__PURE__*/React__default["default"].createElement(Explorer, {
1074
- label: "Match",
1075
- value: activeMatch,
1076
- defaultExpanded: {}
1077
- }))) : null, /*#__PURE__*/React__default["default"].createElement("div", {
1078
- style: {
1079
- flex: '1 1 500px',
1080
- minHeight: '40%',
1081
- maxHeight: '100%',
1082
- overflow: 'auto',
1083
- borderRight: `1px solid ${defaultTheme.grayAlt}`,
1084
- display: 'flex',
1085
- flexDirection: 'column'
1086
- }
1087
- }, /*#__PURE__*/React__default["default"].createElement("div", {
1088
- style: {
1089
- padding: '.5em',
1090
- background: defaultTheme.backgroundAlt,
1091
- position: 'sticky',
1092
- top: 0,
1093
- bottom: 0,
1094
- zIndex: 1
1095
- }
1096
- }, "Search Params"), /*#__PURE__*/React__default["default"].createElement("div", {
1097
- style: {
1098
- padding: '.5em'
1099
- }
1100
- }, Object.keys(last(router.state.currentMatches)?.state.search || {}).length ? /*#__PURE__*/React__default["default"].createElement(Explorer, {
1101
- value: last(router.state.currentMatches)?.state.search || {},
1102
- defaultExpanded: Object.keys(last(router.state.currentMatches)?.state.search || {}).reduce((obj, next) => {
1103
- obj[next] = {};
1104
- return obj;
1105
- }, {})
1106
- }) : /*#__PURE__*/React__default["default"].createElement("em", {
1107
- style: {
1108
- opacity: 0.5
1109
- }
1110
- }, '{ }')))));
1111
- });
1112
-
1113
- exports.TanStackRouterDevtools = TanStackRouterDevtools;
1114
- exports.TanStackRouterDevtoolsPanel = TanStackRouterDevtoolsPanel;
1115
-
1116
- Object.defineProperty(exports, '__esModule', { value: true });
1117
-
1118
- }));
1119
- //# sourceMappingURL=index.development.js.map