fernotify 1.2.8 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -212,6 +212,35 @@ notify.loading('Cargando...', 'Espera', {
212
212
  });
213
213
  ```
214
214
 
215
+ ### Toast — Notificaciones no bloqueantes 🍞
216
+
217
+ Los toasts aparecen en la esquina de la pantalla **sin interrumpir al usuario**, se apilan automáticamente y se cierran solos (o con el botón ×).
218
+
219
+ ```javascript
220
+ // Métodos abreviados (mismo patrón que los modales)
221
+ notify.toastSuccess('Cambios guardados.', 'Título opcional');
222
+ notify.toastError('Error al procesar.', 'Error');
223
+ notify.toastWarning('Revisa los datos.');
224
+ notify.toastInfo('Nueva versión disponible.');
225
+ notify.toastQuestion('Nueva solicitud pendiente.');
226
+
227
+ // Método genérico con opciones completas
228
+ notify.toast('Mensaje aquí', {
229
+ type: 'success', // 'success' | 'error' | 'warning' | 'info' | 'question'
230
+ title: 'Título opcional',
231
+ duration: 4000, // ms hasta auto-cierre (0 = sin auto-cierre, default: 4000)
232
+ position: 'top-right' // 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left'
233
+ });
234
+ ```
235
+
236
+ **Características:**
237
+ - Sin overlay — no bloquea la UI
238
+ - Apilables: se acumulan uno bajo otro
239
+ - Progress bar que indica el tiempo restante
240
+ - Botón × para cierre manual
241
+ - Animación de entrada/salida suave
242
+ - Soporte completo de dark mode
243
+
215
244
  ### Personalización de Animaciones
216
245
 
217
246
  ```javascript
@@ -14,6 +14,17 @@
14
14
 
15
15
  // Importar el código UMD y ejecutarlo para generar window.notify
16
16
  "use strict";
