@tanstack/router-devtools 0.0.1-alpha.1 → 0.0.1-beta.101

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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/build/cjs/{packages/react-router-devtools/src/Explorer.js → Explorer.js} +52 -81
  4. package/build/cjs/Explorer.js.map +1 -0
  5. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +1 -19
  6. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  7. package/build/cjs/devtools.js +637 -0
  8. package/build/cjs/devtools.js.map +1 -0
  9. package/build/cjs/{packages/react-router-devtools/src/index.js → index.js} +1 -1
  10. package/build/cjs/{packages/react-router-devtools/src/styledComponents.js → styledComponents.js} +10 -38
  11. package/build/cjs/styledComponents.js.map +1 -0
  12. package/build/cjs/{packages/react-router-devtools/src/theme.js → theme.js} +6 -9
  13. package/build/cjs/theme.js.map +1 -0
  14. package/build/cjs/{packages/react-router-devtools/src/useLocalStorage.js → useLocalStorage.js} +3 -10
  15. package/build/cjs/useLocalStorage.js.map +1 -0
  16. package/build/cjs/{packages/react-router-devtools/src/useMediaQuery.js → useMediaQuery.js} +13 -12
  17. package/build/cjs/useMediaQuery.js.map +1 -0
  18. package/build/cjs/{packages/react-router-devtools/src/utils.js → utils.js} +30 -35
  19. package/build/cjs/utils.js.map +1 -0
  20. package/build/esm/index.js +390 -1361
  21. package/build/esm/index.js.map +1 -1
  22. package/build/stats-html.html +59 -49
  23. package/build/stats-react.json +223 -9444
  24. package/build/types/Explorer.d.ts +47 -0
  25. package/build/types/devtools.d.ts +65 -0
  26. package/build/types/index.d.ts +1 -76
  27. package/build/types/styledComponents.d.ts +7 -0
  28. package/build/types/theme.d.ts +34 -0
  29. package/build/types/useLocalStorage.d.ts +1 -0
  30. package/build/types/useMediaQuery.d.ts +1 -0
  31. package/build/types/utils.d.ts +23 -0
  32. package/build/umd/index.development.js +429 -1340
  33. package/build/umd/index.development.js.map +1 -1
  34. package/build/umd/index.production.js +22 -2
  35. package/build/umd/index.production.js.map +1 -1
  36. package/package.json +11 -10
  37. package/src/Explorer.tsx +14 -12
  38. package/src/devtools.tsx +354 -345
  39. package/src/useLocalStorage.ts +5 -5
  40. package/src/useMediaQuery.ts +3 -0
  41. package/src/utils.ts +57 -16
  42. package/build/cjs/packages/react-router-devtools/src/Explorer.js.map +0 -1
  43. package/build/cjs/packages/react-router-devtools/src/Logo.js +0 -73
  44. package/build/cjs/packages/react-router-devtools/src/Logo.js.map +0 -1
  45. package/build/cjs/packages/react-router-devtools/src/devtools.js +0 -654
  46. package/build/cjs/packages/react-router-devtools/src/devtools.js.map +0 -1
  47. package/build/cjs/packages/react-router-devtools/src/styledComponents.js.map +0 -1
  48. package/build/cjs/packages/react-router-devtools/src/theme.js.map +0 -1
  49. package/build/cjs/packages/react-router-devtools/src/useLocalStorage.js.map +0 -1
  50. package/build/cjs/packages/react-router-devtools/src/useMediaQuery.js.map +0 -1
  51. package/build/cjs/packages/react-router-devtools/src/utils.js.map +0 -1
  52. package/src/Logo.tsx +0 -37
  53. /package/build/cjs/{packages/react-router-devtools/src/index.js.map → index.js.map} +0 -0
package/src/devtools.tsx CHANGED
@@ -1,14 +1,28 @@
1
1
  import React from 'react'
