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

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 +638 -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 +391 -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 +430 -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 +349 -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,74 @@ export function TanStackRouterDevtools({
352
408
  )
353
409
  }
354
410
 
411
+ function RouteComp({
412
+ route,
413
+ isRoot,
414
+ matches,
415
+ }: {
416
+ route: AnyRootRoute | AnyRoute
417
+ isRoot?: boolean
418
+ matches: RouteMatch[]
419
+ }) {
420
+ const isActive = matches.find((d) => d.route === route)
421
+ return (
422
+ <div>
423
+ <div
424
+ // role="button"
425
+ // aria-label={`Open match details for ${route.id}`}
426
+ // onClick={() =>
427
+ // setActiveRouteId(activeRouteId === route.id ? '' : route.id)
428
+ // }
429
+ style={{
430
+ display: 'flex',
431
+ borderBottom: `solid 1px ${theme.grayAlt}`,
432
+ cursor: 'pointer',
433
+ alignItems: 'center',
434
+ // background:
435
+ // route === activeMatch ? 'rgba(255,255,255,.1)' : undefined,
436
+ }}
437
+ >
438
+ {isRoot ? null : (
439
+ <div
440
+ style={{
441
+ flex: '0 0 auto',
442
+ width: '.7rem',
443
+ height: '.7rem',
444
+ margin: '.5rem .75rem',
445
+ alignItems: 'center',
446
+ justifyContent: 'center',
447
+ fontWeight: 'bold',
448
+ borderRadius: '100%',
449
+ transition: 'all .2s ease-out',
450
+ background: getRouteStatusColor(matches, route, theme),
451
+ opacity: isActive ? 1 : 0.3,
452
+ }}
453
+ />
454
+ )}
455
+ <Code
456
+ style={{
457
+ padding: '.25rem 0',
458
+ paddingLeft: isRoot ? '.5rem' : 0,
459
+ opacity: isActive ? 1 : 0.7,
460
+ }}
461
+ >{`${route.id}`}</Code>
462
+ </div>
463
+ {(route.children as Route[])?.length ? (
464
+ <div
465
+ style={{
466
+ marginLeft: isRoot ? 0 : '1rem',
467
+ borderLeft: isRoot ? '' : `solid 1px ${theme.grayAlt}`,
468
+ }}
469
+ >
470
+ {(route.children as Route[]).map((r) => (
471
+ <RouteComp key={r.id} route={r} matches={matches} />
472
+ ))}
473
+ </div>
474
+ ) : null}
475
+ </div>
476
+ )
477
+ }
478
+
355
479
  export const TanStackRouterDevtoolsPanel = React.forwardRef<
356
480
  HTMLDivElement,
357
481
  DevtoolsPanelOptions
@@ -360,32 +484,55 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
360
484
  isOpen = true,
361
485
  setIsOpen,
362
486
  handleDragStart,
363
- useRouter,
487
+ router: userRouter,
364
488
  ...panelProps
365
489
  } = props
366
490
 
367
- const router = useRouter() as Router
491
+ const routerContextValue = React.useContext(routerContext)
492
+ const router = userRouter ?? routerContextValue?.router
368
493
 
369
- React.useEffect(() => {
370
- let interval = setInterval(() => {
371
- router.cleanPreloadCache()
372
- router.notify()
373
- }, 1000)
494
+ invariant(
495
+ router,
496
+ '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.',
497
+ )
374
498
 
375
- return () => {
376
- clearInterval(interval)
377
- }
378
- }, [])
499
+ useStore(router.__store)
500
+
501
+ const [showMatches, setShowMatches] = useLocalStorage(
502
+ 'tanstackRouterDevtoolsShowMatches',
503
+ true,
504
+ )
379
505
 
380
506
  const [activeRouteId, setActiveRouteId] = useLocalStorage(
381
507
  'tanstackRouterDevtoolsActiveRouteId',
382
508
  '',
383
509
  )
384
510
 
