@tanstack/router-devtools 1.112.4 → 1.112.5

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 (41) hide show
  1. package/dist/cjs/BaseTanStackRouterDevtoolsPanel.cjs +29 -12
  2. package/dist/cjs/BaseTanStackRouterDevtoolsPanel.cjs.map +1 -1
  3. package/dist/cjs/BaseTanStackRouterDevtoolsPanel.d.cts +3 -1
  4. package/dist/cjs/Explorer.cjs +1 -1
  5. package/dist/cjs/Explorer.cjs.map +1 -1
  6. package/dist/cjs/TanStackRouterDevtools.cjs +2 -2
  7. package/dist/cjs/TanStackRouterDevtools.cjs.map +1 -1
  8. package/dist/cjs/TanStackRouterDevtoolsPanel.cjs +7 -5
  9. package/dist/cjs/TanStackRouterDevtoolsPanel.cjs.map +1 -1
  10. package/dist/cjs/TanStackRouterDevtoolsPanel.d.cts +3 -1
  11. package/dist/cjs/context.cjs +1 -1
  12. package/dist/cjs/context.cjs.map +1 -1
  13. package/dist/cjs/useStyles.cjs +1 -1
  14. package/dist/cjs/useStyles.cjs.map +1 -1
  15. package/dist/cjs/utils.cjs.map +1 -1
  16. package/dist/cjs/utils.d.cts +3 -1
  17. package/dist/esm/BaseTanStackRouterDevtoolsPanel.d.ts +3 -1
  18. package/dist/esm/BaseTanStackRouterDevtoolsPanel.js +29 -12
  19. package/dist/esm/BaseTanStackRouterDevtoolsPanel.js.map +1 -1
  20. package/dist/esm/Explorer.js +1 -1
  21. package/dist/esm/Explorer.js.map +1 -1
  22. package/dist/esm/TanStackRouterDevtools.js +2 -2
  23. package/dist/esm/TanStackRouterDevtools.js.map +1 -1
  24. package/dist/esm/TanStackRouterDevtoolsPanel.d.ts +3 -1
  25. package/dist/esm/TanStackRouterDevtoolsPanel.js +7 -5
  26. package/dist/esm/TanStackRouterDevtoolsPanel.js.map +1 -1
  27. package/dist/esm/context.js +1 -1
  28. package/dist/esm/context.js.map +1 -1
  29. package/dist/esm/useStyles.js +1 -1
  30. package/dist/esm/useStyles.js.map +1 -1
  31. package/dist/esm/utils.d.ts +3 -1
  32. package/dist/esm/utils.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/BaseTanStackRouterDevtoolsPanel.tsx +322 -311
  35. package/src/Explorer.tsx +1 -1
  36. package/src/TanStackRouterDevtools.tsx +4 -4
  37. package/src/TanStackRouterDevtoolsPanel.tsx +18 -17
  38. package/src/context.ts +1 -1
  39. package/src/theme.tsx +2 -2
  40. package/src/useStyles.tsx +1 -1
  41. package/src/utils.ts +38 -31
@@ -121,228 +121,273 @@ function RouteComp({
121
121
  )
122
122
  }
123
123
 
