Toast Notifications

Auto-dismissing alerts with severity levels, portaled above all content.

Live Demo

Source

HTML + JavaScript
<div data-component="toasts">
    <button data-action="showSuccess">Success</button>
    <button data-action="showError">Error</button>

    <!-- data-portal="body" ensures toasts render above all stacking contexts -->
    <div data-portal="body">
        <div class="toast-container" data-list="toasts">
            <template>
                <div data-bind-class="'toast-item toast-' + type">
                    <span data-bind="message"></span>
                    <button data-action="dismissToast">&times;</button>
                </div>
            </template>
        </div>
    </div>
</div>

<script>
wildflower.component('toasts', {
    state: { toasts: [] },
    _addToast(message, type) {
        const id = Date.now() + Math.random();
        this.toasts.push({ id, message, type });
        setTimeout(() => {
            this.toasts = this.toasts.filter(t => t.id !== id);
        }, 3000);
    },
    showSuccess() { this._addToast('Operation completed.', 'success'); },
    showError() { this._addToast('Something went wrong.', 'error'); },
    dismissToast(e, el, { index }) { this.toasts.splice(index, 1); }
});
</script>

Key Points

  • data-portal="body" renders the toast container above all stacking contexts. No z-index wars
  • data-list="toasts" renders multiple simultaneous toasts from an array
  • data-bind-class="'toast-item toast-' + type" builds a dynamic class string from item data
  • Auto-dismiss via setTimeout removes items with filter; WF's reactive proxy handles the array mutation
  • Manual dismiss uses splice with the { index } from the action parameter