refactor(web): focus trap (#10915)

This commit is contained in:
Michel Heusschen
2024-07-08 03:33:07 +02:00
committed by GitHub
parent 39221c8d1f
commit cb40db9555
7 changed files with 407 additions and 365 deletions
@@ -0,0 +1,18 @@
<script lang="ts">
import { focusTrap } from '$lib/actions/focus-trap';
export let show: boolean;
</script>
<button type="button" on:click={() => (show = true)}>Open</button>
{#if show}
<div use:focusTrap>
<div>
<span>text</span>
<button data-testid="one" type="button" on:click={() => (show = false)}>Close</button>
</div>
<input data-testid="two" disabled />
<input data-testid="three" />
</div>
{/if}
@@ -0,0 +1,40 @@
import FocusTrapTest from '$lib/actions/__test__/focus-trap-test.svelte';
import { render, screen } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';
import { tick } from 'svelte';
describe('focusTrap action', () => {
const user = userEvent.setup();
it('sets focus to the first focusable element', () => {
render(FocusTrapTest, { show: true });
expect(document.activeElement).toEqual(screen.getByTestId('one'));
});
it('supports backward focus wrapping', async () => {
render(FocusTrapTest, { show: true });
await user.keyboard('{Shift>}{Tab}{/Shift}');
expect(document.activeElement).toEqual(screen.getByTestId('three'));
});
it('supports forward focus wrapping', async () => {
render(FocusTrapTest, { show: true });
screen.getByTestId('three').focus();
await user.keyboard('{Tab}');
expect(document.activeElement).toEqual(screen.getByTestId('one'));
});
it('restores focus to the triggering element', async () => {
render(FocusTrapTest, { show: false });
const openButton = screen.getByText('Open');
openButton.focus();
openButton.click();
await tick();
expect(document.activeElement).toEqual(screen.getByTestId('one'));
screen.getByText('Close').click();
await tick();
expect(document.activeElement).toEqual(openButton);
});
});