Skip to content

Commit 9aed040

Browse files
authored
fix(devtools): Hide devtools when closed, prevent focus (TanStack#2376)
1 parent 29559b1 commit 9aed040

File tree

1 file changed

+35
-1
lines changed

1 file changed

+35
-1
lines changed

src/devtools/devtools.tsx

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,33 @@ export function ReactQueryDevtools({
133133
setIsResolvedOpen(isOpen)
134134
}, [isOpen, isResolvedOpen, setIsResolvedOpen])
135135

136+
// Toggle panel visibility before/after transition (depending on direction).
137+
// Prevents focusing in a closed panel.
138+
React.useEffect(() => {
139+
const ref = panelRef.current
140+
if (ref) {
141+
function handlePanelTransitionStart() {
142+
if (ref && isResolvedOpen) {
143+
ref.style.visibility = 'visible'
144+
}
145+
}
146+
147+
function handlePanelTransitionEnd() {
148+
if (ref && !isResolvedOpen) {
149+
ref.style.visibility = 'hidden'
150+
}
151+
}
152+
153+
ref.addEventListener('transitionstart', handlePanelTransitionStart)
154+
ref.addEventListener('transitionend', handlePanelTransitionEnd)
155+
156+
return () => {
157+
ref.removeEventListener('transitionstart', handlePanelTransitionStart)
158+
ref.removeEventListener('transitionend', handlePanelTransitionEnd)
159+
}
160+
}
161+
}, [isResolvedOpen])
162+
136163
React[isServer ? 'useEffect' : 'useLayoutEffect'](() => {
137164
if (isResolvedOpen) {
138165
const previousValue = rootRef.current?.parentElement.style.paddingBottom
@@ -186,6 +213,8 @@ export function ReactQueryDevtools({
186213
boxShadow: '0 0 20px rgba(0,0,0,.3)',
187214
borderTop: `1px solid ${theme.gray}`,
188215
transformOrigin: 'top',
216+
// visibility will be toggled after transitions, but set initial state here
217+
visibility: isOpen ? 'visible' : 'hidden',
189218
...panelStyle,
190219
...(isResizing
191220
? {
@@ -378,9 +407,14 @@ export const ReactQueryDevtoolsPanel = React.forwardRef(
378407

379408
React.useEffect(() => {
380409
if (isOpen) {
381-
return queryCache.subscribe(() => {
410+
const unsubscribe = queryCache.subscribe(() => {
382411
setUnsortedQueries(Object.values(queryCache.getAll()))
383412
})
413+
// re-subscribing after the panel is closed and re-opened won't trigger the callback,
414+
// So we'll manually populate our state
415+
setUnsortedQueries(Object.values(queryCache.getAll()))
416+
417+
return unsubscribe
384418
}
385419
return undefined
386420
}, [isOpen, sort, sortFn, sortDesc, setUnsortedQueries, queryCache])

0 commit comments

Comments
 (0)