mirror of
https://github.com/immich-app/immich.git
synced 2025-01-16 16:56:46 +01:00
fix(web): focus trap inside portal (#11797)
* fix(web): focus trap inside portal * fix tests
This commit is contained in:
parent
f7bfde6a32
commit
fa64277476
2 changed files with 9 additions and 5 deletions
|
@ -6,19 +6,22 @@ import { tick } from 'svelte';
|
||||||
describe('focusTrap action', () => {
|
describe('focusTrap action', () => {
|
||||||
const user = userEvent.setup();
|
const user = userEvent.setup();
|
||||||
|
|
||||||
it('sets focus to the first focusable element', () => {
|
it('sets focus to the first focusable element', async () => {
|
||||||
render(FocusTrapTest, { show: true });
|
render(FocusTrapTest, { show: true });
|
||||||
|
await tick();
|
||||||
expect(document.activeElement).toEqual(screen.getByTestId('one'));
|
expect(document.activeElement).toEqual(screen.getByTestId('one'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports backward focus wrapping', async () => {
|
it('supports backward focus wrapping', async () => {
|
||||||
render(FocusTrapTest, { show: true });
|
render(FocusTrapTest, { show: true });
|
||||||
|
await tick();
|
||||||
await user.keyboard('{Shift>}{Tab}{/Shift}');
|
await user.keyboard('{Shift>}{Tab}{/Shift}');
|
||||||
expect(document.activeElement).toEqual(screen.getByTestId('three'));
|
expect(document.activeElement).toEqual(screen.getByTestId('three'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('supports forward focus wrapping', async () => {
|
it('supports forward focus wrapping', async () => {
|
||||||
render(FocusTrapTest, { show: true });
|
render(FocusTrapTest, { show: true });
|
||||||
|
await tick();
|
||||||
screen.getByTestId('three').focus();
|
screen.getByTestId('three').focus();
|
||||||
await user.keyboard('{Tab}');
|
await user.keyboard('{Tab}');
|
||||||
expect(document.activeElement).toEqual(screen.getByTestId('one'));
|
expect(document.activeElement).toEqual(screen.getByTestId('one'));
|
||||||
|
@ -28,9 +31,7 @@ describe('focusTrap action', () => {
|
||||||
render(FocusTrapTest, { show: false });
|
render(FocusTrapTest, { show: false });
|
||||||
const openButton = screen.getByText('Open');
|
const openButton = screen.getByText('Open');
|
||||||
|
|
||||||
openButton.focus();
|
await user.click(openButton);
|
||||||
openButton.click();
|
|
||||||
await tick();
|
|
||||||
expect(document.activeElement).toEqual(screen.getByTestId('one'));
|
expect(document.activeElement).toEqual(screen.getByTestId('one'));
|
||||||
|
|
||||||
screen.getByText('Close').click();
|
screen.getByText('Close').click();
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { shortcuts } from '$lib/actions/shortcut';
|
import { shortcuts } from '$lib/actions/shortcut';
|
||||||
|
import { tick } from 'svelte';
|
||||||
|
|
||||||
const selectors =
|
const selectors =
|
||||||
'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
||||||
|
@ -7,7 +8,9 @@ export function focusTrap(container: HTMLElement) {
|
||||||
const triggerElement = document.activeElement;
|
const triggerElement = document.activeElement;
|
||||||
|
|
||||||
const focusableElement = container.querySelector<HTMLElement>(selectors);
|
const focusableElement = container.querySelector<HTMLElement>(selectors);
|
||||||
focusableElement?.focus();
|
|
||||||
|
// Use tick() to ensure focus trap works correctly inside <Portal />
|
||||||
|
void tick().then(() => focusableElement?.focus());
|
||||||
|
|
||||||
const getFocusableElements = (): [HTMLElement | null, HTMLElement | null] => {
|
const getFocusableElements = (): [HTMLElement | null, HTMLElement | null] => {
|
||||||
const focusableElements = container.querySelectorAll<HTMLElement>(selectors);
|
const focusableElements = container.querySelectorAll<HTMLElement>(selectors);
|
||||||
|
|
Loading…
Reference in a new issue