fix(toaster): render error toasts on a red surface

Error toasts previously used the same neutral popover background as
success toasts, so a failure (e.g. a save while the backend is down)
read like a normal 'Canvas saved'. Set sonner's per-type --error-bg/
--error-text/--error-border so errors stand out in red.
This commit is contained in:
Pouzor
2026-07-19 11:33:54 +02:00
parent deccff15cf
commit e85dab8cfc
2 changed files with 41 additions and 0 deletions
@@ -0,0 +1,36 @@
import { describe, it, expect, afterEach, beforeAll, vi } from 'vitest'
import { render, cleanup, waitFor } from '@testing-library/react'
import { toast } from 'sonner'
import { Toaster } from '../sonner'
beforeAll(() => {
// sonner reads matchMedia for theme detection; jsdom doesn't provide it.
window.matchMedia = vi.fn().mockImplementation((query: string) => ({
matches: false,
media: query,
onchange: null,
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
addListener: vi.fn(),
removeListener: vi.fn(),
dispatchEvent: vi.fn(),
}))
})
afterEach(() => cleanup())
describe('Toaster', () => {
it('renders error toasts on a red surface so failures are visible', async () => {
render(<Toaster />)
toast.error('Save failed')
// The style (with the CSS vars) lands on the toast list, mounted on first toast.
const list = await waitFor(() => {
const el = document.querySelector('[data-sonner-toaster]') as HTMLElement | null
expect(el).not.toBeNull()
return el!
})
const style = list.getAttribute('style') ?? ''
expect(style).toContain('--error-bg: #f85149')
expect(style).toContain('--error-text: #ffffff')
})
})
+5
View File
@@ -34,6 +34,11 @@ const Toaster = ({ ...props }: ToasterProps) => {
"--normal-text": "var(--popover-foreground)",
"--normal-border": "var(--border)",
"--border-radius": "var(--radius)",
// Errors use a red surface so failures (e.g. a failed save while the
// backend is down) stand out instead of reading like a normal toast.
"--error-bg": "#f85149",
"--error-text": "#ffffff",
"--error-border": "#da3633",
} as React.CSSProperties
}
toastOptions={{