문서보기더 알아보기디자인 시스템과 함께 쓰기Material UI

Material UI와 함께 쓰기

Material UI(MUI)의 Dialog 컴포넌트를 overlay-kit과 함께 사용하는 방법을 알아볼게요.

설치

MUI와 emotion 패키지를 함께 설치해요.

shell
npm install overlay-kit @mui/material @emotion/react @emotion/styled

기본 사용법

MUI Dialogopen prop으로 열림 상태를 받고, onClose로 닫기 이벤트를 처리해요. overlay-kit에서 제공하는 isOpenclose를 그대로 전달하면 돼요.


import { OverlayProvider, overlay } from 'overlay-kit';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogActions from '@mui/material/DialogActions';

function App() {
  return (
    <Button
      variant="contained"
      onClick={() => {
        overlay.open(({ isOpen, close }) => (
          <Dialog open={isOpen} onClose={close}>
            <DialogTitle>정말로 계속하시겠어요?</DialogTitle>
            <DialogActions>
              <Button onClick={close}>아니요</Button>
              <Button onClick={close}></Button>
            </DialogActions>
          </Dialog>
        ));
      }}
    >
      Confirm Dialog 열기
    </Button>
  );
}

export function Example() {
  return (
    <OverlayProvider>
      <App />
    </OverlayProvider>
  );
}

비동기 결과 받기

overlay.openAsync로 사용자의 선택 결과를 Promise로 받을 수 있어요. “네”를 누르면 true, “아니요”를 누르면 false가 반환되도록 close 함수에 값을 전달해요.


import { useState } from 'react';
import { OverlayProvider, overlay } from 'overlay-kit';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogActions from '@mui/material/DialogActions';

function App() {
  const [result, setResult] = useState<boolean | null>(null);

  return (
    <div>
      <p>결과: {result === null ? '선택 없음' : result ? '네' : '아니요'}</p>
      <Button
        variant="contained"
        onClick={async () => {
          const confirmed = await overlay.openAsync<boolean>(({ isOpen, close }) => (
            <Dialog open={isOpen} onClose={() => close(false)}>
              <DialogTitle>정말로 계속하시겠어요?</DialogTitle>
              <DialogActions>
                <Button onClick={() => close(false)}>아니요</Button>
                <Button onClick={() => close(true)}></Button>
              </DialogActions>
            </Dialog>
          ));
          setResult(confirmed);
        }}
      >
        Confirm Dialog 열기
      </Button>
    </div>
  );
}

export function Example() {
  return (
    <OverlayProvider>
      <App />
    </OverlayProvider>
  );
}

애니메이션 후 메모리 해제

MUI DialogTransitionProps.onExited 콜백을 통해 닫기 애니메이션이 끝나는 시점을 알려줘요. 여기에 unmount를 전달하면 애니메이션을 보여주면서도 오버레이 메모리를 안전하게 해제할 수 있어요.


import { OverlayProvider, overlay } from 'overlay-kit';
import Button from '@mui/material/Button';
import Dialog from '@mui/material/Dialog';
import DialogTitle from '@mui/material/DialogTitle';
import DialogActions from '@mui/material/DialogActions';

function App() {
  return (
    <Button
      variant="contained"
      onClick={() => {
        overlay.open(({ isOpen, close, unmount }) => (
          <Dialog open={isOpen} onClose={close} TransitionProps={{ onExited: unmount }}>
            <DialogTitle>정말로 계속하시겠어요?</DialogTitle>
            <DialogActions>
              <Button onClick={close}>아니요</Button>
              <Button onClick={close}></Button>
            </DialogActions>
          </Dialog>
        ));
      }}
    >
      Confirm Dialog 열기
    </Button>
  );
}

export function Example() {
  return (
    <OverlayProvider>
      <App />
    </OverlayProvider>
  );
}