저장되었습니다.
변경 사항을 안전하게 저장했습니다.
짧고 중요한 알림과 확인 결정을 native modal dialog와 명시적인 종료 사유로 표준화합니다.
owned action, exact close reason, focus 복원, 긴 설명의 내부 scroll을 확인하세요.
변경 사항을 안전하게 저장했습니다.
AlertDialog는 사용자가 반드시 확인해야 하는 짧은 결과나 상태를 한 가지 acknowledgement action과 함께 전달할 때 사용합니다. ConfirmDialog는 취소와 진행 중 하나를 선택해야 하는 삭제, 제출, 상태 변경 같은 짧고 중요한 결정에 사용합니다.
여러 단계를 거치는 입력, 긴 탐색, URL로 공유해야 하는 정보에는 page나 별도 flow를 사용합니다. 단순한 비차단 피드백은 Toast가 적합하고, 현재 문맥 안에서 더 많은 선택 콘텐츠가 필요하면 BottomSheet를 사용합니다. close icon, 임의 action slot, danger tone은 이 계약에 추가하지 않습니다.
두 variant는 hydration 뒤 document.body 또는 portalContainer로 native dialog를 Portal합니다. 공통 surface는 stable ID로 연결된 visible title, 선택 description을 가진 내부 scroll body, body와 분리된 owned action 영역으로 구성됩니다. AlertDialog는 action 하나, ConfirmDialog는 cancel 다음 confirm 순서의 action 두 개를 소유합니다.
surface는 viewport에서 24px 이상 떨어진 중앙에 놓이고 최대 너비는 384px입니다. Alert와 Confirm은 action 개수와 close reason 계약이 다르며 description 유무는 content가 결정합니다. Figma 계약은 Type=Alert|Confirm × Description=Hidden|Visible 네 variant이고 React는 별도 size prop을 노출하지 않습니다.
open은 controlled입니다. Alert action은 alert-button, Confirm의 두 action은 DOM 순서대로 cancel-button, confirm-button을 전달합니다. 기본 dismissible=true일 때 Escape는 escape, 같은 pointer가 backdrop에서 시작하고 끝나면 backdrop을 전달합니다. dismissible=false는 Escape와 backdrop만 막고 visible action은 남깁니다. confirm loading은 confirm action에만 aria-busy와 disabled를 적용합니다.
surface는 320px viewport에서도 dialog padding 안에 유지되고 action copy가 길면 각 action 안에서 줄바꿈됩니다. body의 긴 localized·unbroken description만 내부에서 scroll되며 action 영역은 계속 보입니다. mobile, tablet, desktop 모두 같은 중앙 modal geometry를 유지합니다.
Alert는 role="alertdialog", Confirm은 native dialog semantics를 사용하고 두 variant 모두 aria-modal, aria-labelledby, 선택적인 aria-describedby를 갖습니다. Alert는 acknowledgement action, Confirm은 덜 파괴적인 cancel action으로 초기 focus를 이동합니다. Tab과 Shift+Tab은 modal 안에 머물고 exit 뒤 열기 전 active element로 focus를 복원합니다. reduced motion에서는 exit를 즉시 끝내며 forced colors에서는 system surface와 text를 사용합니다.
import { useState } from 'react';
import {
Button,
ConfirmDialog,
type ConfirmDialogCloseReason,
} from '@hds/react';
import '@hds/react/styles.css';
export function DeleteConfirmation() {
const [open, setOpen] = useState(false);
function handleOpenChange(
nextOpen: boolean,
reason: ConfirmDialogCloseReason,
) {
if (reason === 'confirm-button') {
console.info('delete requested');
}
setOpen(nextOpen);
}
return (
<>
<Button onClick={() => setOpen(true)}>삭제</Button>
<ConfirmDialog
cancelLabel="취소"
confirmLabel="삭제"
description="삭제하면 되돌릴 수 없습니다."
open={open}
title="삭제할까요?"
onOpenChange={handleOpenChange}
/>
</>
);
}
| Prop | Type | Default | 설명 |
|---|---|---|---|
open |
boolean |
required | controlled open state |
title |
string |
required | visible accessible heading |
description |
string |
- | 내부 scroll 가능한 accessible description |
alertLabel |
string |
Alert required | Alert acknowledgement label |
cancelLabel |
string |
Confirm required | Confirm cancel label |
confirmLabel |
string |
Confirm required | Confirm action label |
confirmDisabled |
boolean |
false |
confirm action의 disabled 상태 |
confirmLoading |
boolean |
false |
confirm action의 loading 상태 |
dismissible |
boolean |
true |
Escape와 backdrop 허용 여부 |
portalContainer |
HTMLElement | null |
document.body after hydration |
Portal container |
onOpenChange |
Alert 또는 Confirm close reason callback |
required | exact 종료 사유를 가진 controlled request |
...rootProps |
Omit<HTMLAttributes<HTMLDivElement>, 'children' | 'title'> |
- | surface의 safe native root attributes |
AlertDialogCloseReason은 'alert-button' | 'backdrop' | 'escape'이고 ConfirmDialogCloseReason은 'cancel-button' | 'confirm-button' | 'backdrop' | 'escape'입니다.
size/control/small, size/control/large, size/icon/medium, space/0, space/2, space/4, space/8, space/12, space/16, space/24, space/64, radius/sm, radius/md, radius/xl, radius/fullfont/family/sans, font/size/body, font/size/body-lg, font/size/title-sm, font/weight/semibold, font/line-height/body, font/line-height/body-lg, font/line-height/title-sm, elevation/2, motion/duration/fast, motion/duration/medium, motion/easing/standardcolor/bg/scrim, color/bg/surface, color/bg/subtle, color/text/primary, color/text/secondary, color/text/disabled, color/border/default, color/action/primary, color/action/primary-hover, color/action/primary-pressed, color/action/on-primary, color/focus/ringlive Dialog component set은 Type Alert/Confirm × Description Hidden/Visible = 4 variants와 Title, Description, Alert label, Cancel label, Confirm label TEXT property, Show description BOOLEAN property를 가집니다. 구현은 TDS Mobile Dialog overview, AlertDialog reference, ConfirmDialog reference를 참고하되, 이 저장소는 native dialog와 controlled exact-reason API를 유지합니다.
| React | Svelte | React Native |
|---|---|---|
| preview | planned | planned |