124
- export const BaseTanStackRouterDevtoolsPanel = React.forwardRef<
125
- HTMLDivElement,
126
- DevtoolsPanelOptions
127
- >(function BaseTanStackRouterDevtoolsPanel(props, ref): React.ReactElement {
128
- const {
129
- isOpen = true,
130
- setIsOpen,
131
- handleDragStart,
132
- router: userRouter,
133
- shadowDOMTarget,
134
- ...panelProps
135
- } = props
124
+ export const BaseTanStackRouterDevtoolsPanel =
125
+ function BaseTanStackRouterDevtoolsPanel({
126
+ ref,
127
+ ...props
128
+ }: DevtoolsPanelOptions & {
129
+ ref?: React.RefObject<HTMLDivElement | null>
130
+ }): React.ReactElement {
131
+ const {
132
+ isOpen = true,
133
+ setIsOpen,
134
+ handleDragStart,
135
+ router: userRouter,
136
+ shadowDOMTarget,
137
+ ...panelProps
138
+ } = props
136
139
 
137
- const { onCloseClick } = useDevtoolsOnClose()
138
- const styles = useStyles()
139
- const { className, ...otherPanelProps } = panelProps
140
+ const { onCloseClick } = useDevtoolsOnClose()
141
+ const styles = useStyles()
142
+ const { className, ...otherPanelProps } = panelProps
140
143
 
141
- const contextRouter = useRouter({ warn: false })
142
- const router = userRouter ?? contextRouter
143
- const routerState = useRouterState({
144
- router,
145
- } as any)
144
+ const contextRouter = useRouter({ warn: false })
145
+ const router = userRouter ?? contextRouter
146
+ const routerState = useRouterState({
147
+ router,
148
+ } as any)
146
149
 
147
- invariant(
148
- router,
149
- '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.',
150
- )
150
+ invariant(
151
+ router,
152
+ '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.',
153
+ )
151
154
 
152
- // useStore(router.__store)
155
+ // useStore(router.__store)
153
156
 
154
- const [showMatches, setShowMatches] = useLocalStorage(
155
- 'tanstackRouterDevtoolsShowMatches',
156
- true,
157
- )
157
+ const [showMatches, setShowMatches] = useLocalStorage(
158
+ 'tanstackRouterDevtoolsShowMatches',
159
+ true,
160
+ )
158
161
 
159
- const [activeId, setActiveId] = useLocalStorage(
160
- 'tanstackRouterDevtoolsActiveRouteId',
161
- '',
162
- )
162
+ const [activeId, setActiveId] = useLocalStorage(
163
+ 'tanstackRouterDevtoolsActiveRouteId',
164
+ '',
165
+ )
163
166
 
164
- const activeMatch = React.useMemo(() => {
165
- const matches = [
166
- ...(routerState.pendingMatches ?? []),
167
- ...routerState.matches,
168
- ...routerState.cachedMatches,
169
- ]
170
- return matches.find((d) => d.routeId === activeId || d.id === activeId)
171
- }, [
172
- activeId,
173
- routerState.cachedMatches,
174
- routerState.matches,
175
- routerState.pendingMatches,
176
- ])
167
+ const activeMatch = React.useMemo(() => {
168
+ const matches = [
169
+ ...(routerState.pendingMatches ?? []),
170
+ ...routerState.matches,
171
+ ...routerState.cachedMatches,
172
+ ]
173
+ return matches.find((d) => d.routeId === activeId || d.id === activeId)
174
+ }, [
175
+ activeId,
176
+ routerState.cachedMatches,
177
+ routerState.matches,
178
+ routerState.pendingMatches,
179
+ ])
177
180
 
178
- const hasSearch = Object.keys(routerState.location.search).length
181
+ const hasSearch = Object.keys(routerState.location.search).length
179
182
 
180
- const explorerState = {
181
- ...router,
182
- state: router.state,
183
- }
183
+ const explorerState = {
184
+ ...router,
185
+ state: router.state,
186
+ }
184
187
 
185
- return (
186
- <div
187
- ref={ref}
188
- className={cx(
189
- styles.devtoolsPanel,
190
- 'TanStackRouterDevtoolsPanel',
191
- className,
192
- )}
193
- {...otherPanelProps}
194
- >
195
- {handleDragStart ? (
196
- <div className={styles.dragHandle} onMouseDown={handleDragStart}></div>
197
- ) : null}
198
- <button
199
- className={styles.panelCloseBtn}
200
- onClick={(e) => {
201
- setIsOpen(false)
202
- onCloseClick(e)
203
- }}
188
+ return (
189
+ <div
190
+ ref={ref}
191
+ className={cx(
192
+ styles.devtoolsPanel,
193
+ 'TanStackRouterDevtoolsPanel',
194
+ className,
195
+ )}
196
+ {...otherPanelProps}
204
197
  >
205
- <svg
206
- xmlns="http://www.w3.org/2000/svg"
207
- width="10"
208
- height="6"
209
- fill="none"
210
- viewBox="0 0 10 6"
211
- className={styles.panelCloseBtnIcon}
198
+ {handleDragStart ? (
199
+ <div
200
+ className={styles.dragHandle}
201
+ onMouseDown={handleDragStart}
202
+ ></div>
203
+ ) : null}
204
+ <button
205
+ className={styles.panelCloseBtn}
206
+ onClick={(e) => {
207
+ setIsOpen(false)
208
+ onCloseClick(e)
209
+ }}
212
210
  >
213
- <path
214
- stroke="currentColor"
215
- strokeLinecap="round"
216
- strokeLinejoin="round"
217
- strokeWidth="1.667"
218
- d="M1 1l4 4 4-4"
219
- ></path>
220
- </svg>
221
- </button>
222
- <div className={styles.firstContainer}>
223
- <div className={styles.row}>
224
- <Logo
225
- aria-hidden
226
- onClick={(e) => {
227
- setIsOpen(false)
228
- onCloseClick(e)
229
- }}
230
- />
231
- </div>
232
- <div className={styles.routerExplorerContainer}>
233
- <div className={styles.routerExplorer}>
234
- <Explorer
235
- label="Router"
236
- value={Object.fromEntries(
237
- multiSortBy(
238
- Object.keys(explorerState),
239
- (
240
- [
241
- 'state',
242
- 'routesById',
243
- 'routesByPath',
244
- 'flatRoutes',
245
- 'options',
246
- 'manifest',
247
- ] as const
248
- ).map((d) => (dd) => dd !== d),
249
- )
250
- .map((key) => [key, (explorerState as any)[key]])
251
- .filter(
252
- (d) =>
253
- typeof d[1] !== 'function' &&
254
- ![
255
- '__store',
256
- 'basepath',
257
- 'injectedHtml',
258
- 'subscribers',
259
- 'latestLoadPromise',
260
- 'navigateTimeout',
261
- 'resetNextScroll',
262
- 'tempLocationKey',
263
- 'latestLocation',
264
- 'routeTree',
265
- 'history',
266
- ].includes(d[0]),
267
- ),
268
- )}
269
- defaultExpanded={{
270
- state: {} as any,
271
- context: {} as any,
272
- options: {} as any,
273
- }}
274
- filterSubEntries={(subEntries) => {
275
- return subEntries.filter((d) => typeof d.value !== 'function')
211
+ <svg
212
+ xmlns="http://www.w3.org/2000/svg"
213
+ width="10"
214
+ height="6"
215
+ fill="none"
216
+ viewBox="0 0 10 6"
217
+ className={styles.panelCloseBtnIcon}
218
+ >
219
+ <path
220
+ stroke="currentColor"
221
+ strokeLinecap="round"
222
+ strokeLinejoin="round"
223
+ strokeWidth="1.667"
224
+ d="M1 1l4 4 4-4"
225
+ ></path>
226
+ </svg>
227
+ </button>
228
+ <div className={styles.firstContainer}>
229
+ <div className={styles.row}>
230
+ <Logo
231
+ aria-hidden
232
+ onClick={(e) => {
233
+ setIsOpen(false)
234
+ onCloseClick(e)
276
235
  }}
277
236
  />
278
237
  </div>
279
- </div>
280
- </div>
281
- <div className={styles.secondContainer}>
282
- <div className={styles.matchesContainer}>
283
- <div className={styles.detailsHeader}>
284
- <span>Pathname</span>
285
- {routerState.location.maskedLocation ? (
286
- <div className={styles.maskedBadgeContainer}>
287
- <span className={styles.maskedBadge}>masked</span>
288
- </div>
289
- ) : null}
290
- </div>
291
- <div className={styles.detailsContent}>
292
- <code>{routerState.location.pathname}</code>
293
- {routerState.location.maskedLocation ? (
294
- <code className={styles.maskedLocation}>
295
- {routerState.location.maskedLocation.pathname}
296
- </code>
297
- ) : null}
298
- </div>
299
- <div className={styles.detailsHeader}>
300
- <div className={styles.routeMatchesToggle}>
301
- <button
302
- type="button"
303
- onClick={() => {
304
- setShowMatches(false)
238
+ <div className={styles.routerExplorerContainer}>
239
+ <div className={styles.routerExplorer}>
240
+ <Explorer
241
+ label="Router"
242
+ value={Object.fromEntries(
243
+ multiSortBy(
244
+ Object.keys(explorerState),
245
+ (
246
+ [
247
+ 'state',
248
+ 'routesById',
249
+ 'routesByPath',
250
+ 'flatRoutes',
251
+ 'options',
252
+ 'manifest',
253
+ ] as const
254
+ ).map((d) => (dd) => dd !== d),
255
+ )
256
+ .map((key) => [key, (explorerState as any)[key]])
257
+ .filter(
258
+ (d) =>
259
+ typeof d[1] !== 'function' &&
260
+ ![
261
+ '__store',
262
+ 'basepath',
263
+ 'injectedHtml',
264
+ 'subscribers',
265
+ 'latestLoadPromise',
266
+ 'navigateTimeout',
267
+ 'resetNextScroll',
268
+ 'tempLocationKey',
269
+ 'latestLocation',
270
+ 'routeTree',
271
+ 'history',
272
+ ].includes(d[0]),
273
+ ),
274
+ )}
275
+ defaultExpanded={{
276
+ state: {} as any,
277
+ context: {} as any,
278
+ options: {} as any,
305
279
  }}
306
- disabled={!showMatches}
307
- className={cx(styles.routeMatchesToggleBtn(!showMatches, true))}
308
- >
309
- Routes
310
- </button>
311
- <button
312
- type="button"
313
- onClick={() => {
314
- setShowMatches(true)
280
+ filterSubEntries={(subEntries) => {
281
+ return subEntries.filter((d) => typeof d.value !== 'function')
315
282
  }}
316
- disabled={showMatches}
317
- className={cx(
318
- styles.routeMatchesToggleBtn(!!showMatches, false),
319
- )}
320
- >
321
- Matches
322
- </button>
283
+ />
323
284
  </div>
324
- <div className={styles.detailsHeaderInfo}>
325
- <div>age / staleTime / gcTime</div>
285
+ </div>
286
+ </div>
287
+ <div className={styles.secondContainer}>
288
+ <div className={styles.matchesContainer}>
289
+ <div className={styles.detailsHeader}>
290
+ <span>Pathname</span>
291
+ {routerState.location.maskedLocation ? (
292
+ <div className={styles.maskedBadgeContainer}>
293
+ <span className={styles.maskedBadge}>masked</span>
294
+ </div>
295
+ ) : null}
296
+ </div>
297
+ <div className={styles.detailsContent}>
298
+ <code>{routerState.location.pathname}</code>
299
+ {routerState.location.maskedLocation ? (
300
+ <code className={styles.maskedLocation}>
301
+ {routerState.location.maskedLocation.pathname}
302
+ </code>
303
+ ) : null}
304
+ </div>
305
+ <div className={styles.detailsHeader}>
306
+ <div className={styles.routeMatchesToggle}>
307
+ <button
308
+ type="button"
309
+ onClick={() => {
310
+ setShowMatches(false)
311
+ }}
312
+ disabled={!showMatches}
313
+ className={cx(
314
+ styles.routeMatchesToggleBtn(!showMatches, true),
315
+ )}
316
+ >
317
+ Routes
318
+ </button>
319
+ <button
320
+ type="button"
321
+ onClick={() => {
322
+ setShowMatches(true)
323
+ }}
324
+ disabled={showMatches}
325
+ className={cx(
326
+ styles.routeMatchesToggleBtn(!!showMatches, false),
327
+ )}
328
+ >
329
+ Matches
330
+ </button>
331
+ </div>
332
+ <div className={styles.detailsHeaderInfo}>
333
+ <div>age / staleTime / gcTime</div>
334
+ </div>
335
+ </div>
336
+ <div className={cx(styles.routesContainer)}>
337
+ {!showMatches ? (
338
+ <RouteComp
339
+ router={router}
340
+ route={router.routeTree}
341
+ isRoot
342
+ activeId={activeId}
343
+ setActiveId={setActiveId}
344
+ />
345
+ ) : (
346
+ <div>
347
+ {(routerState.pendingMatches?.length
348
+ ? routerState.pendingMatches
349
+ : routerState.matches
350
+ ).map((match, i) => {
351
+ return (
352
+ <div
353
+ key={match.id || i}
354
+ role="button"
355
+ aria-label={`Open match details for ${match.id}`}
356
+ onClick={() =>
357
+ setActiveId(activeId === match.id ? '' : match.id)
358
+ }
359
+ className={cx(styles.matchRow(match === activeMatch))}
360
+ >
361
+ <div
362
+ className={cx(
363
+ styles.matchIndicator(getStatusColor(match)),
364
+ )}
365
+ />
366
+
367
+ <code
368
+ className={styles.matchID}
369
+ >{`${match.routeId === rootRouteId ? rootRouteId : match.pathname}`}</code>
370
+ <AgeTicker match={match} router={router} />
371
+ </div>
372
+ )
373
+ })}
374
+ </div>
375
+ )}
326
376
  </div>
327
377
  </div>
328
- <div className={cx(styles.routesContainer)}>
329
- {!showMatches ? (
330
- <RouteComp
331
- router={router}
332
- route={router.routeTree}
333
- isRoot
334
- activeId={activeId}
335
- setActiveId={setActiveId}
336
- />
337
- ) : (
378
+ {routerState.cachedMatches.length ? (
379
+ <div className={styles.cachedMatchesContainer}>
380
+ <div className={styles.detailsHeader}>
381
+ <div>Cached Matches</div>
382
+ <div className={styles.detailsHeaderInfo}>
383
+ age / staleTime / gcTime
384
+ </div>
385
+ </div>
338
386
  <div>
339
- {(routerState.pendingMatches?.length
340
- ? routerState.pendingMatches
341
- : routerState.matches
342
- ).map((match, i) => {
387
+ {routerState.cachedMatches.map((match) => {
343
388
  return (
344
389
  <div
345
- key={match.id || i}
390
+ key={match.id}
346
391
  role="button"
347
392
  aria-label={`Open match details for ${match.id}`}
348
393
  onClick={() =>
@@ -356,133 +401,99 @@ export const BaseTanStackRouterDevtoolsPanel = React.forwardRef<
356
401
  )}
357
402
  />
358
403
 
359
- <code
360
- className={styles.matchID}
361
- >{`${match.routeId === rootRouteId ? rootRouteId : match.pathname}`}</code>
404
+ <code className={styles.matchID}>{`${match.id}`}</code>
405
+
362
406
  <AgeTicker match={match} router={router} />
363
407
  </div>
364
408
  )
365
409
  })}
366
410
  </div>
367
- )}
368
- </div>
369
- </div>
370
- {routerState.cachedMatches.length ? (
371
- <div className={styles.cachedMatchesContainer}>
372
- <div className={styles.detailsHeader}>
373
- <div>Cached Matches</div>
374
- <div className={styles.detailsHeaderInfo}>
375
- age / staleTime / gcTime
376
- </div>
377
411
  </div>
412
+ ) : null}
413
+ </div>
414
+ {activeMatch ? (
415
+ <div className={styles.thirdContainer}>
416
+ <div className={styles.detailsHeader}>Match Details</div>
378
417
  <div>
379
- {routerState.cachedMatches.map((match) => {
380
- return (
381
- <div
382
- key={match.id}
383
- role="button"
384
- aria-label={`Open match details for ${match.id}`}
385
- onClick={() =>
386
- setActiveId(activeId === match.id ? '' : match.id)
387
- }
388
- className={cx(styles.matchRow(match === activeMatch))}
389
- >
390
- <div
391
- className={cx(
392
- styles.matchIndicator(getStatusColor(match)),
393
- )}
394
- />
395
-
396
- <code className={styles.matchID}>{`${match.id}`}</code>
397
-
398
- <AgeTicker match={match} router={router} />
418
+ <div className={styles.matchDetails}>
419
+ <div
420
+ className={styles.matchStatus(
421
+ activeMatch.status,
422
+ activeMatch.isFetching,
423
+ )}
424
+ >
425
+ <div>
426
+ {activeMatch.status === 'success' && activeMatch.isFetching
427
+ ? 'fetching'
428
+ : activeMatch.status}
399
429
  </div>
400
- )
401
- })}
402
- </div>
403
- </div>
404
- ) : null}
405
- </div>
406
- {activeMatch ? (
407
- <div className={styles.thirdContainer}>
408
- <div className={styles.detailsHeader}>Match Details</div>
409
- <div>
410
- <div className={styles.matchDetails}>
411
- <div
412
- className={styles.matchStatus(
413
- activeMatch.status,
414
- activeMatch.isFetching,
415
- )}
416
- >
417
- <div>
418
- {activeMatch.status === 'success' && activeMatch.isFetching
419
- ? 'fetching'
420
- : activeMatch.status}
421
430
  </div>
422
- </div>
423
- <div className={styles.matchDetailsInfoLabel}>
424
- <div>ID:</div>
425
- <div className={styles.matchDetailsInfo}>
426
- <code>{activeMatch.id}</code>
431
+ <div className={styles.matchDetailsInfoLabel}>
432
+ <div>ID:</div>
433
+ <div className={styles.matchDetailsInfo}>
434
+ <code>{activeMatch.id}</code>
435
+ </div>
427
436
  </div>
428
- </div>
429
- <div className={styles.matchDetailsInfoLabel}>
430
- <div>State:</div>
431
- <div className={styles.matchDetailsInfo}>
432
- {routerState.pendingMatches?.find(
433
- (d) => d.id === activeMatch.id,
434
- )
435
- ? 'Pending'
436
- : routerState.matches.find((d) => d.id === activeMatch.id)
437
- ? 'Active'
438
- : 'Cached'}
437
+ <div className={styles.matchDetailsInfoLabel}>
438
+ <div>State:</div>
439
+ <div className={styles.matchDetailsInfo}>
440
+ {routerState.pendingMatches?.find(
441
+ (d) => d.id === activeMatch.id,
442
+ )
443
+ ? 'Pending'
444
+ : routerState.matches.find((d) => d.id === activeMatch.id)
445
+ ? 'Active'
446
+ : 'Cached'}
447
+ </div>
439
448
  </div>
440
- </div>
441
- <div className={styles.matchDetailsInfoLabel}>
442
- <div>Last Updated:</div>
443
- <div className={styles.matchDetailsInfo}>
444
- {activeMatch.updatedAt
445
- ? new Date(activeMatch.updatedAt).toLocaleTimeString()
446
- : 'N/A'}
449
+ <div className={styles.matchDetailsInfoLabel}>
450
+ <div>Last Updated:</div>
451
+ <div className={styles.matchDetailsInfo}>
452
+ {activeMatch.updatedAt
453
+ ? new Date(activeMatch.updatedAt).toLocaleTimeString()
454
+ : 'N/A'}
455
+ </div>
447
456
  </div>
448
457
  </div>
449
458
  </div>
459
+ {activeMatch.loaderData ? (
460
+ <>
461
+ <div className={styles.detailsHeader}>Loader Data</div>
462
+ <div className={styles.detailsContent}>
463
+ <Explorer
464
+ label="loaderData"
465
+ value={activeMatch.loaderData}
466
+ defaultExpanded={{}}
467
+ />
468
+ </div>
469
+ </>
470
+ ) : null}
471
+ <div className={styles.detailsHeader}>Explorer</div>
472
+ <div className={styles.detailsContent}>
473
+ <Explorer
474
+ label="Match"
475
+ value={activeMatch}
476
+ defaultExpanded={{}}
477
+ />
478
+ </div>
450
479
  </div>
451
- {activeMatch.loaderData ? (
452
- <>
453
- <div className={styles.detailsHeader}>Loader Data</div>
454
- <div className={styles.detailsContent}>
455
- <Explorer
456
- label="loaderData"
457
- value={activeMatch.loaderData}
458
- defaultExpanded={{}}
459
- />
460
- </div>
461
- </>
462
- ) : null}
463
- <div className={styles.detailsHeader}>Explorer</div>
464
- <div className={styles.detailsContent}>
465
- <Explorer label="Match" value={activeMatch} defaultExpanded={{}} />
466
- </div>
467
- </div>
468
- ) : null}
469
- {hasSearch ? (
470
- <div className={styles.fourthContainer}>
471
- <div className={styles.detailsHeader}>Search Params</div>
472
- <div className={styles.detailsContent}>
473
- <Explorer
474
- value={routerState.location.search}
475
- defaultExpanded={Object.keys(routerState.location.search).reduce(
476
- (obj: any, next) => {
480
+ ) : null}
481
+ {hasSearch ? (
482
+ <div className={styles.fourthContainer}>
483
+ <div className={styles.detailsHeader}>Search Params</div>
484
+ <div className={styles.detailsContent}>
485
+ <Explorer
486
+ value={routerState.location.search}
487
+ defaultExpanded={Object.keys(
488
+ routerState.location.search,
489
+ ).reduce((obj: any, next) => {
477
490
  obj[next] = {}
478
491
  return obj
479
- },
480
- {},
481
- )}
482
- />
492
+ }, {})}
493
+ />
494
+ </div>
483
495
  </div>
484
- </div>
485
- ) : null}
486
- </div>
487
- )
488
- })
496
+ ) : null}
497
+ </div>
498
+ )
499
+ }