diff --git a/docs/config.json b/docs/config.json index 89eb47fd2a..3e77bad407 100644 --- a/docs/config.json +++ b/docs/config.json @@ -929,6 +929,10 @@ { "label": "Shadow DOM", "to": "framework/react/examples/shadow-dom" + }, + { + "label": "Devtools Embedded Panel", + "to": "framework/react/examples/devtools-panel" } ] }, diff --git a/docs/framework/react/devtools.md b/docs/framework/react/devtools.md index ca04fa9110..d97d589749 100644 --- a/docs/framework/react/devtools.md +++ b/docs/framework/react/devtools.md @@ -83,7 +83,7 @@ function App() { - The position of the React Query devtools panel - `client?: QueryClient`, - Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used. -- `errorTypes?: { name: string; initializer: (query: Query) => TError}` +- `errorTypes?: { name: string; initializer: (query: Query) => TError}[]` - Use this to predefine some errors that can be triggered on your queries. Initializer will be called (with the specific query) when that error is toggled on from the UI. It must return an Error. - `styleNonce?: string` - Use this to pass a nonce to the style tag that is added to the document head. This is useful if you are using a Content Security Policy (CSP) nonce to allow inline styles. @@ -106,8 +106,10 @@ function App() { return ( {/* The rest of your application */} - - + + {isOpen && setIsOpen(false)}/>} ) } @@ -115,14 +117,16 @@ function App() { ### Options -- `isOpen: Boolean` - - Defaults to `false` -- `position?: "top" | "bottom" | "left" | "right"` - - Defaults to `bottom` - - The position of the React Query devtools panel +- `style?: React.CSSProperties` + - Custom styles for the devtools panel + - Default: `{ height: '500px' }` + - Example: `{ height: '100%' }` + - Example: `{ height: '100%', width: '100%' }` +- `onClose?: () => unknown` + - Callback function that is called when the devtools panel is closed - `client?: QueryClient`, - Use this to use a custom QueryClient. Otherwise, the one from the nearest context will be used. -- `errorTypes?: { name: string; initializer: (query: Query) => TError}` +- `errorTypes?: { name: string; initializer: (query: Query) => TError}[]` - Use this to predefine some errors that can be triggered on your queries. Initializer will be called (with the specific query) when that error is toggled on from the UI. It must return an Error. - `styleNonce?: string` - Use this to pass a nonce to the style tag that is added to the document head. This is useful if you are using a Content Security Policy (CSP) nonce to allow inline styles. diff --git a/examples/react/devtools-panel/package.json b/examples/react/devtools-panel/package.json index edbc385dca..f6614ffe28 100644 --- a/examples/react/devtools-panel/package.json +++ b/examples/react/devtools-panel/package.json @@ -8,8 +8,8 @@ "preview": "vite preview" }, "dependencies": { - "@tanstack/react-query": "^5.52.0", - "@tanstack/react-query-devtools": "^5.52.0", + "@tanstack/react-query": "^5.53.2", + "@tanstack/react-query-devtools": "^5.53.2", "react": "19.0.0-rc-4c2e457c7c-20240522", "react-dom": "19.0.0-rc-4c2e457c7c-20240522" }, diff --git a/examples/react/devtools-panel/src/index.tsx b/examples/react/devtools-panel/src/index.tsx index 6b564baad5..5931d36e8d 100644 --- a/examples/react/devtools-panel/src/index.tsx +++ b/examples/react/devtools-panel/src/index.tsx @@ -14,15 +14,17 @@ export default function App() { return ( - - - + + + {isOpen && setIsOpen(false)}/>} ) } function Example() { - const { isPending, error, data, isFetching } = useQuery({ + const {isPending, error, data, isFetching} = useQuery({ queryKey: ['repoData'], queryFn: async () => { const response = await fetch( @@ -37,7 +39,11 @@ function Example() { if (error) return 'An error has occurred: ' + error.message return ( -
+

{data.full_name}

{data.description}

👀 {data.subscribers_count}{' '} diff --git a/packages/query-devtools/src/Devtools.tsx b/packages/query-devtools/src/Devtools.tsx index 54e8a80a2e..bef2d2c609 100644 --- a/packages/query-devtools/src/Devtools.tsx +++ b/packages/query-devtools/src/Devtools.tsx @@ -5,7 +5,6 @@ import { createEffect, createMemo, createSignal, - mergeProps, on, onCleanup, onMount, @@ -52,15 +51,24 @@ import { XCircle, } from './icons' import Explorer from './Explorer' +import { usePiPWindow, useQueryDevtoolsContext, useTheme } from './contexts' import { - usePiPWindow, - useQueryDevtoolsContext, - useTheme, -} from './contexts' + BUTTON_POSITION, + DEFAULT_HEIGHT, + DEFAULT_MUTATION_SORT_FN_NAME, + DEFAULT_SORT_FN_NAME, + DEFAULT_SORT_ORDER, + DEFAULT_WIDTH, + INITIAL_IS_OPEN, + POSITION, + firstBreakpoint, + secondBreakpoint, + thirdBreakpoint, +} from './constants' import type { - DevtoolsButtonPosition, DevtoolsErrorType, DevtoolsPosition, + QueryDevtoolsProps, } from './contexts' import type { Mutation, @@ -76,11 +84,13 @@ import type { Accessor, Component, JSX, Setter } from 'solid-js' interface DevtoolsPanelProps { localStore: StorageObject setLocalStore: StorageSetter - withCloseButton?: boolean - withOpenButton?: boolean - withDragPositionPanel?: boolean - withPIPButton?: boolean - withPositionButton?: boolean +} + +interface ContentViewProps { + localStore: StorageObject + setLocalStore: StorageSetter + showPanelViewOnly?: boolean + onClose?: () => unknown } interface QueryStatusProps { @@ -89,20 +99,6 @@ interface QueryStatusProps { count: number } -const firstBreakpoint = 1024 -const secondBreakpoint = 796 -const thirdBreakpoint = 700 - -const BUTTON_POSITION: DevtoolsButtonPosition = 'bottom-right' -const POSITION: DevtoolsPosition = 'bottom' -export const THEME_PREFERENCE = 'system' -const INITIAL_IS_OPEN = false -const DEFAULT_HEIGHT = 500 -const DEFAULT_WIDTH = 500 -const DEFAULT_SORT_FN_NAME = Object.keys(sortFns)[0] -const DEFAULT_SORT_ORDER = 1 -const DEFAULT_MUTATION_SORT_FN_NAME = Object.keys(mutationSortFns)[0] - const [selectedQueryHash, setSelectedQueryHash] = createSignal( null, ) @@ -112,14 +108,11 @@ const [selectedMutationId, setSelectedMutationId] = createSignal( const [panelWidth, setPanelWidth] = createSignal(0) const [offline, setOffline] = createSignal(false) -export const Devtools: Component = (_props) => { - const props = mergeProps({ - withCloseButton: true, - withOpenButton: true, - withDragPositionPanel: true, - withPIPButton: true, - withPositionButton: true - }, _props) +export type DevtoolsComponentType = Component & { + shadowDOMTarget?: ShadowRoot +} + +export const Devtools: Component = (props) => { const theme = useTheme() const css = useQueryDevtoolsContext().shadowDOMTarget ? goober.css.bind({ target: useQueryDevtoolsContext().shadowDOMTarget }) @@ -245,11 +238,14 @@ export const Devtools: Component = (_props) => { > - + - +
= (props) => { +export const ParentPanel: Component<{ + children: JSX.Element +}> = (props) => { + const theme = useTheme() + const css = useQueryDevtoolsContext().shadowDOMTarget + ? goober.css.bind({ target: useQueryDevtoolsContext().shadowDOMTarget }) + : goober.css + const styles = createMemo(() => { + return theme() === 'dark' ? darkStyles(css) : lightStyles(css) + }) + + let panelRef!: HTMLDivElement + + onMount(() => { + createResizeObserver(panelRef, ({ width }, el) => { + if (el === panelRef) { + setPanelWidth(width) + } + }) + }) + + const getPanelDynamicStyles = () => { + const { colors } = tokens + const t = (light: string, dark: string) => + theme() === 'dark' ? dark : light + if (panelWidth() < secondBreakpoint) { + return css` + flex-direction: column; + background-color: ${t(colors.gray[300], colors.gray[600])}; + ` + } + return css` + flex-direction: row; + background-color: ${t(colors.gray[200], colors.darkGray[900])}; + ` + } + + return ( +
+ {props.children} +
+ ) +} + +const DraggablePanel: Component = (props) => { const theme = useTheme() const css = useQueryDevtoolsContext().shadowDOMTarget ? goober.css.bind({ target: useQueryDevtoolsContext().shadowDOMTarget }) @@ -519,35 +574,31 @@ const DevtoolsPanel: Component = (props) => { ref={panelRef} aria-label="Tanstack query devtools" > - -
-
- - - +
+ ) } -const ContentView: Component = (props) => { +export const ContentView: Component = (props) => { setupQueryCacheSubscription() setupMutationCacheSubscription() let containerRef!: HTMLDivElement @@ -698,8 +749,12 @@ const ContentView: Component = (props) => { - +
- + = (props) => { return false } } - if (panelWidth() < thirdBreakpoint) { + if (panelWidth() < secondBreakpoint) { return false } @@ -2403,6 +2458,32 @@ const stylesFactory = ( background: ${t(colors.gray[400], colors.darkGray[300])}; } `, + parentPanel: css` + z-index: 9999; + display: flex; + height: 100%; + gap: ${tokens.size[0.5]}; + & * { + box-sizing: border-box; + text-transform: none; + } + + & *::-webkit-scrollbar { + width: 7px; + } + + & *::-webkit-scrollbar-track { + background: transparent; + } + + & *::-webkit-scrollbar-thumb { + background: ${t(colors.gray[300], colors.darkGray[200])}; + } + + & *::-webkit-scrollbar-thumb:hover { + background: ${t(colors.gray[400], colors.darkGray[300])}; + } + `, 'devtoolsBtn-position-bottom-right': css` bottom: 12px; right: 12px; diff --git a/packages/query-devtools/src/DevtoolsComponent.tsx b/packages/query-devtools/src/DevtoolsComponent.tsx index 2ed76fd0db..45d93204e0 100644 --- a/packages/query-devtools/src/DevtoolsComponent.tsx +++ b/packages/query-devtools/src/DevtoolsComponent.tsx @@ -1,18 +1,10 @@ import { createLocalStorage } from '@solid-primitives/storage' import { createMemo } from 'solid-js' +import { Devtools } from './Devtools' import { getPreferredColorScheme } from './utils' -import { - PiPProvider, - QueryDevtoolsContext, - QueryDevtoolsProps, - ThemeContext, -} from './contexts' -import { Devtools, THEME_PREFERENCE } from './Devtools' -import type { Component } from 'solid-js' - -export type DevtoolsComponentType = Component> & { - shadowDOMTarget?: ShadowRoot -} +import { THEME_PREFERENCE } from './constants' +import { PiPProvider, QueryDevtoolsContext, ThemeContext } from './contexts' +import type { DevtoolsComponentType } from './Devtools' const DevtoolsComponent: DevtoolsComponentType = (props) => { const [localStore, setLocalStore] = createLocalStorage({ @@ -40,4 +32,5 @@ const DevtoolsComponent: DevtoolsComponentType = (props) => { ) } + export default DevtoolsComponent diff --git a/packages/query-devtools/src/DevtoolsPanelComponent.tsx b/packages/query-devtools/src/DevtoolsPanelComponent.tsx index f704c165c5..eb3d19e4d9 100644 --- a/packages/query-devtools/src/DevtoolsPanelComponent.tsx +++ b/packages/query-devtools/src/DevtoolsPanelComponent.tsx @@ -1,20 +1,12 @@ import { createLocalStorage } from '@solid-primitives/storage' import { createMemo } from 'solid-js' +import { ContentView, ParentPanel } from './Devtools' import { getPreferredColorScheme } from './utils' -import { - PiPProvider, - QueryDevtoolsContext, - QueryDevtoolsProps, - ThemeContext, -} from './contexts' -import { Devtools, THEME_PREFERENCE } from './Devtools' -import type { Component } from 'solid-js' +import { THEME_PREFERENCE } from './constants' +import { PiPProvider, QueryDevtoolsContext, ThemeContext } from './contexts' +import type { DevtoolsComponentType } from './Devtools' -export type DevtoolsPanelComponentType = Component> & { - shadowDOMTarget?: ShadowRoot -} - -const DevtoolsPanelComponent: DevtoolsPanelComponentType = (props) => { +const DevtoolsPanelComponent: DevtoolsComponentType = (props) => { const [localStore, setLocalStore] = createLocalStorage({ prefix: 'TanstackQueryDevtools', }) @@ -32,20 +24,24 @@ const DevtoolsPanelComponent: DevtoolsPanelComponentType = (props) => { return ( - + - + + + ) } + export default DevtoolsPanelComponent diff --git a/packages/query-devtools/src/TanstackQueryDevtools.tsx b/packages/query-devtools/src/TanstackQueryDevtools.tsx index 046e0ad1fd..4b14c083f2 100644 --- a/packages/query-devtools/src/TanstackQueryDevtools.tsx +++ b/packages/query-devtools/src/TanstackQueryDevtools.tsx @@ -5,7 +5,7 @@ import type { QueryClient, onlineManager as TOnlineManager, } from '@tanstack/query-core' -import type { DevtoolsComponentType } from './DevtoolsComponent' +import type { DevtoolsComponentType } from './Devtools' import type { DevtoolsButtonPosition, DevtoolsErrorType, diff --git a/packages/query-devtools/src/TanstackQueryDevtoolsPanel.tsx b/packages/query-devtools/src/TanstackQueryDevtoolsPanel.tsx index 58304bebf2..bf26198854 100644 --- a/packages/query-devtools/src/TanstackQueryDevtoolsPanel.tsx +++ b/packages/query-devtools/src/TanstackQueryDevtoolsPanel.tsx @@ -1,17 +1,23 @@ -import type { Signal } from 'solid-js' -import { createSignal, lazy } from 'solid-js' import { render } from 'solid-js/web' +import { createSignal, lazy } from 'solid-js' +import { setupStyleSheet } from './utils' import type { QueryClient, onlineManager as TOnlineManager, } from '@tanstack/query-core' -import type { DevtoolsErrorType, DevtoolsPosition, QueryDevtoolsProps } from './contexts' -import type { DevtoolsPanelComponentType } from './DevtoolsPanelComponent' -import { setupStyleSheet } from './utils' +import type { DevtoolsComponentType } from './Devtools' +import type { + DevtoolsButtonPosition, + DevtoolsErrorType, + DevtoolsPosition, + QueryDevtoolsProps, +} from './contexts' +import type { Signal } from 'solid-js' -export interface TanstackQueryDevtoolsPanelConfig extends Omit { +export interface TanstackQueryDevtoolsPanelConfig extends QueryDevtoolsProps { styleNonce?: string shadowDOMTarget?: ShadowRoot + onClose?: () => unknown } class TanstackQueryDevtoolsPanel { @@ -22,10 +28,12 @@ class TanstackQueryDevtoolsPanel { #isMounted = false #styleNonce?: string #shadowDOMTarget?: ShadowRoot + #buttonPosition: Signal #position: Signal - #isOpen: Signal + #initialIsOpen: Signal #errorTypes: Signal | undefined> - #Component: DevtoolsPanelComponentType | undefined + #onClose: Signal<(() => unknown) | undefined> + #Component: DevtoolsComponentType | undefined #dispose?: () => void constructor(config: TanstackQueryDevtoolsPanelConfig) { @@ -34,11 +42,13 @@ class TanstackQueryDevtoolsPanel { queryFlavor, version, onlineManager, + buttonPosition, position, - isOpen, + initialIsOpen, errorTypes, styleNonce, shadowDOMTarget, + onClose, } = config this.#client = createSignal(client) this.#queryFlavor = queryFlavor @@ -46,17 +56,23 @@ class TanstackQueryDevtoolsPanel { this.#onlineManager = onlineManager this.#styleNonce = styleNonce this.#shadowDOMTarget = shadowDOMTarget + this.#buttonPosition = createSignal(buttonPosition) this.#position = createSignal(position) - this.#isOpen = createSignal(isOpen) + this.#initialIsOpen = createSignal(initialIsOpen) this.#errorTypes = createSignal(errorTypes) + this.#onClose = createSignal(onClose) + } + + setButtonPosition(position: DevtoolsButtonPosition) { + this.#buttonPosition[1](position) } setPosition(position: DevtoolsPosition) { this.#position[1](position) } - setIsOpen(isOpen: boolean) { - this.#isOpen[1](isOpen) + setInitialIsOpen(isOpen: boolean) { + this.#initialIsOpen[1](isOpen) } setErrorTypes(errorTypes: Array) { @@ -67,16 +83,22 @@ class TanstackQueryDevtoolsPanel { this.#client[1](client) } + setOnClose(onClose: () => unknown) { + this.#onClose[1](() => onClose) + } + mount(el: T) { if (this.#isMounted) { - throw new Error('DevtoolsPanel is already mounted') + throw new Error('Devtools is already mounted') } const dispose = render(() => { + const [btnPosition] = this.#buttonPosition const [pos] = this.#position - const [isOpen] = this.#isOpen + const [isOpen] = this.#initialIsOpen const [errors] = this.#errorTypes const [queryClient] = this.#client - let Devtools: DevtoolsPanelComponentType + const [onClose] = this.#onClose + let Devtools: DevtoolsComponentType if (this.#Component) { Devtools = this.#Component @@ -96,15 +118,21 @@ class TanstackQueryDevtoolsPanel { get client() { return queryClient() }, + get buttonPosition() { + return btnPosition() + }, get position() { return pos() }, - get isOpen() { + get initialIsOpen() { return isOpen() }, get errorTypes() { return errors() }, + get onClose() { + return onClose() + }, }} /> ) @@ -115,7 +143,7 @@ class TanstackQueryDevtoolsPanel { unmount() { if (!this.#isMounted) { - throw new Error('DevtoolsPanel is not mounted') + throw new Error('Devtools is not mounted') } this.#dispose?.() this.#isMounted = false diff --git a/packages/query-devtools/src/constants.ts b/packages/query-devtools/src/constants.ts new file mode 100644 index 0000000000..b4c0c22506 --- /dev/null +++ b/packages/query-devtools/src/constants.ts @@ -0,0 +1,17 @@ +import { mutationSortFns, sortFns } from './utils' +import type { DevtoolsButtonPosition, DevtoolsPosition } from './contexts' + +export const firstBreakpoint = 1024 +export const secondBreakpoint = 796 +export const thirdBreakpoint = 700 + +export const BUTTON_POSITION: DevtoolsButtonPosition = 'bottom-right' +export const POSITION: DevtoolsPosition = 'bottom' +export const THEME_PREFERENCE = 'system' +export const INITIAL_IS_OPEN = false +export const DEFAULT_HEIGHT = 500 +export const PIP_DEFAULT_HEIGHT = 500 +export const DEFAULT_WIDTH = 500 +export const DEFAULT_SORT_FN_NAME = Object.keys(sortFns)[0] +export const DEFAULT_SORT_ORDER = 1 +export const DEFAULT_MUTATION_SORT_FN_NAME = Object.keys(mutationSortFns)[0] diff --git a/packages/query-devtools/src/contexts/PiPContext.tsx b/packages/query-devtools/src/contexts/PiPContext.tsx index 995ddb2966..378f469738 100644 --- a/packages/query-devtools/src/contexts/PiPContext.tsx +++ b/packages/query-devtools/src/contexts/PiPContext.tsx @@ -1,21 +1,29 @@ +import { + createContext, + createEffect, + createMemo, + createSignal, + onCleanup, + useContext, +} from 'solid-js' +import { clearDelegatedEvents, delegateEvents } from 'solid-js/web' +import { PIP_DEFAULT_HEIGHT } from '../constants' +import { useQueryDevtoolsContext } from './QueryDevtoolsContext' +import type { Accessor, JSX } from 'solid-js' import type { StorageObject, StorageSetter } from '@solid-primitives/storage' -import type {Accessor, JSX} from 'solid-js'; -import {createContext, createEffect, createMemo, createSignal, onCleanup, useContext} from 'solid-js'; -import {clearDelegatedEvents, delegateEvents} from 'solid-js/web'; -import {useQueryDevtoolsContext} from './QueryDevtoolsContext'; - -const DEFAULT_HEIGHT = 500 interface PiPProviderProps { children: JSX.Element localStore: StorageObject setLocalStore: StorageSetter + disabled?: boolean } type PiPContextType = { pipWindow: Window | null - requestPipWindow: (width: number, height: number) => Promise + requestPipWindow: (width: number, height: number) => void closePipWindow: () => void + disabled: boolean } const PiPContext = createContext | undefined>( @@ -36,7 +44,7 @@ export const PiPProvider = (props: PiPProviderProps) => { } // Open new pipWindow - const requestPipWindow = async (width: number, height: number) => { + const requestPipWindow = (width: number, height: number) => { // We don't want to allow multiple requests. if (pipWindow() != null) { return @@ -125,10 +133,10 @@ export const PiPProvider = (props: PiPProviderProps) => { createEffect(() => { const pip_open = (props.localStore.pip_open ?? 'false') as 'true' | 'false' - if (pip_open === 'true') { + if (pip_open === 'true' && !props.disabled) { requestPipWindow( Number(window.innerWidth), - Number(props.localStore.height || DEFAULT_HEIGHT), + Number(props.localStore.height || PIP_DEFAULT_HEIGHT), ) } }) @@ -163,6 +171,7 @@ export const PiPProvider = (props: PiPProviderProps) => { pipWindow: pipWindow(), requestPipWindow, closePipWindow, + disabled: props.disabled ?? false, })) return ( diff --git a/packages/query-devtools/src/contexts/QueryDevtoolsContext.ts b/packages/query-devtools/src/contexts/QueryDevtoolsContext.ts index a2a1573a39..ff57105a04 100644 --- a/packages/query-devtools/src/contexts/QueryDevtoolsContext.ts +++ b/packages/query-devtools/src/contexts/QueryDevtoolsContext.ts @@ -29,6 +29,7 @@ export interface QueryDevtoolsProps { isOpen?: boolean errorTypes?: Array shadowDOMTarget?: ShadowRoot + onClose?: () => unknown } export const QueryDevtoolsContext = createContext({ diff --git a/packages/react-query-devtools/src/ReactQueryDevtoolsPanel.tsx b/packages/react-query-devtools/src/ReactQueryDevtoolsPanel.tsx index a8c9f105d6..86afd0ba85 100644 --- a/packages/react-query-devtools/src/ReactQueryDevtoolsPanel.tsx +++ b/packages/react-query-devtools/src/ReactQueryDevtoolsPanel.tsx @@ -2,20 +2,10 @@ import * as React from 'react' import { onlineManager, useQueryClient } from '@tanstack/react-query' import { TanstackQueryDevtoolsPanel } from '@tanstack/query-devtools' -import type { DevtoolsErrorType, DevtoolsPosition } from '@tanstack/query-devtools' +import type { DevtoolsErrorType } from '@tanstack/query-devtools' import type { QueryClient } from '@tanstack/react-query' export interface DevtoolsPanelOptions { - /** - * Set this true if you want the dev tools to be open - */ - isOpen?: boolean - /** - * The position of the React Query devtools panel. - * 'top' | 'bottom' | 'left' | 'right' - * Defaults to 'bottom'. - */ - position?: DevtoolsPosition /** * Custom instance of QueryClient */ @@ -32,6 +22,19 @@ export interface DevtoolsPanelOptions { * Use this so you can attach the devtool's styles to specific element in the DOM. */ shadowDOMTarget?: ShadowRoot + + /** + * Custom styles for the devtools panel + * @default { height: '500px' } + * @example { height: '100%' } + * @example { height: '100%', width: '100%' } + */ + style?: React.CSSProperties + + /** + * Callback function that is called when the devtools panel is closed + */ + onClose?: () => unknown } export function ReactQueryDevtoolsPanel( @@ -39,24 +42,20 @@ export function ReactQueryDevtoolsPanel( ): React.ReactElement | null { const queryClient = useQueryClient(props.client) const ref = React.useRef(null) - const { - position, - isOpen, - errorTypes, - styleNonce, - shadowDOMTarget, - } = props + const { errorTypes, styleNonce, shadowDOMTarget } = props const [devtools] = React.useState( new TanstackQueryDevtoolsPanel({ client: queryClient, queryFlavor: 'React Query', version: '5', onlineManager, - position, - isOpen, + buttonPosition: 'bottom-left', + position: 'bottom', + initialIsOpen: true, errorTypes, styleNonce, shadowDOMTarget, + onClose: props.onClose, }), ) @@ -65,14 +64,8 @@ export function ReactQueryDevtoolsPanel( }, [queryClient, devtools]) React.useEffect(() => { - if (position) { - devtools.setPosition(position) - } - }, [position, devtools]) - - React.useEffect(() => { - devtools.setIsOpen(isOpen || false) - }, [isOpen, devtools]) + devtools.setOnClose(props.onClose ?? (() => {})) + }, [props.onClose, devtools]) React.useEffect(() => { devtools.setErrorTypes(errorTypes || []) @@ -88,5 +81,11 @@ export function ReactQueryDevtoolsPanel( } }, [devtools]) - return
+ return ( +
+ ) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0dff47b997..5d23ac0e61 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -481,10 +481,10 @@ importers: examples/react/devtools-panel: dependencies: '@tanstack/react-query': - specifier: ^5.52.0 + specifier: ^5.53.2 version: link:../../../packages/react-query '@tanstack/react-query-devtools': - specifier: ^5.52.0 + specifier: ^5.53.2 version: link:../../../packages/react-query-devtools react: specifier: 19.0.0-rc-4c2e457c7c-20240522