Popup
확인이나 선택이 꼭 필요할 때 화면을 막고 응답을 받는 모달이에요.
치수·스펙은 Web 기준이에요. Mobile 은 추후 반영해요.
Anatomy
- 01Title팝업의 목적을 나타내는 제목. 16px / bold (Web)
- 02Close (X)팝업을 닫는 18×18 아이콘 버튼. 선택적으로 사용
- 03Body상황 설명 또는 선택 안내 텍스트. 14px / regular
- 04Secondary Button취소 또는 보조 액션. 선택적으로 사용
- 05Primary CTA주요 액션 버튼. 항상 포함
- 06다시 보지 않기 (Optional)반복 노출 방지 옵션. 필요 시에만 사용
Properties
Button Type
ONE BTN 과 TWO BTN 두 가지 구성이에요. 되돌릴 수 없는 액션에는 취소 수단이 있는 TWO BTN 을 써요.
Close (X) Button
버튼 레이블이 '닫기'가 아닐 때만 X 를 넣어요. '닫기' 버튼이 있거나 정보성 모달이면 넣지 않아요.
Case
의도와 맥락
응답 없이는 다음 단계로 못 가는 상황에만 써요. 화면을 막는 만큼 꼭 필요할 때만이에요.
01
되돌릴 수 없는 액션 전 확인
삭제·초기화·탈퇴처럼 되돌리기 어려운 작업 전에 한 번 더 확인해요. TWO BTN 으로 취소 수단을 꼭 둬요.
02
선택을 요구하는 분기점
저장 여부·권한·약관 동의처럼 선택해야 흐름이 이어질 때 써요. 버튼 레이블은 선택지가 드러나게 구체적으로 써요.
03
반드시 인지해야 하는 정보 전달
점검·결제 오류·필수 업데이트처럼 확인하고 넘어가야 할 정보를 전해요. ONE BTN('닫기'/'확인')에 X 는 없어요.
!
이런 경우엔 Popup을 쓰지 마세요
- 응답이 필요 없는 알림(저장 완료 등)은 Toast
- 오래 떠 있어야 하는 공지는 Banner/Alert
- 입력 폼·다단계 작업은 별도 페이지나 Bottom Sheet
- 버튼이 3개 이상이면 선택지를 줄이거나 전용 화면으로
Guidelines
✓ DO
- 제목은 질문형(~할까요?)이나 명사형으로 짧게
- TWO BTN 은 오른쪽이 주요 CTA
- '닫기' 가 아닌 액션 버튼이면 X 추가
- '다시 보지 않기' 는 정보성 팝업에만
- 위험 액션의 Primary 는 Delete(Red) 버튼
✗ DON'T
- 흐름을 불필요하게 막는 팝업 남발
- 긴 본문을 팝업에 넣기(별도 페이지로)
- 버튼 3개 이상
다시 보지 않기
반복 노출을 막아야 하는 정보성 팝업에만 제공해요. ONE BTN·TWO BTN 둘 다에 붙일 수 있어요.
배치
Desktop 은 오른쪽이 주요 액션, Mobile 은 위가 주요 액션이에요.
X Button 사용 기준
| 케이스 | X 버튼 |
|---|---|
| 버튼 레이블이 '닫기' | ✗ 불필요 (닫기 버튼으로 대체) |
| Alert · 정보성 모달 | ✗ 불필요 |
| 버튼 레이블이 다른 액션 (ex. 하러가기) | ✓ 필요 (닫을 수단 제공) |
| 다시 보지 않기 포함 팝업 | ✓ 필요 |
Specification
Container
| 속성 | 값 | 설명 |
|---|---|---|
| width | 343px | |
| border-radius | radius-lg (16px) | |
| padding | 12px 16px 16px | top / horizontal / bottom |
| gap (header ↔ footer) | 24px | |
| background | --color-background-base (white) | |
| box-shadow | 0px 2px 8px rgba(0,0,0,0.1) | popover shadow |
| overlay | rgba(0,0,0,0.4) | 배경 딤 처리 |
Button
| 속성 | Primary | Secondary |
|---|---|---|
| height | 32px | 32px |
| padding | 0 10px | 0 10px |
| border-radius | radius-sm (8px) | radius-sm (8px) |
| background | --color-accent-normal (#1d7ff9) | --color-background-base (white) |
| border | none | 1px solid --color-line-neutral (#e8ebed) |
| color | --color-static-white | --color-label-normal (#26282b) |
| font | 14px / 500 | 14px / 500 |
| 배치 | 우측 정렬 (오른쪽이 CTA) | Primary 왼쪽, 버튼 간 gap 8px |
Typography
| 요소 | Size | Weight | Color Token |
|---|---|---|---|
| Title | 16px | 700 | --color-label-normal (#26282b) |
| Title line-height | 1.5 | — | letter-spacing: 0 |
| Body | 14px | 400 | --color-label-neutral (#454c53) |
| 다시 보지 않기 | 13px | 500 | --color-label-assistive (#9ea4aa) |
| 다시보지않기 checkbox | 21×21px | — | border: 2px solid --color-line-normal (#c9cdd2), border-radius: 6px |
| Close (X) icon | 18×18px | — | --color-label-assistive (#9ea4aa) |
설치
npm i @polarisoffice/pds-reactTWO BTN
되돌릴 수 없는 액션 전 확인. 취소 수단을 두고 오른쪽에 주요 CTA 를 놓아요.
import { Popup, Button } from '@polarisoffice/pds-react';
import { useState } from 'react';
const [open, setOpen] = useState(false);
const close = () => setOpen(false);
const remove = () => { /* 삭제 처리 */ close(); };
<Button variant="delete" onClick={() => setOpen(true)}>삭제</Button>
<Popup
open={open}
onClose={close}
title="정말 삭제할까요?"
footer={
<>
<Button variant="default" onClick={close}>취소</Button>
<Button variant="delete" onClick={remove}>삭제</Button>
</>
}
>
삭제된 데이터는 복구할 수 없습니다.
</Popup>ONE BTN
반드시 인지해야 하는 정보 전달. '닫기'/'확인' 레이블이면 X 버튼은 넣지 않아요.
import { Popup, Button } from '@polarisoffice/pds-react';
<Popup
open={open}
onClose={close}
title="서비스 점검 안내"
footer={<Button variant="primary" onClick={close}>확인</Button>}
>
6월 30일 02:00–04:00 서비스 점검이 예정되어 있습니다.
</Popup>Close (X)
버튼 레이블이 '닫기'가 아닌 다른 액션일 때만 X 를 켜요.
import { Popup, Button } from '@polarisoffice/pds-react';
<Popup
open={open}
onClose={close}
closable
title="Title"
footer={<Button variant="primary">하러가기</Button>}
>
Body 내용이 들어가는 영역입니다.
</Popup>다시 보지 않기
정보성 팝업에만 제공해요. 이 옵션이 있으면 X 버튼도 함께 필요해요.
import { Popup, Button } from '@polarisoffice/pds-react';
<Popup
open={open}
onClose={close}
closable
title="Title"
dontShowAgain
onDontShowAgainChange={setSkip}
footer={<Button variant="primary">확인</Button>}
>
Body 내용이 들어가는 영역입니다.
</Popup>