Transition

Transition

미리 만들어진 애니메이션으로 컴포넌트의 표시 유무(presence)를 애니메이션 처리하는 컴포넌트예요. 드롭다운, 모달, 툴팁처럼 고정(fixed) 또는 절대(absolute) 위치를 가진 요소의 등장·퇴장을 부드럽게 처리해요.

출처: 문서

본문

사용법 (Usage)

Transition 컴포넌트는 고정 또는 절대 위치를 가진 요소(드롭다운, 모달, 툴팁 등)의 표시 유무를 애니메이션 처리하도록 설계됐어요. 다른 Mantine 컴포넌트(Modal, Tooltip 등)는 애니메이션을 위해 내부적으로 Transition을 사용해요.

Transition 컴포넌트는 모든 애니메이션을 위한 완전한 솔루션을 의도한 것이 아니라는 점에 주의해요. 고정 또는 절대 위치를 가진 요소의 표시 유무를 애니메이션 처리하는 단순한 유틸리티예요. 더 복잡한 애니메이션이 필요하면 Motion, React Spring 또는 다른 전용 애니메이션 라이브러리를 고려해요.

Transition 컴포넌트 사용 예시:

import { Transition } from '@mantine/core';

function Demo({ opened }: { opened: boolean }) {
  return (
    <Transition mounted={opened} transition="fade" duration={400} timingFunction="ease">
      {(styles) => <div style={styles}>Your modal</div>}
    </Transition>
  );
}

미리 만들어진 트랜지션 (Premade transitions)

Mantine은 여러 미리 만들어진 트랜지션을 포함해요: fade, fade-up, fade-down, fade-left, fade-right, scale, scale-y, scale-x, skew-up, skew-down, rotate-left, rotate-right, slide-down, slide-up, slide-left, slide-right, pop, pop-bottom-left, pop-bottom-right, pop-top-left, pop-top-right.

그중 하나를 사용하려면 transition 속성을 해당 값 중 하나로 설정해요.

import { Transition } from '@mantine/core';

function Demo({ opened }: { opened: boolean }) {
  return (
    <Transition mounted={opened} transition="pop" duration={250} timingFunction="ease">
      {(styles) => <div style={styles}>Your modal</div>}
    </Transition>
  );
}

커스텀 트랜지션 (Custom transitions)

직접 트랜지션을 만들 수 있어요. transition은 4개의 속성을 가진 객체예요.

  • in – 마운트된 상태의 스타일
  • out – 마운트되지 않은 상태의 스타일
  • common (선택) – 마운트·언마운트 상태 모두의 스타일
  • transitionProperty – 트랜지션에 참여하는 속성
import { useState } from 'react';
import { useClickOutside } from '@mantine/hooks';
import { Transition, Paper, Button, Box } from '@mantine/core';

const scaleY = {
  in: { opacity: 1, transform: 'scaleY(1)' },
  out: { opacity: 0, transform: 'scaleY(0)' },
  common: { transformOrigin: 'top' },
  transitionProperty: 'transform, opacity',
};

function Demo() {
  const [opened, setOpened] = useState(false);
  const clickOutsideRef = useClickOutside(() => setOpened(false));

  return (
    <Box ref={clickOutsideRef}>
      <Button onClick={() => setOpened(true)}>Open dropdown</Button>
      <Transition mounted={opened} transition={scaleY} duration={200} timingFunction="ease">
        {(transitionStyle) => (
          <Paper style={transitionStyle}>Dropdown</Paper>
        )}
      </Transition>
    </Box>
  );
}

진입·퇴장 지연 (Enter and exit delay)

enterDelay와 exitDelay props로 트랜지션 시작을 지연시킬 수 있어요. 값은 밀리초 단위예요.

import { useState } from 'react';
import { Button, Flex, Paper, Transition } from '@mantine/core';

export function Demo() {
  const [opened, setOpened] = useState(false);

  return (
    <Flex align="flex-start" direction="column">
      <Button onClick={() => setOpened(true)}>Open dropdown</Button>
      <Transition mounted={opened} transition="pop" enterDelay={200} exitDelay={200}>
        {(transitionStyle) => (
          <Paper onClick={() => setOpened(false)} style={{ ...transitionStyle, zIndex: 1 }}>
            Click to close
          </Paper>
        )}
      </Transition>
    </Flex>
  );
}

축소 모션 (Reduced motion)

Transition은 prefers-reduced-motion 미디어 쿼리와 테마의 respectReducedMotion 설정을 존중해요. 축소 모션이 선호되면 모든 트랜지션이 즉시 완료돼요.

import { createTheme, MantineProvider, Transition } from '@mantine/core';

const theme = createTheme({
  respectReducedMotion: true, // default
});

이것은 애니메이션으로 멀미를 느낄 수 있는 전정 기관(vestibular) 질환 사용자의 접근성을 개선해요.

라이프사이클 콜백 (Lifecycle callbacks)

라이프사이클 콜백을 사용해 트랜지션의 여러 단계에서 동작을 수행할 수 있어요.

  • onEnter – 진입 트랜지션이 시작될 때 호출돼요
  • onEntered – 진입 트랜지션이 완료될 때 호출돼요
  • onExit – 퇴장 트랜지션이 시작될 때 호출돼요
  • onExited – 퇴장 트랜지션이 완료될 때 호출돼요
import { Transition } from '@mantine/core';

function Demo() {
  return (
    <Transition
      mounted={true}
      onEnter={() => console.log('Enter started')}
      onEntered={() => console.log('Enter completed')}
      onExit={() => console.log('Exit started')}
      onExited={() => console.log('Exit completed')}
    >
      {(styles) => <div style={styles}>Content</div>}
    </Transition>
  );
}

마운트 유지 (Keep mounted)

기본적으로 요소는 트랜지션이 완료되면 DOM에서 언마운트돼요. keepMounted를 사용하면 요소를 display: none으로 마운트 상태로 유지할 수 있어요.

import { Transition } from '@mantine/core';

function Demo() {
  return (
    <Transition mounted={true} keepMounted>
      {(styles) => <div style={styles}>Content</div>}
    </Transition>
  );
}

이는 다음과 같은 경우에 유용해요.

  • 숨김/표시 중 요소 상태를 유지할 때
  • 재마운트 오버헤드를 피하고 싶을 때
  • 포커스/스크롤 위치를 유지할 때

더 알아보기 (Learn more)