Skip to content

Commit 16131c3

Browse files
authored
fix(devtools): improve devtools a11y (TanStack#2947)
* fix(devtools): improve devtools container a11y default element changes to aside from footer because aside represents a portion of a document whose content is only indirectly related to the document's main content. aria-label is also added to replace the text "generic" in a11y tree. * fix(devtools): add aria to devtools toggle button aria-expanded indicates open/closed of the menu aria-haspopup indicates this is a menu button aria-controls to link to the menu, also added aria-label on the menu to label it. Read more: https://www.w3.org/TR/wai-aria-practices/examples/menu-button/menu-button-links.html * fix(devtools): menuitem are visible in a11y tree in closed devtools This is because the element is just hidden visually, but is still inside the DOM. The added conditional display only affects the inner container, which means the animation of opening/closing is reserved.
1 parent 5285479 commit 16131c3

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

src/devtools/devtools.tsx

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ interface DevtoolsOptions {
5555
/**
5656
* Use this to render the devtools inside a different type of container element for a11y purposes.
5757
* Any string which corresponds to a valid intrinsic JSX element is allowed.
58-
* Defaults to 'footer'.
58+
* Defaults to 'aside'.
5959
*/
6060
containerElement?: string | any
6161
}
@@ -91,7 +91,7 @@ export function ReactQueryDevtools({
9191
closeButtonProps = {},
9292
toggleButtonProps = {},
9393
position = 'bottom-left',
94-
containerElement: Container = 'footer',
94+
containerElement: Container = 'aside',
9595
}: DevtoolsOptions): React.ReactElement | null {
9696
const rootRef = React.useRef<HTMLDivElement>(null)
9797
const panelRef = React.useRef<HTMLDivElement>(null)
@@ -221,7 +221,11 @@ export function ReactQueryDevtools({
221221
if (!isMounted()) return null
222222

223223
return (
224-
<Container ref={rootRef} className="ReactQueryDevtools">
224+
<Container
225+
ref={rootRef}
226+
className="ReactQueryDevtools"
227+
aria-label="React Query Devtools"
228+
>
225229
<ThemeProvider theme={theme}>
226230
<ReactQueryDevtoolsPanel
227231
ref={panelRef as any}
@@ -265,6 +269,9 @@ export function ReactQueryDevtools({
265269
<Button
266270
type="button"
267271
aria-label="Close React Query Devtools"
272+
aria-controls="ReactQueryDevtoolsPanel"
273+
aria-haspopup="true"
274+
aria-expanded="true"
268275
{...(otherCloseButtonProps as unknown)}
269276
onClick={e => {
270277
setIsOpen(false)
@@ -302,6 +309,9 @@ export function ReactQueryDevtools({
302309
type="button"
303310
{...otherToggleButtonProps}
304311
aria-label="Open React Query Devtools"
312+
aria-controls="ReactQueryDevtoolsPanel"
313+
aria-haspopup="true"
314+
aria-expanded="false"
305315
onClick={e => {
306316
setIsOpen(true)
307317
onToggleClick && onToggleClick(e)
@@ -449,7 +459,13 @@ export const ReactQueryDevtoolsPanel = React.forwardRef<
449459

450460
return (
451461
<ThemeProvider theme={theme}>
452-
<Panel ref={ref} className="ReactQueryDevtoolsPanel" {...panelProps}>
462+
<Panel
463+
ref={ref}
464+
className="ReactQueryDevtoolsPanel"
465+
aria-label="React Query Devtools Panel"
466+
id="ReactQueryDevtoolsPanel"
467+
{...panelProps}
468+
>
453469
<style
454470
dangerouslySetInnerHTML={{
455471
__html: `
@@ -494,7 +510,7 @@ export const ReactQueryDevtoolsPanel = React.forwardRef<
494510
maxHeight: '100%',
495511
overflow: 'auto',
496512
borderRight: `1px solid ${theme.grayAlt}`,
497-
display: 'flex',
513+
display: isOpen ? 'flex' : 'none',
498514
flexDirection: 'column',
499515
}}
500516
>

0 commit comments

Comments
 (0)