Skip to Content

Tag

태그를 표시하는 컴포넌트입니다.

개요

Tag는 작은 레이블이나 카테고리를 표시하는 컴포넌트입니다. Cals Tag는 Cals 브랜드 스타일과 예약 상태 컬러가 적용되어 있으며, 예약 상태 태그, 서비스 카테고리, 고객 레이블 표시에 최적화되어 있습니다. Foundation Tag의 모든 기능을 상속합니다.

주요 특징:

  • 6가지 기본 Variant + 5가지 예약 상태 Variant
  • 3가지 Size (sm, md, lg)
  • Cals 브랜드 컬러 적용 (Pink, Blue, Purple)
  • 예약 상태 컬러 완벽 지원 (Available, Pending, Confirmed, Cancelled, Completed)
  • 닫기 버튼 옵션
  • 아이콘 지원

사용 사례:

  • Cals 예약 상태 태그
  • 서비스 카테고리 레이블
  • 고객 분류 태그
  • 필터 및 검색 태그

설치

npx @vortex/cli add tag --package cals

기본 사용법

import "@vortex/ui-cals/theme"; // Cals 테마 적용 import { Tag } from "@vortex/ui-cals"; export default function Example() { return <Tag>예약 확정</Tag>; }

Variants (변형)

Primary (Cals Pink)

기본 태그에 사용하는 Cals Pink 태그입니다.

<Tag variant="primary">신규 고객</Tag>

Secondary (Cals Blue)

보조 정보에 사용하는 Cals Blue 태그입니다.

<Tag variant="secondary">재방문 고객</Tag>

Accent (Cals Purple)

특별한 상태나 강조가 필요한 정보에 사용하는 Cals Purple 태그입니다.

<Tag variant="accent">VIP 고객</Tag>

Outline

아웃라인 스타일의 태그입니다.

<Tag variant="outline">일반</Tag>

Default

기본 회색 태그입니다.

<Tag variant="default">기타</Tag>

Destructive

삭제나 경고 상태를 나타내는 태그입니다.

<Tag variant="destructive">블랙리스트</Tag>

예약 상태 Variants ⭐

Available (예약 가능)

예약 가능한 상태를 나타내는 Green 태그입니다.

<Tag variant="available">예약 가능</Tag>

사용 예시:

  • 예약 가능한 시간대 표시
  • 가용 서비스 표시
  • 빈 슬롯 표시

Pending (승인 대기)

승인 대기 상태를 나타내는 Orange 태그입니다.

<Tag variant="pending">승인 대기</Tag>

사용 예시:

  • 관리자 승인 대기 표시
  • 대기 목록 표시
  • 처리 중인 예약

Confirmed (예약 확정)

예약 확정 상태를 나타내는 Blue 태그입니다.

<Tag variant="confirmed">예약 확정</Tag>

사용 예시:

  • 확정된 예약 표시
  • 승인 완료 상태
  • 확인된 고객

Cancelled (예약 취소)

예약 취소 상태를 나타내는 Red 태그입니다.

<Tag variant="cancelled">예약 취소</Tag>

사용 예시:

  • 취소된 예약 표시
  • 거절된 요청
  • 무효 상태

Completed (서비스 완료)

서비스 완료 상태를 나타내는 Purple 태그입니다.

<Tag variant="completed">서비스 완료</Tag>

사용 예시:

  • 완료된 예약 표시
  • 처리 완료 상태
  • 종료된 서비스

Sizes (크기)

Small

<Tag size="sm">Small</Tag>

Medium (기본)

<Tag size="md">Medium</Tag>

Large

<Tag size="lg">Large</Tag>

Icon 사용

Icon + Text

import { Calendar, Clock, Check, X, Star } from 'lucide-react' <Tag variant="available"> <Calendar size={14} className="mr-xs" /> 예약 가능 </Tag> <Tag variant="pending"> <Clock size={14} className="mr-xs" /> 승인 대기 </Tag> <Tag variant="confirmed"> <Check size={14} className="mr-xs" /> 예약 확정 </Tag> <Tag variant="cancelled"> <X size={14} className="mr-xs" /> 예약 취소 </Tag> <Tag variant="accent"> <Star size={14} className="mr-xs" /> VIP </Tag>