2
- import { Router, useRouter, last } from '@tanstack/react-router'
3
- import { formatDistanceStrict } from 'date-fns'
2
+ import {
3
+ last,
4
+ routerContext,
5
+ invariant,
6
+ AnyRouter,
7
+ useStore,
8
+ Route,
9
+ AnyRoute,
10
+ AnyRootRoute,
11
+ RouteMatch,
12
+ } from '@tanstack/router'
4
13
 
5
14
  import useLocalStorage from './useLocalStorage'
6
- import { getStatusColor, useIsMounted, useSafeState } from './utils'
15
+ import {
16
+ getRouteStatusColor,
17
+ getStatusColor,
18
+ multiSortBy,
19
+ useIsMounted,
20
+ useSafeState,
21
+ } from './utils'
7
22
  import { Panel, Button, Code, ActivePanel } from './styledComponents'
8
23
  import { ThemeProvider, defaultTheme as theme } from './theme'
9
24
  // import { getQueryStatusLabel, getQueryStatusColor } from './utils'
10
25
  import Explorer from './Explorer'
11
- import Logo from './Logo'
12
26
 
13
27
  export type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
14
28
 
@@ -52,7 +66,7 @@ interface DevtoolsOptions {
52
66
  /**
53
67
  * A boolean variable indicating if the "lite" version of the library is being used
54
68
  */
55
- useRouter?: () => unknown
69
+ router?: AnyRouter
56
70
  }
57
71
 
