feat(renderer): lib/toast.ts typed wrappers over sonner

This commit is contained in:
2026-06-05 22:46:45 +05:30
parent 6762b5f9af
commit 8160ac05e0
2 changed files with 70 additions and 0 deletions
+22
View File
@@ -0,0 +1,22 @@
import { toast as sonnerToast } from 'sonner';
/**
* Typed wrappers over sonner's toast API. Centralizing the import gives us
* a single surface to evolve (e.g., add brand colors, action buttons,
* analytics) without touching every call site.
*/
export const toast = {
success: (message: string) => sonnerToast.success(message),
error: (message: string) => sonnerToast.error(message),
info: (message: string) => sonnerToast.info(message),
warning: (message: string) => sonnerToast.warning(message),
promise: <T>(
promise: Promise<T>,
msgs: {
loading: string;
success: string | ((data: T) => string);
error: string | ((err: unknown) => string);
}
) => sonnerToast.promise(promise, msgs),
dismiss: (id?: string | number) => sonnerToast.dismiss(id),
};
+48
View File
@@ -0,0 +1,48 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
vi.mock('sonner', () => ({
toast: {
success: vi.fn(),
error: vi.fn(),
info: vi.fn(),
warning: vi.fn(),
promise: vi.fn(),
dismiss: vi.fn(),
},
}));
import { toast } from '@/lib/toast';
import { toast as sonnerToast } from 'sonner';
describe('toast helpers', () => {
beforeEach(() => {
vi.clearAllMocks();
});
it('toast.success forwards to sonner with the message', () => {
toast.success('Saved test.md');
expect(sonnerToast.success).toHaveBeenCalledWith('Saved test.md');
});
it('toast.error forwards to sonner with the message', () => {
toast.error('Failed to save: ENOENT');
expect(sonnerToast.error).toHaveBeenCalledWith('Failed to save: ENOENT');
});
it('toast.info forwards to sonner with the message', () => {
toast.info('Update available');
expect(sonnerToast.info).toHaveBeenCalledWith('Update available');
});
it('toast.warning forwards to sonner with the message', () => {
toast.warning('Disk space low');
expect(sonnerToast.warning).toHaveBeenCalledWith('Disk space low');
});
it('toast.promise forwards the promise and messages to sonner', async () => {
const promise = Promise.resolve('ok');
const msgs = { loading: 'Loading…', success: 'Done', error: 'Failed' };
toast.promise(promise, msgs);
expect(sonnerToast.promise).toHaveBeenCalledWith(promise, msgs);
});
});