10efaa921d
* drop `@ts-expect-error`, because `inert` is available now * fix logical error We want to apply `inert` when we _don't_ have nested dialogs, because if we _do_ have nested dialogs, then the inert should be applied from the nested dialog (or visually the top most dialog). * update changelog * replace `useInertOthers` with `useInert` * add `assertInert` and `assertNotInert` accessibility assertion helpers * ensure the `main tree` root is marked as inert As well as the parent dialogs in case of nested dialogs.
142 lines
3.2 KiB
TypeScript
142 lines
3.2 KiB
TypeScript
import React, { ReactNode, useRef, useState } from 'react'
|
|
import { render } from '@testing-library/react'
|
|
import { useInert } from './use-inert'
|
|
import { getByText, assertInert, assertNotInert } from '../test-utils/accessibility-assertions'
|
|
import { click } from '../test-utils/interactions'
|
|
|
|
beforeEach(() => {
|
|
jest.restoreAllMocks()
|
|
jest.spyOn(global.console, 'error').mockImplementation(jest.fn())
|
|
})
|
|
|
|
it('should be possible to inert an element', async () => {
|
|
function Example() {
|
|
let ref = useRef(null)
|
|
let [enabled, setEnabled] = useState(true)
|
|
useInert(ref, enabled)
|
|
|
|
return (
|
|
<div ref={ref} id="main">
|
|
<button onClick={() => setEnabled((v) => !v)}>toggle</button>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function Before() {
|
|
return <div>before</div>
|
|
}
|
|
|
|
function After() {
|
|
return <div>after</div>
|
|
}
|
|
|
|
render(
|
|
<>
|
|
<Before />
|
|
<Example />
|
|
<After />
|
|
</>,
|
|
{ container: document.body }
|
|
)
|
|
|
|
// Verify that `main` is inert
|
|
assertInert(document.getElementById('main'))
|
|
|
|
// Verify that the others are not inert
|
|
assertNotInert(getByText('before'))
|
|
assertNotInert(getByText('after'))
|
|
|
|
// Restore
|
|
await click(getByText('toggle'))
|
|
|
|
// Verify that nothing is inert
|
|
assertNotInert(document.getElementById('main'))
|
|
assertNotInert(getByText('before'))
|
|
assertNotInert(getByText('after'))
|
|
})
|
|
|
|
it('should not mark an element as inert when the hook is disabled', async () => {
|
|
function Example() {
|
|
let ref = useRef(null)
|
|
let [enabled, setEnabled] = useState(false)
|
|
useInert(ref, enabled)
|
|
|
|
return (
|
|
<div ref={ref} id="main">
|
|
<button onClick={() => setEnabled((v) => !v)}>toggle</button>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
function Before() {
|
|
return <div>before</div>
|
|
}
|
|
|
|
function After() {
|
|
return <div>after</div>
|
|
}
|
|
|
|
render(
|
|
<>
|
|
<Before />
|
|
<Example />
|
|
<After />
|
|
</>,
|
|
{ container: document.body }
|
|
)
|
|
|
|
assertNotInert(document.getElementById('main'))
|
|
assertNotInert(getByText('before'))
|
|
assertNotInert(getByText('after'))
|
|
})
|
|
|
|
it('should mark the element as not inert anymore, once all references are gone', async () => {
|
|
function Example({ children }: { children: ReactNode }) {
|
|
let ref = useRef<HTMLDivElement | null>(null)
|
|
|
|
let [enabled, setEnabled] = useState(false)
|
|
useInert(() => ref.current?.parentElement ?? null, enabled)
|
|
|
|
return (
|
|
<div ref={ref}>
|
|
<button onClick={() => setEnabled((v) => !v)}>{children}</button>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
render(
|
|
<div id="parent">
|
|
<Example>A</Example>
|
|
<Example>B</Example>
|
|
</div>,
|
|
{ container: document.body }
|
|
)
|
|
|
|
// Parent should not be inert yet
|
|
assertNotInert(document.getElementById('parent'))
|
|
|
|
// Toggle A
|
|
await click(getByText('A'))
|
|
|
|
// Parent should be inert
|
|
assertInert(document.getElementById('parent'))
|
|
|
|
// Toggle B
|
|
await click(getByText('B'))
|
|
|
|
// Parent should still be inert
|
|
assertInert(document.getElementById('parent'))
|
|
|
|
// Toggle A
|
|
await click(getByText('A'))
|
|
|
|
// Parent should still be inert (because B is still enabled)
|
|
assertInert(document.getElementById('parent'))
|
|
|
|
// Toggle B
|
|
await click(getByText('B'))
|
|
|
|
// Parent should not be inert because both A and B are disabled
|
|
assertNotInert(document.getElementById('parent'))
|
|
})
|