17
+ var __rest = (this && this.__rest) || function (s, e) {
18
+ var t = {};
19
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
20
+ t[p] = s[p];
21
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
22
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
23
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
24
+ t[p[i]] = s[p[i]];
25
+ }
26
+ return t;
27
+ };
17
28
  (function ensureAnimeDependency() {
18
29
  if (typeof anime !== 'undefined') {
19
30
  initFerNotify();
@@ -33,6 +44,7 @@
33
44
  this.currentNotification = null;
34
45
  this._lastActiveElement = null;
35
46
  this._currentLoadingPromise = null;
47
+ this._toastContainers = new Map();
36
48
  this.injectStyles();
37
49
  this.loadBoxicons();
38
50
  }
@@ -339,6 +351,117 @@
339
351
  .dark .notification-loading-text {
340
352
  color: #cbd5e1;
341
353
  }
354
+
355
+ /* ==================== Toast ==================== */
356
+ .notify-toast-container {
357
+ position: fixed;
358
+ z-index: 10000;
359
+ display: flex;
360
+ flex-direction: column;
361
+ gap: 10px;
362
+ pointer-events: none;
363
+ width: 360px;
364
+ max-width: calc(100vw - 40px);
365
+ }
366
+ .notify-toast-top-right { top: 20px; right: 20px; }
367
+ .notify-toast-top-left { top: 20px; left: 20px; }
368
+ .notify-toast-top-center { top: 20px; left: 50%; transform: translateX(-50%); }
369
+ .notify-toast-bottom-right { bottom: 20px; right: 20px; flex-direction: column-reverse; }
370
+ .notify-toast-bottom-left { bottom: 20px; left: 20px; flex-direction: column-reverse; }
371
+
372
+ .notify-toast {
373
+ background: white;
374
+ border-radius: 12px;
375
+ padding: 14px 40px 14px 14px;
376
+ box-shadow: 0 4px 24px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.06);
377
+ display: flex;
378
+ align-items: flex-start;
379
+ gap: 12px;
380
+ pointer-events: auto;
381
+ position: relative;
382
+ overflow: hidden;
383
+ opacity: 0;
384
+ transform: translateX(30px);
385
+ transition: opacity 0.25s ease, transform 0.25s ease;
386
+ }
387
+ .notify-toast-top-left .notify-toast,
388
+ .notify-toast-bottom-left .notify-toast { transform: translateX(-30px); }
389
+ .notify-toast-top-center .notify-toast { transform: translateY(-20px); }
390
+ .notify-toast.notify-toast-visible {
391
+ opacity: 1;
392
+ transform: translateX(0) translateY(0) !important;
393
+ }
394
+
395
+ .notify-toast-icon {
396
+ width: 36px;
397
+ height: 36px;
398
+ border-radius: 50%;
399
+ display: flex;
400
+ align-items: center;
401
+ justify-content: center;
402
+ font-size: 20px;
403
+ flex-shrink: 0;
404
+ color: white;
405
+ }
406
+ .notify-toast-icon.success { background: linear-gradient(135deg, #10b981 0%, #059669 100%); }
407
+ .notify-toast-icon.error { background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); }
408
+ .notify-toast-icon.warning { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); }
409
+ .notify-toast-icon.info { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); }
410
+ .notify-toast-icon.question { background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%); }
411
+
412
+ .notify-toast-content { flex: 1; min-width: 0; }
413
+ .notify-toast-title {
414
+ font-size: 14px;
415
+ font-weight: 700;
416
+ color: #1f2937;
417
+ margin-bottom: 2px;
418
+ line-height: 1.3;
419
+ }
420
+ .notify-toast-message {
421
+ font-size: 13px;
422
+ color: #6b7280;
423
+ line-height: 1.5;
424
+ }
425
+
426
+ .notify-toast-close {
427
+ position: absolute;
428
+ top: 8px;
429
+ right: 8px;
430
+ width: 24px;
431
+ height: 24px;
432
+ border-radius: 6px;
433
+ border: none;
434
+ background: rgba(0,0,0,0.06);
435
+ color: #6b7280;
436
+ cursor: pointer;
437
+ font-size: 16px;
438
+ display: flex;
439
+ align-items: center;
440
+ justify-content: center;
441
+ line-height: 1;
442
+ padding: 0;
443
+ }
444
+ .notify-toast-close:hover { background: rgba(0,0,0,0.1); color: #374151; }
445
+
446
+ .notify-toast-progress {
447
+ position: absolute;
448
+ bottom: 0;
449
+ left: 0;
450
+ height: 3px;
451
+ width: 100%;
452
+ border-radius: 0 0 0 12px;
453
+ }
454
+ .notify-toast-progress.success { background: #10b981; }
455
+ .notify-toast-progress.error { background: #ef4444; }
456
+ .notify-toast-progress.warning { background: #f59e0b; }
457
+ .notify-toast-progress.info { background: #3b82f6; }
458
+ .notify-toast-progress.question { background: #8b5cf6; }
459
+
460
+ .dark .notify-toast { background: #0f1724; box-shadow: 0 4px 24px rgba(0,0,0,0.35); }
461
+ .dark .notify-toast-title { color: #e6eef8; }
462
+ .dark .notify-toast-message { color: #cbd5e1; }
463
+ .dark .notify-toast-close { background: rgba(255,255,255,0.06); color: #94a3b8; }
464
+ .dark .notify-toast-close:hover { background: rgba(255,255,255,0.1); color: #e2e8f0; }
342
465
  `;
343
466
  document.head.appendChild(style);
344
467
  }
@@ -845,6 +968,136 @@
845
968
  const ss = (s % 60).toString().padStart(2, '0');
846
969
  return `${mm}:${ss}`;
847
970
  }
971
+ showToast(message, options = {}) {
972
+ var _a;
973
+ const type = options.type || 'info';
974
+ const title = (_a = options.title) !== null && _a !== void 0 ? _a : null;
975
+ const duration = typeof options.duration === 'number' ? options.duration : 4000;
976
+ const position = options.position || 'top-right';
977
+ const showProgress = options.showProgress !== false;
978
+ let container = this._toastContainers.get(position);
979
+ if (!container || !document.body.contains(container)) {
980
+ container = document.createElement('div');
981
+ container.className = `notify-toast-container notify-toast-${position}`;
982
+ document.body.appendChild(container);
983
+ this._toastContainers.set(position, container);
984
+ }
985
+ const isBottom = position.startsWith('bottom');
986
+ const isCenter = position === 'top-center';
987
+ const toast = document.createElement('div');
988
+ toast.className = 'notify-toast';
989
+ const iconEl = document.createElement('div');
990
+ iconEl.className = `notify-toast-icon ${type}`;
991
+ iconEl.innerHTML = this.getIcon(type);
992
+ const contentEl = document.createElement('div');
993
+ contentEl.className = 'notify-toast-content';
994
+ if (title) {
995
+ const titleEl = document.createElement('div');
996
+ titleEl.className = 'notify-toast-title';
997
+ titleEl.textContent = title;
998
+ contentEl.appendChild(titleEl);
999
+ }
1000
+ const msgEl = document.createElement('div');
1001
+ msgEl.className = 'notify-toast-message';
1002
+ msgEl.textContent = message;
1003
+ contentEl.appendChild(msgEl);
1004
+ const closeBtn = document.createElement('button');
1005
+ closeBtn.className = 'notify-toast-close';
1006
+ closeBtn.setAttribute('aria-label', 'Cerrar notificación');
1007
+ closeBtn.innerHTML = '&times;';
1008
+ toast.appendChild(iconEl);
1009
+ toast.appendChild(contentEl);
1010
+ toast.appendChild(closeBtn);
1011
+ let progressEl = null;
1012
+ if (duration > 0 && showProgress) {
1013
+ progressEl = document.createElement('div');
1014
+ progressEl.className = `notify-toast-progress ${type}`;
1015
+ toast.appendChild(progressEl);
1016
+ }
1017
+ if (isBottom || isCenter) {
1018
+ container.appendChild(toast);
1019
+ }
1020
+ else {
1021
+ container.insertBefore(toast, container.firstChild);
1022
+ }
1023
+ let dismissed = false;
1024
+ let timerId = null;
1025
+ let remaining = duration;
1026
+ let timerStartedAt = 0;
1027
+ const removeToast = () => {
1028
+ if (dismissed)
1029
+ return;
1030
+ dismissed = true;
1031
+ toast.classList.remove('notify-toast-visible');
1032
+ setTimeout(() => {
1033
+ if (toast.parentNode)
1034
+ toast.parentNode.removeChild(toast);
1035
+ }, 300);
1036
+ };
1037
+ const startCountdown = (ms) => {
1038
+ timerStartedAt = Date.now();
1039
+ timerId = setTimeout(removeToast, ms);
1040
+ if (progressEl) {
1041
+ progressEl.style.transition = `width ${ms}ms linear`;
1042
+ progressEl.style.width = '0%';
1043
+ }
1044
+ };
1045
+ const pauseCountdown = () => {
1046
+ if (dismissed || timerId === null)
1047
+ return;
1048
+ clearTimeout(timerId);
1049
+ timerId = null;
1050
+ const elapsed = Date.now() - timerStartedAt;
1051
+ remaining = Math.max(0, remaining - elapsed);
1052
+ if (progressEl) {
1053
+ const pct = (remaining / duration) * 100;
1054
+ progressEl.style.transition = 'none';
1055
+ progressEl.style.width = `${pct}%`;
1056
+ }
1057
+ };
1058
+ const resumeCountdown = () => {
1059
+ if (dismissed || remaining <= 0)
1060
+ return;
1061
+ startCountdown(remaining);
1062
+ };
1063
+ closeBtn.addEventListener('click', removeToast);
1064
+ requestAnimationFrame(() => {
1065
+ requestAnimationFrame(() => {
1066
+ toast.classList.add('notify-toast-visible');
1067
+ if (duration > 0) {
1068
+ startCountdown(duration);
1069
+ }
1070
+ });
1071
+ });
1072
+ if (duration > 0) {
1073
+ toast.addEventListener('mouseenter', pauseCountdown);
1074
+ toast.addEventListener('mouseleave', resumeCountdown);
1075
+ }
1076
+ }
1077
+ toast(messageOrOptions, options = {}) {
1078
+ if (typeof messageOrOptions === 'string') {
1079
+ this.showToast(messageOrOptions, options);
1080
+ }
1081
+ else {
1082
+ const { message = '' } = messageOrOptions, rest = __rest(messageOrOptions, ["message"]);
1083
+ this.showToast(message, rest);
1084
+ }
1085
+ }
1086
+ toastSuccess(message, title, options = {}) {
1087
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'success', title: title !== null && title !== void 0 ? title : options.title }));
1088
+ }
1089
+ toastError(message, title, options = {}) {
1090
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'error', title: title !== null && title !== void 0 ? title : options.title }));
1091
+ }
1092
+ toastWarning(message, title, options = {}) {
1093
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'warning', title: title !== null && title !== void 0 ? title : options.title }));
1094
+ }
1095
+ toastInfo(message, title, options = {}) {
1096
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'info', title: title !== null && title !== void 0 ? title : options.title }));
1097
+ }
1098
+ toastQuestion(message, title, options = {}) {
1099
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'question', title: title !== null && title !== void 0 ? title : options.title }));
1100
+ }
848
1101
  }
849
1102
  const notifyInstance = new NotificationSystem();
850
1103
  const w = window;
@@ -1 +1 @@
1
- "use strict";!function(){if("undefined"!=typeof anime)n();else{const t=document.createElement("script");t.src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js",t.onload=n,t.onerror=()=>{console.error("FerNotify: No se pudo cargar anime.js. Por favor, cargalo manualmente.")},document.head.appendChild(t)}function n(){const n=new class{constructor(){this.currentNotification=null,this._lastActiveElement=null,this._currentLoadingPromise=null,this.injectStyles(),this.loadBoxicons()}loadBoxicons(){if(!document.querySelector('link[href*="boxicons"]')){const n=document.createElement("link");n.rel="stylesheet",n.href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css",document.head.appendChild(n)}}injectStyles(){const n=document.createElement("style");n.textContent="\n .notification-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n opacity: 0;\n overflow: hidden;\n }\n\n .notification-box {\n background: white;\n border-radius: 16px;\n padding: 40px 30px;\n max-width: 500px;\n width: 90%;\n max-height: 80vh;\n overflow: auto;\n position: relative;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n transform: scale(0.7);\n opacity: 0;\n }\n\n .notification-content {\n text-align: left;\n margin-bottom: 18px;\n }\n\n .notification-close {\n position: absolute;\n top: 10px;\n right: 10px;\n width: 38px;\n height: 38px;\n border-radius: 8px;\n border: none;\n background: rgba(0,0,0,0.06);\n color: #111827;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 18px;\n }\n\n .notification-close:hover {\n background: rgba(0,0,0,0.09);\n }\n\n /* Form controls inside the modal */\n .notification-box input,\n .notification-box textarea,\n .notification-box select {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: #ffffff;\n color: #111827;\n font-size: 15px;\n box-sizing: border-box;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n }\n\n .notification-box input:focus,\n .notification-box textarea:focus,\n .notification-box select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 6px 24px rgba(99,102,241,0.12), 0 0 0 4px rgba(99,102,241,0.06);\n }\n\n .notification-box label { display: block; margin-bottom: 6px; color: #374151; font-weight: 600; }\n\n /* Soporte para tema oscuro con clase .dark (Tailwind darkMode: 'class') */\n /* Esto tiene prioridad sobre prefers-color-scheme para respetar la elección del usuario en la web */\n .dark .notification-box { background: #0f1724 !important; color: #e6eef8 !important; }\n .dark .notification-box input,\n .dark .notification-box textarea,\n .dark .notification-box select {\n background: #0b1220 !important;\n border: 1px solid rgba(255,255,255,0.06) !important;\n color: #e6eef8 !important;\n }\n .dark .notification-box .notification-close { background: rgba(255,255,255,0.03) !important; color: #e6eef8 !important; }\n .dark .notification-overlay { background-color: rgba(0,0,0,0.6) !important; }\n .dark .notification-title { color: #e6eef8 !important; }\n .dark .notification-message { color: #cbd5e1 !important; }\n\n /* Forzar modo claro cuando NO hay clase .dark, ignorando prefers-color-scheme */\n html:not(.dark) .notification-box { background: white !important; color: #111827 !important; }\n html:not(.dark) .notification-box input,\n html:not(.dark) .notification-box textarea,\n html:not(.dark) .notification-box select {\n background: #ffffff !important;\n border: 1px solid #e5e7eb !important;\n color: #111827 !important;\n }\n html:not(.dark) .notification-box .notification-close { background: rgba(0,0,0,0.06) !important; color: #111827 !important; }\n html:not(.dark) .notification-overlay { background-color: rgba(0, 0, 0, 0.4) !important; }\n html:not(.dark) .notification-title { color: #1f2937 !important; }\n html:not(.dark) .notification-message { color: #6b7280 !important; }\n\n .notification-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n margin: 0 auto 25px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 40px;\n position: relative;\n }\n\n .notification-icon::before {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n opacity: 0.2;\n }\n\n .notification-icon.success {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n }\n\n .notification-icon.success::before {\n background: #10b981;\n }\n\n .notification-icon.error {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n color: white;\n }\n\n .notification-icon.error::before {\n background: #ef4444;\n }\n\n .notification-icon.warning {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n }\n\n .notification-icon.warning::before {\n background: #f59e0b;\n }\n\n .notification-icon.info {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n }\n\n .notification-icon.info::before {\n background: #3b82f6;\n }\n .notification-icon.question {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n }\n\n .notification-icon.question::before {\n background: #3b82f6;\n }\n\n .notification-title {\n font-size: 24px;\n font-weight: 700;\n color: #1f2937;\n margin-bottom: 12px;\n line-height: 1.3;\n }\n\n .notification-message {\n font-size: 16px;\n color: #6b7280;\n line-height: 1.6;\n margin-bottom: 30px;\n }\n\n .notification-button {\n color: white;\n border: none;\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s ease;\n }\n\n .notification-button:hover {\n transform: translateY(-2px);\n filter: brightness(1.1);\n }\n\n .notification-button:active {\n transform: translateY(0);\n }\n\n /* group container for multiple action buttons */\n .notification-button-group {\n display: flex;\n gap: 12px;\n justify-content: center;\n flex-wrap: wrap;\n margin-top: 10px;\n }\n\n .notification-icon-checkmark {\n animation: checkmark-draw 0.6s ease-in-out;\n }\n\n .notification-icon-cross {\n animation: cross-draw 0.5s ease-in-out;\n }\n\n @keyframes checkmark-draw {\n 0% {\n transform: scale(0) rotate(-45deg);\n opacity: 0;\n }\n 50% {\n transform: scale(1.2) rotate(-45deg);\n }\n 100% {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n @keyframes cross-draw {\n 0% {\n transform: scale(0) rotate(-180deg);\n opacity: 0;\n }\n 50% {\n transform: scale(1.2) rotate(-90deg);\n }\n 100% {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n /* Loading spinner styles */\n .notification-loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0 auto;\n }\n\n .notification-spinner {\n width: 60px;\n height: 60px;\n border: 5px solid rgba(99, 102, 241, 0.15);\n border-top-color: #6366f1;\n border-radius: 50%;\n animation: notification-spin 1s linear infinite;\n margin: 0 auto;\n }\n\n @keyframes notification-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .notification-loading-text {\n font-size: 14px;\n color: #6b7280;\n text-align: center;\n margin-top: 12px;\n }\n\n .dark .notification-loading-text {\n color: #cbd5e1;\n }\n ",document.head.appendChild(n)}getIcon(n){const t={success:'<i class="bx bx-check" aria-hidden="true"></i>',error:'<i class="bx bx-x" aria-hidden="true"></i>',warning:'<i class="bx bx-error" aria-hidden="true"></i>',info:'<i class="bx bx-info-circle" aria-hidden="true"></i>',question:'<i class="bx bx-question-mark" aria-hidden="true"></i>'};return t[n]||t.info}getDefaultTitle(n){return{success:"¡Éxito!",error:"Error",warning:"Advertencia",info:"Información",question:"Pregunta"}[n]||"Notificación"}getButtonGradient(n){const t={success:"linear-gradient(135deg, #10b981 0%, #059669 100%)",error:"linear-gradient(135deg, #ef4444 0%, #dc2626 100%)",warning:"linear-gradient(135deg, #f59e0b 0%, #d97706 100%)",info:"linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)",question:"linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)"};return t[n]||t.info}getButtonShadow(n){const t={success:"rgba(16, 185, 129, 0)",error:"rgba(239, 68, 68, 0)",warning:"rgba(245, 159, 11, 0)",info:"rgba(59, 131, 246, 0)",question:"rgba(108, 99, 245, 0)"};return t[n]||t.info}show(n={}){if(this.currentNotification){const n=this.currentNotification;this.currentNotification=null;try{n&&n.parentNode&&n.parentNode.removeChild(n)}catch(n){}}const{type:t="info",title:e=this.getDefaultTitle(t),message:o="",buttonText:i="OK",buttonColor:a=null,onClose:r=null,timer:c=null,allowOutsideClick:s=!0,allowEscapeKey:l=!0,hideButton:d=!1,buttons:u=null}=n,f=!0===n.showCloseButton;try{document.body.style.overflow="hidden"}catch(n){}try{document.documentElement.style.overflow="hidden"}catch(n){}const p=document.createElement("div");p.className="notification-overlay",p.tabIndex=-1,p.setAttribute("role","dialog"),p.setAttribute("aria-modal","true"),p.style.pointerEvents="auto";const m=document.createElement("div");m.className="notification-box";const b=document.createElement("div");b.className=`notification-icon ${t}`,d&&"info"===t?(b.className="notification-loading-container",b.innerHTML='<div class="notification-spinner"></div>',b.style.background="transparent",b.style.boxShadow="none",b.style.width="100px",b.style.height="100px"):b.innerHTML=this.getIcon(t);const h=document.createElement("h3");h.className="notification-title",h.textContent=e;const g=document.createElement("p");g.className="notification-message",g.textContent=o;let x=null;if(n.html||n.content)if(x=document.createElement("div"),x.className="notification-content",n.html)try{x.innerHTML=n.html}catch(t){x.textContent=n.html}else n.content&&n.content instanceof HTMLElement&&x.appendChild(n.content);const y=()=>this.close(r);let w=null,v=null;if(!d)if(Array.isArray(u)&&u.length)v=document.createElement("div"),v.className="notification-button-group",u.forEach(n=>{const e=document.createElement("button");e.className="notification-button",e.textContent=n.text||"OK";const o=n.color||this.getButtonGradient(t),i=n.shadowColor||this.getButtonShadow(t);e.style.background=o,e.style.boxShadow=`0 4px 12px ${i}`,e.addEventListener("click",t=>{t.stopPropagation(),t.preventDefault();try{y().then(()=>{if("function"==typeof n.onClick)try{const t=n.onClick();t&&"function"==typeof t.then&&t.catch(n=>console.error(n))}catch(n){console.error(n)}}).catch(()=>{})}catch(n){console.error(n)}}),e.addEventListener("mouseenter",()=>{e.style.boxShadow=`0 6px 16px ${i}`}),e.addEventListener("mouseleave",()=>{e.style.boxShadow=`0 4px 12px ${i}`}),v.appendChild(e)});else if(n.onConfirm||n.onCancel||n.confirmText||n.cancelText){v=document.createElement("div"),v.className="notification-button-group";const e=n.cancelText||"Cancelar",o=n.confirmText||"Aceptar",i=document.createElement("button");i.className="notification-button",i.textContent=e;const a=n.cancelColor||"linear-gradient(135deg, #9ca3af 0%, #6b7280 100%)",r=n.cancelShadow||"rgba(107,114,128,0.25)";i.style.background=a,i.style.boxShadow=`0 4px 12px ${r}`,i.addEventListener("click",t=>{t.stopPropagation(),t.preventDefault(),y().then(()=>{try{if("function"==typeof n.onCancel){const t=n.onCancel();t&&"function"==typeof t.then&&t.catch(n=>console.error(n))}}catch(n){console.error(n)}}).catch(()=>{})}),i.addEventListener("mouseenter",()=>{i.style.boxShadow=`0 6px 16px ${r}`}),i.addEventListener("mouseleave",()=>{i.style.boxShadow=`0 4px 12px ${r}`});const c=document.createElement("button");c.className="notification-button",c.textContent=o;const s=n.confirmColor||this.getButtonGradient(t),l=n.confirmShadow||this.getButtonShadow(t);c.style.background=s,c.style.boxShadow=`0 4px 12px ${l}`,c.addEventListener("click",async t=>{t.stopPropagation(),t.preventDefault();try{if(await y(),"function"==typeof n.onConfirm){const t=n.onConfirm();t&&"function"==typeof t.then&&await t}}catch(n){console.error(n)}}),c.addEventListener("mouseenter",()=>{c.style.boxShadow=`0 6px 16px ${l}`}),c.addEventListener("mouseleave",()=>{c.style.boxShadow=`0 4px 12px ${l}`}),v.appendChild(i),v.appendChild(c)}else if(i){w=document.createElement("button"),w.className="notification-button",w.textContent=i;const n=a||this.getButtonGradient(t),e=this.getButtonShadow(t);w.style.background=n,w.style.boxShadow=`0 4px 12px ${e}`}let k=null;if(f&&(k=document.createElement("button"),k.setAttribute("aria-label","Cerrar"),k.className="notification-close",k.innerHTML="&times;",k.addEventListener("click",n=>{n.stopPropagation(),y()})),m.appendChild(b),x){const n="notify-desc-"+Date.now();x.id=n,p.setAttribute("aria-describedby",n),m.appendChild(x)}else m.appendChild(h),m.appendChild(g);k&&m.appendChild(k),v?m.appendChild(v):w&&m.appendChild(w),p.appendChild(m),document.body.appendChild(p);const E=p,C=new Promise(n=>{try{E._externalResolve=n}catch(n){}});try{const n=document.getElementById("notify-live");n&&(n.textContent=`${e}: ${o}`)}catch(n){}try{this._lastActiveElement=document.activeElement}catch(n){this._lastActiveElement=null}this.currentNotification=p;try{const n=m.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])');n&&n.length?n[0].focus():w?w.focus():p.focus()}catch(n){try{p.focus()}catch(n){}}const S=n=>{if("Tab"!==n.key)return;const t=Array.from(m.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])')).filter(n=>n instanceof HTMLElement&&null!==n.offsetParent);if(!t.length)return void n.preventDefault();const e=t[0],o=t[t.length-1];n.shiftKey||document.activeElement!==o?n.shiftKey&&document.activeElement===e&&(n.preventDefault(),o.focus()):(n.preventDefault(),e.focus())};E._focusTrap=S,document.addEventListener("keydown",S);const N=n.anim||{},L="number"==typeof N.overlayDuration?N.overlayDuration:150,T=N.overlayEasing||"easeOutQuad",D="number"==typeof N.boxDuration?N.boxDuration:200,_="number"==typeof N.boxDelay?N.boxDelay:50,j=N.boxEasing||"easeOutBack",A="number"==typeof N.boxStartScale?N.boxStartScale:.8,$="number"==typeof N.iconDuration?N.iconDuration:250,B="number"==typeof N.iconDelay?N.iconDelay:100,q="number"==typeof N.iconRotate?N.iconRotate:"success"===t?-90:"error"===t?90:0;if("number"==typeof N.overlayOpacity&&(p.style.backgroundColor=`rgba(0,0,0,${N.overlayOpacity})`),anime({targets:p,opacity:[0,1],duration:L,easing:T}),anime({targets:m,scale:[A,1],opacity:[0,1],duration:D,easing:j,delay:_}),anime({targets:b,scale:[0,1],rotate:[q,0],duration:$,easing:j,delay:B}),w){const n=this.getButtonShadow(t);w.addEventListener("mouseenter",()=>{w.style.boxShadow=`0 6px 16px ${n}`}),w.addEventListener("mouseleave",()=>{w.style.boxShadow=`0 4px 12px ${n}`}),w.addEventListener("click",n=>{n.stopPropagation(),n.preventDefault(),y().catch(()=>{})})}if(s&&p.addEventListener("click",n=>{m.contains(n.target)||y()}),c&&setTimeout(()=>{y()},c),l){const n=t=>{"Escape"===t.key&&(y(),document.removeEventListener("keydown",n))};E._escHandler=n,document.addEventListener("keydown",n)}return C}close(n=null){if(!this.currentNotification)return Promise.resolve();const t=this.currentNotification,e=t,o=t.querySelector(".notification-box");return this.currentNotification=null,anime({targets:o,scale:.8,opacity:0,duration:100,easing:"easeInQuad"}),new Promise(o=>{anime({targets:t,opacity:0,duration:100,easing:"easeInQuad",complete:()=>{try{e&&e._escHandler&&(document.removeEventListener("keydown",e._escHandler),e._escHandler=void 0)}catch(n){}try{e&&e._focusTrap&&(document.removeEventListener("keydown",e._focusTrap),e._focusTrap=void 0)}catch(n){}try{if(e&&"function"==typeof e._externalResolve){try{e._externalResolve()}catch(n){}e._externalResolve=void 0}}catch(n){}try{t&&t.parentNode&&t.parentNode.removeChild(t)}catch(n){try{t.remove()}catch(n){}}if(!this.currentNotification){try{document.body.style.overflow=""}catch(n){}try{document.documentElement.style.overflow=""}catch(n){}}try{this._lastActiveElement&&"function"==typeof this._lastActiveElement.focus&&this._lastActiveElement.focus()}catch(n){}this._lastActiveElement=null,n&&n(),o()}})})}success(n,t=null,e={}){this.show(Object.assign({type:"success",title:t||this.getDefaultTitle("success"),message:n},e))}error(n,t=null,e={}){this.show(Object.assign({type:"error",title:t||this.getDefaultTitle("error"),message:n},e))}warning(n,t=null,e={}){this.show(Object.assign({type:"warning",title:t||this.getDefaultTitle("warning"),message:n},e))}question(n,t=null,e={}){this.show(Object.assign({type:"question",title:t||this.getDefaultTitle("question"),message:n},e))}info(n,t=null,e={}){this.show(Object.assign({type:"info",title:t||this.getDefaultTitle("info"),message:n},e))}loading(n="Cargando...",t="Espera",e={}){const o=Object.assign({type:"info",title:t,message:n,hideButton:!0,allowOutsideClick:!1,allowEscapeKey:!1},e),i=this.show(o);return this._currentLoadingPromise=i,i}closeLoading(n=null){return this._currentLoadingPromise=null,this.close(n)}hide(n=null){return this.close(n)}hiden(n=null){return this.close(n)}_formatTime(n){const t=Math.max(0,Math.floor(n));return`${Math.floor(t/60).toString().padStart(2,"0")}:${(t%60).toString().padStart(2,"0")}`}},t=window;t.notify=n,t.Notification=n}}();const NotificationSystem=window.notify?.constructor||function(){throw new Error("NotificationSystem no se pudo cargar. Verifica que anime.js esté disponible.")};export default NotificationSystem;export{NotificationSystem};
1
+ "use strict";var __rest=this&&this.__rest||function(t,n){var e={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&n.indexOf(o)<0&&(e[o]=t[o]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(t);i<o.length;i++)n.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(t,o[i])&&(e[o[i]]=t[o[i]])}return e};!function(){if("undefined"!=typeof anime)t();else{const n=document.createElement("script");n.src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js",n.onload=t,n.onerror=()=>{console.error("FerNotify: No se pudo cargar anime.js. Por favor, cargalo manualmente.")},document.head.appendChild(n)}function t(){const t=new class{constructor(){this.currentNotification=null,this._lastActiveElement=null,this._currentLoadingPromise=null,this._toastContainers=new Map,this.injectStyles(),this.loadBoxicons()}loadBoxicons(){if(!document.querySelector('link[href*="boxicons"]')){const t=document.createElement("link");t.rel="stylesheet",t.href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css",document.head.appendChild(t)}}injectStyles(){const t=document.createElement("style");t.textContent="\n .notification-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n opacity: 0;\n overflow: hidden;\n }\n\n .notification-box {\n background: white;\n border-radius: 16px;\n padding: 40px 30px;\n max-width: 500px;\n width: 90%;\n max-height: 80vh;\n overflow: auto;\n position: relative;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n transform: scale(0.7);\n opacity: 0;\n }\n\n .notification-content {\n text-align: left;\n margin-bottom: 18px;\n }\n\n .notification-close {\n position: absolute;\n top: 10px;\n right: 10px;\n width: 38px;\n height: 38px;\n border-radius: 8px;\n border: none;\n background: rgba(0,0,0,0.06);\n color: #111827;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 18px;\n }\n\n .notification-close:hover {\n background: rgba(0,0,0,0.09);\n }\n\n /* Form controls inside the modal */\n .notification-box input,\n .notification-box textarea,\n .notification-box select {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: #ffffff;\n color: #111827;\n font-size: 15px;\n box-sizing: border-box;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n }\n\n .notification-box input:focus,\n .notification-box textarea:focus,\n .notification-box select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 6px 24px rgba(99,102,241,0.12), 0 0 0 4px rgba(99,102,241,0.06);\n }\n\n .notification-box label { display: block; margin-bottom: 6px; color: #374151; font-weight: 600; }\n\n /* Soporte para tema oscuro con clase .dark (Tailwind darkMode: 'class') */\n /* Esto tiene prioridad sobre prefers-color-scheme para respetar la elección del usuario en la web */\n .dark .notification-box { background: #0f1724 !important; color: #e6eef8 !important; }\n .dark .notification-box input,\n .dark .notification-box textarea,\n .dark .notification-box select {\n background: #0b1220 !important;\n border: 1px solid rgba(255,255,255,0.06) !important;\n color: #e6eef8 !important;\n }\n .dark .notification-box .notification-close { background: rgba(255,255,255,0.03) !important; color: #e6eef8 !important; }\n .dark .notification-overlay { background-color: rgba(0,0,0,0.6) !important; }\n .dark .notification-title { color: #e6eef8 !important; }\n .dark .notification-message { color: #cbd5e1 !important; }\n\n /* Forzar modo claro cuando NO hay clase .dark, ignorando prefers-color-scheme */\n html:not(.dark) .notification-box { background: white !important; color: #111827 !important; }\n html:not(.dark) .notification-box input,\n html:not(.dark) .notification-box textarea,\n html:not(.dark) .notification-box select {\n background: #ffffff !important;\n border: 1px solid #e5e7eb !important;\n color: #111827 !important;\n }\n html:not(.dark) .notification-box .notification-close { background: rgba(0,0,0,0.06) !important; color: #111827 !important; }\n html:not(.dark) .notification-overlay { background-color: rgba(0, 0, 0, 0.4) !important; }\n html:not(.dark) .notification-title { color: #1f2937 !important; }\n html:not(.dark) .notification-message { color: #6b7280 !important; }\n\n .notification-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n margin: 0 auto 25px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 40px;\n position: relative;\n }\n\n .notification-icon::before {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n opacity: 0.2;\n }\n\n .notification-icon.success {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n }\n\n .notification-icon.success::before {\n background: #10b981;\n }\n\n .notification-icon.error {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n color: white;\n }\n\n .notification-icon.error::before {\n background: #ef4444;\n }\n\n .notification-icon.warning {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n }\n\n .notification-icon.warning::before {\n background: #f59e0b;\n }\n\n .notification-icon.info {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n }\n\n .notification-icon.info::before {\n background: #3b82f6;\n }\n .notification-icon.question {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n }\n\n .notification-icon.question::before {\n background: #3b82f6;\n }\n\n .notification-title {\n font-size: 24px;\n font-weight: 700;\n color: #1f2937;\n margin-bottom: 12px;\n line-height: 1.3;\n }\n\n .notification-message {\n font-size: 16px;\n color: #6b7280;\n line-height: 1.6;\n margin-bottom: 30px;\n }\n\n .notification-button {\n color: white;\n border: none;\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s ease;\n }\n\n .notification-button:hover {\n transform: translateY(-2px);\n filter: brightness(1.1);\n }\n\n .notification-button:active {\n transform: translateY(0);\n }\n\n /* group container for multiple action buttons */\n .notification-button-group {\n display: flex;\n gap: 12px;\n justify-content: center;\n flex-wrap: wrap;\n margin-top: 10px;\n }\n\n .notification-icon-checkmark {\n animation: checkmark-draw 0.6s ease-in-out;\n }\n\n .notification-icon-cross {\n animation: cross-draw 0.5s ease-in-out;\n }\n\n @keyframes checkmark-draw {\n 0% {\n transform: scale(0) rotate(-45deg);\n opacity: 0;\n }\n 50% {\n transform: scale(1.2) rotate(-45deg);\n }\n 100% {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n @keyframes cross-draw {\n 0% {\n transform: scale(0) rotate(-180deg);\n opacity: 0;\n }\n 50% {\n transform: scale(1.2) rotate(-90deg);\n }\n 100% {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n /* Loading spinner styles */\n .notification-loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0 auto;\n }\n\n .notification-spinner {\n width: 60px;\n height: 60px;\n border: 5px solid rgba(99, 102, 241, 0.15);\n border-top-color: #6366f1;\n border-radius: 50%;\n animation: notification-spin 1s linear infinite;\n margin: 0 auto;\n }\n\n @keyframes notification-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .notification-loading-text {\n font-size: 14px;\n color: #6b7280;\n text-align: center;\n margin-top: 12px;\n }\n\n .dark .notification-loading-text {\n color: #cbd5e1;\n }\n\n /* ==================== Toast ==================== */\n .notify-toast-container {\n position: fixed;\n z-index: 10000;\n display: flex;\n flex-direction: column;\n gap: 10px;\n pointer-events: none;\n width: 360px;\n max-width: calc(100vw - 40px);\n }\n .notify-toast-top-right { top: 20px; right: 20px; }\n .notify-toast-top-left { top: 20px; left: 20px; }\n .notify-toast-top-center { top: 20px; left: 50%; transform: translateX(-50%); }\n .notify-toast-bottom-right { bottom: 20px; right: 20px; flex-direction: column-reverse; }\n .notify-toast-bottom-left { bottom: 20px; left: 20px; flex-direction: column-reverse; }\n\n .notify-toast {\n background: white;\n border-radius: 12px;\n padding: 14px 40px 14px 14px;\n box-shadow: 0 4px 24px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.06);\n display: flex;\n align-items: flex-start;\n gap: 12px;\n pointer-events: auto;\n position: relative;\n overflow: hidden;\n opacity: 0;\n transform: translateX(30px);\n transition: opacity 0.25s ease, transform 0.25s ease;\n }\n .notify-toast-top-left .notify-toast,\n .notify-toast-bottom-left .notify-toast { transform: translateX(-30px); }\n .notify-toast-top-center .notify-toast { transform: translateY(-20px); }\n .notify-toast.notify-toast-visible {\n opacity: 1;\n transform: translateX(0) translateY(0) !important;\n }\n\n .notify-toast-icon {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 20px;\n flex-shrink: 0;\n color: white;\n }\n .notify-toast-icon.success { background: linear-gradient(135deg, #10b981 0%, #059669 100%); }\n .notify-toast-icon.error { background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); }\n .notify-toast-icon.warning { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); }\n .notify-toast-icon.info { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); }\n .notify-toast-icon.question { background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%); }\n\n .notify-toast-content { flex: 1; min-width: 0; }\n .notify-toast-title {\n font-size: 14px;\n font-weight: 700;\n color: #1f2937;\n margin-bottom: 2px;\n line-height: 1.3;\n }\n .notify-toast-message {\n font-size: 13px;\n color: #6b7280;\n line-height: 1.5;\n }\n\n .notify-toast-close {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 24px;\n height: 24px;\n border-radius: 6px;\n border: none;\n background: rgba(0,0,0,0.06);\n color: #6b7280;\n cursor: pointer;\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n padding: 0;\n }\n .notify-toast-close:hover { background: rgba(0,0,0,0.1); color: #374151; }\n\n .notify-toast-progress {\n position: absolute;\n bottom: 0;\n left: 0;\n height: 3px;\n width: 100%;\n border-radius: 0 0 0 12px;\n }\n .notify-toast-progress.success { background: #10b981; }\n .notify-toast-progress.error { background: #ef4444; }\n .notify-toast-progress.warning { background: #f59e0b; }\n .notify-toast-progress.info { background: #3b82f6; }\n .notify-toast-progress.question { background: #8b5cf6; }\n\n .dark .notify-toast { background: #0f1724; box-shadow: 0 4px 24px rgba(0,0,0,0.35); }\n .dark .notify-toast-title { color: #e6eef8; }\n .dark .notify-toast-message { color: #cbd5e1; }\n .dark .notify-toast-close { background: rgba(255,255,255,0.06); color: #94a3b8; }\n .dark .notify-toast-close:hover { background: rgba(255,255,255,0.1); color: #e2e8f0; }\n ",document.head.appendChild(t)}getIcon(t){const n={success:'<i class="bx bx-check" aria-hidden="true"></i>',error:'<i class="bx bx-x" aria-hidden="true"></i>',warning:'<i class="bx bx-error" aria-hidden="true"></i>',info:'<i class="bx bx-info-circle" aria-hidden="true"></i>',question:'<i class="bx bx-question-mark" aria-hidden="true"></i>'};return n[t]||n.info}getDefaultTitle(t){return{success:"¡Éxito!",error:"Error",warning:"Advertencia",info:"Información",question:"Pregunta"}[t]||"Notificación"}getButtonGradient(t){const n={success:"linear-gradient(135deg, #10b981 0%, #059669 100%)",error:"linear-gradient(135deg, #ef4444 0%, #dc2626 100%)",warning:"linear-gradient(135deg, #f59e0b 0%, #d97706 100%)",info:"linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)",question:"linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)"};return n[t]||n.info}getButtonShadow(t){const n={success:"rgba(16, 185, 129, 0)",error:"rgba(239, 68, 68, 0)",warning:"rgba(245, 159, 11, 0)",info:"rgba(59, 131, 246, 0)",question:"rgba(108, 99, 245, 0)"};return n[t]||n.info}show(t={}){if(this.currentNotification){const t=this.currentNotification;this.currentNotification=null;try{t&&t.parentNode&&t.parentNode.removeChild(t)}catch(t){}}const{type:n="info",title:e=this.getDefaultTitle(n),message:o="",buttonText:i="OK",buttonColor:a=null,onClose:r=null,timer:s=null,allowOutsideClick:c=!0,allowEscapeKey:l=!0,hideButton:d=!1,buttons:f=null}=t,u=!0===t.showCloseButton;try{document.body.style.overflow="hidden"}catch(t){}try{document.documentElement.style.overflow="hidden"}catch(t){}const p=document.createElement("div");p.className="notification-overlay",p.tabIndex=-1,p.setAttribute("role","dialog"),p.setAttribute("aria-modal","true"),p.style.pointerEvents="auto";const m=document.createElement("div");m.className="notification-box";const b=document.createElement("div");b.className=`notification-icon ${n}`,d&&"info"===n?(b.className="notification-loading-container",b.innerHTML='<div class="notification-spinner"></div>',b.style.background="transparent",b.style.boxShadow="none",b.style.width="100px",b.style.height="100px"):b.innerHTML=this.getIcon(n);const h=document.createElement("h3");h.className="notification-title",h.textContent=e;const g=document.createElement("p");g.className="notification-message",g.textContent=o;let x=null;if(t.html||t.content)if(x=document.createElement("div"),x.className="notification-content",t.html)try{x.innerHTML=t.html}catch(n){x.textContent=t.html}else t.content&&t.content instanceof HTMLElement&&x.appendChild(t.content);const y=()=>this.close(r);let w=null,v=null;if(!d)if(Array.isArray(f)&&f.length)v=document.createElement("div"),v.className="notification-button-group",f.forEach(t=>{const e=document.createElement("button");e.className="notification-button",e.textContent=t.text||"OK";const o=t.color||this.getButtonGradient(n),i=t.shadowColor||this.getButtonShadow(n);e.style.background=o,e.style.boxShadow=`0 4px 12px ${i}`,e.addEventListener("click",n=>{n.stopPropagation(),n.preventDefault();try{y().then(()=>{if("function"==typeof t.onClick)try{const n=t.onClick();n&&"function"==typeof n.then&&n.catch(t=>console.error(t))}catch(t){console.error(t)}}).catch(()=>{})}catch(t){console.error(t)}}),e.addEventListener("mouseenter",()=>{e.style.boxShadow=`0 6px 16px ${i}`}),e.addEventListener("mouseleave",()=>{e.style.boxShadow=`0 4px 12px ${i}`}),v.appendChild(e)});else if(t.onConfirm||t.onCancel||t.confirmText||t.cancelText){v=document.createElement("div"),v.className="notification-button-group";const e=t.cancelText||"Cancelar",o=t.confirmText||"Aceptar",i=document.createElement("button");i.className="notification-button",i.textContent=e;const a=t.cancelColor||"linear-gradient(135deg, #9ca3af 0%, #6b7280 100%)",r=t.cancelShadow||"rgba(107,114,128,0.25)";i.style.background=a,i.style.boxShadow=`0 4px 12px ${r}`,i.addEventListener("click",n=>{n.stopPropagation(),n.preventDefault(),y().then(()=>{try{if("function"==typeof t.onCancel){const n=t.onCancel();n&&"function"==typeof n.then&&n.catch(t=>console.error(t))}}catch(t){console.error(t)}}).catch(()=>{})}),i.addEventListener("mouseenter",()=>{i.style.boxShadow=`0 6px 16px ${r}`}),i.addEventListener("mouseleave",()=>{i.style.boxShadow=`0 4px 12px ${r}`});const s=document.createElement("button");s.className="notification-button",s.textContent=o;const c=t.confirmColor||this.getButtonGradient(n),l=t.confirmShadow||this.getButtonShadow(n);s.style.background=c,s.style.boxShadow=`0 4px 12px ${l}`,s.addEventListener("click",async n=>{n.stopPropagation(),n.preventDefault();try{if(await y(),"function"==typeof t.onConfirm){const n=t.onConfirm();n&&"function"==typeof n.then&&await n}}catch(t){console.error(t)}}),s.addEventListener("mouseenter",()=>{s.style.boxShadow=`0 6px 16px ${l}`}),s.addEventListener("mouseleave",()=>{s.style.boxShadow=`0 4px 12px ${l}`}),v.appendChild(i),v.appendChild(s)}else if(i){w=document.createElement("button"),w.className="notification-button",w.textContent=i;const t=a||this.getButtonGradient(n),e=this.getButtonShadow(n);w.style.background=t,w.style.boxShadow=`0 4px 12px ${e}`}let k=null;if(u&&(k=document.createElement("button"),k.setAttribute("aria-label","Cerrar"),k.className="notification-close",k.innerHTML="&times;",k.addEventListener("click",t=>{t.stopPropagation(),y()})),m.appendChild(b),x){const t="notify-desc-"+Date.now();x.id=t,p.setAttribute("aria-describedby",t),m.appendChild(x)}else m.appendChild(h),m.appendChild(g);k&&m.appendChild(k),v?m.appendChild(v):w&&m.appendChild(w),p.appendChild(m),document.body.appendChild(p);const E=p,C=new Promise(t=>{try{E._externalResolve=t}catch(t){}});try{const t=document.getElementById("notify-live");t&&(t.textContent=`${e}: ${o}`)}catch(t){}try{this._lastActiveElement=document.activeElement}catch(t){this._lastActiveElement=null}this.currentNotification=p;try{const t=m.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])');t&&t.length?t[0].focus():w?w.focus():p.focus()}catch(t){try{p.focus()}catch(t){}}const N=t=>{if("Tab"!==t.key)return;const n=Array.from(m.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])')).filter(t=>t instanceof HTMLElement&&null!==t.offsetParent);if(!n.length)return void t.preventDefault();const e=n[0],o=n[n.length-1];t.shiftKey||document.activeElement!==o?t.shiftKey&&document.activeElement===e&&(t.preventDefault(),o.focus()):(t.preventDefault(),e.focus())};E._focusTrap=N,document.addEventListener("keydown",N);const S=t.anim||{},T="number"==typeof S.overlayDuration?S.overlayDuration:150,L=S.overlayEasing||"easeOutQuad",j="number"==typeof S.boxDuration?S.boxDuration:200,O="number"==typeof S.boxDelay?S.boxDelay:50,_=S.boxEasing||"easeOutBack",D="number"==typeof S.boxStartScale?S.boxStartScale:.8,$="number"==typeof S.iconDuration?S.iconDuration:250,A="number"==typeof S.iconDelay?S.iconDelay:100,q="number"==typeof S.iconRotate?S.iconRotate:"success"===n?-90:"error"===n?90:0;if("number"==typeof S.overlayOpacity&&(p.style.backgroundColor=`rgba(0,0,0,${S.overlayOpacity})`),anime({targets:p,opacity:[0,1],duration:T,easing:L}),anime({targets:m,scale:[D,1],opacity:[0,1],duration:j,easing:_,delay:O}),anime({targets:b,scale:[0,1],rotate:[q,0],duration:$,easing:_,delay:A}),w){const t=this.getButtonShadow(n);w.addEventListener("mouseenter",()=>{w.style.boxShadow=`0 6px 16px ${t}`}),w.addEventListener("mouseleave",()=>{w.style.boxShadow=`0 4px 12px ${t}`}),w.addEventListener("click",t=>{t.stopPropagation(),t.preventDefault(),y().catch(()=>{})})}if(c&&p.addEventListener("click",t=>{m.contains(t.target)||y()}),s&&setTimeout(()=>{y()},s),l){const t=n=>{"Escape"===n.key&&(y(),document.removeEventListener("keydown",t))};E._escHandler=t,document.addEventListener("keydown",t)}return C}close(t=null){if(!this.currentNotification)return Promise.resolve();const n=this.currentNotification,e=n,o=n.querySelector(".notification-box");return this.currentNotification=null,anime({targets:o,scale:.8,opacity:0,duration:100,easing:"easeInQuad"}),new Promise(o=>{anime({targets:n,opacity:0,duration:100,easing:"easeInQuad",complete:()=>{try{e&&e._escHandler&&(document.removeEventListener("keydown",e._escHandler),e._escHandler=void 0)}catch(t){}try{e&&e._focusTrap&&(document.removeEventListener("keydown",e._focusTrap),e._focusTrap=void 0)}catch(t){}try{if(e&&"function"==typeof e._externalResolve){try{e._externalResolve()}catch(t){}e._externalResolve=void 0}}catch(t){}try{n&&n.parentNode&&n.parentNode.removeChild(n)}catch(t){try{n.remove()}catch(t){}}if(!this.currentNotification){try{document.body.style.overflow=""}catch(t){}try{document.documentElement.style.overflow=""}catch(t){}}try{this._lastActiveElement&&"function"==typeof this._lastActiveElement.focus&&this._lastActiveElement.focus()}catch(t){}this._lastActiveElement=null,t&&t(),o()}})})}success(t,n=null,e={}){this.show(Object.assign({type:"success",title:n||this.getDefaultTitle("success"),message:t},e))}error(t,n=null,e={}){this.show(Object.assign({type:"error",title:n||this.getDefaultTitle("error"),message:t},e))}warning(t,n=null,e={}){this.show(Object.assign({type:"warning",title:n||this.getDefaultTitle("warning"),message:t},e))}question(t,n=null,e={}){this.show(Object.assign({type:"question",title:n||this.getDefaultTitle("question"),message:t},e))}info(t,n=null,e={}){this.show(Object.assign({type:"info",title:n||this.getDefaultTitle("info"),message:t},e))}loading(t="Cargando...",n="Espera",e={}){const o=Object.assign({type:"info",title:n,message:t,hideButton:!0,allowOutsideClick:!1,allowEscapeKey:!1},e),i=this.show(o);return this._currentLoadingPromise=i,i}closeLoading(t=null){return this._currentLoadingPromise=null,this.close(t)}hide(t=null){return this.close(t)}hiden(t=null){return this.close(t)}_formatTime(t){const n=Math.max(0,Math.floor(t));return`${Math.floor(n/60).toString().padStart(2,"0")}:${(n%60).toString().padStart(2,"0")}`}showToast(t,n={}){var e;const o=n.type||"info",i=null!==(e=n.title)&&void 0!==e?e:null,a="number"==typeof n.duration?n.duration:4e3,r=n.position||"top-right",s=!1!==n.showProgress;let c=this._toastContainers.get(r);c&&document.body.contains(c)||(c=document.createElement("div"),c.className=`notify-toast-container notify-toast-${r}`,document.body.appendChild(c),this._toastContainers.set(r,c));const l=r.startsWith("bottom"),d="top-center"===r,f=document.createElement("div");f.className="notify-toast";const u=document.createElement("div");u.className=`notify-toast-icon ${o}`,u.innerHTML=this.getIcon(o);const p=document.createElement("div");if(p.className="notify-toast-content",i){const t=document.createElement("div");t.className="notify-toast-title",t.textContent=i,p.appendChild(t)}const m=document.createElement("div");m.className="notify-toast-message",m.textContent=t,p.appendChild(m);const b=document.createElement("button");b.className="notify-toast-close",b.setAttribute("aria-label","Cerrar notificación"),b.innerHTML="&times;",f.appendChild(u),f.appendChild(p),f.appendChild(b);let h=null;a>0&&s&&(h=document.createElement("div"),h.className=`notify-toast-progress ${o}`,f.appendChild(h)),l||d?c.appendChild(f):c.insertBefore(f,c.firstChild);let g=!1,x=null,y=a,w=0;const v=()=>{g||(g=!0,f.classList.remove("notify-toast-visible"),setTimeout(()=>{f.parentNode&&f.parentNode.removeChild(f)},300))},k=t=>{w=Date.now(),x=setTimeout(v,t),h&&(h.style.transition=`width ${t}ms linear`,h.style.width="0%")};b.addEventListener("click",v),requestAnimationFrame(()=>{requestAnimationFrame(()=>{f.classList.add("notify-toast-visible"),a>0&&k(a)})}),a>0&&(f.addEventListener("mouseenter",()=>{if(g||null===x)return;clearTimeout(x),x=null;const t=Date.now()-w;if(y=Math.max(0,y-t),h){const t=y/a*100;h.style.transition="none",h.style.width=`${t}%`}}),f.addEventListener("mouseleave",()=>{g||y<=0||k(y)}))}toast(t,n={}){if("string"==typeof t)this.showToast(t,n);else{const{message:n=""}=t,e=__rest(t,["message"]);this.showToast(n,e)}}toastSuccess(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"success",title:null!=n?n:e.title}))}toastError(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"error",title:null!=n?n:e.title}))}toastWarning(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"warning",title:null!=n?n:e.title}))}toastInfo(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"info",title:null!=n?n:e.title}))}toastQuestion(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"question",title:null!=n?n:e.title}))}},n=window;n.notify=t,n.Notification=t}}();const NotificationSystem=window.notify?.constructor||function(){throw new Error("NotificationSystem no se pudo cargar. Verifica que anime.js esté disponible.")};export default NotificationSystem;export{NotificationSystem};
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  (function ensureAnimeDependency() {
3
14
  if (typeof anime !== 'undefined') {
4
15
  initFerNotify();
@@ -18,6 +29,7 @@
18
29
  this.currentNotification = null;
19
30
  this._lastActiveElement = null;
20
31
  this._currentLoadingPromise = null;
32
+ this._toastContainers = new Map();
21
33
  this.injectStyles();
22
34
  this.loadBoxicons();
23
35
  }
@@ -324,6 +336,117 @@
324
336
  .dark .notification-loading-text {
325
337
  color: #cbd5e1;
326
338
  }
339
+
340
+ /* ==================== Toast ==================== */
341
+ .notify-toast-container {
342
+ position: fixed;
343
+ z-index: 10000;
344
+ display: flex;
345
+ flex-direction: column;
346
+ gap: 10px;
347
+ pointer-events: none;
348
+ width: 360px;
349
+ max-width: calc(100vw - 40px);
350
+ }
351
+ .notify-toast-top-right { top: 20px; right: 20px; }
352
+ .notify-toast-top-left { top: 20px; left: 20px; }
353
+ .notify-toast-top-center { top: 20px; left: 50%; transform: translateX(-50%); }
354
+ .notify-toast-bottom-right { bottom: 20px; right: 20px; flex-direction: column-reverse; }
355
+ .notify-toast-bottom-left { bottom: 20px; left: 20px; flex-direction: column-reverse; }
356
+
357
+ .notify-toast {
358
+ background: white;
359
+ border-radius: 12px;
360
+ padding: 14px 40px 14px 14px;
361
+ box-shadow: 0 4px 24px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.06);
362
+ display: flex;
363
+ align-items: flex-start;
364
+ gap: 12px;
365
+ pointer-events: auto;
366
+ position: relative;
367
+ overflow: hidden;
368
+ opacity: 0;
369
+ transform: translateX(30px);
370
+ transition: opacity 0.25s ease, transform 0.25s ease;
371
+ }
372
+ .notify-toast-top-left .notify-toast,
373
+ .notify-toast-bottom-left .notify-toast { transform: translateX(-30px); }
374
+ .notify-toast-top-center .notify-toast { transform: translateY(-20px); }
375
+ .notify-toast.notify-toast-visible {
376
+ opacity: 1;
377
+ transform: translateX(0) translateY(0) !important;
378
+ }
379
+
380
+ .notify-toast-icon {
381
+ width: 36px;
382
+ height: 36px;
383
+ border-radius: 50%;
384
+ display: flex;
385
+ align-items: center;
386
+ justify-content: center;
387
+ font-size: 20px;
388
+ flex-shrink: 0;
389
+ color: white;
390
+ }
391
+ .notify-toast-icon.success { background: linear-gradient(135deg, #10b981 0%, #059669 100%); }
392
+ .notify-toast-icon.error { background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); }
393
+ .notify-toast-icon.warning { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); }
394
+ .notify-toast-icon.info { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); }
395
+ .notify-toast-icon.question { background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%); }
396
+
397
+ .notify-toast-content { flex: 1; min-width: 0; }
398
+ .notify-toast-title {
399
+ font-size: 14px;
400
+ font-weight: 700;
401
+ color: #1f2937;
402
+ margin-bottom: 2px;
403
+ line-height: 1.3;
404
+ }
405
+ .notify-toast-message {
406
+ font-size: 13px;
407
+ color: #6b7280;
408
+ line-height: 1.5;
409
+ }
410
+
411
+ .notify-toast-close {
412
+ position: absolute;
413
+ top: 8px;
414
+ right: 8px;
415
+ width: 24px;
416
+ height: 24px;
417
+ border-radius: 6px;
418
+ border: none;
419
+ background: rgba(0,0,0,0.06);
420
+ color: #6b7280;
421
+ cursor: pointer;
422
+ font-size: 16px;
423
+ display: flex;
424
+ align-items: center;
425
+ justify-content: center;
426
+ line-height: 1;
427
+ padding: 0;
428
+ }
429
+ .notify-toast-close:hover { background: rgba(0,0,0,0.1); color: #374151; }
430
+
431
+ .notify-toast-progress {
432
+ position: absolute;
433
+ bottom: 0;
434
+ left: 0;
435
+ height: 3px;
436
+ width: 100%;
437
+ border-radius: 0 0 0 12px;
438
+ }
439
+ .notify-toast-progress.success { background: #10b981; }
440
+ .notify-toast-progress.error { background: #ef4444; }
441
+ .notify-toast-progress.warning { background: #f59e0b; }
442
+ .notify-toast-progress.info { background: #3b82f6; }
443
+ .notify-toast-progress.question { background: #8b5cf6; }
444
+
445
+ .dark .notify-toast { background: #0f1724; box-shadow: 0 4px 24px rgba(0,0,0,0.35); }
446
+ .dark .notify-toast-title { color: #e6eef8; }
447
+ .dark .notify-toast-message { color: #cbd5e1; }
448
+ .dark .notify-toast-close { background: rgba(255,255,255,0.06); color: #94a3b8; }
449
+ .dark .notify-toast-close:hover { background: rgba(255,255,255,0.1); color: #e2e8f0; }
327
450
  `;
328
451
  document.head.appendChild(style);
329
452
  }
@@ -830,6 +953,136 @@
830
953
  const ss = (s % 60).toString().padStart(2, '0');
831
954
  return `${mm}:${ss}`;
832
955
  }
956
+ showToast(message, options = {}) {
957
+ var _a;
958
+ const type = options.type || 'info';
959
+ const title = (_a = options.title) !== null && _a !== void 0 ? _a : null;
960
+ const duration = typeof options.duration === 'number' ? options.duration : 4000;
961
+ const position = options.position || 'top-right';
962
+ const showProgress = options.showProgress !== false;
963
+ let container = this._toastContainers.get(position);
964
+ if (!container || !document.body.contains(container)) {
965
+ container = document.createElement('div');
966
+ container.className = `notify-toast-container notify-toast-${position}`;
967
+ document.body.appendChild(container);
968
+ this._toastContainers.set(position, container);
969
+ }
970
+ const isBottom = position.startsWith('bottom');
971
+ const isCenter = position === 'top-center';
972
+ const toast = document.createElement('div');
973
+ toast.className = 'notify-toast';
974
+ const iconEl = document.createElement('div');
975
+ iconEl.className = `notify-toast-icon ${type}`;
976
+ iconEl.innerHTML = this.getIcon(type);
977
+ const contentEl = document.createElement('div');
978
+ contentEl.className = 'notify-toast-content';
979
+ if (title) {
980
+ const titleEl = document.createElement('div');
981
+ titleEl.className = 'notify-toast-title';
982
+ titleEl.textContent = title;
983
+ contentEl.appendChild(titleEl);
984
+ }
985
+ const msgEl = document.createElement('div');
986
+ msgEl.className = 'notify-toast-message';
987
+ msgEl.textContent = message;
988
+ contentEl.appendChild(msgEl);
989
+ const closeBtn = document.createElement('button');
990
+ closeBtn.className = 'notify-toast-close';
991
+ closeBtn.setAttribute('aria-label', 'Cerrar notificación');
992
+ closeBtn.innerHTML = '&times;';
993
+ toast.appendChild(iconEl);
994
+ toast.appendChild(contentEl);
995
+ toast.appendChild(closeBtn);
996
+ let progressEl = null;
997
+ if (duration > 0 && showProgress) {
998
+ progressEl = document.createElement('div');
999
+ progressEl.className = `notify-toast-progress ${type}`;
1000
+ toast.appendChild(progressEl);
1001
+ }
1002
+ if (isBottom || isCenter) {
1003
+ container.appendChild(toast);
1004
+ }
1005
+ else {
1006
+ container.insertBefore(toast, container.firstChild);
1007
+ }
1008
+ let dismissed = false;
1009
+ let timerId = null;
1010
+ let remaining = duration;
1011
+ let timerStartedAt = 0;
1012
+ const removeToast = () => {
1013
+ if (dismissed)
1014
+ return;
1015
+ dismissed = true;
1016
+ toast.classList.remove('notify-toast-visible');
1017
+ setTimeout(() => {
1018
+ if (toast.parentNode)
1019
+ toast.parentNode.removeChild(toast);
1020
+ }, 300);
1021
+ };
1022
+ const startCountdown = (ms) => {
1023
+ timerStartedAt = Date.now();
1024
+ timerId = setTimeout(removeToast, ms);
1025
+ if (progressEl) {
1026
+ progressEl.style.transition = `width ${ms}ms linear`;
1027
+ progressEl.style.width = '0%';
1028
+ }
1029
+ };
1030
+ const pauseCountdown = () => {
1031
+ if (dismissed || timerId === null)
1032
+ return;
1033
+ clearTimeout(timerId);
1034
+ timerId = null;
1035
+ const elapsed = Date.now() - timerStartedAt;
1036
+ remaining = Math.max(0, remaining - elapsed);
1037
+ if (progressEl) {
1038
+ const pct = (remaining / duration) * 100;
1039
+ progressEl.style.transition = 'none';
1040
+ progressEl.style.width = `${pct}%`;
1041
+ }
1042
+ };
1043
+ const resumeCountdown = () => {
1044
+ if (dismissed || remaining <= 0)
1045
+ return;
1046
+ startCountdown(remaining);
1047
+ };
1048
+ closeBtn.addEventListener('click', removeToast);
1049
+ requestAnimationFrame(() => {
1050
+ requestAnimationFrame(() => {
1051
+ toast.classList.add('notify-toast-visible');
1052
+ if (duration > 0) {
1053
+ startCountdown(duration);
1054
+ }
1055
+ });
1056
+ });
1057
+ if (duration > 0) {
1058
+ toast.addEventListener('mouseenter', pauseCountdown);
1059
+ toast.addEventListener('mouseleave', resumeCountdown);
1060
+ }
1061
+ }
1062
+ toast(messageOrOptions, options = {}) {
1063
+ if (typeof messageOrOptions === 'string') {
1064
+ this.showToast(messageOrOptions, options);
1065
+ }
1066
+ else {
1067
+ const { message = '' } = messageOrOptions, rest = __rest(messageOrOptions, ["message"]);
1068
+ this.showToast(message, rest);
1069
+ }
1070
+ }
1071
+ toastSuccess(message, title, options = {}) {
1072
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'success', title: title !== null && title !== void 0 ? title : options.title }));
1073
+ }
1074
+ toastError(message, title, options = {}) {
1075
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'error', title: title !== null && title !== void 0 ? title : options.title }));
1076
+ }
1077
+ toastWarning(message, title, options = {}) {
1078
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'warning', title: title !== null && title !== void 0 ? title : options.title }));
1079
+ }
1080
+ toastInfo(message, title, options = {}) {
1081
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'info', title: title !== null && title !== void 0 ? title : options.title }));
1082
+ }
1083
+ toastQuestion(message, title, options = {}) {
1084
+ this.showToast(message, Object.assign(Object.assign({}, options), { type: 'question', title: title !== null && title !== void 0 ? title : options.title }));
1085
+ }
833
1086
  }
