Components
Modal
Docs
API 사용가이드입니다. 변형·색상·props 프리뷰는 Overview를 참고하세요.
API
Modal · ModalTrigger · ModalContent · ModalTitle · ModalDescription · ModalFooter · ModalClose 합성 API로 사용합니다. 포커스 트랩·ESC 닫기·ARIA 연결은 내부에서 자동 처리됩니다. 오버레이 클릭으로는 닫히지 않습니다.
import {
Modal,
ModalTrigger,
ModalContent,
ModalTitle,
ModalDescription,
ModalFooter,
ModalClose,
} from "@/components/modal";
import Button from "@/components/button";
<Modal>
<ModalTrigger asChild>
<Button variant="secondary">게시글 삭제</Button>
</ModalTrigger>
<ModalContent>
<ModalTitle>게시글을 삭제할까요?</ModalTitle>
<ModalDescription>삭제한 게시글은 복구할 수 없습니다.</ModalDescription>
<ModalFooter actions="confirm">
<ModalClose asChild>
<Button variant="tertiary">취소</Button>
</ModalClose>
<Button onClick={handleDelete}>삭제</Button>
</ModalFooter>
</ModalContent>
</Modal>
{/* CTA 색 커스텀 — Button className (hover·active 포함) */}
<ModalFooter actions="confirm">
<ModalClose asChild>
<Button variant="tertiary">취소</Button>
</ModalClose>
<Button
className="bg-emerald-500 text-white hover:bg-emerald-600 active:bg-emerald-700"
>
확인
</Button>
</ModalFooter>
{/* 커스텀 크기 셸 — Tailwind className */}
<ModalContent className="max-h-[80vh] w-[min(calc(100vw-2rem),32rem)]">
…
</ModalContent>Props
| Name | Type | Default | Description |
|---|---|---|---|
Modal.open / defaultOpen | boolean | — | 열림 상태. open + onOpenChange로 제어하거나 defaultOpen으로 비제어로 사용합니다. |
ModalTrigger | asChild?: boolean | — | 클릭 시 모달을 엽니다. asChild로 Button 등 커스텀 트리거에 연결합니다. |
ModalContent.className | string | — | 크기·스타일. 미전달 시 w-[min(calc(100vw-2rem),400px)] max-h-[400px]. w/h/max-*를 넣으면 기본 박스를 대체합니다. |
ModalFooter.actionsRequired | "single" | "dual" | "confirm" | — | 버튼 구성·균등 폭 레이아웃 프리셋. 색은 강제하지 않습니다. CTA는 Button 기본(primary), 커스텀은 각 Button className으로 전달합니다. |
ModalTitle / ModalDescription | React.ReactNode | — | 제목·설명. 제목을 시각적으로 숨기려면 ModalTitle에 className="sr-only"를 전달합니다(접근성 유지). |
ModalClose | asChild?: boolean | — | 클릭 시 모달을 닫습니다. 취소·닫기 버튼에 연결합니다. |
Events
| Name | Signature | Description |
|---|---|---|
Modal.onOpenChange | (open: boolean) => void | 열림 상태 변경 시 호출됩니다. ESC·ModalClose로 닫힐 때 전달됩니다. 오버레이 클릭으로는 닫히지 않습니다. |
Notes
- 소비 앱 필수: React 19, Tailwind CSS v4, ClaBi tokens.css(+ @theme 매핑), clsx, @radix-ui/react-dialog.
- clsx 패키지가 필수입니다. className 병합에 import { clsx } from "clsx" 를 사용합니다.
- 내부적으로 @radix-ui/react-dialog를 사용합니다. 소비 앱에도 해당 패키지가 필요합니다.
- Footer CTA 기본색은 Button variant(미지정 시 primary)입니다. bg-·hover:bg-·active:bg-·text-* className을 넣으면 variant 색 대신 해당 클래스가 적용됩니다.
- 확인형 모달이므로 오버레이(외부) 클릭으로는 닫히지 않습니다. Footer 버튼 또는 ESC로 닫습니다.
- 별도의 제목을 전달하지 않을 경우, 제목 없이 설명 텍스트만 표시됩니다(ModalTitle sr-only 권장).
- 최대 크기는 className으로 전달합니다. 미전달 시 400×400(뷰포트 여백 포함). 예: className="w-[min(calc(100vw-2rem),32rem)] max-h-[80vh]".
- 설명 텍스트가 길면 ModalDescription이 스크롤됩니다. 더 큰 콘텐츠·커스텀 팝업도 ModalContent 껍데기 + className으로 구성합니다.