FocusTrap

FocusTrap (포커스 트랩)

FocusTrap 컴포넌트는 자식 노드 안으로 포커스를 가두는 컴포넌트예요. Modal, DatePicker, Popover처럼 포커스 트랩이 필요한 Mantine 컴포넌트에서 사용돼요.

출처: 문서

본문

FocusTrap는 use-focus-trap 훅을 컴포넌트로 구현한 것이에요. 포커스 트랩이 필요한 모든 Mantine 컴포넌트(Modal, DatePicker, Popover 등)에서 사용돼요.

import { useDisclosure } from '@mantine/hooks';
import { FocusTrap, TextInput, Button, Box } from '@mantine/core';

function Demo() {
  const [active, { toggle }] = useDisclosure(false);

  return (
    <Box maw={400} mx="auto">
      <Button onClick={toggle}>{active ? 'Deactivate' : 'Activate'} focus trap</Button>

      <FocusTrap active={active}>
        <div>
          <TextInput mt="sm" label="First input" placeholder="First input" />
          <TextInput mt="sm" label="Second input" placeholder="Second input" />
          <TextInput mt="sm" label="Third input" placeholder="Third input" />
        </div>
      </FocusTrap>
    </Box>
  );
}

초기 포커스 (Initial focus)

초기 포커스를 받을 요소를 지정하려면 data-autofocus 속성을 설정해요.

import { useDisclosure } from '@mantine/hooks';
import { FocusTrap, TextInput, Button, Box } from '@mantine/core';

function Demo() {
  const [active, { toggle }] = useDisclosure(false);

  return (
    <Box maw={400} mx="auto">
      <Button onClick={toggle}>{active ? 'Deactivate' : 'Activate'} focus trap</Button>

      <FocusTrap active={active}>
        <div>
          <TextInput mt="sm" label="First input" placeholder="First input" />
          <TextInput mt="sm" label="Second input" placeholder="Second input" data-autofocus />
          <TextInput mt="sm" label="Third input" placeholder="Third input" />
        </div>
      </FocusTrap>
    </Box>
  );
}

FocusTrap.InitialFocus

FocusTrap.InitialFocus는 포커스 트랩이 활성화될 때 포커스를 받는, 시각적으로 숨겨진 요소를 추가하는 특수 컴포넌트예요. FocusTrap.InitialFocus가 포커스를 잃으면 tab 순서에서 제거돼요.

예를 들어 Modal이 열렸을 때 내부의 어떤 요소에도 포커스를 주고 싶지 않을 때 유용해요.

import { useDisclosure } from '@mantine/hooks';
import { Modal, Button, TextInput, FocusTrap } from '@mantine/core';

function Demo() {
  const [opened, { open, close }] = useDisclosure(false);

  return (
    <>
      <Modal opened={opened} onClose={close} title="Focus demo">
        <FocusTrap.InitialFocus />
        <TextInput label="First input" placeholder="First input" />
        <TextInput
          data-autofocus
          label="Input with initial focus"
          placeholder="It has data-autofocus attribute"
          mt="md"
        />
      </Modal>

      <Button variant="default" onClick={open}>
        Open modal
      </Button>
    </>
  );
}

포커스 트랩 동작 원리

  • active prop이 true이면 자식 노드 안으로 포커스가 가둬져요
  • FocusTrap 컴포넌트가 마운트되거나 active prop이 false에서 true로 바뀌면, data-autofocus 속성을 가진 첫 번째 요소가 포커스돼요
  • data-autofocus 속성을 가진 요소가 없다면, 키보드 상호작용을 지원하는 첫 번째 요소가 포커스돼요
  • 대상 요소에 포커스 가능한 요소가 없거나 ref를 지원하지 않으면 포커스 트랩은 동작하지 않아요
  • FocusTrap 자식 바깥의 요소가 포커스되면 트랩은 동작을 멈춰요

더 알아보기 (Learn more)