🚀 新規事業

focus-trap

最終更新 2026年05月09日 / 40_新規事業/SCALE_Build/カタログ/機能集/focus-trap.md

フォーカストラップ(モーダル用)

用途

モーダル内に Tab フォーカスを閉じ込める。a11y 必須機能。

特徴

  • Tab/Shift+Tab 制御
  • 最初の要素にフォーカス
  • モーダル閉じたら復元
  • a11y 準拠

コード(コピペ用)

import { useEffect, useRef } from 'react';

const FOCUSABLE = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';

export function useFocusTrap<T extends HTMLElement>(active: boolean) {
  const ref = useRef<T>(null);
  useEffect(() => {
    if (!active || !ref.current) return;

    const previousFocus = document.activeElement as HTMLElement;
    const elements = ref.current.querySelectorAll<HTMLElement>(FOCUSABLE);
    const first = elements[0];
    const last = elements[elements.length - 1];
    first?.focus();

    const onKey = (e: KeyboardEvent) => {
      if (e.key !== 'Tab') return;
      if (e.shiftKey) {
        if (document.activeElement === first) { e.preventDefault(); last?.focus(); }
      } else {
        if (document.activeElement === last) { e.preventDefault(); first?.focus(); }
      }
    };
    document.addEventListener('keydown', onKey);
    return () => {
      document.removeEventListener('keydown', onKey);
      previousFocus?.focus();
    };
  }, [active]);
  return ref;
}

使い方

対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。

注意事項

  • 依存パッケージを忘れず追加