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
+55
View File
@@ -0,0 +1,55 @@
import { shortcuts } from '$lib/actions/shortcut';
const selectors =
'button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
export function focusTrap(container: HTMLElement) {
const triggerElement = document.activeElement;
const focusableElement = container.querySelector<HTMLElement>(selectors);
focusableElement?.focus();
const getFocusableElements = (): [HTMLElement | null, HTMLElement | null] => {
const focusableElements = container.querySelectorAll<HTMLElement>(selectors);
return [
focusableElements.item(0), //
focusableElements.item(focusableElements.length - 1),
];
};
const { destroy: destroyShortcuts } = shortcuts(container, [
{
ignoreInputFields: false,
preventDefault: false,
shortcut: { key: 'Tab' },
onShortcut: (event) => {
const [firstElement, lastElement] = getFocusableElements();
if (document.activeElement === lastElement) {
event.preventDefault();
firstElement?.focus();
}
},
},
{
ignoreInputFields: false,
preventDefault: false,
shortcut: { key: 'Tab', shift: true },
onShortcut: (event) => {
const [firstElement, lastElement] = getFocusableElements();
if (document.activeElement === firstElement) {
event.preventDefault();
lastElement?.focus();
}
},
},
]);
return {
destroy() {
destroyShortcuts?.();
if (triggerElement instanceof HTMLElement) {
triggerElement.focus();
}
},
};
}