{"id":13806072,"url":"https://github.com/wobsoriano/svelte-sonner","last_synced_at":"2025-05-15T03:02:48.818Z","repository":{"id":178217999,"uuid":"661249081","full_name":"wobsoriano/svelte-sonner","owner":"wobsoriano","description":"An opinionated toast component for Svelte. A port of @emilkowalski's sonner.","archived":false,"fork":false,"pushed_at":"2025-05-12T02:01:55.000Z","size":764,"stargazers_count":868,"open_issues_count":25,"forks_count":28,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-05-12T03:20:48.800Z","etag":null,"topics":["notifications","svelte","toast"],"latest_commit_sha":null,"homepage":"https://svelte-sonner.vercel.app","language":"Svelte","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wobsoriano.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"wobsoriano"}},"created_at":"2023-07-02T08:57:13.000Z","updated_at":"2025-05-11T14:24:13.000Z","dependencies_parsed_at":"2023-11-11T19:29:57.219Z","dependency_job_id":"5a71db3b-73ca-4e16-8d08-2561f27ffc20","html_url":"https://github.com/wobsoriano/svelte-sonner","commit_stats":{"total_commits":229,"total_committers":20,"mean_commits":11.45,"dds":0.3580786026200873,"last_synced_commit":"a5895f21149779cd829e6039f8d3f8c3ca55f494"},"previous_names":["wobsoriano/svelte-sonner"],"tags_count":43,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wobsoriano%2Fsvelte-sonner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wobsoriano%2Fsvelte-sonner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wobsoriano%2Fsvelte-sonner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wobsoriano%2Fsvelte-sonner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wobsoriano","download_url":"https://codeload.github.com/wobsoriano/svelte-sonner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253793205,"owners_count":21965298,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["notifications","svelte","toast"],"created_at":"2024-08-04T01:01:07.593Z","updated_at":"2025-05-15T03:02:48.804Z","avatar_url":"https://github.com/wobsoriano.png","language":"Svelte","funding_links":["https://github.com/sponsors/wobsoriano"],"categories":["UI Components","Svelte","Front-End"],"sub_categories":["Notification","Sevelt Libraries"],"readme":"https://github.com/wobsoriano/svelte-sonner/assets/13049130/4b9c250f-1431-4130-9c5b-5a4f8b0210c5\n\n# svelte-sonner\n\n[![pnpm](https://img.shields.io/badge/maintained%20with-pnpm-cc00ff.svg?style=for-the-badge\u0026logo=pnpm)](https://pnpm.io/)\n\nAn opinionated toast component for Svelte. A port of Emil Kowalski's [Sonner](https://sonner.emilkowal.ski/).\n\n## Quick start\n\nInstall it:\n\n```bash\nnpm i svelte-sonner\n# or\nyarn add svelte-sonner\n# or\npnpm add svelte-sonner\n```\n\nAdd `\u003cToaster /\u003e` to your app, it will be the place where all your toasts will be rendered. After that, you can use `toast()` from anywhere in your app.\n\n```svelte\n\u003cscript\u003e\n\timport { Toaster, toast } from 'svelte-sonner';\n\u003c/script\u003e\n\n\u003cToaster /\u003e\n\u003cbutton onclick={() =\u003e toast('My first toast')}\u003eGive me a toast\u003c/button\u003e\n```\n\n## Types\n\n### Default\n\nMost basic toast. You can customize it (and any other type) by passing an options object as the second argument.\n\n```js\ntoast('Event has been created');\n```\n\nWith custom icon and description:\n\n```js\nimport Icon from './Icon.svelte';\n\ntoast('Event has been created', {\n\tdescription: 'Monday, January 3rd at 6:00pm',\n\ticon: Icon\n});\n```\n\n### Success\n\nRenders a checkmark icon in front of the message.\n\n```js\ntoast.success('Event has been created');\n```\n\n### Info\n\nRenders a question mark icon in front of the message.\n\n```js\ntoast.info('Event has new information');\n```\n\n### Warning\n\nRenders a warning icon in front of the message.\n\n```js\ntoast.warning('Event has warning');\n```\n\n### Error\n\nRenders an error icon in front of the message.\n\n```js\ntoast.error('Event has not been created');\n```\n\n### Action\n\nRenders a button.\n\n```js\ntoast('Event has been created', {\n\taction: {\n\t\tlabel: 'Undo',\n\t\tonClick: () =\u003e console.log('Undo')\n\t}\n});\n```\n\n### Promise\n\nStarts in a loading state and will update automatically after the promise resolves or fails.\n\n```js\ntoast.promise(() =\u003e new Promise((resolve) =\u003e setTimeout(resolve, 2000)), {\n\tloading: 'Loading',\n\tsuccess: 'Success',\n\terror: 'Error'\n});\n```\n\nYou can pass a function to the success/error messages to incorporate the result/error of the promise.\n\n```js\ntoast.promise(promise, {\n\tloading: 'Loading...',\n\tsuccess: (data) =\u003e {\n\t\treturn `${data.name} has been added!`;\n\t},\n\terror: 'Error'\n});\n```\n\n### Custom Component\n\nYou can pass a component as the first argument instead of a string to render custom component while maintaining default styling. You can use the headless version below for a custom, unstyled toast.\n\n```js\ntoast(CustomComponent);\n```\n\n### Updating a toast\n\nYou can update a toast by using the `toast` function and passing it the id of the toast you want to update, the rest stays the same.\n\n```js\nconst toastId = toast('Sonner');\n\ntoast.success('Toast has been updated', {\n\tid: toastId\n});\n```\n\n## Customization\n\n### Headless\n\nYou can use `toast.custom` to render an unstyled toast with custom component while maintaining the functionality.\n\n```svelte\n\u003cscript\u003e\n\timport { createEventDispatcher } from 'svelte';\n\n\tconst dispatch = createEventDispatcher();\n\u003c/script\u003e\n\n\u003cdiv\u003e\n\tThis is a custom component \u003cbutton onclick={() =\u003e dispatch('closeToast')}\u003eclose\u003c/button\u003e\n\u003c/div\u003e\n```\n\n```js\nimport HeadlessToast from './HeadlessToast.svelte';\n\ntoast.custom(HeadlessToast);\n```\n\n### Theme\n\nYou can change the theme using the `theme` prop. Default theme is light.\n\n```svelte\n\u003cToaster theme=\"dark\" /\u003e\n```\n\n### Position\n\nYou can change the position through the `position` prop on the `\u003cToaster /\u003e` component. Default is `bottom-right`.\n\n```svelte\n\u003c!-- Available positions --\u003e\n\u003c!-- top-left, top-center, top-right, bottom-left, bottom-center, bottom-right --\u003e\n\n\u003cToaster position=\"top-center\" /\u003e\n```\n\n### Expanded\n\nToasts can also be expanded by default through the `expand` prop. You can also change the amount of visible toasts which is 3 by default.\n\n```svelte\n\u003cToaster expand visibleToasts={9} /\u003e\n```\n\n### Styling\n\nStyling can be done globally via `toastOptions`, this way every toast will have the same styling.\n\n```svelte\n\u003cToaster\n\ttoastOptions={{\n\t\tstyle: 'background: red;',\n\t\tclass: 'my-toast',\n\t\tdescriptionClass: 'my-toast-description'\n\t}}\n/\u003e\n```\n\nYou can also use the same props when calling `toast` to style a specific toast.\n\n```js\ntoast('Event has been created', {\n\tstyle: 'background: red;',\n\tclass: 'my-toast',\n\tdescriptionClass: 'my-toast-description'\n});\n```\n\n### Tailwind CSS\n\nThe preferred way to style the toasts with tailwind is by using the `unstyled` prop. That will give you an unstyled toast which you can then style with tailwind.\n\n```svelte\n\u003cToaster\n\ttoastOptions={{\n\t\tunstyled: true,\n\t\tclasses: {\n\t\t\ttoast: 'bg-blue-400',\n\t\t\ttitle: 'text-red-400',\n\t\t\tdescription: 'text-red-400',\n\t\t\tactionButton: 'bg-zinc-400',\n\t\t\tcancelButton: 'bg-orange-400',\n\t\t\tcloseButton: 'bg-lime-400'\n\t\t}\n\t}}\n/\u003e\n```\n\nYou can do the same when calling `toast()`.\n\n```js\ntoast('Hello World', {\n\tunstyled: true,\n\tclasses: {\n\t\ttoast: 'bg-blue-400',\n\t\ttitle: 'text-red-400 text-2xl',\n\t\tdescription: 'text-red-400',\n\t\tactionButton: 'bg-zinc-400',\n\t\tcancelButton: 'bg-orange-400',\n\t\tcloseButton: 'bg-lime-400'\n\t}\n});\n```\n\nStyling per toast type is also possible.\n\n```svelte\n\u003cToaster\n\ttoastOptions={{\n\t\tunstyled: true,\n\t\tclasses: {\n\t\t\terror: 'bg-red-400',\n\t\t\tsuccess: 'text-green-400',\n\t\t\twarning: 'text-yellow-400',\n\t\t\tinfo: 'bg-blue-400'\n\t\t}\n\t}}\n/\u003e\n```\n\n### Changing Icon\n\nYou can change the default icons using snippets:\n\n```svelte\n\u003cToaster\u003e\n\t{#snippet loadingIcon()}\n\t\t\u003cLoadingIcon /\u003e\n\t{/snippet}\n\t{#snippet successIcon()}\n\t\t\u003cSuccessIcon /\u003e\n\t{/snippet}\n\t{#snippet errorIcon()}\n\t\t\u003cErrorIcon /\u003e\n\t{/snippet}\n\t{#snippet infoIcon()}\n\t\t\u003cInfoIcon /\u003e\n\t{/snippet}\n\t{#snippet warningIcon()}\n\t\t\u003cWarningIcon /\u003e\n\t{/snippet}\n\u003c/Toaster\u003e\n```\n\n### Close button\n\nAdd a close button to all toasts that shows on hover by adding the `closeButton` prop.\n\n```svelte\n\u003cToaster closeButton /\u003e\n```\n\n### Rich colors\n\nYou can make error and success state more colorful by adding the `richColors` prop.\n\n```svelte\n\u003cToaster richColors /\u003e\n```\n\n### Custom offset\n\nOffset from the edges of the screen.\n\n```svelte\n\u003cToaster offset=\"80px\" /\u003e\n```\n\n### Programmatically remove toast\n\nTo remove a toast programmatically use `toast.dismiss(id)`. The `toast()` function returns the id of the toast.\n\n```js\nconst toastId = toast('Event has been created');\n\ntoast.dismiss(toastId);\n```\n\nYou can also dismiss all toasts at once by calling `toast.dismiss()` without an id.\n\n```js\ntoast.dismiss();\n```\n\n### `useSonner`\n\nYou can use the `useSonner` hook to retrieve all visible toasts like below.\n\n```ts\nconst sonner = useSonner();\n\n$effect(() =\u003e console.log(sonner.toasts));\n```\n\n### Duration\n\nYou can change the duration of each toast by using the `duration` property, or change the duration of all toasts like this:\n\n```svelte\n\u003cToaster duration={10000} /\u003e\n```\n\n```js\ntoast('Event has been created', {\n\tduration: 10000\n});\n\n// Persisent toast\ntoast('Event has been created', {\n\tduration: Number.POSITIVE_INFINITY\n});\n```\n\n### On Close Callback\n\nYou can pass `onDismiss` and `onAutoClose` callbacks. `onDismiss` gets fired when either the close button gets clicked or the toast is swiped. `onAutoClose` fires when the toast disappears automatically after it's timeout (`duration` prop).\n\n```js\ntoast('Event has been created', {\n\tonDismiss: (t) =\u003e console.log(`Toast with id ${t.id} has been dismissed`),\n\tonAutoClose: (t) =\u003e console.log(`Toast with id ${t.id} has been closed automatically`)\n});\n```\n\n## Keyboard focus\n\nYou can focus on the toast area by pressing ⌥/alt + T. You can override it by providing an array of `event.code` values for each key.\n\n```svelte\n\u003cToaster hotkey={['KeyC']} /\u003e\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwobsoriano%2Fsvelte-sonner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwobsoriano%2Fsvelte-sonner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwobsoriano%2Fsvelte-sonner/lists"}