Closable Tag

닫기 버튼이 있는 태그입니다.

import { X } from "lucide-react"; <Tag> 프리미엄 <button className="ml-xs hover:opacity-70"> <X size={12} /> </button> </Tag>;

Cals 브랜딩

브랜드 컬러

Cals Tag는 다음 브랜드 컬러를 사용합니다:

  • Primary (Pink): #e91e63 - 주요 레이블 (신규 고객, VIP)
  • Secondary (Blue): #03a9f4 - 보조 레이블 (재방문)
  • Accent (Purple): #9c27b0 - 특별 레이블 (프리미엄)

예약 상태 컬러 ⭐

Cals는 예약 시스템에 특화된 5가지 상태 컬러를 제공합니다:

  • Available (Green): #4caf50 - 예약 가능
  • Pending (Orange): #ff9800 - 승인 대기
  • Confirmed (Blue): #03a9f4 - 예약 확정
  • Cancelled (Red): #f44336 - 예약 취소
  • Completed (Purple): #9c27b0 - 서비스 완료

Cals 특화 사용 가이드

예약 상태 표시:

import { Tag } from "@vortex/ui-cals"; import { Calendar, Clock, Check, X, CheckCircle } from "lucide-react"; // 예약 목록의 상태 태그 <div className="flex gap-xs"> <Tag variant="available"> <Calendar size={14} className="mr-xs" /> 예약 가능 </Tag> <Tag variant="pending"> <Clock size={14} className="mr-xs" /> 승인 대기 </Tag> <Tag variant="confirmed"> <Check size={14} className="mr-xs" /> 예약 확정 </Tag> <Tag variant="cancelled"> <X size={14} className="mr-xs" /> 예약 취소 </Tag> <Tag variant="completed"> <CheckCircle size={14} className="mr-xs" /> 서비스 완료 </Tag> </div>;

서비스 카테고리 태그:

import { Tag } from "@vortex/ui-cals"; import { Star, Zap, Award } from "lucide-react"; <div className="flex flex-wrap gap-xs"> <Tag variant="accent"> <Star size={14} className="mr-xs" /> VIP 패키지 </Tag> <Tag variant="primary"> <Zap size={14} className="mr-xs" /> 프리미엄 서비스 </Tag> <Tag variant="secondary"> <Award size={14} className="mr-xs" /> 스탠다드 </Tag> <Tag variant="outline">베이직</Tag> </div>;

고객 레이블 태그:

import { Tag } from "@vortex/ui-cals"; import { Star, Users, Gift } from "lucide-react"; <div className="flex flex-wrap gap-xs"> <Tag variant="accent"> <Star size={14} className="mr-xs" /> VIP 고객 </Tag> <Tag variant="primary">신규 고객</Tag> <Tag variant="secondary"> <Users size={14} className="mr-xs" /> 단골 고객 </Tag> <Tag variant="outline"> <Gift size={14} className="mr-xs" /> 프로모션 대상 </Tag> </div>;

Foundation/iCignal/Cals 비교

속성FoundationiCignalCals
Primary Color#3B82F6 (중립 블루)#2196f3 (iCignal 블루)#e91e63 (Cals 핑크)
브랜드 적용없음iCignal AnalyticsCals 예약 시스템
특화 Variants없음없음5가지 예약 상태
사용 맥락범용데이터 분석예약 관리
예약 상태 지원✅ Available/Pending/Confirmed/Cancelled/Completed
테마중립적 테마iCignal 테마Cals 테마 (@vortex/ui-cals/theme)

import 경로 차이:

// Foundation import { Tag } from "@vortex/ui-foundation"; // iCignal import "@vortex/ui-icignal/theme"; import { Tag } from "@vortex/ui-icignal"; // Cals import "@vortex/ui-cals/theme"; // 테마 import 필수 import { Tag } from "@vortex/ui-cals";

Props API

PropTypeDefaultDescription
variant’primary’ | ‘secondary’ | ‘accent’ | ‘outline’ | ‘default’ | ‘destructive’ | ‘available’ | ‘pending’ | ‘confirmed’ | ‘cancelled’ | ‘completed''default’태그 변형
size’sm’ | ‘md’ | ‘lg''md’태그 크기
classNamestring-추가 CSS 클래스
childrenReactNode-태그 내용

