Allra Fintech
Modal

ZustandModal

전역 Zustand 스토어를 사용해 어디서든 열 수 있는 모달 컴포넌트

Description

ZustandModal은 전역 Zustand 스토어를 이용해 모달의 열림/닫힘 상태와 내용을 관리하는 모달 컴포넌트입니다.
루트 레이아웃에 Modal 컴포넌트를 한 번만 선언해 두면, 어느 컴포넌트에서든 modal.show() 함수를 호출하여 모달을 열 수 있습니다.

"use client";

import Modal from "@/registry/ui/zustand-modal/modal";
import { modal } from "@/registry/ui/zustand-modal/use-modal";
import { Button } from "@/shared/ui/button";

export const ZustandModalDemo = () => {
  const handleOpenModal = () => {
    modal.show((onModalClose) => (
      <div className="w-[320px] rounded-2xl bg-white p-6 shadow-lg">
        <h3 className="text-base font-semibold text-gray-900">
          Zustand Modal
        </h3>
        <p className="mt-2 text-sm text-gray-600">
          전역 Zustand 스토어로 제어되는 모달입니다.
        </p>
        <div className="mt-6 flex justify-end gap-2">
          <Button variant="outline" onClick={onModalClose}>
            닫기
          </Button>
          <Button
            onClick={() => {
              console.log("확인 버튼 클릭");
              onModalClose();
            }}
          >
            확인
          </Button>
        </div>
      </div>
    ));
  };

  return (
      <Button onClick={handleOpenModal}>모달 열기</Button>
  );
};

Installation

pnpx shadcn add @allra/zustand-modal

Usage

1. 루트 레이아웃에 전역 선언

먼저 루트 레이아웃(예: app/layout.tsx)에 Modal 컴포넌트를 한 번 선언합니다.

import Modal from "@/registry/ui/zustand-modal/modal";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html>
      <body>
        {children}
        <Modal />
      </body>
    </html>
  );
}

2. 사용처에서 modal.show() 호출

어디서든 modal.show() 함수를 호출하여 모달을 열 수 있습니다.
modal.show에는 onModalClose 콜백을 인자로 받는 함수(ReactNode를 반환)를 전달하며, 이 콜백을 사용해 모달을 쉽게 닫을 수 있습니다.

"use client";

import Modal from "@/registry/ui/zustand-modal/modal";
import { modal } from "@/registry/ui/zustand-modal/use-modal";
import { Button } from "@/shared/ui/button";

export default function MyComponent() {
  const handleOpenModal = () => {
    modal.show((onModalClose) => (
      <div className="w-[320px] rounded-2xl bg-white p-6 shadow-lg">
        <h3 className="text-base font-semibold text-gray-900">
          제목
        </h3>
        <p className="mt-2 text-sm text-gray-600">
          내용입니다.
        </p>
        <div className="mt-6 flex justify-end gap-2">
          <Button variant="outline" onClick={onModalClose}>
            닫기
          </Button>
          <Button
            onClick={() => {
              console.log("확인 버튼 클릭");
              onModalClose();
            }}
          >
            확인
          </Button>
        </div>
      </div>
    ));
  };

  return (
      <Button onClick={handleOpenModal}>모달 열기</Button>
  );
}

API

modal.show

modal.show(
  (onModalClose: () => void) => React.ReactNode,
);
  • onModalClose: 모달을 닫을 때 호출하는 콜백입니다. 모달 내부에서 닫기 버튼 클릭 시 이 함수를 호출하면 됩니다.

modal.close

modal.close();
  • 어디서든 호출하여 현재 열린 모달을 즉시 닫을 수 있습니다.

Examples

기본 사용

modal.show((onModalClose) => (
  <div>
    <p>기본 모달</p>
    <Button onClick={onModalClose}>닫기</Button>
  </div>
));

확인 / 취소 액션 처리

modal.show((onModalClose) => (
  <div>
    <p>정말 삭제하시겠습니까?</p>
    <div className="mt-4 flex justify-end gap-2">
      <Button variant="outline" onClick={onModalClose}>
        취소
      </Button>
      <Button
        variant="destructive"
        onClick={() => {
          console.log("삭제 진행");
          onModalClose();
        }}
      >
        삭제
      </Button>
    </div>
  </div>
));