- 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>
78 lines
2.1 KiB
TypeScript
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,
|
|
}),
|
|
}
|