UNPKG

react-next-toast

Version:

A premium, modern toast notification system for React applications

1 lines 48.2 kB
{"version":3,"sources":["../src/context/ToastContext.tsx","../src/components/ToastContainer.tsx","../src/styles/styles.ts","../src/components/Toast.tsx","../src/icons/Icons.tsx","../src/types/index.ts","../src/ToastNotification.tsx","../src/index.ts"],"sourcesContent":["import React, { createContext, useContext, useState, useCallback, ReactNode } from 'react';\nimport { createRoot, Root } from 'react-dom/client';\nimport {\n Toast,\n ToastState,\n ToastOptions,\n ToastVariant,\n ToastContainerProps,\n} from '../types';\nimport { ToastContainer } from '../components/ToastContainer';\nimport { ToastType } from '../partials/interfaces';\n\ninterface ToastContextValue {\n toasts: Toast[];\n addToast: (variant: ToastVariant, title: string, options?: ToastOptions) => string;\n dismissToast: (id: string) => void;\n dismissAll: () => void;\n}\n\nconst ToastContext = createContext<ToastContextValue | null>(null);\n\nexport const useToast = (): ToastContextValue => {\n const context = useContext(ToastContext);\n if (!context) {\n throw new Error('useToast must be used within a ToastProvider');\n }\n return context;\n};\n\ninterface ToastProviderProps extends ToastContainerProps {\n children: ReactNode;\n}\n\nexport const ToastProvider: React.FC<ToastProviderProps> = ({\n children,\n position = 'bottom-right',\n theme = 'dark',\n maxVisible = 5,\n gap = 12,\n}) => {\n const [toasts, setToasts] = useState<Toast[]>([]);\n\n const generateId = (): string => {\n return `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n };\n\n const addToast = useCallback(\n (variant: ToastVariant, title: string, options: ToastOptions = {}): string => {\n const id = options.id || generateId();\n\n const toast: Toast = {\n id,\n variant,\n title,\n description: options.description,\n duration: options.duration ?? 5000,\n dismissible: options.dismissible ?? true,\n action: options.action,\n icon: options.icon,\n position: options.position ?? position,\n createdAt: Date.now(),\n };\n\n setToasts((prev) => [...prev, toast]);\n return id;\n },\n [position]\n );\n\n const dismissToast = useCallback((id: string) => {\n setToasts((prev) => prev.filter((t: Toast) => t.id !== id));\n }, []);\n\n const dismissAll = useCallback(() => {\n setToasts([]);\n }, []);\n\n const contextValue: ToastContextValue = {\n toasts,\n addToast,\n dismissToast,\n dismissAll,\n };\n\n return (\n <ToastContext.Provider value={contextValue}>\n {children}\n <ToastContainer\n toasts={toasts}\n onDismiss={dismissToast}\n position={position}\n theme={theme}\n maxVisible={maxVisible}\n gap={gap}\n />\n </ToastContext.Provider>\n );\n};\n\n// Toast API (standalone, no Provider needed)\nlet globalRoot: Root | null = null;\nlet globalState: ToastState = { toasts: [] };\nlet globalConfig: ToastContainerProps = {\n position: 'bottom-right',\n theme: 'dark',\n maxVisible: 5,\n gap: 12,\n};\n\nfunction ensureContainer() {\n if (typeof document === 'undefined') return;\n\n if (!globalRoot) {\n const container = document.createElement('div');\n container.id = 'react-next-toast-root';\n document.body.appendChild(container);\n globalRoot = createRoot(container);\n }\n\n renderToasts();\n}\n\nfunction renderToasts() {\n if (!globalRoot) return;\n\n const dismissToast = (id: string) => {\n globalState = {\n ...globalState,\n toasts: globalState.toasts.filter((t: Toast) => t.id !== id),\n };\n renderToasts();\n };\n\n globalRoot.render(\n <ToastContainer\n toasts={globalState.toasts}\n onDismiss={dismissToast}\n position={globalConfig.position}\n theme={globalConfig.theme}\n maxVisible={globalConfig.maxVisible}\n gap={globalConfig.gap}\n />\n );\n}\n\nfunction generateId(): string {\n return `toast-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\nfunction addToast(variant: ToastVariant, title: string, options: ToastOptions = {}): string {\n ensureContainer();\n\n const id = options.id || generateId();\n\n const toast: Toast = {\n id,\n variant,\n title,\n description: options.description,\n duration: options.duration ?? 5000,\n dismissible: options.dismissible ?? true,\n action: options.action,\n icon: options.icon,\n position: options.position ?? globalConfig.position ?? 'bottom-right',\n createdAt: Date.now(),\n };\n\n globalState = {\n ...globalState,\n toasts: [...globalState.toasts, toast],\n };\n\n renderToasts();\n return id;\n}\n\nfunction dismissToast(id: string) {\n globalState = {\n ...globalState,\n toasts: globalState.toasts.filter((t: Toast) => t.id !== id),\n };\n renderToasts();\n}\n\nfunction dismissAll() {\n globalState = { toasts: [] };\n renderToasts();\n}\n\n// Public Toast API\n\nexport interface ToastAPI {\n (title: string, options?: ToastOptions): string;\n success: (title: string, options?: ToastOptions) => string;\n error: (title: string, options?: ToastOptions) => string;\n warning: (title: string, options?: ToastOptions) => string;\n info: (title: string, options?: ToastOptions) => string;\n loading: (title: string, options?: ToastOptions) => string;\n dismiss: (id: string) => void;\n dismissAll: () => void;\n promise: <T>(\n promise: Promise<T>,\n messages: {\n loading: string;\n success: string | ((data: T) => string);\n error: string | ((err: any) => string);\n },\n options?: ToastOptions\n ) => Promise<T>;\n configure: (config: Partial<ToastContainerProps>) => void;\n}\n\nexport const toast: ToastAPI = Object.assign(\n (title: string, options?: ToastOptions) => addToast('default', title, options),\n {\n success: (title: string, options?: ToastOptions) => addToast(ToastType.SUCCESS, title, options),\n error: (title: string, options?: ToastOptions) => addToast(ToastType.ERROR, title, options),\n warning: (title: string, options?: ToastOptions) => addToast(ToastType.WARNING, title, options),\n info: (title: string, options?: ToastOptions) => addToast(ToastType.INFO, title, options),\n loading: (title: string, options?: ToastOptions) => addToast(ToastType.LOADING, title, { ...options, duration: 0 }),\n dismiss: dismissToast,\n dismissAll,\n promise: async function <T>(\n promise: Promise<T>,\n messages: {\n loading: string;\n success: string | ((data: T) => string);\n error: string | ((err: any) => string);\n },\n options?: ToastOptions\n ): Promise<T> {\n const id = addToast(ToastType.LOADING, messages.loading, { ...options, duration: 0 });\n\n try {\n const result = await promise;\n dismissToast(id);\n const successMessage = typeof messages.success === 'function'\n ? messages.success(result)\n : messages.success;\n addToast(ToastType.SUCCESS, successMessage, options);\n return result;\n } catch (error) {\n dismissToast(id);\n const errorMessage = typeof messages.error === 'function'\n ? messages.error(error)\n : messages.error;\n addToast(ToastType.ERROR, errorMessage, options);\n throw error;\n }\n },\n configure: (config: Partial<ToastContainerProps>) => {\n globalConfig = { ...globalConfig, ...config };\n renderToasts();\n },\n }\n);\n\nexport default toast;\n","import React, { useEffect } from 'react';\nimport { Toast as ToastType, ToastPosition, ToastContainerProps } from '../types';\nimport { containerStyles, injectStyles } from '../styles/styles';\nimport { Toast } from './Toast';\n\ninterface InternalToastContainerProps extends ToastContainerProps {\n toasts: ToastType[];\n onDismiss: (id: string) => void;\n}\n\nexport const ToastContainer: React.FC<InternalToastContainerProps> = ({\n toasts,\n onDismiss,\n position = 'bottom-right',\n theme = 'dark',\n maxVisible = 5,\n gap = 12,\n}) => {\n\n // inject keyframe animations on mount\n useEffect(() => {\n injectStyles();\n\n\n }, []);\n\n // group toasts by position\n const groupedToasts = toasts.reduce((acc, toast) => {\n const pos = toast.position || position;\n if (!acc[pos]) acc[pos] = [];\n acc[pos].push(toast);\n return acc;\n }, {} as Record<ToastPosition, ToastType[]>);\n\n // limit visible toasts per position\n const limitedToasts = Object.entries(groupedToasts).reduce((acc, [pos, toastList]) => {\n acc[pos as ToastPosition] = toastList.slice(-maxVisible);\n return acc;\n }, {} as Record<ToastPosition, ToastType[]>);\n\n // responsive position adjustment\n const getResponsivePosition = (pos: ToastPosition): ToastPosition => {\n if (typeof window === 'undefined') return pos;\n\n const isMobile = window.innerWidth < 640;\n if (isMobile && (pos === 'bottom-right' || pos === 'bottom-left')) {\n return 'top-center';\n }\n return pos;\n };\n\n return (\n <>\n {Object.entries(limitedToasts).map(([pos, toastList]) => {\n const responsivePos = getResponsivePosition(pos as ToastPosition);\n\n return (\n <div\n key={pos}\n style={containerStyles(responsivePos, theme, gap)}\n data-toast-container={pos}\n >\n {toastList.map((toast) => (\n <Toast\n key={toast.id}\n toast={toast}\n theme={theme}\n onDismiss={onDismiss}\n />\n ))}\n </div>\n );\n })}\n </>\n );\n};\n\nexport default ToastContainer;\n","import React from 'react';\nimport { ToastVariant } from '../types';\n\n// Design Tokens\nexport const colors = {\n success: '#10B981',\n error: '#EF4444',\n warning: '#F59E0B',\n info: '#3B82F6',\n loading: '#6366F1',\n default: '#6B7280',\n};\n\nexport const theme = {\n dark: {\n surface: 'rgba(23, 25, 30, 0.92)',\n surfaceSolid: '#17191E',\n border: 'rgba(255, 255, 255, 0.08)',\n textPrimary: '#FFFFFF',\n textSecondary: '#9CA3AF',\n backdrop: 'rgba(0, 0, 0, 0.4)',\n },\n light: {\n surface: 'rgba(255, 255, 255, 0.92)',\n surfaceSolid: '#FFFFFF',\n border: 'rgba(0, 0, 0, 0.08)',\n textPrimary: '#111827',\n textSecondary: '#6B7280',\n backdrop: 'rgba(255, 255, 255, 0.4)',\n },\n};\n\n// ============================================================================\n// CSS keyframes (injected once)\n// ============================================================================\nconst keyframes = `\n@keyframes toast-slide-in-right {\n from {\n transform: translateX(100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes toast-slide-out-right {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(100%);\n opacity: 0;\n }\n}\n\n@keyframes toast-slide-in-left {\n from {\n transform: translateX(-100%);\n opacity: 0;\n }\n to {\n transform: translateX(0);\n opacity: 1;\n }\n}\n\n@keyframes toast-slide-out-left {\n from {\n transform: translateX(0);\n opacity: 1;\n }\n to {\n transform: translateX(-100%);\n opacity: 0;\n }\n}\n\n@keyframes toast-slide-in-top {\n from {\n transform: translateY(-100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n@keyframes toast-slide-in-bottom {\n from {\n transform: translateY(100%);\n opacity: 0;\n }\n to {\n transform: translateY(0);\n opacity: 1;\n }\n}\n\n@keyframes toast-spinner {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n@keyframes toast-fade-in {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n`;\n\nlet styleInjected = false;\n\nexport function injectStyles(): void {\n if (styleInjected || typeof document === 'undefined') return;\n\n const style = document.createElement('style');\n style.id = 'react-next-toast-styles';\n style.textContent = keyframes;\n document.head.appendChild(style);\n styleInjected = true;\n}\n\n// style objects\nexport const containerStyles = (\n position: string,\n _themeMode: 'light' | 'dark',\n gap: number\n): React.CSSProperties => {\n const isTop = position.startsWith('top');\n const isLeft = position.endsWith('left');\n const isCenter = position.endsWith('center');\n\n return {\n position: 'fixed',\n zIndex: 999999,\n pointerEvents: 'none',\n display: 'flex',\n flexDirection: isTop ? 'column' : 'column-reverse',\n gap: `${gap}px`,\n padding: '16px',\n maxHeight: '100vh',\n boxSizing: 'border-box',\n ...(isTop ? { top: 0 } : { bottom: 0 }),\n ...(isCenter\n ? { left: '50%', transform: 'translateX(-50%)' }\n : isLeft\n ? { left: 0 }\n : { right: 0 }),\n };\n};\n\nexport const toastStyles = (\n _variant: ToastVariant,\n themeMode: 'light' | 'dark',\n isExiting: boolean\n): React.CSSProperties => {\n const t = theme[themeMode];\n\n return {\n position: 'relative',\n pointerEvents: 'auto',\n display: 'flex',\n alignItems: 'flex-start',\n gap: '12px',\n width: '380px',\n maxWidth: 'calc(100vw - 32px)',\n padding: '14px 16px',\n backgroundColor: t.surface,\n backdropFilter: 'blur(12px)',\n WebkitBackdropFilter: 'blur(12px)',\n border: `1px solid ${t.border}`,\n borderRadius: '12px',\n boxShadow: themeMode === 'dark'\n ? '0 4px 24px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.2)'\n : '0 4px 24px rgba(0, 0, 0, 0.08), 0 1px 3px rgba(0, 0, 0, 0.04)',\n overflow: 'hidden',\n animation: isExiting\n ? 'toast-slide-out-right 0.2s ease-in forwards'\n : 'toast-slide-in-right 0.3s ease-out',\n };\n};\n\nexport const accentLineStyles = (\n variant: ToastVariant\n): React.CSSProperties => {\n return {\n position: 'absolute',\n left: 0,\n top: 0,\n bottom: 0,\n width: '3px',\n backgroundColor: colors[variant] || colors.default,\n borderRadius: '3px 0 0 3px',\n };\n};\n\nexport const iconContainerStyles = (\n _variant: ToastVariant\n): React.CSSProperties => {\n return {\n flexShrink: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n marginTop: '1px',\n };\n};\n\nexport const contentStyles: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n display: 'flex',\n flexDirection: 'column',\n gap: '2px',\n};\n\nexport const titleStyles = (themeMode: 'light' | 'dark'): React.CSSProperties => ({\n margin: 0,\n fontSize: '14px',\n fontWeight: 500,\n lineHeight: 1.4,\n color: theme[themeMode].textPrimary,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n});\n\nexport const descriptionStyles = (themeMode: 'light' | 'dark'): React.CSSProperties => ({\n margin: 0,\n fontSize: '13px',\n fontWeight: 400,\n lineHeight: 1.4,\n color: theme[themeMode].textSecondary,\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n});\n\nexport const actionsStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n flexShrink: 0,\n marginLeft: 'auto',\n};\n\nexport const actionButtonStyles = (_themeMode: 'light' | 'dark'): React.CSSProperties => ({\n padding: '6px 12px',\n fontSize: '13px',\n fontWeight: 500,\n color: '#3B82F6',\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\n transition: 'background-color 0.15s ease',\n});\n\nexport const closeButtonStyles = (themeMode: 'light' | 'dark'): React.CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n padding: 0,\n backgroundColor: 'transparent',\n border: 'none',\n borderRadius: '6px',\n cursor: 'pointer',\n color: theme[themeMode].textSecondary,\n opacity: 0.6,\n transition: 'opacity 0.15s ease, background-color 0.15s ease',\n});\n\nexport const spinnerStyles: React.CSSProperties = {\n width: '20px',\n height: '20px',\n animation: 'toast-spinner 1s linear infinite',\n};\n","import React, { useState, useEffect, useCallback } from 'react';\nimport { Toast as ToastType } from '../types';\nimport {\n toastStyles,\n accentLineStyles,\n iconContainerStyles,\n contentStyles,\n titleStyles,\n descriptionStyles,\n actionsStyles,\n actionButtonStyles,\n closeButtonStyles,\n} from '../styles/styles';\nimport { getVariantIcon, CloseIcon } from '../icons/Icons';\n\ninterface ToastProps {\n toast: ToastType;\n theme: 'light' | 'dark';\n onDismiss: (id: string) => void;\n}\n\nexport const Toast: React.FC<ToastProps> = ({ toast, theme, onDismiss }) => {\n const [isExiting, setIsExiting] = useState<boolean>(false);\n\n const handleDismiss = useCallback(() => {\n setIsExiting(true);\n setTimeout(() => {\n onDismiss(toast?.id);\n }, 200); // match animation duration\n }, [toast?.id, onDismiss]);\n\n // auto-dismiss timer\n useEffect(() => {\n if (toast?.duration === 0) return; // persistent toast\n\n const timer = setTimeout(() => {\n handleDismiss();\n }, toast?.duration);\n\n return () => clearTimeout(timer);\n }, [toast?.duration, handleDismiss]);\n\n const handleActionClick = () => {\n toast?.action?.onClick();\n handleDismiss();\n };\n\n return (\n <div\n style={toastStyles(toast?.variant, theme, isExiting)}\n role=\"alert\"\n aria-live=\"polite\"\n data-toast-id={toast?.id}\n >\n <div style={accentLineStyles(toast?.variant)} />\n <div style={iconContainerStyles(toast?.variant)}>\n {toast?.icon || getVariantIcon(toast?.variant)}\n </div>\n\n {/* Content */}\n <div style={contentStyles}>\n <p style={titleStyles(theme)}>{toast?.title}</p>\n {toast?.description && (\n <p style={descriptionStyles(theme)}>{toast?.description}</p>\n )}\n </div>\n\n {/* Actions */}\n <div style={actionsStyles}>\n {toast.action && (\n <button\n style={actionButtonStyles(theme)}\n onClick={handleActionClick}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor =\n theme === 'dark' ? 'rgba(59, 130, 246, 0.1)' : 'rgba(59, 130, 246, 0.08)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent';\n }}\n >\n {toast?.action?.label}\n </button>\n )}\n {toast.dismissible && (\n <button\n style={closeButtonStyles(theme)}\n onClick={handleDismiss}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1';\n e.currentTarget.style.backgroundColor =\n theme === 'dark' ? 'rgba(255, 255, 255, 0.08)' : 'rgba(0, 0, 0, 0.05)';\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.6';\n e.currentTarget.style.backgroundColor = 'transparent';\n }}\n aria-label=\"Dismiss notification\"\n >\n <CloseIcon size={14} />\n </button>\n )}\n </div>\n </div>\n );\n};\n\nexport default Toast;\n","import React from 'react';\nimport { ToastVariant } from '../types';\nimport { colors, spinnerStyles } from '../styles/styles';\n\n// Icon Components\ninterface IconProps {\n size?: number;\n color?: string;\n}\n\nexport const SuccessIcon: React.FC<IconProps> = ({ size = 20, color = colors.success }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <rect width=\"24\" height=\"24\" rx=\"6\" fill={color} fillOpacity=\"0.15\" />\n <path\n d=\"M7.5 12L10.5 15L16.5 9\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const ErrorIcon: React.FC<IconProps> = ({ size = 20, color = colors.error }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill={color} fillOpacity=\"0.15\" />\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke={color} strokeWidth=\"1.5\" />\n <path\n d=\"M12 8V12\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <circle cx=\"12\" cy=\"16\" r=\"1\" fill={color} />\n </svg>\n);\n\nexport const WarningIcon: React.FC<IconProps> = ({ size = 20, color = colors.warning }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 3L22 20H2L12 3Z\"\n fill={color}\n fillOpacity=\"0.15\"\n stroke={color}\n strokeWidth=\"1.5\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M12 10V14\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <circle cx=\"12\" cy=\"17\" r=\"1\" fill={color} />\n </svg>\n);\n\nexport const InfoIcon: React.FC<IconProps> = ({ size = 20, color = colors.info }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" fill={color} fillOpacity=\"0.15\" />\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke={color} strokeWidth=\"1.5\" />\n <circle cx=\"12\" cy=\"8\" r=\"1\" fill={color} />\n <path\n d=\"M12 11V16\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport const LoadingIcon: React.FC<IconProps> = ({ size = 20, color = colors.loading }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={spinnerStyles}\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke={color}\n strokeOpacity=\"0.2\"\n strokeWidth=\"2.5\"\n />\n <path\n d=\"M12 2C6.48 2 2 6.48 2 12\"\n stroke={color}\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport const CloseIcon: React.FC<IconProps> = ({ size = 16, color = 'currentColor' }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M18 6L6 18M6 6L18 18\"\n stroke={color}\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const TrashIcon: React.FC<IconProps> = ({ size = 20, color = '#9CA3AF' }) => (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M3 6H21M19 6V20C19 21 18 22 17 22H7C6 22 5 21 5 20V6M8 6V4C8 3 9 2 10 2H14C15 2 16 3 16 4V6\"\n stroke={color}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n <path\n d=\"M10 11V17M14 11V17\"\n stroke={color}\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// Icon Mapping\nexport const variantIcons: Record<ToastVariant, React.FC<IconProps>> = {\n success: SuccessIcon,\n error: ErrorIcon,\n warning: WarningIcon,\n info: InfoIcon,\n loading: LoadingIcon,\n default: InfoIcon,\n};\n\nexport function getVariantIcon(variant: ToastVariant): React.ReactElement {\n const IconComponent = variantIcons[variant] || variantIcons.default;\n return <IconComponent />;\n}\n\n// Legacy Icon export (backwards compatibility)\n/** @deprecated Use individual icon exports instead */\nexport const Icon = {\n Success: () => <SuccessIcon />,\n Error: () => <ErrorIcon />,\n Warning: () => <WarningIcon />,\n Info: () => <InfoIcon />,\n};\n","import React from 'react';\n\n// toast Types\nexport type ToastVariant = 'success' | 'error' | 'warning' | 'info' | 'loading' | 'default';\n\nexport type ToastPosition =\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n\nexport interface ToastAction {\n label: string;\n onClick: () => void;\n}\n\nexport interface ToastOptions {\n /** optional description text below the title */\n description?: string;\n /** duration in ms before auto-dismiss. 0 = persistent. Default: 5000 */\n duration?: number;\n /** show close button. Default: true */\n dismissible?: boolean;\n /** action button configuration */\n action?: ToastAction;\n /** custom icon to override default variant icon */\n icon?: React.ReactNode;\n /** unique ID for programmatic control */\n id?: string;\n /** toast position. Default: 'bottom-right' */\n position?: ToastPosition;\n}\n\nexport interface Toast {\n id: string;\n variant: ToastVariant;\n title: string;\n description?: string;\n duration: number;\n dismissible: boolean;\n action?: ToastAction;\n icon?: React.ReactNode;\n position: ToastPosition;\n createdAt: number;\n}\n\nexport interface ToastState {\n toasts: Toast[];\n}\n\nexport type ToastActionType =\n | { type: 'ADD_TOAST'; toast: Toast }\n | { type: 'DISMISS_TOAST'; id: string }\n | { type: 'DISMISS_ALL' };\n\n\n\n// legacy types (backwards compatibility)\n\n/** @deprecated Use ToastVariant instead */\nexport enum ToastType {\n SUCCESS = 'success',\n ERROR = 'error',\n WARNING = 'warning',\n INFO = 'info',\n}\n\n/** @deprecated Use toast() with options instead */\nexport interface ToastDetail {\n type: 'success' | 'error' | 'info' | 'warning';\n message: string;\n backgroundColor?: string;\n textColor?: string;\n position?: 'right' | 'top-right' | 'bottom-right' | 'left' | 'top-left' | 'bottom-left';\n duration?: number;\n}\n\n// style types\nexport interface ToastTheme {\n mode: 'light' | 'dark';\n}\n\nexport interface ToastContainerProps {\n /** Default position for all toasts. Default: 'bottom-right' */\n position?: ToastPosition;\n /** Theme mode. Default: 'dark' */\n theme?: 'light' | 'dark';\n /** Maximum number of visible toasts. Default: 5 */\n maxVisible?: number;\n /** Gap between stacked toasts in px. Default: 12 */\n gap?: number;\n}\n","import React from 'react';\nimport { ToastDetail, ToastType } from './types';\nimport { SuccessIcon, ErrorIcon, WarningIcon, InfoIcon } from './icons/Icons';\n\n/**\n * @deprecated This component is preserved for backwards compatibility.\n * Use the new `toast()` API or `<ToastProvider>` for the v3 experience.\n */\n\nconst typeToIconMap = {\n [ToastType.SUCCESS]: SuccessIcon,\n [ToastType.ERROR]: ErrorIcon,\n [ToastType.WARNING]: WarningIcon,\n [ToastType.INFO]: InfoIcon,\n};\n\nconst ToastNotification: React.FC<ToastDetail> = ({\n message,\n backgroundColor,\n textColor,\n type,\n position,\n}) => {\n const IconComponent = typeToIconMap[type] || InfoIcon;\n\n const defaultPositionStyle: React.CSSProperties = {\n top: '30px',\n bottom: '30px',\n right: '10px',\n left: '10px',\n };\n\n const notificationStyle: React.CSSProperties = {\n position: 'fixed',\n top:\n position === 'top-right' || position === 'top-left' || !position\n ? defaultPositionStyle.top\n : undefined,\n bottom:\n position === 'bottom-right' || position === 'bottom-left' || !position\n ? defaultPositionStyle.bottom\n : undefined,\n right:\n position === 'top-right' || position === 'bottom-right' || !position\n ? defaultPositionStyle.right\n : undefined,\n left:\n position === 'top-left' ||\n position === 'bottom-left' ||\n position === 'left'\n ? defaultPositionStyle.left\n : undefined,\n maxWidth: '30%',\n minWidth: '320px',\n maxHeight: 'max-content',\n backgroundColor:\n backgroundColor ||\n (type === ToastType.SUCCESS\n ? '#10B981'\n : type === ToastType.ERROR\n ? '#EF4444'\n : type === ToastType.WARNING\n ? '#F59E0B'\n : type === ToastType.INFO\n ? '#3B82F6'\n : '#6B7280'),\n border: '1px solid rgba(255, 255, 255, 0.1)',\n borderRadius: '12px',\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n paddingInline: '16px',\n paddingBlock: '14px',\n zIndex: 99999999,\n backdropFilter: 'blur(12px)',\n };\n\n const messageStyle: React.CSSProperties = {\n color: textColor || '#FFFFFF',\n fontSize: '14px',\n fontWeight: 500,\n maxHeight: '100px',\n overflowX: 'hidden',\n overflowY: 'visible',\n textOverflow: 'ellipsis',\n whiteSpace: 'pre-line',\n fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n margin: 0,\n };\n\n return (\n <div style={notificationStyle} data-toast-container>\n <div style={{ flexShrink: 0 }}>\n <IconComponent size={20} color=\"#FFFFFF\" />\n </div>\n <p\n style={messageStyle}\n dangerouslySetInnerHTML={{\n __html: message,\n }}\n />\n </div>\n );\n};\n\nexport default ToastNotification;\n","export { toast, ToastProvider, useToast } from './context/ToastContext';\nexport type { ToastAPI } from './context/ToastContext';\n\n// components\nexport { Toast } from './components/Toast';\nexport { ToastContainer } from './components/ToastContainer';\n\n// icons\nexport {\n SuccessIcon,\n ErrorIcon,\n WarningIcon,\n InfoIcon,\n LoadingIcon,\n CloseIcon,\n TrashIcon,\n getVariantIcon,\n Icon, // legacy icon component\n} from './icons/Icons';\n\nexport type {\n ToastVariant,\n ToastPosition,\n ToastAction,\n ToastOptions,\n Toast as ToastType,\n ToastState,\n ToastContainerProps,\n ToastTheme,\n //legacy types...\n ToastDetail,\n} from './types';\n\nexport { ToastType as ToastTypeEnum } from './types';\n\n// styles (for advanced customization)\nexport { colors, theme, injectStyles } from './styles/styles';\n\n// Backwards Compatibility\n\n// legacy showToast API - wraps new toast API..\nimport { toast } from './context/ToastContext';\n\n/** @deprecated Use `toast` instead */\nexport const showToast = {\n success: (message: string, duration?: number) =>\n toast.success(message, { duration }),\n error: (message: string, duration?: number) =>\n toast.error(message, { duration }),\n warning: (message: string, duration?: number) =>\n toast.warning(message, { duration }),\n info: (message: string, duration?: number) =>\n toast.info(message, { duration }),\n};\n\n// legacy ToastNotification component export\nexport { default as ToastNotification } from './ToastNotification';\n"],"mappings":"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","names":["createContext","useContext","useState","useCallback","createRoot","useEffect","colors","theme","keyframes","styleInjected","injectStyles","style","containerStyles","position","_themeMode","gap","isTop","isLeft","isCenter","toastStyles","_variant","themeMode","isExiting","t","accentLineStyles","variant","iconContainerStyles","contentStyles","titleStyles","descriptionStyles","actionsStyles","actionButtonStyles","closeButtonStyles","spinnerStyles","useState","useEffect","useCallback","jsx","jsxs","SuccessIcon","size","color","colors","ErrorIcon","WarningIcon","InfoIcon","LoadingIcon","spinnerStyles","CloseIcon","TrashIcon","variantIcons","getVariantIcon","variant","IconComponent","Icon","jsx","jsxs","Toast","toast","theme","onDismiss","isExiting","setIsExiting","useState","handleDismiss","useCallback","useEffect","timer","handleActionClick","toastStyles","accentLineStyles","iconContainerStyles","getVariantIcon","contentStyles","titleStyles","descriptionStyles","actionsStyles","actionButtonStyles","e","closeButtonStyles","CloseIcon","Fragment","jsx","ToastContainer","toasts","onDismiss","position","theme","maxVisible","gap","useEffect","injectStyles","groupedToasts","acc","toast","pos","limitedToasts","toastList","getResponsivePosition","responsivePos","containerStyles","Toast","jsx","jsxs","ToastContext","createContext","useToast","context","useContext","ToastProvider","children","position","theme","maxVisible","gap","toasts","setToasts","useState","generateId","addToast","useCallback","variant","title","options","id","toast","prev","dismissToast","t","dismissAll","contextValue","ToastContainer","globalRoot","globalState","globalConfig","ensureContainer","container","createRoot","renderToasts","promise","messages","result","successMessage","error","errorMessage","config","ToastType","jsx","jsxs","typeToIconMap","SuccessIcon","ErrorIcon","WarningIcon","InfoIcon","ToastNotification","message","backgroundColor","textColor","type","position","IconComponent","defaultPositionStyle","notificationStyle","ToastNotification_default","showToast","message","duration","toast"]}