DOM manipulation utilities for Material Components providing cross-browser compatibility, focus management, and accessibility features.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Focus trapping utility for managing focus within modal components like dialogs, drawers, and popups. Ensures keyboard navigation stays within the modal and provides accessible focus management.
Utility class that traps focus within a given root element, intended for modal components.
/**
* Utility to trap focus in a given root element, e.g. for modal components such
* as dialogs. The root should have at least one focusable child element,
* for setting initial focus when trapping focus.
* Also tracks the previously focused element, and restores focus to that
* element when releasing focus.
*/
class FocusTrap {
constructor(root: HTMLElement, options?: FocusOptions);
trapFocus(): void;
releaseFocus(): void;
}Create a new FocusTrap instance for a root element.
/**
* Creates a new FocusTrap instance
* @param root - The root element to trap focus within
* @param options - Configuration options for focus behavior
*/
constructor(root: HTMLElement, options?: FocusOptions);Activate focus trapping within the root element.
/**
* Traps focus in root. Also focuses on either initialFocusEl if set;
* otherwise sets initial focus to the first focusable child element.
* @throws Error if the root element has no focusable children
*/
trapFocus(): void;Deactivate focus trapping and restore previous focus.
/**
* Releases focus from root. Also restores focus to the previously focused
* element.
*/
releaseFocus(): void;interface FocusOptions {
/**
* The element to focus initially when trapping focus.
* Must be a child of the root element.
*/
initialFocusEl?: HTMLElement;
/**
* Whether to skip initially focusing on any element when trapping focus.
* By default, focus is set on the first focusable child element of the root.
* This is useful if the caller wants to handle setting initial focus.
*/
skipInitialFocus?: boolean;
/**
* Whether to restore focus on the previously focused element when releasing
* focus. This is useful if the caller wants to handle restoring focus.
*/
skipRestoreFocus?: boolean;
}import { FocusTrap } from '@material/dom/focus-trap';
// Create modal dialog
const dialog = document.querySelector('.dialog');
const focusTrap = new FocusTrap(dialog);
// Show modal and trap focus
dialog.classList.add('open');
focusTrap.trapFocus();
// Close modal and restore focus
function closeDialog() {
focusTrap.releaseFocus();
dialog.classList.remove('open');
}import { FocusTrap } from '@material/dom/focus-trap';
const modal = document.querySelector('.modal');
const primaryButton = modal.querySelector('.primary-button');
const focusTrap = new FocusTrap(modal, {
initialFocusEl: primaryButton
});
// Show modal - focus will go to primary button
modal.style.display = 'block';
focusTrap.trapFocus();import { FocusTrap } from '@material/dom/focus-trap';
const drawer = document.querySelector('.drawer');
const focusTrap = new FocusTrap(drawer, {
skipInitialFocus: true, // Handle initial focus manually
skipRestoreFocus: true // Handle focus restoration manually
});
// Show drawer
drawer.classList.add('open');
focusTrap.trapFocus();
// Manually set focus
drawer.querySelector('.first-item').focus();
// Close drawer
focusTrap.releaseFocus();
drawer.classList.remove('open');
// Manually restore focus
document.querySelector('.menu-button').focus();FocusTrap automatically detects focusable elements including:
tabindex attributeautofocus attributea, input, textarea, select, buttonaria-hidden="true"The focus trap uses hidden "sentinel" elements to detect when focus attempts to leave the trapped area:
aria-hidden="true" for screen readersaria-hidden and aria-disabled attributestabindex values// FocusTrap will throw an error if root has no focusable children
const emptyDiv = document.createElement('div');
const focusTrap = new FocusTrap(emptyDiv);
try {
focusTrap.trapFocus();
} catch (error) {
console.error('FocusTrap: Element must have at least one focusable child.');
}