{"id":13808756,"url":"https://github.com/tutkli/ngx-sonner","last_synced_at":"2025-05-16T14:07:32.878Z","repository":{"id":223539269,"uuid":"760679244","full_name":"tutkli/ngx-sonner","owner":"tutkli","description":"An opinionated toast component for Angular. A port of @emilkowalski's sonner.","archived":false,"fork":false,"pushed_at":"2025-03-28T12:29:35.000Z","size":1128,"stargazers_count":128,"open_issues_count":5,"forks_count":10,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-09T11:03:36.060Z","etag":null,"topics":["angular","sonner","toast"],"latest_commit_sha":null,"homepage":"https://tutkli.github.io/ngx-sonner/","language":"TypeScript","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/tutkli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"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}},"created_at":"2024-02-20T18:28:45.000Z","updated_at":"2025-05-06T06:54:33.000Z","dependencies_parsed_at":"2024-06-03T11:05:58.374Z","dependency_job_id":"1b86cff6-7f1b-4ee2-a34e-42d26ff8e9ee","html_url":"https://github.com/tutkli/ngx-sonner","commit_stats":null,"previous_names":["tutkli/ngx-sonner"],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tutkli%2Fngx-sonner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tutkli%2Fngx-sonner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tutkli%2Fngx-sonner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tutkli%2Fngx-sonner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tutkli","download_url":"https://codeload.github.com/tutkli/ngx-sonner/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254544146,"owners_count":22088807,"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":["angular","sonner","toast"],"created_at":"2024-08-04T01:01:51.206Z","updated_at":"2025-05-16T14:07:32.849Z","avatar_url":"https://github.com/tutkli.png","language":"TypeScript","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Notifications"],"readme":"# ngx-sonner\n\nAn opinionated toast component for Angular.\n\nBased on [emilkowalski](https://github.com/emilkowalski)'s React [implementation](https://sonner.emilkowal.ski/).\n\n## Angular compatibility\n\n| ngx-sonner | @angular |\n|------------|----------|\n| 2.0.0      | ≥18.0.0  |\n| 1.0.0      | ≥17.3.0  |\n\n## Quick start\n\nInstall it with your favorite package manager:\n\n```bash\nnpm i ngx-sonner\n# or\nyarn add ngx-sonner\n# or\npnpm add ngx-sonner\n# or\nbun add ngx-sonner\n```\n\nAdd `\u003cngx-sonner-toaster /\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```ts\nimport { toast, NgxSonnerToaster } from 'ngx-sonner';\n\n@Component({\n  selector: 'app-root',\n  imports: [NgxSonnerToaster],\n  template: `\n    \u003cngx-sonner-toaster /\u003e\n    \u003cbutton (click)=\"toast('My first toast')\"\u003eGive me a toast\u003c/button\u003e\n`\n})\nexport class AppComponent {\n  protected readonly toast = toast;\n}\n```\n\n## Table of contents\n\n- [toast()](#toast)\n  - [Creating toasts](#creating-toasts)\n    - [Default](#default)\n    - [Success](#success)\n    - [Info](#info)\n    - [Warning](#warning)\n    - [Error](#error)\n    - [Action](#action)\n    - [Cancel](#cancel)\n    - [Promise](#promise)\n    - [Loading](#loading)\n    - [Custom component](#custom-component)\n    - [Headless](#headless)\n    - [Dynamic position](#dynamic-position)\n  - [Other](#other)\n    - [Updating a toast](#updating-a-toast)\n    - [On Close Callback](#on-close-callback)\n    - [Dismissing toasts programmatically](#dismissing-toasts-programmatically)\n- [Toaster](#toaster)\n  - [Theme](#theme)\n  - [Position](#position)\n  - [Expand](#expand)\n  - [Custom Icons](#custom-icons)\n  - [Close button](#close-button)\n  - [Rich colors](#rich-colors)\n  - [Custom offset](#custom-offset)\n  - [Duration](#duration)\n  - [Keyboard focus](#keyboard-focus)\n- [Styling](#styling)\n  - [TailwindCSS](#tailwind-css)\n\n## toast()\n\nUse it to render a toast. You can call it from anywhere, even outside of React.\n\n### Creating toasts\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```ts\ntoast('Event has been created');\n```\n\nWith custom icon and description:\n\n```ts\ntoast('Event has been created', {\n  description: 'Monday, January 3rd at 6:00pm',\n  icon: IconComponent\n});\n```\n\n#### Success\n\nRenders a checkmark icon in front of the message.\n\n```ts\ntoast.success('Event has been created');\n```\n\n#### Info\n\nRenders a question mark icon in front of the message.\n\n```ts\ntoast.info('Event has new information');\n```\n\n#### Warning\n\nRenders a warning icon in front of the message.\n\n```ts\ntoast.warning('Event has warning');\n```\n\n#### Error\n\nRenders an error icon in front of the message.\n\n```ts\ntoast.error('Event has not been created');\n```\n\n#### Action\n\nRenders a primary button, clicking it will close the toast and run the callback passed via `onClick`.\nYou can prevent the toast from closing by calling `event.preventDefault()` in the onClick callback.\n\n```ts\ntoast('My action toast', {\n  action: {\n    label: 'Action',\n    onClick: () =\u003e console.log('Action!')\n  }\n});\n```\n\n#### Cancel\n\nRenders a secondary button, clicking it will close the toast and run the callback passed via `onClick`.\n\n```ts\ntoast('My cancel toast', {\n  cancel: {\n    label: 'Cancel',\n    onClick: () =\u003e console.log('Cancel!'),\n  },\n});\n```\n\n#### Promise\n\nStarts in a loading state and will update automatically after the promise resolves or fails.\n\n```ts\ntoast.promise(() =\u003e new Promise((resolve) =\u003e setTimeout(resolve, 2000)), {\n  loading: 'Loading',\n  success: 'Success',\n  error: 'Error'\n});\n```\n\nYou can pass a function to the success/error messages to incorporate the result/error of the promise.\n\n```ts\ntoast.promise(promise, {\n  loading: 'Loading...',\n  success: (data) =\u003e {\n    return `${data.name} has been added!`;\n  },\n  error: 'Error'\n});\n```\n\n#### Loading\n\nRenders a toast with a loading spinner. Useful when you want to handle various states yourself instead of using a promise toast.\n\n```ts\ntoast.loading('Loading data');\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.\n\n```ts\ntoast(CustomComponent);\n```\n\n#### Headless\n\nYou can use `toast.custom()` to render an unstyled toast with a custom component while maintaining the functionality.\n\n```ts\n@Component({\n  selector: 'app-custom',\n  template: `\n    \u003cdiv\u003e\n      This is a custom component \u003cbutton (click)=\"toastClick()\"\u003eclose\u003c/button\u003e\n    \u003c/div\u003e\n`\n})\nexport class CustomComponent {\n  toastClick() {\n    console.log('Hello world!');\n  }\n}\n```\n\n```ts\nimport { CustomComponent } from './custom.component';\n\ntoast.custom(CustomComponent);\n```\n\n#### Dynamic position\n\nYou can change the position of the toast dynamically by passing a position prop to the toast function. It will not affect the positioning of other toasts.\n\n```ts\n// Available positions:\n// top-left, top-center, top-right, bottom-left, bottom-center, bottom-right\ntoast('Hello World', {\n  position: 'top-center',\n});\n```\n\n### Other\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```ts\nconst toastId = toast('Sonner');\n\ntoast.success('Toast has been updated', {\n  id: toastId\n});\n```\n\n#### On Close Callback\n\nYou can pass `onDismiss` and `onAutoClose` callbacks to each toast. `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```ts\ntoast('Event has been created', {\n  onDismiss: (t) =\u003e console.log(`Toast with id ${t.id} has been dismissed`),\n  onAutoClose: (t) =\u003e console.log(`Toast with id ${t.id} has been closed automatically`),\n});\n```\n\n#### Dismissing toasts programmatically\n\nTo remove a toast programmatically use `toast.dismiss(id)`. The `toast()` function return the id of the toast.\n\n```ts\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```ts\ntoast.dismiss();\n```\n\n## Toaster\n\nThis component renders all the toasts, you can place it anywhere in your app.\n\n### Theme\n\nYou can change the theme using the `theme` prop. Default theme is light.\n\n```html\n\u003cngx-sonner-toaster theme=\"dark\" /\u003e\n```\n\n### Position\n\nYou can change the position through the `position` prop on the `\u003cngx-sonner-toaster /\u003e` component. Default is `bottom-right`.\n\n```html\n\u003c!-- Available positions --\u003e\n\u003c!-- top-left, top-center, top-right, bottom-left, bottom-center, bottom-right --\u003e\n\n\u003cngx-sonner-toaster position=\"top-center\" /\u003e\n```\n\n### Expand\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```html\n\u003cngx-sonner-toaster expand visibleToasts=\"9\" /\u003e\n```\n\n### Custom icons\n\nYou can change the default icons by providing your icons inside the toaster component.\n\n```html\n\u003cngx-sonner-toaster\u003e\n  \u003ccustom-loading-icon loading-icon/\u003e\n  \u003ccustom-success-icon success-icon /\u003e\n  \u003ccustom-error-icon error-icon /\u003e\n  \u003ccustom-info-icon info-icon /\u003e\n  \u003ccustom-warning-icon warning-icon /\u003e\n\u003c/ngx-sonner-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```html\n\u003cngx-sonner-toaster closeButton /\u003e\n```\n\n### Rich colors\n\nYou can make error and success state more colorful by adding the `richColors` prop.\n\n```html\n\u003cngx-sonner-toaster richColors /\u003e\n```\n\n### Custom offset\n\nOffset from the edges of the screen.\n\n```html\n\u003cngx-sonner-toaster offset=\"80px\" /\u003e\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```html\n\u003cngx-sonner-toaster duration=\"10000\" /\u003e\n```\n\n```ts\ntoast('Event has been created', {\n  duration: 10000\n});\n\n// Persisent toast\ntoast('Event has been created', {\n  duration: Number.POSITIVE_INFINITY\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```html\n\u003cngx-sonner-toaster [hotKey]=\"['KeyC']\" /\u003e\n```\n\n## Styling\n\nStyling can be done globally via `toastOptions`, this way every toast will have the same styling.\n\n```html\n\u003cngx-sonner-toaster\n  [toastOptions]=\"{\n\t\tstyle: { background: 'red' },\n    className: 'my-toast',\n\t}\"\n/\u003e\n```\n\nYou can also use the same props when calling `toast` to style a specific toast.\n\n```ts\ntoast('Event has been created', {\n  style: 'background: red;',\n  class: 'my-toast',\n  descriptionClass: '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```html\n\u003cngx-sonner-toaster\n  [toastOptions]=\"{\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```ts\ntoast('Hello World', {\n  unstyled: true,\n  classes: {\n    toast: 'bg-blue-400',\n    title: 'text-red-400 text-2xl',\n    description: 'text-red-400',\n    actionButton: 'bg-zinc-400',\n    cancelButton: 'bg-orange-400',\n    closeButton: 'bg-lime-400',\n  },\n})\n```\n\nStyling per toast type is also possible.\n\n```html\n\u003cngx-sonner-toaster\n  [toastOptions]=\"{\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## License\n\n[MIT](https://github.com/tutkli/ngx-sonner/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftutkli%2Fngx-sonner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftutkli%2Fngx-sonner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftutkli%2Fngx-sonner/lists"}