JAVASCRIPT

Accessibility-Friendly Focus Trap with useFocusTrap Hook

Implement an accessible focus trap within any React component (e.g., modals) to keep keyboard focus confined, enhancing user experience.

import { useEffect, useCallback, useRef } from 'react';

function useFocusTrap(isActive) {
  const trapRef = useRef(null);

  const handleKeyDown = useCallback((event) => {
    if (!isActive || event.key !== 'Tab') {
      return;
    }

    const focusableElements = trapRef.current.querySelectorAll(
      'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])'
    );
    const firstElement = focusableElements[0];
    const lastElement = focusableElements[focusableElements.length - 1];

    if (!firstElement || !lastElement) {
        return; // No focusable elements
    }

    if (event.shiftKey) { // Shift + Tab
      if (document.activeElement === firstElement) {
        lastElement.focus();
        event.preventDefault();
      }
    } else { // Tab
      if (document.activeElement === lastElement) {
        firstElement.focus();
        event.preventDefault();
      }
    }
  }, [isActive]);

  useEffect(() => {
    if (isActive && trapRef.current) {
      trapRef.current.focus(); // Optionally focus the trap container itself or a specific element
      document.addEventListener('keydown', handleKeyDown);
    } else if (trapRef.current) {
      document.removeEventListener('keydown', handleKeyDown);
    }

    return () => {
      document.removeEventListener('keydown', handleKeyDown);
    };
  }, [isActive, handleKeyDown]);

  return trapRef;
}
How it works: The `useFocusTrap` hook helps create an accessible user experience by ensuring that keyboard focus remains within a designated element, typically a modal or dialog. When active, it listens for Tab key presses and redirects focus from the last focusable element back to the first, and vice-versa for Shift+Tab, preventing users from tabbing outside the trapped area.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs