Stack
수직/수평 스택 레이아웃 컴포넌트입니다.
개요
Stack은 요소들을 수직 또는 수평으로 정렬하는 레이아웃 컴포넌트입니다. iCignal Stack은 분석 도구와 대시보드 UI에 최적화된 간격과 정렬을 제공하며, Foundation Stack의 모든 기능을 상속합니다.
주요 특징:
- 수직/수평 방향
- Spacing 옵션
- Alignment 옵션
- Wrap 옵션
- iCignal 대시보드 UI 최적화
사용 사례:
- iCignal Analytics 버튼 그룹
- 리포트 필터 레이아웃
- 데이터 입력 폼
- 대시보드 툴바
알림: 이 컴포넌트는 현재 구현 중입니다. 임시로 Tailwind CSS Flex를 사용할 수 있습니다.
기본 사용법
import "@vortex/ui-icignal/theme"; // iCignal 테마 적용
<div className="flex flex-col gap-md">
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</div>;Variants (변형)
수직 스택 (기본)
<div className="flex flex-col gap-md">
<Button>버튼 1</Button>
<Button>버튼 2</Button>
<Button>버튼 3</Button>
</div>수평 스택
<div className="flex flex-row gap-md">
<Button>버튼 1</Button>
<Button>버튼 2</Button>
<Button>버튼 3</Button>
</div>iCignal 브랜딩
iCignal 특화 사용 가이드
Analytics 대시보드 툴바:
import { Button } from "@vortex/ui-icignal";
import { Download, Share2, Filter, RefreshCw } from "lucide-react";
<div className="flex items-center justify-between p-md bg-white border-b">
<h2 className="text-xl font-semibold">Analytics Dashboard</h2>
<div className="flex gap-sm">
<Button variant="outline" size="sm">
<Filter size={16} className="mr-xs" />
필터
</Button>
<Button variant="ghost" size="sm">
<RefreshCw size={16} className="mr-xs" />
새로고침
</Button>
<Button variant="outline" size="sm">
<Share2 size={16} className="mr-xs" />
공유
</Button>
<Button variant="primary" size="sm">
<Download size={16} className="mr-xs" />
내보내기
</Button>
</div>
</div>;리포트 필터 레이아웃:
import { Select, Input, Button } from "@vortex/ui-icignal";
import { Calendar, Search } from "lucide-react";
<div className="flex flex-col gap-md p-md bg-gray-50 rounded-lg">
<div className="flex gap-md">
<div className="flex-1">
<label className="text-sm font-medium mb-xs block">기간</label>
<Select>
<option>최근 7일</option>
<option>최근 30일</option>
<option>최근 90일</option>
</Select>
</div>
<div className="flex-1">
<label className="text-sm font-medium mb-xs block">카테고리</label>
<Select>
<option>전체</option>
<option>트래픽</option>
<option>전환</option>
</Select>
</div>
</div>
<div className="flex gap-sm">
<Input
placeholder="검색..."
className="flex-1"
icon={<Search size={16} />}
/>
<Button variant="primary">적용</Button>
<Button variant="outline">초기화</Button>
</div>
</div>;데이터 입력 폼:
import { Input, Button } from "@vortex/ui-icignal";
<div className="flex flex-col gap-md max-w-md">
<div>
<label className="text-sm font-medium mb-xs block">캠페인 이름</label>
<Input placeholder="예: 신규 고객 유치" />
</div>
<div>
<label className="text-sm font-medium mb-xs block">목표</label>
<Input placeholder="예: 전환율 3% 달성" />
</div>
<div>
<label className="text-sm font-medium mb-xs block">예산</label>
<Input type="number" placeholder="1000000" />
</div>
<div className="flex gap-md pt-md">
<Button variant="outline" className="flex-1">
취소
</Button>
<Button variant="primary" className="flex-1">
캠페인 생성
</Button>
</div>
</div>;대시보드 액션 그룹:
import { Button } from "@vortex/ui-icignal";
import { Play, Pause, Stop, Settings } from "lucide-react";
<Card>
<CardHeader>
<h3 className="font-semibold">실시간 모니터링</h3>
</CardHeader>
<CardContent>
<div className="flex flex-col gap-md">
<div className="flex justify-between items-center">
<span className="text-sm text-gray-600">상태</span>
<Badge variant="success">실행 중</Badge>
</div>
<div className="flex gap-sm">
<Button variant="outline" size="sm" className="flex-1">
<Pause size={16} className="mr-xs" />
일시정지
</Button>
<Button variant="outline" size="sm" className="flex-1">
<Stop size={16} className="mr-xs" />
중지
</Button>
<Button variant="ghost" size="sm">
<Settings size={16} />
</Button>
</div>
</div>
</CardContent>
</Card>;Foundation과의 차이점
| 속성 | Foundation | iCignal |
|---|---|---|
| 기본 Gap | md | sm (UI 밀도 최적화) |
| 브랜드 적용 | 없음 | iCignal 툴바/필터 패턴 |
| 사용 맥락 | 범용 | Analytics Dashboard 특화 |
| 정렬 설정 | 표준 | 대시보드 액션 그룹 최적화 |
| 테마 | 중립적 테마 | iCignal 테마 (@vortex/ui-icignal/theme) |
사용 패턴 차이:
// Foundation - 범용 스택
<div className="flex gap-md">
<Button>버튼 1</Button>
<Button>버튼 2</Button>
</div>
// iCignal - Dashboard Toolbar
<div className="flex items-center justify-between">
<h2>Title</h2>
<div className="flex gap-sm">
<Button variant="outline" size="sm">액션 1</Button>
<Button variant="primary" size="sm">액션 2</Button>
</div>
</div>예제
예제 1: iCignal 대시보드 헤더
import "@vortex/ui-icignal/theme";
import { Button, Select, Input } from "@vortex/ui-icignal";
import { Download, Filter, Calendar, Search, Bell } from "lucide-react";
export default function DashboardHeader() {
return (
<div className="flex flex-col gap-md p-lg bg-white border-b">
{/* Title Row */}
<div className="flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold">Analytics Dashboard</h1>
<p className="text-sm text-gray-600">실시간 데이터 모니터링</p>
</div>
<div className="flex items-center gap-sm">
<Button variant="ghost" size="sm">
<Bell size={16} />
</Button>
<Button variant="outline" size="sm">
<Download size={16} className="mr-xs" />
내보내기
</Button>
<Button variant="primary" size="sm">
<Calendar size={16} className="mr-xs" />
기간 설정
</Button>
</div>
</div>
{/* Filter Row */}
<div className="flex items-center gap-md">
<Select className="w-48">
<option>최근 7일</option>
<option>최근 30일</option>
<option>최근 90일</option>
</Select>
<Select className="w-48">
<option>전체 카테고리</option>
<option>트래픽</option>
<option>전환</option>
</Select>
<Input
placeholder="검색..."
className="flex-1"
icon={<Search size={16} />}
/>
<Button variant="outline" size="sm">
<Filter size={16} className="mr-xs" />
필터
</Button>
</div>
</div>
);
}예제 2: iCignal 리포트 생성 폼
import "@vortex/ui-icignal/theme";
import { Input, Select, Button, Textarea } from "@vortex/ui-icignal";
import { FileText, Calendar } from "lucide-react";
export default function ReportForm() {
return (
<div className="max-w-2xl mx-auto p-lg">
<div className="flex items-center gap-md mb-lg">
<FileText size={32} className="text-icignal-blue" />
<div>
<h2 className="text-2xl font-bold">새 리포트 생성</h2>
<p className="text-sm text-gray-600">분석 리포트를 생성합니다</p>
</div>
</div>
<div className="flex flex-col gap-lg">
{/* Basic Info */}
<div className="flex flex-col gap-md">
<div>
<label className="text-sm font-medium mb-xs block">
리포트 제목
</label>
<Input placeholder="예: 월간 트래픽 분석" />
</div>
<div>
<label className="text-sm font-medium mb-xs block">설명</label>
<Textarea placeholder="리포트 설명을 입력하세요..." rows={3} />
</div>
</div>
{/* Date Range */}
<div className="flex gap-md">
<div className="flex-1">
<label className="text-sm font-medium mb-xs block">시작일</label>
<Input type="date" icon={<Calendar size={16} />} />
</div>
<div className="flex-1">
<label className="text-sm font-medium mb-xs block">종료일</label>
<Input type="date" icon={<Calendar size={16} />} />
</div>
</div>
{/* Options */}
<div className="flex gap-md">
<div className="flex-1">
<label className="text-sm font-medium mb-xs block">
리포트 유형
</label>
<Select>
<option>트래픽 분석</option>
<option>사용자 행동</option>
<option>전환 분석</option>
</Select>
</div>
<div className="flex-1">
<label className="text-sm font-medium mb-xs block">포맷</label>
<Select>
<option>PDF</option>
<option>Excel</option>
<option>CSV</option>
</Select>
</div>
</div>
{/* Actions */}
<div className="flex gap-md pt-md border-t">
<Button variant="outline" className="flex-1">
취소
</Button>
<Button variant="primary" className="flex-1">
리포트 생성
</Button>
</div>
</div>
</div>
);
}관련 컴포넌트
- Foundation Stack - 기본 버전 참조
- Container - 레이아웃 컨테이너
- Grid - 그리드 레이아웃
- Button - 액션 버튼
Last updated on