Skip to content

feat[toasts]: instead of queueing, remove oldest toasts#2899

Merged
peterchinman merged 1 commit into
mainfrom
peter/dismiss-older-toasts
Apr 27, 2026
Merged

feat[toasts]: instead of queueing, remove oldest toasts#2899
peterchinman merged 1 commit into
mainfrom
peter/dismiss-older-toasts

Conversation

@peterchinman
Copy link
Copy Markdown
Contributor

No description provided.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 27, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Toast notifications now limit non-persistent messages to a maximum of 3 simultaneous displays. When the limit is reached, the oldest notification automatically dismisses, allowing new notifications to appear immediately without manual intervention or queue cleanup.

Walkthrough

The Toast component now enforces a maximum of 3 visible non-persistent toasts by maintaining an activeToastIds list. When the limit is exceeded, the oldest toast is automatically evicted. The ToastContent component gains an onDismiss callback that executes on unmount to keep the tracking list synchronized with DOM lifecycle.

Changes

Cohort / File(s) Summary
Toast Component Updates
js/app/packages/core/component/Toast/Toast.tsx
Implements 3-toast visibility limit with automatic eviction of oldest toast when exceeded. Adds onDismiss callback to ToastContent that fires on unmount via onCleanup to maintain activeToastIds consistency. Updates solid-js imports.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive No pull request description was provided, which makes it impossible to verify if the description relates to the changeset. Add a description explaining the purpose, motivation, and impact of the toast eviction behavior change to help reviewers understand the rationale.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title follows the conventional commits format with 'feat' prefix and descriptive message about changing toast behavior from queueing to removing oldest toasts, staying well under 72 characters.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
js/app/packages/core/component/Toast/Toast.tsx (1)

502-530: ⚠️ Potential issue | 🟠 Major

Cap enforcement is bypassed for other non-persistent toast-region APIs.

Line 502–Line 530 applies eviction/tracking only inside createToast, but embed (Line 560) and custom (Line 588) can still create non-persistent toasts in toast-region without this path. That means queueing can still happen, so the “remove oldest instead of queueing” behavior is not consistently enforced.

Proposed consolidation (single tracked show path)
+function showToastInRegion(
+  render: Parameters<typeof toaster.show>[0],
+  options?: { region?: string; persistent?: boolean; onDismiss?: (id: number) => void }
+) {
+  const region = options?.region ?? 'toast-region';
+  const shouldTrack = region === 'toast-region' && !options?.persistent;
+
+  if (shouldTrack && activeToastIds.length >= MAX_VISIBLE_TOASTS) {
+    const oldestId = activeToastIds.shift();
+    if (oldestId !== undefined) toaster.dismiss(oldestId);
+  }
+
+  const toastId = toaster.show(render, { region });
+  if (shouldTrack) activeToastIds.push(toastId);
+  return toastId;
+}

Then route createToast, embed, and custom through this helper (with persistent/region passed through) so cap behavior is consistent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@js/app/packages/core/component/Toast/Toast.tsx` around lines 502 - 530, The
eviction/tracking logic (activeToastIds, MAX_VISIBLE_TOASTS, toaster.show) is
only used in createToast so embed and custom can still create non-persistent
toasts in 'toast-region' and bypass the cap; refactor by extracting a single
helper (e.g., showTrackedToast or showToastWithCap) that accepts the toast
payload plus region and persistent flags, performs the oldest-id eviction when
region === 'toast-region' and persistent is false, calls toaster.show with the
provided renderer/opts, pushes the returned toastId into activeToastIds, and
wires the onDismiss removal; then replace direct calls in createToast, embed,
and custom to use this helper so cap behavior is consistently enforced across
all APIs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@js/app/packages/core/component/Toast/Toast.tsx`:
- Around line 502-530: The eviction/tracking logic (activeToastIds,
MAX_VISIBLE_TOASTS, toaster.show) is only used in createToast so embed and
custom can still create non-persistent toasts in 'toast-region' and bypass the
cap; refactor by extracting a single helper (e.g., showTrackedToast or
showToastWithCap) that accepts the toast payload plus region and persistent
flags, performs the oldest-id eviction when region === 'toast-region' and
persistent is false, calls toaster.show with the provided renderer/opts, pushes
the returned toastId into activeToastIds, and wires the onDismiss removal; then
replace direct calls in createToast, embed, and custom to use this helper so cap
behavior is consistently enforced across all APIs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: a656fadd-5a3f-45b6-a1e5-f4d579ce703e

📥 Commits

Reviewing files that changed from the base of the PR and between e9a9032 and d854c44.

📒 Files selected for processing (1)
  • js/app/packages/core/component/Toast/Toast.tsx

@github-actions
Copy link
Copy Markdown

@peterchinman peterchinman merged commit 62f857b into main Apr 27, 2026
28 of 33 checks passed
@peterchinman peterchinman deleted the peter/dismiss-older-toasts branch April 27, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant