43 lines
1.3 KiB
JavaScript
43 lines
1.3 KiB
JavaScript
// Toast notification system — shared across all pages.
|
|
// Usage: showToast('message', 'error' | 'info' | 'success');
|
|
// Auto-dismisses after 4 seconds. Multiple toasts stack vertically.
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
const TOAST_DURATION = 4000;
|
|
const MAX_VISIBLE = 3;
|
|
const STACK_GAP = 8; // px between stacked toasts
|
|
|
|
/**
|
|
* Show a toast notification.
|
|
* @param {string} message - Toast text content.
|
|
* @param {'error'|'info'|'success'} [type='info'] - Visual style.
|
|
*/
|
|
window.showToast = function showToast(message, type) {
|
|
if (typeof message !== 'string') return;
|
|
type = type || 'info';
|
|
|
|
// Remove old toasts of the same type to avoid clutter
|
|
document.querySelectorAll('.toast-' + type).forEach(function (t) {
|
|
t.remove();
|
|
});
|
|
|
|
var toast = document.createElement('div');
|
|
toast.className = 'toast toast-' + type;
|
|
toast.setAttribute('role', 'alert');
|
|
toast.textContent = message;
|
|
|
|
// Position: stack from bottom
|
|
var existing = document.querySelectorAll('.toast');
|
|
var offset = existing.length * STACK_GAP;
|
|
toast.style.bottom = (1.5 + offset / 16) + 'rem';
|
|
|
|
document.body.appendChild(toast);
|
|
|
|
setTimeout(function () {
|
|
if (toast.parentNode) toast.remove();
|
|
}, TOAST_DURATION);
|
|
};
|
|
})();
|