Dialog

Dialog는 페이지 위에 모달 형태로 정보를 표시하거나 작업을 수행하도록 하는 컴포넌트입니다.
import { Button, Dialog } from '@vapor-ui/core';

export default function DefaultDialog() {
    return (
        <Dialog.Root>
            <Dialog.Trigger render={<Button />}>클릭</Dialog.Trigger>
            <Dialog.Content>
                <Dialog.Header>
                    <Dialog.Title>알림</Dialog.Title>
                    <Dialog.Close aria-label="Close" />
                </Dialog.Header>
                <Dialog.Body>
                    <Dialog.Description>
                        여기에 다이얼로그 본문 내용이 들어갑니다.
                    </Dialog.Description>
                </Dialog.Body>
                <Dialog.Footer style={{ marginLeft: 'auto' }}>
                    <Button color="primary">확인</Button>
                </Dialog.Footer>
            </Dialog.Content>
        </Dialog.Root>
    );
}

Property


Size

Dialog 사이즈는 md, lg, xl로 제공합니다.

import { Button, Dialog } from '@vapor-ui/core';

export default function DialogSize() {
    return (
        <div className="flex gap-4">
            <Dialog.Root size="md">
                <Dialog.Trigger render={<Button>Medium Dialog</Button>} />
                <Dialog.Content>
                    <Dialog.Header>
                        <Dialog.Title>Medium Size</Dialog.Title>
                    </Dialog.Header>
                    <Dialog.Body>
                        <Dialog.Description>Medium 크기의 다이얼로그입니다.</Dialog.Description>
                    </Dialog.Body>
                    <Dialog.Footer>
                        <Dialog.Close render={<Button variant="ghost">취소</Button>} />
                        <Button>확인</Button>
                    </Dialog.Footer>
                </Dialog.Content>
            </Dialog.Root>

            <Dialog.Root size="lg">
                <Dialog.Trigger render={<Button>Large Dialog</Button>} />
                <Dialog.Content>
                    <Dialog.Header>
                        <Dialog.Title>Large Size</Dialog.Title>
                    </Dialog.Header>
                    <Dialog.Body>
                        <Dialog.Description>Large 크기의 다이얼로그입니다.</Dialog.Description>
                    </Dialog.Body>
                    <Dialog.Footer>
                        <Dialog.Close render={<Button variant="ghost">취소</Button>} />
                        <Button>확인</Button>
                    </Dialog.Footer>
                </Dialog.Content>
            </Dialog.Root>

            <Dialog.Root size="xl">
                <Dialog.Trigger render={<Button>Extra Large Dialog</Button>} />
                <Dialog.Content>
                    <Dialog.Header>
                        <Dialog.Title>Extra Large Size</Dialog.Title>
                    </Dialog.Header>
                    <Dialog.Body>
                        <Dialog.Description>
                            Extra Large 크기의 다이얼로그입니다.
                        </Dialog.Description>
                    </Dialog.Body>
                    <Dialog.Footer>
                        <Dialog.Close render={<Button variant="ghost">취소</Button>} />
                        <Button>확인</Button>
                    </Dialog.Footer>
                </Dialog.Content>
            </Dialog.Root>
        </div>
    );
}

Dialog의 모달 동작을 제어할 수 있습니다.

import { Button, Dialog } from '@vapor-ui/core';

export default function DialogModal() {
    return (
        <div className="flex gap-4">
            <Dialog.Root modal={true}>
                <Dialog.Trigger render={<Button>Modal Dialog</Button>} />
                <Dialog.Content>
                    <Dialog.Header>
                        <Dialog.Title>Modal Dialog</Dialog.Title>
                    </Dialog.Header>
                    <Dialog.Body>
                        <Dialog.Description>
                            포커스가 다이얼로그 내부에 제한됩니다.
                        </Dialog.Description>
                    </Dialog.Body>
                    <Dialog.Footer>
                        <Dialog.Close render={<Button>확인</Button>} />
                    </Dialog.Footer>
                </Dialog.Content>
            </Dialog.Root>

            <Dialog.Root modal={false}>
                <Dialog.Trigger render={<Button>Non-Modal Dialog</Button>} />
                <Dialog.Content>
                    <Dialog.Header>
                        <Dialog.Title>Non-Modal Dialog</Dialog.Title>
                    </Dialog.Header>
                    <Dialog.Body>
                        <Dialog.Description>
                            배경의 다른 요소들과 상호작용할 수 있습니다.
                        </Dialog.Description>
                    </Dialog.Body>
                    <Dialog.Footer>
                        <Dialog.Close render={<Button>확인</Button>} />
                    </Dialog.Footer>
                </Dialog.Content>
            </Dialog.Root>
        </div>
    );
}

Examples


Simple Usage

기본적인 Dialog 사용법입니다.

import { Button, Dialog } from '@vapor-ui/core';

export default function DialogSimple() {
    return (
        <Dialog.Root>
            <Dialog.Trigger render={<Button>단순 다이얼로그 열기</Button>} />
            <Dialog.Content>
                <Dialog.Header>
                    <Dialog.Title>알림</Dialog.Title>
                </Dialog.Header>
                <Dialog.Body>
                    <Dialog.Description>
                        이것은 기본적인 다이얼로그입니다. Escape 키나 배경 클릭으로 닫을 수
                        있습니다.
                    </Dialog.Description>
                </Dialog.Body>
                <Dialog.Footer>
                    <Dialog.Close render={<Button>확인</Button>} />
                </Dialog.Footer>
            </Dialog.Content>
        </Dialog.Root>
    );
}

Composition Pattern

Dialog.Root, Dialog.Trigger, Dialog.CombinedContent, Dialog.Header, Dialog.Body, Dialog.Footer를 조합한 패턴입니다.

