-
-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathpanel.tsx
More file actions
55 lines (48 loc) · 1.71 KB
/
panel.tsx
File metadata and controls
55 lines (48 loc) · 1.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { useEffect, useRef } from 'react'
export interface DevtoolsPanelProps {
theme?: 'light' | 'dark'
}
/**
* Creates a React component that dynamically imports and mounts a devtools panel. SSR friendly.
* @param devtoolsPackageName The name of the devtools package to be imported, e.g., '@tanstack/devtools-react'
* @param importName The name of the export to be imported from the devtools package (e.g., 'default' or 'DevtoolsCore')
* @returns A React component that mounts the devtools
* @example
* ```tsx
* // if the export is default
* const [ReactDevtoolsPanel, NoOpReactDevtoolsPanel] = createReactPanel('@tanstack/devtools-react')
* ```
*
* @example
* ```tsx
* // if the export is named differently
* const [ReactDevtoolsPanel, NoOpReactDevtoolsPanel] = createReactPanel('@tanstack/devtools-react', 'DevtoolsCore')
* ```
*/
export function createReactPanel<
TComponentProps extends DevtoolsPanelProps | undefined,
TCoreDevtoolsClass extends {
mount: (el: HTMLElement, theme: 'light' | 'dark') => void
unmount: () => void
},
>(CoreClass: new () => TCoreDevtoolsClass) {
function Panel(props: TComponentProps) {
const devToolRef = useRef<HTMLDivElement>(null)
const devtools = useRef<TCoreDevtoolsClass | null>(null)
useEffect(() => {
if (devtools.current) return
devtools.current = new CoreClass()
if (devToolRef.current) {
devtools.current.mount(devToolRef.current, props?.theme ?? 'dark')
}
return () => {
devtools.current?.unmount()
}
}, [props?.theme])
return <div style={{ height: '100%' }} ref={devToolRef} />
}
function NoOpPanel(_props: TComponentProps) {
return <></>
}
return [Panel, NoOpPanel] as const
}