58
72
  interface DevtoolsPanelOptions {
@@ -79,11 +93,53 @@ interface DevtoolsPanelOptions {
79
93
  /**
80
94
  * A boolean variable indicating if the "lite" version of the library is being used
81
95
  */
82
- useRouter: () => unknown
96
+ router?: AnyRouter
83
97
  }
84
98
 
85
99
  const isServer = typeof window === 'undefined'
86
100
 
101
+ function Logo(props: React.HTMLProps<HTMLDivElement>) {
102
+ return (
103
+ <div
104
+ {...props}
105
+ style={{
106
+ ...(props.style ?? {}),
107
+ display: 'flex',
108
+ alignItems: 'center',
109
+ flexDirection: 'column',
110
+ fontSize: '0.8rem',
111
+ fontWeight: 'bolder',
112
+ lineHeight: '1',
113
+ }}
114
+ >
115
+ <div
116
+ style={{
117
+ letterSpacing: '-0.05rem',
118
+ }}
119
+ >
120
+ TANSTACK
121
+ </div>
122
+ <div
123
+ style={{
124
+ backgroundImage:
125
+ 'linear-gradient(to right, var(--tw-gradient-stops))',
126
+ // @ts-ignore
127
+ '--tw-gradient-from': '#84cc16',
128
+ '--tw-gradient-stops':
129
+ 'var(--tw-gradient-from), var(--tw-gradient-to)',
130
+ '--tw-gradient-to': '#10b981',
131
+ WebkitBackgroundClip: 'text',
132
+ color: 'transparent',
133
+ letterSpacing: '0.1rem',
134
+ marginRight: '-0.2rem',
135
+ }}
136
+ >
137
+ ROUTER
138
+ </div>
139
+ </div>
140
+ )
141
+ }
142
+
87
143
  export function TanStackRouterDevtools({
88
144
  initialIsOpen,
89
145
  panelProps = {},
@@ -91,7 +147,7 @@ export function TanStackRouterDevtools({
91
147
  toggleButtonProps = {},
92
148
  position = 'bottom-left',
93
149
  containerElement: Container = 'footer',
94
- useRouter: useRouterImpl = useRouter,
150
+ router,
95
151
  }: DevtoolsOptions): React.ReactElement | null {
96
152
  const rootRef = React.useRef<HTMLDivElement>(null)
97
153
  const panelRef = React.useRef<HTMLDivElement>(null)
@@ -230,7 +286,7 @@ export function TanStackRouterDevtools({
230
286
  <TanStackRouterDevtoolsPanel
231
287
  ref={panelRef as any}
232
288
  {...otherPanelProps}
233
- useRouter={useRouterImpl}
289
+ router={router}
234
290
  style={{
235
291
  position: 'fixed',
236
292
  bottom: '0',
@@ -352,6 +408,84 @@ export function TanStackRouterDevtools({
352
408
  )
353
409
  }
354
410
 
411
+ function RouteComp({
412
+ route,
413
+ isRoot,
414
+ matches,
415
+ activeRouteId,
416
+ setActiveRouteId,
417
+ }: {
418
+ route: AnyRootRoute | AnyRoute
419
+ isRoot?: boolean
420
+ matches: RouteMatch[]
421
+ activeRouteId: string | undefined
422
+ setActiveRouteId: (id: string) => void
423
+ }) {
424
+ const isActive = matches.find((d) => d.route === route)
425
+ return (
426
+ <div>
427
+ <div
428
+ role="button"
429
+ aria-label={`Open match details for ${route.id}`}
430
+ onClick={() =>
431
+ setActiveRouteId(activeRouteId === route.id ? '' : route.id)
432
+ }
433
+ style={{
434
+ display: 'flex',
435
+ borderBottom: `solid 1px ${theme.grayAlt}`,
436
+ cursor: 'pointer',
437
+ alignItems: 'center',
438
+ background:
439
+ route.id === activeRouteId ? 'rgba(255,255,255,.1)' : undefined,
440
+ }}
441
+ >
442
+ {isRoot ? null : (
443
+ <div
444
+ style={{
445
+ flex: '0 0 auto',
446
+ width: '.7rem',
447
+ height: '.7rem',
448
+ margin: '.5rem .75rem',
449
+ alignItems: 'center',
450
+ justifyContent: 'center',
451
+ fontWeight: 'bold',
452
+ borderRadius: '100%',
453
+ transition: 'all .2s ease-out',
454
+ background: getRouteStatusColor(matches, route, theme),
455
+ opacity: isActive ? 1 : 0.3,
456
+ }}
457
+ />
458
+ )}
459
+ <Code
460
+ style={{
461
+ padding: '.25rem 0',
462
+ paddingLeft: isRoot ? '.5rem' : 0,
463
+ opacity: isActive ? 1 : 0.7,
464
+ }}
465
+ >{`${route.id}`}</Code>
466
+ </div>
467
+ {(route.children as Route[])?.length ? (
468
+ <div
469
+ style={{
470
+ marginLeft: isRoot ? 0 : '1rem',
471
+ borderLeft: isRoot ? '' : `solid 1px ${theme.grayAlt}`,
472
+ }}
473
+ >
474
+ {(route.children as Route[]).map((r) => (
475
+ <RouteComp
476
+ key={r.id}
477
+ route={r}
478
+ matches={matches}
479
+ activeRouteId={activeRouteId}
480
+ setActiveRouteId={setActiveRouteId}
481
+ />
482
+ ))}
483
+ </div>
484
+ ) : null}
485
+ </div>
486
+ )
487
+ }
488
+
355
489
  export const TanStackRouterDevtoolsPanel = React.forwardRef<
356
490
  HTMLDivElement,
357
491
  DevtoolsPanelOptions
@@ -360,32 +494,44 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
360
494
  isOpen = true,
361
495
  setIsOpen,
362
496
  handleDragStart,
363
- useRouter,
497
+ router: userRouter,
364
498
  ...panelProps
365
499
  } = props
366
500
 
367
- const router = useRouter() as Router
501
+ const routerContextValue = React.useContext(routerContext)
502
+ const router = userRouter ?? routerContextValue?.router
368
503
 
369
- React.useEffect(() => {
370
- let interval = setInterval(() => {
371
- router.cleanPreloadCache()
372
- router.notify()
373
- }, 1000)
504
+ invariant(
505
+ router,
506
+ '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.',
507
+ )
374
508
 
375
- return () => {
376
- clearInterval(interval)
377
- }
378
- }, [])
509
+ useStore(router.__store)
510
+
511
+ const [showMatches, setShowMatches] = useLocalStorage(
512
+ 'tanstackRouterDevtoolsShowMatches',
513
+ true,
514
+ )
379
515
 
380
516
  const [activeRouteId, setActiveRouteId] = useLocalStorage(
381
517
  'tanstackRouterDevtoolsActiveRouteId',
382
518
  '',
383
519
  )
384
520
 
385
- const activeMatch = router.state.matches?.find(
386
- (d) => d.routeId === activeRouteId,
521
+ const allMatches: RouteMatch[] = React.useMemo(
522
+ () => [
523
+ ...Object.values(router.state.currentMatches),
524
+ ...Object.values(router.state.pendingMatches ?? []),
525
+ ],
526
+ [router.state.currentMatches, router.state.pendingMatches],
387
527
  )
388
528
 
529
+ const activeMatch = allMatches?.find((d) => d.route.id === activeRouteId)
530
+
531
+ const hasSearch = Object.keys(
532
+ last(router.state.currentMatches)?.state.search || {},
533
+ ).length
534
+
389
535
  return (
390
536
  <ThemeProvider theme={theme}>
391
537
  <Panel ref={ref} className="TanStackRouterDevtoolsPanel" {...panelProps}>
@@ -462,27 +608,21 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
462
608
  >
463
609
  <div
464
610
  style={{
465
- padding: '.5em',
466
- background: theme.backgroundAlt,
467
611
  display: 'flex',
468
- justifyContent: 'space-between',
612
+ justifyContent: 'start',
613
+ gap: '1rem',
614
+ padding: '1rem',
469
615
  alignItems: 'center',
616
+ background: theme.backgroundAlt,
470
617
  }}
471
618
  >
472
- <Logo
473
- aria-hidden
474
- style={{
475
- marginRight: '.5em',
476
- }}
477
- />
619
+ <Logo aria-hidden />
478
620
  <div
479
621
  style={{
480
- marginRight: 'auto',
481
622
  fontSize: 'clamp(.8rem, 2vw, 1.3rem)',
482
623
  fontWeight: 'bold',
483
624
  }}
484
625
  >
485
- TanStack Router{' '}
486
626
  <span
487
627
  style={{
488
628
  fontWeight: 100,
@@ -503,34 +643,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
503
643
  padding: '.5em',
504
644
  }}
505
645
  >
506
- <Explorer
507
- label="Router"
508
- value={(() => {
509
- const {
510
- listeners,
511
- buildLocation,
512
- mount,
513
- update,
514
- buildNext,
515
- navigate,
516
- cancelMatches,
517
- loadLocation,
518
- cleanPreloadCache,
519
- loadRoute,
520
- matchRoutes,
521
- loadMatches,
522
- invalidateRoute,
523
- resolvePath,
524
- matchRoute,
525
- buildLink,
526
- __experimental__createSnapshot,
527
- destroy,
528
- ...rest
529
- } = router
530
- return rest
531
- })()}
532
- defaultExpanded={{}}
533
- />
646
+ <Explorer label="Router" value={router} defaultExpanded={{}} />
534
647
  </div>
535
648
  </div>
536
649
  </div>
@@ -552,204 +665,161 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
552
665
  position: 'sticky',
553
666
  top: 0,
554
667
  zIndex: 1,
668
+ display: 'flex',
669
+ alignItems: 'center',
670
+ gap: '.5rem',
555
671
  }}
556
672
  >
557
- Current Matches
558
- </div>
559
- {router.state.matches.map((match, i) => {
560
- return (
561
- <div
562
- key={match.routeId || i}
563
- role="button"
564
- aria-label={`Open match details for ${match.routeId}`}
565
- onClick={() =>
566
- setActiveRouteId(
567
- activeRouteId === match.routeId ? '' : match.routeId,
568
- )
569
- }
570
- style={{
571
- display: 'flex',
572
- borderBottom: `solid 1px ${theme.grayAlt}`,
573
- cursor: 'pointer',
574
- alignItems: 'center',
575
- background:
576
- match === activeMatch ? 'rgba(255,255,255,.1)' : undefined,
577
- }}
578
- >
579
- <div
580
- style={{
581
- flex: '0 0 auto',
582
- width: '1.3rem',
583
- height: '1.3rem',
584
- marginLeft: '.25rem',
585
- background: getStatusColor(match, theme),
586
- alignItems: 'center',
587
- justifyContent: 'center',
588
- fontWeight: 'bold',
589
- borderRadius: '.25rem',
590
- transition: 'all .2s ease-out',
591
- }}
592
- />
593
-
594
- <Code
595
- style={{
596
- padding: '.5em',
597
- }}
598
- >
599
- {`${match.matchId}`}
600
- </Code>
601
- </div>
602
- )
603
- })}
604
- <div
605
- style={{
606
- marginTop: '2rem',
607
- padding: '.5em',
608
- background: theme.backgroundAlt,
609
- position: 'sticky',
610
- top: 0,
611
- zIndex: 1,
612
- }}
613
- >
614
- Pending Matches
615
- </div>
616
- {router.state.pending?.matches.map((match, i) => {
617
- return (
618
- <div
619
- key={match.routeId || i}
620
- role="button"
621
- aria-label={`Open match details for ${match.routeId}`}
622
- onClick={() =>
623
- setActiveRouteId(
624
- activeRouteId === match.routeId ? '' : match.routeId,
625
- )
626
- }
627
- style={{
628
- display: 'flex',
629
- borderBottom: `solid 1px ${theme.grayAlt}`,
630
- cursor: 'pointer',
631
- background:
632
- match === activeMatch ? 'rgba(255,255,255,.1)' : undefined,
633
- }}
634
- >
635
- <div
636
- style={{
637
- flex: '0 0 auto',
638
- width: '1.3rem',
639
- height: '1.3rem',
640
- marginLeft: '.25rem',
641
- background: getStatusColor(match, theme),
642
- alignItems: 'center',
643
- justifyContent: 'center',
644
- fontWeight: 'bold',
645
- borderRadius: '.25rem',
646
- transition: 'all .2s ease-out',
647
- }}
648
- />
649
-
650
- <Code
651
- style={{
652
- padding: '.5em',
653
- }}
654
- >
655
- {`${match.matchId}`}
656
- </Code>
657
- </div>
658
- )
659
- })}
660
- <div
661
- style={{
662
- marginTop: '2rem',
663
- padding: '.5em',
664
- background: theme.backgroundAlt,
665
- position: 'sticky',
666
- top: 0,
667
- zIndex: 1,
668
- }}
669
- >
670
- Preloading Matches
673
+ <button
674
+ type="button"
675
+ onClick={() => {
676
+ setShowMatches(false)
677
+ }}
678
+ disabled={!showMatches}
679
+ style={{
680
+ opacity: showMatches ? 0.5 : 1,
681
+ }}
682
+ >
683
+ Routes
684
+ </button>
685
+ /
686
+ <button
687
+ type="button"
688
+ onClick={() => {
689
+ setShowMatches(true)
690
+ }}
691
+ disabled={showMatches}
692
+ style={{
693
+ opacity: !showMatches ? 0.5 : 1,
694
+ }}
695
+ >
696
+ Matches
697
+ </button>
671
698
  </div>
672
- {Object.keys(router.preloadCache)
673
- .filter((key) => {
674
- const cacheEntry = router.preloadCache[key]!
675
- return (
676
- (cacheEntry.match.updatedAt ?? Date.now()) + cacheEntry.maxAge >
677
- Date.now()
678
- )
679
- })
680
- .map((key, i) => {
681
- const { match, maxAge } = router.preloadCache[key]!
682
-
683
- return (
684
- <div
685
- key={match.matchId || i}
686
- role="button"
687
- aria-label={`Open match details for ${match.matchId}`}
688
- onClick={() =>
689
- setActiveRouteId(
690
- activeRouteId === match.routeId ? '' : match.routeId,
691
- )
692
- }
693
- style={{
694
- display: 'flex',
695
- borderBottom: `solid 1px ${theme.grayAlt}`,
696
- cursor: 'pointer',
697
- background:
698
- match === activeMatch
699
- ? 'rgba(255,255,255,.1)'
700
- : undefined,
701
- }}
702
- >
699
+ {!showMatches ? (
700
+ <RouteComp
701
+ route={router.routeTree}
702
+ isRoot
703
+ matches={allMatches}
704
+ activeRouteId={activeRouteId}
705
+ setActiveRouteId={setActiveRouteId}
706
+ />
707
+ ) : (
708
+ <div>
709
+ {router.state.currentMatches.map((match, i) => {
710
+ return (
703
711
  <div
712
+ key={match.route.id || i}
713
+ role="button"
714
+ aria-label={`Open match details for ${match.route.id}`}
715
+ onClick={() =>
716
+ setActiveRouteId(
717
+ activeRouteId === match.route.id ? '' : match.route.id,
718
+ )
719
+ }
704
720
  style={{
705
721
  display: 'flex',
706
- flexDirection: 'column',
707
- padding: '.5rem',
708
- gap: '.3rem',
722
+ borderBottom: `solid 1px ${theme.grayAlt}`,
723
+ cursor: 'pointer',
724
+ alignItems: 'center',
725
+ background:
726
+ match === activeMatch
727
+ ? 'rgba(255,255,255,.1)'
728
+ : undefined,
709
729
  }}
710
730
  >
711
731
  <div
712
732
  style={{
713
- display: 'flex',
733
+ flex: '0 0 auto',
734
+ width: '1.3rem',
735
+ height: '1.3rem',
736
+ marginLeft: '.25rem',
737
+ background: getStatusColor(match, theme),
714
738
  alignItems: 'center',
715
- gap: '.5rem',
739
+ justifyContent: 'center',
740
+ fontWeight: 'bold',
741
+ borderRadius: '.25rem',
742
+ transition: 'all .2s ease-out',
716
743
  }}
717
- >
718
- <div
719
- style={{
720
- flex: '0 0 auto',
721
- width: '1.3rem',
722
- height: '1.3rem',
723
- background: getStatusColor(match, theme),
724
- alignItems: 'center',
725
- justifyContent: 'center',
726
- fontWeight: 'bold',
727
- borderRadius: '.25rem',
728
- transition: 'all .2s ease-out',
729
- }}
730
- />
731
- <Code>{`${match.matchId}`}</Code>
732
- </div>
733
- <span
744
+ />
745
+
746
+ <Code
734
747
  style={{
735
- opacity: '.5',
748
+ padding: '.5em',
736
749
  }}
737
750
  >
738
- Expires{' '}
739
- {formatDistanceStrict(
740
- new Date(),
741
- new Date((match.updatedAt ?? Date.now()) + maxAge),
742
- {
743
- addSuffix: true,
744
- },
745
- )}
746
- </span>
751
+ {`${match.id}`}
752
+ </Code>
747
753
  </div>
748
- </div>
749
- )
750
- })}
754
+ )
755
+ })}
756
+ {router.state.pendingMatches?.length ? (
757
+ <>
758
+ <div
759
+ style={{
760
+ marginTop: '2rem',
761
+ padding: '.5em',
762
+ background: theme.backgroundAlt,
763
+ position: 'sticky',
764
+ top: 0,
765
+ zIndex: 1,
766
+ }}
767
+ >
768
+ Pending Matches
769
+ </div>
770
+ {router.state.pendingMatches?.map((match, i) => {
771
+ return (
772
+ <div
773
+ key={match.route.id || i}
774
+ role="button"
775
+ aria-label={`Open match details for ${match.route.id}`}
776
+ onClick={() =>
777
+ setActiveRouteId(
778
+ activeRouteId === match.route.id
779
+ ? ''
780
+ : match.route.id,
781
+ )
782
+ }
783
+ style={{
784
+ display: 'flex',
785
+ borderBottom: `solid 1px ${theme.grayAlt}`,
786
+ cursor: 'pointer',
787
+ background:
788
+ match === activeMatch
789
+ ? 'rgba(255,255,255,.1)'
790
+ : undefined,
791
+ }}
792
+ >
793
+ <div
794
+ style={{
795
+ flex: '0 0 auto',
796
+ width: '1.3rem',
797
+ height: '1.3rem',
798
+ marginLeft: '.25rem',
799
+ background: getStatusColor(match, theme),
800
+ alignItems: 'center',
801
+ justifyContent: 'center',
802
+ fontWeight: 'bold',
803
+ borderRadius: '.25rem',
804
+ transition: 'all .2s ease-out',
805
+ }}
806
+ />
807
+
808
+ <Code
809
+ style={{
810
+ padding: '.5em',
811
+ }}
812
+ >
813
+ {`${match.id}`}
814
+ </Code>
815
+ </div>
816
+ )
817
+ })}
818
+ </>
819
+ ) : null}
820
+ </div>
821
+ )}
751
822
  </div>
752
-
753
823
  {activeMatch ? (
754
824
  <ActivePanel>
755
825
  <div
@@ -758,6 +828,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
758
828
  background: theme.backgroundAlt,
759
829
  position: 'sticky',
760
830
  top: 0,
831
+ bottom: 0,
761
832
  zIndex: 1,
762
833
  }}
763
834
  >
@@ -774,28 +845,24 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
774
845
  lineHeight: '1.8em',
775
846
  }}
776
847
  >
777
- {JSON.stringify(activeMatch.matchId, null, 2)}
848
+ {JSON.stringify(activeMatch.id, null, 2)}
778
849
  </Code>
779
850
  </td>
780
851
  </tr>
781
852
  <tr>
782
853
  <td style={{ opacity: '.5' }}>Status</td>
783
- <td>{activeMatch.status}</td>
784
- </tr>
785
- <tr>
786
- <td style={{ opacity: '.5' }}>Pending</td>
787
- <td>{activeMatch.isPending.toString()}</td>
854
+ <td>{activeMatch.state.status}</td>
788
855
  </tr>
789
- <tr>
856
+ {/* <tr>
790
857
  <td style={{ opacity: '.5' }}>Invalid</td>
791
- <td>{activeMatch.isInvalid.toString()}</td>
792
- </tr>
858
+ <td>{activeMatch.getIsInvalid().toString()}</td>
859
+ </tr> */}
793
860
  <tr>
794
861
  <td style={{ opacity: '.5' }}>Last Updated</td>
795
862
  <td>
796
- {activeMatch.updatedAt
863
+ {activeMatch.state.updatedAt
797
864
  ? new Date(
798
- activeMatch.updatedAt as number,
865
+ activeMatch.state.updatedAt as number,
799
866
  ).toLocaleTimeString()
800
867
  : 'N/A'}
801
868
  </td>
@@ -803,12 +870,13 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
803
870
  </tbody>
804
871
  </table>
805
872
  </div>
806
- <div
873
+ {/* <div
807
874
  style={{
808
875
  background: theme.backgroundAlt,
809
876
  padding: '.5em',
810
877
  position: 'sticky',
811
878
  top: 0,
879
+ bottom: 0,
812
880
  zIndex: 1,
813
881
  }}
814
882
  >
@@ -821,33 +889,21 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
821
889
  >
822
890
  <Button
823
891
  type="button"
824
- onClick={() => {
825
- router.invalidateRoute(activeMatch as any)
826
- router.notify()
827
- }}
828
- style={{
829
- background: theme.warning,
830
- color: theme.inputTextColor,
831
- }}
832
- >
833
- Invalidate
834
- </Button>{' '}
835
- <Button
836
- type="button"
837
- onClick={() => router.reload()}
892
+ onClick={() => activeMatch.__store.setState(d => ({...d, status: 'pending'}))}
838
893
  style={{
839
894
  background: theme.gray,
840
895
  }}
841
896
  >
842
897
  Reload
843
898
  </Button>
844
- </div>
899
+ </div> */}
845
900
  <div
846
901
  style={{
847
902
  background: theme.backgroundAlt,
848
903
  padding: '.5em',
849
904
  position: 'sticky',
850
905
  top: 0,
906
+ bottom: 0,
851
907
  zIndex: 1,
852
908
  }}
853
909
  >
@@ -860,100 +916,53 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
860
916
  >
861
917
  <Explorer
862
918
  label="Match"
863
- value={(() => {
864
- const {
865
- cancel,
866
- load,
867
- router,
868
- Link,
869
- MatchRoute,
870
- buildLink,
871
- linkProps,
872
- matchRoute,
873
- navigate,
874
- ...rest
875
- } = activeMatch
876
-
877
- return rest
878
- })()}
919
+ value={activeMatch}
879
920
  defaultExpanded={{}}
880
921
  />
881
922
  </div>
882
923
  </ActivePanel>
883
924
  ) : null}
884
- <div
885
- style={{
886
- flex: '1 1 500px',
887
- minHeight: '40%',
888
- maxHeight: '100%',
889
- overflow: 'auto',
890
- borderRight: `1px solid ${theme.grayAlt}`,
891
- display: 'flex',
892
- flexDirection: 'column',
893
- }}
894
- >
895
- <div
896
- style={{
897
- padding: '.5em',
898
- background: theme.backgroundAlt,
899
- position: 'sticky',
900
- top: 0,
901
- zIndex: 1,
902
- }}
903
- >
904
- Loader Data
905
- </div>
925
+ {hasSearch ? (
906
926
  <div
907
927
  style={{
908
- padding: '.5em',
909
- }}
910
- >
911
- {Object.keys(last(router.state.matches)?.loaderData || {})
912
- .length ? (
913
- <Explorer
914
- value={last(router.state.matches)?.loaderData || {}}
915
- defaultExpanded={Object.keys(
916
- (last(router.state.matches)?.loaderData as {}) || {},
917
- ).reduce((obj: any, next) => {
918
- obj[next] = {}
919
- return obj
920
- }, {})}
921
- />
922
- ) : (
923
- <em style={{ opacity: 0.5 }}>{'{ }'}</em>
924
- )}
925
- </div>
926
- <div
927
- style={{
928
- padding: '.5em',
929
- background: theme.backgroundAlt,
930
- position: 'sticky',
931
- top: 0,
932
- zIndex: 1,
933
- }}
934
- >
935
- Search Params
936
- </div>
937
- <div
938
- style={{
939
- padding: '.5em',
928
+ flex: '1 1 500px',
929
+ minHeight: '40%',
930
+ maxHeight: '100%',
931
+ overflow: 'auto',
932
+ borderRight: `1px solid ${theme.grayAlt}`,
933
+ display: 'flex',
934
+ flexDirection: 'column',
940
935
  }}
941
936
  >
942
- {Object.keys(last(router.state.matches)?.search || {}).length ? (
937
+ <div
938
+ style={{
939
+ padding: '.5em',
940
+ background: theme.backgroundAlt,
941
+ position: 'sticky',
942
+ top: 0,
943
+ bottom: 0,
944
+ zIndex: 1,
945
+ }}
946
+ >
947
+ Search Params
948
+ </div>
949
+ <div
950
+ style={{
951
+ padding: '.5em',
952
+ }}
953
+ >
943
954
  <Explorer
944
- value={last(router.state.matches)?.search || {}}
955
+ value={last(router.state.currentMatches)?.state.search || {}}
945
956
  defaultExpanded={Object.keys(
946
- (last(router.state.matches)?.search as {}) || {},
957
+ (last(router.state.currentMatches)?.state.search as {}) || {},
947
958
  ).reduce((obj: any, next) => {
948
959
  obj[next] = {}
949
960
  return obj
950
961
  }, {})}
951
962
  />
952
- ) : (
953
- <em style={{ opacity: 0.5 }}>{'{ }'}</em>
954
- )}
963
+ </div>
955
964
  </div>
956
- </div>
965
+ ) : null}
957
966
  </Panel>
958
967
  </ThemeProvider>
959
968
  )