'use client'; import * as React from 'react'; import { Toaster as Sonner, ToasterProps } from 'sonner'; /** * Global toast notification injector (ephemeral notifications). * * @description * Wraps the `sonner` library with Xertica UI Tailwind styles and automatic * theme detection (light/dark). Renders toast notifications at the app level. * * @ai-rules * 1. `` must be injected ONCE in the entire app (e.g., in `App.tsx`). NEVER inside a page component. * 2. To show a toast, import `{ toast }` from `'sonner'` and call `toast.success("Saved!")` — do NOT re-render ``. * 3. Use toasts ONLY for global feedback ("Item saved", "Connection error"). Local form errors go in ``. */ const Toaster = ({ theme, ...props }: ToasterProps) => { // If no theme is provided, detect from document const [resolvedTheme, setResolvedTheme] = React.useState(theme); React.useEffect(() => { if (theme) { setResolvedTheme(theme); return; } // Auto-detect theme from document const detectTheme = () => { const isDark = document.documentElement.classList.contains('dark') || document.documentElement.getAttribute('data-theme') === 'dark'; setResolvedTheme(isDark ? 'dark' : 'light'); }; detectTheme(); // Watch for theme changes const observer = new MutationObserver(detectTheme); observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class', 'data-theme'], }); return () => observer.disconnect(); }, [theme]); return ( svg]:text-[color:var(--chart-2)]', error: 'group-[.toaster]:bg-destructive/10 group-[.toaster]:border-l-4 group-[.toaster]:border-l-destructive group-[.toaster]:text-foreground [&>svg]:text-destructive', warning: 'group-[.toaster]:bg-[color:var(--chart-3)]/10 group-[.toaster]:border-l-4 group-[.toaster]:border-l-[color:var(--chart-3)] group-[.toaster]:text-foreground [&>svg]:text-[color:var(--chart-3)]', info: 'group-[.toaster]:bg-[color:var(--chart-4)]/10 group-[.toaster]:border-l-4 group-[.toaster]:border-l-[color:var(--chart-4)] group-[.toaster]:text-foreground [&>svg]:text-[color:var(--chart-4)]', }, }} {...props} /> ); }; export { Toaster };