Skip to Content

Toast

개요

Toast는 사용자 액션의 결과를 일시적으로 표시하는 알림 컴포넌트입니다. Cals에서는 예약 성공, 취소, 상태 변경 등 즉각적인 피드백을 제공하는 데 사용됩니다.

언제 사용하는가

  • 예약 생성/수정/삭제 성공 알림
  • 예약 상태 변경 완료 알림
  • 파일 업로드 완료 알림
  • 설정 저장 완료 알림
  • 오류 발생 시 즉각적인 피드백

언제 사용하지 말아야 하는가

  • 중요한 정보 전달 → Alert 사용
  • 사용자 확인 필요 → Dialog 사용
  • 영구적인 상태 표시 → Badge 또는 Alert 사용
  • 복잡한 정보 → Popover 또는 Dialog 사용

설치

npx @vortex/cli add toast

기본 사용법

import { useToast } from "@/hooks/use-toast"; import { Button } from "@/components/ui/button"; export default function ToastDemo() { const { toast } = useToast(); return ( <Button onClick={() => { toast({ title: "예약 완료", description: "2024년 1월 15일 14:00 예약이 완료되었습니다.", }); }} > 예약하기 </Button> ); }

Variants

Default

일반적인 정보 메시지를 표시합니다.

toast({ title: "예약 확정", description: "예약이 확정되었습니다.", });

Success

성공 메시지를 표시합니다.

toast({ title: "예약 성공", description: "2024년 1월 15일 14:00 예약이 완료되었습니다.", variant: "success", });

Destructive (Error)

오류 메시지를 표시합니다.

toast({ title: "예약 실패", description: "선택하신 시간대가 이미 예약되었습니다.", variant: "destructive", });

With Action

액션 버튼을 포함한 Toast를 표시합니다.

toast({ title: "예약 취소", description: "예약이 취소되었습니다.", action: ( <Button variant="outline" size="sm"> 실행 취소 </Button> ), });

Cals 브랜딩

브랜드 컬러

Cals의 Primary Pink를 활용한 브랜드 Toast 스타일입니다.

// components/ui/toast.tsx에 커스텀 variant 추가 const toastVariants = cva("...", { variants: { variant: { default: "...", destructive: "...", cals: "border-cals-primary bg-cals-primary text-white", }, }, });
toast({ title: "Cals 예약", description: "새로운 예약이 생성되었습니다.", variant: "cals", });

예약 상태 컬러

예약 상태별 Toast 스타일을 제공합니다.

// Available - 예약 가능 toast({ title: "예약 가능", description: "해당 시간대에 예약하실 수 있습니다.", className: "border-green-500 bg-green-50 text-green-900", }); // Pending - 승인 대기 toast({ title: "승인 대기", description: "예약 요청이 접수되었습니다.", className: "border-orange-500 bg-orange-50 text-orange-900", }); // Confirmed - 예약 확정 toast({ title: "예약 확정", description: "2024년 1월 15일 14:00 예약이 확정되었습니다.", className: "border-blue-500 bg-blue-50 text-blue-900", }); // Cancelled - 예약 취소 toast({ title: "예약 취소", description: "예약이 취소되었습니다.", className: "border-red-500 bg-red-50 text-red-900", }); // Completed - 예약 완료 toast({ title: "서비스 완료", description: "예약하신 서비스가 완료되었습니다.", className: "border-purple-500 bg-purple-50 text-purple-900", });

브랜드 비교표

속성FoundationiCignalCals
Primary ColorNeutral GrayCorporate Blue #0066ccPrimary Pink #e91e63
Use Case범용 알림기업 액션 피드백예약 액션 결과
Duration3-5초5초 (중요도 높음)3초 (빠른 피드백)
PositionBottom RightTop RightBottom Right
Action ButtonOptionalRequired (추적)Optional (실행 취소)
Status ColorsSemanticCorporate Blue 기반5가지 예약 상태 컬러

Props API

toast()

PropTypeDefaultDescription
titlestring-Toast 제목
descriptionstring-Toast 설명
variant"default" | "destructive""default"Toast 스타일 변형
durationnumber3000표시 시간 (ms)
actionReactNode-액션 버튼
classNamestring-커스텀 CSS 클래스

