Skip to content

Commit 93a1fe5

Browse files
committed
feat: improve react plugin handling to support contexts
1 parent b156e6e commit 93a1fe5

File tree

7 files changed

+54
-31
lines changed

7 files changed

+54
-31
lines changed

examples/react/basic/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@
3535
"last 1 safari version"
3636
]
3737
}
38-
}
38+
}

examples/react/basic/src/setup.tsx

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const indexRoute = createRoute({
4343
function About() {
4444
return <div className="p-2">Hello from About!</div>
4545
}
46+
4647
const aboutRoute = createRoute({
4748
getParentRoute: () => rootRoute,
4849
path: '/about',
@@ -58,22 +59,20 @@ const queryClient = new QueryClient()
5859
export default function DevtoolsExample() {
5960
return (
6061
<>
61-
<Devtools
62-
plugins={[
63-
{
64-
name: 'Tanstack Query',
65-
render: (
66-
<QueryClientProvider client={queryClient}>
67-
<ReactQueryDevtoolsPanel />
68-
</QueryClientProvider>
69-
),
70-
},
71-
{
72-
name: 'Tanstack Router',
73-
render: <TanStackRouterDevtoolsPanel router={router} />,
74-
},
75-
]}
76-
/>
62+
<QueryClientProvider client={queryClient}>
63+
<Devtools
64+
plugins={[
65+
{
66+
name: 'Tanstack Query',
67+
render: <ReactQueryDevtoolsPanel />,
68+
},
69+
{
70+
name: 'Tanstack Router',
71+
render: <TanStackRouterDevtoolsPanel router={router} />,
72+
},
73+
]}
74+
/>
75+
</QueryClientProvider>
7776
</>
7877
)
7978
}

examples/solid/basic/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@
3232
"last 1 safari version"
3333
]
3434
}
35-
}
35+
}

packages/devtools/src/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const PLUGIN_CONTAINER_ID = 'plugin-container'
2+
export const PLUGIN_TITLE_CONTAINER_ID = 'plugin-title-container'

packages/devtools/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export { TanStackRouterDevtoolsCore } from './core'
22
export type { DevtoolsOptions } from './core'
33
export type { DevtoolsPlugin } from './context/devtools-context'
4+
export { PLUGIN_CONTAINER_ID, PLUGIN_TITLE_CONTAINER_ID } from './constants'

packages/devtools/src/tabs/plugins-tab.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { For, createEffect } from 'solid-js'
22
import clsx from 'clsx'
33
import { usePlugins } from '../context/use-devtools-context'
44
import { useStyles } from '../styles/use-styles'
5+
import { PLUGIN_TITLE_CONTAINER_ID, PLUGIN_CONTAINER_ID } from '../constants'
56

67
export const PluginsTab = () => {
78
const { plugins, activePlugin, setActivePlugin } = usePlugins()
@@ -36,13 +37,17 @@ export const PluginsTab = () => {
3637
active: activePlugin() === plugin.id,
3738
})}
3839
>
39-
<h3 ref={pluginHeading} />
40+
<h3 id={PLUGIN_TITLE_CONTAINER_ID} ref={pluginHeading} />
4041
</div>
4142
)
4243
}}
4344
</For>
4445
</div>
45-
<div ref={activePluginRef} class={styles().pluginsTabContent}></div>
46+
<div
47+
id={PLUGIN_CONTAINER_ID}
48+
ref={activePluginRef}
49+
class={styles().pluginsTabContent}
50+
></div>
4651
</div>
4752
)
4853
}

packages/react-devtools/src/devtools.tsx

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import React, { useEffect, useRef, useState } from 'react'
2-
import { TanStackRouterDevtoolsCore } from '@tanstack/devtools'
3-
import { createRoot } from 'react-dom/client'
2+
import {
3+
TanStackRouterDevtoolsCore,
4+
PLUGIN_CONTAINER_ID,
5+
PLUGIN_TITLE_CONTAINER_ID,
6+
} from '@tanstack/devtools'
47
import type { JSX } from 'react'
58
import type { DevtoolsOptions, DevtoolsPlugin } from '@tanstack/devtools'
9+
import { createPortal } from 'react-dom'
610

711
type Render = JSX.Element | (() => JSX.Element)
812
type ReactPlugin = Omit<DevtoolsPlugin, 'render' | 'name'> & {
@@ -15,17 +19,18 @@ interface DevtoolsProps {
1519
}
1620

1721
const convertRender = (
18-
el: HTMLDivElement | HTMLHeadingElement,
1922
Component: Render,
23+
setComponent: React.Dispatch<React.SetStateAction<JSX.Element | null>>,
2024
) => {
21-
const domNode = document.createElement('div')
22-
const root = createRoot(domNode)
23-
root.render(typeof Component === 'function' ? <Component /> : Component)
24-
el.appendChild(domNode)
25+
setComponent(typeof Component === 'function' ? Component() : Component)
2526
}
2627

2728
export const Devtools = ({ plugins, options }: DevtoolsProps) => {
2829
const devToolRef = useRef<HTMLDivElement>(null)
30+
const [PluginComponent, setPluginComponent] = useState<JSX.Element | null>(
31+
null,
32+
)
33+
const [TitleComponent, setTitleComponent] = useState<JSX.Element | null>(null)
2934
const [devtools] = useState(
3035
() =>
3136
new TanStackRouterDevtoolsCore({
@@ -37,8 +42,8 @@ export const Devtools = ({ plugins, options }: DevtoolsProps) => {
3742
typeof plugin.name === 'string'
3843
? plugin.name
3944
: // The check above confirms that `plugin.name` is of Render type
40-
(el) => convertRender(el, plugin.name as Render),
41-
render: (el: HTMLDivElement) => convertRender(el, plugin.render),
45+
() => convertRender(plugin.name as Render, setTitleComponent),
46+
render: () => convertRender(plugin.render, setPluginComponent),
4247
}
4348
}),
4449
}),
@@ -52,6 +57,17 @@ export const Devtools = ({ plugins, options }: DevtoolsProps) => {
5257
devtools.unmount()
5358
}
5459
}, [devtools])
55-
56-
return <div ref={devToolRef} />
60+
const pluginContainer = document.getElementById(PLUGIN_CONTAINER_ID)
61+
const titleContainer = document.getElementById(PLUGIN_TITLE_CONTAINER_ID)
62+
return (
63+
<>
64+
<div ref={devToolRef} />
65+
{pluginContainer && PluginComponent
66+
? createPortal(<>{PluginComponent}</>, pluginContainer)
67+
: null}
68+
{titleContainer && TitleComponent
69+
? createPortal(<>{TitleComponent}</>, titleContainer)
70+
: null}
71+
</>
72+
)
5773
}

0 commit comments

Comments
 (0)