Component
Stacked Toasts
Notification queue that stacks incoming toasts vertically. New toasts push older ones up with a staggered slide-in, and each clears itself on its own 5-second timer. Includes a dismiss-all control.
- Component
- Tailwind
- HTML
- MIT
Preview
Live component
9:41 100%
devsnips.dev/library/tailwind/components/toasts/stacked-toasts/ fluid · no fixed width 100%
Install
Add to your project
npx devsnips add Tailwind/Components/Toasts/stacked-toasts Tailwind/Components/Toasts/stacked-toasts <!--
Snippet Name: Stacked Toasts
Description: Notification queue that stacks incoming toasts with a staggered slide-in. New toasts push older ones up; each auto-dismisses on its own timer.
Author: DevSnips Contributors
Usage Example: Call showToast(title, body) repeatedly — they queue vertically and clear themselves.
-->
<div
id="stacked-toast-region"
class="pointer-events-none fixed bottom-4 right-4 z-50 flex w-full max-w-sm flex-col items-end gap-3"
role="region"
aria-label="Notifications"
aria-live="polite"
data-toast-region
></div>
<!-- Demo trigger buttons -->
<div class="flex flex-wrap gap-2">
<button onclick="pushRandom()" class="rounded-lg bg-blue-600 px-4 py-2 text-sm font-medium text-white hover:bg-blue-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2">Push toast</button>
<button onclick="dismissAll()" class="rounded-lg border border-gray-200 px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400 focus-visible:ring-offset-2">Dismiss all</button>
</div>
<script>
(function () {
const root = document.currentScript.closest('[data-toast-region]');
if (!root) return;
function dismiss(toast) {
if (!toast || toast.dataset.dismissed === 'true') return;
toast.dataset.dismissed = 'true';
toast.classList.add('translate-x-2', 'opacity-0');
toast.addEventListener('transitionend', () => toast.remove(), { once: true });
setTimeout(() => toast.remove(), 400);
}
function dismissAll() {
root.querySelectorAll('.toast-item:not([data-dismissed="true"])').forEach(dismiss);
}
function showToast(title, body) {
const toast = document.createElement('div');
toast.className = 'toast-item pointer-events-auto flex w-full items-start gap-3 rounded-xl border border-gray-200 bg-white p-4 shadow-lg ring-1 ring-black/5 transition duration-300 ease-out';
toast.setAttribute('role', 'status');
toast.innerHTML = `
<span class="flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-blue-100 text-blue-600">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9"/></svg>
</span>
<div class="min-w-0 flex-1">
<p class="text-sm font-semibold text-gray-900">${title}</p>
<p class="mt-0.5 text-sm text-gray-500">${body}</p>
</div>
<button type="button" class="toast-close shrink-0 rounded-md p-1 text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-400" aria-label="Dismiss notification">
<svg class="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/></svg>
</button>`;
root.appendChild(toast);
const timer = setTimeout(() => dismiss(toast), 5000);
toast.querySelector('.toast-close').addEventListener('click', () => { clearTimeout(timer); dismiss(toast); });
toast.addEventListener('mouseenter', () => clearTimeout(timer));
}
window.showToast = showToast;
window.dismissAll = dismissAll;
// Demo helper: push a randomized notification
const samples = [
['New comment', 'Alex replied to your snippet.'],
['Deploy succeeded', 'Production build finished.'],
['Invite accepted', 'Sam joined the workspace.'],
['Export ready', 'Your CSV is available to download.'],
['Sync complete', '3 files updated from GitHub.'],
];
let i = 0;
window.pushRandom = function () {
const s = samples[i % samples.length];
i++;
showToast(s[0], s[1]);
};
})();
</script> # Stacked Toasts
Stacked toast container layout.
## Usage
```bash
npx devsnips add Tailwind/Components/Toasts/stacked-toasts
```
Copy from `code.html`.
## File Structure
`code.html` · `preview.html` · `metadata.json` · `README.md` 79 lines UTF-8 · LF · Spaces: 2
Continue browsing