Component
Action Toast
Toast with an inline action button (Undo). Fires an onAction callback when the action button is clicked, otherwise auto-dismisses after 6 seconds. Ideal for reversible destructive actions like delete.
- Component
- Tailwind
- HTML
- MIT
What it does
Capabilities
- Inline action button
- OnAction callback
- 6s auto-dismiss
- Pause on hover
- Close button
- Role status
- Aria-live polite
Preview
Live component
9:41 100%
devsnips.site/library/tailwind/components/toasts/action-toast/ fluid · no fixed width 100%
Install
Add to your project
npx devsnips add Tailwind/Components/Toasts/action-toast Tailwind/Components/Toasts/action-toast <!--
Snippet Name: Action Toast
Description: Toast with an inline action button (Undo). Fires a callback on action, or auto-dismisses if ignored.
Author: DevSnips Contributors
Usage Example: Call showToast({ action: 'Undo', onAction: () => revert() }) after destructive actions.
-->
<div
id="action-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="showToast()" class="inline-flex items-center gap-2 rounded-xl bg-gray-900 px-5 py-2.5 text-sm font-semibold text-white hover:bg-gray-800 focus:outline-none focus-visible:ring-2 focus-visible:ring-gray-500 focus-visible:ring-offset-2">
<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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6M1 7h22M9 7V4a1 1 0 011-1h4a1 1 0 011 1v3"/></svg>
Delete item
</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 showToast(opts) {
opts = opts || {};
const actionLabel = opts.action || 'Undo';
const onAction = typeof opts.onAction === 'function' ? opts.onAction : function () {};
const duration = opts.duration || 6000;
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-gray-900 text-white">
<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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6M1 7h22M9 7V4a1 1 0 011-1h4a1 1 0 011 1v3"/></svg>
</span>
<div class="min-w-0 flex-1">
<p class="text-sm font-semibold text-gray-900">1 item deleted</p>
<p class="mt-0.5 text-sm text-gray-500">Removed from your workspace.</p>
</div>
<div class="flex shrink-0 items-center gap-2">
<button type="button" class="toast-action rounded-md px-2.5 py-1 text-sm font-semibold text-blue-600 transition-colors hover:bg-blue-50 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500">${actionLabel}</button>
<button type="button" class="toast-close 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>
</div>`;
root.appendChild(toast);
function close() { clearTimeout(timer); dismiss(toast); }
const timer = setTimeout(() => dismiss(toast), duration);
toast.querySelector('.toast-close').addEventListener('click', close);
toast.querySelector('.toast-action').addEventListener('click', () => { onAction(); close(); });
toast.addEventListener('mouseenter', () => clearTimeout(timer));
}
window.showToast = showToast;
})();
</script> # Action Toast
Toast with an action button.
## Usage
```bash
npx devsnips add Tailwind/Components/Toasts/action-toast
```
Copy from `code.html`. Use appropriate live region roles when dynamic.
## File Structure
`code.html` · `preview.html` · `metadata.json` · `README.md` 73 lines UTF-8 · LF · Spaces: 2
DevSnips AI ready Claude · Cursor · Windsurf
Agent skill & Model Context Protocol
Pass this component straight into your AI workflow. DevSnips exposes each resource as a structured, addressable registry entry, so your agent installs the real files instead of approximating them.
devsnips://components/toasts/action-toast I want to use this DevSnips resource in production: Page: https://devsnips.site/library/tailwind/components/toasts/action-toast/ Install: npx devsnips add Tailwind/Components/Toasts/action-toast This is the Action Toast — Toast with an inline action button (Undo). Fires an onAction callback when the action button is clicked, otherwise auto-dismisses after 6 seconds. Ideal for reversible destructive actions like delete. Use this DevSnips resource as the starting point for my project. Adapt it to my project's stack and conventions, fix any issues, and make it production-ready while preserving its intended design and behavior.
Paste into ChatGPT, Claude or your agent — it already carries the page URL and the exact install path.
Resource URI
devsnips://components/toasts/action-toast