83 lines
2.4 KiB
JavaScript
83 lines
2.4 KiB
JavaScript
/**
|
|
* Toast Notification System
|
|
* Provides temporary notifications for game events (quest acceptance, errors, etc.)
|
|
*
|
|
* Usage:
|
|
* showToast('Quest accepted!', 'success');
|
|
* showToast('Failed to save', 'error');
|
|
* showToast('Item added to inventory', 'info');
|
|
*/
|
|
|
|
/**
|
|
* Show a toast notification
|
|
* @param {string} message - The message to display
|
|
* @param {string} type - Type of toast: 'success', 'error', or 'info'
|
|
* @param {number} duration - Duration in ms before auto-dismiss (default: 4000)
|
|
*/
|
|
function showToast(message, type = 'info', duration = 4000) {
|
|
// Create toast container if it doesn't exist
|
|
let container = document.getElementById('toast-container');
|
|
if (!container) {
|
|
container = document.createElement('div');
|
|
container.id = 'toast-container';
|
|
container.className = 'toast-container';
|
|
document.body.appendChild(container);
|
|
}
|
|
|
|
// Create toast element
|
|
const toast = document.createElement('div');
|
|
toast.className = `toast toast--${type}`;
|
|
toast.innerHTML = `
|
|
<span class="toast-message">${escapeHtml(message)}</span>
|
|
<button class="toast-close" onclick="dismissToast(this.parentElement)" aria-label="Close">×</button>
|
|
`;
|
|
|
|
// Add to container
|
|
container.appendChild(toast);
|
|
|
|
// Trigger animation (small delay for DOM to register element)
|
|
requestAnimationFrame(() => {
|
|
toast.classList.add('toast--visible');
|
|
});
|
|
|
|
// Auto-remove after duration
|
|
setTimeout(() => {
|
|
dismissToast(toast);
|
|
}, duration);
|
|
}
|
|
|
|
/**
|
|
* Dismiss a toast notification with animation
|
|
* @param {HTMLElement} toast - The toast element to dismiss
|
|
*/
|
|
function dismissToast(toast) {
|
|
if (!toast || toast.classList.contains('toast--dismissing')) {
|
|
return;
|
|
}
|
|
|
|
toast.classList.add('toast--dismissing');
|
|
toast.classList.remove('toast--visible');
|
|
|
|
// Remove from DOM after animation completes
|
|
setTimeout(() => {
|
|
if (toast.parentElement) {
|
|
toast.remove();
|
|
}
|
|
}, 300);
|
|
}
|
|
|
|
/**
|
|
* Escape HTML to prevent XSS
|
|
* @param {string} text - Text to escape
|
|
* @returns {string} Escaped text
|
|
*/
|
|
function escapeHtml(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
// Make functions globally available
|
|
window.showToast = showToast;
|
|
window.dismissToast = dismissToast;
|