@tanstack/devtools
Version:
TanStack Devtools is a set of tools for building advanced devtools for your application.
132 lines (107 loc) • 3.4 kB
text/typescript
import { createEffect, createMemo, useContext } from 'solid-js'
import { MAX_ACTIVE_PLUGINS } from '../utils/constants.js'
import { DevtoolsContext } from './devtools-context.jsx'
import { useDrawContext } from './draw-context.jsx'
import type { DevtoolsStore } from './devtools-store.js'
/**
* Returns an object containing the current state and setState function of the ShellContext.
* Throws an error if used outside of a ShellContextProvider.
*/
const useDevtoolsContext = () => {
const context = useContext(DevtoolsContext)
if (context === undefined) {
throw new Error(
'useDevtoolsShellContext must be used within a ShellContextProvider',
)
}
return context
}
export function useTheme() {
const { settings, setSettings } = useDevtoolsSettings()
const theme = createMemo(() => settings().theme)
return {
theme,
setTheme: (theme: DevtoolsStore['settings']['theme']) =>
setSettings({ theme }),
}
}
export const usePlugins = () => {
const { store, setStore } = useDevtoolsContext()
const { setForceExpand } = useDrawContext()
const plugins = createMemo(() => store.plugins)
const activePlugins = createMemo(() => store.state.activePlugins)
createEffect(() => {
if (activePlugins().length === 0) {
setForceExpand(true)
} else {
setForceExpand(false)
}
})
const toggleActivePlugins = (pluginId: string) => {
setStore((prev) => {
const isActive = prev.state.activePlugins.includes(pluginId)
const currentPlugin = store.plugins?.find(
(plugin) => plugin.id === pluginId,
)
if (currentPlugin?.destroy && isActive) {
currentPlugin.destroy(pluginId)
}
const updatedPlugins = isActive
? prev.state.activePlugins.filter((id) => id !== pluginId)
: [...prev.state.activePlugins, pluginId]
if (updatedPlugins.length > MAX_ACTIVE_PLUGINS) return prev
return {
...prev,
state: {
...prev.state,
activePlugins: updatedPlugins,
},
}
})
}
return { plugins, toggleActivePlugins, activePlugins }
}
export const useDevtoolsState = () => {
const { store, setStore } = useDevtoolsContext()
const state = createMemo(() => store.state)
const setState = (newState: Partial<DevtoolsStore['state']>) => {
setStore((prev) => ({
...prev,
state: {
...prev.state,
...newState,
},
}))
}
return { state, setState }
}
export const useDevtoolsSettings = () => {
const { store, setStore } = useDevtoolsContext()
const settings = createMemo(() => store.settings)
const setSettings = (newSettings: Partial<DevtoolsStore['settings']>) => {
setStore((prev) => ({
...prev,
settings: {
...prev.settings,
...newSettings,
},
}))
}
return { setSettings, settings }
}
export const usePersistOpen = () => {
const { state, setState } = useDevtoolsState()
const persistOpen = createMemo(() => state().persistOpen)
const setPersistOpen = (value: boolean) => {
setState({ persistOpen: value })
}
return { persistOpen, setPersistOpen }
}
export const useHeight = () => {
const { state, setState } = useDevtoolsState()
const height = createMemo(() => state().height)
const setHeight = (newHeight: number) => {
setState({ height: newHeight })
}
return { height, setHeight }
}