/**
* PyRunner Toast Notification System
*/
const PyRunnerToast = {
container: null,
defaults: {
duration: 5000,
maxToasts: 5
},
init() {
if (!this.container) {
this.container = document.createElement('div');
this.container.id = 'toast-container';
this.container.className = 'fixed flex flex-col gap-3 pointer-events-none';
this.container.style.cssText = 'top: 5rem; right: 1rem; z-index: 9999;';
document.body.appendChild(this.container);
}
},
show(message, type = 'info', duration = this.defaults.duration) {
this.init();
const toast = document.createElement('div');
toast.className = this.getToastClasses(type);
toast.innerHTML = this.getToastHTML(message, type);
toast.style.animation = 'toastSlideIn 0.3s ease-out';
const closeBtn = toast.querySelector('[data-toast-close]');
if (closeBtn) {
closeBtn.addEventListener('click', () => this.dismiss(toast));
}
while (this.container.children.length >= this.defaults.maxToasts) {
this.dismiss(this.container.firstChild);
}
this.container.appendChild(toast);
if (duration > 0) {
setTimeout(() => this.dismiss(toast), duration);
}
return toast;
},
dismiss(toast) {
if (!toast || !toast.parentNode) return;
toast.style.animation = 'toastSlideOut 0.2s ease-in forwards';
setTimeout(() => toast.remove(), 200);
},
getToastClasses(type) {
const base = 'pointer-events-auto max-w-sm w-full p-4 rounded-lg border shadow-lg flex items-start gap-3';
const types = {
success: 'bg-code-surface border-code-green/30 text-code-green',
error: 'bg-code-surface border-code-red/30 text-code-red',
warning: 'bg-code-surface border-code-yellow/30 text-code-yellow',
info: 'bg-code-surface border-code-accent/30 text-code-accent'
};
return `${base} ${types[type] || types.info}`;
},
getToastHTML(message, type) {
const icons = {
success: '
${message}
`; }, success(message, duration) { return this.show(message, 'success', duration); }, error(message, duration) { return this.show(message, 'error', duration); }, warning(message, duration) { return this.show(message, 'warning', duration); }, info(message, duration) { return this.show(message, 'info', duration); } }; window.Toast = PyRunnerToast;