nextui icon indicating copy to clipboard operation
nextui copied to clipboard

feat(toast): support multiple ToastProvider

Open ChaserZ98 opened this issue 6 months ago โ€ข 7 comments

Related Issue #5559 Related PR #5602 #5590

๐Ÿ“ Description

This PR adopts the multi toaster design from react-hot-toast and adds support for multiple ToastProvider. It might provide an alternative solution to the above issues and PRs.

โ›ณ๏ธ Current behavior (updates)

All the ToastProvider instance shares the same ToastQueue. If there are multiple ToastProvider instances, call addToast once would cause all the ToastProvider instance to render the same toast, and hence create duplicate toasts.

๐Ÿš€ New behavior

Each ToastProvider instance has their own ToastQueue and an unique ID field toasterId (default to heroui) is used to distinguish each of them. addToast and closeToast API also receives this toasterId field to control the add and close behavior of the corresponding ToastProvider.

๐Ÿ’ฃ Is this a breaking change (Yes/No):

Only a bit change on params, so kind of a no.

๐Ÿ“ Additional Information

Please see the storybook Multi Toaster example for demo.

Summary by CodeRabbit

  • New Features

    • Support multiple ToastProviders with unique IDs and independent toast queues; toasts can be targeted, closed, and cleared per provider via a toasterId prop.
  • Documentation

    • Added a Storybook/demo showing two providers with separate queues and controls.
  • Tests

    • Added a unit test verifying multiple ToastProvider instances operate independently and scope placement/content.
  • Chores

    • Added a changeset for a patch release of the toast package.

ChaserZ98 avatar Aug 17 '25 18:08 ChaserZ98

๐Ÿฆ‹ Changeset detected

Latest commit: c6ab38f2c75c33c40aa922e6e836a75b25f371d6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@heroui/toast Patch
@heroui/react Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

changeset-bot[bot] avatar Aug 17 '25 18:08 changeset-bot[bot]

@ChaserZ98 is attempting to deploy a commit to the HeroUI Inc Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Aug 17 '25 18:08 vercel[bot]

Walkthrough

Adds support for multiple ToastProvider instances by introducing per-toaster queues keyed by toasterId, updating toast API signatures and ToastProvider to accept toasterId, and adding stories, tests, docs, and a changeset for the feature.

Changes

Cohort / File(s) Summary
Toast provider & queue routing
packages/components/toast/src/toast-provider.tsx
Replace single global queue with globalToastQueues keyed by toasterId. Update getToastQueue (overloads), addToast, closeToast, closeAll to accept/use toasterId. ToastProvider gains toasterId prop (defaults to defaultToasterId) and binds to per-id queue.
Toast props surface
packages/components/toast/src/use-toast.ts
Add public toasterId?: string to ToastProps to target a specific ToastProvider.
Stories / examples
packages/components/toast/stories/toast.stories.tsx, apps/docs/content/components/toast/multiple-ToastProvider.raw.jsx, apps/docs/content/components/toast/multiple-ToastProvider.ts, apps/docs/content/docs/components/toast.mdx, apps/docs/content/components/toast/index.ts
Add a MultiToaster story and docs example demonstrating two ToastProvider instances with distinct toasterIds and buttons that call addToast({ toasterId, ... }). Export the example in docs content and include it in toastContent.
Tests
packages/components/toast/__tests__/toast.test.tsx
Add unit test "should work with multiple ToastProvider" validating isolation and correct routing/placement for two providers keyed by toasterId.
Release metadata
.changeset/great-keys-admire.md
Add changeset for @heroui/toast patch release describing support for multiple ToastProvider instances via unique IDs.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Caller (e.g., Button)
  participant API as addToast / closeToast / closeAll
  participant Map as globalToastQueues
  participant TP as ToastProvider (toasterId)

  UI->>API: addToast({ toasterId, ... })
  API->>Map: get/create queue for toasterId
  Map-->>API: ToastQueue
  API-->>TP: enqueue toast in matching ToastQueue
  TP->>TP: render region for its toasterId

  UI->>API: closeToast({ key, toasterId })
  API->>Map: get queue for toasterId
  API-->>TP: close toast by key

  UI->>API: closeAll(toasterId)
  API->>Map: get queue for toasterId
  API-->>TP: close all visible toasts

Estimated code review effort

๐ŸŽฏ 3 (Moderate) | โฑ๏ธ ~20 minutes

Possibly related PRs

  • heroui-inc/heroui#4919 โ€” Touches ToastProps in packages/components/toast/src/use-toast.ts (also modifies the public toast API), which may overlap with the toasterId addition.

Suggested labels

๐Ÿ‘€ Status: To Review

Suggested reviewers

  • jrgarciadev
  • wingkwong
  • macci001

