@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
package/src/devtools.tsx DELETED
@@ -1,984 +0,0 @@
1
- import React from 'react'
2
- import {
3
- last,
4
- routerContext,
5
- invariant,
6
- useRouter,
7
- AnyRouter,
8
- useStore,
9
- } from '@tanstack/react-router'
10
-
11
- import useLocalStorage from './useLocalStorage'
12
- import {
13
- getStatusColor,
14
- multiSortBy,
15
- useIsMounted,
16
- useSafeState,
17
- } from './utils'
18
- import { Panel, Button, Code, ActivePanel } from './styledComponents'
19
- import { ThemeProvider, defaultTheme as theme } from './theme'
20
- // import { getQueryStatusLabel, getQueryStatusColor } from './utils'
21
- import Explorer from './Explorer'
22
-
23
- export type PartialKeys<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
24
-
25
- interface DevtoolsOptions {
26
- /**
27
- * Set this true if you want the dev tools to default to being open
28
- */
29
- initialIsOpen?: boolean
30
- /**
31
- * Use this to add props to the panel. For example, you can add className, style (merge and override default style), etc.
32
- */
33
- panelProps?: React.DetailedHTMLProps<
34
- React.HTMLAttributes<HTMLDivElement>,
35
- HTMLDivElement
36
- >
37
- /**
38
- * Use this to add props to the close button. For example, you can add className, style (merge and override default style), onClick (extend default handler), etc.
39
- */
40
- closeButtonProps?: React.DetailedHTMLProps<
41
- React.ButtonHTMLAttributes<HTMLButtonElement>,
42
- HTMLButtonElement
43
- >
44
- /**
45
- * Use this to add props to the toggle button. For example, you can add className, style (merge and override default style), onClick (extend default handler), etc.
46
- */
47
- toggleButtonProps?: React.DetailedHTMLProps<
48
- React.ButtonHTMLAttributes<HTMLButtonElement>,
49
- HTMLButtonElement
50
- >
51
- /**
52
- * The position of the TanStack Router logo to open and close the devtools panel.
53
- * Defaults to 'bottom-left'.
54
- */
55
- position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
56
- /**
57
- * Use this to render the devtools inside a different type of container element for a11y purposes.
58
- * Any string which corresponds to a valid intrinsic JSX element is allowed.
59
- * Defaults to 'footer'.
60
- */
61
- containerElement?: string | any
62
- /**
63
- * A boolean variable indicating if the "lite" version of the library is being used
64
- */
65
- router?: AnyRouter
66
- }
67
-
68
- interface DevtoolsPanelOptions {
69
- /**
70
- * The standard React style object used to style a component with inline styles
71
- */
72
- style?: React.CSSProperties
73
- /**
74
- * The standard React className property used to style a component with classes
75
- */
76
- className?: string
77
- /**
78
- * A boolean variable indicating whether the panel is open or closed
79
- */
80
- isOpen?: boolean
81
- /**
82
- * A function that toggles the open and close state of the panel
83
- */
84
- setIsOpen: (isOpen: boolean) => void
85
- /**
86
- * Handles the opening and closing the devtools panel
87
- */
88
- handleDragStart: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
89
- /**
90
- * A boolean variable indicating if the "lite" version of the library is being used
91
- */
92
- router?: AnyRouter
93
- }
94
-
95
- const isServer = typeof window === 'undefined'
96
-
97
- function Logo(props: React.HTMLProps<HTMLDivElement>) {
98
- return (
99
- <div
100
- {...props}
101
- style={{
102
- ...(props.style ?? {}),
103
- display: 'flex',
104
- alignItems: 'center',
105
- flexDirection: 'column',
106
- fontSize: '0.8rem',
107
- fontWeight: 'bolder',
108
- lineHeight: '1',
109
- }}
110
- >
111
- <div
112
- style={{
113
- letterSpacing: '-0.05rem',
114
- }}
115
- >
116
- TANSTACK
117
- </div>
118
- <div
119
- style={{
120
- backgroundImage:
121
- 'linear-gradient(to right, var(--tw-gradient-stops))',
122
- // @ts-ignore
123
- '--tw-gradient-from': '#84cc16',
124
- '--tw-gradient-stops':
125
- 'var(--tw-gradient-from), var(--tw-gradient-to)',
126
- '--tw-gradient-to': '#10b981',
127
- WebkitBackgroundClip: 'text',
128
- color: 'transparent',
129
- letterSpacing: '0.1rem',
130
- marginRight: '-0.2rem',
131
- }}
132
- >
133
- ROUTER
134
- </div>
135
- </div>
136
- )
137
- }
138
-
139
- export function TanStackRouterDevtools({
140
- initialIsOpen,
141
- panelProps = {},
142
- closeButtonProps = {},
143
- toggleButtonProps = {},
144
- position = 'bottom-left',
145
- containerElement: Container = 'footer',
146
- router,
147
- }: DevtoolsOptions): React.ReactElement | null {
148
- const rootRef = React.useRef<HTMLDivElement>(null)
149
- const panelRef = React.useRef<HTMLDivElement>(null)
150
- const [isOpen, setIsOpen] = useLocalStorage(
151
- 'tanstackRouterDevtoolsOpen',
152
- initialIsOpen,
153
- )
154
- const [devtoolsHeight, setDevtoolsHeight] = useLocalStorage<number | null>(
155
- 'tanstackRouterDevtoolsHeight',
156
- null,
157
- )
158
- const [isResolvedOpen, setIsResolvedOpen] = useSafeState(false)
159
- const [isResizing, setIsResizing] = useSafeState(false)
160
- const isMounted = useIsMounted()
161
-
162
- const handleDragStart = (
163
- panelElement: HTMLDivElement | null,
164
- startEvent: React.MouseEvent<HTMLDivElement, MouseEvent>,
165
- ) => {
166
- if (startEvent.button !== 0) return // Only allow left click for drag
167
-
168
- setIsResizing(true)
169
-
170
- const dragInfo = {
171
- originalHeight: panelElement?.getBoundingClientRect().height ?? 0,
172
- pageY: startEvent.pageY,
173
- }
174
-
175
- const run = (moveEvent: MouseEvent) => {
176
- const delta = dragInfo.pageY - moveEvent.pageY
177
- const newHeight = dragInfo?.originalHeight + delta
178
-
179
- setDevtoolsHeight(newHeight)
180
-
181
- if (newHeight < 70) {
182
- setIsOpen(false)
183
- } else {
184
- setIsOpen(true)
185
- }
186
- }
187
-
188
- const unsub = () => {
189
- setIsResizing(false)
190
- document.removeEventListener('mousemove', run)
191
- document.removeEventListener('mouseUp', unsub)
192
- }
193
-
194
- document.addEventListener('mousemove', run)
195
- document.addEventListener('mouseup', unsub)
196
- }
197
-
198
- React.useEffect(() => {
199
- setIsResolvedOpen(isOpen ?? false)
200
- }, [isOpen, isResolvedOpen, setIsResolvedOpen])
201
-
202
- // Toggle panel visibility before/after transition (depending on direction).
203
- // Prevents focusing in a closed panel.
204
- React.useEffect(() => {
205
- const ref = panelRef.current
206
-
207
- if (ref) {
208
- const handlePanelTransitionStart = () => {
209
- if (ref && isResolvedOpen) {
210
- ref.style.visibility = 'visible'
211
- }
212
- }
213
-
214
- const handlePanelTransitionEnd = () => {
215
- if (ref && !isResolvedOpen) {
216
- ref.style.visibility = 'hidden'
217
- }
218
- }
219
-
220
- ref.addEventListener('transitionstart', handlePanelTransitionStart)
221
- ref.addEventListener('transitionend', handlePanelTransitionEnd)
222
-
223
- return () => {
224
- ref.removeEventListener('transitionstart', handlePanelTransitionStart)
225
- ref.removeEventListener('transitionend', handlePanelTransitionEnd)
226
- }
227
- }
228
-
229
- return
230
- }, [isResolvedOpen])
231
-
232
- React[isServer ? 'useEffect' : 'useLayoutEffect'](() => {
233
- if (isResolvedOpen) {
234
- const previousValue = rootRef.current?.parentElement?.style.paddingBottom
235
-
236
- const run = () => {
237
- const containerHeight = panelRef.current?.getBoundingClientRect().height
238
- if (rootRef.current?.parentElement) {
239
- rootRef.current.parentElement.style.paddingBottom = `${containerHeight}px`
240
- }
241
- }
242
-
243
- run()
244
-
245
- if (typeof window !== 'undefined') {
246
- window.addEventListener('resize', run)
247
-
248
- return () => {
249
- window.removeEventListener('resize', run)
250
- if (
251
- rootRef.current?.parentElement &&
252
- typeof previousValue === 'string'
253
- ) {
254
- rootRef.current.parentElement.style.paddingBottom = previousValue
255
- }
256
- }
257
- }
258
- }
259
- return
260
- }, [isResolvedOpen])
261
-
262
- const { style: panelStyle = {}, ...otherPanelProps } = panelProps
263
-
264
- const {
265
- style: closeButtonStyle = {},
266
- onClick: onCloseClick,
267
- ...otherCloseButtonProps
268
- } = closeButtonProps
269
-
270
- const {
271
- style: toggleButtonStyle = {},
272
- onClick: onToggleClick,
273
- ...otherToggleButtonProps
274
- } = toggleButtonProps
275
-
276
- // Do not render on the server
277
- if (!isMounted()) return null
278
-
279
- return (
280
- <Container ref={rootRef} className="TanStackRouterDevtools">
281
- <ThemeProvider theme={theme}>
282
- <TanStackRouterDevtoolsPanel
283
- ref={panelRef as any}
284
- {...otherPanelProps}
285
- router={router}
286
- style={{
287
- position: 'fixed',
288
- bottom: '0',
289
- right: '0',
290
- zIndex: 99999,
291
- width: '100%',
292
- height: devtoolsHeight ?? 500,
293
- maxHeight: '90%',
294
- boxShadow: '0 0 20px rgba(0,0,0,.3)',
295
- borderTop: `1px solid ${theme.gray}`,
296
- transformOrigin: 'top',
297
- // visibility will be toggled after transitions, but set initial state here
298
- visibility: isOpen ? 'visible' : 'hidden',
299
- ...panelStyle,
300
- ...(isResizing
301
- ? {
302
- transition: `none`,
303
- }
304
- : { transition: `all .2s ease` }),
305
- ...(isResolvedOpen
306
- ? {
307
- opacity: 1,
308
- pointerEvents: 'all',
309
- transform: `translateY(0) scale(1)`,
310
- }
311
- : {
312
- opacity: 0,
313
- pointerEvents: 'none',
314
- transform: `translateY(15px) scale(1.02)`,
315
- }),
316
- }}
317
- isOpen={isResolvedOpen}
318
- setIsOpen={setIsOpen}
319
- handleDragStart={(e) => handleDragStart(panelRef.current, e)}
320
- />
321
- {isResolvedOpen ? (
322
- <Button
323
- type="button"
324
- aria-label="Close TanStack Router Devtools"
325
- {...(otherCloseButtonProps as any)}
326
- onClick={(e) => {
327
- setIsOpen(false)
328
- onCloseClick && onCloseClick(e)
329
- }}
330
- style={{
331
- position: 'fixed',
332
- zIndex: 99999,
333
- margin: '.5em',
334
- bottom: 0,
335
- ...(position === 'top-right'
336
- ? {
337
- right: '0',
338
- }
339
- : position === 'top-left'
340
- ? {
341
- left: '0',
342
- }
343
- : position === 'bottom-right'
344
- ? {
345
- right: '0',
346
- }
347
- : {
348
- left: '0',
349
- }),
350
- ...closeButtonStyle,
351
- }}
352
- >
353
- Close
354
- </Button>
355
- ) : null}
356
- </ThemeProvider>
357
- {!isResolvedOpen ? (
358
- <button
359
- type="button"
360
- {...otherToggleButtonProps}
361
- aria-label="Open TanStack Router Devtools"
362
- onClick={(e) => {
363
- setIsOpen(true)
364
- onToggleClick && onToggleClick(e)
365
- }}
366
- style={{
367
- appearance: 'none',
368
- background: 'none',
369
- border: 0,
370
- padding: 0,
371
- position: 'fixed',
372
- zIndex: 99999,
373
- display: 'inline-flex',
374
- fontSize: '1.5em',
375
- margin: '.5em',
376
- cursor: 'pointer',
377
- width: 'fit-content',
378
- ...(position === 'top-right'
379
- ? {
380
- top: '0',
381
- right: '0',
382
- }
383
- : position === 'top-left'
384
- ? {
385
- top: '0',
386
- left: '0',
387
- }
388
- : position === 'bottom-right'
389
- ? {
390
- bottom: '0',
391
- right: '0',
392
- }
393
- : {
394
- bottom: '0',
395
- left: '0',
396
- }),
397
- ...toggleButtonStyle,
398
- }}
399
- >
400
- <Logo aria-hidden />
401
- </button>
402
- ) : null}
403
- </Container>
404
- )
405
- }
406
-
407
- export const TanStackRouterDevtoolsPanel = React.forwardRef<
408
- HTMLDivElement,
409
- DevtoolsPanelOptions
410
- >(function TanStackRouterDevtoolsPanel(props, ref): React.ReactElement {
411
- const {
412
- isOpen = true,
413
- setIsOpen,
414
- handleDragStart,
415
- router: userRouter,
416
- ...panelProps
417
- } = props
418
-
419
- const routerContextValue = React.useContext(routerContext)
420
- const router = userRouter ?? routerContextValue?.router
421
-
422
- invariant(
423
- router,
424
- '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.',
425
- )
426
-
427
- useStore(router.__store)
428
-
429
- const [activeRouteId, setActiveRouteId] = useLocalStorage(
430
- 'tanstackRouterDevtoolsActiveRouteId',
431
- '',
432
- )
433
-
434
- const [activeMatchId, setActiveMatchId] = useLocalStorage(
435
- 'tanstackRouterDevtoolsActiveMatchId',
436
- '',
437
- )
438
-
439
- React.useEffect(() => {
440
- setActiveMatchId('')
441
- }, [activeRouteId])
442
-
443
- const allMatches = React.useMemo(
444
- () => [
445
- ...Object.values(router.state.currentMatches),
446
- ...Object.values(router.state.pendingMatches ?? []),
447
- ],
448
- [router.state.currentMatches, router.state.pendingMatches],
449
- )
450
-
451
- const activeMatch =
452
- allMatches?.find((d) => d.id === activeMatchId) ||
453
- allMatches?.find((d) => d.route.id === activeRouteId)
454
-
455
- return (
456
- <ThemeProvider theme={theme}>
457
- <Panel ref={ref} className="TanStackRouterDevtoolsPanel" {...panelProps}>
458
- <style
459
- dangerouslySetInnerHTML={{
460
- __html: `
461
-
462
- .TanStackRouterDevtoolsPanel * {
463
- scrollbar-color: ${theme.backgroundAlt} ${theme.gray};
464
- }
465
-
466
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar, .TanStackRouterDevtoolsPanel scrollbar {
467
- width: 1em;
468
- height: 1em;
469
- }
470
-
471
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-track, .TanStackRouterDevtoolsPanel scrollbar-track {
472
- background: ${theme.backgroundAlt};
473
- }
474
-
475
- .TanStackRouterDevtoolsPanel *::-webkit-scrollbar-thumb, .TanStackRouterDevtoolsPanel scrollbar-thumb {
476
- background: ${theme.gray};
477
- border-radius: .5em;
478
- border: 3px solid ${theme.backgroundAlt};
479
- }
480
-
481
- .TanStackRouterDevtoolsPanel table {
482
- width: 100%;
483
- }
484
-
485
- .TanStackRouterDevtoolsPanel table tr {
486
- border-bottom: 2px dotted rgba(255, 255, 255, .2);
487
- }
488
-
489
- .TanStackRouterDevtoolsPanel table tr:last-child {
490
- border-bottom: none
491
- }
492
-
493
- .TanStackRouterDevtoolsPanel table td {
494
- padding: .25rem .5rem;
495
- border-right: 2px dotted rgba(255, 255, 255, .05);
496
- }
497
-
498
- .TanStackRouterDevtoolsPanel table td:last-child {
499
- border-right: none
500
- }
501
-
502
- `,
503
- }}
504
- />
505
- <div
506
- style={{
507
- position: 'absolute',
508
- left: 0,
509
- top: 0,
510
- width: '100%',
511
- height: '4px',
512
- marginBottom: '-4px',
513
- cursor: 'row-resize',
514
- zIndex: 100000,
515
- }}
516
- onMouseDown={handleDragStart}
517
- ></div>
518
- <div
519
- style={{
520
- flex: '1 1 500px',
521
- minHeight: '40%',
522
- maxHeight: '100%',
523
- overflow: 'auto',
524
- borderRight: `1px solid ${theme.grayAlt}`,
525
- display: 'flex',
526
- flexDirection: 'column',
527
- }}
528
- >
529
- <div
530
- style={{
531
- display: 'flex',
532
- justifyContent: 'start',
533
- gap: '1rem',
534
- padding: '1rem',
535
- alignItems: 'center',
536
- background: theme.backgroundAlt,
537
- }}
538
- >
539
- <Logo aria-hidden />
540
- <div
541
- style={{
542
- fontSize: 'clamp(.8rem, 2vw, 1.3rem)',
543
- fontWeight: 'bold',
544
- }}
545
- >
546
- <span
547
- style={{
548
- fontWeight: 100,
549
- }}
550
- >
551
- Devtools
552
- </span>
553
- </div>
554
- </div>
555
- <div
556
- style={{
557
- overflowY: 'auto',
558
- flex: '1',
559
- }}
560
- >
561
- <div
562
- style={{
563
- padding: '.5em',
564
- }}
565
- >
566
- <Explorer label="Router" value={router} defaultExpanded={{}} />
567
- </div>
568
- </div>
569
- </div>
570
- <div
571
- style={{
572
- flex: '1 1 500px',
573
- minHeight: '40%',
574
- maxHeight: '100%',
575
- overflow: 'auto',
576
- borderRight: `1px solid ${theme.grayAlt}`,
577
- display: 'flex',
578
- flexDirection: 'column',
579
- }}
580
- >
581
- <div
582
- style={{
583
- padding: '.5em',
584
- background: theme.backgroundAlt,
585
- position: 'sticky',
586
- top: 0,
587
- zIndex: 1,
588
- }}
589
- >
590
- Active Matches
591
- </div>
592
- {router.state.currentMatches.map((match, i) => {
593
- return (
594
- <div
595
- key={match.route.id || i}
596
- role="button"
597
- aria-label={`Open match details for ${match.route.id}`}
598
- onClick={() =>
599
- setActiveRouteId(
600
- activeRouteId === match.route.id ? '' : match.route.id,
601
- )
602
- }
603
- style={{
604
- display: 'flex',
605
- borderBottom: `solid 1px ${theme.grayAlt}`,
606
- cursor: 'pointer',
607
- alignItems: 'center',
608
- background:
609
- match === activeMatch ? 'rgba(255,255,255,.1)' : undefined,
610
- }}
611
- >
612
- <div
613
- style={{
614
- flex: '0 0 auto',
615
- width: '1.3rem',
616
- height: '1.3rem',
617
- marginLeft: '.25rem',
618
- background: getStatusColor(match, theme),
619
- alignItems: 'center',
620
- justifyContent: 'center',
621
- fontWeight: 'bold',
622
- borderRadius: '.25rem',
623
- transition: 'all .2s ease-out',
624
- }}
625
- />
626
-
627
- <Code
628
- style={{
629
- padding: '.5em',
630
- }}
631
- >
632
- {`${match.id}`}
633
- </Code>
634
- </div>
635
- )
636
- })}
637
- {router.state.pendingMatches?.length ? (
638
- <>
639
- <div
640
- style={{
641
- marginTop: '2rem',
642
- padding: '.5em',
643
- background: theme.backgroundAlt,
644
- position: 'sticky',
645
- top: 0,
646
- zIndex: 1,
647
- }}
648
- >
649
- Pending Matches
650
- </div>
651
- {router.state.pendingMatches?.map((match, i) => {
652
- return (
653
- <div
654
- key={match.route.id || i}
655
- role="button"
656
- aria-label={`Open match details for ${match.route.id}`}
657
- onClick={() =>
658
- setActiveRouteId(
659
- activeRouteId === match.route.id ? '' : match.route.id,
660
- )
661
- }
662
- style={{
663
- display: 'flex',
664
- borderBottom: `solid 1px ${theme.grayAlt}`,
665
- cursor: 'pointer',
666
- background:
667
- match === activeMatch
668
- ? 'rgba(255,255,255,.1)'
669
- : undefined,
670
- }}
671
- >
672
- <div
673
- style={{
674
- flex: '0 0 auto',
675
- width: '1.3rem',
676
- height: '1.3rem',
677
- marginLeft: '.25rem',
678
- background: getStatusColor(match, theme),
679
- alignItems: 'center',
680
- justifyContent: 'center',
681
- fontWeight: 'bold',
682
- borderRadius: '.25rem',
683
- transition: 'all .2s ease-out',
684
- }}
685
- />
686
-
687
- <Code
688
- style={{
689
- padding: '.5em',
690
- }}
691
- >
692
- {`${match.id}`}
693
- </Code>
694
- </div>
695
- )
696
- })}
697
- </>
698
- ) : null}
699
- {/* {matchCacheValues.length ? (
700
- <>
701
- <div
702
- style={{
703
- marginTop: '2rem',
704
- padding: '.5em',
705
- background: theme.backgroundAlt,
706
- position: 'sticky',
707
- top: 0,
708
- bottom: 0,
709
- zIndex: 1,
710
- display: 'flex',
711
- alignItems: 'center',
712
- justifyContent: 'space-between',
713
- }}
714
- >
715
- <div>Match Cache</div>
716
- <Button
717
- onClick={() => {
718
- router.store.setState((s) => (s.matchCache = {}))
719
- }}
720
- >
721
- Clear
722
- </Button>
723
- </div>
724
- {matchCacheValues.map((d, i) => {
725
- const { match, gc } = d
726
-
727
- return (
728
- <div
729
- key={match.id || i}
730
- role="button"
731
- aria-label={`Open match details for ${match.id}`}
732
- onClick={() =>
733
- setActiveMatchId(
734
- activeMatchId === match.id ? '' : match.id,
735
- )
736
- }
737
- style={{
738
- display: 'flex',
739
- borderBottom: `solid 1px ${theme.grayAlt}`,
740
- cursor: 'pointer',
741
- background:
742
- match === activeMatch
743
- ? 'rgba(255,255,255,.1)'
744
- : undefined,
745
- }}
746
- >
747
- <div
748
- style={{
749
- display: 'flex',
750
- flexDirection: 'column',
751
- padding: '.5rem',
752
- gap: '.3rem',
753
- }}
754
- >
755
- <div
756
- style={{
757
- display: 'flex',
758
- alignItems: 'center',
759
- gap: '.5rem',
760
- }}
761
- >
762
- <div
763
- style={{
764
- flex: '0 0 auto',
765
- width: '1.3rem',
766
- height: '1.3rem',
767
- background: getStatusColor(match, theme),
768
- alignItems: 'center',
769
- justifyContent: 'center',
770
- fontWeight: 'bold',
771
- borderRadius: '.25rem',
772
- transition: 'all .2s ease-out',
773
- }}
774
- />
775
- <Code>{`${match.id}`}</Code>
776
- </div>
777
- <span
778
- style={{
779
- fontSize: '.7rem',
780
- opacity: '.5',
781
- lineHeight: 1,
782
- }}
783
- >
784
- Expires{' '}
785
- {formatDistanceStrict(new Date(gc), new Date(), {
786
- addSuffix: true,
787
- })}
788
- </span>
789
- </div>
790
- </div>
791
- )
792
- })}
793
- </>
794
- ) : null} */}
795
- </div>
796
-
797
- {activeMatch ? (
798
- <ActivePanel>
799
- <div
800
- style={{
801
- padding: '.5em',
802
- background: theme.backgroundAlt,
803
- position: 'sticky',
804
- top: 0,
805
- bottom: 0,
806
- zIndex: 1,
807
- }}
808
- >
809
- Match Details
810
- </div>
811
- <div>
812
- <table>
813
- <tbody>
814
- <tr>
815
- <td style={{ opacity: '.5' }}>ID</td>
816
- <td>
817
- <Code
818
- style={{
819
- lineHeight: '1.8em',
820
- }}
821
- >
822
- {JSON.stringify(activeMatch.id, null, 2)}
823
- </Code>
824
- </td>
825
- </tr>
826
- <tr>
827
- <td style={{ opacity: '.5' }}>Status</td>
828
- <td>{activeMatch.state.status}</td>
829
- </tr>
830
- {/* <tr>
831
- <td style={{ opacity: '.5' }}>Invalid</td>
832
- <td>{activeMatch.getIsInvalid().toString()}</td>
833
- </tr> */}
834
- <tr>
835
- <td style={{ opacity: '.5' }}>Last Updated</td>
836
- <td>
837
- {activeMatch.state.updatedAt
838
- ? new Date(
839
- activeMatch.state.updatedAt as number,
840
- ).toLocaleTimeString()
841
- : 'N/A'}
842
- </td>
843
- </tr>
844
- </tbody>
845
- </table>
846
- </div>
847
- <div
848
- style={{
849
- background: theme.backgroundAlt,
850
- padding: '.5em',
851
- position: 'sticky',
852
- top: 0,
853
- bottom: 0,
854
- zIndex: 1,
855
- }}
856
- >
857
- Actions
858
- </div>
859
- <div
860
- style={{
861
- padding: '0.5em',
862
- }}
863
- >
864
- <Button
865
- type="button"
866
- onClick={() => activeMatch.load()}
867
- style={{
868
- background: theme.gray,
869
- }}
870
- >
871
- Reload
872
- </Button>
873
- </div>
874
- <div
875
- style={{
876
- background: theme.backgroundAlt,
877
- padding: '.5em',
878
- position: 'sticky',
879
- top: 0,
880
- bottom: 0,
881
- zIndex: 1,
882
- }}
883
- >
884
- Explorer
885
- </div>
886
- <div
887
- style={{
888
- padding: '.5em',
889
- }}
890
- >
891
- <Explorer
892
- label="Match"
893
- value={activeMatch}
894
- defaultExpanded={{}}
895
- />
896
- </div>
897
- </ActivePanel>
898
- ) : null}
899
- <div
900
- style={{
901
- flex: '1 1 500px',
902
- minHeight: '40%',
903
- maxHeight: '100%',
904
- overflow: 'auto',
905
- borderRight: `1px solid ${theme.grayAlt}`,
906
- display: 'flex',
907
- flexDirection: 'column',
908
- }}
909
- >
910
- {/* <div
911
- style={{
912
- padding: '.5em',
913
- background: theme.backgroundAlt,
914
- position: 'sticky',
915
- top: 0,
916
- bottom: 0,
917
- zIndex: 1,
918
- }}
919
- >
920
- All Loader Data
921
- </div>
922
- <div
923
- style={{
924
- padding: '.5em',
925
- }}
926
- >
927
- {Object.keys(
928
- last(router.state.currentMatches)?.state.loaderData ||
929
- {},
930
- ).length ? (
931
- <Explorer
932
- value={
933
- last(router.state.currentMatches)?.state
934
- .loaderData || {}
935
- }
936
- defaultExpanded={Object.keys(
937
- (last(router.state.currentMatches)?.state
938
- .loaderData as {}) || {},
939
- ).reduce((obj: any, next) => {
940
- obj[next] = {}
941
- return obj
942
- }, {})}
943
- />
944
- ) : (
945
- <em style={{ opacity: 0.5 }}>{'{ }'}</em>
946
- )}
947
- </div> */}
948
- <div
949
- style={{
950
- padding: '.5em',
951
- background: theme.backgroundAlt,
952
- position: 'sticky',
953
- top: 0,
954
- bottom: 0,
955
- zIndex: 1,
956
- }}
957
- >
958
- Search Params
959
- </div>
960
- <div
961
- style={{
962
- padding: '.5em',
963
- }}
964
- >
965
- {Object.keys(last(router.state.currentMatches)?.state.search || {})
966
- .length ? (
967
- <Explorer
968
- value={last(router.state.currentMatches)?.state.search || {}}
969
- defaultExpanded={Object.keys(
970
- (last(router.state.currentMatches)?.state.search as {}) || {},
971
- ).reduce((obj: any, next) => {
972
- obj[next] = {}
973
- return obj
974
- }, {})}
975
- />
976
- ) : (
977
- <em style={{ opacity: 0.5 }}>{'{ }'}</em>
978
- )}
979
- </div>
980
- </div>
981
- </Panel>
982
- </ThemeProvider>
983
- )
984
- })