385
- const activeMatch = router.state.matches?.find(
386
- (d) => d.routeId === activeRouteId,
511
+ const [activeMatchId, setActiveMatchId] = useLocalStorage(
512
+ 'tanstackRouterDevtoolsActiveMatchId',
513
+ '',
387
514
  )
388
515
 
516
+ React.useEffect(() => {
517
+ setActiveMatchId('')
518
+ }, [activeRouteId])
519
+
520
+ const allMatches: RouteMatch[] = React.useMemo(
521
+ () => [
522
+ ...Object.values(router.state.currentMatches),
523
+ ...Object.values(router.state.pendingMatches ?? []),
524
+ ],
525
+ [router.state.currentMatches, router.state.pendingMatches],
526
+ )
527
+
528
+ const activeMatch =
529
+ allMatches?.find((d) => d.id === activeMatchId) ||
530
+ allMatches?.find((d) => d.route.id === activeRouteId)
531
+
532
+ const hasSearch = Object.keys(
533
+ last(router.state.currentMatches)?.state.search || {},
534
+ ).length
535
+
389
536
  return (
390
537
  <ThemeProvider theme={theme}>
391
538
  <Panel ref={ref} className="TanStackRouterDevtoolsPanel" {...panelProps}>
@@ -462,27 +609,21 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
462
609
  >
463
610
  <div
464
611
  style={{
465
- padding: '.5em',
466
- background: theme.backgroundAlt,
467
612
  display: 'flex',
468
- justifyContent: 'space-between',
613
+ justifyContent: 'start',
614
+ gap: '1rem',
615
+ padding: '1rem',
469
616
  alignItems: 'center',
617
+ background: theme.backgroundAlt,
470
618
  }}
471
619
  >
472
- <Logo
473
- aria-hidden
474
- style={{
475
- marginRight: '.5em',
476
- }}
477
- />
620
+ <Logo aria-hidden />
478
621
  <div
479
622
  style={{
480
- marginRight: 'auto',
481
623
  fontSize: 'clamp(.8rem, 2vw, 1.3rem)',
482
624
  fontWeight: 'bold',
483
625
  }}
484
626
  >
485
- TanStack Router{' '}
486
627
  <span
487
628
  style={{
488
629
  fontWeight: 100,
@@ -503,34 +644,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
503
644
  padding: '.5em',
504
645
  }}
505
646
  >
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
- />
647
+ <Explorer label="Router" value={router} defaultExpanded={{}} />
534
648
  </div>
535
649
  </div>
536
650
  </div>
@@ -552,204 +666,155 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
552
666
  position: 'sticky',
553
667
  top: 0,
554
668
  zIndex: 1,
669
+ display: 'flex',
670
+ alignItems: 'center',
671
+ gap: '.5rem',
555
672
  }}
556
673
  >
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
674
+ <button
675
+ type="button"
676
+ onClick={() => {
677
+ setShowMatches(false)
678
+ }}
679
+ disabled={!showMatches}
680
+ style={{
681
+ opacity: showMatches ? 0.5 : 1,
682
+ }}
683
+ >
684
+ Routes
685
+ </button>
686
+ /
687
+ <button
688
+ type="button"
689
+ onClick={() => {
690
+ setShowMatches(true)
691
+ }}
692
+ disabled={showMatches}
693
+ style={{
694
+ opacity: !showMatches ? 0.5 : 1,
695
+ }}
696
+ >
697
+ Matches
698
+ </button>
671
699
  </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
