@tanstack/react-router-devtools 0.0.1-beta.83 → 1.114.0

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