@votodigital-onpeui/react 0.1.56 → 0.1.57

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
@@ -115,7 +115,7 @@ function App() {
115
115
  <>
116
116
  <button onClick={() => setIsOpen(true)}>Abrir Modal</button>
117
117
 
118
- <Modal isOpen={isOpen} onClose={() => setIsOpen(false)} closeButton>
118
+ <Modal isOpen={isOpen} onClose={() => setIsOpen(false)} closeButton className="bg-white">
119
119
  <h2>Título del Modal</h2>
120
120
  <p>Contenido del modal.</p>
121
121
  </Modal>
@@ -163,8 +163,9 @@ function App() {
163
163
  onClose={() => setIsOpen(false)}
164
164
  title="¿Estás seguro?"
165
165
  message="Esta acción no se puede deshacer."
166
- icon="warning"
166
+ type="warning"
167
167
  color="red"
168
+ buttonMode="double"
168
169
  textButtonConfirm="Eliminar"
169
170
  textButtonCancel="Cancelar"
170
171
  onConfirm={() => console.log("confirmado")}
@@ -181,17 +182,26 @@ function App() {
181
182
  |------|------|---------|-------------|
182
183
  | `isOpen` | `boolean` | — | **(requerido)** |
183
184
  | `onClose` | `() => void` | — | **(requerido)** |
184
- | `title` | `string` | — | Título del modal **(requerido)** |
185
- | `message` | `ReactNode` | — | Mensaje descriptivo **(requerido)** |
186
- | `icon` | `'warning' \| 'success'` | `'warning'` | Icono a mostrar |
187
- | `color` | `'blue' \| 'red'` | `'blue'` | Color del icono y título |
188
- | `twoButtons` | `boolean` | `true` | Muestra dos botones (confirmar + cancelar) |
185
+ | `title` | `string` | — | Título del modal |
186
+ | `message` | `ReactNode` | — | Mensaje descriptivo (string o JSX) |
187
+ | `content` | `ReactNode` | | Alias de `message` |
188
+ | `type` | `'warning' \| 'success' \| 'question' \| 'info' \| 'none'` | `'warning'` | Determina el icono y el color por defecto |
189
+ | `buttonMode` | `'single' \| 'double' \| 'confirm'` | — | `single` = un botón, `double` = Cancelar + Confirmar, `confirm` = No + Sí |
190
+ | `color` | `'blue' \| 'red' \| 'skyblue' \| 'yellow'` | — | Override manual del color del icono y título |
189
191
  | `textButtonConfirm` | `string` | `'Confirmar'` | Texto del botón de confirmación |
190
192
  | `textButtonCancel` | `string` | `'Cancelar'` | Texto del botón de cancelación |
191
- | `onConfirm` | `() => void` | — | Acción al confirmar |
192
- | `onCancel` | `() => void` | — | Acción al cancelar |
193
+ | `onConfirm` | `() => void \| Promise<void>` | — | Acción al confirmar |
194
+ | `onCancel` | `() => void \| Promise<void>` | — | Acción al cancelar |
193
195
  | `withoutAutoClose` | `boolean` | `false` | Evita que el modal se cierre automáticamente al confirmar/cancelar |
196
+ | `disabledConfirmButton` | `boolean` | `false` | Deshabilita el botón confirmar |
197
+ | `closeDisabled` | `boolean` | `false` | Deshabilita el cierre por click fuera y Escape |
198
+ | `closeButton` | `boolean` | `false` | Muestra botón X para cerrar |
199
+ | `alignJustify` | `boolean` | `false` | Alinea el texto del mensaje en justify en vez de centrado |
200
+ | `alignTop` | `boolean` | `false` | Alinea el modal al tope de la pantalla |
201
+ | `animated` | `boolean` | `true` | Habilita animación de entrada/salida |
202
+ | `preventBodyScroll` | `boolean` | `true` | Bloquea el scroll del body mientras el modal está abierto |
194
203
  | `zIndexLevel` | `number` | `100` | Nivel de z-index |
204
+ | `className` | `string` | — | Clases adicionales |
195
205
 
196
206
  ---
197
207
 
@@ -202,10 +212,18 @@ Modal de carga con spinner animado y mensaje.
202
212
  ```tsx
203
213
  import { ModalLoading } from "@votodigital-onpeui/react";
204
214
 
215
+ // Uso básico
205
216
  <ModalLoading
206
217
  isOpen={loading}
207
218
  message="Procesando información..."
208
219
  />
220
+
221
+ // Con spinner personalizado
222
+ <ModalLoading
223
+ isOpen={loading}
224
+ message="Subiendo archivo..."
225
+ spinner={<div className="w-16 h-16 rounded-full border-4 border-white border-t-transparent animate-spin" />}
226
+ />
209
227
  ```
210
228
 
211
229
  #### Props
@@ -213,8 +231,156 @@ import { ModalLoading } from "@votodigital-onpeui/react";
213
231
  | Prop | Tipo | Default | Descripción |
214
232
  |------|------|---------|-------------|
215
233
  | `isOpen` | `boolean` | — | **(requerido)** |
234
+ | `onClose` | `() => void` | — | Callback al cerrar |
216
235
  | `message` | `string` | `'Cargando...'` | Mensaje de carga |
236
+ | `spinner` | `ReactNode` | — | Spinner personalizado. Si no se provee, se usa el spinner por defecto |
237
+ | `animated` | `boolean` | `true` | Habilita animación de entrada/salida |
238
+ | `preventBodyScroll` | `boolean` | `true` | Bloquea el scroll del body |
217
239
  | `zIndexLevel` | `number` | `100` | Nivel de z-index |
240
+ | `className` | `string` | — | Clases adicionales |
241
+
242
+ ---
243
+
244
+ ### ModalLoadingPercentage
245
+
246
+ Modal de carga con barra de progreso y porcentaje.
247
+
248
+ ```tsx
249
+ import { ModalLoadingPercentage } from "@votodigital-onpeui/react";
250
+
251
+ <ModalLoadingPercentage
252
+ isOpen={isOpen}
253
+ message="Importando padrón electoral"
254
+ percentage={progress}
255
+ />
256
+ ```
257
+
258
+ #### Props
259
+
260
+ | Prop | Tipo | Default | Descripción |
261
+ |------|------|---------|-------------|
262
+ | `isOpen` | `boolean` | — | **(requerido)** |
263
+ | `message` | `string` | — | **(requerido)** Texto que aparece sobre la barra de progreso |
264
+ | `percentage` | `number` | — | **(requerido)** Valor entre 0 y 100. Se clampea automáticamente |
265
+ | `alignTop` | `boolean` | `false` | Alinea el modal al tope de la pantalla en vez de al centro |
266
+ | `animated` | `boolean` | `true` | Habilita animación de entrada/salida |
267
+ | `preventBodyScroll` | `boolean` | `true` | Bloquea el scroll del body |
268
+ | `zIndexLevel` | `number` | `300` | Nivel de z-index |
269
+
270
+ ---
271
+
272
+ ### ModalGlobalProvider
273
+
274
+ Proveedor centralizado que gestiona los tres modales (ModalConfirm, ModalLoading, ModalLoadingPercentage) desde cualquier parte de la app sin props drilling. Usa Zustand internamente.
275
+
276
+ #### Setup
277
+
278
+ Envuelve tu app una sola vez:
279
+
280
+ ```tsx
281
+ import { ModalGlobalProvider } from "@votodigital-onpeui/react";
282
+
283
+ function App() {
284
+ return (
285
+ <ModalGlobalProvider>
286
+ <Router />
287
+ </ModalGlobalProvider>
288
+ );
289
+ }
290
+ ```
291
+
292
+ #### Usar el modal de confirmación
293
+
294
+ ```tsx
295
+ import { useModalGlobalStore } from "@votodigital-onpeui/react";
296
+
297
+ function MiComponente() {
298
+ const { openModal, openModalWithClose } = useModalGlobalStore();
299
+
300
+ const handleEliminar = async () => {
301
+ // Retorna true (confirmar) o false (cancelar)
302
+ const confirmed = await openModal({
303
+ type: "warning",
304
+ title: "¿Estás seguro?",
305
+ message: "Esta acción no se puede deshacer.",
306
+ buttonMode: "double",
307
+ color: "red",
308
+ textButtonConfirm: "Eliminar",
309
+ });
310
+
311
+ if (confirmed) {
312
+ // lógica de eliminación
313
+ }
314
+ };
315
+
316
+ const handleConX = async () => {
317
+ // Retorna 'confirm' | 'cancel' | 'close'
318
+ const result = await openModalWithClose({
319
+ type: "info",
320
+ title: "Aviso",
321
+ message: "Revisa los datos antes de continuar.",
322
+ buttonMode: "single",
323
+ });
324
+ };
325
+ }
326
+ ```
327
+
328
+ #### Usar el modal de loading
329
+
330
+ ```tsx
331
+ import { useModalLoadingStore } from "@votodigital-onpeui/react";
332
+
333
+ function MiComponente() {
334
+ const { openLoading, closeLoading } = useModalLoadingStore();
335
+
336
+ const handleGuardar = async () => {
337
+ const sessionId = openLoading("Guardando...");
338
+ try {
339
+ await guardarDatos();
340
+ } finally {
341
+ closeLoading(sessionId);
342
+ }
343
+ };
344
+ }
345
+ ```
346
+
347
+ #### Usar el modal de loading con porcentaje
348
+
349
+ ```tsx
350
+ import { useModalLoadingPercentageStore } from "@votodigital-onpeui/react";
351
+
352
+ function MiComponente() {
353
+ const { openLoadingPercentage, updatePercentage, closeLoadingPercentage } =
354
+ useModalLoadingPercentageStore();
355
+
356
+ const handleImportar = async () => {
357
+ const sessionId = openLoadingPercentage("Importando padrón", 0);
358
+ for (let i = 0; i <= 100; i += 10) {
359
+ await procesarLote(i);
360
+ updatePercentage(i, sessionId);
361
+ }
362
+ closeLoadingPercentage(sessionId);
363
+ };
364
+ }
365
+ ```
366
+
367
+ > **Nota sobre sessionId:** `openLoading`, `openLoadingPercentage` retornan un `sessionId`. Pasarlo a `closeLoading` / `closeLoadingPercentage` evita que una llamada tardía cierre un loading abierto por otra operación posterior.
368
+
369
+ #### Props de ModalGlobalProvider
370
+
371
+ | Prop | Tipo | Default | Descripción |
372
+ |------|------|---------|-------------|
373
+ | `children` | `ReactNode` | — | **(requerido)** |
374
+ | `zIndexLevel` | `number` | `200` | z-index del ModalConfirm |
375
+ | `zIndexLoading` | `number` | `300` | z-index del ModalLoading |
376
+ | `zIndexLoadingPercentage` | `number` | `300` | z-index del ModalLoadingPercentage |
377
+ | `animated` | `boolean` | `true` | Animación en todos los modales |
378
+ | `preventBodyScroll` | `boolean` | `true` | Scroll lock en todos los modales |
379
+ | `loadingSpinner` | `ReactNode` | — | Spinner personalizado para ModalLoading |
380
+ | `loadingPercentageAlignTop` | `boolean` | `false` | Alinea el ModalLoadingPercentage al tope |
381
+ | `defaultTextButtonConfirm` | `string` | — | Texto por defecto del botón confirmar |
382
+ | `defaultTextButtonCancel` | `string` | — | Texto por defecto del botón cancelar |
383
+ | `disableFocus` | `boolean` | `false` | Deshabilita el manejo de focus en todos los modales |
218
384
 
219
385
  ---
220
386
 
@@ -495,12 +661,18 @@ Modal
495
661
  ├── Portal
496
662
  └── IconCloseRadius
497
663
 
498
- ModalConfirm → Modal
499
- ModalLoading → Modal
664
+ ModalConfirm → Modal
665
+ ModalLoading → Modal
666
+ ModalLoadingPercentage → Modal
500
667
  ModalBrowserIncompatible → Modal + IconWarning + IconChromeColor + IconSafariColor + IconEdgeColor
501
668
  ModalSystemIncompatible → Modal + IconWarning + IconWindow + IconAndroid + IconApple
502
- ModalDnieVersions → Modal
503
- ModalNfc → Modal + IconAndroid + IconApple
669
+ ModalDnieVersions → Modal
670
+ ModalNfc → Modal + IconAndroid + IconApple
671
+
672
+ ModalGlobalProvider → ModalConfirm + ModalLoading + ModalLoadingPercentage
673
+ useModalGlobalStore (Zustand) — openModal, openModalWithClose
674
+ useModalLoadingStore (Zustand) — openLoading, closeLoading
675
+ useModalLoadingPercentageStore (Zustand) — openLoadingPercentage, updatePercentage, closeLoadingPercentage
504
676
 
505
677
  Footer → BrowserRecommended + iconos de redes sociales
506
678
  NotRecommended → IconWarningNotRecommended + IconCloseRadius
package/dist/modal.js CHANGED
@@ -867,7 +867,7 @@ var ModalLoadingPercentage = ({
867
867
  "div",
868
868
  {
869
869
  style: { width: `${clamped}%` },
870
- className: "h-10 bg-blue border-white border-2 transition-all ease-in-out duration-300"
870
+ className: "h-10 bg-onpe-blue border-white border-2 transition-all ease-in-out duration-300"
871
871
  }
872
872
  ) })
873
873
  ] })
