Modal
화면 중앙에 표시되는 Next.js Client Component입니다. 확인·폼·상세 보기 등 사용자의 집중이 필요한 작업에 사용하며, role="dialog" · aria-modal로 접근성을 보장합니다.
기본
data-modal-trigger로 대화상자를 열고, 백드롭·닫기 버튼·Esc로 닫습니다.
Modal 대화상자 본문입니다. 백드롭을 클릭하거나 닫기 버튼, Esc 키로 닫을 수 있습니다.
열린 상태
open prop으로 is-open 클래스를 추가하고 hidden을 해제합니다. 문서 미리보기에서는 modal_demo-frame 안에서 열린 모습을 확인합니다.
open prop으로 대화상자가 열린 상태를 미리 보여 줍니다.
열린 상태의 Modal입니다. 백드롭·헤더·푸터 구성을 한눈에 확인할 수 있습니다.
크기
modal_sm · modal_lg · modal_fullscreen으로 대화상자 너비를 조정합니다.
modal_sm — 확인·간단한 알림에 적합한 좁은 너비입니다.
기본 너비 32rem
modal_lg — 상세 보기·넓은 폼·테이블 미리보기 등에 사용합니다.
modal_fullscreen — 뷰포트 전체를 사용하는 대화상자입니다.
헤더·푸터
modal_header · modal_body · modal_footer로 영역을 나눕니다. 푸터에 액션 버튼을 배치합니다.
푸터 정렬
footerAlign으로 푸터 버튼을 정렬합니다. start · center · end(기본) · between(좌·우 병합) · even(균등). even은 footerRatio로 좌·우 비율(1-1 · 1-2 · 2-1)을 지정하고, footerNoPadBottom으로 하단 패딩을 제거할 수 있습니다. between은 modal_footer-group으로 좌·우에 1~2개씩 묶습니다.
확인 대화상자
삭제·취소 등 되돌릴 수 없는 작업 전에 사용자 확인을 받습니다. modal_sm으로 좁은 레이아웃을 사용합니다.
이 작업은 되돌릴 수 없습니다. 정말 삭제하시겠습니까?
폼
입력 필드가 포함된 대화상자입니다. Form Layout · Input 컴포넌트와 조합합니다.
스크롤 본문
modal_scrollable을 루트에 추가하면 본문이 길 때 modal_body 안에서 스크롤됩니다.
제1조 (목적) 본 약관은 서비스 이용과 관련하여 회사와 이용자 간의 권리·의무 및 책임사항을 규정함을 목적으로 합니다.
제2조 (정의) 본 약관에서 사용하는 용어의 정의는 다음과 같습니다. ① "서비스"란 회사가 제공하는 모든 온라인 서비스를 의미합니다. ② "이용자"란 본 약관에 따라 서비스를 이용하는 회원 및 비회원을 말합니다.
제3조 (약관의 효력) 본 약관은 서비스 화면에 게시하거나 기타의 방법으로 이용자에게 공지함으로써 효력이 발생합니다.
제4조 (서비스의 제공) 회사는 다음과 같은 서비스를 제공합니다. 정보 제공, 커뮤니티, 기타 회사가 정하는 서비스.
제5조 (서비스의 중단) 회사는 컴퓨터 등 정보통신설비의 보수점검·교체 및 고장, 통신의 두절 등의 사유가 발생한 경우 서비스의 제공을 일시적으로 중단할 수 있습니다.
제6조 (회원가입) 이용자는 회사가 정한 가입 양식에 따라 회원정보를 기입한 후 본 약관에 동의한다는 의사표시를 함으로써 회원가입을 신청합니다.
제7조 (회원 탈퇴 및 자격 상실) 회원은 회사에 언제든지 탈퇴를 요청할 수 있으며 회사는 즉시 회원탈퇴를 처리합니다.
제8조 (개인정보보호) 회사는 관련 법령이 정하는 바에 따라 이용자의 개인정보를 보호하기 위해 노력합니다.
제9조 (회사의 의무) 회사는 법령과 본 약관이 금지하거나 공서양속에 반하는 행위를 하지 않으며, 지속적이고 안정적으로 서비스를 제공하기 위해 노력합니다.
제10조 (이용자의 의무) 이용자는 관계 법령, 본 약관의 규정, 이용안내 및 서비스와 관련하여 공지한 주의사항을 준수하여야 합니다.
중첩 Modal
열린 Modal 안에서 다른 Modal을 열 수 있습니다. 2단계가 열리면 1단계 백드롭은 숨겨지고, 2단계가 닫히면 다시 표시됩니다. Esc는 가장 위에 열린 대화상자부터 닫습니다.
다음 단계 Modal을 열어 중첩 동작을 확인하세요.
중첩된 Modal입니다. 닫으면 1단계 백드롭이 다시 표시됩니다. Esc를 누르면 이 대화상자부터 닫힙니다.
백드롭 없음
backdrop={false}로 어두운 배경을 숨깁니다. 본문과 동시에 상호작용할 수 있습니다.
본문을 가리지 않고 대화상자만 표시합니다. 닫기 버튼이나 Esc로 닫으세요.
마크업
트리거 버튼과 Modal 루트를 id · aria-controls로 연결합니다. 기본은 닫힌 상태(hidden)이며, 클릭 이벤트로 열립니다.
<!-- 트리거 -->
<button type="button" data-modal-trigger="#modal-1"
aria-controls="modal-1" aria-expanded="false">
모달 열기
</button>
<!-- Modal -->
<div class="modal" id="modal-1" data-modal
role="dialog" aria-modal="true" aria-labelledby="modal-1-title"
tabindex="-1" hidden>
<div class="modal_backdrop" data-modal-close aria-hidden="true"></div>
<div class="modal_dialog">
<div class="modal_header">
<h2 class="modal_title" id="modal-1-title">제목</h2>
<button type="button" class="modal_close"
data-modal-close aria-label="닫기">…</button>
</div>
<div class="modal_body">본문</div>
<div class="modal_footer">
<button type="button" class="btn btn_ghost" data-modal-close>취소</button>
<button type="button" class="btn btn_filled color_primary" data-modal-close>확인</button>
</div>
</div>
</div>
<!-- 푸터 정렬: start · center · end · between · even -->
<!-- 균등 비율: modal_footer-even · modal_footer-even-1-2 · modal_footer-even-2-1 -->
<!-- 하단 패딩 없음: modal_footer-no-pad-b (+ even 권장) -->
<div class="modal_footer modal_footer-even modal_footer-no-pad-b">
<button type="button" class="btn btn_ghost" data-modal-close>취소</button>
<button type="button" class="btn btn_filled color_primary" data-modal-close>확인</button>
</div>
<!-- 옵션: 백드롭 없음 (React) -->
<Modal id="modal-plain" backdrop={false} …>…</Modal>
<!-- 옵션: 백드롭 없음 (HTML) -->
<div class="modal" id="modal-plain" data-modal
data-modal-backdrop="false" …>…</div>
<!-- 옵션: 스크롤 본문 -->
<div class="modal modal_scrollable" id="modal-long" data-modal …>…</div>API · Props
| Prop | 타입 | 기본값 | 설명 |
|---|---|---|---|
id | string | — | 루트 id (필수, data-modal-trigger 연결) |
title | string | — | 기본 헤더 제목 (modal_title) |
size | 'sm' | 'md' | 'lg' | 'fullscreen' | md | modal_sm · modal_lg · modal_fullscreen |
scrollable | boolean | false | 본문 스크롤 (modal_scrollable) |
backdrop | boolean | true | 백드롭 표시 (false → data-modal-backdrop="false") |
open | boolean | false | 열림 상태 (is-open, hidden 해제) |
footerAlign | 'start' | 'center' | 'end' | 'between' | 'even' | end | 푸터 정렬 (modal_footer-start · center · between · even). between은 modal_footer-group으로 좌·우 묶음 |
footerRatio | '1-1' | '1-2' | '2-1' | 1-1 | 균등 정렬(even) 좌·우 비율 (modal_footer-even-1-2 · even-2-1) |
footerNoPadBottom | boolean | false | 푸터 하단 패딩 제거 (modal_footer-no-pad-b). even과 함께 쓰면 좌우 패딩·간격도 제거 |
header | ReactNode | — | 커스텀 헤더 (title 대체) |
footer | ReactNode | — | 하단 액션 영역 (modal_footer) |
className | string | — | modal 루트에 추가 클래스 |
ripple | boolean | true | 클릭 파장(ripple). 닫기·트리거 버튼에 적용 · true 활성 · false 비활성 |
API · Children
| Children | 설명 |
|---|---|
header | 헤더 (title 대체) |
children | 본문 (modal_body, Vue default 슬롯 대응) |
footer | 하단 액션 (modal_footer) |
클래스 · 속성
React 컴포넌트가 렌더하는 OOCSS 클래스입니다. HTML 마크업으로 직접 작성할 때 동일하게 조합합니다.
| 클래스 | 설명 |
|---|---|
modal · modal_backdrop · modal_dialog | 루트·백드롭·대화상자 |
modal_header · modal_title · modal_close · modal_body · modal_footer | 구조 파트 |
modal_footer-start · modal_footer-center · modal_footer-end · modal_footer-between · modal_footer-even | 푸터 정렬 (기본 end) |
modal_footer-even-1-2 · modal_footer-even-2-1 | 균등 정렬 좌·우 비율 (기본 1:1) |
modal_footer-no-pad-b | 푸터 하단 패딩 없음 (even 조합 시 좌우 패딩·간격 제거) |
modal_footer-group | 병합 정렬용 좌·우 버튼 묶음 |
modal_sm · modal_lg · modal_fullscreen · modal_scrollable | 크기·스크롤 |
data-modal · data-modal-trigger · data-modal-close | JS 연동 속성 |
is-open · is-stack-covered · hidden | 열림·중첩 하위(백드롭 숨김)·닫힘 상태 |
role="dialog" · aria-modal="true" | 접근성 시맨틱 |
data-ripple | 클릭 파장 활성. data-ripple="surface"는 절대 위치 보조 버튼용 |
data-ripple="false" | 해당 요소 ripple 비활성 |
data-no-ripple | 하위 전체 ripple 비활성 |
닫기: 백드롭 클릭 · data-modal-close · Esc. 열릴 때 포커스는 닫기 버튼으로 이동하고, 닫힐 때 트리거로 복원됩니다.
디자인 토큰
| 토큰 | 기본값 | 설명 |
|---|---|---|
--modal-z-index | 300 | 레이어 순서 |
--modal-width · --modal-width-sm · --modal-width-lg | 32rem · 24rem · 48rem | 대화상자 너비 |
--modal-bg · --modal-radius · --modal-shadow | — | 배경·모서리·그림자 |