YusufCeng1z/ding has 509 GitHub stars and 12 forks. GitHot measured +178 stars in 24 hours. Last checked 2026-11-11 09:28 UTC. Last push 2026-11-06.
Comment ces chiffres sont mesurés
Notifications toast avec une véritable physique de ressort. Une seule notification se transforme sur place. Aucune dépendance. Compatible avec React, Svelte et le DOM natif.
Progression mesurée des étoiles
- in 24h
- +178
- in 7 days
- Mise à jour retardée
- in 15 days
- Mise à jour retardée
- in 1 month
- Mise à jour retardée
Variations nettes sur des périodes qui se chevauchent, pas des totaux quotidiens. Les mesures absentes restent vides. Les étoiles indiquent l’intérêt, pas la qualité.
README.md
Original
Ding
Toasts with real spring physics.
One toast that morphs in place. No dependencies. React, Svelte or plain DOM.
Why Ding
- One toast at a time. A new call morphs the toast on screen instead of stacking a second one.
- Real springs. Size, shape and text move on a spring solver, so interrupting an animation keeps its momentum.
- No stylesheet. Styles are injected from JavaScript. Nothing to import.
- Light, dark and system themes, six positions, right-to-left support.
- Rich content. Description, avatar, buttons, progress bar, a countdown line, small trailing text.
- Accessible by default. Persistent live regions, keyboard dismiss,
prefers-reduced-motion. - Optional sound. A soft built-in tone per status, or plug in your own.
- Strict TypeScript, ESM and CommonJS builds.
Install
npm i @yusufceng1z/ding-react # React 18+
npm i @yusufceng1z/ding-svelte # Svelte 5
npm i @yusufceng1z/ding # plain DOM
Each framework package depends on the small @yusufceng1z/ding core, so you install only one.
Quick start
Render the toaster once, then call toast from anywhere.
React
import { Toaster, toast } from '@yusufceng1z/ding-react';
export default function App() {
return (
<>
<Toaster position="top-center" theme="system" />
<button onClick={() => toast.success('Saved')}>Save</button>
</>
);
}
Svelte 5
<script>
import { Toaster, toast } from '@yusufceng1z/ding-svelte';
</script>
<Toaster position="top-center" theme="system" />
<button onclick={() => toast.success('Saved')}>Save</button>
Plain DOM
import { mountToaster, toast } from '@yusufceng1z/ding';
mountToaster({ position: 'top-center' });
toast.success('Saved');
Usage
toast.success('Saved');
toast.error('Payment failed', { description: 'Card declined' });
toast.warning('Storage almost full');
toast.info('New version available');
toast.loading('Uploading…');
Every call returns the toast id.
Promises and updates
toast.promise(save(), {
loading: 'Saving…',
success: 'Saved',
error: (err) => `Could not save: ${err.message}`,
});
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.
toast.success('Message deleted', {
action: {
label: 'Undo',
onClick: () => {
restore();
return { type: 'info', title: 'Restored' };
},
},
});
Options
| Option | Description |
|---|---|
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 |
duration |
Milliseconds before it closes. 0 keeps 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. Hover and keyboard focus pause the timer. Repeating the same toast adds a counter (×2).
Configure
toast.configure({
position: 'bottom-right', // top-left, top-center, top-right, bottom-left, bottom-center, bottom-right
theme: 'dark', // system, light, dark
sound: true,
volume: 0.5,
});
toast.dismiss(id); // one toast
toast.dismiss(); // all
Sound
Off by default. With sound: true each status plays 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. Browsers keep audio locked until a click or key press.
To use your own sounds, pass a function. It receives success, error, warning, info or loading:
toast.configure({ sound: (type) => mySounds.play(type) });
Accessibility
- Messages go through persistent live regions: errors are assertive, everything else is polite.
Escdismisses.Alt+Tmoves focus into the toast.- Respects
prefers-reduced-motion. - Mirrors automatically on right-to-left pages.
Packages
| Package | Description |
|---|---|
@yusufceng1z/ding |
Springs, timers, store, sound and the plain DOM renderer |
@yusufceng1z/ding-react |
React renderer |
@yusufceng1z/ding-svelte |
Svelte 5 renderer |
The core owns all behavior. The framework packages only render.
Development
pnpm install
pnpm test # unit tests
pnpm typecheck
pnpm build # build all packages
pnpm dev # docs and demo site
The docs site lives in apps/docs. A machine-readable summary is in apps/docs/public/llms.txt.
License
Explorer des projets similaires
ytdl-org/youtube-dl
Programme en ligne de commande pour télécharger des vidéos depuis YouTube.com et d’autres sites vidéo
141,527 étoilesexcalidraw/excalidraw
Tableau blanc virtuel pour esquisser des diagrammes au style dessiné à la main
135,492 étoilesgodotengine/godot
Godot Engine – Moteur de jeu 2D et 3D multiplateforme
119,942 étoilesmrdoob/three.js
Bibliothèque 3D en JavaScript.
118,122 étoiles