Progress
진행 상태를 표시하는 프로그레스 바 컴포넌트입니다.
개요
Progress는 작업이나 프로세스의 진행 상태를 시각적으로 표시하는 컴포넌트입니다. Cals Progress는 Cals 브랜드 스타일과 예약 상태 컬러가 적용되어 있으며, 예약 진행 상태, 서비스 완료율, 예약 채움률 표시에 최적화되어 있습니다. Foundation Progress의 모든 기능을 상속합니다.
주요 특징:
- 6가지 기본 Variant + 5가지 예약 상태 Variant
- 3가지 Size (sm, md, lg)
- Cals 브랜드 컬러 적용 (Pink, Blue, Purple)
- 예약 상태 컬러 완벽 지원 (Available, Pending, Confirmed, Cancelled, Completed)
- 애니메이션 효과
- 레이블 및 퍼센트 표시
사용 사례:
- Cals 예약 진행 상태
- 서비스 완료율 표시
- 예약 채움률 (시간대별, 일별)
- 고객 만족도 지표
설치
npx @vortex/cli add progress --package cals기본 사용법
import "@vortex/ui-cals/theme"; // Cals 테마 적용
import { Progress } from "@vortex/ui-cals";
export default function Example() {
return <Progress value={60} />;
}Variants (변형)
Primary (Cals Pink)
기본 진행 바에 사용하는 Cals Pink 프로그레스입니다.
<Progress variant="primary" value={75} />Secondary (Cals Blue)
보조 정보에 사용하는 Cals Blue 프로그레스입니다.
<Progress variant="secondary" value={60} />Accent (Cals Purple)
특별한 상태나 강조가 필요한 정보에 사용하는 Cals Purple 프로그레스입니다.
<Progress variant="accent" value={90} />Default
기본 회색 프로그레스입니다.
<Progress variant="default" value={50} />예약 상태 Variants ⭐
Available (예약 가능)
예약 가능한 상태를 나타내는 Green 프로그레스입니다.
<Progress variant="available" value={80} />사용 예시:
- 예약 가능 슬롯 비율
- 가용 서비스 잔여율
- 예약 여유도
Pending (승인 대기)
승인 대기 상태를 나타내는 Orange 프로그레스입니다.
<Progress variant="pending" value={40} />사용 예시:
- 승인 대기 중인 예약 비율
- 처리 진행률
- 대기 목록 현황
Confirmed (예약 확정)
예약 확정 상태를 나타내는 Blue 프로그레스입니다.
<Progress variant="confirmed" value={70} />사용 예시:
- 확정된 예약 비율
- 예약 채움률
- 확정률 지표
Cancelled (예약 취소)
예약 취소 상태를 나타내는 Red 프로그레스입니다.
<Progress variant="cancelled" value={15} />사용 예시:
- 취소된 예약 비율
- 취소율 지표
- 노쇼 비율
Completed (서비스 완료)
서비스 완료 상태를 나타내는 Purple 프로그레스입니다.
<Progress variant="completed" value={95} />사용 예시:
- 완료된 서비스 비율
- 이행률
- 달성도
Sizes (크기)
Small
<Progress size="sm" value={60} />Medium (기본)
<Progress size="md" value={60} />Large
<Progress size="lg" value={60} />With Label
레이블과 퍼센트 표시가 있는 프로그레스입니다.
<div className="space-y-xs">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">예약 채움률</span>
<span className="text-muted-foreground">75%</span>
</div>
<Progress variant="confirmed" value={75} />
</div>Cals 브랜딩
브랜드 컬러
Cals Progress는 다음 브랜드 컬러를 사용합니다:
- Primary (Pink):
#e91e63- 주요 지표 (전체 예약률) - Secondary (Blue):
#03a9f4- 보조 지표 (재방문율) - Accent (Purple):
#9c27b0- 특별 지표 (VIP 비율)
예약 상태 컬러 ⭐
Cals는 예약 시스템에 특화된 5가지 상태 컬러를 제공합니다:
- Available (Green):
#4caf50- 예약 가능 - Pending (Orange):
#ff9800- 승인 대기 - Confirmed (Blue):
#03a9f4- 예약 확정 - Cancelled (Red):
#f44336- 예약 취소 - Completed (Purple):
#9c27b0- 서비스 완료
Cals 특화 사용 가이드
예약 진행 상태:
import { Progress } from "@vortex/ui-cals";
import { Badge } from "@vortex/ui-cals";
<div className="space-y-md">
<div className="space-y-xs">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">예약 가능</span>
<div className="flex items-center gap-xs">
<Badge variant="available" size="sm">
80%
</Badge>
</div>
</div>
<Progress variant="available" value={80} />
</div>
<div className="space-y-xs">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">승인 대기</span>
<Badge variant="pending" size="sm">
15%
</Badge>
</div>
<Progress variant="pending" value={15} />
</div>
<div className="space-y-xs">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">예약 확정</span>
<Badge variant="confirmed" size="sm">
70%
</Badge>
</div>
<Progress variant="confirmed" value={70} />
</div>
<div className="space-y-xs">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">예약 취소</span>
<Badge variant="cancelled" size="sm">
5%
</Badge>
</div>
<Progress variant="cancelled" value={5} />
</div>
<div className="space-y-xs">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">서비스 완료</span>
<Badge variant="completed" size="sm">
95%
</Badge>
</div>
<Progress variant="completed" value={95} />
</div>
</div>;시간대별 예약 채움률:
import { Progress } from '@vortex/ui-cals'
import { Clock } from 'lucide-react'
const timeSlots = [
{ time: '10:00', filled: 100, total: 100, percentage: 100 },
{ time: '12:00', filled: 90, total: 100, percentage: 90 },
{ time: '14:00', filled: 50, total: 100, percentage: 50 },
{ time: '16:00', filled: 30, total: 100, percentage: 30 }
]
<div className="space-y-md">
{timeSlots.map((slot) => (
<div key={slot.time} className="space-y-xs">
<div className="flex items-center justify-between text-sm">
<div className="flex items-center gap-xs">
<Clock size={14} />
<span className="font-medium">{slot.time}</span>
</div>
<span className="text-muted-foreground">
{slot.filled}/{slot.total}석 ({slot.percentage}%)
</span>
</div>
<Progress
variant={slot.percentage === 100 ? 'completed' : slot.percentage >= 70 ? 'confirmed' : 'available'}
value={slot.percentage}
/>
</div>
))}
</div>Foundation/iCignal/Cals 비교
| 속성 | Foundation | iCignal | Cals |
|---|---|---|---|
| Primary Color | #3B82F6 (중립 블루) | #2196f3 (iCignal 블루) | #e91e63 (Cals 핑크) |
| 브랜드 적용 | 없음 | iCignal Analytics | Cals 예약 시스템 |
| 특화 Variants | 없음 | 없음 | 5가지 예약 상태 |
| 사용 맥락 | 범용 | 데이터 분석 | 예약 관리 |
| 예약 상태 지원 | ❌ | ❌ | ✅ Available/Pending/Confirmed/Cancelled/Completed |
| 테마 | 중립적 테마 | iCignal 테마 | Cals 테마 (@vortex/ui-cals/theme) |
import 경로 차이:
// Foundation
import { Progress } from "@vortex/ui-foundation";
// iCignal
import "@vortex/ui-icignal/theme";
import { Progress } from "@vortex/ui-icignal";
// Cals
import "@vortex/ui-cals/theme"; // 테마 import 필수
import { Progress } from "@vortex/ui-cals";Props API
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | ’primary’ | ‘secondary’ | ‘accent’ | ‘default’ | ‘available’ | ‘pending’ | ‘confirmed’ | ‘cancelled’ | ‘completed' | 'primary’ | 프로그레스 변형 |
| size | ’sm’ | ‘md’ | ‘lg' | 'md’ | 프로그레스 크기 |
| value | number | 0 | 진행률 (0-100) |
| max | number | 100 | 최대값 |
| className | string | - | 추가 CSS 클래스 |
접근성
Progress 컴포넌트는 WCAG 2.1 AA 기준을 준수합니다.
ARIA 속성:
role="progressbar"aria-valuenow(현재 값)aria-valuemin(최소값)aria-valuemax(최대값)aria-label(진행 상태 설명)
스크린 리더 지원:
- 진행률이 명확하게 읽힘
- 레이블이 정확하게 전달됨
색상 대비:
- 프로그레스 바와 배경 3:1 이상
- 모든 variant 색상 대비 충족
예제
예제 1: 예약 현황 대시보드 ⭐
import "@vortex/ui-cals/theme";
import { Progress } from "@vortex/ui-cals";
import { Badge } from "@vortex/ui-cals";
import { Card, CardHeader, CardContent } from "@vortex/ui-cals";
import { Calendar, Users, TrendingUp } from "lucide-react";
export default function ReservationDashboard() {
const stats = [
{
label: "예약 가능 슬롯",
value: 80,
total: 100,
variant: "available",
icon: Calendar,
description: "80개 슬롯 예약 가능",
},
{
label: "승인 대기",
value: 15,
total: 100,
variant: "pending",
icon: Users,
description: "15건 승인 대기 중",
},
{
label: "예약 확정",
value: 70,
total: 100,
variant: "confirmed",
icon: TrendingUp,
description: "70% 예약 채워짐",
},
{
label: "예약 취소",
value: 5,
total: 100,
variant: "cancelled",
icon: Users,
description: "5% 취소율",
},
{
label: "서비스 완료",
value: 95,
total: 100,
variant: "completed",
icon: TrendingUp,
description: "95% 이행률",
},
];
return (
<Card>
<CardHeader>
<h2 className="text-xl font-bold">예약 현황</h2>
</CardHeader>
<CardContent>
<div className="space-y-lg">
{stats.map((stat) => {
const Icon = stat.icon;
return (
<div key={stat.label} className="space-y-sm">
<div className="flex items-center justify-between">
<div className="flex items-center gap-sm">
<Icon size={18} className={`text-${stat.variant}`} />
<span className="font-medium">{stat.label}</span>
</div>
<Badge variant={stat.variant} size="sm">
{stat.value}%
</Badge>
</div>
<Progress variant={stat.variant} value={stat.value} size="md" />
<p className="text-sm text-muted-foreground">
{stat.description}
</p>
</div>
);
})}
</div>
</CardContent>
</Card>
);
}예제 2: 일별 예약 채움률 ⭐
import "@vortex/ui-cals/theme";
import { Progress } from "@vortex/ui-cals";
import { Calendar } from "lucide-react";
export default function DailyReservationRate() {
const weeklyData = [
{
day: "월요일",
date: "2024-01-15",
filled: 45,
total: 50,
percentage: 90,
},
{
day: "화요일",
date: "2024-01-16",
filled: 50,
total: 50,
percentage: 100,
},
{
day: "수요일",
date: "2024-01-17",
filled: 35,
total: 50,
percentage: 70,
},
{
day: "목요일",
date: "2024-01-18",
filled: 40,
total: 50,
percentage: 80,
},
{
day: "금요일",
date: "2024-01-19",
filled: 50,
total: 50,
percentage: 100,
},
{
day: "토요일",
date: "2024-01-20",
filled: 25,
total: 50,
percentage: 50,
},
{
day: "일요일",
date: "2024-01-21",
filled: 15,
total: 50,
percentage: 30,
},
];
const getVariant = (percentage) => {
if (percentage === 100) return "completed";
if (percentage >= 80) return "confirmed";
if (percentage >= 50) return "pending";
return "available";
};
return (
<div className="space-y-md">
<div className="flex items-center gap-sm mb-lg">
<Calendar size={24} className="text-primary" />
<h3 className="text-xl font-bold">주간 예약 채움률</h3>
</div>
<div className="space-y-md">
{weeklyData.map((day) => (
<div key={day.date} className="space-y-xs">
<div className="flex items-center justify-between text-sm">
<div>
<span className="font-semibold">{day.day}</span>
<span className="text-muted-foreground ml-sm">{day.date}</span>
</div>
<div className="text-right">
<span className="font-medium">
{day.filled}/{day.total}석
</span>
<span className="text-muted-foreground ml-xs">
({day.percentage}%)
</span>
</div>
</div>
<Progress
variant={getVariant(day.percentage)}
value={day.percentage}
size="lg"
/>
</div>
))}
</div>
<div className="mt-lg p-md bg-muted rounded-lg">
<div className="grid grid-cols-2 gap-md text-sm">
<div>
<span className="text-muted-foreground">평균 예약률:</span>
<span className="font-bold ml-xs">74%</span>
</div>
<div>
<span className="text-muted-foreground">주간 총 예약:</span>
<span className="font-bold ml-xs">260/350석</span>
</div>
</div>
</div>
</div>
);
}관련 컴포넌트
- Foundation Progress - 기본 버전 참조
- iCignal Progress - iCignal 버전 참조
- Badge - 상태 표시
- Card - 프로그레스 컨테이너
- Chart - 상세 데이터 시각화
Last updated on