Docs
Press Run on any example to see the real toast. Prefer plain text? llms.txt
Install
There is no stylesheet to import: styles are injected from JavaScript.
npm i @yusufceng1z/ding-react
Using shadcn/ui? This installs the package and adds a ding-toaster.tsx wrapper:
npx shadcn@latest add @ding/ding
npm i @yusufceng1z/ding-svelte
npm i @yusufceng1z/ding
Setup
Render the toaster once, near the root of your app.
import { Toaster } from '@yusufceng1z/ding-react';
export default function App() {
return (
<>
<Toaster position="top-center" theme="system" />
{/* your app */}
</>
);
}
<script>
import { Toaster } from '@yusufceng1z/ding-svelte';
</script>
<Toaster position="top-center" theme="system" />
import { mountToaster } from '@yusufceng1z/ding';
const unmount = mountToaster({ position: 'top-center' });
Show a toast
Import toast from the same package and call it from anywhere. Every call returns the toast id. toast.loading(title) works the same and stays until you update or dismiss it.
import { toast } from '@yusufceng1z/ding-react@yusufceng1z/ding-svelte@yusufceng1z/ding';
toast.success('Saved');
toast.error('Payment failed', { description: 'Card declined' });
toast.warning('Storage almost full');
toast.info('New version available');
Only one toast is visible at a time. A new call morphs the toast on screen instead of stacking a second one. Repeating the same toast adds a counter (×2).
Update in place
Wrap a promise and one toast moves from loading to the result:
toast.promise(save(), {
loading: 'Saving…',
success: 'Saved',
error: (err) => `Could not save: ${err.message}`,
});
Or update by hand, for progress and other long jobs:
const id = toast.loading('Uploading photo…', { progress: 0 });
toast.update(id, { progress: 0.6 });
toast.update(id, { type: 'success', title: 'Photo uploaded', progress: null });
Only the newest caller can update the shared toast, so a slow request that finishes late cannot overwrite a newer message.
Actions
An onClick may return a patch. The toast then morphs in place instead of closing. A returned patch removes the buttons unless it names them again.
toast.success('Message deleted', {
action: {
label: 'Undo',
onClick: () => {
restore();
return { type: 'info', title: 'Restored' };
},
},
});
Options
description- Second line of text.
action{ label, onClick }. The main button.secondary{ label, onClick }. A quieter button beside the action.image- Avatar or thumbnail URL. Replaces the status icon.
meta- Small trailing text, such as “now” or “⌘V”.
progress- 0 to 1. Draws a thin bar at the bottom of the toast.
duration- Milliseconds before it closes.
0keeps it until dismissed. Default 5000. id- Reuse an id so repeated calls from one place stay one caller.
Errors, loading toasts and toasts with a button stay until dismissed, so nobody misses something they need to act on. Hover and keyboard focus pause the timer.
Configure
toast.configure({
position: 'bottom-right', // top-left, top-center, top-right, bottom-left, bottom-center, bottom-right
theme: 'dark', // system, light, dark
labels: { dismiss: 'Fermer la notification' }, // screen reader names, English by default
sound: true,
volume: 0.5,
});
toast.dismiss(id); // one toast
toast.dismiss(); // all
Position, theme and labels can also be set as props on the toaster. The toast follows reading direction, so right-to-left pages mirror automatically.
labels sets the names screen readers announce for the notifications region (region) and the close button (dismiss). Keys you leave out keep their English default, so a non-English page only needs to translate what it uses.
Sound
Off by default. Turn it on and each status gets its own soft tone: success rises, error falls, warning double-taps, info is a single note. Loading is silent, and progress updates never make a sound.
toast.configure({ sound: true, volume: 0.5 });
Browsers keep audio locked until a click or key press, so the first sound has to follow one. To use your own sounds or a sound library, pass a function. It receives success, error, warning, info or loading, once per new toast and once per status change.
toast.configure({ sound: (type) => mySounds.play(type) });
Accessibility
- Messages go through persistent live regions: errors are announced assertively, everything else politely.
- Esc dismisses. Alt + T moves focus into the toast.
- Respects
prefers-reduced-motion. - Buttons stay out of the tab order until the toast has opened.