Dialog
모달 대화상자 컴포넌트입니다.
개요
Dialog는 사용자의 주의를 집중시키는 모달 대화상자 컴포넌트입니다. iCignal Dialog는 iCignal 브랜드 스타일이 적용되어 있으며, 분석 설정과 데이터 관리 작업에 최적화되어 있습니다. Foundation Dialog의 모든 기능을 상속합니다.
주요 특징:
- 모달 오버레이
- 제목/내용/푸터 구조
- 닫기 버튼
- 키보드 ESC 지원
- iCignal 브랜드 스타일 적용
사용 사례:
- iCignal 분석 설정 대화상자
- 데이터 삭제 확인
- 리포트 생성 옵션 선택
- 캠페인 상세 정보
설치
npx @vortex/cli add dialog --package icignal기본 사용법
import "@vortex/ui-icignal/theme"; // iCignal 테마 적용
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
} from "@vortex/ui-icignal";
import { Button } from "@vortex/ui-icignal";
export default function Example() {
return (
<Dialog>
<DialogTrigger asChild>
<Button>대화상자 열기</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>제목</DialogTitle>
</DialogHeader>
<p>내용</p>
</DialogContent>
</Dialog>
);
}iCignal 브랜딩
iCignal 특화 사용 가이드
분석 설정 대화상자:
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@vortex/ui-icignal";
import { Button, Select, Input } from "@vortex/ui-icignal";
import { Settings, Calendar } from "lucide-react";
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className="max-w-2xl">
<DialogHeader>
<Settings size={24} className="text-icignal-blue mb-sm" />
<DialogTitle>분석 설정</DialogTitle>
</DialogHeader>
<div className="space-y-md">
<div>
<label className="text-sm font-medium mb-xs block">분석 기간</label>
<Select>
<option>최근 7일</option>
<option>최근 30일</option>
<option>최근 90일</option>
<option>사용자 지정</option>
</Select>
</div>
<div>
<label className="text-sm font-medium mb-xs block">데이터 소스</label>
<Select>
<option>전체</option>
<option>웹사이트</option>
<option>모바일 앱</option>
</Select>
</div>
<div>
<label className="text-sm font-medium mb-xs block">샘플링 비율</label>
<Input type="number" defaultValue="100" min="1" max="100" />
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setOpen(false)}>
취소
</Button>
<Button variant="primary">설정 적용</Button>
</DialogFooter>
</DialogContent>
</Dialog>;데이터 삭제 확인:
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@vortex/ui-icignal";
import { Button, Alert, AlertDescription } from "@vortex/ui-icignal";
import { Trash2, AlertTriangle } from "lucide-react";
<Dialog open={deleteOpen} onOpenChange={setDeleteOpen}>
<DialogContent>
<DialogHeader>
<AlertTriangle size={32} className="text-red-600 mb-sm" />
<DialogTitle>데이터 삭제 확인</DialogTitle>
</DialogHeader>
<Alert variant="warning">
<AlertDescription>
이 작업은 되돌릴 수 없습니다. 45,231건의 분석 데이터가 영구적으로
삭제됩니다.
</AlertDescription>
</Alert>
<p className="text-sm text-gray-600 mt-md">
정말로 선택한 데이터를 삭제하시겠습니까?
</p>
<DialogFooter className="mt-lg">
<Button variant="outline" onClick={() => setDeleteOpen(false)}>
취소
</Button>
<Button variant="destructive" onClick={handleDelete}>
<Trash2 size={16} className="mr-xs" />
영구 삭제
</Button>
</DialogFooter>
</DialogContent>
</Dialog>;리포트 생성 옵션:
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@vortex/ui-icignal";
import { Button, Checkbox, Select } from "@vortex/ui-icignal";
import { FileText } from "lucide-react";
<Dialog open={reportOpen} onOpenChange={setReportOpen}>
<DialogContent className="max-w-lg">
<DialogHeader>
<FileText size={24} className="text-icignal-blue mb-sm" />
<DialogTitle>리포트 생성 옵션</DialogTitle>
</DialogHeader>
<div className="space-y-md">
<div>
<label className="text-sm font-medium mb-xs block">포함 항목</label>
<div className="space-y-sm">
<Checkbox label="트래픽 분석" defaultChecked />
<Checkbox label="사용자 행동" defaultChecked />
<Checkbox label="전환 분석" defaultChecked />
<Checkbox label="A/B 테스트 결과" />
</div>
</div>
<div>
<label className="text-sm font-medium mb-xs block">파일 형식</label>
<Select>
<option>PDF</option>
<option>Excel</option>
<option>PowerPoint</option>
</Select>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setReportOpen(false)}>
취소
</Button>
<Button variant="primary">리포트 생성</Button>
</DialogFooter>
</DialogContent>
</Dialog>;Foundation과의 차이점
| 속성 | Foundation | iCignal |
|---|---|---|
| 스타일 | 중립적 | iCignal 브랜드 강조 |
| 브랜드 적용 | 없음 | iCignal 아이콘 및 색상 |
| 사용 맥락 | 범용 | Analytics/Reports 특화 |
| 내용 | 일반적 | 데이터 관리 작업 맥락 |
| 테마 | 중립적 테마 | iCignal 테마 (@vortex/ui-icignal/theme) |
import 경로 차이:
// Foundation
import { Dialog } from "@vortex/ui-foundation";
// iCignal
import "@vortex/ui-icignal/theme"; // 테마 import 필수
import { Dialog } from "@vortex/ui-icignal";Props API
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | false | 열림 상태 |
| onOpenChange | (open) => void | - | 상태 변경 핸들러 |
예제
예제 1: iCignal 분석 필터 설정
import "@vortex/ui-icignal/theme";
import {
Dialog,
DialogTrigger,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@vortex/ui-icignal";
import { Button, Select, Input } from "@vortex/ui-icignal";
import { Filter, Calendar } from "lucide-react";
import { useState } from "react";
export default function AnalyticsFilter() {
const [open, setOpen] = useState(false);
const [filters, setFilters] = useState({
period: "30days",
source: "all",
device: "all",
});
const handleApply = () => {
console.log("Applying filters:", filters);
setOpen(false);
toast.success("필터가 적용되었습니다.");
};
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="outline">
<Filter size={16} className="mr-xs" />
필터
</Button>
</DialogTrigger>
<DialogContent className="max-w-lg">
<DialogHeader>
<Filter size={24} className="text-icignal-blue mb-sm" />
<DialogTitle>분석 필터 설정</DialogTitle>
</DialogHeader>
<div className="space-y-lg">
<div>
<label className="text-sm font-medium mb-xs block">분석 기간</label>
<Select
value={filters.period}
onChange={(e) =>
setFilters({ ...filters, period: e.target.value })
}
>
<option value="7days">최근 7일</option>
<option value="30days">최근 30일</option>
<option value="90days">최근 90일</option>
<option value="custom">사용자 지정</option>
</Select>
</div>
<div>
<label className="text-sm font-medium mb-xs block">
데이터 소스
</label>
<Select
value={filters.source}
onChange={(e) =>
setFilters({ ...filters, source: e.target.value })
}
>
<option value="all">전체</option>
<option value="web">웹사이트</option>
<option value="mobile">모바일 앱</option>
<option value="api">API</option>
</Select>
</div>
<div>
<label className="text-sm font-medium mb-xs block">디바이스</label>
<Select
value={filters.device}
onChange={(e) =>
setFilters({ ...filters, device: e.target.value })
}
>
<option value="all">전체</option>
<option value="desktop">데스크톱</option>
<option value="mobile">모바일</option>
<option value="tablet">태블릿</option>
</Select>
</div>
</div>
<DialogFooter className="mt-lg">
<Button variant="outline" onClick={() => setOpen(false)}>
취소
</Button>
<Button variant="primary" onClick={handleApply}>
필터 적용
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}예제 2: iCignal 데이터 내보내기
import "@vortex/ui-icignal/theme";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogFooter,
} from "@vortex/ui-icignal";
import { Button, Checkbox, Select, Alert } from "@vortex/ui-icignal";
import { Download } from "lucide-react";
import { useState } from "react";
export default function ExportDialog() {
const [open, setOpen] = useState(false);
const [options, setOptions] = useState({
format: "csv",
includeMetadata: true,
compressFile: false,
});
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="primary">
<Download size={16} className="mr-xs" />
데이터 내보내기
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<Download size={24} className="text-icignal-blue mb-sm" />
<DialogTitle>데이터 내보내기</DialogTitle>
</DialogHeader>
<Alert variant="info">
<AlertDescription>
45,231건의 분석 데이터를 내보냅니다.
</AlertDescription>
</Alert>
<div className="space-y-md mt-md">
<div>
<label className="text-sm font-medium mb-xs block">파일 형식</label>
<Select
value={options.format}
onChange={(e) =>
setOptions({ ...options, format: e.target.value })
}
>
<option value="csv">CSV</option>
<option value="excel">Excel</option>
<option value="json">JSON</option>
</Select>
</div>
<div className="space-y-sm">
<Checkbox
label="메타데이터 포함"
checked={options.includeMetadata}
onChange={(checked) =>
setOptions({ ...options, includeMetadata: checked })
}
/>
<Checkbox
label="압축 파일로 다운로드"
checked={options.compressFile}
onChange={(checked) =>
setOptions({ ...options, compressFile: checked })
}
/>
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setOpen(false)}>
취소
</Button>
<Button variant="primary">
<Download size={16} className="mr-xs" />
내보내기
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
}관련 컴포넌트
- Foundation Dialog - 기본 버전 참조
- Alert - 알림 메시지
- Button - 액션 버튼
- Select - 선택 입력
Last updated on