- >
700
+ {!showMatches ? (
701
+ <RouteComp route={router.routeTree} isRoot matches={allMatches} />
702
+ ) : (
703
+ <div>
704
+ {router.state.currentMatches.map((match, i) => {
705
+ return (
703
706
  <div
707
+ key={match.route.id || i}
708
+ role="button"
709
+ aria-label={`Open match details for ${match.route.id}`}
710
+ onClick={() =>
711
+ setActiveRouteId(
712
+ activeRouteId === match.route.id ? '' : match.route.id,
713
+ )
714
+ }
704
715
  style={{
705
716
  display: 'flex',
706
- flexDirection: 'column',
707
- padding: '.5rem',
708
- gap: '.3rem',
717
+ borderBottom: `solid 1px ${theme.grayAlt}`,
718
+ cursor: 'pointer',
719
+ alignItems: 'center',
720
+ background:
721
+ match === activeMatch
722
+ ? 'rgba(255,255,255,.1)'
723
+ : undefined,
709
724
  }}
710
725
  >
711
726
  <div
712
727
  style={{
713
- display: 'flex',
728
+ flex: '0 0 auto',
729
+ width: '1.3rem',
730
+ height: '1.3rem',
731
+ marginLeft: '.25rem',
732
+ background: getStatusColor(match, theme),
714
733
  alignItems: 'center',
715
- gap: '.5rem',
734
+ justifyContent: 'center',
735
+ fontWeight: 'bold',
736
+ borderRadius: '.25rem',
737
+ transition: 'all .2s ease-out',
716
738
  }}
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
739
+ />
740
+
741
+ <Code
734
742
  style={{
735
- opacity: '.5',
743
+ padding: '.5em',
736
744
  }}
737
745
  >
738
- Expires{' '}
739
- {formatDistanceStrict(
740
- new Date(),
741
- new Date((match.updatedAt ?? Date.now()) + maxAge),
742
- {
743
- addSuffix: true,
744
- },
745
- )}
746
- </span>
746
+ {`${match.id}`}
747
+ </Code>
747
748
  </div>
748
- </div>
749
- )
750
- })}
749
+ )
750
+ })}
751
+ {router.state.pendingMatches?.length ? (
752
+ <>
753
+ <div
754
+ style={{
755
+ marginTop: '2rem',
756
+ padding: '.5em',
757
+ background: theme.backgroundAlt,
758
+ position: 'sticky',
759
+ top: 0,
760
+ zIndex: 1,
761
+ }}
762
+ >
763
+ Pending Matches
764
+ </div>
765
+ {router.state.pendingMatches?.map((match, i) => {
766
+ return (
767
+ <div
768
+ key={match.route.id || i}
769
+ role="button"
770
+ aria-label={`Open match details for ${match.route.id}`}
771
+ onClick={() =>
772
+ setActiveRouteId(
773
+ activeRouteId === match.route.id
774
+ ? ''
775
+ : match.route.id,
776
+ )
777
+ }
778
+ style={{
779
+ display: 'flex',
780
+ borderBottom: `solid 1px ${theme.grayAlt}`,
781
+ cursor: 'pointer',
782
+ background:
783
+ match === activeMatch
784
+ ? 'rgba(255,255,255,.1)'
785
+ : undefined,
786
+ }}
787
+ >
788
+ <div
789
+ style={{
790
+ flex: '0 0 auto',
791
+ width: '1.3rem',
792
+ height: '1.3rem',
793
+ marginLeft: '.25rem',
794
+ background: getStatusColor(match, theme),
795
+ alignItems: 'center',
796
+ justifyContent: 'center',
797
+ fontWeight: 'bold',
798
+ borderRadius: '.25rem',
799
+ transition: 'all .2s ease-out',
800
+ }}
801
+ />
802
+
803
+ <Code
804
+ style={{
805
+ padding: '.5em',
806
+ }}
807
+ >
808
+ {`${match.id}`}
809
+ </Code>
810
+ </div>
811
+ )
812
+ })}
813
+ </>
814
+ ) : null}
815
+ </div>
816
+ )}
751
817
  </div>
752
-
753
818
  {activeMatch ? (
754
819
  <ActivePanel>
755
820
  <div
@@ -758,6 +823,7 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
758
823
  background: theme.backgroundAlt,
759
824
  position: 'sticky',
760
825
  top: 0,
826
+ bottom: 0,
761
827
  zIndex: 1,
762
828
  }}
763
829
  >
@@ -774,28 +840,24 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
774
840
  lineHeight: '1.8em',
775
841
  }}
776
842
  >
777
- {JSON.stringify(activeMatch.matchId, null, 2)}
843
+ {JSON.stringify(activeMatch.id, null, 2)}
778
844
  </Code>
779
845
  </td>