import { Button, Dialog } from '@vapor-ui/core';

export default function DialogComposition() {
    return (
        <Dialog.Root size="lg" closeOnClickOverlay={false}>
            <Dialog.Trigger render={<Button variant="outline">확인 다이얼로그</Button>} />
            <Dialog.Content>
                <Dialog.Header>
                    <Dialog.Title>작업 확인</Dialog.Title>
                </Dialog.Header>
                <Dialog.Body>
                    <Dialog.Description>
                        이 작업을 진행하시겠습니까? 이 작업은 되돌릴 수 없습니다.
                    </Dialog.Description>
                </Dialog.Body>
                <Dialog.Footer>
                    <Dialog.Close render={<Button variant="ghost">취소</Button>} />
                    <Dialog.Close render={<Button color="danger">삭제</Button>} />
                </Dialog.Footer>
            </Dialog.Content>
        </Dialog.Root>
    );
}

Size & Modal Variants

다양한 크기와 모달 설정을 조합한 예시입니다.

import { Button, Dialog } from '@vapor-ui/core';

export default function DialogVariants() {
    return (
        <div className="flex gap-4">
            <Dialog.Root size="md" closeOnClickOverlay={false}>
                <Dialog.Trigger render={<Button>Medium + Prevent Overlay Click</Button>} />
                <Dialog.Content>
                    <Dialog.Header>
                        <Dialog.Title>Medium Size</Dialog.Title>
                    </Dialog.Header>
                    <Dialog.Body>
                        <Dialog.Description>Overlay 클릭 시 닫을 수 없습니다.</Dialog.Description>
                    </Dialog.Body>
                    <Dialog.Footer>
                        <Dialog.Close render={<Button>확인</Button>} />
                    </Dialog.Footer>
                </Dialog.Content>
            </Dialog.Root>

            <Dialog.Root size="xl" modal={false}>
                <Dialog.Trigger render={<Button>XL + Non-Modal</Button>} />
                <Dialog.Content>
                    <Dialog.Header>
                        <Dialog.Title>Extra Large Size</Dialog.Title>
                    </Dialog.Header>
                    <Dialog.Body>
                        <Dialog.Description>
                            매우 큰 크기의 non-modal 다이얼로그입니다. 배경과 상호작용이 가능합니다.
                        </Dialog.Description>
                    </Dialog.Body>
                    <Dialog.Footer>
                        <Dialog.Close render={<Button>확인</Button>} />
                    </Dialog.Footer>
                </Dialog.Content>
            </Dialog.Root>
        </div>
    );
}

Props Table


Dialog.Root

Dialog의 루트 컨테이너로, 다이얼로그의 상태와 동작을 관리합니다. 크기, 모달 동작, 열림/닫힘 상태를 제어할 수 있습니다.

PropDefaultType
defaultOpen?
null
boolean
open?
null
boolean
onOpenChange?
null
function
modal?
true
boolean
dismissible?
true
boolean
size?
"md"
"md""lg""xl"

Dialog.Portal

Dialog 콘텐츠를 document.body 또는 지정된 컨테이너에 렌더링합니다. 다이얼로그가 다른 요소들 위에 표시되도록 보장합니다.

PropDefaultType
keepMounted?
false
boolean
container?
document.body
HTMLElement

Dialog.Overlay

Dialog의 배경 오버레이입니다. 다이얼로그 외부 영역을 어둡게 하고 클릭 이벤트를 처리합니다.

PropDefaultType
render?
div
ReactElement
keepMounted?
false
boolean
className?
null
string

Dialog.Content

Dialog의 실제 콘텐츠 영역입니다. Portal과 Overlay를 별도로 구성해야 합니다. 세밀한 제어가 필요할 때 사용합니다.

PropDefaultType
render?
div
ReactElement
initialFocus?
null
function
finalFocus?
null
function
className?
null
string

Dialog.CombinedContent

Portal, Overlay, Content가 통합된 편의 컴포넌트입니다. 대부분의 경우 이 컴포넌트를 사용하는 것을 권장합니다.

PropDefaultType
className?
null
string
children?
null
React.ReactNode

Dialog.Trigger

Dialog를 여는 트리거 버튼입니다. render prop을 통해 커스텀 요소로 렌더링할 수 있습니다.

PropDefaultType
render?
button
ReactElement
className?
null
string

Dialog.Close

Dialog를 닫는 버튼입니다. 다이얼로그 내 어디든 배치할 수 있으며, render prop을 통해 커스텀 요소로 사용할 수 있습니다.

PropDefaultType
render?
button
ReactElement
className?
null
string

Dialog.Title

Dialog의 제목입니다. 접근성을 위해 필수로 포함해야 하며, 스크린 리더가 다이얼로그를 식별할 때 사용됩니다.

PropDefaultType
render?
h2
ReactElement
className?
null
string

Dialog.Description

Dialog의 설명 텍스트입니다. 스크린 리더 사용자에게 추가 컨텍스트를 제공하기 위해 사용하는 것을 권장합니다.

PropDefaultType
render?
p
ReactElement
className?
null
string

Dialog.Header

Dialog의 상단 영역입니다. 일반적으로 Title과 Close 버튼을 배치합니다.

PropDefaultType
render?
div
ReactElement
className?
null
string
children?
null
React.ReactNode

Dialog.Body

Dialog의 중앙 콘텐츠 영역입니다. Description과 주요 내용을 배치합니다.

PropDefaultType
render?
div
ReactElement
className?
null
string
children?
null
React.ReactNode

Dialog.Footer

Dialog의 하단 영역입니다. 확인, 취소 등의 액션 버튼들을 배치합니다.

PropDefaultType
render?
div
ReactElement
className?
null
string
children?
null
React.ReactNode