Trap focus within a DOM node for accessible modals and interactive UI components.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Methods for activating, deactivating, pausing, and controlling focus trap behavior. These methods provide fine-grained control over when and how focus trapping occurs.
Activates the focus trap, adding event listeners and beginning focus management.
/**
* Activates the focus trap
* @param activateOptions - Override options for this activation
* @returns The trap instance for method chaining
*/
activate(activateOptions?: ActivateOptions): FocusTrap;
interface ActivateOptions {
/** Override onActivate callback for this activation */
onActivate?: () => void;
/** Override onPostActivate callback for this activation */
onPostActivate?: () => void;
/** Check if trap can receive focus before activating */
checkCanFocusTrap?: (containers: Array<HTMLElement | SVGElement>) => Promise<void>;
}Activation Behavior:
onActivate callback (if provided)onPostActivate callback (if provided)Usage Examples:
// Basic activation
trap.activate();
// With override callbacks (these override the base configuration)
trap.activate({
onActivate: () => console.log('Custom activation logic'),
onPostActivate: () => console.log('Trap is now active')
});
// With async focus check (for animated elements)
trap.activate({
checkCanFocusTrap: async (containers) => {
// Wait for animation to complete
await new Promise(resolve => setTimeout(resolve, 300));
}
});Deactivates the focus trap, removing event listeners and optionally restoring focus.
/**
* Deactivates the focus trap
* @param deactivateOptions - Override options for this deactivation
* @returns The trap instance for method chaining
*/
deactivate(deactivateOptions?: DeactivateOptions): FocusTrap;
interface DeactivateOptions {
/** Whether to return focus to the previously focused element */
returnFocus?: boolean;
/** Override onDeactivate callback for this deactivation */
onDeactivate?: () => void;
/** Override onPostDeactivate callback for this deactivation */
onPostDeactivate?: () => void;
/** Check if focus can be returned before attempting */
checkCanReturnFocus?: (trigger: HTMLElement | SVGElement) => Promise<void>;
}Deactivation Behavior:
onDeactivate callback (if provided)onPostDeactivate callback (if provided)Usage Examples:
// Basic deactivation (uses default returnFocus setting)
trap.deactivate();
// Force return focus regardless of default setting
trap.deactivate({ returnFocus: true });
// Prevent focus return (overrides returnFocusOnDeactivate configuration)
trap.deactivate({ returnFocus: false });
// With async focus return check
trap.deactivate({
checkCanReturnFocus: async (trigger) => {
// Wait for trigger element to be ready
await waitForElement(trigger);
}
});Pauses an active trap without fully deactivating it, temporarily suspending focus management.
/**
* Pauses an active focus trap
* @param pauseOptions - Options for this pause operation
* @returns The trap instance for method chaining
*/
pause(pauseOptions?: PauseOptions): FocusTrap;
interface PauseOptions {
/** Callback called immediately after pause state is set */
onPause?: () => void;
/** Callback called after trap is completely paused */
onPostPause?: () => void;
}Pause Behavior:
onDeactivate or restore focusUsage Examples:
// Basic pause
trap.pause();
// With callbacks
trap.pause({
onPause: () => console.log('Pausing trap'),
onPostPause: () => console.log('Trap paused')
});
// Check pause state
if (trap.paused) {
console.log('Trap is paused');
}Resumes a paused trap, restoring focus management without full reactivation.
/**
* Resumes a paused focus trap
* @param unpauseOptions - Options for this unpause operation
* @returns The trap instance for method chaining
*/
unpause(unpauseOptions?: UnpauseOptions): FocusTrap;
interface UnpauseOptions {
/** Callback called immediately after unpause state is set */
onUnpause?: () => void;
/** Callback called after trap is completely unpaused */
onPostUnpause?: () => void;
}Unpause Behavior:
Usage Examples:
// Basic unpause
trap.unpause();
// With callbacks
trap.unpause({
onUnpause: () => console.log('Resuming trap'),
onPostUnpause: () => console.log('Trap resumed')
});Updates the elements that serve as containers for the focus trap, even while active.
/**
* Updates the container elements for this trap
* @param containerElements - New container elements (same format as createFocusTrap)
* @returns The trap instance for method chaining
*/
updateContainerElements(
containerElements: HTMLElement | SVGElement | string | Array<HTMLElement | SVGElement | string>
): FocusTrap;Usage Examples:
// Update to new container
trap.updateContainerElements('#new-modal');
// Update to multiple containers
trap.updateContainerElements(['.sidebar', '.main-content']);
// Update with DOM elements
const newContainer = document.createElement('div');
trap.updateContainerElements(newContainer);Multiple traps automatically coordinate through a stack system:
// First trap activates normally
const trap1 = createFocusTrap('#modal1');
trap1.activate(); // trap1 is active
// Second trap auto-pauses first
const trap2 = createFocusTrap('#modal2');
trap2.activate(); // trap1 paused, trap2 active
// Deactivating second trap auto-unpauses first
trap2.deactivate(); // trap1 active again, trap2 inactive
// Manual pause prevents auto-unpause
trap1.pause(); // trap1 manually paused
trap2.activate(); // trap2 active
trap2.deactivate(); // trap1 remains paused (manual)
trap1.unpause(); // trap1 active againAll control methods return the trap instance, enabling method chaining:
// Chain multiple operations
trap
.activate()
.pause()
.unpause()
.deactivate();
// Conditional chaining
const result = trap.active ? trap.deactivate() : trap.activate();