use-focus-trap

Traps focus inside given element

PackageIcon

Usage

The use-focus-trap hook traps focus at the given node, for example in a modal, drawer, or menu. The node must include at least one focusable element. When the node unmounts, the focus trap is automatically released.

import { useFocusTrap } from '@mantine/hooks';

function Demo() {
  const focusTrapRef = useFocusTrap();

  return (
    <div ref={focusTrapRef}>
      <input />
    </div>
  );
}

API

The hook accepts focus trap active state as a single argument:

import { useFocusTrap } from '@mantine/hooks';

useFocusTrap(); // -> focus trap inactive
useFocusTrap(true); // -> focus trap active

useFocusTrap(false); // -> focus trap disabled

The hook returns ref that should be passed to the element:

import { Paper } from '@mantine/core';
import { useFocusTrap } from '@mantine/hooks';

function Demo() {
  const focusTrapRef = useFocusTrap();

  return (
    <>
      {/* With regular element: */}
      <div ref={focusTrapRef} />

      {/* With Mantine component: */}
      <Paper ref={focusTrapRef} />
    </>
  );
}

Combine with other ref based hooks

To combine use-focus-trap with other ref-based hooks, use the use-merged-ref hook:

import { useRef } from 'react';
import {
  useClickOutside,
  useFocusTrap,
  useMergedRef,
} from '@mantine/hooks';

function Demo() {
  const myRef = useRef();
  const useClickOutsideRef = useClickOutside(() => {});
  const focusTrapRef = useFocusTrap();
  const mergedRef = useMergedRef(
    myRef,
    useClickOutsideRef,
    focusTrapRef
  );

  return <div ref={mergedRef} />;
}

Initial focus

By default, the focus trap will move focus to the first interactive element. To specify the element that should receive initial focus, add the data-autofocus attribute:

import { useFocusTrap } from '@mantine/hooks';

function Demo() {
  const focusTrapRef = useFocusTrap();

  return (
    <div ref={focusTrapRef}>
      <input />
      {/* The second input in the modal will have initial focus */}
      <input data-autofocus />
      <input />
    </div>
  );
}

Definition

function useFocusTrap(active?: boolean): React.RefCallback<HTMLElement | null>