780
846
  </tr>
781
847
  <tr>
782
848
  <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>
849
+ <td>{activeMatch.state.status}</td>
788
850
  </tr>
789
- <tr>
851
+ {/* <tr>
790
852
  <td style={{ opacity: '.5' }}>Invalid</td>
791
- <td>{activeMatch.isInvalid.toString()}</td>
792
- </tr>
853
+ <td>{activeMatch.getIsInvalid().toString()}</td>
854
+ </tr> */}
793
855
  <tr>
794
856
  <td style={{ opacity: '.5' }}>Last Updated</td>
795
857
  <td>
796
- {activeMatch.updatedAt
858
+ {activeMatch.state.updatedAt
797
859
  ? new Date(
798
- activeMatch.updatedAt as number,
860
+ activeMatch.state.updatedAt as number,
799
861
  ).toLocaleTimeString()
800
862
  : 'N/A'}
801
863
  </td>
@@ -803,12 +865,13 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
803
865
  </tbody>
804
866
  </table>
805
867
  </div>
806
- <div
868
+ {/* <div
807
869
  style={{
808
870
  background: theme.backgroundAlt,
809
871
  padding: '.5em',
810
872
  position: 'sticky',
811
873
  top: 0,
874
+ bottom: 0,
812
875
  zIndex: 1,
813
876
  }}
814
877
  >
@@ -821,33 +884,21 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
821
884
  >
822
885
  <Button
823
886
  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()}
887
+ onClick={() => activeMatch.__store.setState(d => ({...d, status: 'pending'}))}
838
888
  style={{
839
889
  background: theme.gray,
840
890
  }}
841
891
  >
842
892
  Reload
843
893
  </Button>
844
- </div>
894
+ </div> */}
845
895
  <div
846
896
  style={{
847
897
  background: theme.backgroundAlt,
848
898
  padding: '.5em',
849
899
  position: 'sticky',
850
900
  top: 0,
901
+ bottom: 0,
851
902
  zIndex: 1,
852
903
  }}
853
904
  >
@@ -860,100 +911,53 @@ export const TanStackRouterDevtoolsPanel = React.forwardRef<
860
911
  >
861
912
  <Explorer
862
913
  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
- })()}
914
+ value={activeMatch}
879
915
  defaultExpanded={{}}
880
916
  />
881
917
  </div>
882
918
  </ActivePanel>
883
919
  ) : 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>
920
+ {hasSearch ? (
906
921
  <div
907
922
  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',
923
+ flex: '1 1 500px',
924
+ minHeight: '40%',
925
+ maxHeight: '100%',
926
+ overflow: 'auto',
927
+ borderRight: `1px solid ${theme.grayAlt}`,
928
+ display: 'flex',
929
+ flexDirection: 'column',
940
930
  }}
941
931
  >
942
- {Object.keys(last(router.state.matches)?.search || {}).length ? (
932
+ <div
933
+ style={{
934
+ padding: '.5em',
935
+ background: theme.backgroundAlt,
936
+ position: 'sticky',
937
+ top: 0,
938
+ bottom: 0,
939
+ zIndex: 1,
940
+ }}
941
+ >
942
+ Search Params
943
+ </div>
944
+ <div
945
+ style={{
946
+ padding: '.5em',
947
+ }}
948
+ >
943
949
  <Explorer
944
- value={last(router.state.matches)?.search || {}}
950
+ value={last(router.state.currentMatches)?.state.search || {}}
945
951
  defaultExpanded={Object.keys(
946
- (last(router.state.matches)?.search as {}) || {},
952
+ (last(router.state.currentMatches)?.state.search as {}) || {},
947
953
  ).reduce((obj: any, next) => {
948
954
  obj[next] = {}
949
955
  return obj
950
956
  }, {})}
951
957
  />
952
- ) : (
953
- <em style={{ opacity: 0.5 }}>{'{ }'}</em>
954
- )}
958
+ </div>
955
959
  </div>
956
- </div>
960
+ ) : null}
957
961
  </Panel>
958
962
  </ThemeProvider>
959
963
  )