접근성

Tag 컴포넌트는 WCAG 2.1 AA 기준을 준수합니다.

ARIA 속성:

  • role="status" (상태 표시 태그)
  • aria-label (아이콘 전용 태그)

색상 대비:

  • 텍스트와 배경 4.5:1 이상
  • 모든 variant 색상 대비 충족

스크린 리더 지원:

  • 태그 내용이 명확하게 읽힘
  • 상태 정보 정확하게 전달

예제

예제 1: 예약 상태 필터 ⭐

import "@vortex/ui-cals/theme"; import { Tag } from "@vortex/ui-cals"; import { Card, CardHeader, CardContent } from "@vortex/ui-cals"; import { Calendar, Clock, Check, X, CheckCircle } from "lucide-react"; import { useState } from "react"; export default function ReservationStatusFilter() { const [activeFilters, setActiveFilters] = useState(["confirmed"]); const statusFilters = [ { value: "all", label: "전체", variant: "outline", icon: null }, { value: "available", label: "예약 가능", variant: "available", icon: Calendar, }, { value: "pending", label: "승인 대기", variant: "pending", icon: Clock }, { value: "confirmed", label: "예약 확정", variant: "confirmed", icon: Check, }, { value: "cancelled", label: "예약 취소", variant: "cancelled", icon: X }, { value: "completed", label: "서비스 완료", variant: "completed", icon: CheckCircle, }, ]; const toggleFilter = (value) => { setActiveFilters((prev) => prev.includes(value) ? prev.filter((f) => f !== value) : [...prev, value] ); }; return ( <Card> <CardHeader> <h3 className="font-semibold">예약 상태 필터</h3> </CardHeader> <CardContent> <div className="flex flex-wrap gap-sm"> {statusFilters.map((filter) => { const Icon = filter.icon; const isActive = activeFilters.includes(filter.value); return ( <Tag key={filter.value} variant={isActive ? filter.variant : "outline"} className="cursor-pointer hover:opacity-80 transition-opacity" onClick={() => toggleFilter(filter.value)} > {Icon && <Icon size={14} className="mr-xs" />} {filter.label} {isActive && filter.value !== "all" && ( <span className="ml-xs font-bold">•</span> )} </Tag> ); })} </div> <div className="mt-md text-sm text-muted-foreground"> 선택된 필터: {activeFilters.length}개 </div> </CardContent> </Card> ); }

예제 2: 서비스 카테고리 태그 그룹 ⭐

import "@vortex/ui-cals/theme"; import { Tag } from "@vortex/ui-cals"; import { Star, Zap, Award, Package } from "lucide-react"; export default function ServiceCategoryTags() { const services = [ { id: 1, name: "VIP 프리미엄 패키지", price: "200,000원", tags: [ { label: "VIP", variant: "accent", icon: Star }, { label: "프리미엄", variant: "primary", icon: Zap }, { label: "인기", variant: "secondary", icon: Award }, ], }, { id: 2, name: "스탠다드 패키지", price: "100,000원", tags: [ { label: "스탠다드", variant: "secondary", icon: Package }, { label: "추천", variant: "outline", icon: null }, ], }, { id: 3, name: "베이직 패키지", price: "80,000원", tags: [ { label: "베이직", variant: "outline", icon: Package }, { label: "신규 출시", variant: "primary", icon: null }, ], }, ]; return ( <div className="space-y-md"> {services.map((service) => ( <div key={service.id} className="border rounded-lg p-md hover:border-primary transition-colors" > <div className="flex items-start justify-between mb-sm"> <div> <h4 className="font-semibold">{service.name}</h4> <p className="text-lg font-bold text-primary mt-xs"> {service.price} </p> </div> </div> <div className="flex flex-wrap gap-xs"> {service.tags.map((tag, index) => { const Icon = tag.icon; return ( <Tag key={index} variant={tag.variant} size="sm"> {Icon && <Icon size={12} className="mr-xs" />} {tag.label} </Tag> ); })} </div> </div> ))} </div> ); }

관련 컴포넌트

Last updated on