[!TIP]

๐Ÿ”Œ Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

โœจ Finishing Touches
  • [ ] ๐Ÿ“ Generate Docstrings
๐Ÿงช Generate unit tests
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

โค๏ธ Share
๐Ÿชง Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

coderabbitai[bot] avatar Aug 17 '25 18:08 coderabbitai[bot]

Open in StackBlitz

@heroui/accordion

npm i https://pkg.pr.new/@heroui/accordion@5606
@heroui/alert

npm i https://pkg.pr.new/@heroui/alert@5606
@heroui/autocomplete

npm i https://pkg.pr.new/@heroui/autocomplete@5606
@heroui/avatar

npm i https://pkg.pr.new/@heroui/avatar@5606
@heroui/badge

npm i https://pkg.pr.new/@heroui/badge@5606
@heroui/breadcrumbs

npm i https://pkg.pr.new/@heroui/breadcrumbs@5606
@heroui/button

npm i https://pkg.pr.new/@heroui/button@5606
@heroui/calendar

npm i https://pkg.pr.new/@heroui/calendar@5606
@heroui/card

npm i https://pkg.pr.new/@heroui/card@5606
@heroui/checkbox

npm i https://pkg.pr.new/@heroui/checkbox@5606
@heroui/chip

npm i https://pkg.pr.new/@heroui/chip@5606
@heroui/code

npm i https://pkg.pr.new/@heroui/code@5606
@heroui/date-input

npm i https://pkg.pr.new/@heroui/date-input@5606
@heroui/date-picker

npm i https://pkg.pr.new/@heroui/date-picker@5606
@heroui/divider

npm i https://pkg.pr.new/@heroui/divider@5606
@heroui/drawer

npm i https://pkg.pr.new/@heroui/drawer@5606
@heroui/dropdown

npm i https://pkg.pr.new/@heroui/dropdown@5606
@heroui/form

npm i https://pkg.pr.new/@heroui/form@5606
@heroui/image

npm i https://pkg.pr.new/@heroui/image@5606
@heroui/input

npm i https://pkg.pr.new/@heroui/input@5606
@heroui/input-otp

npm i https://pkg.pr.new/@heroui/input-otp@5606
@heroui/kbd

npm i https://pkg.pr.new/@heroui/kbd@5606
@heroui/link

npm i https://pkg.pr.new/@heroui/link@5606
@heroui/listbox

npm i https://pkg.pr.new/@heroui/listbox@5606
@heroui/menu

npm i https://pkg.pr.new/@heroui/menu@5606
@heroui/modal

npm i https://pkg.pr.new/@heroui/modal@5606
@heroui/navbar

npm i https://pkg.pr.new/@heroui/navbar@5606
@heroui/number-input

npm i https://pkg.pr.new/@heroui/number-input@5606
@heroui/pagination

npm i https://pkg.pr.new/@heroui/pagination@5606
@heroui/popover

npm i https://pkg.pr.new/@heroui/popover@5606
@heroui/progress

npm i https://pkg.pr.new/@heroui/progress@5606
@heroui/radio

npm i https://pkg.pr.new/@heroui/radio@5606
@heroui/ripple

npm i https://pkg.pr.new/@heroui/ripple@5606
@heroui/scroll-shadow

npm i https://pkg.pr.new/@heroui/scroll-shadow@5606
@heroui/select

npm i https://pkg.pr.new/@heroui/select@5606
@heroui/skeleton

npm i https://pkg.pr.new/@heroui/skeleton@5606
@heroui/slider

npm i https://pkg.pr.new/@heroui/slider@5606
@heroui/snippet

npm i https://pkg.pr.new/@heroui/snippet@5606
@heroui/spacer

npm i https://pkg.pr.new/@heroui/spacer@5606
@heroui/spinner

npm i https://pkg.pr.new/@heroui/spinner@5606
@heroui/switch

npm i https://pkg.pr.new/@heroui/switch@5606
@heroui/table

npm i https://pkg.pr.new/@heroui/table@5606
@heroui/tabs

npm i https://pkg.pr.new/@heroui/tabs@5606
@heroui/toast

npm i https://pkg.pr.new/@heroui/toast@5606
@heroui/tooltip

npm i https://pkg.pr.new/@heroui/tooltip@5606
@heroui/user

npm i https://pkg.pr.new/@heroui/user@5606
@heroui/react

npm i https://pkg.pr.new/@heroui/react@5606
@heroui/system

npm i https://pkg.pr.new/@heroui/system@5606
@heroui/system-rsc

npm i https://pkg.pr.new/@heroui/system-rsc@5606
@heroui/theme

npm i https://pkg.pr.new/@heroui/theme@5606
@heroui/use-aria-accordion