834
1087
  const notifyInstance = new NotificationSystem();
835
1088
  const w = window;
@@ -1 +1 @@
1
- "use strict";!function(){if("undefined"!=typeof anime)n();else{const t=document.createElement("script");t.src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js",t.onload=n,t.onerror=()=>{console.error("FerNotify: No se pudo cargar anime.js. Por favor, cargalo manualmente.")},document.head.appendChild(t)}function n(){const n=new class{constructor(){this.currentNotification=null,this._lastActiveElement=null,this._currentLoadingPromise=null,this.injectStyles(),this.loadBoxicons()}loadBoxicons(){if(!document.querySelector('link[href*="boxicons"]')){const n=document.createElement("link");n.rel="stylesheet",n.href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css",document.head.appendChild(n)}}injectStyles(){const n=document.createElement("style");n.textContent="\n .notification-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n opacity: 0;\n overflow: hidden;\n }\n\n .notification-box {\n background: white;\n border-radius: 16px;\n padding: 40px 30px;\n max-width: 500px;\n width: 90%;\n max-height: 80vh;\n overflow: auto;\n position: relative;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n transform: scale(0.7);\n opacity: 0;\n }\n\n .notification-content {\n text-align: left;\n margin-bottom: 18px;\n }\n\n .notification-close {\n position: absolute;\n top: 10px;\n right: 10px;\n width: 38px;\n height: 38px;\n border-radius: 8px;\n border: none;\n background: rgba(0,0,0,0.06);\n color: #111827;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 18px;\n }\n\n .notification-close:hover {\n background: rgba(0,0,0,0.09);\n }\n\n /* Form controls inside the modal */\n .notification-box input,\n .notification-box textarea,\n .notification-box select {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: #ffffff;\n color: #111827;\n font-size: 15px;\n box-sizing: border-box;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n }\n\n .notification-box input:focus,\n .notification-box textarea:focus,\n .notification-box select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 6px 24px rgba(99,102,241,0.12), 0 0 0 4px rgba(99,102,241,0.06);\n }\n\n .notification-box label { display: block; margin-bottom: 6px; color: #374151; font-weight: 600; }\n\n /* Soporte para tema oscuro con clase .dark (Tailwind darkMode: 'class') */\n /* Esto tiene prioridad sobre prefers-color-scheme para respetar la elección del usuario en la web */\n .dark .notification-box { background: #0f1724 !important; color: #e6eef8 !important; }\n .dark .notification-box input,\n .dark .notification-box textarea,\n .dark .notification-box select {\n background: #0b1220 !important;\n border: 1px solid rgba(255,255,255,0.06) !important;\n color: #e6eef8 !important;\n }\n .dark .notification-box .notification-close { background: rgba(255,255,255,0.03) !important; color: #e6eef8 !important; }\n .dark .notification-overlay { background-color: rgba(0,0,0,0.6) !important; }\n .dark .notification-title { color: #e6eef8 !important; }\n .dark .notification-message { color: #cbd5e1 !important; }\n\n /* Forzar modo claro cuando NO hay clase .dark, ignorando prefers-color-scheme */\n html:not(.dark) .notification-box { background: white !important; color: #111827 !important; }\n html:not(.dark) .notification-box input,\n html:not(.dark) .notification-box textarea,\n html:not(.dark) .notification-box select {\n background: #ffffff !important;\n border: 1px solid #e5e7eb !important;\n color: #111827 !important;\n }\n html:not(.dark) .notification-box .notification-close { background: rgba(0,0,0,0.06) !important; color: #111827 !important; }\n html:not(.dark) .notification-overlay { background-color: rgba(0, 0, 0, 0.4) !important; }\n html:not(.dark) .notification-title { color: #1f2937 !important; }\n html:not(.dark) .notification-message { color: #6b7280 !important; }\n\n .notification-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n margin: 0 auto 25px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 40px;\n position: relative;\n }\n\n .notification-icon::before {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n opacity: 0.2;\n }\n\n .notification-icon.success {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n }\n\n .notification-icon.success::before {\n background: #10b981;\n }\n\n .notification-icon.error {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n color: white;\n }\n\n .notification-icon.error::before {\n background: #ef4444;\n }\n\n .notification-icon.warning {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n }\n\n .notification-icon.warning::before {\n background: #f59e0b;\n }\n\n .notification-icon.info {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n }\n\n .notification-icon.info::before {\n background: #3b82f6;\n }\n .notification-icon.question {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n }\n\n .notification-icon.question::before {\n background: #3b82f6;\n }\n\n .notification-title {\n font-size: 24px;\n font-weight: 700;\n color: #1f2937;\n margin-bottom: 12px;\n line-height: 1.3;\n }\n\n .notification-message {\n font-size: 16px;\n color: #6b7280;\n line-height: 1.6;\n margin-bottom: 30px;\n }\n\n .notification-button {\n color: white;\n border: none;\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s ease;\n }\n\n .notification-button:hover {\n transform: translateY(-2px);\n filter: brightness(1.1);\n }\n\n .notification-button:active {\n transform: translateY(0);\n }\n\n /* group container for multiple action buttons */\n .notification-button-group {\n display: flex;\n gap: 12px;\n justify-content: center;\n flex-wrap: wrap;\n margin-top: 10px;\n }\n\n .notification-icon-checkmark {\n animation: checkmark-draw 0.6s ease-in-out;\n }\n\n .notification-icon-cross {\n animation: cross-draw 0.5s ease-in-out;\n }\n\n @keyframes checkmark-draw {\n 0% {\n transform: scale(0) rotate(-45deg);\n opacity: 0;\n }\n 50% {\n transform: scale(1.2) rotate(-45deg);\n }\n 100% {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n @keyframes cross-draw {\n 0% {\n transform: scale(0) rotate(-180deg);\n opacity: 0;\n }\n 50% {\n transform: scale(1.2) rotate(-90deg);\n }\n 100% {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n /* Loading spinner styles */\n .notification-loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0 auto;\n }\n\n .notification-spinner {\n width: 60px;\n height: 60px;\n border: 5px solid rgba(99, 102, 241, 0.15);\n border-top-color: #6366f1;\n border-radius: 50%;\n animation: notification-spin 1s linear infinite;\n margin: 0 auto;\n }\n\n @keyframes notification-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .notification-loading-text {\n font-size: 14px;\n color: #6b7280;\n text-align: center;\n margin-top: 12px;\n }\n\n .dark .notification-loading-text {\n color: #cbd5e1;\n }\n ",document.head.appendChild(n)}getIcon(n){const t={success:'<i class="bx bx-check" aria-hidden="true"></i>',error:'<i class="bx bx-x" aria-hidden="true"></i>',warning:'<i class="bx bx-error" aria-hidden="true"></i>',info:'<i class="bx bx-info-circle" aria-hidden="true"></i>',question:'<i class="bx bx-question-mark" aria-hidden="true"></i>'};return t[n]||t.info}getDefaultTitle(n){return{success:"¡Éxito!",error:"Error",warning:"Advertencia",info:"Información",question:"Pregunta"}[n]||"Notificación"}getButtonGradient(n){const t={success:"linear-gradient(135deg, #10b981 0%, #059669 100%)",error:"linear-gradient(135deg, #ef4444 0%, #dc2626 100%)",warning:"linear-gradient(135deg, #f59e0b 0%, #d97706 100%)",info:"linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)",question:"linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)"};return t[n]||t.info}getButtonShadow(n){const t={success:"rgba(16, 185, 129, 0)",error:"rgba(239, 68, 68, 0)",warning:"rgba(245, 159, 11, 0)",info:"rgba(59, 131, 246, 0)",question:"rgba(108, 99, 245, 0)"};return t[n]||t.info}show(n={}){if(this.currentNotification){const n=this.currentNotification;this.currentNotification=null;try{n&&n.parentNode&&n.parentNode.removeChild(n)}catch(n){}}const{type:t="info",title:e=this.getDefaultTitle(t),message:o="",buttonText:i="OK",buttonColor:a=null,onClose:r=null,timer:c=null,allowOutsideClick:s=!0,allowEscapeKey:l=!0,hideButton:d=!1,buttons:u=null}=n,f=!0===n.showCloseButton;try{document.body.style.overflow="hidden"}catch(n){}try{document.documentElement.style.overflow="hidden"}catch(n){}const p=document.createElement("div");p.className="notification-overlay",p.tabIndex=-1,p.setAttribute("role","dialog"),p.setAttribute("aria-modal","true"),p.style.pointerEvents="auto";const m=document.createElement("div");m.className="notification-box";const b=document.createElement("div");b.className=`notification-icon ${t}`,d&&"info"===t?(b.className="notification-loading-container",b.innerHTML='<div class="notification-spinner"></div>',b.style.background="transparent",b.style.boxShadow="none",b.style.width="100px",b.style.height="100px"):b.innerHTML=this.getIcon(t);const h=document.createElement("h3");h.className="notification-title",h.textContent=e;const g=document.createElement("p");g.className="notification-message",g.textContent=o;let x=null;if(n.html||n.content)if(x=document.createElement("div"),x.className="notification-content",n.html)try{x.innerHTML=n.html}catch(t){x.textContent=n.html}else n.content&&n.content instanceof HTMLElement&&x.appendChild(n.content);const y=()=>this.close(r);let w=null,v=null;if(!d)if(Array.isArray(u)&&u.length)v=document.createElement("div"),v.className="notification-button-group",u.forEach(n=>{const e=document.createElement("button");e.className="notification-button",e.textContent=n.text||"OK";const o=n.color||this.getButtonGradient(t),i=n.shadowColor||this.getButtonShadow(t);e.style.background=o,e.style.boxShadow=`0 4px 12px ${i}`,e.addEventListener("click",t=>{t.stopPropagation(),t.preventDefault();try{y().then(()=>{if("function"==typeof n.onClick)try{const t=n.onClick();t&&"function"==typeof t.then&&t.catch(n=>console.error(n))}catch(n){console.error(n)}}).catch(()=>{})}catch(n){console.error(n)}}),e.addEventListener("mouseenter",()=>{e.style.boxShadow=`0 6px 16px ${i}`}),e.addEventListener("mouseleave",()=>{e.style.boxShadow=`0 4px 12px ${i}`}),v.appendChild(e)});else if(n.onConfirm||n.onCancel||n.confirmText||n.cancelText){v=document.createElement("div"),v.className="notification-button-group";const e=n.cancelText||"Cancelar",o=n.confirmText||"Aceptar",i=document.createElement("button");i.className="notification-button",i.textContent=e;const a=n.cancelColor||"linear-gradient(135deg, #9ca3af 0%, #6b7280 100%)",r=n.cancelShadow||"rgba(107,114,128,0.25)";i.style.background=a,i.style.boxShadow=`0 4px 12px ${r}`,i.addEventListener("click",t=>{t.stopPropagation(),t.preventDefault(),y().then(()=>{try{if("function"==typeof n.onCancel){const t=n.onCancel();t&&"function"==typeof t.then&&t.catch(n=>console.error(n))}}catch(n){console.error(n)}}).catch(()=>{})}),i.addEventListener("mouseenter",()=>{i.style.boxShadow=`0 6px 16px ${r}`}),i.addEventListener("mouseleave",()=>{i.style.boxShadow=`0 4px 12px ${r}`});const c=document.createElement("button");c.className="notification-button",c.textContent=o;const s=n.confirmColor||this.getButtonGradient(t),l=n.confirmShadow||this.getButtonShadow(t);c.style.background=s,c.style.boxShadow=`0 4px 12px ${l}`,c.addEventListener("click",async t=>{t.stopPropagation(),t.preventDefault();try{if(await y(),"function"==typeof n.onConfirm){const t=n.onConfirm();t&&"function"==typeof t.then&&await t}}catch(n){console.error(n)}}),c.addEventListener("mouseenter",()=>{c.style.boxShadow=`0 6px 16px ${l}`}),c.addEventListener("mouseleave",()=>{c.style.boxShadow=`0 4px 12px ${l}`}),v.appendChild(i),v.appendChild(c)}else if(i){w=document.createElement("button"),w.className="notification-button",w.textContent=i;const n=a||this.getButtonGradient(t),e=this.getButtonShadow(t);w.style.background=n,w.style.boxShadow=`0 4px 12px ${e}`}let k=null;if(f&&(k=document.createElement("button"),k.setAttribute("aria-label","Cerrar"),k.className="notification-close",k.innerHTML="&times;",k.addEventListener("click",n=>{n.stopPropagation(),y()})),m.appendChild(b),x){const n="notify-desc-"+Date.now();x.id=n,p.setAttribute("aria-describedby",n),m.appendChild(x)}else m.appendChild(h),m.appendChild(g);k&&m.appendChild(k),v?m.appendChild(v):w&&m.appendChild(w),p.appendChild(m),document.body.appendChild(p);const E=p,C=new Promise(n=>{try{E._externalResolve=n}catch(n){}});try{const n=document.getElementById("notify-live");n&&(n.textContent=`${e}: ${o}`)}catch(n){}try{this._lastActiveElement=document.activeElement}catch(n){this._lastActiveElement=null}this.currentNotification=p;try{const n=m.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])');n&&n.length?n[0].focus():w?w.focus():p.focus()}catch(n){try{p.focus()}catch(n){}}const S=n=>{if("Tab"!==n.key)return;const t=Array.from(m.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])')).filter(n=>n instanceof HTMLElement&&null!==n.offsetParent);if(!t.length)return void n.preventDefault();const e=t[0],o=t[t.length-1];n.shiftKey||document.activeElement!==o?n.shiftKey&&document.activeElement===e&&(n.preventDefault(),o.focus()):(n.preventDefault(),e.focus())};E._focusTrap=S,document.addEventListener("keydown",S);const N=n.anim||{},L="number"==typeof N.overlayDuration?N.overlayDuration:150,T=N.overlayEasing||"easeOutQuad",D="number"==typeof N.boxDuration?N.boxDuration:200,_="number"==typeof N.boxDelay?N.boxDelay:50,j=N.boxEasing||"easeOutBack",A="number"==typeof N.boxStartScale?N.boxStartScale:.8,$="number"==typeof N.iconDuration?N.iconDuration:250,B="number"==typeof N.iconDelay?N.iconDelay:100,O="number"==typeof N.iconRotate?N.iconRotate:"success"===t?-90:"error"===t?90:0;if("number"==typeof N.overlayOpacity&&(p.style.backgroundColor=`rgba(0,0,0,${N.overlayOpacity})`),anime({targets:p,opacity:[0,1],duration:L,easing:T}),anime({targets:m,scale:[A,1],opacity:[0,1],duration:D,easing:j,delay:_}),anime({targets:b,scale:[0,1],rotate:[O,0],duration:$,easing:j,delay:B}),w){const n=this.getButtonShadow(t);w.addEventListener("mouseenter",()=>{w.style.boxShadow=`0 6px 16px ${n}`}),w.addEventListener("mouseleave",()=>{w.style.boxShadow=`0 4px 12px ${n}`}),w.addEventListener("click",n=>{n.stopPropagation(),n.preventDefault(),y().catch(()=>{})})}if(s&&p.addEventListener("click",n=>{m.contains(n.target)||y()}),c&&setTimeout(()=>{y()},c),l){const n=t=>{"Escape"===t.key&&(y(),document.removeEventListener("keydown",n))};E._escHandler=n,document.addEventListener("keydown",n)}return C}close(n=null){if(!this.currentNotification)return Promise.resolve();const t=this.currentNotification,e=t,o=t.querySelector(".notification-box");return this.currentNotification=null,anime({targets:o,scale:.8,opacity:0,duration:100,easing:"easeInQuad"}),new Promise(o=>{anime({targets:t,opacity:0,duration:100,easing:"easeInQuad",complete:()=>{try{e&&e._escHandler&&(document.removeEventListener("keydown",e._escHandler),e._escHandler=void 0)}catch(n){}try{e&&e._focusTrap&&(document.removeEventListener("keydown",e._focusTrap),e._focusTrap=void 0)}catch(n){}try{if(e&&"function"==typeof e._externalResolve){try{e._externalResolve()}catch(n){}e._externalResolve=void 0}}catch(n){}try{t&&t.parentNode&&t.parentNode.removeChild(t)}catch(n){try{t.remove()}catch(n){}}if(!this.currentNotification){try{document.body.style.overflow=""}catch(n){}try{document.documentElement.style.overflow=""}catch(n){}}try{this._lastActiveElement&&"function"==typeof this._lastActiveElement.focus&&this._lastActiveElement.focus()}catch(n){}this._lastActiveElement=null,n&&n(),o()}})})}success(n,t=null,e={}){this.show(Object.assign({type:"success",title:t||this.getDefaultTitle("success"),message:n},e))}error(n,t=null,e={}){this.show(Object.assign({type:"error",title:t||this.getDefaultTitle("error"),message:n},e))}warning(n,t=null,e={}){this.show(Object.assign({type:"warning",title:t||this.getDefaultTitle("warning"),message:n},e))}question(n,t=null,e={}){this.show(Object.assign({type:"question",title:t||this.getDefaultTitle("question"),message:n},e))}info(n,t=null,e={}){this.show(Object.assign({type:"info",title:t||this.getDefaultTitle("info"),message:n},e))}loading(n="Cargando...",t="Espera",e={}){const o=Object.assign({type:"info",title:t,message:n,hideButton:!0,allowOutsideClick:!1,allowEscapeKey:!1},e),i=this.show(o);return this._currentLoadingPromise=i,i}closeLoading(n=null){return this._currentLoadingPromise=null,this.close(n)}hide(n=null){return this.close(n)}hiden(n=null){return this.close(n)}_formatTime(n){const t=Math.max(0,Math.floor(n));return`${Math.floor(t/60).toString().padStart(2,"0")}:${(t%60).toString().padStart(2,"0")}`}},t=window;t.notify=n,t.Notification=n}}();
1
+ "use strict";var __rest=this&&this.__rest||function(t,n){var e={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&n.indexOf(o)<0&&(e[o]=t[o]);if(null!=t&&"function"==typeof Object.getOwnPropertySymbols){var i=0;for(o=Object.getOwnPropertySymbols(t);i<o.length;i++)n.indexOf(o[i])<0&&Object.prototype.propertyIsEnumerable.call(t,o[i])&&(e[o[i]]=t[o[i]])}return e};!function(){if("undefined"!=typeof anime)t();else{const n=document.createElement("script");n.src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js",n.onload=t,n.onerror=()=>{console.error("FerNotify: No se pudo cargar anime.js. Por favor, cargalo manualmente.")},document.head.appendChild(n)}function t(){const t=new class{constructor(){this.currentNotification=null,this._lastActiveElement=null,this._currentLoadingPromise=null,this._toastContainers=new Map,this.injectStyles(),this.loadBoxicons()}loadBoxicons(){if(!document.querySelector('link[href*="boxicons"]')){const t=document.createElement("link");t.rel="stylesheet",t.href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css",document.head.appendChild(t)}}injectStyles(){const t=document.createElement("style");t.textContent="\n .notification-overlay {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background-color: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(4px);\n -webkit-backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 9999;\n opacity: 0;\n overflow: hidden;\n }\n\n .notification-box {\n background: white;\n border-radius: 16px;\n padding: 40px 30px;\n max-width: 500px;\n width: 90%;\n max-height: 80vh;\n overflow: auto;\n position: relative;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n transform: scale(0.7);\n opacity: 0;\n }\n\n .notification-content {\n text-align: left;\n margin-bottom: 18px;\n }\n\n .notification-close {\n position: absolute;\n top: 10px;\n right: 10px;\n width: 38px;\n height: 38px;\n border-radius: 8px;\n border: none;\n background: rgba(0,0,0,0.06);\n color: #111827;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n font-size: 18px;\n }\n\n .notification-close:hover {\n background: rgba(0,0,0,0.09);\n }\n\n /* Form controls inside the modal */\n .notification-box input,\n .notification-box textarea,\n .notification-box select {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid #e5e7eb;\n border-radius: 8px;\n background: #ffffff;\n color: #111827;\n font-size: 15px;\n box-sizing: border-box;\n transition: box-shadow 0.15s ease, border-color 0.15s ease;\n }\n\n .notification-box input:focus,\n .notification-box textarea:focus,\n .notification-box select:focus {\n outline: none;\n border-color: #6366f1;\n box-shadow: 0 6px 24px rgba(99,102,241,0.12), 0 0 0 4px rgba(99,102,241,0.06);\n }\n\n .notification-box label { display: block; margin-bottom: 6px; color: #374151; font-weight: 600; }\n\n /* Soporte para tema oscuro con clase .dark (Tailwind darkMode: 'class') */\n /* Esto tiene prioridad sobre prefers-color-scheme para respetar la elección del usuario en la web */\n .dark .notification-box { background: #0f1724 !important; color: #e6eef8 !important; }\n .dark .notification-box input,\n .dark .notification-box textarea,\n .dark .notification-box select {\n background: #0b1220 !important;\n border: 1px solid rgba(255,255,255,0.06) !important;\n color: #e6eef8 !important;\n }\n .dark .notification-box .notification-close { background: rgba(255,255,255,0.03) !important; color: #e6eef8 !important; }\n .dark .notification-overlay { background-color: rgba(0,0,0,0.6) !important; }\n .dark .notification-title { color: #e6eef8 !important; }\n .dark .notification-message { color: #cbd5e1 !important; }\n\n /* Forzar modo claro cuando NO hay clase .dark, ignorando prefers-color-scheme */\n html:not(.dark) .notification-box { background: white !important; color: #111827 !important; }\n html:not(.dark) .notification-box input,\n html:not(.dark) .notification-box textarea,\n html:not(.dark) .notification-box select {\n background: #ffffff !important;\n border: 1px solid #e5e7eb !important;\n color: #111827 !important;\n }\n html:not(.dark) .notification-box .notification-close { background: rgba(0,0,0,0.06) !important; color: #111827 !important; }\n html:not(.dark) .notification-overlay { background-color: rgba(0, 0, 0, 0.4) !important; }\n html:not(.dark) .notification-title { color: #1f2937 !important; }\n html:not(.dark) .notification-message { color: #6b7280 !important; }\n\n .notification-icon {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n margin: 0 auto 25px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 40px;\n position: relative;\n }\n\n .notification-icon::before {\n content: '';\n position: absolute;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n opacity: 0.2;\n }\n\n .notification-icon.success {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n }\n\n .notification-icon.success::before {\n background: #10b981;\n }\n\n .notification-icon.error {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n color: white;\n }\n\n .notification-icon.error::before {\n background: #ef4444;\n }\n\n .notification-icon.warning {\n background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);\n color: white;\n }\n\n .notification-icon.warning::before {\n background: #f59e0b;\n }\n\n .notification-icon.info {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n }\n\n .notification-icon.info::before {\n background: #3b82f6;\n }\n .notification-icon.question {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n }\n\n .notification-icon.question::before {\n background: #3b82f6;\n }\n\n .notification-title {\n font-size: 24px;\n font-weight: 700;\n color: #1f2937;\n margin-bottom: 12px;\n line-height: 1.3;\n }\n\n .notification-message {\n font-size: 16px;\n color: #6b7280;\n line-height: 1.6;\n margin-bottom: 30px;\n }\n\n .notification-button {\n color: white;\n border: none;\n padding: 10px 14px;\n border-radius: 8px;\n font-size: 16px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.3s ease;\n }\n\n .notification-button:hover {\n transform: translateY(-2px);\n filter: brightness(1.1);\n }\n\n .notification-button:active {\n transform: translateY(0);\n }\n\n /* group container for multiple action buttons */\n .notification-button-group {\n display: flex;\n gap: 12px;\n justify-content: center;\n flex-wrap: wrap;\n margin-top: 10px;\n }\n\n .notification-icon-checkmark {\n animation: checkmark-draw 0.6s ease-in-out;\n }\n\n .notification-icon-cross {\n animation: cross-draw 0.5s ease-in-out;\n }\n\n @keyframes checkmark-draw {\n 0% {\n transform: scale(0) rotate(-45deg);\n opacity: 0;\n }\n 50% {\n transform: scale(1.2) rotate(-45deg);\n }\n 100% {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n @keyframes cross-draw {\n 0% {\n transform: scale(0) rotate(-180deg);\n opacity: 0;\n }\n 50% {\n transform: scale(1.2) rotate(-90deg);\n }\n 100% {\n transform: scale(1) rotate(0deg);\n opacity: 1;\n }\n }\n\n /* Loading spinner styles */\n .notification-loading-container {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0 auto;\n }\n\n .notification-spinner {\n width: 60px;\n height: 60px;\n border: 5px solid rgba(99, 102, 241, 0.15);\n border-top-color: #6366f1;\n border-radius: 50%;\n animation: notification-spin 1s linear infinite;\n margin: 0 auto;\n }\n\n @keyframes notification-spin {\n to {\n transform: rotate(360deg);\n }\n }\n\n .notification-loading-text {\n font-size: 14px;\n color: #6b7280;\n text-align: center;\n margin-top: 12px;\n }\n\n .dark .notification-loading-text {\n color: #cbd5e1;\n }\n\n /* ==================== Toast ==================== */\n .notify-toast-container {\n position: fixed;\n z-index: 10000;\n display: flex;\n flex-direction: column;\n gap: 10px;\n pointer-events: none;\n width: 360px;\n max-width: calc(100vw - 40px);\n }\n .notify-toast-top-right { top: 20px; right: 20px; }\n .notify-toast-top-left { top: 20px; left: 20px; }\n .notify-toast-top-center { top: 20px; left: 50%; transform: translateX(-50%); }\n .notify-toast-bottom-right { bottom: 20px; right: 20px; flex-direction: column-reverse; }\n .notify-toast-bottom-left { bottom: 20px; left: 20px; flex-direction: column-reverse; }\n\n .notify-toast {\n background: white;\n border-radius: 12px;\n padding: 14px 40px 14px 14px;\n box-shadow: 0 4px 24px rgba(0,0,0,0.12), 0 1px 4px rgba(0,0,0,0.06);\n display: flex;\n align-items: flex-start;\n gap: 12px;\n pointer-events: auto;\n position: relative;\n overflow: hidden;\n opacity: 0;\n transform: translateX(30px);\n transition: opacity 0.25s ease, transform 0.25s ease;\n }\n .notify-toast-top-left .notify-toast,\n .notify-toast-bottom-left .notify-toast { transform: translateX(-30px); }\n .notify-toast-top-center .notify-toast { transform: translateY(-20px); }\n .notify-toast.notify-toast-visible {\n opacity: 1;\n transform: translateX(0) translateY(0) !important;\n }\n\n .notify-toast-icon {\n width: 36px;\n height: 36px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 20px;\n flex-shrink: 0;\n color: white;\n }\n .notify-toast-icon.success { background: linear-gradient(135deg, #10b981 0%, #059669 100%); }\n .notify-toast-icon.error { background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); }\n .notify-toast-icon.warning { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); }\n .notify-toast-icon.info { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); }\n .notify-toast-icon.question { background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%); }\n\n .notify-toast-content { flex: 1; min-width: 0; }\n .notify-toast-title {\n font-size: 14px;\n font-weight: 700;\n color: #1f2937;\n margin-bottom: 2px;\n line-height: 1.3;\n }\n .notify-toast-message {\n font-size: 13px;\n color: #6b7280;\n line-height: 1.5;\n }\n\n .notify-toast-close {\n position: absolute;\n top: 8px;\n right: 8px;\n width: 24px;\n height: 24px;\n border-radius: 6px;\n border: none;\n background: rgba(0,0,0,0.06);\n color: #6b7280;\n cursor: pointer;\n font-size: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n line-height: 1;\n padding: 0;\n }\n .notify-toast-close:hover { background: rgba(0,0,0,0.1); color: #374151; }\n\n .notify-toast-progress {\n position: absolute;\n bottom: 0;\n left: 0;\n height: 3px;\n width: 100%;\n border-radius: 0 0 0 12px;\n }\n .notify-toast-progress.success { background: #10b981; }\n .notify-toast-progress.error { background: #ef4444; }\n .notify-toast-progress.warning { background: #f59e0b; }\n .notify-toast-progress.info { background: #3b82f6; }\n .notify-toast-progress.question { background: #8b5cf6; }\n\n .dark .notify-toast { background: #0f1724; box-shadow: 0 4px 24px rgba(0,0,0,0.35); }\n .dark .notify-toast-title { color: #e6eef8; }\n .dark .notify-toast-message { color: #cbd5e1; }\n .dark .notify-toast-close { background: rgba(255,255,255,0.06); color: #94a3b8; }\n .dark .notify-toast-close:hover { background: rgba(255,255,255,0.1); color: #e2e8f0; }\n ",document.head.appendChild(t)}getIcon(t){const n={success:'<i class="bx bx-check" aria-hidden="true"></i>',error:'<i class="bx bx-x" aria-hidden="true"></i>',warning:'<i class="bx bx-error" aria-hidden="true"></i>',info:'<i class="bx bx-info-circle" aria-hidden="true"></i>',question:'<i class="bx bx-question-mark" aria-hidden="true"></i>'};return n[t]||n.info}getDefaultTitle(t){return{success:"¡Éxito!",error:"Error",warning:"Advertencia",info:"Información",question:"Pregunta"}[t]||"Notificación"}getButtonGradient(t){const n={success:"linear-gradient(135deg, #10b981 0%, #059669 100%)",error:"linear-gradient(135deg, #ef4444 0%, #dc2626 100%)",warning:"linear-gradient(135deg, #f59e0b 0%, #d97706 100%)",info:"linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)",question:"linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%)"};return n[t]||n.info}getButtonShadow(t){const n={success:"rgba(16, 185, 129, 0)",error:"rgba(239, 68, 68, 0)",warning:"rgba(245, 159, 11, 0)",info:"rgba(59, 131, 246, 0)",question:"rgba(108, 99, 245, 0)"};return n[t]||n.info}show(t={}){if(this.currentNotification){const t=this.currentNotification;this.currentNotification=null;try{t&&t.parentNode&&t.parentNode.removeChild(t)}catch(t){}}const{type:n="info",title:e=this.getDefaultTitle(n),message:o="",buttonText:i="OK",buttonColor:a=null,onClose:r=null,timer:s=null,allowOutsideClick:c=!0,allowEscapeKey:l=!0,hideButton:d=!1,buttons:f=null}=t,u=!0===t.showCloseButton;try{document.body.style.overflow="hidden"}catch(t){}try{document.documentElement.style.overflow="hidden"}catch(t){}const p=document.createElement("div");p.className="notification-overlay",p.tabIndex=-1,p.setAttribute("role","dialog"),p.setAttribute("aria-modal","true"),p.style.pointerEvents="auto";const m=document.createElement("div");m.className="notification-box";const b=document.createElement("div");b.className=`notification-icon ${n}`,d&&"info"===n?(b.className="notification-loading-container",b.innerHTML='<div class="notification-spinner"></div>',b.style.background="transparent",b.style.boxShadow="none",b.style.width="100px",b.style.height="100px"):b.innerHTML=this.getIcon(n);const h=document.createElement("h3");h.className="notification-title",h.textContent=e;const g=document.createElement("p");g.className="notification-message",g.textContent=o;let x=null;if(t.html||t.content)if(x=document.createElement("div"),x.className="notification-content",t.html)try{x.innerHTML=t.html}catch(n){x.textContent=t.html}else t.content&&t.content instanceof HTMLElement&&x.appendChild(t.content);const y=()=>this.close(r);let w=null,v=null;if(!d)if(Array.isArray(f)&&f.length)v=document.createElement("div"),v.className="notification-button-group",f.forEach(t=>{const e=document.createElement("button");e.className="notification-button",e.textContent=t.text||"OK";const o=t.color||this.getButtonGradient(n),i=t.shadowColor||this.getButtonShadow(n);e.style.background=o,e.style.boxShadow=`0 4px 12px ${i}`,e.addEventListener("click",n=>{n.stopPropagation(),n.preventDefault();try{y().then(()=>{if("function"==typeof t.onClick)try{const n=t.onClick();n&&"function"==typeof n.then&&n.catch(t=>console.error(t))}catch(t){console.error(t)}}).catch(()=>{})}catch(t){console.error(t)}}),e.addEventListener("mouseenter",()=>{e.style.boxShadow=`0 6px 16px ${i}`}),e.addEventListener("mouseleave",()=>{e.style.boxShadow=`0 4px 12px ${i}`}),v.appendChild(e)});else if(t.onConfirm||t.onCancel||t.confirmText||t.cancelText){v=document.createElement("div"),v.className="notification-button-group";const e=t.cancelText||"Cancelar",o=t.confirmText||"Aceptar",i=document.createElement("button");i.className="notification-button",i.textContent=e;const a=t.cancelColor||"linear-gradient(135deg, #9ca3af 0%, #6b7280 100%)",r=t.cancelShadow||"rgba(107,114,128,0.25)";i.style.background=a,i.style.boxShadow=`0 4px 12px ${r}`,i.addEventListener("click",n=>{n.stopPropagation(),n.preventDefault(),y().then(()=>{try{if("function"==typeof t.onCancel){const n=t.onCancel();n&&"function"==typeof n.then&&n.catch(t=>console.error(t))}}catch(t){console.error(t)}}).catch(()=>{})}),i.addEventListener("mouseenter",()=>{i.style.boxShadow=`0 6px 16px ${r}`}),i.addEventListener("mouseleave",()=>{i.style.boxShadow=`0 4px 12px ${r}`});const s=document.createElement("button");s.className="notification-button",s.textContent=o;const c=t.confirmColor||this.getButtonGradient(n),l=t.confirmShadow||this.getButtonShadow(n);s.style.background=c,s.style.boxShadow=`0 4px 12px ${l}`,s.addEventListener("click",async n=>{n.stopPropagation(),n.preventDefault();try{if(await y(),"function"==typeof t.onConfirm){const n=t.onConfirm();n&&"function"==typeof n.then&&await n}}catch(t){console.error(t)}}),s.addEventListener("mouseenter",()=>{s.style.boxShadow=`0 6px 16px ${l}`}),s.addEventListener("mouseleave",()=>{s.style.boxShadow=`0 4px 12px ${l}`}),v.appendChild(i),v.appendChild(s)}else if(i){w=document.createElement("button"),w.className="notification-button",w.textContent=i;const t=a||this.getButtonGradient(n),e=this.getButtonShadow(n);w.style.background=t,w.style.boxShadow=`0 4px 12px ${e}`}let k=null;if(u&&(k=document.createElement("button"),k.setAttribute("aria-label","Cerrar"),k.className="notification-close",k.innerHTML="&times;",k.addEventListener("click",t=>{t.stopPropagation(),y()})),m.appendChild(b),x){const t="notify-desc-"+Date.now();x.id=t,p.setAttribute("aria-describedby",t),m.appendChild(x)}else m.appendChild(h),m.appendChild(g);k&&m.appendChild(k),v?m.appendChild(v):w&&m.appendChild(w),p.appendChild(m),document.body.appendChild(p);const E=p,C=new Promise(t=>{try{E._externalResolve=t}catch(t){}});try{const t=document.getElementById("notify-live");t&&(t.textContent=`${e}: ${o}`)}catch(t){}try{this._lastActiveElement=document.activeElement}catch(t){this._lastActiveElement=null}this.currentNotification=p;try{const t=m.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])');t&&t.length?t[0].focus():w?w.focus():p.focus()}catch(t){try{p.focus()}catch(t){}}const N=t=>{if("Tab"!==t.key)return;const n=Array.from(m.querySelectorAll('a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex="-1"])')).filter(t=>t instanceof HTMLElement&&null!==t.offsetParent);if(!n.length)return void t.preventDefault();const e=n[0],o=n[n.length-1];t.shiftKey||document.activeElement!==o?t.shiftKey&&document.activeElement===e&&(t.preventDefault(),o.focus()):(t.preventDefault(),e.focus())};E._focusTrap=N,document.addEventListener("keydown",N);const T=t.anim||{},S="number"==typeof T.overlayDuration?T.overlayDuration:150,L=T.overlayEasing||"easeOutQuad",j="number"==typeof T.boxDuration?T.boxDuration:200,O="number"==typeof T.boxDelay?T.boxDelay:50,_=T.boxEasing||"easeOutBack",D="number"==typeof T.boxStartScale?T.boxStartScale:.8,$="number"==typeof T.iconDuration?T.iconDuration:250,A="number"==typeof T.iconDelay?T.iconDelay:100,q="number"==typeof T.iconRotate?T.iconRotate:"success"===n?-90:"error"===n?90:0;if("number"==typeof T.overlayOpacity&&(p.style.backgroundColor=`rgba(0,0,0,${T.overlayOpacity})`),anime({targets:p,opacity:[0,1],duration:S,easing:L}),anime({targets:m,scale:[D,1],opacity:[0,1],duration:j,easing:_,delay:O}),anime({targets:b,scale:[0,1],rotate:[q,0],duration:$,easing:_,delay:A}),w){const t=this.getButtonShadow(n);w.addEventListener("mouseenter",()=>{w.style.boxShadow=`0 6px 16px ${t}`}),w.addEventListener("mouseleave",()=>{w.style.boxShadow=`0 4px 12px ${t}`}),w.addEventListener("click",t=>{t.stopPropagation(),t.preventDefault(),y().catch(()=>{})})}if(c&&p.addEventListener("click",t=>{m.contains(t.target)||y()}),s&&setTimeout(()=>{y()},s),l){const t=n=>{"Escape"===n.key&&(y(),document.removeEventListener("keydown",t))};E._escHandler=t,document.addEventListener("keydown",t)}return C}close(t=null){if(!this.currentNotification)return Promise.resolve();const n=this.currentNotification,e=n,o=n.querySelector(".notification-box");return this.currentNotification=null,anime({targets:o,scale:.8,opacity:0,duration:100,easing:"easeInQuad"}),new Promise(o=>{anime({targets:n,opacity:0,duration:100,easing:"easeInQuad",complete:()=>{try{e&&e._escHandler&&(document.removeEventListener("keydown",e._escHandler),e._escHandler=void 0)}catch(t){}try{e&&e._focusTrap&&(document.removeEventListener("keydown",e._focusTrap),e._focusTrap=void 0)}catch(t){}try{if(e&&"function"==typeof e._externalResolve){try{e._externalResolve()}catch(t){}e._externalResolve=void 0}}catch(t){}try{n&&n.parentNode&&n.parentNode.removeChild(n)}catch(t){try{n.remove()}catch(t){}}if(!this.currentNotification){try{document.body.style.overflow=""}catch(t){}try{document.documentElement.style.overflow=""}catch(t){}}try{this._lastActiveElement&&"function"==typeof this._lastActiveElement.focus&&this._lastActiveElement.focus()}catch(t){}this._lastActiveElement=null,t&&t(),o()}})})}success(t,n=null,e={}){this.show(Object.assign({type:"success",title:n||this.getDefaultTitle("success"),message:t},e))}error(t,n=null,e={}){this.show(Object.assign({type:"error",title:n||this.getDefaultTitle("error"),message:t},e))}warning(t,n=null,e={}){this.show(Object.assign({type:"warning",title:n||this.getDefaultTitle("warning"),message:t},e))}question(t,n=null,e={}){this.show(Object.assign({type:"question",title:n||this.getDefaultTitle("question"),message:t},e))}info(t,n=null,e={}){this.show(Object.assign({type:"info",title:n||this.getDefaultTitle("info"),message:t},e))}loading(t="Cargando...",n="Espera",e={}){const o=Object.assign({type:"info",title:n,message:t,hideButton:!0,allowOutsideClick:!1,allowEscapeKey:!1},e),i=this.show(o);return this._currentLoadingPromise=i,i}closeLoading(t=null){return this._currentLoadingPromise=null,this.close(t)}hide(t=null){return this.close(t)}hiden(t=null){return this.close(t)}_formatTime(t){const n=Math.max(0,Math.floor(t));return`${Math.floor(n/60).toString().padStart(2,"0")}:${(n%60).toString().padStart(2,"0")}`}showToast(t,n={}){var e;const o=n.type||"info",i=null!==(e=n.title)&&void 0!==e?e:null,a="number"==typeof n.duration?n.duration:4e3,r=n.position||"top-right",s=!1!==n.showProgress;let c=this._toastContainers.get(r);c&&document.body.contains(c)||(c=document.createElement("div"),c.className=`notify-toast-container notify-toast-${r}`,document.body.appendChild(c),this._toastContainers.set(r,c));const l=r.startsWith("bottom"),d="top-center"===r,f=document.createElement("div");f.className="notify-toast";const u=document.createElement("div");u.className=`notify-toast-icon ${o}`,u.innerHTML=this.getIcon(o);const p=document.createElement("div");if(p.className="notify-toast-content",i){const t=document.createElement("div");t.className="notify-toast-title",t.textContent=i,p.appendChild(t)}const m=document.createElement("div");m.className="notify-toast-message",m.textContent=t,p.appendChild(m);const b=document.createElement("button");b.className="notify-toast-close",b.setAttribute("aria-label","Cerrar notificación"),b.innerHTML="&times;",f.appendChild(u),f.appendChild(p),f.appendChild(b);let h=null;a>0&&s&&(h=document.createElement("div"),h.className=`notify-toast-progress ${o}`,f.appendChild(h)),l||d?c.appendChild(f):c.insertBefore(f,c.firstChild);let g=!1,x=null,y=a,w=0;const v=()=>{g||(g=!0,f.classList.remove("notify-toast-visible"),setTimeout(()=>{f.parentNode&&f.parentNode.removeChild(f)},300))},k=t=>{w=Date.now(),x=setTimeout(v,t),h&&(h.style.transition=`width ${t}ms linear`,h.style.width="0%")};b.addEventListener("click",v),requestAnimationFrame(()=>{requestAnimationFrame(()=>{f.classList.add("notify-toast-visible"),a>0&&k(a)})}),a>0&&(f.addEventListener("mouseenter",()=>{if(g||null===x)return;clearTimeout(x),x=null;const t=Date.now()-w;if(y=Math.max(0,y-t),h){const t=y/a*100;h.style.transition="none",h.style.width=`${t}%`}}),f.addEventListener("mouseleave",()=>{g||y<=0||k(y)}))}toast(t,n={}){if("string"==typeof t)this.showToast(t,n);else{const{message:n=""}=t,e=__rest(t,["message"]);this.showToast(n,e)}}toastSuccess(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"success",title:null!=n?n:e.title}))}toastError(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"error",title:null!=n?n:e.title}))}toastWarning(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"warning",title:null!=n?n:e.title}))}toastInfo(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"info",title:null!=n?n:e.title}))}toastQuestion(t,n,e={}){this.showToast(t,Object.assign(Object.assign({},e),{type:"question",title:null!=n?n:e.title}))}},n=window;n.notify=t,n.Notification=t}}();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fernotify",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "description": "Sistema moderno de notificaciones con animaciones fluidas y soporte completo de Dark Mode",
5
5
  "main": "dist/notification-system.js",
6
6
  "module": "dist/notification-system.esm.js",