useToast()

ReturnTypeDescription
toast(options: ToastOptions) => voidToast 표시 함수
dismiss(id?: string) => voidToast 닫기 함수
toastsToast[]현재 표시 중인 Toast 목록

접근성

  • Role: role="status" 또는 role="alert" 자동 적용
  • ARIA: aria-live="polite" (일반) 또는 aria-live="assertive" (오류) 사용
  • Focus Management: Toast는 포커스를 가져가지 않음
  • Keyboard: 액션 버튼은 Tab으로 접근 가능
  • Screen Reader: 제목과 설명을 자동으로 읽음
  • Dismiss: ESC 키로 닫기 가능

예제

예약 상태별 Toast

import { useToast } from "@/hooks/use-toast"; import { Button } from "@/components/ui/button"; export default function ReservationToasts() { const { toast } = useToast(); const handleAvailable = () => { toast({ title: "예약 가능", description: "해당 시간대에 예약하실 수 있습니다.", className: "border-green-500 bg-green-50 text-green-900", }); }; const handlePending = () => { toast({ title: "승인 대기", description: "예약 요청이 접수되었습니다. 승인까지 최대 24시간 소요됩니다.", className: "border-orange-500 bg-orange-50 text-orange-900", duration: 5000, }); }; const handleConfirmed = () => { toast({ title: "예약 확정", description: "2024년 1월 15일 14:00 예약이 확정되었습니다.", className: "border-blue-500 bg-blue-50 text-blue-900", }); }; const handleCancelled = () => { toast({ title: "예약 취소", description: "예약이 취소되었습니다. 취소 수수료가 부과될 수 있습니다.", className: "border-red-500 bg-red-50 text-red-900", action: ( <Button variant="outline" size="sm"> 실행 취소 </Button> ), }); }; const handleCompleted = () => { toast({ title: "서비스 완료", description: "예약하신 서비스가 정상적으로 완료되었습니다.", className: "border-purple-500 bg-purple-50 text-purple-900", }); }; return ( <div className="space-x-2"> <Button onClick={handleAvailable}>예약 가능</Button> <Button onClick={handlePending}>승인 대기</Button> <Button onClick={handleConfirmed}>예약 확정</Button> <Button onClick={handleCancelled}>예약 취소</Button> <Button onClick={handleCompleted}>서비스 완료</Button> </div> ); }

실행 취소 기능

import { useToast } from "@/hooks/use-toast"; import { Button } from "@/components/ui/button"; export default function UndoToast() { const { toast } = useToast(); const handleCancelReservation = () => { // 예약 취소 로직 cancelReservation(); // Toast 표시 toast({ title: "예약 취소", description: "예약이 취소되었습니다.", className: "border-red-500 bg-red-50 text-red-900", action: ( <Button variant="outline" size="sm" onClick={() => { // 실행 취소 로직 undoCancelReservation(); toast({ title: "취소 복구", description: "예약이 복구되었습니다.", className: "border-blue-500 bg-blue-50 text-blue-900", }); }} > 실행 취소 </Button> ), duration: 5000, // 실행 취소 시간 확보 }); }; return ( <Button onClick={handleCancelReservation} variant="destructive"> 예약 취소 </Button> ); } function cancelReservation() { // 예약 취소 API 호출 } function undoCancelReservation() { // 예약 복구 API 호출 }

Cals 브랜드 Toast

import { useToast } from "@/hooks/use-toast"; import { Button } from "@/components/ui/button"; export default function CalsBrandToast() { const { toast } = useToast(); return ( <Button onClick={() => { toast({ title: "Cals 예약 시스템", description: "새로운 예약이 생성되었습니다.", className: "border-cals-primary bg-cals-primary text-white", }); }} > Cals Toast </Button> ); }

관련 컴포넌트

  • Alert - 영구적인 알림
  • Dialog - 사용자 확인 필요 시
  • Popover - 추가 정보 표시
  • Badge - 상태 라벨 표시
Last updated on