o2o-negosium-original/frontend/src/lib/toast.ts
민헌 7bdd10207a feat(frontend): 공통 토스트(sonner)·모달 컴포넌트 추가
- sonner 기반 토스트 래퍼(lib/toast): error/info/success/warning,
  프로젝트 디자인 토큰으로 스타일 통일. Toaster 를 provider 에 마운트
- 공통 Modal 컴포넌트: 반투명 배경 + 배경 클릭/ESC 닫기
- core/Provider import 케이싱 정리(provider)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:12:16 +09:00

78 lines
2.1 KiB
TypeScript

// 전역 토스트 (sonner 래퍼). 프로젝트 디자인 토큰으로 스타일을 맞춘다.
// <Toaster /> 는 core/provider.tsx 에 마운트되어 있어야 한다.
import { toast as sonnerToast, type ExternalToast } from 'sonner'
type ToastOptions = ExternalToast
const baseStyle = {
fontFamily: 'var(--font-sans)',
fontSize: '18px',
fontWeight: 600,
letterSpacing: '-0.28px',
borderRadius: '8px',
padding: '18px 24px',
backgroundColor: 'var(--neutral-00)',
color: 'var(--neutral-90)',
boxShadow: '0px 4px 12px rgba(0, 0, 0, 0.08)',
minWidth: '440px',
wordBreak: 'keep-all' as const,
overflowWrap: 'break-word' as const,
whiteSpace: 'pre-wrap' as const,
}
const errorStyle = {
...baseStyle,
border: '1px solid var(--negative)',
color: 'var(--negative)',
backgroundColor: '#fdf2f3',
}
const infoStyle = {
...baseStyle,
border: '1px solid var(--info)',
color: 'var(--info)',
backgroundColor: '#eff5ff',
}
const successStyle = {
...baseStyle,
border: '1px solid var(--success)',
color: '#0f766e',
backgroundColor: '#f0fdf9',
}
const warningStyle = {
...baseStyle,
border: '1px solid var(--neutral-60)',
color: 'var(--neutral-70)',
backgroundColor: 'var(--neutral-10)',
}
export const toast = {
error: (message: string, options?: ToastOptions) =>
sonnerToast.error(message, {
...options,
style: { ...errorStyle, ...options?.style },
duration: options?.duration ?? 4000,
}),
info: (message: string, options?: ToastOptions) =>
sonnerToast.info(message, {
...options,
style: { ...infoStyle, ...options?.style },
duration: options?.duration ?? 3000,
}),
success: (message: string, options?: ToastOptions) =>
sonnerToast.success(message, {
...options,
style: { ...successStyle, ...options?.style },
duration: options?.duration ?? 3500,
}),
// 완료 안내: 체크 아이콘(success)에 중립 톤 스타일
warning: (message: string, options?: ToastOptions) =>
sonnerToast.success(message, {
...options,
style: { ...warningStyle, ...options?.style },
duration: options?.duration ?? 3500,
}),
}