package/dist/modal.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/ModalGlobal/ModalGlobalContext.ts","../src/store/modalGlobal/useModalGlobalStore.ts","../src/store/modalGlobal/useModalLoadingStore.ts","../src/store/modalGlobal/useModalLoadingPercentageStore.ts","../src/components/Portal/Portal.tsx","../src/icons/Actions/IconCloseRadius.tsx","../src/components/Modal/Modal.tsx","../src/components/Button/Button.tsx","../src/icons/Actions/IconCheck.tsx","../src/icons/Actions/IconInfo.tsx","../src/icons/Actions/IconQuestion.tsx","../src/icons/Actions/IconSpinnerDesktop.tsx","../src/icons/Actions/IconSpinnerMobile.tsx","../src/icons/Actions/IconWarningNotRecommended.tsx","../src/components/Feedback/ModalConfirm/ModalConfirm.tsx","../src/components/Feedback/ModalLoading/ModalLoading.tsx","../src/components/Feedback/ModalLoadingPercentage/ModalLoadingPercentage.tsx","../src/components/ModalGlobal/ModalGlobalProvider.tsx","../src/utils/showGlobalModal.ts"],"names":["createContext","useContext","create","useState","useEffect","createPortal","jsx","useId","useRef","useLayoutEffect","activeIndex","jsxs","Fragment","useMemo"],"mappings":"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","file":"modal.js","sourcesContent":["import { createContext, useContext } from \"react\";\n\ninterface ModalGlobalContextValue {\n animated: boolean;\n disableFocus: boolean;\n}\n\nexport const ModalGlobalContext = createContext<ModalGlobalContextValue | null>(null);\n\nexport const useModalGlobalContext = () => useContext(ModalGlobalContext);\n","import { create } from \"zustand\";\nimport type { ReactNode } from \"react\";\nimport type { ModalType } from \"../../components/Feedback/ModalConfirm/ModalConfirm\";\n\nexport type { ModalType };\n\nexport type ModalResult = \"confirm\" | \"cancel\" | \"close\";\n\n/**\n * Payload del modal global.\n * Combina los props de ModalGlobalComponent (type, buttonMode, content)\n * con los de ModalConfirm (icon, color, twoButtons).\n * Los props del global component predominan; color e icon son overrides manuales.\n */\nexport interface ModalPayload {\n title?: string;\n /** Contenido del modal (string o JSX). Alias: content */\n message?: ReactNode;\n /** Alias de message para compatibilidad */\n content?: ReactNode;\n /** Tipo semántico: determina icono y color */\n type: ModalType;\n /**\n * Override del icono independiente del `type`.\n * Usa los mismos valores que `type`. Si se provee, tiene prioridad sobre `type` para el icono.\n */\n iconType?: ModalType;\n /**\n * \"single\" → un botón \"Confirmar\".\n * \"double\" → \"Cancelar\" + \"Confirmar\".\n * \"confirm\" → \"No\" + \"Sí\" (diálogo de confirmación).\n */\n buttonMode?: \"single\" | \"double\" | \"confirm\";\n /** Deshabilita el botón confirmar */\n disabledConfirmButton?: boolean;\n /** Deshabilita el cierre del modal */\n closeDisabled?: boolean;\n /** Override manual del color del icono y título */\n color?: \"red\" | \"blue\" | \"skyblue\" | \"yellow\";\n textButtonConfirm?: string;\n textButtonCancel?: string;\n /** Muestra el botón X para cerrar el modal */\n closeButton?: boolean;\n /** Alinea el texto del mensaje a la izquierda (justify) en vez de centrado */\n alignJustify?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n top?: boolean;\n /**\n * Tiempo en ms para auto-confirmar el modal (ej: 30000 = 30s).\n * Útil para modales de error de sesión/red que deben cerrarse solos.\n */\n autoConfirmTimeout?: number;\n /**\n * Marca este modal como controlado por axios interceptor.\n * Cuando es true, los handlers de cambio de ruta NO deben cerrarlo.\n */\n alreadyHandled?: boolean;\n}\n\ninterface ModalGlobalState {\n isOpen: boolean;\n payload: ModalPayload | null;\n modalId: number;\n /** true cuando fue abierto con openModalWithClose (3 estados) */\n isTriState: boolean;\n _resolve: ((result: boolean) => void) | null;\n _resolveWithClose: ((result: ModalResult) => void) | null;\n\n openModal: (payload: ModalPayload) => Promise<boolean>;\n openModalWithClose: (payload: ModalPayload) => Promise<ModalResult>;\n closeModal: (confirmed?: boolean) => void;\n closeModalWithResult: (result: ModalResult) => void;\n}\n\nexport const useModalGlobalStore = create<ModalGlobalState>((set, get) => ({\n isOpen: false,\n payload: null,\n modalId: 0,\n isTriState: false,\n _resolve: null,\n _resolveWithClose: null,\n\n openModal: (payload) => {\n return new Promise<boolean>((resolve) => {\n set((state) => ({\n isOpen: true,\n payload,\n modalId: state.modalId + 1,\n isTriState: false,\n _resolve: resolve,\n _resolveWithClose: null,\n }));\n });\n },\n\n openModalWithClose: (payload) => {\n return new Promise<ModalResult>((resolve) => {\n set((state) => ({\n isOpen: true,\n payload,\n modalId: state.modalId + 1,\n isTriState: true,\n _resolve: null,\n _resolveWithClose: resolve,\n }));\n });\n },\n\n closeModal: (confirmed = false) => {\n const { _resolve, _resolveWithClose } = get();\n _resolve?.(confirmed);\n _resolveWithClose?.(confirmed ? \"confirm\" : \"cancel\");\n set({ isOpen: false, payload: null, isTriState: false, _resolve: null, _resolveWithClose: null });\n },\n\n closeModalWithResult: (result) => {\n const { _resolve, _resolveWithClose } = get();\n _resolve?.(result === \"confirm\");\n _resolveWithClose?.(result);\n set({ isOpen: false, payload: null, isTriState: false, _resolve: null, _resolveWithClose: null });\n },\n}));\n","import { create } from \"zustand\";\n\ninterface ModalLoadingState {\n isOpen: boolean;\n message: string;\n sessionId: number;\n openLoading: (message?: string) => number;\n closeLoading: (sessionId?: number) => void;\n}\n\nexport const useModalLoadingStore = create<ModalLoadingState>((set, get) => ({\n isOpen: false,\n message: \"Cargando...\",\n sessionId: 0,\n openLoading: (message = \"Cargando...\") => {\n const nextId = get().sessionId + 1;\n set({ isOpen: true, message, sessionId: nextId });\n return nextId;\n },\n closeLoading: (sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ isOpen: false, message: \"Cargando...\" });\n },\n}));\n","import { create } from \"zustand\";\n\ninterface ModalLoadingPercentageState {\n isOpen: boolean;\n message: string;\n percentage: number;\n /** ID de sesión actual — se incrementa en cada apertura */\n sessionId: number;\n openLoadingPercentage: (message?: string, initialPercentage?: number) => number;\n updatePercentage: (percentage: number, sessionId?: number) => void;\n closeLoadingPercentage: (sessionId?: number) => void;\n}\n\nexport const useModalLoadingPercentageStore = create<ModalLoadingPercentageState>((set, get) => ({\n isOpen: false,\n message: \"Cargando...\",\n percentage: 0,\n sessionId: 0,\n openLoadingPercentage: (message = \"Cargando...\", initialPercentage = 0) => {\n const nextId = get().sessionId + 1;\n set({ isOpen: true, message, percentage: Math.min(100, Math.max(0, initialPercentage)), sessionId: nextId });\n return nextId;\n },\n updatePercentage: (percentage, sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ percentage: Math.min(100, Math.max(0, percentage)) });\n },\n closeLoadingPercentage: (sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ isOpen: false, message: \"Cargando...\", percentage: 0 });\n },\n}));\n","import { ReactNode, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nexport interface PortalProps {\n children?: ReactNode;\n container?: Element | DocumentFragment | null;\n}\n\nexport const Portal = ({ children, container }: PortalProps) => {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n return () => setMounted(false);\n }, []);\n\n if (!mounted) return null;\n\n let portalElement = container || document.querySelector(\"#portal\");\n if (!portalElement) {\n portalElement = document.body;\n }\n\n return createPortal(children, portalElement);\n};\n\nexport default Portal;\n","import { SVGProps } from \"react\";\n\nexport const IconCloseRadius = (props: SVGProps<SVGSVGElement>) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width={28} height={28} viewBox=\"0 0 28 28\" fill=\"none\" {...props}>\n <path\n d=\"M14 0C6.2 0 0 6.2 0 14C0 21.8 6.2 28 14 28C21.8 28 28 21.8 28 14C28 6.2 21.8 0 14 0ZM19.4 21L14 15.6L8.6 21L7 19.4L12.4 14L7 8.6L8.6 7L14 12.4L19.4 7L21 8.6L15.6 14L21 19.4L19.4 21Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport default IconCloseRadius;\n","import { HTMLAttributes, ReactNode, useEffect, useId, useLayoutEffect, useRef, useState } from \"react\";\nimport { Portal } from \"../Portal/Portal\";\nimport { IconCloseRadius } from \"../../icons/Actions/IconCloseRadius\";\nimport { useModalGlobalContext } from \"../ModalGlobal/ModalGlobalContext\";\n\nexport interface ModalProps extends HTMLAttributes<HTMLDivElement> {\n isOpen: boolean;\n onClose: () => void;\n children: ReactNode;\n whitoutBackground?: boolean;\n closeButton?: boolean;\n closeDisabled?: boolean;\n escapeToClose?: boolean;\n disableFocus?: boolean;\n disableFocusRestore?: boolean;\n existTabIndex?: boolean;\n zIndexLevel?: number;\n onCloseComplete?: () => void;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n alignTop?: boolean;\n /** Habilita animación de entrada/salida (default: true) */\n animated?: boolean;\n /** Bloquea el scroll del body mientras el modal está abierto (default: true) */\n preventBodyScroll?: boolean;\n overlayColor?:\n | \"blue\"\n | \"skyblue\"\n | \"skyblue-light\"\n | \"yellow\"\n | \"light-skyblue\"\n | \"gray\"\n | \"gray-light\"\n | \"gray-extra-light\"\n | \"red\"\n | \"dark-gray\"\n | \"green\"\n | \"yellow-light\"\n | \"primary\";\n}\n\nconst openModals: Set<string> =\n (globalThis as unknown as Record<string, unknown>).__openModals as Set<string> ||\n ((globalThis as unknown as Record<string, Set<string>>).__openModals = new Set<string>());\n\nconst lockBodyScroll = (id: string, enabled: boolean) => {\n if (!enabled || typeof document === \"undefined\") return;\n openModals.add(id);\n document.body.style.overflow = \"hidden\";\n};\n\nconst unlockBodyScroll = (id: string, enabled: boolean) => {\n if (!enabled || typeof document === \"undefined\") return;\n openModals.delete(id);\n if (openModals.size === 0) {\n document.body.style.overflow = \"\";\n }\n};\n\nconst FOCUSABLE_SELECTOR = [\n \"a[href]\",\n \"area[href]\",\n \"button:not([disabled])\",\n 'input:not([disabled]):not([type=\"hidden\"])',\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n \"iframe\",\n \"object\",\n \"embed\",\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n].join(\",\");\n\nconst FOCUS_GUARD_ATTRIBUTE = \"data-focus-guard\";\n\nconst focusGuardStyle = {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: 0,\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n border: 0,\n} as const;\n\nconst isElementVisible = (element: HTMLElement) => {\n const style = globalThis.getComputedStyle(element);\n return (\n style.visibility !== \"hidden\" &&\n style.display !== \"none\" &&\n element.offsetParent !== null\n );\n};\n\nconst getFocusableElements = (wrapper: HTMLElement, includeWrapper = true) => {\n let focusable = Array.from(wrapper.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) =>\n !el.hasAttribute(FOCUS_GUARD_ATTRIBUTE) &&\n isElementVisible(el) &&\n el.tabIndex !== -1,\n );\n\n if (includeWrapper && wrapper.tabIndex >= 0) {\n focusable = [wrapper, ...focusable];\n }\n\n return focusable;\n};\n\nconst focusWrapper = (wrapper: HTMLElement, options?: FocusOptions) => {\n if (wrapper.tabIndex >= 0) {\n wrapper.focus(options);\n return;\n }\n\n const focusable = getFocusableElements(wrapper, false);\n focusable[0]?.focus(options);\n};\n\nconst focusEdgeElement = (\n wrapper: HTMLElement,\n position: \"first\" | \"last\",\n options?: FocusOptions,\n) => {\n const focusable = getFocusableElements(wrapper, false);\n const target = position === \"last\" ? focusable.at(-1) : focusable[0];\n\n if (target) {\n target.focus(options);\n return;\n }\n\n focusWrapper(wrapper, options);\n};\n\nexport const Modal = ({\n isOpen,\n onClose,\n children,\n whitoutBackground = false,\n closeButton = false,\n closeDisabled = false,\n escapeToClose = true,\n disableFocus: disableFocusProp,\n disableFocusRestore = false,\n existTabIndex = true,\n zIndexLevel = 100,\n onCloseComplete,\n alignTop = false,\n animated: animatedProp,\n preventBodyScroll = true,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- overlayColor reservado para uso futuro\n overlayColor: _overlayColor = \"blue\",\n ...props\n}: ModalProps) => {\n const modalId = useId();\n const ctx = useModalGlobalContext();\n const animated = animatedProp ?? ctx?.animated ?? true;\n const disableFocus = disableFocusProp ?? ctx?.disableFocus ?? false;\n const ariaLabelledBy = props[\"aria-labelledby\"];\n const modalRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n const handleStartFocusGuard = () => {\n const wrapper = modalRef.current;\n if (!wrapper) return;\n focusEdgeElement(wrapper, \"last\", { preventScroll: true });\n };\n const handleEndFocusGuard = () => {\n const wrapper = modalRef.current;\n if (!wrapper) return;\n focusEdgeElement(wrapper, \"first\", { preventScroll: true });\n };\n\n // CSS animation state (replaces framer-motion AnimatePresence)\n const [mounted, setMounted] = useState(false);\n const [visible, setVisible] = useState(false);\n\n // Cache children during exit animation (replicates AnimatePresence behavior):\n // when global state clears data before the modal finishes closing, the cached\n // children keep the content visible throughout the exit animation.\n const [cachedChildren, setCachedChildren] = useState<ReactNode>(children);\n useEffect(() => {\n if (isOpen) {\n setCachedChildren(children);\n }\n }, [isOpen, children]);\n\n useEffect(() => {\n if (!animated) return;\n if (isOpen) {\n setMounted(true);\n const raf = requestAnimationFrame(() => {\n requestAnimationFrame(() => setVisible(true));\n });\n return () => cancelAnimationFrame(raf);\n } else {\n setVisible(false);\n const timer = setTimeout(() => {\n setMounted(false);\n onCloseComplete?.();\n }, 200);\n return () => clearTimeout(timer);\n }\n }, [isOpen, animated, onCloseComplete]);\n\n // Body scroll lock — usa counter global para soportar múltiples modales simultáneos\n useLayoutEffect(() => {\n if (isOpen) lockBodyScroll(modalId, preventBodyScroll);\n return () => {\n if (isOpen) unlockBodyScroll(modalId, preventBodyScroll);\n };\n }, [isOpen, preventBodyScroll, modalId]);\n\n // Scroll reset when opening\n useEffect(() => {\n if (!isOpen) return;\n const resetScroll = () => {\n const el = contentRef.current;\n if (!el) return;\n el.style.scrollBehavior = \"auto\";\n el.scrollTop = 0;\n requestAnimationFrame(() => {\n el.scrollTop = 0;\n setTimeout(() => {\n el.style.scrollBehavior = \"smooth\";\n }, 10);\n });\n };\n resetScroll();\n [10, 50, 100, 200].forEach((d) => setTimeout(resetScroll, d));\n }, [isOpen]);\n\n // Keyboard handling and focus trap\n useEffect(() => {\n const pendingTasks: Array<ReturnType<typeof globalThis.setTimeout>> = [];\n\n const handleDocumentFocusIn = (e: FocusEvent) => {\n if (!isOpen || disableFocus) return;\n const wrapper = modalRef.current;\n const target = e.target;\n\n if (!wrapper || !(target instanceof HTMLElement) || wrapper.contains(target)) {\n return;\n }\n\n requestAnimationFrame(() => {\n const currentActive = document.activeElement;\n if (currentActive instanceof HTMLElement && wrapper.contains(currentActive)) {\n return;\n }\n\n focusWrapper(wrapper, { preventScroll: true });\n });\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && escapeToClose && !closeDisabled) {\n onClose();\n return;\n }\n\n if (!isOpen || disableFocus) return;\n const wrapper = modalRef.current;\n if (!wrapper) return;\n\n const focusable = getFocusableElements(wrapper);\n const active = (document.activeElement as HTMLElement) || null;\n\n const arrowKeys = [\"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"];\n if (arrowKeys.includes(e.key)) {\n if (active && wrapper.contains(active)) {\n const activeIndex = focusable.indexOf(active);\n if (\n (e.key === \"ArrowUp\" || e.key === \"ArrowLeft\") &&\n activeIndex === 0\n ) {\n e.preventDefault();\n e.stopPropagation();\n if (focusable.length > 1) focusable.at(-1)?.focus();\n else active.focus();\n return;\n }\n if (\n (e.key === \"ArrowDown\" || e.key === \"ArrowRight\") &&\n activeIndex === focusable.length - 1\n ) {\n e.preventDefault();\n e.stopPropagation();\n if (focusable.length > 1) focusable[0].focus();\n else active.focus();\n return;\n }\n requestAnimationFrame(() => {\n const currentActive = document.activeElement as HTMLElement;\n if (!currentActive || !wrapper.contains(currentActive)) {\n if (activeIndex !== -1 && focusable[activeIndex])\n focusable[activeIndex].focus();\n else if (focusable.length > 0) focusable[0].focus();\n else wrapper.focus();\n }\n });\n } else {\n e.preventDefault();\n if (focusable.length > 0) {\n if (e.key === \"ArrowUp\" || e.key === \"ArrowLeft\")\n focusable.at(-1)?.focus();\n else focusable[0].focus();\n } else {\n wrapper.focus();\n }\n }\n return;\n }\n\n if (e.key !== \"Tab\") return;\n if (focusable.length === 0) {\n e.preventDefault();\n wrapper.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable.at(-1);\n const isShift = e.shiftKey;\n\n if (!first || !last) {\n e.preventDefault();\n wrapper.focus();\n return;\n }\n\n if (!active || !wrapper.contains(active)) {\n e.preventDefault();\n (isShift ? last : first).focus();\n return;\n }\n\n const activeIndex = focusable.indexOf(active);\n if (\n !isShift &&\n (active === last || activeIndex === focusable.length - 1)\n ) {\n e.preventDefault();\n first.focus();\n return;\n }\n\n if (isShift) {\n e.preventDefault();\n if (active === first || active === wrapper || activeIndex === 0)\n last.focus();\n else if (activeIndex > 0) focusable[activeIndex - 1].focus();\n else last.focus();\n }\n };\n\n if (isOpen && !disableFocus) {\n previousActiveElement.current = document.activeElement as HTMLElement;\n\n const focusInitial = (wrapper: HTMLElement) => {\n focusWrapper(wrapper, { preventScroll: true });\n };\n\n const bindFocusManagement = (attempt = 0) => {\n const wrapper = modalRef.current;\n if (!wrapper) {\n if (attempt < 10) {\n pendingTasks.push(\n globalThis.setTimeout(() => bindFocusManagement(attempt + 1), 25),\n );\n }\n return;\n }\n\n focusInitial(wrapper);\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"focusin\", handleDocumentFocusIn, true);\n pendingTasks.push(globalThis.setTimeout(() => bindFocusManagement(), 0));\n } else if (isOpen && disableFocus) {\n document.addEventListener(\"keydown\", handleKeyDown);\n }\n\n return () => {\n pendingTasks.forEach((task) => globalThis.clearTimeout(task));\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"focusin\", handleDocumentFocusIn, true);\n if (\n !disableFocus &&\n !disableFocusRestore &&\n previousActiveElement.current\n ) {\n previousActiveElement.current.focus();\n }\n };\n }, [\n isOpen,\n onClose,\n closeDisabled,\n escapeToClose,\n disableFocus,\n disableFocusRestore,\n ariaLabelledBy,\n ]);\n\n // Sin animación: renderizar directo desde isOpen (sin delay de useEffect)\n if (!animated && !isOpen) return null;\n // Con animación: usar mounted para controlar enter/exit transitions\n if (animated && !mounted) return null;\n\n const contentClass = [\n \"relative flex flex-col items-center justify-start\",\n whitoutBackground\n ? \"bg-transparent\"\n : [\n \"min-w-[320px] w-[95vw] max-w-[95vw] max-h-[90vh]\",\n \"overflow-y-auto scroll-smooth\",\n \"md:max-w-[1000px]\",\n ].join(\" \"),\n props.className || \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <Portal>\n {/* Backdrop */}\n <div\n style={{ zIndex: zIndexLevel }}\n className={[\n \"fixed inset-0 bg-onpe-blue\",\n animated ? \"transition-opacity duration-200\" : \"\",\n animated ? (visible ? \"opacity-80\" : \"opacity-0\") : \"opacity-80\",\n ].join(\" \")}\n onClick={onClose}\n />\n\n {/* Container */}\n <div\n style={{ zIndex: zIndexLevel + 10 }}\n className={[\n \"fixed top-0 w-full h-screen grid\",\n alignTop ? \"place-items-start pt-8\" : \"place-items-center\",\n animated ? \"transition-all duration-200\" : \"\",\n animated\n ? visible\n ? \"opacity-100 scale-100 translate-y-0\"\n : \"opacity-[0.2] scale-95 -translate-y-5\"\n : \"opacity-100 scale-100 translate-y-0\",\n ].join(\" \")}\n >\n <div className=\"relative grid place-items-center\">\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n {...(existTabIndex && { tabIndex: disableFocus ? -1 : 0 })}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={props[\"aria-labelledby\"]}\n aria-describedby={props[\"aria-describedby\"]}\n aria-label={props[\"aria-label\"]}\n >\n <span\n tabIndex={disableFocus ? -1 : 0}\n aria-hidden=\"true\"\n {...{ [FOCUS_GUARD_ATTRIBUTE]: \"start\" }}\n style={focusGuardStyle}\n onFocus={handleStartFocusGuard}\n />\n <div ref={contentRef} className={contentClass}>\n {isOpen ? children : cachedChildren}\n </div>\n {closeButton && (\n <button\n onClick={onClose}\n className=\"absolute top-2.5 right-2.5 text-onpe-red cursor-pointer w-4 h-4 border-none bg-transparent p-0 md:w-6 md:h-6\"\n aria-label=\"Cerrar\"\n type=\"button\"\n >\n <IconCloseRadius aria-hidden=\"true\" className=\"w-full h-full\" />\n </button>\n )}\n <span\n tabIndex={disableFocus ? -1 : 0}\n aria-hidden=\"true\"\n {...{ [FOCUS_GUARD_ATTRIBUTE]: \"end\" }}\n style={focusGuardStyle}\n onFocus={handleEndFocusGuard}\n />\n </div>\n </div>\n </div>\n </Portal>\n );\n};\n\nexport default Modal;\n","type ButtonColor =\n | \"blue\"\n | \"skyblue\"\n | \"skyblue-light\"\n | \"yellow\"\n | \"light-skyblue\"\n | \"gray\"\n | \"gray-light\"\n | \"gray-extra-light\"\n | \"red\"\n | \"dark-gray\"\n | \"green\"\n | \"yellow-light\"\n | \"primary\";\n\ntype ButtonSize = \"small\" | \"normal\" | \"large\";\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n color: ButtonColor;\n title: string;\n size?: ButtonSize;\n}\n\nconst colorClasses: Record<ButtonColor, string> = {\n blue: \"bg-onpe-blue\",\n skyblue: \"bg-onpe-skyblue\",\n \"skyblue-light\": \"bg-onpe-skyblue-light\",\n yellow: \"bg-onpe-yellow\",\n \"light-skyblue\": \"bg-onpe-light-skyblue\",\n gray: \"bg-onpe-gray\",\n \"gray-light\": \"bg-onpe-gray-light\",\n \"gray-extra-light\": \"bg-onpe-gray-extra-light\",\n red: \"bg-onpe-red\",\n \"dark-gray\": \"bg-onpe-dark-gray\",\n green: \"bg-onpe-green\",\n \"yellow-light\": \"bg-onpe-yellow-light\",\n primary: \"bg-onpe-blue\",\n};\n\nconst sizeClasses: Record<ButtonSize, string> = {\n small: \"h-10 text-sm\",\n normal: \"h-12 text-base\",\n large: \"h-14 text-lg\",\n};\n\nexport function Button({\n color,\n title,\n size = \"normal\",\n className = \"\",\n ...props\n}: ButtonProps) {\n return (\n <button\n className={[\n \"inline-flex items-center justify-center\",\n \"min-w-[200px] border-none\",\n \"text-white font-semibold cursor-pointer\",\n \"transition-all duration-300 ease-in-out\",\n \"disabled:cursor-default disabled:!bg-onpe-gray\",\n colorClasses[color],\n sizeClasses[size],\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n {...props}\n >\n {title}\n </button>\n );\n}\n\nexport default Button;\n","import { SVGProps } from \"react\";\n\nexport const IconCheck = (props: SVGProps<SVGSVGElement>) => (\n <svg width={64} height={64} viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M28.2673 44.2663L47.0673 25.4663L43.334 21.733L28.2673 36.7997L20.6673 29.1997L16.934 32.933L28.2673 44.2663ZM32.0007 58.6663C28.3118 58.6663 24.8451 57.9659 21.6007 56.565C18.3562 55.1641 15.534 53.2646 13.134 50.8663C10.734 48.4663 8.83443 45.6441 7.43532 42.3997C6.03621 39.1552 5.33576 35.6886 5.33398 31.9997C5.33398 28.3108 6.03443 24.8441 7.43532 21.5997C8.83621 18.3552 10.7358 15.533 13.134 13.133C15.534 10.733 18.3562 8.83345 21.6007 7.43434C24.8451 6.03523 28.3118 5.33479 32.0007 5.33301C35.6895 5.33301 39.1562 6.03345 42.4007 7.43434C45.6451 8.83523 48.4673 10.7348 50.8673 13.133C53.2673 15.533 55.1678 18.3552 56.5686 21.5997C57.9695 24.8441 58.6691 28.3108 58.6673 31.9997C58.6673 35.6886 57.9669 39.1552 56.566 42.3997C55.1651 45.6441 53.2655 48.4663 50.8673 50.8663C48.4673 53.2663 45.6451 55.1668 42.4007 56.5677C39.1562 57.9686 35.6895 58.6681 32.0007 58.6663ZM32.0007 53.333C37.9562 53.333 43.0006 51.2663 47.134 47.133C51.2673 42.9997 53.334 37.9552 53.334 31.9997C53.334 26.0441 51.2673 20.9997 47.134 16.8663C43.0006 12.733 37.9562 10.6663 32.0007 10.6663C26.0451 10.6663 21.0007 12.733 16.8673 16.8663C12.734 20.9997 10.6673 26.0441 10.6673 31.9997C10.6673 37.9552 12.734 42.9997 16.8673 47.133C21.0007 51.2663 26.0451 53.333 32.0007 53.333Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport default IconCheck;\n","import { SVGProps } from \"react\";\n\nexport const IconInfo = (props: SVGProps<SVGSVGElement>) => (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\" fill=\"currentColor\" />\n </svg>\n);\n\nexport default IconInfo;\n","import type { SVGProps } from \"react\";\n\nexport const IconQuestion = (props: SVGProps<SVGSVGElement>) => (\n <svg\n width=\"64\"\n height=\"64\"\n viewBox=\"0 0 64 64\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M31.9997 5.33325C46.7277 5.33325 58.6663 17.2719 58.6663 31.9999C58.6663 46.7279 46.7277 58.6666 31.9997 58.6666C17.2717 58.6666 5.33301 46.7279 5.33301 31.9999C5.33301 17.2719 17.2717 5.33325 31.9997 5.33325ZM31.9997 10.6666C26.3417 10.6666 20.9155 12.9142 16.9147 16.915C12.914 20.9157 10.6663 26.342 10.6663 31.9999C10.6663 37.6579 12.914 43.0841 16.9147 47.0849C20.9155 51.0856 26.3417 53.3332 31.9997 53.3332C37.6576 53.3332 43.0838 51.0856 47.0846 47.0849C51.0854 43.0841 53.333 37.6579 53.333 31.9999C53.333 26.342 51.0854 20.9157 47.0846 16.915C43.0838 12.9142 37.6576 10.6666 31.9997 10.6666ZM31.9997 42.6666C32.7069 42.6666 33.3852 42.9475 33.8853 43.4476C34.3854 43.9477 34.6663 44.626 34.6663 45.3332C34.6663 46.0405 34.3854 46.7188 33.8853 47.2189C33.3852 47.719 32.7069 47.9999 31.9997 47.9999C31.2924 47.9999 30.6142 47.719 30.1141 47.2189C29.614 46.7188 29.333 46.0405 29.333 45.3332C29.333 44.626 29.614 43.9477 30.1141 43.4476C30.6142 42.9475 31.2924 42.6666 31.9997 42.6666ZM31.9997 17.3333C34.2458 17.3333 36.4217 18.1155 38.1538 19.5455C39.8858 20.9755 41.0658 22.964 41.4912 25.1695C41.9165 27.3749 41.5605 29.6596 40.4844 31.6311C39.4084 33.6027 37.6793 35.1379 35.5943 35.9732C35.2855 36.0868 35.0072 36.2703 34.781 36.5093C34.6637 36.6426 34.645 36.8133 34.6477 36.9893L34.6663 37.3333C34.6656 38.0129 34.4053 38.6667 33.9387 39.1609C33.4722 39.6551 32.8345 39.9525 32.156 39.9924C31.4774 40.0322 31.8093 39.8115 30.2881 39.3752C29.7669 38.939 29.4319 38.3202 29.3517 37.6452L29.333 37.3333V36.6666C29.333 33.5919 31.813 31.7466 33.6103 31.0239C34.3418 30.7318 34.98 30.246 35.4562 29.6185C35.9324 28.9911 36.2287 28.2458 36.3133 27.4627C36.3979 26.6796 36.2675 25.8883 35.9363 25.1736C35.605 24.459 35.0854 23.8481 34.4331 23.4065C33.7808 22.965 33.0206 22.7094 32.2341 22.6673C31.4475 22.6252 30.6644 22.7982 29.9687 23.1676C29.2731 23.537 28.6912 24.0889 28.2855 24.7641C27.8799 25.4393 27.6658 26.2122 27.6663 26.9999C27.6663 27.7072 27.3854 28.3854 26.8853 28.8855C26.3852 29.3856 25.7069 29.6666 24.9997 29.6666C24.2924 29.6666 23.6142 29.3856 23.1141 28.8855C22.614 28.3854 22.333 27.7072 22.333 26.9999C22.333 24.4362 23.3515 21.9774 25.1643 20.1646C26.9772 18.3517 29.4359 17.3333 31.9997 17.3333Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport default IconQuestion;\n","import { SVGProps } from \"react\";\n\nexport const IconSpinnerDesktop = (props: SVGProps<SVGSVGElement>) => (\n <svg width={102} height={102} viewBox=\"0 0 102 102\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M50.9999 3.08313C23.9241 3.08208 3.08296 24.6456 3.08325 51C3.08354 75.4375 22.453 98.9167 50.9999 98.9167C77.5573 98.9167 98.9166 77.3542 98.9166 51\"\n stroke=\"currentColor\"\n strokeWidth={6}\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport default IconSpinnerDesktop;\n","import { SVGProps } from \"react\";\n\nexport const IconSpinnerMobile = (props: SVGProps<SVGSVGElement>) => (\n <svg width={33} height={33} viewBox=\"0 0 33 33\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M16.5 3C8.87169 2.9997 2.99992 9.07499 3 16.5C3.00008 23.385 8.45721 30 16.5 30C23.9822 30 30 23.925 30 16.5\"\n stroke=\"currentColor\"\n strokeWidth={6}\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport default IconSpinnerMobile;\n","import type { SVGProps } from \"react\";\n\nexport const IconWarningNotRecommended = (props: SVGProps<SVGSVGElement>) => (\n <svg\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 49 42\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M0 42L24.5 0L49 42H0ZM7.68409 37.5789H41.3159L24.5 8.84211L7.68409 37.5789ZM24.5 35.3684C25.1311 35.3684 25.6604 35.1562 26.088 34.7318C26.5157 34.3074 26.7288 33.7827 26.7273 33.1579C26.7273 32.5316 26.5135 32.0062 26.0858 31.5818C25.6582 31.1574 25.1296 30.9459 24.5 30.9474C23.8689 30.9474 23.3396 31.1596 22.912 31.584C22.4843 32.0084 22.2712 32.5331 22.2727 33.1579C22.2727 33.7842 22.4865 34.3096 22.9142 34.734C23.3418 35.1584 23.8704 35.3699 24.5 35.3684ZM22.2727 28.7368H26.7273V17.6842H22.2727V28.7368Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport default IconWarningNotRecommended;\n","import { type ReactNode } from \"react\";\nimport { Modal } from \"../../Modal/Modal\";\nimport { Button } from \"../../Button/Button\";\nimport { IconCheck } from \"../../../icons/Actions/IconCheck\";\nimport { IconWarningNotRecommended } from \"../../../icons\";\nimport { IconQuestion } from \"../../../icons/Actions/IconQuestion\";\nimport { IconInfo } from \"../../../icons/Actions/IconInfo\";\n\nexport type ModalType = \"warning\" | \"success\" | \"question\" | \"info\" | \"none\";\n\n/** Mapa de override de color a clase CSS (icono + título) */\nconst colorOverrideMap: Record<string, string> = {\n red: \"text-onpe-red\",\n blue: \"text-onpe-blue\",\n skyblue: \"text-onpe-skyblue\",\n yellow: \"text-onpe-yellow\",\n};\n\nfunction renderIcon(type: ModalType, colorClass: string): ReactNode {\n if (type === \"none\") return null;\n if (type === \"success\") {\n return (\n <IconCheck role=\"presentation\" className={`w-16 h-16 ${colorClass}`} />\n );\n }\n if (type === \"question\") {\n return (\n <IconQuestion role=\"presentation\" className={`w-16 h-16 ${colorClass}`} />\n );\n }\n if (type === \"info\") {\n return (\n <IconInfo role=\"presentation\" className={`w-16 h-16 ${colorClass}`} />\n );\n }\n // error | warning\n return (\n <IconWarningNotRecommended\n role=\"presentation\"\n className={`w-16 h-16 ${colorClass}`}\n />\n );\n}\n\nconst defaultTitleByType: Record<string, string> = {\n success: \"Confirmación\",\n warning: \"Advertencia\",\n question: \"Atención\",\n info: \"Información\",\n};\n\nexport interface ModalConfirmProps {\n isOpen: boolean;\n onClose: () => void;\n title?: string;\n /** Contenido del modal (string o JSX) */\n message?: ReactNode;\n /** Alias de message */\n content?: ReactNode;\n /** Tipo semántico: determina icono, color de título y color de botón confirmar */\n type?: ModalType;\n /**\n * \"single\" → un botón \"Confirmar\".\n * \"double\" → \"Cancelar\" + \"Confirmar\".\n * \"confirm\" → \"No\" + \"Sí\" (diálogo de confirmación Sí/No).\n */\n buttonMode?: \"single\" | \"double\" | \"confirm\";\n /** Deshabilita el botón confirmar */\n disabledConfirmButton?: boolean;\n /** Deshabilita el cierre del modal */\n closeDisabled?: boolean;\n /**\n * Override del color del icono y título.\n * Si no se provee, se deriva automáticamente del `type`.\n */\n color?: \"red\" | \"blue\" | \"skyblue\" | \"yellow\";\n onConfirm?: () => void | Promise<void>;\n onCancel?: () => void | Promise<void>;\n textButtonConfirm?: string;\n textButtonCancel?: string;\n className?: string;\n zIndexLevel?: number;\n withoutAutoClose?: boolean;\n disableFocus?: boolean;\n /** Muestra el botón X para cerrar el modal */\n closeButton?: boolean;\n /** Alinea el texto del mensaje a la izquierda (justify) en vez de centrado */\n alignJustify?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n alignTop?: boolean;\n /** Habilita animación de entrada/salida (default: true) */\n animated?: boolean;\n /** Bloquea el scroll del body mientras el modal está abierto (default: true) */\n preventBodyScroll?: boolean;\n}\n\nexport const ModalConfirm = ({\n isOpen = false,\n onClose = () => {},\n withoutAutoClose = false,\n title,\n message,\n content,\n type = \"warning\",\n buttonMode,\n disabledConfirmButton = false,\n closeDisabled = false,\n color,\n onConfirm = () => {},\n onCancel = () => {},\n textButtonConfirm,\n textButtonCancel,\n className = \"\",\n zIndexLevel = 100,\n disableFocus = false,\n closeButton = false,\n alignJustify = false,\n alignTop = false,\n animated = true,\n preventBodyScroll = true,\n}: ModalConfirmProps) => {\n const titleId = \"modal-confirm-title\";\n const messageId = \"modal-confirm-message\";\n\n const effectiveTitle = title ?? defaultTitleByType[type] ?? \"\";\n // Título e ícono siempre skyblue por defecto; `color` es el único override\n const effectiveColorClass = color\n ? (colorOverrideMap[color] ?? \"text-onpe-skyblue\")\n : \"text-onpe-skyblue\";\n const effectiveButtonMode =\n buttonMode ?? (type === \"question\" ? \"confirm\" : \"single\");\n const isConfirmMode = effectiveButtonMode === \"confirm\";\n const showTwoButtons = effectiveButtonMode === \"double\" || isConfirmMode;\n const confirmLabel =\n textButtonConfirm ??\n (isConfirmMode\n ? \"Sí\"\n : effectiveButtonMode === \"double\"\n ? \"Confirmar\"\n : \"Aceptar\");\n const cancelLabel = textButtonCancel ?? (isConfirmMode ? \"No\" : \"Cancelar\");\n\n const handleConfirm = async () => {\n try {\n await onConfirm();\n if (!withoutAutoClose) onClose();\n } catch (error) {\n console.error(\"Error en handleConfirm:\", error);\n if (!withoutAutoClose) onClose();\n }\n };\n\n const handleCancel = () => {\n onCancel();\n if (!withoutAutoClose) onClose();\n };\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n className={`bg-white pt-[30px] pb-[30px] px-[30px] max-w-[719px]! ${className}`}\n closeButton={closeButton}\n closeDisabled={closeDisabled}\n zIndexLevel={zIndexLevel}\n aria-labelledby={titleId}\n aria-describedby={messageId}\n disableFocus={disableFocus}\n alignTop={alignTop}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n >\n {/* Icono */}\n <div className=\"flex items-center justify-center\">\n {renderIcon(type, effectiveColorClass)}\n </div>\n\n {/* Título */}\n <p\n id={titleId}\n className={[\n \"text-lg md:text-2xl font-semibold text-center mt-0 md:mt-4\",\n effectiveColorClass,\n ].join(\" \")}\n >\n {effectiveTitle}\n </p>\n\n {/* Mensaje / Contenido */}\n {message &&\n (typeof message === \"string\" ? (\n <div\n id={messageId}\n className={`mt-7 w-full text-sm md:text-lg text-black ${alignJustify ? \"text-justify\" : \"text-center\"}`}\n dangerouslySetInnerHTML={{ __html: message }}\n />\n ) : (\n <div\n id={messageId}\n className={`mt-7 w-full text-sm md:text-lg max-w-full text-black ${alignJustify ? \"text-justify\" : \"text-center\"}`}\n >\n {message}\n </div>\n ))}\n {content && (\n <div\n id={message ? undefined : messageId}\n className={`text-sm w-full md:text-lg max-w-full text-black ${alignJustify ? \"text-justify\" : \"text-center\"}`}\n >\n {content}\n </div>\n )}\n\n {/* Mobile: apilado */}\n <div className=\"flex flex-col items-center justify-center w-full gap-5 mt-11 md:hidden\">\n <Button\n className=\"w-full max-w-[200px]\"\n color=\"red\"\n title={confirmLabel}\n onClick={handleConfirm}\n disabled={disabledConfirmButton}\n />\n {showTwoButtons && (\n <Button\n className=\"w-full max-w-[200px]\"\n color=\"skyblue\"\n title={cancelLabel}\n onClick={handleCancel}\n />\n )}\n </div>\n\n {/* Desktop: fila */}\n <div className=\"hidden md:flex md:flex-row items-center justify-center w-full gap-5 mt-11\">\n {showTwoButtons && (\n <Button\n className=\"w-[200px]\"\n color=\"skyblue\"\n title={cancelLabel}\n onClick={handleCancel}\n />\n )}\n <Button\n className=\"w-[200px]\"\n color=\"red\"\n title={confirmLabel}\n onClick={handleConfirm}\n disabled={disabledConfirmButton}\n />\n </div>\n </Modal>\n );\n};\n\nexport default ModalConfirm;\n","import { type ReactNode, useEffect, useState } from \"react\";\nimport { Modal } from \"../../Modal/Modal\";\nimport { IconSpinnerDesktop } from \"../../../icons/Actions/IconSpinnerDesktop\";\nimport { IconSpinnerMobile } from \"../../../icons/Actions/IconSpinnerMobile\";\n\nexport interface ModalLoadingProps {\n isOpen: boolean;\n onClose?: () => void;\n message?: string;\n className?: string;\n zIndexLevel?: number;\n animated?: boolean;\n preventBodyScroll?: boolean;\n /** Spinner personalizado. Si no se provee, se usa el spinner por defecto de la librería. */\n spinner?: ReactNode;\n}\n\nexport const ModalLoading = ({\n isOpen = false,\n onClose = () => {},\n message = \"Cargando...\",\n className = \"\",\n zIndexLevel = 100,\n animated = true,\n preventBodyScroll = true,\n spinner,\n}: ModalLoadingProps) => {\n const [announceMessage, setAnnounceMessage] = useState(\"\");\n\n useEffect(() => {\n if (!isOpen) {\n setAnnounceMessage(\"\");\n return;\n }\n setAnnounceMessage(\"\");\n const t = globalThis.setTimeout(() => {\n setAnnounceMessage(message);\n }, 150);\n return () => {\n globalThis.clearTimeout(t);\n };\n }, [isOpen, message]);\n\n return (\n <Modal\n disableFocus\n zIndexLevel={zIndexLevel}\n isOpen={isOpen}\n onClose={onClose}\n className={className}\n closeDisabled\n whitoutBackground={true}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n >\n <div className=\"sr-only\" aria-live=\"assertive\" aria-atomic=\"true\">\n {announceMessage}\n </div>\n {spinner ?? (\n <>\n <IconSpinnerDesktop\n className=\"hidden md:block text-white animate-spin\"\n aria-hidden=\"true\"\n />\n <IconSpinnerMobile\n className=\"block md:hidden text-white animate-spin\"\n aria-hidden=\"true\"\n />\n </>\n )}\n <p\n className={`text-white leading-normal text-2xl md:text-[64px] text-center ${spinner ? \"mt-5\" : \"mt-10 md:mt-20\"}`}\n >\n {message}\n </p>\n </Modal>\n );\n};\n\nexport default ModalLoading;\n","\"use client\";\n\nimport { Modal } from \"../../Modal/Modal\";\n\ninterface ModalLoadingPercentageProps {\n isOpen: boolean;\n message: string;\n percentage: number;\n zIndexLevel?: number;\n animated?: boolean;\n preventBodyScroll?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n alignTop?: boolean;\n}\n\nexport const ModalLoadingPercentage = ({\n isOpen,\n message,\n percentage,\n zIndexLevel = 300,\n animated = true,\n preventBodyScroll = true,\n alignTop = false,\n}: ModalLoadingPercentageProps) => {\n const clamped = Math.min(100, Math.max(0, percentage));\n\n return (\n <Modal\n disableFocus\n isOpen={isOpen}\n onClose={() => {}}\n closeDisabled\n whitoutBackground\n zIndexLevel={zIndexLevel}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n alignTop={alignTop}\n >\n <div className=\"bg-transparent flex-col flex items-center p-[50px]\">\n <p className=\"text-white leading-normal text-6xl text-center mt-4\">\n {message} {Math.floor(clamped)}%\n </p>\n <div className=\"w-[600px] h-10 bg-white inline-block\">\n <div\n style={{ width: `${clamped}%` }}\n className=\"h-10 bg-blue border-white border-2 transition-all ease-in-out duration-300\"\n />\n </div>\n </div>\n </Modal>\n );\n};\n\nexport default ModalLoadingPercentage;\n","\"use client\";\n\nimport { type ReactNode, useEffect, useMemo } from \"react\";\nimport { ModalGlobalContext } from \"./ModalGlobalContext\";\nimport { useModalGlobalStore } from \"../../store/modalGlobal/useModalGlobalStore\";\nimport { useModalLoadingStore } from \"../../store/modalGlobal/useModalLoadingStore\";\nimport { useModalLoadingPercentageStore } from \"../../store/modalGlobal/useModalLoadingPercentageStore\";\nimport { ModalConfirm } from \"../Feedback/ModalConfirm/ModalConfirm\";\nimport { ModalLoading } from \"../Feedback/ModalLoading/ModalLoading\";\nimport { ModalLoadingPercentage } from \"../Feedback/ModalLoadingPercentage/ModalLoadingPercentage\";\n\ninterface ModalGlobalProviderProps {\n children: ReactNode;\n /** z-index del modal principal (default: 200) */\n zIndexLevel?: number;\n /** z-index del modal de loading (default: 300) */\n zIndexLoading?: number;\n /** z-index del modal de loading con porcentaje (default: 300) */\n zIndexLoadingPercentage?: number;\n /** Habilita animación de entrada/salida en todos los modales (default: true) */\n animated?: boolean;\n /** Bloquea el scroll del body en todos los modales (default: true) */\n preventBodyScroll?: boolean;\n /** Spinner personalizado para ModalLoading. Si no se provee, se usa el spinner por defecto. */\n loadingSpinner?: ReactNode;\n /** Alinea el ModalLoadingPercentage al tope de la pantalla (default: false) */\n loadingPercentageAlignTop?: boolean;\n /** Texto por defecto del botón confirmar cuando el payload no lo especifica */\n defaultTextButtonConfirm?: string;\n /** Texto por defecto del botón cancelar cuando el payload no lo especifica */\n defaultTextButtonCancel?: string;\n /** Deshabilita el manejo de focus en todos los modales (default: false) */\n disableFocus?: boolean;\n}\n\nexport const ModalGlobalProvider = ({\n children,\n zIndexLevel = 200,\n zIndexLoading = 300,\n zIndexLoadingPercentage = 300,\n animated = true,\n preventBodyScroll = true,\n loadingSpinner,\n loadingPercentageAlignTop = false,\n defaultTextButtonConfirm,\n defaultTextButtonCancel,\n disableFocus = false,\n}: ModalGlobalProviderProps) => {\n const isOpen = useModalGlobalStore((s) => s.isOpen);\n const payload = useModalGlobalStore((s) => s.payload);\n const modalId = useModalGlobalStore((s) => s.modalId);\n const isTriState = useModalGlobalStore((s) => s.isTriState);\n const closeModal = useModalGlobalStore((s) => s.closeModal);\n const closeModalWithResult = useModalGlobalStore(\n (s) => s.closeModalWithResult,\n );\n const isLoadingOpen = useModalLoadingStore((s) => s.isOpen);\n const loadingMessage = useModalLoadingStore((s) => s.message);\n const isPercentageOpen = useModalLoadingPercentageStore((s) => s.isOpen);\n const percentageMessage = useModalLoadingPercentageStore((s) => s.message);\n const percentage = useModalLoadingPercentageStore((s) => s.percentage);\n\n // Auto-confirmar el modal después del timeout especificado\n useEffect(() => {\n if (!isOpen || !payload?.autoConfirmTimeout) return;\n\n const timerId = setTimeout(() => {\n closeModal(true);\n }, payload.autoConfirmTimeout);\n\n return () => clearTimeout(timerId);\n }, [isOpen, modalId]);\n\n const contextValue = useMemo(\n () => ({ animated, disableFocus }),\n [animated, disableFocus],\n );\n\n return (\n <ModalGlobalContext.Provider value={contextValue}>\n {children}\n\n {/* Modal principal — usa ModalConfirm de la librería directamente */}\n <ModalConfirm\n isOpen={isOpen}\n onClose={() => closeModalWithResult(\"close\")}\n title={payload?.title}\n message={payload?.message}\n content={payload?.content}\n type={payload?.iconType ?? payload?.type}\n buttonMode={payload?.buttonMode}\n disabledConfirmButton={payload?.disabledConfirmButton}\n closeDisabled={payload?.closeDisabled}\n color={payload?.color}\n onConfirm={() => closeModal(true)}\n onCancel={() => closeModal(false)}\n withoutAutoClose\n textButtonConfirm={\n payload?.textButtonConfirm ?? defaultTextButtonConfirm\n }\n textButtonCancel={payload?.textButtonCancel ?? defaultTextButtonCancel}\n closeButton={payload?.closeButton ?? isTriState}\n alignJustify={payload?.alignJustify}\n alignTop={payload?.top}\n zIndexLevel={zIndexLevel}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n disableFocus={disableFocus}\n />\n\n {/* Loading */}\n <ModalLoading\n isOpen={isLoadingOpen}\n message={loadingMessage}\n zIndexLevel={zIndexLoading}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n spinner={loadingSpinner}\n />\n\n {/* Loading con porcentaje */}\n <ModalLoadingPercentage\n isOpen={isPercentageOpen}\n message={percentageMessage}\n percentage={percentage}\n zIndexLevel={zIndexLoadingPercentage}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n alignTop={loadingPercentageAlignTop}\n />\n </ModalGlobalContext.Provider>\n );\n};\n\nexport default ModalGlobalProvider;\n","import { useModalGlobalStore } from \"../store/modalGlobal/useModalGlobalStore\";\nimport { useModalLoadingStore } from \"../store/modalGlobal/useModalLoadingStore\";\nimport { useModalLoadingPercentageStore } from \"../store/modalGlobal/useModalLoadingPercentageStore\";\nimport type { ModalPayload, ModalResult } from \"../store/modalGlobal/useModalGlobalStore\";\n\n/**\n * Open the global modal. Returns a promise that resolves to `true` if the user\n * confirmed, or `false` if they cancelled/closed.\n *\n * @example\n * const confirmed = await showGlobalModal({\n * type: \"question\",\n * title: \"¿Eliminar votante?\",\n * message: \"Esta acción no se puede deshacer.\",\n * buttonMode: \"double\",\n * });\n *\n * @example — with custom JSX content\n * await showGlobalModal({\n * type: \"error\",\n * title: \"Error de sesión\",\n * content: <SesionExpiredDetails />,\n * });\n */\nexport const showGlobalModal = (payload: ModalPayload): Promise<boolean> => {\n // Close loading modals first (ModalGlobal handles its own pending promise internally)\n useModalLoadingStore.getState().closeLoading();\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalGlobalStore.getState().openModal(payload);\n};\n\n/**\n * Like `showGlobalModal` but resolves to `\"confirm\"`, `\"cancel\"`, or `\"close\"`,\n * letting you distinguish between the three ways a modal can be dismissed.\n *\n * @example\n * const result = await showGlobalModalWithClose({\n * type: \"warning\",\n * title: \"Guardar cambios\",\n * buttonMode: \"double\",\n * });\n * if (result === \"confirm\") save();\n * if (result === \"close\") navigateAway();\n */\nexport const showGlobalModalWithClose = (payload: ModalPayload): Promise<ModalResult> => {\n // Close loading modals first (ModalGlobal handles its own pending promise internally)\n useModalLoadingStore.getState().closeLoading();\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalGlobalStore.getState().openModalWithClose(payload);\n};\n\n/**\n * Programmatically close the global modal (resolves as cancelled).\n * Useful for layout/route-change handlers.\n *\n * ⚠️ Always check `isAlreadyHandled()` before calling this from a route handler\n * to avoid closing axios-controlled modals.\n */\nexport const closeGlobalModal = (): void =>\n useModalGlobalStore.getState().closeModal(false);\n\n/** Returns true if the global modal is currently open. */\nexport const isGlobalModalOpen = (): boolean =>\n useModalGlobalStore.getState().isOpen;\n\n/**\n * Returns true if the currently open modal was opened by an axios interceptor\n * (i.e. `alreadyHandled: true` was set). Use this to skip auto-close on\n * route changes.\n *\n * @example — in a Next.js layout\n * router.events.on(\"routeChangeStart\", () => {\n * if (isGlobalModalOpen() && !isAlreadyHandled()) {\n * closeGlobalModal();\n * }\n * });\n */\nexport const isAlreadyHandled = (): boolean =>\n useModalGlobalStore.getState().payload?.alreadyHandled ?? false;\n\n// ---------------------------------------------------------------------------\n// Loading helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Show the global loading modal.\n *\n * @example\n * showGlobalLoading(\"Guardando cambios...\");\n * await api.save(data);\n * closeGlobalLoading();\n */\nexport const showGlobalLoading = (message?: string): number => {\n // Close the other loading modal (safe — no pending promises)\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalLoadingStore.getState().openLoading(message);\n};\n\n/** Close the global loading modal. If sessionId is provided, only closes if it matches. */\nexport const closeGlobalLoading = (sessionId?: number): void =>\n useModalLoadingStore.getState().closeLoading(sessionId);\n\n/** Returns true if the global loading modal is currently visible. */\nexport const isGlobalLoadingOpen = (): boolean =>\n useModalLoadingStore.getState().isOpen;\n\n// ---------------------------------------------------------------------------\n// Loading percentage helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Show the global loading modal with a percentage progress bar.\n *\n * @example\n * showGlobalLoadingPercentage(\"Subiendo archivo...\");\n * for (const chunk of chunks) {\n * await upload(chunk);\n * updateGlobalLoadingPercentage(Math.round((i / chunks.length) * 100));\n * }\n * closeGlobalLoadingPercentage();\n */\n/**\n * Abre el modal de loading con porcentaje. Retorna un sessionId para evitar\n * interferencias si se abre otro modal del mismo tipo antes de cerrar el actual.\n * Pasar el sessionId a updateGlobalLoadingPercentage y closeGlobalLoadingPercentage\n * garantiza que solo la instancia activa pueda actualizar o cerrar el modal.\n */\nexport const showGlobalLoadingPercentage = (message?: string, initialPercentage?: number): number => {\n // Close the other loading modal (safe — no pending promises)\n useModalLoadingStore.getState().closeLoading();\n return useModalLoadingPercentageStore.getState().openLoadingPercentage(message, initialPercentage);\n};\n\n/** Update the percentage value (0–100). Si se pasa sessionId y no coincide con la sesión activa, se ignora. */\nexport const updateGlobalLoadingPercentage = (percentage: number, sessionId?: number): void =>\n useModalLoadingPercentageStore.getState().updatePercentage(percentage, sessionId);\n\n/** Close the global loading percentage modal. Si se pasa sessionId y no coincide con la sesión activa, se ignora. */\nexport const closeGlobalLoadingPercentage = (sessionId?: number): void =>\n useModalLoadingPercentageStore.getState().closeLoadingPercentage(sessionId);\n\n/** Returns true if the global loading percentage modal is currently visible. */\nexport const isGlobalLoadingPercentageOpen = (): boolean =>\n useModalLoadingPercentageStore.getState().isOpen;\n"]}
1
+ {"version":3,"sources":["../src/components/ModalGlobal/ModalGlobalContext.ts","../src/store/modalGlobal/useModalGlobalStore.ts","../src/store/modalGlobal/useModalLoadingStore.ts","../src/store/modalGlobal/useModalLoadingPercentageStore.ts","../src/components/Portal/Portal.tsx","../src/icons/Actions/IconCloseRadius.tsx","../src/components/Modal/Modal.tsx","../src/components/Button/Button.tsx","../src/icons/Actions/IconCheck.tsx","../src/icons/Actions/IconInfo.tsx","../src/icons/Actions/IconQuestion.tsx","../src/icons/Actions/IconSpinnerDesktop.tsx","../src/icons/Actions/IconSpinnerMobile.tsx","../src/icons/Actions/IconWarningNotRecommended.tsx","../src/components/Feedback/ModalConfirm/ModalConfirm.tsx","../src/components/Feedback/ModalLoading/ModalLoading.tsx","../src/components/Feedback/ModalLoadingPercentage/ModalLoadingPercentage.tsx","../src/components/ModalGlobal/ModalGlobalProvider.tsx","../src/utils/showGlobalModal.ts"],"names":["createContext","useContext","create","useState","useEffect","createPortal","jsx","useId","useRef","useLayoutEffect","activeIndex","jsxs","Fragment","useMemo"],"mappings":"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","file":"modal.js","sourcesContent":["import { createContext, useContext } from \"react\";\n\ninterface ModalGlobalContextValue {\n animated: boolean;\n disableFocus: boolean;\n}\n\nexport const ModalGlobalContext = createContext<ModalGlobalContextValue | null>(null);\n\nexport const useModalGlobalContext = () => useContext(ModalGlobalContext);\n","import { create } from \"zustand\";\nimport type { ReactNode } from \"react\";\nimport type { ModalType } from \"../../components/Feedback/ModalConfirm/ModalConfirm\";\n\nexport type { ModalType };\n\nexport type ModalResult = \"confirm\" | \"cancel\" | \"close\";\n\n/**\n * Payload del modal global.\n * Combina los props de ModalGlobalComponent (type, buttonMode, content)\n * con los de ModalConfirm (icon, color, twoButtons).\n * Los props del global component predominan; color e icon son overrides manuales.\n */\nexport interface ModalPayload {\n title?: string;\n /** Contenido del modal (string o JSX). Alias: content */\n message?: ReactNode;\n /** Alias de message para compatibilidad */\n content?: ReactNode;\n /** Tipo semántico: determina icono y color */\n type: ModalType;\n /**\n * Override del icono independiente del `type`.\n * Usa los mismos valores que `type`. Si se provee, tiene prioridad sobre `type` para el icono.\n */\n iconType?: ModalType;\n /**\n * \"single\" → un botón \"Confirmar\".\n * \"double\" → \"Cancelar\" + \"Confirmar\".\n * \"confirm\" → \"No\" + \"Sí\" (diálogo de confirmación).\n */\n buttonMode?: \"single\" | \"double\" | \"confirm\";\n /** Deshabilita el botón confirmar */\n disabledConfirmButton?: boolean;\n /** Deshabilita el cierre del modal */\n closeDisabled?: boolean;\n /** Override manual del color del icono y título */\n color?: \"red\" | \"blue\" | \"skyblue\" | \"yellow\";\n textButtonConfirm?: string;\n textButtonCancel?: string;\n /** Muestra el botón X para cerrar el modal */\n closeButton?: boolean;\n /** Alinea el texto del mensaje a la izquierda (justify) en vez de centrado */\n alignJustify?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n top?: boolean;\n /**\n * Tiempo en ms para auto-confirmar el modal (ej: 30000 = 30s).\n * Útil para modales de error de sesión/red que deben cerrarse solos.\n */\n autoConfirmTimeout?: number;\n /**\n * Marca este modal como controlado por axios interceptor.\n * Cuando es true, los handlers de cambio de ruta NO deben cerrarlo.\n */\n alreadyHandled?: boolean;\n}\n\ninterface ModalGlobalState {\n isOpen: boolean;\n payload: ModalPayload | null;\n modalId: number;\n /** true cuando fue abierto con openModalWithClose (3 estados) */\n isTriState: boolean;\n _resolve: ((result: boolean) => void) | null;\n _resolveWithClose: ((result: ModalResult) => void) | null;\n\n openModal: (payload: ModalPayload) => Promise<boolean>;\n openModalWithClose: (payload: ModalPayload) => Promise<ModalResult>;\n closeModal: (confirmed?: boolean) => void;\n closeModalWithResult: (result: ModalResult) => void;\n}\n\nexport const useModalGlobalStore = create<ModalGlobalState>((set, get) => ({\n isOpen: false,\n payload: null,\n modalId: 0,\n isTriState: false,\n _resolve: null,\n _resolveWithClose: null,\n\n openModal: (payload) => {\n return new Promise<boolean>((resolve) => {\n set((state) => ({\n isOpen: true,\n payload,\n modalId: state.modalId + 1,\n isTriState: false,\n _resolve: resolve,\n _resolveWithClose: null,\n }));\n });\n },\n\n openModalWithClose: (payload) => {\n return new Promise<ModalResult>((resolve) => {\n set((state) => ({\n isOpen: true,\n payload,\n modalId: state.modalId + 1,\n isTriState: true,\n _resolve: null,\n _resolveWithClose: resolve,\n }));\n });\n },\n\n closeModal: (confirmed = false) => {\n const { _resolve, _resolveWithClose } = get();\n _resolve?.(confirmed);\n _resolveWithClose?.(confirmed ? \"confirm\" : \"cancel\");\n set({ isOpen: false, payload: null, isTriState: false, _resolve: null, _resolveWithClose: null });\n },\n\n closeModalWithResult: (result) => {\n const { _resolve, _resolveWithClose } = get();\n _resolve?.(result === \"confirm\");\n _resolveWithClose?.(result);\n set({ isOpen: false, payload: null, isTriState: false, _resolve: null, _resolveWithClose: null });\n },\n}));\n","import { create } from \"zustand\";\n\ninterface ModalLoadingState {\n isOpen: boolean;\n message: string;\n sessionId: number;\n openLoading: (message?: string) => number;\n closeLoading: (sessionId?: number) => void;\n}\n\nexport const useModalLoadingStore = create<ModalLoadingState>((set, get) => ({\n isOpen: false,\n message: \"Cargando...\",\n sessionId: 0,\n openLoading: (message = \"Cargando...\") => {\n const nextId = get().sessionId + 1;\n set({ isOpen: true, message, sessionId: nextId });\n return nextId;\n },\n closeLoading: (sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ isOpen: false, message: \"Cargando...\" });\n },\n}));\n","import { create } from \"zustand\";\n\ninterface ModalLoadingPercentageState {\n isOpen: boolean;\n message: string;\n percentage: number;\n /** ID de sesión actual — se incrementa en cada apertura */\n sessionId: number;\n openLoadingPercentage: (message?: string, initialPercentage?: number) => number;\n updatePercentage: (percentage: number, sessionId?: number) => void;\n closeLoadingPercentage: (sessionId?: number) => void;\n}\n\nexport const useModalLoadingPercentageStore = create<ModalLoadingPercentageState>((set, get) => ({\n isOpen: false,\n message: \"Cargando...\",\n percentage: 0,\n sessionId: 0,\n openLoadingPercentage: (message = \"Cargando...\", initialPercentage = 0) => {\n const nextId = get().sessionId + 1;\n set({ isOpen: true, message, percentage: Math.min(100, Math.max(0, initialPercentage)), sessionId: nextId });\n return nextId;\n },\n updatePercentage: (percentage, sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ percentage: Math.min(100, Math.max(0, percentage)) });\n },\n closeLoadingPercentage: (sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ isOpen: false, message: \"Cargando...\", percentage: 0 });\n },\n}));\n","import { ReactNode, useEffect, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\n\nexport interface PortalProps {\n children?: ReactNode;\n container?: Element | DocumentFragment | null;\n}\n\nexport const Portal = ({ children, container }: PortalProps) => {\n const [mounted, setMounted] = useState(false);\n\n useEffect(() => {\n setMounted(true);\n return () => setMounted(false);\n }, []);\n\n if (!mounted) return null;\n\n let portalElement = container || document.querySelector(\"#portal\");\n if (!portalElement) {\n portalElement = document.body;\n }\n\n return createPortal(children, portalElement);\n};\n\nexport default Portal;\n","import { SVGProps } from \"react\";\n\nexport const IconCloseRadius = (props: SVGProps<SVGSVGElement>) => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" width={28} height={28} viewBox=\"0 0 28 28\" fill=\"none\" {...props}>\n <path\n d=\"M14 0C6.2 0 0 6.2 0 14C0 21.8 6.2 28 14 28C21.8 28 28 21.8 28 14C28 6.2 21.8 0 14 0ZM19.4 21L14 15.6L8.6 21L7 19.4L12.4 14L7 8.6L8.6 7L14 12.4L19.4 7L21 8.6L15.6 14L21 19.4L19.4 21Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport default IconCloseRadius;\n","import { HTMLAttributes, ReactNode, useEffect, useId, useLayoutEffect, useRef, useState } from \"react\";\nimport { Portal } from \"../Portal/Portal\";\nimport { IconCloseRadius } from \"../../icons/Actions/IconCloseRadius\";\nimport { useModalGlobalContext } from \"../ModalGlobal/ModalGlobalContext\";\n\nexport interface ModalProps extends HTMLAttributes<HTMLDivElement> {\n isOpen: boolean;\n onClose: () => void;\n children: ReactNode;\n whitoutBackground?: boolean;\n closeButton?: boolean;\n closeDisabled?: boolean;\n escapeToClose?: boolean;\n disableFocus?: boolean;\n disableFocusRestore?: boolean;\n existTabIndex?: boolean;\n zIndexLevel?: number;\n onCloseComplete?: () => void;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n alignTop?: boolean;\n /** Habilita animación de entrada/salida (default: true) */\n animated?: boolean;\n /** Bloquea el scroll del body mientras el modal está abierto (default: true) */\n preventBodyScroll?: boolean;\n overlayColor?:\n | \"blue\"\n | \"skyblue\"\n | \"skyblue-light\"\n | \"yellow\"\n | \"light-skyblue\"\n | \"gray\"\n | \"gray-light\"\n | \"gray-extra-light\"\n | \"red\"\n | \"dark-gray\"\n | \"green\"\n | \"yellow-light\"\n | \"primary\";\n}\n\nconst openModals: Set<string> =\n (globalThis as unknown as Record<string, unknown>).__openModals as Set<string> ||\n ((globalThis as unknown as Record<string, Set<string>>).__openModals = new Set<string>());\n\nconst lockBodyScroll = (id: string, enabled: boolean) => {\n if (!enabled || typeof document === \"undefined\") return;\n openModals.add(id);\n document.body.style.overflow = \"hidden\";\n};\n\nconst unlockBodyScroll = (id: string, enabled: boolean) => {\n if (!enabled || typeof document === \"undefined\") return;\n openModals.delete(id);\n if (openModals.size === 0) {\n document.body.style.overflow = \"\";\n }\n};\n\nconst FOCUSABLE_SELECTOR = [\n \"a[href]\",\n \"area[href]\",\n \"button:not([disabled])\",\n 'input:not([disabled]):not([type=\"hidden\"])',\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n \"iframe\",\n \"object\",\n \"embed\",\n '[tabindex]:not([tabindex=\"-1\"])',\n '[contenteditable=\"true\"]',\n].join(\",\");\n\nconst FOCUS_GUARD_ATTRIBUTE = \"data-focus-guard\";\n\nconst focusGuardStyle = {\n position: \"absolute\",\n width: \"1px\",\n height: \"1px\",\n padding: 0,\n margin: 0,\n overflow: \"hidden\",\n clip: \"rect(0, 0, 0, 0)\",\n whiteSpace: \"nowrap\",\n border: 0,\n} as const;\n\nconst isElementVisible = (element: HTMLElement) => {\n const style = globalThis.getComputedStyle(element);\n return (\n style.visibility !== \"hidden\" &&\n style.display !== \"none\" &&\n element.offsetParent !== null\n );\n};\n\nconst getFocusableElements = (wrapper: HTMLElement, includeWrapper = true) => {\n let focusable = Array.from(wrapper.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter(\n (el) =>\n !el.hasAttribute(FOCUS_GUARD_ATTRIBUTE) &&\n isElementVisible(el) &&\n el.tabIndex !== -1,\n );\n\n if (includeWrapper && wrapper.tabIndex >= 0) {\n focusable = [wrapper, ...focusable];\n }\n\n return focusable;\n};\n\nconst focusWrapper = (wrapper: HTMLElement, options?: FocusOptions) => {\n if (wrapper.tabIndex >= 0) {\n wrapper.focus(options);\n return;\n }\n\n const focusable = getFocusableElements(wrapper, false);\n focusable[0]?.focus(options);\n};\n\nconst focusEdgeElement = (\n wrapper: HTMLElement,\n position: \"first\" | \"last\",\n options?: FocusOptions,\n) => {\n const focusable = getFocusableElements(wrapper, false);\n const target = position === \"last\" ? focusable.at(-1) : focusable[0];\n\n if (target) {\n target.focus(options);\n return;\n }\n\n focusWrapper(wrapper, options);\n};\n\nexport const Modal = ({\n isOpen,\n onClose,\n children,\n whitoutBackground = false,\n closeButton = false,\n closeDisabled = false,\n escapeToClose = true,\n disableFocus: disableFocusProp,\n disableFocusRestore = false,\n existTabIndex = true,\n zIndexLevel = 100,\n onCloseComplete,\n alignTop = false,\n animated: animatedProp,\n preventBodyScroll = true,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- overlayColor reservado para uso futuro\n overlayColor: _overlayColor = \"blue\",\n ...props\n}: ModalProps) => {\n const modalId = useId();\n const ctx = useModalGlobalContext();\n const animated = animatedProp ?? ctx?.animated ?? true;\n const disableFocus = disableFocusProp ?? ctx?.disableFocus ?? false;\n const ariaLabelledBy = props[\"aria-labelledby\"];\n const modalRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const previousActiveElement = useRef<HTMLElement | null>(null);\n const handleStartFocusGuard = () => {\n const wrapper = modalRef.current;\n if (!wrapper) return;\n focusEdgeElement(wrapper, \"last\", { preventScroll: true });\n };\n const handleEndFocusGuard = () => {\n const wrapper = modalRef.current;\n if (!wrapper) return;\n focusEdgeElement(wrapper, \"first\", { preventScroll: true });\n };\n\n // CSS animation state (replaces framer-motion AnimatePresence)\n const [mounted, setMounted] = useState(false);\n const [visible, setVisible] = useState(false);\n\n // Cache children during exit animation (replicates AnimatePresence behavior):\n // when global state clears data before the modal finishes closing, the cached\n // children keep the content visible throughout the exit animation.\n const [cachedChildren, setCachedChildren] = useState<ReactNode>(children);\n useEffect(() => {\n if (isOpen) {\n setCachedChildren(children);\n }\n }, [isOpen, children]);\n\n useEffect(() => {\n if (!animated) return;\n if (isOpen) {\n setMounted(true);\n const raf = requestAnimationFrame(() => {\n requestAnimationFrame(() => setVisible(true));\n });\n return () => cancelAnimationFrame(raf);\n } else {\n setVisible(false);\n const timer = setTimeout(() => {\n setMounted(false);\n onCloseComplete?.();\n }, 200);\n return () => clearTimeout(timer);\n }\n }, [isOpen, animated, onCloseComplete]);\n\n // Body scroll lock — usa counter global para soportar múltiples modales simultáneos\n useLayoutEffect(() => {\n if (isOpen) lockBodyScroll(modalId, preventBodyScroll);\n return () => {\n if (isOpen) unlockBodyScroll(modalId, preventBodyScroll);\n };\n }, [isOpen, preventBodyScroll, modalId]);\n\n // Scroll reset when opening\n useEffect(() => {\n if (!isOpen) return;\n const resetScroll = () => {\n const el = contentRef.current;\n if (!el) return;\n el.style.scrollBehavior = \"auto\";\n el.scrollTop = 0;\n requestAnimationFrame(() => {\n el.scrollTop = 0;\n setTimeout(() => {\n el.style.scrollBehavior = \"smooth\";\n }, 10);\n });\n };\n resetScroll();\n [10, 50, 100, 200].forEach((d) => setTimeout(resetScroll, d));\n }, [isOpen]);\n\n // Keyboard handling and focus trap\n useEffect(() => {\n const pendingTasks: Array<ReturnType<typeof globalThis.setTimeout>> = [];\n\n const handleDocumentFocusIn = (e: FocusEvent) => {\n if (!isOpen || disableFocus) return;\n const wrapper = modalRef.current;\n const target = e.target;\n\n if (!wrapper || !(target instanceof HTMLElement) || wrapper.contains(target)) {\n return;\n }\n\n requestAnimationFrame(() => {\n const currentActive = document.activeElement;\n if (currentActive instanceof HTMLElement && wrapper.contains(currentActive)) {\n return;\n }\n\n focusWrapper(wrapper, { preventScroll: true });\n });\n };\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\" && escapeToClose && !closeDisabled) {\n onClose();\n return;\n }\n\n if (!isOpen || disableFocus) return;\n const wrapper = modalRef.current;\n if (!wrapper) return;\n\n const focusable = getFocusableElements(wrapper);\n const active = (document.activeElement as HTMLElement) || null;\n\n const arrowKeys = [\"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"];\n if (arrowKeys.includes(e.key)) {\n if (active && wrapper.contains(active)) {\n const activeIndex = focusable.indexOf(active);\n if (\n (e.key === \"ArrowUp\" || e.key === \"ArrowLeft\") &&\n activeIndex === 0\n ) {\n e.preventDefault();\n e.stopPropagation();\n if (focusable.length > 1) focusable.at(-1)?.focus();\n else active.focus();\n return;\n }\n if (\n (e.key === \"ArrowDown\" || e.key === \"ArrowRight\") &&\n activeIndex === focusable.length - 1\n ) {\n e.preventDefault();\n e.stopPropagation();\n if (focusable.length > 1) focusable[0].focus();\n else active.focus();\n return;\n }\n requestAnimationFrame(() => {\n const currentActive = document.activeElement as HTMLElement;\n if (!currentActive || !wrapper.contains(currentActive)) {\n if (activeIndex !== -1 && focusable[activeIndex])\n focusable[activeIndex].focus();\n else if (focusable.length > 0) focusable[0].focus();\n else wrapper.focus();\n }\n });\n } else {\n e.preventDefault();\n if (focusable.length > 0) {\n if (e.key === \"ArrowUp\" || e.key === \"ArrowLeft\")\n focusable.at(-1)?.focus();\n else focusable[0].focus();\n } else {\n wrapper.focus();\n }\n }\n return;\n }\n\n if (e.key !== \"Tab\") return;\n if (focusable.length === 0) {\n e.preventDefault();\n wrapper.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable.at(-1);\n const isShift = e.shiftKey;\n\n if (!first || !last) {\n e.preventDefault();\n wrapper.focus();\n return;\n }\n\n if (!active || !wrapper.contains(active)) {\n e.preventDefault();\n (isShift ? last : first).focus();\n return;\n }\n\n const activeIndex = focusable.indexOf(active);\n if (\n !isShift &&\n (active === last || activeIndex === focusable.length - 1)\n ) {\n e.preventDefault();\n first.focus();\n return;\n }\n\n if (isShift) {\n e.preventDefault();\n if (active === first || active === wrapper || activeIndex === 0)\n last.focus();\n else if (activeIndex > 0) focusable[activeIndex - 1].focus();\n else last.focus();\n }\n };\n\n if (isOpen && !disableFocus) {\n previousActiveElement.current = document.activeElement as HTMLElement;\n\n const focusInitial = (wrapper: HTMLElement) => {\n focusWrapper(wrapper, { preventScroll: true });\n };\n\n const bindFocusManagement = (attempt = 0) => {\n const wrapper = modalRef.current;\n if (!wrapper) {\n if (attempt < 10) {\n pendingTasks.push(\n globalThis.setTimeout(() => bindFocusManagement(attempt + 1), 25),\n );\n }\n return;\n }\n\n focusInitial(wrapper);\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"focusin\", handleDocumentFocusIn, true);\n pendingTasks.push(globalThis.setTimeout(() => bindFocusManagement(), 0));\n } else if (isOpen && disableFocus) {\n document.addEventListener(\"keydown\", handleKeyDown);\n }\n\n return () => {\n pendingTasks.forEach((task) => globalThis.clearTimeout(task));\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"focusin\", handleDocumentFocusIn, true);\n if (\n !disableFocus &&\n !disableFocusRestore &&\n previousActiveElement.current\n ) {\n previousActiveElement.current.focus();\n }\n };\n }, [\n isOpen,\n onClose,\n closeDisabled,\n escapeToClose,\n disableFocus,\n disableFocusRestore,\n ariaLabelledBy,\n ]);\n\n // Sin animación: renderizar directo desde isOpen (sin delay de useEffect)\n if (!animated && !isOpen) return null;\n // Con animación: usar mounted para controlar enter/exit transitions\n if (animated && !mounted) return null;\n\n const contentClass = [\n \"relative flex flex-col items-center justify-start\",\n whitoutBackground\n ? \"bg-transparent\"\n : [\n \"min-w-[320px] w-[95vw] max-w-[95vw] max-h-[90vh]\",\n \"overflow-y-auto scroll-smooth\",\n \"md:max-w-[1000px]\",\n ].join(\" \"),\n props.className || \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n\n return (\n <Portal>\n {/* Backdrop */}\n <div\n style={{ zIndex: zIndexLevel }}\n className={[\n \"fixed inset-0 bg-onpe-blue\",\n animated ? \"transition-opacity duration-200\" : \"\",\n animated ? (visible ? \"opacity-80\" : \"opacity-0\") : \"opacity-80\",\n ].join(\" \")}\n onClick={onClose}\n />\n\n {/* Container */}\n <div\n style={{ zIndex: zIndexLevel + 10 }}\n className={[\n \"fixed top-0 w-full h-screen grid\",\n alignTop ? \"place-items-start pt-8\" : \"place-items-center\",\n animated ? \"transition-all duration-200\" : \"\",\n animated\n ? visible\n ? \"opacity-100 scale-100 translate-y-0\"\n : \"opacity-[0.2] scale-95 -translate-y-5\"\n : \"opacity-100 scale-100 translate-y-0\",\n ].join(\" \")}\n >\n <div className=\"relative grid place-items-center\">\n <div\n ref={modalRef}\n onClick={(e) => e.stopPropagation()}\n {...(existTabIndex && { tabIndex: disableFocus ? -1 : 0 })}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={props[\"aria-labelledby\"]}\n aria-describedby={props[\"aria-describedby\"]}\n aria-label={props[\"aria-label\"]}\n >\n <span\n tabIndex={disableFocus ? -1 : 0}\n aria-hidden=\"true\"\n {...{ [FOCUS_GUARD_ATTRIBUTE]: \"start\" }}\n style={focusGuardStyle}\n onFocus={handleStartFocusGuard}\n />\n <div ref={contentRef} className={contentClass}>\n {isOpen ? children : cachedChildren}\n </div>\n {closeButton && (\n <button\n onClick={onClose}\n className=\"absolute top-2.5 right-2.5 text-onpe-red cursor-pointer w-4 h-4 border-none bg-transparent p-0 md:w-6 md:h-6\"\n aria-label=\"Cerrar\"\n type=\"button\"\n >\n <IconCloseRadius aria-hidden=\"true\" className=\"w-full h-full\" />\n </button>\n )}\n <span\n tabIndex={disableFocus ? -1 : 0}\n aria-hidden=\"true\"\n {...{ [FOCUS_GUARD_ATTRIBUTE]: \"end\" }}\n style={focusGuardStyle}\n onFocus={handleEndFocusGuard}\n />\n </div>\n </div>\n </div>\n </Portal>\n );\n};\n\nexport default Modal;\n","type ButtonColor =\n | \"blue\"\n | \"skyblue\"\n | \"skyblue-light\"\n | \"yellow\"\n | \"light-skyblue\"\n | \"gray\"\n | \"gray-light\"\n | \"gray-extra-light\"\n | \"red\"\n | \"dark-gray\"\n | \"green\"\n | \"yellow-light\"\n | \"primary\";\n\ntype ButtonSize = \"small\" | \"normal\" | \"large\";\n\nexport interface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n color: ButtonColor;\n title: string;\n size?: ButtonSize;\n}\n\nconst colorClasses: Record<ButtonColor, string> = {\n blue: \"bg-onpe-blue\",\n skyblue: \"bg-onpe-skyblue\",\n \"skyblue-light\": \"bg-onpe-skyblue-light\",\n yellow: \"bg-onpe-yellow\",\n \"light-skyblue\": \"bg-onpe-light-skyblue\",\n gray: \"bg-onpe-gray\",\n \"gray-light\": \"bg-onpe-gray-light\",\n \"gray-extra-light\": \"bg-onpe-gray-extra-light\",\n red: \"bg-onpe-red\",\n \"dark-gray\": \"bg-onpe-dark-gray\",\n green: \"bg-onpe-green\",\n \"yellow-light\": \"bg-onpe-yellow-light\",\n primary: \"bg-onpe-blue\",\n};\n\nconst sizeClasses: Record<ButtonSize, string> = {\n small: \"h-10 text-sm\",\n normal: \"h-12 text-base\",\n large: \"h-14 text-lg\",\n};\n\nexport function Button({\n color,\n title,\n size = \"normal\",\n className = \"\",\n ...props\n}: ButtonProps) {\n return (\n <button\n className={[\n \"inline-flex items-center justify-center\",\n \"min-w-[200px] border-none\",\n \"text-white font-semibold cursor-pointer\",\n \"transition-all duration-300 ease-in-out\",\n \"disabled:cursor-default disabled:!bg-onpe-gray\",\n colorClasses[color],\n sizeClasses[size],\n className,\n ]\n .filter(Boolean)\n .join(\" \")}\n {...props}\n >\n {title}\n </button>\n );\n}\n\nexport default Button;\n","import { SVGProps } from \"react\";\n\nexport const IconCheck = (props: SVGProps<SVGSVGElement>) => (\n <svg width={64} height={64} viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M28.2673 44.2663L47.0673 25.4663L43.334 21.733L28.2673 36.7997L20.6673 29.1997L16.934 32.933L28.2673 44.2663ZM32.0007 58.6663C28.3118 58.6663 24.8451 57.9659 21.6007 56.565C18.3562 55.1641 15.534 53.2646 13.134 50.8663C10.734 48.4663 8.83443 45.6441 7.43532 42.3997C6.03621 39.1552 5.33576 35.6886 5.33398 31.9997C5.33398 28.3108 6.03443 24.8441 7.43532 21.5997C8.83621 18.3552 10.7358 15.533 13.134 13.133C15.534 10.733 18.3562 8.83345 21.6007 7.43434C24.8451 6.03523 28.3118 5.33479 32.0007 5.33301C35.6895 5.33301 39.1562 6.03345 42.4007 7.43434C45.6451 8.83523 48.4673 10.7348 50.8673 13.133C53.2673 15.533 55.1678 18.3552 56.5686 21.5997C57.9695 24.8441 58.6691 28.3108 58.6673 31.9997C58.6673 35.6886 57.9669 39.1552 56.566 42.3997C55.1651 45.6441 53.2655 48.4663 50.8673 50.8663C48.4673 53.2663 45.6451 55.1668 42.4007 56.5677C39.1562 57.9686 35.6895 58.6681 32.0007 58.6663ZM32.0007 53.333C37.9562 53.333 43.0006 51.2663 47.134 47.133C51.2673 42.9997 53.334 37.9552 53.334 31.9997C53.334 26.0441 51.2673 20.9997 47.134 16.8663C43.0006 12.733 37.9562 10.6663 32.0007 10.6663C26.0451 10.6663 21.0007 12.733 16.8673 16.8663C12.734 20.9997 10.6673 26.0441 10.6673 31.9997C10.6673 37.9552 12.734 42.9997 16.8673 47.133C21.0007 51.2663 26.0451 53.333 32.0007 53.333Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport default IconCheck;\n","import { SVGProps } from \"react\";\n\nexport const IconInfo = (props: SVGProps<SVGSVGElement>) => (\n <svg width={16} height={16} viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z\" fill=\"currentColor\" />\n </svg>\n);\n\nexport default IconInfo;\n","import type { SVGProps } from \"react\";\n\nexport const IconQuestion = (props: SVGProps<SVGSVGElement>) => (\n <svg\n width=\"64\"\n height=\"64\"\n viewBox=\"0 0 64 64\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M31.9997 5.33325C46.7277 5.33325 58.6663 17.2719 58.6663 31.9999C58.6663 46.7279 46.7277 58.6666 31.9997 58.6666C17.2717 58.6666 5.33301 46.7279 5.33301 31.9999C5.33301 17.2719 17.2717 5.33325 31.9997 5.33325ZM31.9997 10.6666C26.3417 10.6666 20.9155 12.9142 16.9147 16.915C12.914 20.9157 10.6663 26.342 10.6663 31.9999C10.6663 37.6579 12.914 43.0841 16.9147 47.0849C20.9155 51.0856 26.3417 53.3332 31.9997 53.3332C37.6576 53.3332 43.0838 51.0856 47.0846 47.0849C51.0854 43.0841 53.333 37.6579 53.333 31.9999C53.333 26.342 51.0854 20.9157 47.0846 16.915C43.0838 12.9142 37.6576 10.6666 31.9997 10.6666ZM31.9997 42.6666C32.7069 42.6666 33.3852 42.9475 33.8853 43.4476C34.3854 43.9477 34.6663 44.626 34.6663 45.3332C34.6663 46.0405 34.3854 46.7188 33.8853 47.2189C33.3852 47.719 32.7069 47.9999 31.9997 47.9999C31.2924 47.9999 30.6142 47.719 30.1141 47.2189C29.614 46.7188 29.333 46.0405 29.333 45.3332C29.333 44.626 29.614 43.9477 30.1141 43.4476C30.6142 42.9475 31.2924 42.6666 31.9997 42.6666ZM31.9997 17.3333C34.2458 17.3333 36.4217 18.1155 38.1538 19.5455C39.8858 20.9755 41.0658 22.964 41.4912 25.1695C41.9165 27.3749 41.5605 29.6596 40.4844 31.6311C39.4084 33.6027 37.6793 35.1379 35.5943 35.9732C35.2855 36.0868 35.0072 36.2703 34.781 36.5093C34.6637 36.6426 34.645 36.8133 34.6477 36.9893L34.6663 37.3333C34.6656 38.0129 34.4053 38.6667 33.9387 39.1609C33.4722 39.6551 32.8345 39.9525 32.156 39.9924C31.4774 40.0322 31.8093 39.8115 30.2881 39.3752C29.7669 38.939 29.4319 38.3202 29.3517 37.6452L29.333 37.3333V36.6666C29.333 33.5919 31.813 31.7466 33.6103 31.0239C34.3418 30.7318 34.98 30.246 35.4562 29.6185C35.9324 28.9911 36.2287 28.2458 36.3133 27.4627C36.3979 26.6796 36.2675 25.8883 35.9363 25.1736C35.605 24.459 35.0854 23.8481 34.4331 23.4065C33.7808 22.965 33.0206 22.7094 32.2341 22.6673C31.4475 22.6252 30.6644 22.7982 29.9687 23.1676C29.2731 23.537 28.6912 24.0889 28.2855 24.7641C27.8799 25.4393 27.6658 26.2122 27.6663 26.9999C27.6663 27.7072 27.3854 28.3854 26.8853 28.8855C26.3852 29.3856 25.7069 29.6666 24.9997 29.6666C24.2924 29.6666 23.6142 29.3856 23.1141 28.8855C22.614 28.3854 22.333 27.7072 22.333 26.9999C22.333 24.4362 23.3515 21.9774 25.1643 20.1646C26.9772 18.3517 29.4359 17.3333 31.9997 17.3333Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport default IconQuestion;\n","import { SVGProps } from \"react\";\n\nexport const IconSpinnerDesktop = (props: SVGProps<SVGSVGElement>) => (\n <svg width={102} height={102} viewBox=\"0 0 102 102\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M50.9999 3.08313C23.9241 3.08208 3.08296 24.6456 3.08325 51C3.08354 75.4375 22.453 98.9167 50.9999 98.9167C77.5573 98.9167 98.9166 77.3542 98.9166 51\"\n stroke=\"currentColor\"\n strokeWidth={6}\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport default IconSpinnerDesktop;\n","import { SVGProps } from \"react\";\n\nexport const IconSpinnerMobile = (props: SVGProps<SVGSVGElement>) => (\n <svg width={33} height={33} viewBox=\"0 0 33 33\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" {...props}>\n <path\n d=\"M16.5 3C8.87169 2.9997 2.99992 9.07499 3 16.5C3.00008 23.385 8.45721 30 16.5 30C23.9822 30 30 23.925 30 16.5\"\n stroke=\"currentColor\"\n strokeWidth={6}\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport default IconSpinnerMobile;\n","import type { SVGProps } from \"react\";\n\nexport const IconWarningNotRecommended = (props: SVGProps<SVGSVGElement>) => (\n <svg\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 49 42\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n {...props}\n >\n <path\n d=\"M0 42L24.5 0L49 42H0ZM7.68409 37.5789H41.3159L24.5 8.84211L7.68409 37.5789ZM24.5 35.3684C25.1311 35.3684 25.6604 35.1562 26.088 34.7318C26.5157 34.3074 26.7288 33.7827 26.7273 33.1579C26.7273 32.5316 26.5135 32.0062 26.0858 31.5818C25.6582 31.1574 25.1296 30.9459 24.5 30.9474C23.8689 30.9474 23.3396 31.1596 22.912 31.584C22.4843 32.0084 22.2712 32.5331 22.2727 33.1579C22.2727 33.7842 22.4865 34.3096 22.9142 34.734C23.3418 35.1584 23.8704 35.3699 24.5 35.3684ZM22.2727 28.7368H26.7273V17.6842H22.2727V28.7368Z\"\n fill=\"currentColor\"\n />\n </svg>\n);\n\nexport default IconWarningNotRecommended;\n","import { type ReactNode } from \"react\";\nimport { Modal } from \"../../Modal/Modal\";\nimport { Button } from \"../../Button/Button\";\nimport { IconCheck } from \"../../../icons/Actions/IconCheck\";\nimport { IconWarningNotRecommended } from \"../../../icons\";\nimport { IconQuestion } from \"../../../icons/Actions/IconQuestion\";\nimport { IconInfo } from \"../../../icons/Actions/IconInfo\";\n\nexport type ModalType = \"warning\" | \"success\" | \"question\" | \"info\" | \"none\";\n\n/** Mapa de override de color a clase CSS (icono + título) */\nconst colorOverrideMap: Record<string, string> = {\n red: \"text-onpe-red\",\n blue: \"text-onpe-blue\",\n skyblue: \"text-onpe-skyblue\",\n yellow: \"text-onpe-yellow\",\n};\n\nfunction renderIcon(type: ModalType, colorClass: string): ReactNode {\n if (type === \"none\") return null;\n if (type === \"success\") {\n return (\n <IconCheck role=\"presentation\" className={`w-16 h-16 ${colorClass}`} />\n );\n }\n if (type === \"question\") {\n return (\n <IconQuestion role=\"presentation\" className={`w-16 h-16 ${colorClass}`} />\n );\n }\n if (type === \"info\") {\n return (\n <IconInfo role=\"presentation\" className={`w-16 h-16 ${colorClass}`} />\n );\n }\n // error | warning\n return (\n <IconWarningNotRecommended\n role=\"presentation\"\n className={`w-16 h-16 ${colorClass}`}\n />\n );\n}\n\nconst defaultTitleByType: Record<string, string> = {\n success: \"Confirmación\",\n warning: \"Advertencia\",\n question: \"Atención\",\n info: \"Información\",\n};\n\nexport interface ModalConfirmProps {\n isOpen: boolean;\n onClose: () => void;\n title?: string;\n /** Contenido del modal (string o JSX) */\n message?: ReactNode;\n /** Alias de message */\n content?: ReactNode;\n /** Tipo semántico: determina icono, color de título y color de botón confirmar */\n type?: ModalType;\n /**\n * \"single\" → un botón \"Confirmar\".\n * \"double\" → \"Cancelar\" + \"Confirmar\".\n * \"confirm\" → \"No\" + \"Sí\" (diálogo de confirmación Sí/No).\n */\n buttonMode?: \"single\" | \"double\" | \"confirm\";\n /** Deshabilita el botón confirmar */\n disabledConfirmButton?: boolean;\n /** Deshabilita el cierre del modal */\n closeDisabled?: boolean;\n /**\n * Override del color del icono y título.\n * Si no se provee, se deriva automáticamente del `type`.\n */\n color?: \"red\" | \"blue\" | \"skyblue\" | \"yellow\";\n onConfirm?: () => void | Promise<void>;\n onCancel?: () => void | Promise<void>;\n textButtonConfirm?: string;\n textButtonCancel?: string;\n className?: string;\n zIndexLevel?: number;\n withoutAutoClose?: boolean;\n disableFocus?: boolean;\n /** Muestra el botón X para cerrar el modal */\n closeButton?: boolean;\n /** Alinea el texto del mensaje a la izquierda (justify) en vez de centrado */\n alignJustify?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n alignTop?: boolean;\n /** Habilita animación de entrada/salida (default: true) */\n animated?: boolean;\n /** Bloquea el scroll del body mientras el modal está abierto (default: true) */\n preventBodyScroll?: boolean;\n}\n\nexport const ModalConfirm = ({\n isOpen = false,\n onClose = () => {},\n withoutAutoClose = false,\n title,\n message,\n content,\n type = \"warning\",\n buttonMode,\n disabledConfirmButton = false,\n closeDisabled = false,\n color,\n onConfirm = () => {},\n onCancel = () => {},\n textButtonConfirm,\n textButtonCancel,\n className = \"\",\n zIndexLevel = 100,\n disableFocus = false,\n closeButton = false,\n alignJustify = false,\n alignTop = false,\n animated = true,\n preventBodyScroll = true,\n}: ModalConfirmProps) => {\n const titleId = \"modal-confirm-title\";\n const messageId = \"modal-confirm-message\";\n\n const effectiveTitle = title ?? defaultTitleByType[type] ?? \"\";\n // Título e ícono siempre skyblue por defecto; `color` es el único override\n const effectiveColorClass = color\n ? (colorOverrideMap[color] ?? \"text-onpe-skyblue\")\n : \"text-onpe-skyblue\";\n const effectiveButtonMode =\n buttonMode ?? (type === \"question\" ? \"confirm\" : \"single\");\n const isConfirmMode = effectiveButtonMode === \"confirm\";\n const showTwoButtons = effectiveButtonMode === \"double\" || isConfirmMode;\n const confirmLabel =\n textButtonConfirm ??\n (isConfirmMode\n ? \"Sí\"\n : effectiveButtonMode === \"double\"\n ? \"Confirmar\"\n : \"Aceptar\");\n const cancelLabel = textButtonCancel ?? (isConfirmMode ? \"No\" : \"Cancelar\");\n\n const handleConfirm = async () => {\n try {\n await onConfirm();\n if (!withoutAutoClose) onClose();\n } catch (error) {\n console.error(\"Error en handleConfirm:\", error);\n if (!withoutAutoClose) onClose();\n }\n };\n\n const handleCancel = () => {\n onCancel();\n if (!withoutAutoClose) onClose();\n };\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={onClose}\n className={`bg-white pt-[30px] pb-[30px] px-[30px] max-w-[719px]! ${className}`}\n closeButton={closeButton}\n closeDisabled={closeDisabled}\n zIndexLevel={zIndexLevel}\n aria-labelledby={titleId}\n aria-describedby={messageId}\n disableFocus={disableFocus}\n alignTop={alignTop}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n >\n {/* Icono */}\n <div className=\"flex items-center justify-center\">\n {renderIcon(type, effectiveColorClass)}\n </div>\n\n {/* Título */}\n <p\n id={titleId}\n className={[\n \"text-lg md:text-2xl font-semibold text-center mt-0 md:mt-4\",\n effectiveColorClass,\n ].join(\" \")}\n >\n {effectiveTitle}\n </p>\n\n {/* Mensaje / Contenido */}\n {message &&\n (typeof message === \"string\" ? (\n <div\n id={messageId}\n className={`mt-7 w-full text-sm md:text-lg text-black ${alignJustify ? \"text-justify\" : \"text-center\"}`}\n dangerouslySetInnerHTML={{ __html: message }}\n />\n ) : (\n <div\n id={messageId}\n className={`mt-7 w-full text-sm md:text-lg max-w-full text-black ${alignJustify ? \"text-justify\" : \"text-center\"}`}\n >\n {message}\n </div>\n ))}\n {content && (\n <div\n id={message ? undefined : messageId}\n className={`text-sm w-full md:text-lg max-w-full text-black ${alignJustify ? \"text-justify\" : \"text-center\"}`}\n >\n {content}\n </div>\n )}\n\n {/* Mobile: apilado */}\n <div className=\"flex flex-col items-center justify-center w-full gap-5 mt-11 md:hidden\">\n <Button\n className=\"w-full max-w-[200px]\"\n color=\"red\"\n title={confirmLabel}\n onClick={handleConfirm}\n disabled={disabledConfirmButton}\n />\n {showTwoButtons && (\n <Button\n className=\"w-full max-w-[200px]\"\n color=\"skyblue\"\n title={cancelLabel}\n onClick={handleCancel}\n />\n )}\n </div>\n\n {/* Desktop: fila */}\n <div className=\"hidden md:flex md:flex-row items-center justify-center w-full gap-5 mt-11\">\n {showTwoButtons && (\n <Button\n className=\"w-[200px]\"\n color=\"skyblue\"\n title={cancelLabel}\n onClick={handleCancel}\n />\n )}\n <Button\n className=\"w-[200px]\"\n color=\"red\"\n title={confirmLabel}\n onClick={handleConfirm}\n disabled={disabledConfirmButton}\n />\n </div>\n </Modal>\n );\n};\n\nexport default ModalConfirm;\n","import { type ReactNode, useEffect, useState } from \"react\";\nimport { Modal } from \"../../Modal/Modal\";\nimport { IconSpinnerDesktop } from \"../../../icons/Actions/IconSpinnerDesktop\";\nimport { IconSpinnerMobile } from \"../../../icons/Actions/IconSpinnerMobile\";\n\nexport interface ModalLoadingProps {\n isOpen: boolean;\n onClose?: () => void;\n message?: string;\n className?: string;\n zIndexLevel?: number;\n animated?: boolean;\n preventBodyScroll?: boolean;\n /** Spinner personalizado. Si no se provee, se usa el spinner por defecto de la librería. */\n spinner?: ReactNode;\n}\n\nexport const ModalLoading = ({\n isOpen = false,\n onClose = () => {},\n message = \"Cargando...\",\n className = \"\",\n zIndexLevel = 100,\n animated = true,\n preventBodyScroll = true,\n spinner,\n}: ModalLoadingProps) => {\n const [announceMessage, setAnnounceMessage] = useState(\"\");\n\n useEffect(() => {\n if (!isOpen) {\n setAnnounceMessage(\"\");\n return;\n }\n setAnnounceMessage(\"\");\n const t = globalThis.setTimeout(() => {\n setAnnounceMessage(message);\n }, 150);\n return () => {\n globalThis.clearTimeout(t);\n };\n }, [isOpen, message]);\n\n return (\n <Modal\n disableFocus\n zIndexLevel={zIndexLevel}\n isOpen={isOpen}\n onClose={onClose}\n className={className}\n closeDisabled\n whitoutBackground={true}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n >\n <div className=\"sr-only\" aria-live=\"assertive\" aria-atomic=\"true\">\n {announceMessage}\n </div>\n {spinner ?? (\n <>\n <IconSpinnerDesktop\n className=\"hidden md:block text-white animate-spin\"\n aria-hidden=\"true\"\n />\n <IconSpinnerMobile\n className=\"block md:hidden text-white animate-spin\"\n aria-hidden=\"true\"\n />\n </>\n )}\n <p\n className={`text-white leading-normal text-2xl md:text-[64px] text-center ${spinner ? \"mt-5\" : \"mt-10 md:mt-20\"}`}\n >\n {message}\n </p>\n </Modal>\n );\n};\n\nexport default ModalLoading;\n","\"use client\";\n\nimport { Modal } from \"../../Modal/Modal\";\n\ninterface ModalLoadingPercentageProps {\n isOpen: boolean;\n message: string;\n percentage: number;\n zIndexLevel?: number;\n animated?: boolean;\n preventBodyScroll?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n alignTop?: boolean;\n}\n\nexport const ModalLoadingPercentage = ({\n isOpen,\n message,\n percentage,\n zIndexLevel = 300,\n animated = true,\n preventBodyScroll = true,\n alignTop = false,\n}: ModalLoadingPercentageProps) => {\n const clamped = Math.min(100, Math.max(0, percentage));\n\n return (\n <Modal\n disableFocus\n isOpen={isOpen}\n onClose={() => {}}\n closeDisabled\n whitoutBackground\n zIndexLevel={zIndexLevel}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n alignTop={alignTop}\n >\n <div className=\"bg-transparent flex-col flex items-center p-[50px]\">\n <p className=\"text-white leading-normal text-6xl text-center mt-4\">\n {message} {Math.floor(clamped)}%\n </p>\n <div className=\"w-[600px] h-10 bg-white inline-block\">\n <div\n style={{ width: `${clamped}%` }}\n className=\"h-10 bg-onpe-blue border-white border-2 transition-all ease-in-out duration-300\"\n />\n </div>\n </div>\n </Modal>\n );\n};\n\nexport default ModalLoadingPercentage;\n","\"use client\";\n\nimport { type ReactNode, useEffect, useMemo } from \"react\";\nimport { ModalGlobalContext } from \"./ModalGlobalContext\";\nimport { useModalGlobalStore } from \"../../store/modalGlobal/useModalGlobalStore\";\nimport { useModalLoadingStore } from \"../../store/modalGlobal/useModalLoadingStore\";\nimport { useModalLoadingPercentageStore } from \"../../store/modalGlobal/useModalLoadingPercentageStore\";\nimport { ModalConfirm } from \"../Feedback/ModalConfirm/ModalConfirm\";\nimport { ModalLoading } from \"../Feedback/ModalLoading/ModalLoading\";\nimport { ModalLoadingPercentage } from \"../Feedback/ModalLoadingPercentage/ModalLoadingPercentage\";\n\ninterface ModalGlobalProviderProps {\n children: ReactNode;\n /** z-index del modal principal (default: 200) */\n zIndexLevel?: number;\n /** z-index del modal de loading (default: 300) */\n zIndexLoading?: number;\n /** z-index del modal de loading con porcentaje (default: 300) */\n zIndexLoadingPercentage?: number;\n /** Habilita animación de entrada/salida en todos los modales (default: true) */\n animated?: boolean;\n /** Bloquea el scroll del body en todos los modales (default: true) */\n preventBodyScroll?: boolean;\n /** Spinner personalizado para ModalLoading. Si no se provee, se usa el spinner por defecto. */\n loadingSpinner?: ReactNode;\n /** Alinea el ModalLoadingPercentage al tope de la pantalla (default: false) */\n loadingPercentageAlignTop?: boolean;\n /** Texto por defecto del botón confirmar cuando el payload no lo especifica */\n defaultTextButtonConfirm?: string;\n /** Texto por defecto del botón cancelar cuando el payload no lo especifica */\n defaultTextButtonCancel?: string;\n /** Deshabilita el manejo de focus en todos los modales (default: false) */\n disableFocus?: boolean;\n}\n\nexport const ModalGlobalProvider = ({\n children,\n zIndexLevel = 200,\n zIndexLoading = 300,\n zIndexLoadingPercentage = 300,\n animated = true,\n preventBodyScroll = true,\n loadingSpinner,\n loadingPercentageAlignTop = false,\n defaultTextButtonConfirm,\n defaultTextButtonCancel,\n disableFocus = false,\n}: ModalGlobalProviderProps) => {\n const isOpen = useModalGlobalStore((s) => s.isOpen);\n const payload = useModalGlobalStore((s) => s.payload);\n const modalId = useModalGlobalStore((s) => s.modalId);\n const isTriState = useModalGlobalStore((s) => s.isTriState);\n const closeModal = useModalGlobalStore((s) => s.closeModal);\n const closeModalWithResult = useModalGlobalStore(\n (s) => s.closeModalWithResult,\n );\n const isLoadingOpen = useModalLoadingStore((s) => s.isOpen);\n const loadingMessage = useModalLoadingStore((s) => s.message);\n const isPercentageOpen = useModalLoadingPercentageStore((s) => s.isOpen);\n const percentageMessage = useModalLoadingPercentageStore((s) => s.message);\n const percentage = useModalLoadingPercentageStore((s) => s.percentage);\n\n // Auto-confirmar el modal después del timeout especificado\n useEffect(() => {\n if (!isOpen || !payload?.autoConfirmTimeout) return;\n\n const timerId = setTimeout(() => {\n closeModal(true);\n }, payload.autoConfirmTimeout);\n\n return () => clearTimeout(timerId);\n }, [isOpen, modalId]);\n\n const contextValue = useMemo(\n () => ({ animated, disableFocus }),\n [animated, disableFocus],\n );\n\n return (\n <ModalGlobalContext.Provider value={contextValue}>\n {children}\n\n {/* Modal principal — usa ModalConfirm de la librería directamente */}\n <ModalConfirm\n isOpen={isOpen}\n onClose={() => closeModalWithResult(\"close\")}\n title={payload?.title}\n message={payload?.message}\n content={payload?.content}\n type={payload?.iconType ?? payload?.type}\n buttonMode={payload?.buttonMode}\n disabledConfirmButton={payload?.disabledConfirmButton}\n closeDisabled={payload?.closeDisabled}\n color={payload?.color}\n onConfirm={() => closeModal(true)}\n onCancel={() => closeModal(false)}\n withoutAutoClose\n textButtonConfirm={\n payload?.textButtonConfirm ?? defaultTextButtonConfirm\n }\n textButtonCancel={payload?.textButtonCancel ?? defaultTextButtonCancel}\n closeButton={payload?.closeButton ?? isTriState}\n alignJustify={payload?.alignJustify}\n alignTop={payload?.top}\n zIndexLevel={zIndexLevel}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n disableFocus={disableFocus}\n />\n\n {/* Loading */}\n <ModalLoading\n isOpen={isLoadingOpen}\n message={loadingMessage}\n zIndexLevel={zIndexLoading}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n spinner={loadingSpinner}\n />\n\n {/* Loading con porcentaje */}\n <ModalLoadingPercentage\n isOpen={isPercentageOpen}\n message={percentageMessage}\n percentage={percentage}\n zIndexLevel={zIndexLoadingPercentage}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n alignTop={loadingPercentageAlignTop}\n />\n </ModalGlobalContext.Provider>\n );\n};\n\nexport default ModalGlobalProvider;\n","import { useModalGlobalStore } from \"../store/modalGlobal/useModalGlobalStore\";\nimport { useModalLoadingStore } from \"../store/modalGlobal/useModalLoadingStore\";\nimport { useModalLoadingPercentageStore } from \"../store/modalGlobal/useModalLoadingPercentageStore\";\nimport type { ModalPayload, ModalResult } from \"../store/modalGlobal/useModalGlobalStore\";\n\n/**\n * Open the global modal. Returns a promise that resolves to `true` if the user\n * confirmed, or `false` if they cancelled/closed.\n *\n * @example\n * const confirmed = await showGlobalModal({\n * type: \"question\",\n * title: \"¿Eliminar votante?\",\n * message: \"Esta acción no se puede deshacer.\",\n * buttonMode: \"double\",\n * });\n *\n * @example — with custom JSX content\n * await showGlobalModal({\n * type: \"error\",\n * title: \"Error de sesión\",\n * content: <SesionExpiredDetails />,\n * });\n */\nexport const showGlobalModal = (payload: ModalPayload): Promise<boolean> => {\n // Close loading modals first (ModalGlobal handles its own pending promise internally)\n useModalLoadingStore.getState().closeLoading();\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalGlobalStore.getState().openModal(payload);\n};\n\n/**\n * Like `showGlobalModal` but resolves to `\"confirm\"`, `\"cancel\"`, or `\"close\"`,\n * letting you distinguish between the three ways a modal can be dismissed.\n *\n * @example\n * const result = await showGlobalModalWithClose({\n * type: \"warning\",\n * title: \"Guardar cambios\",\n * buttonMode: \"double\",\n * });\n * if (result === \"confirm\") save();\n * if (result === \"close\") navigateAway();\n */\nexport const showGlobalModalWithClose = (payload: ModalPayload): Promise<ModalResult> => {\n // Close loading modals first (ModalGlobal handles its own pending promise internally)\n useModalLoadingStore.getState().closeLoading();\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalGlobalStore.getState().openModalWithClose(payload);\n};\n\n/**\n * Programmatically close the global modal (resolves as cancelled).\n * Useful for layout/route-change handlers.\n *\n * ⚠️ Always check `isAlreadyHandled()` before calling this from a route handler\n * to avoid closing axios-controlled modals.\n */\nexport const closeGlobalModal = (): void =>\n useModalGlobalStore.getState().closeModal(false);\n\n/** Returns true if the global modal is currently open. */\nexport const isGlobalModalOpen = (): boolean =>\n useModalGlobalStore.getState().isOpen;\n\n/**\n * Returns true if the currently open modal was opened by an axios interceptor\n * (i.e. `alreadyHandled: true` was set). Use this to skip auto-close on\n * route changes.\n *\n * @example — in a Next.js layout\n * router.events.on(\"routeChangeStart\", () => {\n * if (isGlobalModalOpen() && !isAlreadyHandled()) {\n * closeGlobalModal();\n * }\n * });\n */\nexport const isAlreadyHandled = (): boolean =>\n useModalGlobalStore.getState().payload?.alreadyHandled ?? false;\n\n// ---------------------------------------------------------------------------\n// Loading helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Show the global loading modal.\n *\n * @example\n * showGlobalLoading(\"Guardando cambios...\");\n * await api.save(data);\n * closeGlobalLoading();\n */\nexport const showGlobalLoading = (message?: string): number => {\n // Close the other loading modal (safe — no pending promises)\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalLoadingStore.getState().openLoading(message);\n};\n\n/** Close the global loading modal. If sessionId is provided, only closes if it matches. */\nexport const closeGlobalLoading = (sessionId?: number): void =>\n useModalLoadingStore.getState().closeLoading(sessionId);\n\n/** Returns true if the global loading modal is currently visible. */\nexport const isGlobalLoadingOpen = (): boolean =>\n useModalLoadingStore.getState().isOpen;\n\n// ---------------------------------------------------------------------------\n// Loading percentage helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Show the global loading modal with a percentage progress bar.\n *\n * @example\n * showGlobalLoadingPercentage(\"Subiendo archivo...\");\n * for (const chunk of chunks) {\n * await upload(chunk);\n * updateGlobalLoadingPercentage(Math.round((i / chunks.length) * 100));\n * }\n * closeGlobalLoadingPercentage();\n */\n/**\n * Abre el modal de loading con porcentaje. Retorna un sessionId para evitar\n * interferencias si se abre otro modal del mismo tipo antes de cerrar el actual.\n * Pasar el sessionId a updateGlobalLoadingPercentage y closeGlobalLoadingPercentage\n * garantiza que solo la instancia activa pueda actualizar o cerrar el modal.\n */\nexport const showGlobalLoadingPercentage = (message?: string, initialPercentage?: number): number => {\n // Close the other loading modal (safe — no pending promises)\n useModalLoadingStore.getState().closeLoading();\n return useModalLoadingPercentageStore.getState().openLoadingPercentage(message, initialPercentage);\n};\n\n/** Update the percentage value (0–100). Si se pasa sessionId y no coincide con la sesión activa, se ignora. */\nexport const updateGlobalLoadingPercentage = (percentage: number, sessionId?: number): void =>\n useModalLoadingPercentageStore.getState().updatePercentage(percentage, sessionId);\n\n/** Close the global loading percentage modal. Si se pasa sessionId y no coincide con la sesión activa, se ignora. */\nexport const closeGlobalLoadingPercentage = (sessionId?: number): void =>\n useModalLoadingPercentageStore.getState().closeLoadingPercentage(sessionId);\n\n/** Returns true if the global loading percentage modal is currently visible. */\nexport const isGlobalLoadingPercentageOpen = (): boolean =>\n useModalLoadingPercentageStore.getState().isOpen;\n"]}
package/dist/modal.mjs CHANGED
@@ -117,7 +117,7 @@ var ModalLoadingPercentage = ({
117
117
  "div",
118
118
  {
119
119
  style: { width: `${clamped}%` },
120
- className: "h-10 bg-blue border-white border-2 transition-all ease-in-out duration-300"
120
+ className: "h-10 bg-onpe-blue border-white border-2 transition-all ease-in-out duration-300"
121
121
  }
122
122
  ) })
123
123
  ] })
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store/modalGlobal/useModalGlobalStore.ts","../src/store/modalGlobal/useModalLoadingStore.ts","../src/store/modalGlobal/useModalLoadingPercentageStore.ts","../src/components/Feedback/ModalLoadingPercentage/ModalLoadingPercentage.tsx","../src/components/ModalGlobal/ModalGlobalProvider.tsx","../src/utils/showGlobalModal.ts"],"names":["create","jsxs","jsx"],"mappings":";;;;;;;;AA0EO,IAAM,mBAAA,GAAsB,MAAA,CAAyB,CAAC,GAAA,EAAK,GAAA,MAAS;AAAA,EACzE,MAAA,EAAQ,KAAA;AAAA,EACR,OAAA,EAAS,IAAA;AAAA,EACT,OAAA,EAAS,CAAA;AAAA,EACT,UAAA,EAAY,KAAA;AAAA,EACZ,QAAA,EAAU,IAAA;AAAA,EACV,iBAAA,EAAmB,IAAA;AAAA,EAEnB,SAAA,EAAW,CAAC,OAAA,KAAY;AACtB,IAAA,OAAO,IAAI,OAAA,CAAiB,CAAC,OAAA,KAAY;AACvC,MAAA,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,QACd,MAAA,EAAQ,IAAA;AAAA,QACR,OAAA;AAAA,QACA,OAAA,EAAS,MAAM,OAAA,GAAU,CAAA;AAAA,QACzB,UAAA,EAAY,KAAA;AAAA,QACZ,QAAA,EAAU,OAAA;AAAA,QACV,iBAAA,EAAmB;AAAA,OACrB,CAAE,CAAA;AAAA,IACJ,CAAC,CAAA;AAAA,EACH,CAAA;AAAA,EAEA,kBAAA,EAAoB,CAAC,OAAA,KAAY;AAC/B,IAAA,OAAO,IAAI,OAAA,CAAqB,CAAC,OAAA,KAAY;AAC3C,MAAA,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,QACd,MAAA,EAAQ,IAAA;AAAA,QACR,OAAA;AAAA,QACA,OAAA,EAAS,MAAM,OAAA,GAAU,CAAA;AAAA,QACzB,UAAA,EAAY,IAAA;AAAA,QACZ,QAAA,EAAU,IAAA;AAAA,QACV,iBAAA,EAAmB;AAAA,OACrB,CAAE,CAAA;AAAA,IACJ,CAAC,CAAA;AAAA,EACH,CAAA;AAAA,EAEA,UAAA,EAAY,CAAC,SAAA,GAAY,KAAA,KAAU;AACjC,IAAA,MAAM,EAAE,QAAA,EAAU,iBAAA,EAAkB,GAAI,GAAA,EAAI;AAC5C,IAAA,QAAA,GAAW,SAAS,CAAA;AACpB,IAAA,iBAAA,GAAoB,SAAA,GAAY,YAAY,QAAQ,CAAA;AACpD,IAAA,GAAA,CAAI,EAAE,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,CAAA;AAAA,EAClG,CAAA;AAAA,EAEA,oBAAA,EAAsB,CAAC,MAAA,KAAW;AAChC,IAAA,MAAM,EAAE,QAAA,EAAU,iBAAA,EAAkB,GAAI,GAAA,EAAI;AAC5C,IAAA,QAAA,GAAW,WAAW,SAAS,CAAA;AAC/B,IAAA,iBAAA,GAAoB,MAAM,CAAA;AAC1B,IAAA,GAAA,CAAI,EAAE,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,IAAA,EAAM,UAAA,EAAY,KAAA,EAAO,QAAA,EAAU,IAAA,EAAM,iBAAA,EAAmB,IAAA,EAAM,CAAA;AAAA,EAClG;AACF,CAAA,CAAE;AC/GK,IAAM,oBAAA,GAAuBA,MAAAA,CAA0B,CAAC,GAAA,EAAK,GAAA,MAAS;AAAA,EAC3E,MAAA,EAAQ,KAAA;AAAA,EACR,OAAA,EAAS,aAAA;AAAA,EACT,SAAA,EAAW,CAAA;AAAA,EACX,WAAA,EAAa,CAAC,OAAA,GAAU,aAAA,KAAkB;AACxC,IAAA,MAAM,MAAA,GAAS,GAAA,EAAI,CAAE,SAAA,GAAY,CAAA;AACjC,IAAA,GAAA,CAAI,EAAE,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,SAAA,EAAW,QAAQ,CAAA;AAChD,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAAA,EACA,YAAA,EAAc,CAAC,SAAA,KAAc;AAC3B,IAAA,IAAI,SAAA,KAAc,MAAA,IAAa,SAAA,KAAc,GAAA,GAAM,SAAA,EAAW;AAC9D,IAAA,GAAA,CAAI,EAAE,MAAA,EAAQ,KAAA,EAAO,OAAA,EAAS,eAAe,CAAA;AAAA,EAC/C;AACF,CAAA,CAAE;ACVK,IAAM,8BAAA,GAAiCA,MAAAA,CAAoC,CAAC,GAAA,EAAK,GAAA,MAAS;AAAA,EAC/F,MAAA,EAAQ,KAAA;AAAA,EACR,OAAA,EAAS,aAAA;AAAA,EACT,UAAA,EAAY,CAAA;AAAA,EACZ,SAAA,EAAW,CAAA;AAAA,EACX,qBAAA,EAAuB,CAAC,OAAA,GAAU,aAAA,EAAe,oBAAoB,CAAA,KAAM;AACzE,IAAA,MAAM,MAAA,GAAS,GAAA,EAAI,CAAE,SAAA,GAAY,CAAA;AACjC,IAAA,GAAA,CAAI,EAAE,MAAA,EAAQ,IAAA,EAAM,OAAA,EAAS,UAAA,EAAY,KAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,GAAG,iBAAiB,CAAC,CAAA,EAAG,SAAA,EAAW,QAAQ,CAAA;AAC3G,IAAA,OAAO,MAAA;AAAA,EACT,CAAA;AAAA,EACA,gBAAA,EAAkB,CAAC,UAAA,EAAY,SAAA,KAAc;AAC3C,IAAA,IAAI,SAAA,KAAc,MAAA,IAAa,SAAA,KAAc,GAAA,GAAM,SAAA,EAAW;AAC9D,IAAA,GAAA,CAAI,EAAE,UAAA,EAAY,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,UAAU,CAAC,CAAA,EAAG,CAAA;AAAA,EAC5D,CAAA;AAAA,EACA,sBAAA,EAAwB,CAAC,SAAA,KAAc;AACrC,IAAA,IAAI,SAAA,KAAc,MAAA,IAAa,SAAA,KAAc,GAAA,GAAM,SAAA,EAAW;AAC9D,IAAA,GAAA,CAAI,EAAE,MAAA,EAAQ,KAAA,EAAO,SAAS,aAAA,EAAe,UAAA,EAAY,GAAG,CAAA;AAAA,EAC9D;AACF,CAAA,CAAE;AChBK,IAAM,yBAAyB,CAAC;AAAA,EACrC,MAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA,GAAc,GAAA;AAAA,EACd,QAAA,GAAW,IAAA;AAAA,EACX,iBAAA,GAAoB,IAAA;AAAA,EACpB,QAAA,GAAW;AACb,CAAA,KAAmC;AACjC,EAAA,MAAM,OAAA,GAAU,KAAK,GAAA,CAAI,GAAA,EAAK,KAAK,GAAA,CAAI,CAAA,EAAG,UAAU,CAAC,CAAA;AAErD,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,YAAA,EAAY,IAAA;AAAA,MACZ,MAAA;AAAA,MACA,SAAS,MAAM;AAAA,MAAC,CAAA;AAAA,MAChB,aAAA,EAAa,IAAA;AAAA,MACb,iBAAA,EAAiB,IAAA;AAAA,MACjB,WAAA;AAAA,MACA,QAAA;AAAA,MACA,iBAAA;AAAA,MACA,QAAA;AAAA,MAEA,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,oDAAA,EACb,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,GAAA,EAAA,EAAE,WAAU,qDAAA,EACV,QAAA,EAAA;AAAA,UAAA,OAAA;AAAA,UAAQ,GAAA;AAAA,UAAE,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,UAAE;AAAA,SAAA,EACjC,CAAA;AAAA,wBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,sCAAA,EACb,QAAA,kBAAA,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,EAAE,KAAA,EAAO,CAAA,EAAG,OAAO,CAAA,CAAA,CAAA,EAAI;AAAA,YAC9B,SAAA,EAAU;AAAA;AAAA,SACZ,EACF;AAAA,OAAA,EACF;AAAA;AAAA,GACF;AAEJ,CAAA;AChBO,IAAM,sBAAsB,CAAC;AAAA,EAClC,QAAA;AAAA,EACA,WAAA,GAAc,GAAA;AAAA,EACd,aAAA,GAAgB,GAAA;AAAA,EAChB,uBAAA,GAA0B,GAAA;AAAA,EAC1B,QAAA,GAAW,IAAA;AAAA,EACX,iBAAA,GAAoB,IAAA;AAAA,EACpB,cAAA;AAAA,EACA,yBAAA,GAA4B,KAAA;AAAA,EAC5B,wBAAA;AAAA,EACA,uBAAA;AAAA,EACA,YAAA,GAAe;AACjB,CAAA,KAAgC;AAC9B,EAAA,MAAM,MAAA,GAAS,mBAAA,CAAoB,CAAC,CAAA,KAAM,EAAE,MAAM,CAAA;AAClD,EAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AACpD,EAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AACpD,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AAC1D,EAAA,MAAM,UAAA,GAAa,mBAAA,CAAoB,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AAC1D,EAAA,MAAM,oBAAA,GAAuB,mBAAA;AAAA,IAC3B,CAAC,MAAM,CAAA,CAAE;AAAA,GACX;AACA,EAAA,MAAM,aAAA,GAAgB,oBAAA,CAAqB,CAAC,CAAA,KAAM,EAAE,MAAM,CAAA;AAC1D,EAAA,MAAM,cAAA,GAAiB,oBAAA,CAAqB,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AAC5D,EAAA,MAAM,gBAAA,GAAmB,8BAAA,CAA+B,CAAC,CAAA,KAAM,EAAE,MAAM,CAAA;AACvE,EAAA,MAAM,iBAAA,GAAoB,8BAAA,CAA+B,CAAC,CAAA,KAAM,EAAE,OAAO,CAAA;AACzE,EAAA,MAAM,UAAA,GAAa,8BAAA,CAA+B,CAAC,CAAA,KAAM,EAAE,UAAU,CAAA;AAGrE,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS,kBAAA,EAAoB;AAE7C,IAAA,MAAM,OAAA,GAAU,WAAW,MAAM;AAC/B,MAAA,UAAA,CAAW,IAAI,CAAA;AAAA,IACjB,CAAA,EAAG,QAAQ,kBAAkB,CAAA;AAE7B,IAAA,OAAO,MAAM,aAAa,OAAO,CAAA;AAAA,EACnC,CAAA,EAAG,CAAC,MAAA,EAAQ,OAAO,CAAC,CAAA;AAEpB,EAAA,MAAM,YAAA,GAAe,OAAA;AAAA,IACnB,OAAO,EAAE,QAAA,EAAU,YAAA,EAAa,CAAA;AAAA,IAChC,CAAC,UAAU,YAAY;AAAA,GACzB;AAEA,EAAA,uBACEC,IAAAA,CAAC,kBAAA,CAAmB,QAAA,EAAnB,EAA4B,OAAO,YAAA,EACjC,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,oBAGDC,GAAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,MAAA;AAAA,QACA,OAAA,EAAS,MAAM,oBAAA,CAAqB,OAAO,CAAA;AAAA,QAC3C,OAAO,OAAA,EAAS,KAAA;AAAA,QAChB,SAAS,OAAA,EAAS,OAAA;AAAA,QAClB,SAAS,OAAA,EAAS,OAAA;AAAA,QAClB,IAAA,EAAM,OAAA,EAAS,QAAA,IAAY,OAAA,EAAS,IAAA;AAAA,QACpC,YAAY,OAAA,EAAS,UAAA;AAAA,QACrB,uBAAuB,OAAA,EAAS,qBAAA;AAAA,QAChC,eAAe,OAAA,EAAS,aAAA;AAAA,QACxB,OAAO,OAAA,EAAS,KAAA;AAAA,QAChB,SAAA,EAAW,MAAM,UAAA,CAAW,IAAI,CAAA;AAAA,QAChC,QAAA,EAAU,MAAM,UAAA,CAAW,KAAK,CAAA;AAAA,QAChC,gBAAA,EAAgB,IAAA;AAAA,QAChB,iBAAA,EACE,SAAS,iBAAA,IAAqB,wBAAA;AAAA,QAEhC,gBAAA,EAAkB,SAAS,gBAAA,IAAoB,uBAAA;AAAA,QAC/C,WAAA,EAAa,SAAS,WAAA,IAAe,UAAA;AAAA,QACrC,cAAc,OAAA,EAAS,YAAA;AAAA,QACvB,UAAU,OAAA,EAAS,GAAA;AAAA,QACnB,WAAA;AAAA,QACA,QAAA;AAAA,QACA,iBAAA;AAAA,QACA;AAAA;AAAA,KACF;AAAA,oBAGAA,GAAAA;AAAA,MAAC,YAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAQ,aAAA;AAAA,QACR,OAAA,EAAS,cAAA;AAAA,QACT,WAAA,EAAa,aAAA;AAAA,QACb,QAAA;AAAA,QACA,iBAAA;AAAA,QACA,OAAA,EAAS;AAAA;AAAA,KACX;AAAA,oBAGAA,GAAAA;AAAA,MAAC,sBAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAQ,gBAAA;AAAA,QACR,OAAA,EAAS,iBAAA;AAAA,QACT,UAAA;AAAA,QACA,WAAA,EAAa,uBAAA;AAAA,QACb,QAAA;AAAA,QACA,iBAAA;AAAA,QACA,QAAA,EAAU;AAAA;AAAA;AACZ,GAAA,EACF,CAAA;AAEJ;;;AC5GO,IAAM,eAAA,GAAkB,CAAC,OAAA,KAA4C;AAE1E,EAAA,oBAAA,CAAqB,QAAA,GAAW,YAAA,EAAa;AAC7C,EAAA,8BAAA,CAA+B,QAAA,GAAW,sBAAA,EAAuB;AACjE,EAAA,OAAO,mBAAA,CAAoB,QAAA,EAAS,CAAE,SAAA,CAAU,OAAO,CAAA;AACzD;AAeO,IAAM,wBAAA,GAA2B,CAAC,OAAA,KAAgD;AAEvF,EAAA,oBAAA,CAAqB,QAAA,GAAW,YAAA,EAAa;AAC7C,EAAA,8BAAA,CAA+B,QAAA,GAAW,sBAAA,EAAuB;AACjE,EAAA,OAAO,mBAAA,CAAoB,QAAA,EAAS,CAAE,kBAAA,CAAmB,OAAO,CAAA;AAClE;AASO,IAAM,mBAAmB,MAC9B,mBAAA,CAAoB,QAAA,EAAS,CAAE,WAAW,KAAK;AAG1C,IAAM,iBAAA,GAAoB,MAC/B,mBAAA,CAAoB,QAAA,EAAS,CAAE;AAc1B,IAAM,mBAAmB,MAC9B,mBAAA,CAAoB,QAAA,EAAS,CAAE,SAAS,cAAA,IAAkB;AAcrD,IAAM,iBAAA,GAAoB,CAAC,OAAA,KAA6B;AAE7D,EAAA,8BAAA,CAA+B,QAAA,GAAW,sBAAA,EAAuB;AACjE,EAAA,OAAO,oBAAA,CAAqB,QAAA,EAAS,CAAE,WAAA,CAAY,OAAO,CAAA;AAC5D;AAGO,IAAM,qBAAqB,CAAC,SAAA,KACjC,qBAAqB,QAAA,EAAS,CAAE,aAAa,SAAS;AAGjD,IAAM,mBAAA,GAAsB,MACjC,oBAAA,CAAqB,QAAA,EAAS,CAAE;AAuB3B,IAAM,2BAAA,GAA8B,CAAC,OAAA,EAAkB,iBAAA,KAAuC;AAEnG,EAAA,oBAAA,CAAqB,QAAA,GAAW,YAAA,EAAa;AAC7C,EAAA,OAAO,8BAAA,CAA+B,QAAA,EAAS,CAAE,qBAAA,CAAsB,SAAS,iBAAiB,CAAA;AACnG;AAGO,IAAM,6BAAA,GAAgC,CAAC,UAAA,EAAoB,SAAA,KAChE,+BAA+B,QAAA,EAAS,CAAE,gBAAA,CAAiB,UAAA,EAAY,SAAS;AAG3E,IAAM,+BAA+B,CAAC,SAAA,KAC3C,+BAA+B,QAAA,EAAS,CAAE,uBAAuB,SAAS;AAGrE,IAAM,6BAAA,GAAgC,MAC3C,8BAAA,CAA+B,QAAA,EAAS,CAAE","file":"modal.mjs","sourcesContent":["import { create } from \"zustand\";\nimport type { ReactNode } from \"react\";\nimport type { ModalType } from \"../../components/Feedback/ModalConfirm/ModalConfirm\";\n\nexport type { ModalType };\n\nexport type ModalResult = \"confirm\" | \"cancel\" | \"close\";\n\n/**\n * Payload del modal global.\n * Combina los props de ModalGlobalComponent (type, buttonMode, content)\n * con los de ModalConfirm (icon, color, twoButtons).\n * Los props del global component predominan; color e icon son overrides manuales.\n */\nexport interface ModalPayload {\n title?: string;\n /** Contenido del modal (string o JSX). Alias: content */\n message?: ReactNode;\n /** Alias de message para compatibilidad */\n content?: ReactNode;\n /** Tipo semántico: determina icono y color */\n type: ModalType;\n /**\n * Override del icono independiente del `type`.\n * Usa los mismos valores que `type`. Si se provee, tiene prioridad sobre `type` para el icono.\n */\n iconType?: ModalType;\n /**\n * \"single\" → un botón \"Confirmar\".\n * \"double\" → \"Cancelar\" + \"Confirmar\".\n * \"confirm\" → \"No\" + \"Sí\" (diálogo de confirmación).\n */\n buttonMode?: \"single\" | \"double\" | \"confirm\";\n /** Deshabilita el botón confirmar */\n disabledConfirmButton?: boolean;\n /** Deshabilita el cierre del modal */\n closeDisabled?: boolean;\n /** Override manual del color del icono y título */\n color?: \"red\" | \"blue\" | \"skyblue\" | \"yellow\";\n textButtonConfirm?: string;\n textButtonCancel?: string;\n /** Muestra el botón X para cerrar el modal */\n closeButton?: boolean;\n /** Alinea el texto del mensaje a la izquierda (justify) en vez de centrado */\n alignJustify?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n top?: boolean;\n /**\n * Tiempo en ms para auto-confirmar el modal (ej: 30000 = 30s).\n * Útil para modales de error de sesión/red que deben cerrarse solos.\n */\n autoConfirmTimeout?: number;\n /**\n * Marca este modal como controlado por axios interceptor.\n * Cuando es true, los handlers de cambio de ruta NO deben cerrarlo.\n */\n alreadyHandled?: boolean;\n}\n\ninterface ModalGlobalState {\n isOpen: boolean;\n payload: ModalPayload | null;\n modalId: number;\n /** true cuando fue abierto con openModalWithClose (3 estados) */\n isTriState: boolean;\n _resolve: ((result: boolean) => void) | null;\n _resolveWithClose: ((result: ModalResult) => void) | null;\n\n openModal: (payload: ModalPayload) => Promise<boolean>;\n openModalWithClose: (payload: ModalPayload) => Promise<ModalResult>;\n closeModal: (confirmed?: boolean) => void;\n closeModalWithResult: (result: ModalResult) => void;\n}\n\nexport const useModalGlobalStore = create<ModalGlobalState>((set, get) => ({\n isOpen: false,\n payload: null,\n modalId: 0,\n isTriState: false,\n _resolve: null,\n _resolveWithClose: null,\n\n openModal: (payload) => {\n return new Promise<boolean>((resolve) => {\n set((state) => ({\n isOpen: true,\n payload,\n modalId: state.modalId + 1,\n isTriState: false,\n _resolve: resolve,\n _resolveWithClose: null,\n }));\n });\n },\n\n openModalWithClose: (payload) => {\n return new Promise<ModalResult>((resolve) => {\n set((state) => ({\n isOpen: true,\n payload,\n modalId: state.modalId + 1,\n isTriState: true,\n _resolve: null,\n _resolveWithClose: resolve,\n }));\n });\n },\n\n closeModal: (confirmed = false) => {\n const { _resolve, _resolveWithClose } = get();\n _resolve?.(confirmed);\n _resolveWithClose?.(confirmed ? \"confirm\" : \"cancel\");\n set({ isOpen: false, payload: null, isTriState: false, _resolve: null, _resolveWithClose: null });\n },\n\n closeModalWithResult: (result) => {\n const { _resolve, _resolveWithClose } = get();\n _resolve?.(result === \"confirm\");\n _resolveWithClose?.(result);\n set({ isOpen: false, payload: null, isTriState: false, _resolve: null, _resolveWithClose: null });\n },\n}));\n","import { create } from \"zustand\";\n\ninterface ModalLoadingState {\n isOpen: boolean;\n message: string;\n sessionId: number;\n openLoading: (message?: string) => number;\n closeLoading: (sessionId?: number) => void;\n}\n\nexport const useModalLoadingStore = create<ModalLoadingState>((set, get) => ({\n isOpen: false,\n message: \"Cargando...\",\n sessionId: 0,\n openLoading: (message = \"Cargando...\") => {\n const nextId = get().sessionId + 1;\n set({ isOpen: true, message, sessionId: nextId });\n return nextId;\n },\n closeLoading: (sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ isOpen: false, message: \"Cargando...\" });\n },\n}));\n","import { create } from \"zustand\";\n\ninterface ModalLoadingPercentageState {\n isOpen: boolean;\n message: string;\n percentage: number;\n /** ID de sesión actual — se incrementa en cada apertura */\n sessionId: number;\n openLoadingPercentage: (message?: string, initialPercentage?: number) => number;\n updatePercentage: (percentage: number, sessionId?: number) => void;\n closeLoadingPercentage: (sessionId?: number) => void;\n}\n\nexport const useModalLoadingPercentageStore = create<ModalLoadingPercentageState>((set, get) => ({\n isOpen: false,\n message: \"Cargando...\",\n percentage: 0,\n sessionId: 0,\n openLoadingPercentage: (message = \"Cargando...\", initialPercentage = 0) => {\n const nextId = get().sessionId + 1;\n set({ isOpen: true, message, percentage: Math.min(100, Math.max(0, initialPercentage)), sessionId: nextId });\n return nextId;\n },\n updatePercentage: (percentage, sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ percentage: Math.min(100, Math.max(0, percentage)) });\n },\n closeLoadingPercentage: (sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ isOpen: false, message: \"Cargando...\", percentage: 0 });\n },\n}));\n","\"use client\";\n\nimport { Modal } from \"../../Modal/Modal\";\n\ninterface ModalLoadingPercentageProps {\n isOpen: boolean;\n message: string;\n percentage: number;\n zIndexLevel?: number;\n animated?: boolean;\n preventBodyScroll?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n alignTop?: boolean;\n}\n\nexport const ModalLoadingPercentage = ({\n isOpen,\n message,\n percentage,\n zIndexLevel = 300,\n animated = true,\n preventBodyScroll = true,\n alignTop = false,\n}: ModalLoadingPercentageProps) => {\n const clamped = Math.min(100, Math.max(0, percentage));\n\n return (\n <Modal\n disableFocus\n isOpen={isOpen}\n onClose={() => {}}\n closeDisabled\n whitoutBackground\n zIndexLevel={zIndexLevel}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n alignTop={alignTop}\n >\n <div className=\"bg-transparent flex-col flex items-center p-[50px]\">\n <p className=\"text-white leading-normal text-6xl text-center mt-4\">\n {message} {Math.floor(clamped)}%\n </p>\n <div className=\"w-[600px] h-10 bg-white inline-block\">\n <div\n style={{ width: `${clamped}%` }}\n className=\"h-10 bg-blue border-white border-2 transition-all ease-in-out duration-300\"\n />\n </div>\n </div>\n </Modal>\n );\n};\n\nexport default ModalLoadingPercentage;\n","\"use client\";\n\nimport { type ReactNode, useEffect, useMemo } from \"react\";\nimport { ModalGlobalContext } from \"./ModalGlobalContext\";\nimport { useModalGlobalStore } from \"../../store/modalGlobal/useModalGlobalStore\";\nimport { useModalLoadingStore } from \"../../store/modalGlobal/useModalLoadingStore\";\nimport { useModalLoadingPercentageStore } from \"../../store/modalGlobal/useModalLoadingPercentageStore\";\nimport { ModalConfirm } from \"../Feedback/ModalConfirm/ModalConfirm\";\nimport { ModalLoading } from \"../Feedback/ModalLoading/ModalLoading\";\nimport { ModalLoadingPercentage } from \"../Feedback/ModalLoadingPercentage/ModalLoadingPercentage\";\n\ninterface ModalGlobalProviderProps {\n children: ReactNode;\n /** z-index del modal principal (default: 200) */\n zIndexLevel?: number;\n /** z-index del modal de loading (default: 300) */\n zIndexLoading?: number;\n /** z-index del modal de loading con porcentaje (default: 300) */\n zIndexLoadingPercentage?: number;\n /** Habilita animación de entrada/salida en todos los modales (default: true) */\n animated?: boolean;\n /** Bloquea el scroll del body en todos los modales (default: true) */\n preventBodyScroll?: boolean;\n /** Spinner personalizado para ModalLoading. Si no se provee, se usa el spinner por defecto. */\n loadingSpinner?: ReactNode;\n /** Alinea el ModalLoadingPercentage al tope de la pantalla (default: false) */\n loadingPercentageAlignTop?: boolean;\n /** Texto por defecto del botón confirmar cuando el payload no lo especifica */\n defaultTextButtonConfirm?: string;\n /** Texto por defecto del botón cancelar cuando el payload no lo especifica */\n defaultTextButtonCancel?: string;\n /** Deshabilita el manejo de focus en todos los modales (default: false) */\n disableFocus?: boolean;\n}\n\nexport const ModalGlobalProvider = ({\n children,\n zIndexLevel = 200,\n zIndexLoading = 300,\n zIndexLoadingPercentage = 300,\n animated = true,\n preventBodyScroll = true,\n loadingSpinner,\n loadingPercentageAlignTop = false,\n defaultTextButtonConfirm,\n defaultTextButtonCancel,\n disableFocus = false,\n}: ModalGlobalProviderProps) => {\n const isOpen = useModalGlobalStore((s) => s.isOpen);\n const payload = useModalGlobalStore((s) => s.payload);\n const modalId = useModalGlobalStore((s) => s.modalId);\n const isTriState = useModalGlobalStore((s) => s.isTriState);\n const closeModal = useModalGlobalStore((s) => s.closeModal);\n const closeModalWithResult = useModalGlobalStore(\n (s) => s.closeModalWithResult,\n );\n const isLoadingOpen = useModalLoadingStore((s) => s.isOpen);\n const loadingMessage = useModalLoadingStore((s) => s.message);\n const isPercentageOpen = useModalLoadingPercentageStore((s) => s.isOpen);\n const percentageMessage = useModalLoadingPercentageStore((s) => s.message);\n const percentage = useModalLoadingPercentageStore((s) => s.percentage);\n\n // Auto-confirmar el modal después del timeout especificado\n useEffect(() => {\n if (!isOpen || !payload?.autoConfirmTimeout) return;\n\n const timerId = setTimeout(() => {\n closeModal(true);\n }, payload.autoConfirmTimeout);\n\n return () => clearTimeout(timerId);\n }, [isOpen, modalId]);\n\n const contextValue = useMemo(\n () => ({ animated, disableFocus }),\n [animated, disableFocus],\n );\n\n return (\n <ModalGlobalContext.Provider value={contextValue}>\n {children}\n\n {/* Modal principal — usa ModalConfirm de la librería directamente */}\n <ModalConfirm\n isOpen={isOpen}\n onClose={() => closeModalWithResult(\"close\")}\n title={payload?.title}\n message={payload?.message}\n content={payload?.content}\n type={payload?.iconType ?? payload?.type}\n buttonMode={payload?.buttonMode}\n disabledConfirmButton={payload?.disabledConfirmButton}\n closeDisabled={payload?.closeDisabled}\n color={payload?.color}\n onConfirm={() => closeModal(true)}\n onCancel={() => closeModal(false)}\n withoutAutoClose\n textButtonConfirm={\n payload?.textButtonConfirm ?? defaultTextButtonConfirm\n }\n textButtonCancel={payload?.textButtonCancel ?? defaultTextButtonCancel}\n closeButton={payload?.closeButton ?? isTriState}\n alignJustify={payload?.alignJustify}\n alignTop={payload?.top}\n zIndexLevel={zIndexLevel}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n disableFocus={disableFocus}\n />\n\n {/* Loading */}\n <ModalLoading\n isOpen={isLoadingOpen}\n message={loadingMessage}\n zIndexLevel={zIndexLoading}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n spinner={loadingSpinner}\n />\n\n {/* Loading con porcentaje */}\n <ModalLoadingPercentage\n isOpen={isPercentageOpen}\n message={percentageMessage}\n percentage={percentage}\n zIndexLevel={zIndexLoadingPercentage}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n alignTop={loadingPercentageAlignTop}\n />\n </ModalGlobalContext.Provider>\n );\n};\n\nexport default ModalGlobalProvider;\n","import { useModalGlobalStore } from \"../store/modalGlobal/useModalGlobalStore\";\nimport { useModalLoadingStore } from \"../store/modalGlobal/useModalLoadingStore\";\nimport { useModalLoadingPercentageStore } from \"../store/modalGlobal/useModalLoadingPercentageStore\";\nimport type { ModalPayload, ModalResult } from \"../store/modalGlobal/useModalGlobalStore\";\n\n/**\n * Open the global modal. Returns a promise that resolves to `true` if the user\n * confirmed, or `false` if they cancelled/closed.\n *\n * @example\n * const confirmed = await showGlobalModal({\n * type: \"question\",\n * title: \"¿Eliminar votante?\",\n * message: \"Esta acción no se puede deshacer.\",\n * buttonMode: \"double\",\n * });\n *\n * @example — with custom JSX content\n * await showGlobalModal({\n * type: \"error\",\n * title: \"Error de sesión\",\n * content: <SesionExpiredDetails />,\n * });\n */\nexport const showGlobalModal = (payload: ModalPayload): Promise<boolean> => {\n // Close loading modals first (ModalGlobal handles its own pending promise internally)\n useModalLoadingStore.getState().closeLoading();\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalGlobalStore.getState().openModal(payload);\n};\n\n/**\n * Like `showGlobalModal` but resolves to `\"confirm\"`, `\"cancel\"`, or `\"close\"`,\n * letting you distinguish between the three ways a modal can be dismissed.\n *\n * @example\n * const result = await showGlobalModalWithClose({\n * type: \"warning\",\n * title: \"Guardar cambios\",\n * buttonMode: \"double\",\n * });\n * if (result === \"confirm\") save();\n * if (result === \"close\") navigateAway();\n */\nexport const showGlobalModalWithClose = (payload: ModalPayload): Promise<ModalResult> => {\n // Close loading modals first (ModalGlobal handles its own pending promise internally)\n useModalLoadingStore.getState().closeLoading();\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalGlobalStore.getState().openModalWithClose(payload);\n};\n\n/**\n * Programmatically close the global modal (resolves as cancelled).\n * Useful for layout/route-change handlers.\n *\n * ⚠️ Always check `isAlreadyHandled()` before calling this from a route handler\n * to avoid closing axios-controlled modals.\n */\nexport const closeGlobalModal = (): void =>\n useModalGlobalStore.getState().closeModal(false);\n\n/** Returns true if the global modal is currently open. */\nexport const isGlobalModalOpen = (): boolean =>\n useModalGlobalStore.getState().isOpen;\n\n/**\n * Returns true if the currently open modal was opened by an axios interceptor\n * (i.e. `alreadyHandled: true` was set). Use this to skip auto-close on\n * route changes.\n *\n * @example — in a Next.js layout\n * router.events.on(\"routeChangeStart\", () => {\n * if (isGlobalModalOpen() && !isAlreadyHandled()) {\n * closeGlobalModal();\n * }\n * });\n */\nexport const isAlreadyHandled = (): boolean =>\n useModalGlobalStore.getState().payload?.alreadyHandled ?? false;\n\n// ---------------------------------------------------------------------------\n// Loading helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Show the global loading modal.\n *\n * @example\n * showGlobalLoading(\"Guardando cambios...\");\n * await api.save(data);\n * closeGlobalLoading();\n */\nexport const showGlobalLoading = (message?: string): number => {\n // Close the other loading modal (safe — no pending promises)\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalLoadingStore.getState().openLoading(message);\n};\n\n/** Close the global loading modal. If sessionId is provided, only closes if it matches. */\nexport const closeGlobalLoading = (sessionId?: number): void =>\n useModalLoadingStore.getState().closeLoading(sessionId);\n\n/** Returns true if the global loading modal is currently visible. */\nexport const isGlobalLoadingOpen = (): boolean =>\n useModalLoadingStore.getState().isOpen;\n\n// ---------------------------------------------------------------------------\n// Loading percentage helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Show the global loading modal with a percentage progress bar.\n *\n * @example\n * showGlobalLoadingPercentage(\"Subiendo archivo...\");\n * for (const chunk of chunks) {\n * await upload(chunk);\n * updateGlobalLoadingPercentage(Math.round((i / chunks.length) * 100));\n * }\n * closeGlobalLoadingPercentage();\n */\n/**\n * Abre el modal de loading con porcentaje. Retorna un sessionId para evitar\n * interferencias si se abre otro modal del mismo tipo antes de cerrar el actual.\n * Pasar el sessionId a updateGlobalLoadingPercentage y closeGlobalLoadingPercentage\n * garantiza que solo la instancia activa pueda actualizar o cerrar el modal.\n */\nexport const showGlobalLoadingPercentage = (message?: string, initialPercentage?: number): number => {\n // Close the other loading modal (safe — no pending promises)\n useModalLoadingStore.getState().closeLoading();\n return useModalLoadingPercentageStore.getState().openLoadingPercentage(message, initialPercentage);\n};\n\n/** Update the percentage value (0–100). Si se pasa sessionId y no coincide con la sesión activa, se ignora. */\nexport const updateGlobalLoadingPercentage = (percentage: number, sessionId?: number): void =>\n useModalLoadingPercentageStore.getState().updatePercentage(percentage, sessionId);\n\n/** Close the global loading percentage modal. Si se pasa sessionId y no coincide con la sesión activa, se ignora. */\nexport const closeGlobalLoadingPercentage = (sessionId?: number): void =>\n useModalLoadingPercentageStore.getState().closeLoadingPercentage(sessionId);\n\n/** Returns true if the global loading percentage modal is currently visible. */\nexport const isGlobalLoadingPercentageOpen = (): boolean =>\n useModalLoadingPercentageStore.getState().isOpen;\n"]}
1
+ {"version":3,"sources":["../src/store/modalGlobal/useModalGlobalStore.ts","../src/store/modalGlobal/useModalLoadingStore.ts","../src/store/modalGlobal/useModalLoadingPercentageStore.ts","../src/components/Feedback/ModalLoadingPercentage/ModalLoadingPercentage.tsx","../src/components/ModalGlobal/ModalGlobalProvider.tsx","../src/utils/showGlobalModal.ts"],"names":["create","jsxs","jsx"],"mappings":"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","file":"modal.mjs","sourcesContent":["import { create } from \"zustand\";\nimport type { ReactNode } from \"react\";\nimport type { ModalType } from \"../../components/Feedback/ModalConfirm/ModalConfirm\";\n\nexport type { ModalType };\n\nexport type ModalResult = \"confirm\" | \"cancel\" | \"close\";\n\n/**\n * Payload del modal global.\n * Combina los props de ModalGlobalComponent (type, buttonMode, content)\n * con los de ModalConfirm (icon, color, twoButtons).\n * Los props del global component predominan; color e icon son overrides manuales.\n */\nexport interface ModalPayload {\n title?: string;\n /** Contenido del modal (string o JSX). Alias: content */\n message?: ReactNode;\n /** Alias de message para compatibilidad */\n content?: ReactNode;\n /** Tipo semántico: determina icono y color */\n type: ModalType;\n /**\n * Override del icono independiente del `type`.\n * Usa los mismos valores que `type`. Si se provee, tiene prioridad sobre `type` para el icono.\n */\n iconType?: ModalType;\n /**\n * \"single\" → un botón \"Confirmar\".\n * \"double\" → \"Cancelar\" + \"Confirmar\".\n * \"confirm\" → \"No\" + \"Sí\" (diálogo de confirmación).\n */\n buttonMode?: \"single\" | \"double\" | \"confirm\";\n /** Deshabilita el botón confirmar */\n disabledConfirmButton?: boolean;\n /** Deshabilita el cierre del modal */\n closeDisabled?: boolean;\n /** Override manual del color del icono y título */\n color?: \"red\" | \"blue\" | \"skyblue\" | \"yellow\";\n textButtonConfirm?: string;\n textButtonCancel?: string;\n /** Muestra el botón X para cerrar el modal */\n closeButton?: boolean;\n /** Alinea el texto del mensaje a la izquierda (justify) en vez de centrado */\n alignJustify?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n top?: boolean;\n /**\n * Tiempo en ms para auto-confirmar el modal (ej: 30000 = 30s).\n * Útil para modales de error de sesión/red que deben cerrarse solos.\n */\n autoConfirmTimeout?: number;\n /**\n * Marca este modal como controlado por axios interceptor.\n * Cuando es true, los handlers de cambio de ruta NO deben cerrarlo.\n */\n alreadyHandled?: boolean;\n}\n\ninterface ModalGlobalState {\n isOpen: boolean;\n payload: ModalPayload | null;\n modalId: number;\n /** true cuando fue abierto con openModalWithClose (3 estados) */\n isTriState: boolean;\n _resolve: ((result: boolean) => void) | null;\n _resolveWithClose: ((result: ModalResult) => void) | null;\n\n openModal: (payload: ModalPayload) => Promise<boolean>;\n openModalWithClose: (payload: ModalPayload) => Promise<ModalResult>;\n closeModal: (confirmed?: boolean) => void;\n closeModalWithResult: (result: ModalResult) => void;\n}\n\nexport const useModalGlobalStore = create<ModalGlobalState>((set, get) => ({\n isOpen: false,\n payload: null,\n modalId: 0,\n isTriState: false,\n _resolve: null,\n _resolveWithClose: null,\n\n openModal: (payload) => {\n return new Promise<boolean>((resolve) => {\n set((state) => ({\n isOpen: true,\n payload,\n modalId: state.modalId + 1,\n isTriState: false,\n _resolve: resolve,\n _resolveWithClose: null,\n }));\n });\n },\n\n openModalWithClose: (payload) => {\n return new Promise<ModalResult>((resolve) => {\n set((state) => ({\n isOpen: true,\n payload,\n modalId: state.modalId + 1,\n isTriState: true,\n _resolve: null,\n _resolveWithClose: resolve,\n }));\n });\n },\n\n closeModal: (confirmed = false) => {\n const { _resolve, _resolveWithClose } = get();\n _resolve?.(confirmed);\n _resolveWithClose?.(confirmed ? \"confirm\" : \"cancel\");\n set({ isOpen: false, payload: null, isTriState: false, _resolve: null, _resolveWithClose: null });\n },\n\n closeModalWithResult: (result) => {\n const { _resolve, _resolveWithClose } = get();\n _resolve?.(result === \"confirm\");\n _resolveWithClose?.(result);\n set({ isOpen: false, payload: null, isTriState: false, _resolve: null, _resolveWithClose: null });\n },\n}));\n","import { create } from \"zustand\";\n\ninterface ModalLoadingState {\n isOpen: boolean;\n message: string;\n sessionId: number;\n openLoading: (message?: string) => number;\n closeLoading: (sessionId?: number) => void;\n}\n\nexport const useModalLoadingStore = create<ModalLoadingState>((set, get) => ({\n isOpen: false,\n message: \"Cargando...\",\n sessionId: 0,\n openLoading: (message = \"Cargando...\") => {\n const nextId = get().sessionId + 1;\n set({ isOpen: true, message, sessionId: nextId });\n return nextId;\n },\n closeLoading: (sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ isOpen: false, message: \"Cargando...\" });\n },\n}));\n","import { create } from \"zustand\";\n\ninterface ModalLoadingPercentageState {\n isOpen: boolean;\n message: string;\n percentage: number;\n /** ID de sesión actual — se incrementa en cada apertura */\n sessionId: number;\n openLoadingPercentage: (message?: string, initialPercentage?: number) => number;\n updatePercentage: (percentage: number, sessionId?: number) => void;\n closeLoadingPercentage: (sessionId?: number) => void;\n}\n\nexport const useModalLoadingPercentageStore = create<ModalLoadingPercentageState>((set, get) => ({\n isOpen: false,\n message: \"Cargando...\",\n percentage: 0,\n sessionId: 0,\n openLoadingPercentage: (message = \"Cargando...\", initialPercentage = 0) => {\n const nextId = get().sessionId + 1;\n set({ isOpen: true, message, percentage: Math.min(100, Math.max(0, initialPercentage)), sessionId: nextId });\n return nextId;\n },\n updatePercentage: (percentage, sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ percentage: Math.min(100, Math.max(0, percentage)) });\n },\n closeLoadingPercentage: (sessionId) => {\n if (sessionId !== undefined && sessionId !== get().sessionId) return;\n set({ isOpen: false, message: \"Cargando...\", percentage: 0 });\n },\n}));\n","\"use client\";\n\nimport { Modal } from \"../../Modal/Modal\";\n\ninterface ModalLoadingPercentageProps {\n isOpen: boolean;\n message: string;\n percentage: number;\n zIndexLevel?: number;\n animated?: boolean;\n preventBodyScroll?: boolean;\n /** Alinea el modal al tope de la pantalla en vez de al centro */\n alignTop?: boolean;\n}\n\nexport const ModalLoadingPercentage = ({\n isOpen,\n message,\n percentage,\n zIndexLevel = 300,\n animated = true,\n preventBodyScroll = true,\n alignTop = false,\n}: ModalLoadingPercentageProps) => {\n const clamped = Math.min(100, Math.max(0, percentage));\n\n return (\n <Modal\n disableFocus\n isOpen={isOpen}\n onClose={() => {}}\n closeDisabled\n whitoutBackground\n zIndexLevel={zIndexLevel}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n alignTop={alignTop}\n >\n <div className=\"bg-transparent flex-col flex items-center p-[50px]\">\n <p className=\"text-white leading-normal text-6xl text-center mt-4\">\n {message} {Math.floor(clamped)}%\n </p>\n <div className=\"w-[600px] h-10 bg-white inline-block\">\n <div\n style={{ width: `${clamped}%` }}\n className=\"h-10 bg-onpe-blue border-white border-2 transition-all ease-in-out duration-300\"\n />\n </div>\n </div>\n </Modal>\n );\n};\n\nexport default ModalLoadingPercentage;\n","\"use client\";\n\nimport { type ReactNode, useEffect, useMemo } from \"react\";\nimport { ModalGlobalContext } from \"./ModalGlobalContext\";\nimport { useModalGlobalStore } from \"../../store/modalGlobal/useModalGlobalStore\";\nimport { useModalLoadingStore } from \"../../store/modalGlobal/useModalLoadingStore\";\nimport { useModalLoadingPercentageStore } from \"../../store/modalGlobal/useModalLoadingPercentageStore\";\nimport { ModalConfirm } from \"../Feedback/ModalConfirm/ModalConfirm\";\nimport { ModalLoading } from \"../Feedback/ModalLoading/ModalLoading\";\nimport { ModalLoadingPercentage } from \"../Feedback/ModalLoadingPercentage/ModalLoadingPercentage\";\n\ninterface ModalGlobalProviderProps {\n children: ReactNode;\n /** z-index del modal principal (default: 200) */\n zIndexLevel?: number;\n /** z-index del modal de loading (default: 300) */\n zIndexLoading?: number;\n /** z-index del modal de loading con porcentaje (default: 300) */\n zIndexLoadingPercentage?: number;\n /** Habilita animación de entrada/salida en todos los modales (default: true) */\n animated?: boolean;\n /** Bloquea el scroll del body en todos los modales (default: true) */\n preventBodyScroll?: boolean;\n /** Spinner personalizado para ModalLoading. Si no se provee, se usa el spinner por defecto. */\n loadingSpinner?: ReactNode;\n /** Alinea el ModalLoadingPercentage al tope de la pantalla (default: false) */\n loadingPercentageAlignTop?: boolean;\n /** Texto por defecto del botón confirmar cuando el payload no lo especifica */\n defaultTextButtonConfirm?: string;\n /** Texto por defecto del botón cancelar cuando el payload no lo especifica */\n defaultTextButtonCancel?: string;\n /** Deshabilita el manejo de focus en todos los modales (default: false) */\n disableFocus?: boolean;\n}\n\nexport const ModalGlobalProvider = ({\n children,\n zIndexLevel = 200,\n zIndexLoading = 300,\n zIndexLoadingPercentage = 300,\n animated = true,\n preventBodyScroll = true,\n loadingSpinner,\n loadingPercentageAlignTop = false,\n defaultTextButtonConfirm,\n defaultTextButtonCancel,\n disableFocus = false,\n}: ModalGlobalProviderProps) => {\n const isOpen = useModalGlobalStore((s) => s.isOpen);\n const payload = useModalGlobalStore((s) => s.payload);\n const modalId = useModalGlobalStore((s) => s.modalId);\n const isTriState = useModalGlobalStore((s) => s.isTriState);\n const closeModal = useModalGlobalStore((s) => s.closeModal);\n const closeModalWithResult = useModalGlobalStore(\n (s) => s.closeModalWithResult,\n );\n const isLoadingOpen = useModalLoadingStore((s) => s.isOpen);\n const loadingMessage = useModalLoadingStore((s) => s.message);\n const isPercentageOpen = useModalLoadingPercentageStore((s) => s.isOpen);\n const percentageMessage = useModalLoadingPercentageStore((s) => s.message);\n const percentage = useModalLoadingPercentageStore((s) => s.percentage);\n\n // Auto-confirmar el modal después del timeout especificado\n useEffect(() => {\n if (!isOpen || !payload?.autoConfirmTimeout) return;\n\n const timerId = setTimeout(() => {\n closeModal(true);\n }, payload.autoConfirmTimeout);\n\n return () => clearTimeout(timerId);\n }, [isOpen, modalId]);\n\n const contextValue = useMemo(\n () => ({ animated, disableFocus }),\n [animated, disableFocus],\n );\n\n return (\n <ModalGlobalContext.Provider value={contextValue}>\n {children}\n\n {/* Modal principal — usa ModalConfirm de la librería directamente */}\n <ModalConfirm\n isOpen={isOpen}\n onClose={() => closeModalWithResult(\"close\")}\n title={payload?.title}\n message={payload?.message}\n content={payload?.content}\n type={payload?.iconType ?? payload?.type}\n buttonMode={payload?.buttonMode}\n disabledConfirmButton={payload?.disabledConfirmButton}\n closeDisabled={payload?.closeDisabled}\n color={payload?.color}\n onConfirm={() => closeModal(true)}\n onCancel={() => closeModal(false)}\n withoutAutoClose\n textButtonConfirm={\n payload?.textButtonConfirm ?? defaultTextButtonConfirm\n }\n textButtonCancel={payload?.textButtonCancel ?? defaultTextButtonCancel}\n closeButton={payload?.closeButton ?? isTriState}\n alignJustify={payload?.alignJustify}\n alignTop={payload?.top}\n zIndexLevel={zIndexLevel}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n disableFocus={disableFocus}\n />\n\n {/* Loading */}\n <ModalLoading\n isOpen={isLoadingOpen}\n message={loadingMessage}\n zIndexLevel={zIndexLoading}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n spinner={loadingSpinner}\n />\n\n {/* Loading con porcentaje */}\n <ModalLoadingPercentage\n isOpen={isPercentageOpen}\n message={percentageMessage}\n percentage={percentage}\n zIndexLevel={zIndexLoadingPercentage}\n animated={animated}\n preventBodyScroll={preventBodyScroll}\n alignTop={loadingPercentageAlignTop}\n />\n </ModalGlobalContext.Provider>\n );\n};\n\nexport default ModalGlobalProvider;\n","import { useModalGlobalStore } from \"../store/modalGlobal/useModalGlobalStore\";\nimport { useModalLoadingStore } from \"../store/modalGlobal/useModalLoadingStore\";\nimport { useModalLoadingPercentageStore } from \"../store/modalGlobal/useModalLoadingPercentageStore\";\nimport type { ModalPayload, ModalResult } from \"../store/modalGlobal/useModalGlobalStore\";\n\n/**\n * Open the global modal. Returns a promise that resolves to `true` if the user\n * confirmed, or `false` if they cancelled/closed.\n *\n * @example\n * const confirmed = await showGlobalModal({\n * type: \"question\",\n * title: \"¿Eliminar votante?\",\n * message: \"Esta acción no se puede deshacer.\",\n * buttonMode: \"double\",\n * });\n *\n * @example — with custom JSX content\n * await showGlobalModal({\n * type: \"error\",\n * title: \"Error de sesión\",\n * content: <SesionExpiredDetails />,\n * });\n */\nexport const showGlobalModal = (payload: ModalPayload): Promise<boolean> => {\n // Close loading modals first (ModalGlobal handles its own pending promise internally)\n useModalLoadingStore.getState().closeLoading();\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalGlobalStore.getState().openModal(payload);\n};\n\n/**\n * Like `showGlobalModal` but resolves to `\"confirm\"`, `\"cancel\"`, or `\"close\"`,\n * letting you distinguish between the three ways a modal can be dismissed.\n *\n * @example\n * const result = await showGlobalModalWithClose({\n * type: \"warning\",\n * title: \"Guardar cambios\",\n * buttonMode: \"double\",\n * });\n * if (result === \"confirm\") save();\n * if (result === \"close\") navigateAway();\n */\nexport const showGlobalModalWithClose = (payload: ModalPayload): Promise<ModalResult> => {\n // Close loading modals first (ModalGlobal handles its own pending promise internally)\n useModalLoadingStore.getState().closeLoading();\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalGlobalStore.getState().openModalWithClose(payload);\n};\n\n/**\n * Programmatically close the global modal (resolves as cancelled).\n * Useful for layout/route-change handlers.\n *\n * ⚠️ Always check `isAlreadyHandled()` before calling this from a route handler\n * to avoid closing axios-controlled modals.\n */\nexport const closeGlobalModal = (): void =>\n useModalGlobalStore.getState().closeModal(false);\n\n/** Returns true if the global modal is currently open. */\nexport const isGlobalModalOpen = (): boolean =>\n useModalGlobalStore.getState().isOpen;\n\n/**\n * Returns true if the currently open modal was opened by an axios interceptor\n * (i.e. `alreadyHandled: true` was set). Use this to skip auto-close on\n * route changes.\n *\n * @example — in a Next.js layout\n * router.events.on(\"routeChangeStart\", () => {\n * if (isGlobalModalOpen() && !isAlreadyHandled()) {\n * closeGlobalModal();\n * }\n * });\n */\nexport const isAlreadyHandled = (): boolean =>\n useModalGlobalStore.getState().payload?.alreadyHandled ?? false;\n\n// ---------------------------------------------------------------------------\n// Loading helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Show the global loading modal.\n *\n * @example\n * showGlobalLoading(\"Guardando cambios...\");\n * await api.save(data);\n * closeGlobalLoading();\n */\nexport const showGlobalLoading = (message?: string): number => {\n // Close the other loading modal (safe — no pending promises)\n useModalLoadingPercentageStore.getState().closeLoadingPercentage();\n return useModalLoadingStore.getState().openLoading(message);\n};\n\n/** Close the global loading modal. If sessionId is provided, only closes if it matches. */\nexport const closeGlobalLoading = (sessionId?: number): void =>\n useModalLoadingStore.getState().closeLoading(sessionId);\n\n/** Returns true if the global loading modal is currently visible. */\nexport const isGlobalLoadingOpen = (): boolean =>\n useModalLoadingStore.getState().isOpen;\n\n// ---------------------------------------------------------------------------\n// Loading percentage helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Show the global loading modal with a percentage progress bar.\n *\n * @example\n * showGlobalLoadingPercentage(\"Subiendo archivo...\");\n * for (const chunk of chunks) {\n * await upload(chunk);\n * updateGlobalLoadingPercentage(Math.round((i / chunks.length) * 100));\n * }\n * closeGlobalLoadingPercentage();\n */\n/**\n * Abre el modal de loading con porcentaje. Retorna un sessionId para evitar\n * interferencias si se abre otro modal del mismo tipo antes de cerrar el actual.\n * Pasar el sessionId a updateGlobalLoadingPercentage y closeGlobalLoadingPercentage\n * garantiza que solo la instancia activa pueda actualizar o cerrar el modal.\n */\nexport const showGlobalLoadingPercentage = (message?: string, initialPercentage?: number): number => {\n // Close the other loading modal (safe — no pending promises)\n useModalLoadingStore.getState().closeLoading();\n return useModalLoadingPercentageStore.getState().openLoadingPercentage(message, initialPercentage);\n};\n\n/** Update the percentage value (0–100). Si se pasa sessionId y no coincide con la sesión activa, se ignora. */\nexport const updateGlobalLoadingPercentage = (percentage: number, sessionId?: number): void =>\n useModalLoadingPercentageStore.getState().updatePercentage(percentage, sessionId);\n\n/** Close the global loading percentage modal. Si se pasa sessionId y no coincide con la sesión activa, se ignora. */\nexport const closeGlobalLoadingPercentage = (sessionId?: number): void =>\n useModalLoadingPercentageStore.getState().closeLoadingPercentage(sessionId);\n\n/** Returns true if the global loading percentage modal is currently visible. */\nexport const isGlobalLoadingPercentageOpen = (): boolean =>\n useModalLoadingPercentageStore.getState().isOpen;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@votodigital-onpeui/react",
3
- "version": "0.1.56",
3
+ "version": "0.1.57",
4
4
  "description": "Librería de componentes UI para proyectos ONPE",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -52,7 +52,8 @@
52
52
  "storybook": "storybook dev -p 6006",
53
53
  "build-storybook": "storybook build",
54
54
  "prepublishOnly": "npm run build",
55
- "lint": "npx eslint src --ext .ts,.tsx"
55
+ "lint": "npx eslint src --ext .ts,.tsx",
56
+ "deploy-storybook": "npm run build-storybook && netlify deploy --prod --dir=storybook-static"
56
57
  },
57
58
  "peerDependencies": {
58
59
  "react": ">=18",