@olundot/ui · Surfaces
ConfirmDialog
되돌리기 어렵거나 결과가 큰 action을 실행하기 전, 사용자의 명시적 확인을 받는 모달 조합입니다.
- 상태 제어
- open과 onOpenChange를 필수로 받아 호출부가 열림 상태를 소유합니다.
- tone
- default는 일반 승인, destructive는 삭제·취소처럼 위험한 action에 사용합니다.
- onConfirm
- 동기와 비동기 함수를 모두 지원하며 처리 중에는 중복 실행과 닫기를 막습니다.
- 레이블
- confirmLabel은 action 결과를 구체적으로 말해야 합니다. '확인'만으로 끝내지 않습니다.
기본 확인
기본 tone과 비동기 확인코드 보기tsx
import { useState } from "react";
import { Button, ConfirmDialog } from "@olundot/ui";
export function ConfirmDialogDefault() {
const [open, setOpen] = useState(false);
const [confirmed, setConfirmed] = useState(false);
return (
<div style={{ display: "grid", gap: "12px" }}>
<Button variant="primary" onClick={() => setOpen(true)}>
승인 요청
</Button>
<ConfirmDialog
open={open}
onOpenChange={setOpen}
title="요청을 승인할까요?"
description="승인하면 담당자에게 검토 완료 알림이 전송됩니다."
confirmLabel="승인"
cancelLabel="취소"
onConfirm={async () => {
await new Promise((resolve) => setTimeout(resolve, 800));
setConfirmed(true);
}}
/>
{confirmed ? <p>승인 처리되었습니다.</p> : null}
</div>
);
}파괴적 확인
destructive tone과 구체적인 action label코드 보기tsx
import { useState } from "react";
import { Button, ConfirmDialog } from "@olundot/ui";
export function ConfirmDialogDestructive() {
const [open, setOpen] = useState(false);
return (
<>
<Button variant="destructive" onClick={() => setOpen(true)}>
제출 취소
</Button>
<ConfirmDialog
open={open}
onOpenChange={setOpen}
title="제출을 취소하시겠습니까?"
description="취소하면 현재 채점 대기열에서 빠지고, 학생에게 다시 제출 요청을 보내야 합니다."
tone="destructive"
confirmLabel="제출 취소"
cancelLabel="돌아가기"
onConfirm={async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
}}
/>
</>
);
}외부 loading
loading prop으로 닫기 방지코드 보기tsx
import { useState } from "react";
import { Button, ConfirmDialog } from "@olundot/ui";
export function ConfirmDialogLoading() {
const [open, setOpen] = useState(false);
const [loading, setLoading] = useState(false);
async function handleConfirm() {
setLoading(true);
await new Promise((resolve) => setTimeout(resolve, 1200));
setLoading(false);
}
return (
<>
<Button variant="outline" onClick={() => setOpen(true)}>
재계산 실행
</Button>
<ConfirmDialog
open={open}
onOpenChange={setOpen}
title="점수를 다시 계산할까요?"
description="계산 중에는 창을 닫을 수 없고, 완료 후 결과가 갱신됩니다."
confirmLabel="재계산"
loading={loading}
onConfirm={handleConfirm}
/>
</>
);
}