Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FocusTrap] Improve tab test and simplify demo #34008

Merged
merged 3 commits into from Aug 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 2 additions & 8 deletions docs/data/base/components/trap-focus/BasicTrapFocus.js
@@ -1,18 +1,12 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Box from '@mui/system/Box';
import TrapFocus from '@mui/base/TrapFocus';

export default function BasicTrapFocus() {
const [open, setOpen] = React.useState(false);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
<button type="button" onClick={() => setOpen(true)}>
Open
</button>
Expand Down
10 changes: 2 additions & 8 deletions docs/data/base/components/trap-focus/BasicTrapFocus.tsx
@@ -1,18 +1,12 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Box from '@mui/system/Box';
import TrapFocus from '@mui/base/TrapFocus';

export default function BasicTrapFocus() {
const [open, setOpen] = React.useState(false);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
<button type="button" onClick={() => setOpen(true)}>
Open
</button>
Expand Down
@@ -1,33 +1,24 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import Stack from '@mui/system/Stack';
import TrapFocus from '@mui/base/TrapFocus';

export default function BasicTrapFocus() {
export default function ContainedToggleTrappedFocus() {
const [open, setOpen] = React.useState(false);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<React.Fragment>
<TrapFocus open={open} disableRestoreFocus disableAutoFocus>
<Stack>
<Stack alignItems="center">
<button type="button" onClick={() => setOpen(!open)}>
{open ? 'Close' : 'Open'}
</button>
</Stack>
<Stack alignItems="center" spacing={2}>
<button type="button" onClick={() => setOpen(!open)}>
{open ? 'Close' : 'Open'}
</button>
{open && (
<label>
First name: <input type="text" />
</label>
)}
</Stack>
</TrapFocus>
</Box>
</React.Fragment>
);
}
@@ -1,33 +1,24 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import Stack from '@mui/system/Stack';
import TrapFocus from '@mui/base/TrapFocus';

export default function BasicTrapFocus() {
export default function ContainedToggleTrappedFocus() {
const [open, setOpen] = React.useState(false);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<React.Fragment>
<TrapFocus open={open} disableRestoreFocus disableAutoFocus>
<Stack>
<Stack alignItems="center">
<button type="button" onClick={() => setOpen(!open)}>
{open ? 'Close' : 'Open'}
</button>
</Stack>
<Stack alignItems="center" spacing={2}>
<button type="button" onClick={() => setOpen(!open)}>
{open ? 'Close' : 'Open'}
</button>
{open && (
<label>
First name: <input type="text" />
</label>
)}
</Stack>
</TrapFocus>
</Box>
</React.Fragment>
);
}
@@ -1,14 +1,14 @@
<TrapFocus open={open} disableRestoreFocus disableAutoFocus>
<Stack>
<Stack alignItems="center">
<React.Fragment>
<TrapFocus open={open} disableRestoreFocus disableAutoFocus>
<Stack alignItems="center" spacing={2}>
<button type="button" onClick={() => setOpen(!open)}>
{open ? 'Close' : 'Open'}
</button>
{open && (
<label>
First name: <input type="text" />
</label>
)}
</Stack>
{open && (
<label>
First name: <input type="text" />
</label>
)}
</Stack>
</TrapFocus>
</TrapFocus>
</React.Fragment>
10 changes: 2 additions & 8 deletions docs/data/base/components/trap-focus/DisableEnforceFocus.js
@@ -1,18 +1,12 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Box from '@mui/system/Box';
import TrapFocus from '@mui/base/TrapFocus';

export default function DisableEnforceFocus() {
const [open, setOpen] = React.useState(false);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
<button type="button" onClick={() => setOpen(true)}>
Open
</button>
Expand Down
10 changes: 2 additions & 8 deletions docs/data/base/components/trap-focus/DisableEnforceFocus.tsx
@@ -1,18 +1,12 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Box from '@mui/system/Box';
import TrapFocus from '@mui/base/TrapFocus';

export default function DisableEnforceFocus() {
const [open, setOpen] = React.useState(false);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
<button type="button" onClick={() => setOpen(true)}>
Open
</button>
Expand Down
10 changes: 2 additions & 8 deletions docs/data/base/components/trap-focus/LazyTrapFocus.js
@@ -1,18 +1,12 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Box from '@mui/system/Box';
import TrapFocus from '@mui/base/TrapFocus';

export default function LazyTrapFocus() {
const [open, setOpen] = React.useState(false);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
<button type="button" onClick={() => setOpen(true)}>
Open
</button>
Expand Down
10 changes: 2 additions & 8 deletions docs/data/base/components/trap-focus/LazyTrapFocus.tsx
@@ -1,18 +1,12 @@
import * as React from 'react';
import Box from '@mui/material/Box';
import Box from '@mui/system/Box';
import TrapFocus from '@mui/base/TrapFocus';

export default function LazyTrapFocus() {
const [open, setOpen] = React.useState(false);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
<button type="button" onClick={() => setOpen(true)}>
Open
</button>
Expand Down
10 changes: 2 additions & 8 deletions docs/data/base/components/trap-focus/PortalTrapFocus.js
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Box } from '@mui/system';
import Box from '@mui/system/Box';
import Portal from '@mui/base/Portal';
import TrapFocus from '@mui/base/TrapFocus';

Expand All @@ -8,13 +8,7 @@ export default function PortalTrapFocus() {
const [container, setContainer] = React.useState(null);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
<button type="button" onClick={() => setOpen(true)}>
Open
</button>
Expand Down
10 changes: 2 additions & 8 deletions docs/data/base/components/trap-focus/PortalTrapFocus.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Box } from '@mui/system';
import Box from '@mui/system/Box';
import Portal from '@mui/base/Portal';
import TrapFocus from '@mui/base/TrapFocus';

Expand All @@ -8,13 +8,7 @@ export default function PortalTrapFocus() {
const [container, setContainer] = React.useState<HTMLElement | null>(null);

return (
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'column',
}}
>
<Box sx={{ display: 'flex', alignItems: 'center', flexDirection: 'column' }}>
<button type="button" onClick={() => setOpen(true)}>
Open
</button>
Expand Down
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -88,7 +88,6 @@
"@rollup/plugin-replace": "^4.0.0",
"@testing-library/dom": "^8.17.1",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^14.3.0",
"@types/chai": "^4.3.3",
"@types/chai-dom": "^0.0.13",
"@types/enzyme": "^3.10.12",
Expand Down
31 changes: 0 additions & 31 deletions packages/mui-base/src/TrapFocus/TrapFocus.test.js
Expand Up @@ -4,7 +4,6 @@ import { expect } from 'chai';
import { act, createRenderer, screen } from 'test/utils';
import TrapFocus from '@mui/base/TrapFocus';
import Portal from '@mui/base/Portal';
import userEvent from '@testing-library/user-event';

describe('<TrapFocus />', () => {
const { clock, render } = createRenderer();
Expand Down Expand Up @@ -284,36 +283,6 @@ describe('<TrapFocus />', () => {
expect(screen.getByTestId('root')).toHaveFocus();
});

it('does not create any tabbable elements when open={false}', () => {
function Test(props) {
return (
<div>
<button autoFocus data-testid="initial-focus">
Test
</button>
<TrapFocus open={false} {...props}>
<div tabIndex={-1}>
<button data-testid="inside-focus">Test</button>
</div>
</TrapFocus>
<button data-testid="end-focus">Test</button>
</div>
);
}

render(<Test />);

expect(screen.getByTestId('initial-focus')).toHaveFocus();
act(() => {
userEvent.tab();
});
expect(screen.getByTestId('inside-focus')).toHaveFocus();
act(() => {
userEvent.tab();
});
expect(screen.getByTestId('end-focus')).toHaveFocus();
});

describe('interval', () => {
clock.withFakeTimers();

Expand Down
18 changes: 18 additions & 0 deletions test/e2e/fixtures/TrapFocus/ClosedTrapFocus.tsx
@@ -0,0 +1,18 @@
import * as React from 'react';
import TrapFocus from '@mui/base/TrapFocus';

export default function ClosedTrapFocus() {
return (
<React.Fragment>
<button type="button" autoFocus>
initial focus
</button>
<TrapFocus open={false}>
<div data-testid="root">
<button type="button">inside focusable</button>
</div>
</TrapFocus>
<button type="button">final tab target</button>
</React.Fragment>
);
}
10 changes: 10 additions & 0 deletions test/e2e/index.test.ts
Expand Up @@ -162,6 +162,16 @@ describe('e2e', () => {
await page.keyboard.press('Tab');
await expect(screen.getByText('ok')).toHaveFocus();
});

it('should be able to be tabbed straight through when rendered closed', async () => {
await renderFixture('TrapFocus/ClosedTrapFocus');

await expect(screen.getByText('initial focus')).toHaveFocus();
await page.keyboard.press('Tab');
await expect(screen.getByText('inside focusable')).toHaveFocus();
await page.keyboard.press('Tab');
await expect(screen.getByText('final tab target')).toHaveFocus();
});
});

describe('<Rating />', () => {
Expand Down
5 changes: 0 additions & 5 deletions yarn.lock
Expand Up @@ -3167,11 +3167,6 @@
"@testing-library/dom" "^8.5.0"
"@types/react-dom" "^18.0.0"

"@testing-library/user-event@^14.3.0":
version "14.3.0"
resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.3.0.tgz#0a6750b94b40e4739706d41e8efc2ccf64d2aad9"
integrity sha512-P02xtBBa8yMaLhK8CzJCIns8rqwnF6FxhR9zs810flHOBXUYCFjLd8Io1rQrAkQRWEmW2PGdZIEdMxf/KLsqFA==

"@theme-ui/color-modes@0.14.7":
version "0.14.7"
resolved "https://registry.yarnpkg.com/@theme-ui/color-modes/-/color-modes-0.14.7.tgz#6f93bf4d0890ffe3386df311663eaee9bea40796"
Expand Down