npm i https://pkg.pr.new/@heroui/use-aria-accordion@5606
@heroui/use-aria-accordion-item

npm i https://pkg.pr.new/@heroui/use-aria-accordion-item@5606
@heroui/use-aria-button

npm i https://pkg.pr.new/@heroui/use-aria-button@5606
@heroui/use-aria-link

npm i https://pkg.pr.new/@heroui/use-aria-link@5606
@heroui/use-aria-modal-overlay

npm i https://pkg.pr.new/@heroui/use-aria-modal-overlay@5606
@heroui/use-aria-multiselect

npm i https://pkg.pr.new/@heroui/use-aria-multiselect@5606
@heroui/use-aria-overlay

npm i https://pkg.pr.new/@heroui/use-aria-overlay@5606
@heroui/use-callback-ref

npm i https://pkg.pr.new/@heroui/use-callback-ref@5606
@heroui/use-clipboard

npm i https://pkg.pr.new/@heroui/use-clipboard@5606
@heroui/use-data-scroll-overflow

npm i https://pkg.pr.new/@heroui/use-data-scroll-overflow@5606
@heroui/use-disclosure

npm i https://pkg.pr.new/@heroui/use-disclosure@5606
@heroui/use-draggable

npm i https://pkg.pr.new/@heroui/use-draggable@5606
@heroui/use-form-reset

npm i https://pkg.pr.new/@heroui/use-form-reset@5606
@heroui/use-image

npm i https://pkg.pr.new/@heroui/use-image@5606
@heroui/use-infinite-scroll

npm i https://pkg.pr.new/@heroui/use-infinite-scroll@5606
@heroui/use-intersection-observer

npm i https://pkg.pr.new/@heroui/use-intersection-observer@5606
@heroui/use-is-mobile

npm i https://pkg.pr.new/@heroui/use-is-mobile@5606
@heroui/use-is-mounted

npm i https://pkg.pr.new/@heroui/use-is-mounted@5606
@heroui/use-measure

npm i https://pkg.pr.new/@heroui/use-measure@5606
@heroui/use-pagination

npm i https://pkg.pr.new/@heroui/use-pagination@5606
@heroui/use-real-shape

npm i https://pkg.pr.new/@heroui/use-real-shape@5606
@heroui/use-ref-state

npm i https://pkg.pr.new/@heroui/use-ref-state@5606
@heroui/use-resize

npm i https://pkg.pr.new/@heroui/use-resize@5606
@heroui/use-safe-layout-effect

npm i https://pkg.pr.new/@heroui/use-safe-layout-effect@5606
@heroui/use-scroll-position

npm i https://pkg.pr.new/@heroui/use-scroll-position@5606
@heroui/use-ssr

npm i https://pkg.pr.new/@heroui/use-ssr@5606
@heroui/use-theme

npm i https://pkg.pr.new/@heroui/use-theme@5606
@heroui/use-update-effect

npm i https://pkg.pr.new/@heroui/use-update-effect@5606
@heroui/use-viewport-size

npm i https://pkg.pr.new/@heroui/use-viewport-size@5606
@heroui/aria-utils

npm i https://pkg.pr.new/@heroui/aria-utils@5606
@heroui/dom-animation

npm i https://pkg.pr.new/@heroui/dom-animation@5606
@heroui/framer-utils

npm i https://pkg.pr.new/@heroui/framer-utils@5606
@heroui/react-rsc-utils

npm i https://pkg.pr.new/@heroui/react-rsc-utils@5606
@heroui/react-utils

npm i https://pkg.pr.new/@heroui/react-utils@5606
@heroui/shared-icons

npm i https://pkg.pr.new/@heroui/shared-icons@5606
@heroui/shared-utils

npm i https://pkg.pr.new/@heroui/shared-utils@5606
@heroui/stories-utils

npm i https://pkg.pr.new/@heroui/stories-utils@5606
@heroui/test-utils

npm i https://pkg.pr.new/@heroui/test-utils@5606

commit: c6ab38f

pkg-pr-new[bot] avatar Aug 17 '25 18:08 pkg-pr-new[bot]

@ChaserZ98 can you help resolve the conflicts?

wingkwong avatar Nov 23 '25 09:11 wingkwong

@wingkwong Can you take a look at my comment here? I have some problems understanding the new implementation. I doubt if I could resolve the conflict without an answer for them.

ChaserZ98 avatar Dec 04 '25 18:12 ChaserZ98

@wingkwong Can you take a look at my comment here? I have some problems understanding the new implementation. I doubt if I could resolve the conflict without an answer for them.

Sorry I missed. I replied in the comment. You may also ping me at discord (same userid ) for faster communication.

wingkwong avatar Dec 05 '25 03:12 wingkwong