/** * Toast service global. Sin dependencias. * Inyecta un container en y empuja toasts apilados. * * Uso: * import { toast } from "./toast.js"; * toast({ kind: "error", text: "No se pudo guardar" }); * toast({ kind: "ok", text: "Listo", ms: 2000 }); */ const KIND_COLORS = { error: { bg: "#241214", border: "#e74c3c", text: "#ffe9ea" }, ok: { bg: "#0f2a1a", border: "#1f6f43", text: "#cdebd8" }, warn: { bg: "#2a1f0a", border: "#F59E0B", text: "#ffe6b0" }, info: { bg: "#0f2030", border: "#1f6feb", text: "#cce0ff" }, }; let _container = null; function ensureContainer() { if (_container) return _container; _container = document.createElement("div"); _container.id = "toast-stack"; Object.assign(_container.style, { position: "fixed", right: "16px", bottom: "16px", display: "flex", flexDirection: "column", gap: "8px", zIndex: "9999", pointerEvents: "none", maxWidth: "420px", }); document.body.appendChild(_container); return _container; } export function toast({ kind = "error", text = "", ms = 4000 } = {}) { if (!text) return; const colors = KIND_COLORS[kind] || KIND_COLORS.info; const el = document.createElement("div"); Object.assign(el.style, { background: colors.bg, border: `1px solid ${colors.border}`, color: colors.text, padding: "10px 12px", borderRadius: "10px", fontSize: "13px", boxShadow: "0 4px 12px rgba(0,0,0,.4)", pointerEvents: "auto", cursor: "pointer", transform: "translateX(120%)", transition: "transform .25s ease, opacity .25s ease", opacity: "0", wordBreak: "break-word", overflowWrap: "anywhere", }); el.textContent = String(text); const c = ensureContainer(); c.appendChild(el); // Animar entrada requestAnimationFrame(() => { el.style.transform = "translateX(0)"; el.style.opacity = "1"; }); const dismiss = () => { el.style.transform = "translateX(120%)"; el.style.opacity = "0"; setTimeout(() => el.remove(), 280); }; el.addEventListener("click", dismiss); setTimeout(dismiss, Math.max(800, ms)); } export function toastError(text) { toast({ kind: "error", text }); } export function toastOk(text) { toast({ kind: "ok", text, ms: 2500 }); } export function toastWarn(text) { toast({ kind: "warn", text }); }