fernotify 1.2.9 → 1.2.10
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
|
@@ -226,10 +226,12 @@ notify.toastQuestion('Nueva solicitud pendiente.');
|
|
|
226
226
|
|
|
227
227
|
// Método genérico con opciones completas
|
|
228
228
|
notify.toast('Mensaje aquí', {
|
|
229
|
-
type: 'success', // 'success' | 'error' | 'warning' | 'info' | 'question'
|
|
229
|
+
type: 'success', // 'success' | 'error' | 'warning' | 'info' | 'question' | 'loading'
|
|
230
230
|
title: 'Título opcional',
|
|
231
231
|
duration: 4000, // ms hasta auto-cierre (0 = sin auto-cierre, default: 4000)
|
|
232
|
-
position: 'top-right'
|
|
232
|
+
position: 'top-right', // 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left'
|
|
233
|
+
id: 'my-toast', // ID para deduplicación (optional)
|
|
234
|
+
closeable: true // false = oculta el botón × (default: true)
|
|
233
235
|
});
|
|
234
236
|
```
|
|
235
237
|
|
|
@@ -241,6 +243,48 @@ notify.toast('Mensaje aquí', {
|
|
|
241
243
|
- Animación de entrada/salida suave
|
|
242
244
|
- Soporte completo de dark mode
|
|
243
245
|
|
|
246
|
+
### Toast de carga 🔄
|
|
247
|
+
|
|
248
|
+
Muestra un toast con spinner para operaciones asíncronas. Solo puede existir uno a la vez y no se puede cerrar manualmente; ciérralo con `closeToastLoading()`.
|
|
249
|
+
|
|
250
|
+
```javascript
|
|
251
|
+
async function fetchData() {
|
|
252
|
+
notify.toastLoading('Obteniendo datos...', 'Cargando');
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
const res = await fetch('/api/data');
|
|
256
|
+
const data = await res.json();
|
|
257
|
+
notify.closeToastLoading();
|
|
258
|
+
notify.toastSuccess('Datos cargados correctamente');
|
|
259
|
+
} catch {
|
|
260
|
+
notify.closeToastLoading();
|
|
261
|
+
notify.toastError('No se pudieron cargar los datos');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
fetchData();
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```javascript
|
|
269
|
+
// Firma completa
|
|
270
|
+
notify.toastLoading(message?, title?, options?)
|
|
271
|
+
notify.closeToastLoading()
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Deduplicación de toasts por ID
|
|
275
|
+
|
|
276
|
+
Asigna un `id` a un toast para evitar duplicados. Si ya hay un toast visible con ese ID, se resetea su cuenta regresiva en lugar de crear uno nuevo.
|
|
277
|
+
|
|
278
|
+
```javascript
|
|
279
|
+
// Aunque el usuario haga clic muchas veces, solo existe un toast
|
|
280
|
+
button.addEventListener('click', () => {
|
|
281
|
+
notify.toastError('Email o contraseña incorrectos', 'Error', {
|
|
282
|
+
id: 'login-error',
|
|
283
|
+
duration: 4000
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
244
288
|
### Personalización de Animaciones
|
|
245
289
|
|
|
246
290
|
```javascript
|
|
@@ -45,6 +45,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
45
45
|
this._lastActiveElement = null;
|
|
46
46
|
this._currentLoadingPromise = null;
|
|
47
47
|
this._toastContainers = new Map();
|
|
48
|
+
this._toastInstances = new Map();
|
|
48
49
|
this.injectStyles();
|
|
49
50
|
this.loadBoxicons();
|
|
50
51
|
}
|
|
@@ -408,6 +409,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
408
409
|
.notify-toast-icon.warning { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); }
|
|
409
410
|
.notify-toast-icon.info { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); }
|
|
410
411
|
.notify-toast-icon.question { background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%); }
|
|
412
|
+
.notify-toast-icon.loading { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); }
|
|
411
413
|
|
|
412
414
|
.notify-toast-content { flex: 1; min-width: 0; }
|
|
413
415
|
.notify-toast-title {
|
|
@@ -416,11 +418,13 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
416
418
|
color: #1f2937;
|
|
417
419
|
margin-bottom: 2px;
|
|
418
420
|
line-height: 1.3;
|
|
421
|
+
cursor: default;
|
|
419
422
|
}
|
|
420
423
|
.notify-toast-message {
|
|
421
424
|
font-size: 13px;
|
|
422
425
|
color: #6b7280;
|
|
423
426
|
line-height: 1.5;
|
|
427
|
+
cursor: default;
|
|
424
428
|
}
|
|
425
429
|
|
|
426
430
|
.notify-toast-close {
|
|
@@ -443,6 +447,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
443
447
|
}
|
|
444
448
|
.notify-toast-close:hover { background: rgba(0,0,0,0.1); color: #374151; }
|
|
445
449
|
|
|
450
|
+
/* Sin botón de cierre: reducir padding derecho */
|
|
451
|
+
.notify-toast.notify-toast-no-close { padding-right: 14px; }
|
|
452
|
+
|
|
446
453
|
.notify-toast-progress {
|
|
447
454
|
position: absolute;
|
|
448
455
|
bottom: 0;
|
|
@@ -456,12 +463,41 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
456
463
|
.notify-toast-progress.warning { background: #f59e0b; }
|
|
457
464
|
.notify-toast-progress.info { background: #3b82f6; }
|
|
458
465
|
.notify-toast-progress.question { background: #8b5cf6; }
|
|
466
|
+
.notify-toast-progress.loading { background: #6366f1; }
|
|
467
|
+
|
|
468
|
+
/* Spinner para toast de carga */
|
|
469
|
+
.notify-toast-spinner {
|
|
470
|
+
width: 18px;
|
|
471
|
+
height: 18px;
|
|
472
|
+
border: 2.5px solid rgba(255,255,255,0.35);
|
|
473
|
+
border-top-color: white;
|
|
474
|
+
border-radius: 50%;
|
|
475
|
+
animation: notification-spin 0.8s linear infinite;
|
|
476
|
+
flex-shrink: 0;
|
|
477
|
+
}
|
|
459
478
|
|
|
460
479
|
.dark .notify-toast { background: #0f1724; box-shadow: 0 4px 24px rgba(0,0,0,0.35); }
|
|
461
480
|
.dark .notify-toast-title { color: #e6eef8; }
|
|
462
481
|
.dark .notify-toast-message { color: #cbd5e1; }
|
|
463
482
|
.dark .notify-toast-close { background: rgba(255,255,255,0.06); color: #94a3b8; }
|
|
464
483
|
.dark .notify-toast-close:hover { background: rgba(255,255,255,0.1); color: #e2e8f0; }
|
|
484
|
+
|
|
485
|
+
/* Respeta la preferencia de movimiento reducido del sistema */
|
|
486
|
+
@media (prefers-reduced-motion: reduce) {
|
|
487
|
+
.notify-toast {
|
|
488
|
+
transition: opacity 0.1s ease !important;
|
|
489
|
+
transform: none !important;
|
|
490
|
+
}
|
|
491
|
+
.notify-toast.notify-toast-visible {
|
|
492
|
+
transform: none !important;
|
|
493
|
+
}
|
|
494
|
+
.notify-toast-spinner {
|
|
495
|
+
animation-duration: 1.5s !important;
|
|
496
|
+
}
|
|
497
|
+
.notify-toast-progress {
|
|
498
|
+
transition: none !important;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
465
501
|
`;
|
|
466
502
|
document.head.appendChild(style);
|
|
467
503
|
}
|
|
@@ -471,7 +507,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
471
507
|
'error': '<i class="bx bx-x" aria-hidden="true"></i>',
|
|
472
508
|
'warning': '<i class="bx bx-error" aria-hidden="true"></i>',
|
|
473
509
|
'info': '<i class="bx bx-info-circle" aria-hidden="true"></i>',
|
|
474
|
-
'question': '<i class="bx bx-question-mark" aria-hidden="true"></i>'
|
|
510
|
+
'question': '<i class="bx bx-question-mark" aria-hidden="true"></i>',
|
|
511
|
+
'loading': '<div class="notify-toast-spinner" aria-hidden="true"></div>'
|
|
475
512
|
};
|
|
476
513
|
return icons[type] || icons.info;
|
|
477
514
|
}
|
|
@@ -969,16 +1006,27 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
969
1006
|
return `${mm}:${ss}`;
|
|
970
1007
|
}
|
|
971
1008
|
showToast(message, options = {}) {
|
|
972
|
-
var _a;
|
|
1009
|
+
var _a, _b;
|
|
973
1010
|
const type = options.type || 'info';
|
|
974
1011
|
const title = (_a = options.title) !== null && _a !== void 0 ? _a : null;
|
|
975
1012
|
const duration = typeof options.duration === 'number' ? options.duration : 4000;
|
|
976
1013
|
const position = options.position || 'top-right';
|
|
977
1014
|
const showProgress = options.showProgress !== false;
|
|
1015
|
+
const toastId = (_b = options.id) !== null && _b !== void 0 ? _b : null;
|
|
1016
|
+
const closeable = options.closeable !== false;
|
|
1017
|
+
// Deduplicación: si ya existe un toast con este ID, resetear su cuenta regresiva
|
|
1018
|
+
if (toastId !== null) {
|
|
1019
|
+
const existing = this._toastInstances.get(toastId);
|
|
1020
|
+
if (existing) {
|
|
1021
|
+
existing.reset(duration);
|
|
1022
|
+
return;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
978
1025
|
let container = this._toastContainers.get(position);
|
|
979
1026
|
if (!container || !document.body.contains(container)) {
|
|
980
1027
|
container = document.createElement('div');
|
|
981
1028
|
container.className = `notify-toast-container notify-toast-${position}`;
|
|
1029
|
+
container.setAttribute('aria-label', 'Notificaciones');
|
|
982
1030
|
document.body.appendChild(container);
|
|
983
1031
|
this._toastContainers.set(position, container);
|
|
984
1032
|
}
|
|
@@ -986,6 +1034,20 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
986
1034
|
const isCenter = position === 'top-center';
|
|
987
1035
|
const toast = document.createElement('div');
|
|
988
1036
|
toast.className = 'notify-toast';
|
|
1037
|
+
if (!closeable) {
|
|
1038
|
+
toast.classList.add('notify-toast-no-close');
|
|
1039
|
+
}
|
|
1040
|
+
// Accesibilidad: role + aria-live según la urgencia del tipo
|
|
1041
|
+
// role="alert" implica aria-live="assertive" + aria-atomic="true" → lector lo interrumpe
|
|
1042
|
+
// role="status" implica aria-live="polite" + aria-atomic="true" → lector espera pausa
|
|
1043
|
+
if (type === 'error' || type === 'warning') {
|
|
1044
|
+
toast.setAttribute('role', 'alert');
|
|
1045
|
+
}
|
|
1046
|
+
else {
|
|
1047
|
+
toast.setAttribute('role', 'status');
|
|
1048
|
+
}
|
|
1049
|
+
toast.setAttribute('aria-atomic', 'true');
|
|
1050
|
+
toast.setAttribute('aria-live', type === 'error' || type === 'warning' ? 'assertive' : 'polite');
|
|
989
1051
|
const iconEl = document.createElement('div');
|
|
990
1052
|
iconEl.className = `notify-toast-icon ${type}`;
|
|
991
1053
|
iconEl.innerHTML = this.getIcon(type);
|
|
@@ -1001,17 +1063,22 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1001
1063
|
msgEl.className = 'notify-toast-message';
|
|
1002
1064
|
msgEl.textContent = message;
|
|
1003
1065
|
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 = '×';
|
|
1008
1066
|
toast.appendChild(iconEl);
|
|
1009
1067
|
toast.appendChild(contentEl);
|
|
1010
|
-
|
|
1068
|
+
if (closeable) {
|
|
1069
|
+
const closeBtn = document.createElement('button');
|
|
1070
|
+
closeBtn.className = 'notify-toast-close';
|
|
1071
|
+
closeBtn.setAttribute('aria-label', 'Cerrar notificación');
|
|
1072
|
+
closeBtn.innerHTML = '×';
|
|
1073
|
+
closeBtn.addEventListener('click', removeToast);
|
|
1074
|
+
toast.appendChild(closeBtn);
|
|
1075
|
+
}
|
|
1011
1076
|
let progressEl = null;
|
|
1012
1077
|
if (duration > 0 && showProgress) {
|
|
1013
1078
|
progressEl = document.createElement('div');
|
|
1014
1079
|
progressEl.className = `notify-toast-progress ${type}`;
|
|
1080
|
+
progressEl.setAttribute('role', 'progressbar');
|
|
1081
|
+
progressEl.setAttribute('aria-hidden', 'true'); // decorativo: el timer no añade info que el usuario necesite leer
|
|
1015
1082
|
toast.appendChild(progressEl);
|
|
1016
1083
|
}
|
|
1017
1084
|
if (isBottom || isCenter) {
|
|
@@ -1024,19 +1091,34 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1024
1091
|
let timerId = null;
|
|
1025
1092
|
let remaining = duration;
|
|
1026
1093
|
let timerStartedAt = 0;
|
|
1027
|
-
|
|
1094
|
+
function removeToast() {
|
|
1028
1095
|
if (dismissed)
|
|
1029
|
-
return;
|
|
1096
|
+
return Promise.resolve();
|
|
1030
1097
|
dismissed = true;
|
|
1098
|
+
// Si el foco estaba dentro del toast, sacarlo antes de que el nodo desaparezca
|
|
1099
|
+
// para evitar que el foco se pierda silenciosamente en el documento
|
|
1100
|
+
if (toast.contains(document.activeElement)) {
|
|
1101
|
+
try {
|
|
1102
|
+
document.activeElement.blur();
|
|
1103
|
+
}
|
|
1104
|
+
catch (e) { }
|
|
1105
|
+
}
|
|
1031
1106
|
toast.classList.remove('notify-toast-visible');
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
toast.parentNode
|
|
1035
|
-
|
|
1036
|
-
|
|
1107
|
+
return new Promise(resolve => {
|
|
1108
|
+
setTimeout(() => {
|
|
1109
|
+
if (toast.parentNode)
|
|
1110
|
+
toast.parentNode.removeChild(toast);
|
|
1111
|
+
resolve();
|
|
1112
|
+
}, 300);
|
|
1113
|
+
});
|
|
1114
|
+
}
|
|
1037
1115
|
const startCountdown = (ms) => {
|
|
1038
1116
|
timerStartedAt = Date.now();
|
|
1039
|
-
timerId = setTimeout(
|
|
1117
|
+
timerId = setTimeout(() => {
|
|
1118
|
+
if (toastId !== null)
|
|
1119
|
+
this._toastInstances.delete(toastId);
|
|
1120
|
+
removeToast();
|
|
1121
|
+
}, ms);
|
|
1040
1122
|
if (progressEl) {
|
|
1041
1123
|
progressEl.style.transition = `width ${ms}ms linear`;
|
|
1042
1124
|
progressEl.style.width = '0%';
|
|
@@ -1060,7 +1142,46 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1060
1142
|
return;
|
|
1061
1143
|
startCountdown(remaining);
|
|
1062
1144
|
};
|
|
1063
|
-
|
|
1145
|
+
const resetCountdown = (newDuration) => {
|
|
1146
|
+
if (dismissed)
|
|
1147
|
+
return;
|
|
1148
|
+
if (timerId !== null) {
|
|
1149
|
+
clearTimeout(timerId);
|
|
1150
|
+
timerId = null;
|
|
1151
|
+
}
|
|
1152
|
+
remaining = newDuration;
|
|
1153
|
+
if (newDuration > 0) {
|
|
1154
|
+
if (progressEl) {
|
|
1155
|
+
progressEl.style.transition = 'none';
|
|
1156
|
+
progressEl.style.width = '100%';
|
|
1157
|
+
// Forzar reflow para que la transición se aplique desde el inicio
|
|
1158
|
+
void progressEl.offsetWidth;
|
|
1159
|
+
}
|
|
1160
|
+
startCountdown(newDuration);
|
|
1161
|
+
}
|
|
1162
|
+
else if (progressEl) {
|
|
1163
|
+
progressEl.style.transition = 'none';
|
|
1164
|
+
progressEl.style.width = '100%';
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
if (toastId !== null) {
|
|
1168
|
+
const silentDismiss = () => {
|
|
1169
|
+
if (dismissed)
|
|
1170
|
+
return;
|
|
1171
|
+
dismissed = true;
|
|
1172
|
+
if (timerId !== null)
|
|
1173
|
+
clearTimeout(timerId);
|
|
1174
|
+
if (toast.contains(document.activeElement)) {
|
|
1175
|
+
try {
|
|
1176
|
+
document.activeElement.blur();
|
|
1177
|
+
}
|
|
1178
|
+
catch (e) { }
|
|
1179
|
+
}
|
|
1180
|
+
if (toast.parentNode)
|
|
1181
|
+
toast.parentNode.removeChild(toast);
|
|
1182
|
+
};
|
|
1183
|
+
this._toastInstances.set(toastId, { reset: resetCountdown, dismiss: removeToast, _silentDismiss: silentDismiss });
|
|
1184
|
+
}
|
|
1064
1185
|
requestAnimationFrame(() => {
|
|
1065
1186
|
requestAnimationFrame(() => {
|
|
1066
1187
|
toast.classList.add('notify-toast-visible');
|
|
@@ -1069,7 +1190,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1069
1190
|
}
|
|
1070
1191
|
});
|
|
1071
1192
|
});
|
|
1072
|
-
if (duration > 0) {
|
|
1193
|
+
if (duration > 0 && closeable) {
|
|
1073
1194
|
toast.addEventListener('mouseenter', pauseCountdown);
|
|
1074
1195
|
toast.addEventListener('mouseleave', resumeCountdown);
|
|
1075
1196
|
}
|
|
@@ -1098,6 +1219,38 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1098
1219
|
toastQuestion(message, title, options = {}) {
|
|
1099
1220
|
this.showToast(message, Object.assign(Object.assign({}, options), { type: 'question', title: title !== null && title !== void 0 ? title : options.title }));
|
|
1100
1221
|
}
|
|
1222
|
+
/**
|
|
1223
|
+
* Muestra un toast de carga con spinner.
|
|
1224
|
+
* - No se puede cerrar manualmente (closeable: false por defecto).
|
|
1225
|
+
* - No tiene cuenta regresiva (duration: 0 por defecto).
|
|
1226
|
+
* - Solo puede existir uno a la vez (id '__loading__').
|
|
1227
|
+
* Ciérralo con notify.closeToastLoading().
|
|
1228
|
+
*/
|
|
1229
|
+
toastLoading(message = 'Cargando...', title, options = {}) {
|
|
1230
|
+
this.showToast(message, Object.assign(Object.assign({ position: 'top-right' }, options), { type: 'loading', title: title !== null && title !== void 0 ? title : options.title, id: '__loading__', closeable: false, duration: 0, showProgress: false }));
|
|
1231
|
+
}
|
|
1232
|
+
/** Cierra el toast de carga activo (si existe). Devuelve una Promise que resuelve cuando la animación de salida termina (≈300 ms). */
|
|
1233
|
+
closeToastLoading() {
|
|
1234
|
+
const entry = this._toastInstances.get('__loading__');
|
|
1235
|
+
if (entry) {
|
|
1236
|
+
this._toastInstances.delete('__loading__');
|
|
1237
|
+
return entry.dismiss();
|
|
1238
|
+
}
|
|
1239
|
+
return Promise.resolve();
|
|
1240
|
+
}
|
|
1241
|
+
/**
|
|
1242
|
+
* Reemplaza el toast de carga activo por un toast de resultado en el mismo lugar,
|
|
1243
|
+
* sin animación de salida/entrada — no hay solapamiento ni hueco visual.
|
|
1244
|
+
* Si no existe un toast de carga activo, simplemente muestra un toast normal.
|
|
1245
|
+
*/
|
|
1246
|
+
replaceToastLoading(message, options = {}) {
|
|
1247
|
+
const entry = this._toastInstances.get('__loading__');
|
|
1248
|
+
if (entry) {
|
|
1249
|
+
this._toastInstances.delete('__loading__');
|
|
1250
|
+
entry._silentDismiss();
|
|
1251
|
+
}
|
|
1252
|
+
this.showToast(message, options);
|
|
1253
|
+
}
|
|
1101
1254
|
}
|
|
1102
1255
|
const notifyInstance = new NotificationSystem();
|
|
1103
1256
|
const w = window;
|
|
@@ -1 +1 @@
|
|
|
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="×",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="×",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
|
+
"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._toastInstances=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 .notify-toast-icon.loading { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 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 cursor: default;\n }\n .notify-toast-message {\n font-size: 13px;\n color: #6b7280;\n line-height: 1.5;\n cursor: default;\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 /* Sin botón de cierre: reducir padding derecho */\n .notify-toast.notify-toast-no-close { padding-right: 14px; }\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 .notify-toast-progress.loading { background: #6366f1; }\n\n /* Spinner para toast de carga */\n .notify-toast-spinner {\n width: 18px;\n height: 18px;\n border: 2.5px solid rgba(255,255,255,0.35);\n border-top-color: white;\n border-radius: 50%;\n animation: notification-spin 0.8s linear infinite;\n flex-shrink: 0;\n }\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\n /* Respeta la preferencia de movimiento reducido del sistema */\n @media (prefers-reduced-motion: reduce) {\n .notify-toast {\n transition: opacity 0.1s ease !important;\n transform: none !important;\n }\n .notify-toast.notify-toast-visible {\n transform: none !important;\n }\n .notify-toast-spinner {\n animation-duration: 1.5s !important;\n }\n .notify-toast-progress {\n transition: none !important;\n }\n }\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>',loading:'<div class="notify-toast-spinner" aria-hidden="true"></div>'};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 g=document.createElement("h3");g.className="notification-title",g.textContent=e;const h=document.createElement("p");h.className="notification-message",h.textContent=o;let y=null;if(t.html||t.content)if(y=document.createElement("div"),y.className="notification-content",t.html)try{y.innerHTML=t.html}catch(n){y.textContent=t.html}else t.content&&t.content instanceof HTMLElement&&y.appendChild(t.content);const x=()=>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{x().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(),x().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 x(),"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="×",k.addEventListener("click",t=>{t.stopPropagation(),x()})),m.appendChild(b),y){const t="notify-desc-"+Date.now();y.id=t,p.setAttribute("aria-describedby",t),m.appendChild(y)}else m.appendChild(g),m.appendChild(h);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 _=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=_,document.addEventListener("keydown",_);const N=t.anim||{},T="number"==typeof N.overlayDuration?N.overlayDuration:150,S=N.overlayEasing||"easeOutQuad",L="number"==typeof N.boxDuration?N.boxDuration:200,j="number"==typeof N.boxDelay?N.boxDelay:50,O=N.boxEasing||"easeOutBack",D="number"==typeof N.boxStartScale?N.boxStartScale:.8,A="number"==typeof N.iconDuration?N.iconDuration:250,$="number"==typeof N.iconDelay?N.iconDelay:100,P="number"==typeof N.iconRotate?N.iconRotate:"success"===n?-90:"error"===n?90:0;if("number"==typeof N.overlayOpacity&&(p.style.backgroundColor=`rgba(0,0,0,${N.overlayOpacity})`),anime({targets:p,opacity:[0,1],duration:T,easing:S}),anime({targets:m,scale:[D,1],opacity:[0,1],duration:L,easing:O,delay:j}),anime({targets:b,scale:[0,1],rotate:[P,0],duration:A,easing:O,delay:$}),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(),x().catch(()=>{})})}if(c&&p.addEventListener("click",t=>{m.contains(t.target)||x()}),s&&setTimeout(()=>{x()},s),l){const t=n=>{"Escape"===n.key&&(x(),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,o;const i=n.type||"info",a=null!==(e=n.title)&&void 0!==e?e:null,r="number"==typeof n.duration?n.duration:4e3,s=n.position||"top-right",c=!1!==n.showProgress,l=null!==(o=n.id)&&void 0!==o?o:null,d=!1!==n.closeable;if(null!==l){const t=this._toastInstances.get(l);if(t)return void t.reset(r)}let f=this._toastContainers.get(s);f&&document.body.contains(f)||(f=document.createElement("div"),f.className=`notify-toast-container notify-toast-${s}`,f.setAttribute("aria-label","Notificaciones"),document.body.appendChild(f),this._toastContainers.set(s,f));const u=s.startsWith("bottom"),p="top-center"===s,m=document.createElement("div");m.className="notify-toast",d||m.classList.add("notify-toast-no-close"),"error"===i||"warning"===i?m.setAttribute("role","alert"):m.setAttribute("role","status"),m.setAttribute("aria-atomic","true"),m.setAttribute("aria-live","error"===i||"warning"===i?"assertive":"polite");const b=document.createElement("div");b.className=`notify-toast-icon ${i}`,b.innerHTML=this.getIcon(i);const g=document.createElement("div");if(g.className="notify-toast-content",a){const t=document.createElement("div");t.className="notify-toast-title",t.textContent=a,g.appendChild(t)}const h=document.createElement("div");if(h.className="notify-toast-message",h.textContent=t,g.appendChild(h),m.appendChild(b),m.appendChild(g),d){const t=document.createElement("button");t.className="notify-toast-close",t.setAttribute("aria-label","Cerrar notificación"),t.innerHTML="×",t.addEventListener("click",E),m.appendChild(t)}let y=null;r>0&&c&&(y=document.createElement("div"),y.className=`notify-toast-progress ${i}`,y.setAttribute("role","progressbar"),y.setAttribute("aria-hidden","true"),m.appendChild(y)),u||p?f.appendChild(m):f.insertBefore(m,f.firstChild);let x=!1,w=null,v=r,k=0;function E(){if(x)return Promise.resolve();if(x=!0,m.contains(document.activeElement))try{document.activeElement.blur()}catch(t){}return m.classList.remove("notify-toast-visible"),new Promise(t=>{setTimeout(()=>{m.parentNode&&m.parentNode.removeChild(m),t()},300)})}const C=t=>{k=Date.now(),w=setTimeout(()=>{null!==l&&this._toastInstances.delete(l),E()},t),y&&(y.style.transition=`width ${t}ms linear`,y.style.width="0%")},_=t=>{x||(null!==w&&(clearTimeout(w),w=null),v=t,t>0?(y&&(y.style.transition="none",y.style.width="100%",y.offsetWidth),C(t)):y&&(y.style.transition="none",y.style.width="100%"))};if(null!==l){const t=()=>{if(!x){if(x=!0,null!==w&&clearTimeout(w),m.contains(document.activeElement))try{document.activeElement.blur()}catch(t){}m.parentNode&&m.parentNode.removeChild(m)}};this._toastInstances.set(l,{reset:_,dismiss:E,_silentDismiss:t})}requestAnimationFrame(()=>{requestAnimationFrame(()=>{m.classList.add("notify-toast-visible"),r>0&&C(r)})}),r>0&&d&&(m.addEventListener("mouseenter",()=>{if(x||null===w)return;clearTimeout(w),w=null;const t=Date.now()-k;if(v=Math.max(0,v-t),y){const t=v/r*100;y.style.transition="none",y.style.width=`${t}%`}}),m.addEventListener("mouseleave",()=>{x||v<=0||C(v)}))}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}))}toastLoading(t="Cargando...",n,e={}){this.showToast(t,Object.assign(Object.assign({position:"top-right"},e),{type:"loading",title:null!=n?n:e.title,id:"__loading__",closeable:!1,duration:0,showProgress:!1}))}closeToastLoading(){const t=this._toastInstances.get("__loading__");return t?(this._toastInstances.delete("__loading__"),t.dismiss()):Promise.resolve()}replaceToastLoading(t,n={}){const e=this._toastInstances.get("__loading__");e&&(this._toastInstances.delete("__loading__"),e._silentDismiss()),this.showToast(t,n)}},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};
|
|
@@ -30,6 +30,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
30
30
|
this._lastActiveElement = null;
|
|
31
31
|
this._currentLoadingPromise = null;
|
|
32
32
|
this._toastContainers = new Map();
|
|
33
|
+
this._toastInstances = new Map();
|
|
33
34
|
this.injectStyles();
|
|
34
35
|
this.loadBoxicons();
|
|
35
36
|
}
|
|
@@ -393,6 +394,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
393
394
|
.notify-toast-icon.warning { background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); }
|
|
394
395
|
.notify-toast-icon.info { background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%); }
|
|
395
396
|
.notify-toast-icon.question { background: linear-gradient(135deg, #8b5cf6 0%, #6366f1 100%); }
|
|
397
|
+
.notify-toast-icon.loading { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%); }
|
|
396
398
|
|
|
397
399
|
.notify-toast-content { flex: 1; min-width: 0; }
|
|
398
400
|
.notify-toast-title {
|
|
@@ -401,11 +403,13 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
401
403
|
color: #1f2937;
|
|
402
404
|
margin-bottom: 2px;
|
|
403
405
|
line-height: 1.3;
|
|
406
|
+
cursor: default;
|
|
404
407
|
}
|
|
405
408
|
.notify-toast-message {
|
|
406
409
|
font-size: 13px;
|
|
407
410
|
color: #6b7280;
|
|
408
411
|
line-height: 1.5;
|
|
412
|
+
cursor: default;
|
|
409
413
|
}
|
|
410
414
|
|
|
411
415
|
.notify-toast-close {
|
|
@@ -428,6 +432,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
428
432
|
}
|
|
429
433
|
.notify-toast-close:hover { background: rgba(0,0,0,0.1); color: #374151; }
|
|
430
434
|
|
|
435
|
+
/* Sin botón de cierre: reducir padding derecho */
|
|
436
|
+
.notify-toast.notify-toast-no-close { padding-right: 14px; }
|
|
437
|
+
|
|
431
438
|
.notify-toast-progress {
|
|
432
439
|
position: absolute;
|
|
433
440
|
bottom: 0;
|
|
@@ -441,12 +448,41 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
441
448
|
.notify-toast-progress.warning { background: #f59e0b; }
|
|
442
449
|
.notify-toast-progress.info { background: #3b82f6; }
|
|
443
450
|
.notify-toast-progress.question { background: #8b5cf6; }
|
|
451
|
+
.notify-toast-progress.loading { background: #6366f1; }
|
|
452
|
+
|
|
453
|
+
/* Spinner para toast de carga */
|
|
454
|
+
.notify-toast-spinner {
|
|
455
|
+
width: 18px;
|
|
456
|
+
height: 18px;
|
|
457
|
+
border: 2.5px solid rgba(255,255,255,0.35);
|
|
458
|
+
border-top-color: white;
|
|
459
|
+
border-radius: 50%;
|
|
460
|
+
animation: notification-spin 0.8s linear infinite;
|
|
461
|
+
flex-shrink: 0;
|
|
462
|
+
}
|
|
444
463
|
|
|
445
464
|
.dark .notify-toast { background: #0f1724; box-shadow: 0 4px 24px rgba(0,0,0,0.35); }
|
|
446
465
|
.dark .notify-toast-title { color: #e6eef8; }
|
|
447
466
|
.dark .notify-toast-message { color: #cbd5e1; }
|
|
448
467
|
.dark .notify-toast-close { background: rgba(255,255,255,0.06); color: #94a3b8; }
|
|
449
468
|
.dark .notify-toast-close:hover { background: rgba(255,255,255,0.1); color: #e2e8f0; }
|
|
469
|
+
|
|
470
|
+
/* Respeta la preferencia de movimiento reducido del sistema */
|
|
471
|
+
@media (prefers-reduced-motion: reduce) {
|
|
472
|
+
.notify-toast {
|
|
473
|
+
transition: opacity 0.1s ease !important;
|
|
474
|
+
transform: none !important;
|
|
475
|
+
}
|
|
476
|
+
.notify-toast.notify-toast-visible {
|
|
477
|
+
transform: none !important;
|
|
478
|
+
}
|
|
479
|
+
.notify-toast-spinner {
|
|
480
|
+
animation-duration: 1.5s !important;
|
|
481
|
+
}
|
|
482
|
+
.notify-toast-progress {
|
|
483
|
+
transition: none !important;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
450
486
|
`;
|
|
451
487
|
document.head.appendChild(style);
|
|
452
488
|
}
|
|
@@ -456,7 +492,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
456
492
|
'error': '<i class="bx bx-x" aria-hidden="true"></i>',
|
|
457
493
|
'warning': '<i class="bx bx-error" aria-hidden="true"></i>',
|
|
458
494
|
'info': '<i class="bx bx-info-circle" aria-hidden="true"></i>',
|
|
459
|
-
'question': '<i class="bx bx-question-mark" aria-hidden="true"></i>'
|
|
495
|
+
'question': '<i class="bx bx-question-mark" aria-hidden="true"></i>',
|
|
496
|
+
'loading': '<div class="notify-toast-spinner" aria-hidden="true"></div>'
|
|
460
497
|
};
|
|
461
498
|
return icons[type] || icons.info;
|
|
462
499
|
}
|
|
@@ -954,16 +991,27 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
954
991
|
return `${mm}:${ss}`;
|
|
955
992
|
}
|
|
956
993
|
showToast(message, options = {}) {
|
|
957
|
-
var _a;
|
|
994
|
+
var _a, _b;
|
|
958
995
|
const type = options.type || 'info';
|
|
959
996
|
const title = (_a = options.title) !== null && _a !== void 0 ? _a : null;
|
|
960
997
|
const duration = typeof options.duration === 'number' ? options.duration : 4000;
|
|
961
998
|
const position = options.position || 'top-right';
|
|
962
999
|
const showProgress = options.showProgress !== false;
|
|
1000
|
+
const toastId = (_b = options.id) !== null && _b !== void 0 ? _b : null;
|
|
1001
|
+
const closeable = options.closeable !== false;
|
|
1002
|
+
// Deduplicación: si ya existe un toast con este ID, resetear su cuenta regresiva
|
|
1003
|
+
if (toastId !== null) {
|
|
1004
|
+
const existing = this._toastInstances.get(toastId);
|
|
1005
|
+
if (existing) {
|
|
1006
|
+
existing.reset(duration);
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
963
1010
|
let container = this._toastContainers.get(position);
|
|
964
1011
|
if (!container || !document.body.contains(container)) {
|
|
965
1012
|
container = document.createElement('div');
|
|
966
1013
|
container.className = `notify-toast-container notify-toast-${position}`;
|
|
1014
|
+
container.setAttribute('aria-label', 'Notificaciones');
|
|
967
1015
|
document.body.appendChild(container);
|
|
968
1016
|
this._toastContainers.set(position, container);
|
|
969
1017
|
}
|
|
@@ -971,6 +1019,20 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
971
1019
|
const isCenter = position === 'top-center';
|
|
972
1020
|
const toast = document.createElement('div');
|
|
973
1021
|
toast.className = 'notify-toast';
|
|
1022
|
+
if (!closeable) {
|
|
1023
|
+
toast.classList.add('notify-toast-no-close');
|
|
1024
|
+
}
|
|
1025
|
+
// Accesibilidad: role + aria-live según la urgencia del tipo
|
|
1026
|
+
// role="alert" implica aria-live="assertive" + aria-atomic="true" → lector lo interrumpe
|
|
1027
|
+
// role="status" implica aria-live="polite" + aria-atomic="true" → lector espera pausa
|
|
1028
|
+
if (type === 'error' || type === 'warning') {
|
|
1029
|
+
toast.setAttribute('role', 'alert');
|
|
1030
|
+
}
|
|
1031
|
+
else {
|
|
1032
|
+
toast.setAttribute('role', 'status');
|
|
1033
|
+
}
|
|
1034
|
+
toast.setAttribute('aria-atomic', 'true');
|
|
1035
|
+
toast.setAttribute('aria-live', type === 'error' || type === 'warning' ? 'assertive' : 'polite');
|
|
974
1036
|
const iconEl = document.createElement('div');
|
|
975
1037
|
iconEl.className = `notify-toast-icon ${type}`;
|
|
976
1038
|
iconEl.innerHTML = this.getIcon(type);
|
|
@@ -986,17 +1048,22 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
986
1048
|
msgEl.className = 'notify-toast-message';
|
|
987
1049
|
msgEl.textContent = message;
|
|
988
1050
|
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 = '×';
|
|
993
1051
|
toast.appendChild(iconEl);
|
|
994
1052
|
toast.appendChild(contentEl);
|
|
995
|
-
|
|
1053
|
+
if (closeable) {
|
|
1054
|
+
const closeBtn = document.createElement('button');
|
|
1055
|
+
closeBtn.className = 'notify-toast-close';
|
|
1056
|
+
closeBtn.setAttribute('aria-label', 'Cerrar notificación');
|
|
1057
|
+
closeBtn.innerHTML = '×';
|
|
1058
|
+
closeBtn.addEventListener('click', removeToast);
|
|
1059
|
+
toast.appendChild(closeBtn);
|
|
1060
|
+
}
|
|
996
1061
|
let progressEl = null;
|
|
997
1062
|
if (duration > 0 && showProgress) {
|
|
998
1063
|
progressEl = document.createElement('div');
|
|
999
1064
|
progressEl.className = `notify-toast-progress ${type}`;
|
|
1065
|
+
progressEl.setAttribute('role', 'progressbar');
|
|
1066
|
+
progressEl.setAttribute('aria-hidden', 'true'); // decorativo: el timer no añade info que el usuario necesite leer
|
|
1000
1067
|
toast.appendChild(progressEl);
|
|
1001
1068
|
}
|
|
1002
1069
|
if (isBottom || isCenter) {
|
|
@@ -1009,19 +1076,34 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1009
1076
|
let timerId = null;
|
|
1010
1077
|
let remaining = duration;
|
|
1011
1078
|
let timerStartedAt = 0;
|
|
1012
|
-
|
|
1079
|
+
function removeToast() {
|
|
1013
1080
|
if (dismissed)
|
|
1014
|
-
return;
|
|
1081
|
+
return Promise.resolve();
|
|
1015
1082
|
dismissed = true;
|
|
1083
|
+
// Si el foco estaba dentro del toast, sacarlo antes de que el nodo desaparezca
|
|
1084
|
+
// para evitar que el foco se pierda silenciosamente en el documento
|
|
1085
|
+
if (toast.contains(document.activeElement)) {
|
|
1086
|
+
try {
|
|
1087
|
+
document.activeElement.blur();
|
|
1088
|
+
}
|
|
1089
|
+
catch (e) { }
|
|
1090
|
+
}
|
|
1016
1091
|
toast.classList.remove('notify-toast-visible');
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
toast.parentNode
|
|
1020
|
-
|
|
1021
|
-
|
|
1092
|
+
return new Promise(resolve => {
|
|
1093
|
+
setTimeout(() => {
|
|
1094
|
+
if (toast.parentNode)
|
|
1095
|
+
toast.parentNode.removeChild(toast);
|
|
1096
|
+
resolve();
|
|
1097
|
+
}, 300);
|
|
1098
|
+
});
|
|
1099
|
+
}
|
|
1022
1100
|
const startCountdown = (ms) => {
|
|
1023
1101
|
timerStartedAt = Date.now();
|
|
1024
|
-
timerId = setTimeout(
|
|
1102
|
+
timerId = setTimeout(() => {
|
|
1103
|
+
if (toastId !== null)
|
|
1104
|
+
this._toastInstances.delete(toastId);
|
|
1105
|
+
removeToast();
|
|
1106
|
+
}, ms);
|
|
1025
1107
|
if (progressEl) {
|
|
1026
1108
|
progressEl.style.transition = `width ${ms}ms linear`;
|
|
1027
1109
|
progressEl.style.width = '0%';
|
|
@@ -1045,7 +1127,46 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1045
1127
|
return;
|
|
1046
1128
|
startCountdown(remaining);
|
|
1047
1129
|
};
|
|
1048
|
-
|
|
1130
|
+
const resetCountdown = (newDuration) => {
|
|
1131
|
+
if (dismissed)
|
|
1132
|
+
return;
|
|
1133
|
+
if (timerId !== null) {
|
|
1134
|
+
clearTimeout(timerId);
|
|
1135
|
+
timerId = null;
|
|
1136
|
+
}
|
|
1137
|
+
remaining = newDuration;
|
|
1138
|
+
if (newDuration > 0) {
|
|
1139
|
+
if (progressEl) {
|
|
1140
|
+
progressEl.style.transition = 'none';
|
|
1141
|
+
progressEl.style.width = '100%';
|
|
1142
|
+
// Forzar reflow para que la transición se aplique desde el inicio
|
|
1143
|
+
void progressEl.offsetWidth;
|
|
1144
|
+
}
|
|
1145
|
+
startCountdown(newDuration);
|
|
1146
|
+
}
|
|
1147
|
+
else if (progressEl) {
|
|
1148
|
+
progressEl.style.transition = 'none';
|
|
1149
|
+
progressEl.style.width = '100%';
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1152
|
+
if (toastId !== null) {
|
|
1153
|
+
const silentDismiss = () => {
|
|
1154
|
+
if (dismissed)
|
|
1155
|
+
return;
|
|
1156
|
+
dismissed = true;
|
|
1157
|
+
if (timerId !== null)
|
|
1158
|
+
clearTimeout(timerId);
|
|
1159
|
+
if (toast.contains(document.activeElement)) {
|
|
1160
|
+
try {
|
|
1161
|
+
document.activeElement.blur();
|
|
1162
|
+
}
|
|
1163
|
+
catch (e) { }
|
|
1164
|
+
}
|
|
1165
|
+
if (toast.parentNode)
|
|
1166
|
+
toast.parentNode.removeChild(toast);
|
|
1167
|
+
};
|
|
1168
|
+
this._toastInstances.set(toastId, { reset: resetCountdown, dismiss: removeToast, _silentDismiss: silentDismiss });
|
|
1169
|
+
}
|
|
1049
1170
|
requestAnimationFrame(() => {
|
|
1050
1171
|
requestAnimationFrame(() => {
|
|
1051
1172
|
toast.classList.add('notify-toast-visible');
|
|
@@ -1054,7 +1175,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1054
1175
|
}
|
|
1055
1176
|
});
|
|
1056
1177
|
});
|
|
1057
|
-
if (duration > 0) {
|
|
1178
|
+
if (duration > 0 && closeable) {
|
|
1058
1179
|
toast.addEventListener('mouseenter', pauseCountdown);
|
|
1059
1180
|
toast.addEventListener('mouseleave', resumeCountdown);
|
|
1060
1181
|
}
|
|
@@ -1083,6 +1204,38 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
1083
1204
|
toastQuestion(message, title, options = {}) {
|
|
1084
1205
|
this.showToast(message, Object.assign(Object.assign({}, options), { type: 'question', title: title !== null && title !== void 0 ? title : options.title }));
|
|
1085
1206
|
}
|
|
1207
|
+
/**
|
|
1208
|
+
* Muestra un toast de carga con spinner.
|
|
1209
|
+
* - No se puede cerrar manualmente (closeable: false por defecto).
|
|
1210
|
+
* - No tiene cuenta regresiva (duration: 0 por defecto).
|
|
1211
|
+
* - Solo puede existir uno a la vez (id '__loading__').
|
|
1212
|
+
* Ciérralo con notify.closeToastLoading().
|
|
1213
|
+
*/
|
|
1214
|
+
toastLoading(message = 'Cargando...', title, options = {}) {
|
|
1215
|
+
this.showToast(message, Object.assign(Object.assign({ position: 'top-right' }, options), { type: 'loading', title: title !== null && title !== void 0 ? title : options.title, id: '__loading__', closeable: false, duration: 0, showProgress: false }));
|
|
1216
|
+
}
|
|
1217
|
+
/** Cierra el toast de carga activo (si existe). Devuelve una Promise que resuelve cuando la animación de salida termina (≈300 ms). */
|
|
1218
|
+
closeToastLoading() {
|
|
1219
|
+
const entry = this._toastInstances.get('__loading__');
|
|
1220
|
+
if (entry) {
|
|
1221
|
+
this._toastInstances.delete('__loading__');
|
|
1222
|
+
return entry.dismiss();
|
|
1223
|
+
}
|
|
1224
|
+
return Promise.resolve();
|
|
1225
|
+
}
|
|
1226
|
+
/**
|
|
1227
|
+
* Reemplaza el toast de carga activo por un toast de resultado en el mismo lugar,
|
|
1228
|
+
* sin animación de salida/entrada — no hay solapamiento ni hueco visual.
|
|
1229
|
+
* Si no existe un toast de carga activo, simplemente muestra un toast normal.
|
|
1230
|
+
*/
|
|
1231
|
+
replaceToastLoading(message, options = {}) {
|
|
1232
|
+
const entry = this._toastInstances.get('__loading__');
|
|
1233
|
+
if (entry) {
|
|
1234
|
+
this._toastInstances.delete('__loading__');
|
|
1235
|
+
entry._silentDismiss();
|
|
1236
|
+
}
|
|
1237
|
+
this.showToast(message, options);
|
|
1238
|
+
}
|
|
1086
1239
|
}
|
|
1087
1240
|
const notifyInstance = new NotificationSystem();
|
|
1088
1241
|
const w = window;
|
|
@@ -1 +1 @@
|
|
|
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="×",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="×",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}}();
|
|
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._toastInstances=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 .notify-toast-icon.loading { background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 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 cursor: default;\n }\n .notify-toast-message {\n font-size: 13px;\n color: #6b7280;\n line-height: 1.5;\n cursor: default;\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 /* Sin botón de cierre: reducir padding derecho */\n .notify-toast.notify-toast-no-close { padding-right: 14px; }\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 .notify-toast-progress.loading { background: #6366f1; }\n\n /* Spinner para toast de carga */\n .notify-toast-spinner {\n width: 18px;\n height: 18px;\n border: 2.5px solid rgba(255,255,255,0.35);\n border-top-color: white;\n border-radius: 50%;\n animation: notification-spin 0.8s linear infinite;\n flex-shrink: 0;\n }\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\n /* Respeta la preferencia de movimiento reducido del sistema */\n @media (prefers-reduced-motion: reduce) {\n .notify-toast {\n transition: opacity 0.1s ease !important;\n transform: none !important;\n }\n .notify-toast.notify-toast-visible {\n transform: none !important;\n }\n .notify-toast-spinner {\n animation-duration: 1.5s !important;\n }\n .notify-toast-progress {\n transition: none !important;\n }\n }\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>',loading:'<div class="notify-toast-spinner" aria-hidden="true"></div>'};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 g=document.createElement("h3");g.className="notification-title",g.textContent=e;const h=document.createElement("p");h.className="notification-message",h.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="×",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(g),m.appendChild(h);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 _=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=_,document.addEventListener("keydown",_);const T=t.anim||{},N="number"==typeof T.overlayDuration?T.overlayDuration:150,L=T.overlayEasing||"easeOutQuad",S="number"==typeof T.boxDuration?T.boxDuration:200,j="number"==typeof T.boxDelay?T.boxDelay:50,O=T.boxEasing||"easeOutBack",D="number"==typeof T.boxStartScale?T.boxStartScale:.8,A="number"==typeof T.iconDuration?T.iconDuration:250,$="number"==typeof T.iconDelay?T.iconDelay:100,P="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:N,easing:L}),anime({targets:m,scale:[D,1],opacity:[0,1],duration:S,easing:O,delay:j}),anime({targets:b,scale:[0,1],rotate:[P,0],duration:A,easing:O,delay:$}),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,o;const i=n.type||"info",a=null!==(e=n.title)&&void 0!==e?e:null,r="number"==typeof n.duration?n.duration:4e3,s=n.position||"top-right",c=!1!==n.showProgress,l=null!==(o=n.id)&&void 0!==o?o:null,d=!1!==n.closeable;if(null!==l){const t=this._toastInstances.get(l);if(t)return void t.reset(r)}let f=this._toastContainers.get(s);f&&document.body.contains(f)||(f=document.createElement("div"),f.className=`notify-toast-container notify-toast-${s}`,f.setAttribute("aria-label","Notificaciones"),document.body.appendChild(f),this._toastContainers.set(s,f));const u=s.startsWith("bottom"),p="top-center"===s,m=document.createElement("div");m.className="notify-toast",d||m.classList.add("notify-toast-no-close"),"error"===i||"warning"===i?m.setAttribute("role","alert"):m.setAttribute("role","status"),m.setAttribute("aria-atomic","true"),m.setAttribute("aria-live","error"===i||"warning"===i?"assertive":"polite");const b=document.createElement("div");b.className=`notify-toast-icon ${i}`,b.innerHTML=this.getIcon(i);const g=document.createElement("div");if(g.className="notify-toast-content",a){const t=document.createElement("div");t.className="notify-toast-title",t.textContent=a,g.appendChild(t)}const h=document.createElement("div");if(h.className="notify-toast-message",h.textContent=t,g.appendChild(h),m.appendChild(b),m.appendChild(g),d){const t=document.createElement("button");t.className="notify-toast-close",t.setAttribute("aria-label","Cerrar notificación"),t.innerHTML="×",t.addEventListener("click",E),m.appendChild(t)}let x=null;r>0&&c&&(x=document.createElement("div"),x.className=`notify-toast-progress ${i}`,x.setAttribute("role","progressbar"),x.setAttribute("aria-hidden","true"),m.appendChild(x)),u||p?f.appendChild(m):f.insertBefore(m,f.firstChild);let y=!1,w=null,v=r,k=0;function E(){if(y)return Promise.resolve();if(y=!0,m.contains(document.activeElement))try{document.activeElement.blur()}catch(t){}return m.classList.remove("notify-toast-visible"),new Promise(t=>{setTimeout(()=>{m.parentNode&&m.parentNode.removeChild(m),t()},300)})}const C=t=>{k=Date.now(),w=setTimeout(()=>{null!==l&&this._toastInstances.delete(l),E()},t),x&&(x.style.transition=`width ${t}ms linear`,x.style.width="0%")},_=t=>{y||(null!==w&&(clearTimeout(w),w=null),v=t,t>0?(x&&(x.style.transition="none",x.style.width="100%",x.offsetWidth),C(t)):x&&(x.style.transition="none",x.style.width="100%"))};if(null!==l){const t=()=>{if(!y){if(y=!0,null!==w&&clearTimeout(w),m.contains(document.activeElement))try{document.activeElement.blur()}catch(t){}m.parentNode&&m.parentNode.removeChild(m)}};this._toastInstances.set(l,{reset:_,dismiss:E,_silentDismiss:t})}requestAnimationFrame(()=>{requestAnimationFrame(()=>{m.classList.add("notify-toast-visible"),r>0&&C(r)})}),r>0&&d&&(m.addEventListener("mouseenter",()=>{if(y||null===w)return;clearTimeout(w),w=null;const t=Date.now()-k;if(v=Math.max(0,v-t),x){const t=v/r*100;x.style.transition="none",x.style.width=`${t}%`}}),m.addEventListener("mouseleave",()=>{y||v<=0||C(v)}))}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}))}toastLoading(t="Cargando...",n,e={}){this.showToast(t,Object.assign(Object.assign({position:"top-right"},e),{type:"loading",title:null!=n?n:e.title,id:"__loading__",closeable:!1,duration:0,showProgress:!1}))}closeToastLoading(){const t=this._toastInstances.get("__loading__");return t?(this._toastInstances.delete("__loading__"),t.dismiss()):Promise.resolve()}replaceToastLoading(t,n={}){const e=this._toastInstances.get("__loading__");e&&(this._toastInstances.delete("__loading__"),e._silentDismiss()),this.showToast(t,n)}},n=window;n.notify=t,n.Notification=t}}();
|
package/package.json
CHANGED