next-recomponents 2.0.33 → 2.0.34

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/dist/index.d.mts CHANGED
@@ -232,12 +232,12 @@ type PopupColor = "white" | "primary" | "secondary" | "info" | "danger" | "warni
232
232
 
233
233
  declare function usePopup(): {
234
234
  alert: (message: string, color?: PopupColor) => Promise<void>;
235
- confirm: typeof confirm;
236
- prompt: typeof prompt;
235
+ confirm: (message: string, color?: PopupColor) => Promise<boolean>;
236
+ prompt: (message: string, color?: PopupColor) => Promise<string | null>;
237
237
  modal: (message: ReactNode, color?: PopupColor, icons?: boolean, full?: boolean) => Promise<void>;
238
+ PopupComponent: () => react_jsx_runtime.JSX.Element | null;
238
239
  close: (confirmed: boolean, value?: string) => void;
239
240
  updateMessage: (message: ReactNode) => void;
240
- PopupComponent: () => react_jsx_runtime.JSX.Element | null;
241
241
  };
242
242
 
243
243
  export { Alert, Button, Container, DocumentViewer, Form, Input, Modal, MyCalendar, Pre, Select, Table, Table3, type TableButtonProps, type TableButtonProps as TableEventProps, TextArea, regularExpresions, useDates, useExcel, useFormValues, usePopup, useResources };
package/dist/index.d.ts CHANGED
@@ -232,12 +232,12 @@ type PopupColor = "white" | "primary" | "secondary" | "info" | "danger" | "warni
232
232
 
233
233
  declare function usePopup(): {
234
234
  alert: (message: string, color?: PopupColor) => Promise<void>;
235
- confirm: typeof confirm;
236
- prompt: typeof prompt;
235
+ confirm: (message: string, color?: PopupColor) => Promise<boolean>;
236
+ prompt: (message: string, color?: PopupColor) => Promise<string | null>;
237
237
  modal: (message: ReactNode, color?: PopupColor, icons?: boolean, full?: boolean) => Promise<void>;
238
+ PopupComponent: () => react_jsx_runtime.JSX.Element | null;
238
239
  close: (confirmed: boolean, value?: string) => void;
239
240
  updateMessage: (message: ReactNode) => void;
240
- PopupComponent: () => react_jsx_runtime.JSX.Element | null;
241
241
  };
242
242
 
243
243
  export { Alert, Button, Container, DocumentViewer, Form, Input, Modal, MyCalendar, Pre, Select, Table, Table3, type TableButtonProps, type TableButtonProps as TableEventProps, TextArea, regularExpresions, useDates, useExcel, useFormValues, usePopup, useResources };
package/dist/index.js CHANGED
@@ -36958,7 +36958,7 @@ var import_react10 = require("react");
36958
36958
  var import_jsx_runtime12 = require("react/jsx-runtime");
36959
36959
  function PopupActions({
36960
36960
  type,
36961
- confirm: confirm2,
36961
+ confirm,
36962
36962
  focusRing,
36963
36963
  onConfirm,
36964
36964
  onCancel
@@ -36977,7 +36977,7 @@ function PopupActions({
36977
36977
  "button",
36978
36978
  {
36979
36979
  onClick: onConfirm,
36980
- className: `px-5 py-2 rounded-lg text-sm font-semibold text-white ${confirm2} transition focus:outline-none focus:ring-2 ${focusRing}`,
36980
+ className: `px-5 py-2 rounded-lg text-sm font-semibold text-white ${confirm} transition focus:outline-none focus:ring-2 ${focusRing}`,
36981
36981
  children: "Aceptar"
36982
36982
  }
36983
36983
  )
@@ -37193,18 +37193,16 @@ var INITIAL_STATE = {
37193
37193
  inputValue: "",
37194
37194
  color: "primary",
37195
37195
  icons: true,
37196
- full: false,
37197
- message: null
37196
+ full: false
37198
37197
  };
37199
37198
  function usePopup() {
37200
37199
  const [popup, setPopup] = (0, import_react10.useState)(INITIAL_STATE);
37200
+ const messageRef = (0, import_react10.useRef)(null);
37201
37201
  const open = (0, import_react10.useCallback)(
37202
37202
  (partial) => {
37203
- setPopup({
37204
- ...partial,
37205
- visible: true,
37206
- inputValue: ""
37207
- });
37203
+ const { message, ...rest } = partial;
37204
+ messageRef.current = message;
37205
+ setPopup({ ...rest, visible: true, inputValue: "" });
37208
37206
  },
37209
37207
  []
37210
37208
  );
@@ -37213,19 +37211,9 @@ function usePopup() {
37213
37211
  var _a, _b;
37214
37212
  if (confirmed) (_a = prev.onConfirm) == null ? void 0 : _a.call(prev, value);
37215
37213
  else (_b = prev.onCancel) == null ? void 0 : _b.call(prev);
37216
- return {
37217
- ...prev,
37218
- visible: false,
37219
- inputValue: ""
37220
- };
37214
+ return { ...prev, visible: false, inputValue: "" };
37221
37215
  });
37222
37216
  }, []);
37223
- const updateMessage = (0, import_react10.useCallback)((message) => {
37224
- setPopup((prev) => ({
37225
- ...prev,
37226
- message
37227
- }));
37228
- }, []);
37229
37217
  const alert2 = (0, import_react10.useCallback)(
37230
37218
  (message, color = "primary") => new Promise(
37231
37219
  (resolve) => open({
@@ -37233,9 +37221,7 @@ function usePopup() {
37233
37221
  message,
37234
37222
  color,
37235
37223
  onConfirm: () => resolve(),
37236
- onCancel: () => resolve(),
37237
- icons: true,
37238
- full: false
37224
+ onCancel: () => resolve()
37239
37225
  })
37240
37226
  ),
37241
37227
  [open]
@@ -37246,36 +37232,61 @@ function usePopup() {
37246
37232
  type: "modal",
37247
37233
  message,
37248
37234
  color,
37249
- icons,
37250
- full,
37251
37235
  onConfirm: () => resolve(),
37252
- onCancel: () => resolve()
37236
+ onCancel: () => resolve(),
37237
+ icons,
37238
+ full
37253
37239
  })
37254
37240
  ),
37255
37241
  [open]
37256
37242
  );
37257
- const PopupComponent = () => {
37243
+ const confirm = (0, import_react10.useCallback)(
37244
+ (message, color = "primary") => new Promise(
37245
+ (resolve) => open({
37246
+ type: "confirm",
37247
+ message,
37248
+ color,
37249
+ onConfirm: () => resolve(true),
37250
+ onCancel: () => resolve(false)
37251
+ })
37252
+ ),
37253
+ [open]
37254
+ );
37255
+ const prompt = (0, import_react10.useCallback)(
37256
+ (message, color = "primary") => new Promise(
37257
+ (resolve) => open({
37258
+ type: "prompt",
37259
+ message,
37260
+ color,
37261
+ onConfirm: (value) => resolve(value != null ? value : ""),
37262
+ onCancel: () => resolve(null)
37263
+ })
37264
+ ),
37265
+ [open]
37266
+ );
37267
+ const updateMessage = (0, import_react10.useCallback)((message) => {
37268
+ messageRef.current = message;
37269
+ setPopup((prev) => ({ ...prev }));
37270
+ }, []);
37271
+ const PopupComponent = (0, import_react10.useCallback)(() => {
37258
37272
  if (!popup.visible) return null;
37259
37273
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
37260
37274
  PopupOverlay,
37261
37275
  {
37262
- popup,
37276
+ popup: { ...popup, message: messageRef.current },
37263
37277
  onClose: close,
37264
- onInputChange: (v) => setPopup((prev) => ({
37265
- ...prev,
37266
- inputValue: v
37267
- }))
37278
+ onInputChange: (v) => setPopup((prev) => ({ ...prev, inputValue: v }))
37268
37279
  }
37269
37280
  );
37270
- };
37281
+ }, [popup, close]);
37271
37282
  return {
37272
37283
  alert: alert2,
37273
37284
  confirm,
37274
37285
  prompt,
37275
37286
  modal,
37287
+ PopupComponent,
37276
37288
  close,
37277
- updateMessage,
37278
- PopupComponent
37289
+ updateMessage
37279
37290
  };
37280
37291
  }
37281
37292
 
@@ -37288,23 +37299,14 @@ function Modal({
37288
37299
  title
37289
37300
  }) {
37290
37301
  const pop = usePopup();
37291
- const hide = () => pop.close(false);
37292
- const content = (0, import_react11.useMemo)(() => {
37293
- return (0, import_react11.cloneElement)(children, {
37294
- hide,
37295
- key: crypto.randomUUID()
37296
- });
37297
- }, [children]);
37298
- (0, import_react11.useEffect)(() => {
37299
- pop.updateMessage(content);
37300
- }, [content]);
37302
+ const hide = (0, import_react11.useCallback)(() => pop.close(false), [pop.close]);
37301
37303
  const props = button == null ? void 0 : button.props;
37302
- const originalOnClick = props == null ? void 0 : props.onClick;
37304
+ const onClick = props == null ? void 0 : props.onClick;
37303
37305
  return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
37304
37306
  (0, import_react11.cloneElement)(button, {
37305
- onClick: async (e) => {
37306
- originalOnClick == null ? void 0 : originalOnClick(e);
37307
- await pop.modal(content, color, false, true);
37307
+ onClick: (e) => {
37308
+ onClick == null ? void 0 : onClick(e);
37309
+ pop.modal((0, import_react11.cloneElement)(children, { hide }), color, false, true);
37308
37310
  }
37309
37311
  }),
37310
37312
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(pop.PopupComponent, {})
package/dist/index.mjs CHANGED
@@ -36935,16 +36935,16 @@ function Select({
36935
36935
  }
36936
36936
 
36937
36937
  // src/modal/index.tsx
36938
- import { cloneElement as cloneElement2, useEffect as useEffect6, useMemo as useMemo4 } from "react";
36938
+ import { cloneElement as cloneElement2, useCallback as useCallback2 } from "react";
36939
36939
 
36940
36940
  // src/pop/index.tsx
36941
- import { useState as useState9, useCallback } from "react";
36941
+ import { useState as useState9, useCallback, useRef as useRef3 } from "react";
36942
36942
 
36943
36943
  // src/pop/actions.tsx
36944
36944
  import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
36945
36945
  function PopupActions({
36946
36946
  type,
36947
- confirm: confirm2,
36947
+ confirm,
36948
36948
  focusRing,
36949
36949
  onConfirm,
36950
36950
  onCancel
@@ -36963,7 +36963,7 @@ function PopupActions({
36963
36963
  "button",
36964
36964
  {
36965
36965
  onClick: onConfirm,
36966
- className: `px-5 py-2 rounded-lg text-sm font-semibold text-white ${confirm2} transition focus:outline-none focus:ring-2 ${focusRing}`,
36966
+ className: `px-5 py-2 rounded-lg text-sm font-semibold text-white ${confirm} transition focus:outline-none focus:ring-2 ${focusRing}`,
36967
36967
  children: "Aceptar"
36968
36968
  }
36969
36969
  )
@@ -37179,18 +37179,16 @@ var INITIAL_STATE = {
37179
37179
  inputValue: "",
37180
37180
  color: "primary",
37181
37181
  icons: true,
37182
- full: false,
37183
- message: null
37182
+ full: false
37184
37183
  };
37185
37184
  function usePopup() {
37186
37185
  const [popup, setPopup] = useState9(INITIAL_STATE);
37186
+ const messageRef = useRef3(null);
37187
37187
  const open = useCallback(
37188
37188
  (partial) => {
37189
- setPopup({
37190
- ...partial,
37191
- visible: true,
37192
- inputValue: ""
37193
- });
37189
+ const { message, ...rest } = partial;
37190
+ messageRef.current = message;
37191
+ setPopup({ ...rest, visible: true, inputValue: "" });
37194
37192
  },
37195
37193
  []
37196
37194
  );
@@ -37199,19 +37197,9 @@ function usePopup() {
37199
37197
  var _a, _b;
37200
37198
  if (confirmed) (_a = prev.onConfirm) == null ? void 0 : _a.call(prev, value);
37201
37199
  else (_b = prev.onCancel) == null ? void 0 : _b.call(prev);
37202
- return {
37203
- ...prev,
37204
- visible: false,
37205
- inputValue: ""
37206
- };
37200
+ return { ...prev, visible: false, inputValue: "" };
37207
37201
  });
37208
37202
  }, []);
37209
- const updateMessage = useCallback((message) => {
37210
- setPopup((prev) => ({
37211
- ...prev,
37212
- message
37213
- }));
37214
- }, []);
37215
37203
  const alert2 = useCallback(
37216
37204
  (message, color = "primary") => new Promise(
37217
37205
  (resolve) => open({
@@ -37219,9 +37207,7 @@ function usePopup() {
37219
37207
  message,
37220
37208
  color,
37221
37209
  onConfirm: () => resolve(),
37222
- onCancel: () => resolve(),
37223
- icons: true,
37224
- full: false
37210
+ onCancel: () => resolve()
37225
37211
  })
37226
37212
  ),
37227
37213
  [open]
@@ -37232,36 +37218,61 @@ function usePopup() {
37232
37218
  type: "modal",
37233
37219
  message,
37234
37220
  color,
37235
- icons,
37236
- full,
37237
37221
  onConfirm: () => resolve(),
37238
- onCancel: () => resolve()
37222
+ onCancel: () => resolve(),
37223
+ icons,
37224
+ full
37225
+ })
37226
+ ),
37227
+ [open]
37228
+ );
37229
+ const confirm = useCallback(
37230
+ (message, color = "primary") => new Promise(
37231
+ (resolve) => open({
37232
+ type: "confirm",
37233
+ message,
37234
+ color,
37235
+ onConfirm: () => resolve(true),
37236
+ onCancel: () => resolve(false)
37237
+ })
37238
+ ),
37239
+ [open]
37240
+ );
37241
+ const prompt = useCallback(
37242
+ (message, color = "primary") => new Promise(
37243
+ (resolve) => open({
37244
+ type: "prompt",
37245
+ message,
37246
+ color,
37247
+ onConfirm: (value) => resolve(value != null ? value : ""),
37248
+ onCancel: () => resolve(null)
37239
37249
  })
37240
37250
  ),
37241
37251
  [open]
37242
37252
  );
37243
- const PopupComponent = () => {
37253
+ const updateMessage = useCallback((message) => {
37254
+ messageRef.current = message;
37255
+ setPopup((prev) => ({ ...prev }));
37256
+ }, []);
37257
+ const PopupComponent = useCallback(() => {
37244
37258
  if (!popup.visible) return null;
37245
37259
  return /* @__PURE__ */ jsx15(
37246
37260
  PopupOverlay,
37247
37261
  {
37248
- popup,
37262
+ popup: { ...popup, message: messageRef.current },
37249
37263
  onClose: close,
37250
- onInputChange: (v) => setPopup((prev) => ({
37251
- ...prev,
37252
- inputValue: v
37253
- }))
37264
+ onInputChange: (v) => setPopup((prev) => ({ ...prev, inputValue: v }))
37254
37265
  }
37255
37266
  );
37256
- };
37267
+ }, [popup, close]);
37257
37268
  return {
37258
37269
  alert: alert2,
37259
37270
  confirm,
37260
37271
  prompt,
37261
37272
  modal,
37273
+ PopupComponent,
37262
37274
  close,
37263
- updateMessage,
37264
- PopupComponent
37275
+ updateMessage
37265
37276
  };
37266
37277
  }
37267
37278
 
@@ -37274,23 +37285,14 @@ function Modal({
37274
37285
  title
37275
37286
  }) {
37276
37287
  const pop = usePopup();
37277
- const hide = () => pop.close(false);
37278
- const content = useMemo4(() => {
37279
- return cloneElement2(children, {
37280
- hide,
37281
- key: crypto.randomUUID()
37282
- });
37283
- }, [children]);
37284
- useEffect6(() => {
37285
- pop.updateMessage(content);
37286
- }, [content]);
37288
+ const hide = useCallback2(() => pop.close(false), [pop.close]);
37287
37289
  const props = button == null ? void 0 : button.props;
37288
- const originalOnClick = props == null ? void 0 : props.onClick;
37290
+ const onClick = props == null ? void 0 : props.onClick;
37289
37291
  return /* @__PURE__ */ jsxs10(Fragment2, { children: [
37290
37292
  cloneElement2(button, {
37291
- onClick: async (e) => {
37292
- originalOnClick == null ? void 0 : originalOnClick(e);
37293
- await pop.modal(content, color, false, true);
37293
+ onClick: (e) => {
37294
+ onClick == null ? void 0 : onClick(e);
37295
+ pop.modal(cloneElement2(children, { hide }), color, false, true);
37294
37296
  }
37295
37297
  }),
37296
37298
  /* @__PURE__ */ jsx16(pop.PopupComponent, {})
@@ -37539,15 +37541,15 @@ function DocumentViewer({ item }) {
37539
37541
 
37540
37542
  // src/table3/index.tsx
37541
37543
  import React9, {
37542
- useEffect as useEffect9,
37543
- useMemo as useMemo7,
37544
+ useEffect as useEffect8,
37545
+ useMemo as useMemo6,
37544
37546
  useReducer as useReducer2,
37545
- useRef as useRef4,
37547
+ useRef as useRef5,
37546
37548
  useState as useState13
37547
37549
  } from "react";
37548
37550
 
37549
37551
  // src/table3/filter.tsx
37550
- import { useEffect as useEffect8, useMemo as useMemo5, useState as useState11 } from "react";
37552
+ import { useEffect as useEffect7, useMemo as useMemo4, useState as useState11 } from "react";
37551
37553
 
37552
37554
  // src/table3/filters.tsx
37553
37555
  import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
@@ -37659,12 +37661,12 @@ function Filter({
37659
37661
  }) {
37660
37662
  const [visible, setVisible] = useState11(false);
37661
37663
  const [text, setText] = useState11("");
37662
- const items = useMemo5(
37664
+ const items = useMemo4(
37663
37665
  () => [...new Set(Object.values(objectData).map((o) => o[h]))],
37664
37666
  [objectData]
37665
37667
  );
37666
37668
  const [selected, setSelected] = useState11(items);
37667
- const itemsFiltered = useMemo5(
37669
+ const itemsFiltered = useMemo4(
37668
37670
  () => items.sort((a, b) => `${a}`.localeCompare(b)).filter((item) => {
37669
37671
  if (!text) return true;
37670
37672
  return `${item}`.toLowerCase().includes(text.toLowerCase());
@@ -37701,7 +37703,7 @@ function Filter({
37701
37703
  const hidden = Object.values(objectData).filter(
37702
37704
  (d) => d._visible === false
37703
37705
  );
37704
- useEffect8(() => {
37706
+ useEffect7(() => {
37705
37707
  if (data.length != Object.values(objectData).map((o) => (o == null ? void 0 : o._id) || (o == null ? void 0 : o.id)).length) {
37706
37708
  const news = [...new Set(data.map((o) => o[h]))];
37707
37709
  setSelected(news);
@@ -38273,7 +38275,7 @@ function TableFooter({
38273
38275
  }
38274
38276
 
38275
38277
  // src/table3/dialog.tsx
38276
- import React8, { useMemo as useMemo6 } from "react";
38278
+ import React8, { useMemo as useMemo5 } from "react";
38277
38279
  import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
38278
38280
  function Dialog3({
38279
38281
  modalRef,
@@ -38290,7 +38292,7 @@ function Dialog3({
38290
38292
  var _a;
38291
38293
  return (_a = modalRef.current) == null ? void 0 : _a.close();
38292
38294
  };
38293
- const clonedModal = useMemo6(() => {
38295
+ const clonedModal = useMemo5(() => {
38294
38296
  if (dialogRow && React8.isValidElement(children)) {
38295
38297
  return React8.cloneElement(children, {
38296
38298
  key: JSON.stringify(dialogRow),
@@ -38389,11 +38391,11 @@ function Table3({
38389
38391
  }
38390
38392
  }
38391
38393
  const [objectData, setObjectData] = useReducer2(dataReducer, null);
38392
- useEffect9(() => {
38394
+ useEffect8(() => {
38393
38395
  setObjectData(data);
38394
38396
  setPage(1);
38395
38397
  }, [data]);
38396
- const headers = useMemo7(() => {
38398
+ const headers = useMemo6(() => {
38397
38399
  if (!objectData) return [];
38398
38400
  return [
38399
38401
  ...new Set(
@@ -38401,12 +38403,12 @@ function Table3({
38401
38403
  )
38402
38404
  ];
38403
38405
  }, [objectData]);
38404
- const totalPages = useMemo7(() => {
38406
+ const totalPages = useMemo6(() => {
38405
38407
  if (!objectData) return 0;
38406
38408
  return maxItems ? Math.ceil(Object.keys(objectData).length / maxItems) : 1;
38407
38409
  }, [objectData, maxItems]);
38408
38410
  const [sort, setSort] = useState13(sortBy);
38409
- const modalRef = useRef4(null);
38411
+ const modalRef = useRef5(null);
38410
38412
  const [dialogRow, setDialogRow] = useState13({});
38411
38413
  const context = {
38412
38414
  objectData,
@@ -38434,7 +38436,7 @@ function Table3({
38434
38436
  setSort,
38435
38437
  ...props
38436
38438
  };
38437
- useEffect9(() => {
38439
+ useEffect8(() => {
38438
38440
  if ((dialogRow == null ? void 0 : dialogRow.id) || (dialogRow == null ? void 0 : dialogRow._id)) {
38439
38441
  const newDialogRow = objectData[dialogRow == null ? void 0 : dialogRow.id] || objectData[dialogRow == null ? void 0 : dialogRow._id];
38440
38442
  setDialogRow(newDialogRow);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-recomponents",
3
- "version": "2.0.33",
3
+ "version": "2.0.34",
4
4
  "description": "description nueva",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,7 +1,5 @@
1
1
  "use client";
2
-
3
- import React, { ReactElement, cloneElement, useEffect, useMemo } from "react";
4
-
2
+ import React, { ReactElement, cloneElement, useCallback } from "react";
5
3
  import usePopup from "../pop";
6
4
 
7
5
  export type PopupColor =
@@ -28,34 +26,22 @@ export default function Modal({
28
26
  }) {
29
27
  const pop = usePopup();
30
28
 
31
- const hide = () => pop.close(false);
32
-
33
- // key dinámica para forzar remount cuando cambie el children
34
- const content = useMemo(() => {
35
- return cloneElement(children, {
36
- hide,
37
- key: crypto.randomUUID(),
38
- });
39
- }, [children]);
40
-
41
- // actualizar SOLO si el modal está abierto
42
- useEffect(() => {
43
- pop.updateMessage(content);
44
- }, [content]);
29
+ const hide = useCallback(() => pop.close(false), [pop.close]);
45
30
 
46
31
  const props = button?.props;
47
- const originalOnClick = props?.onClick;
32
+ const onClick = props?.onClick;
48
33
 
49
34
  return (
50
35
  <>
51
36
  {cloneElement(button, {
52
- onClick: async (e) => {
53
- originalOnClick?.(e as any);
54
-
55
- await pop.modal(content, color, false, true);
37
+ onClick: (e) => {
38
+ onClick?.(e as any);
39
+ // En la apertura pasamos children con hide
40
+ pop.modal(cloneElement(children, { hide }), color, false, true);
56
41
  },
57
42
  })}
58
43
 
44
+ {/* ✅ Componente, no elemento JSX */}
59
45
  <pop.PopupComponent />
60
46
  </>
61
47
  );
package/src/pop/index.tsx CHANGED
@@ -1,53 +1,36 @@
1
+ // usePopup.ts - Solución definitiva
1
2
  "use client";
2
-
3
- import { useState, useCallback, type ReactNode } from "react";
3
+ import { useState, useCallback, useRef, type ReactNode } from "react";
4
4
  import { PopupColor, PopupState } from "./types";
5
5
  import { PopupOverlay } from "./overlay";
6
-
7
- const INITIAL_STATE: PopupState = {
6
+ type PopupStateWithoutMessage = Omit<PopupState, "message">;
7
+ const INITIAL_STATE: PopupStateWithoutMessage = {
8
8
  type: "alert",
9
9
  visible: false,
10
10
  inputValue: "",
11
11
  color: "primary",
12
12
  icons: true,
13
13
  full: false,
14
- message: null,
15
14
  };
16
-
17
15
  export default function usePopup() {
18
- const [popup, setPopup] = useState<PopupState>(INITIAL_STATE);
19
-
16
+ const [popup, setPopup] = useState<PopupStateWithoutMessage>(INITIAL_STATE);
17
+ // El message vive FUERA del estado para no quedar congelado
18
+ const messageRef = useRef<ReactNode>(null);
20
19
  const open = useCallback(
21
20
  (partial: Omit<PopupState, "visible" | "inputValue">) => {
22
- setPopup({
23
- ...partial,
24
- visible: true,
25
- inputValue: "",
26
- });
21
+ const { message, ...rest } = partial;
22
+ messageRef.current = message as any;
23
+ setPopup({ ...rest, visible: true, inputValue: "" });
27
24
  },
28
25
  [],
29
26
  );
30
-
31
27
  const close = useCallback((confirmed: boolean, value?: string) => {
32
28
  setPopup((prev) => {
33
29
  if (confirmed) prev.onConfirm?.(value);
34
30
  else prev.onCancel?.();
35
-
36
- return {
37
- ...prev,
38
- visible: false,
39
- inputValue: "",
40
- };
31
+ return { ...prev, visible: false, inputValue: "" };
41
32
  });
42
33
  }, []);
43
-
44
- const updateMessage = useCallback((message: ReactNode) => {
45
- setPopup((prev) => ({
46
- ...prev,
47
- message,
48
- }));
49
- }, []);
50
-
51
34
  const alert = useCallback(
52
35
  (message: string, color: PopupColor = "primary"): Promise<void> =>
53
36
  new Promise((resolve) =>
@@ -57,58 +40,80 @@ export default function usePopup() {
57
40
  color,
58
41
  onConfirm: () => resolve(),
59
42
  onCancel: () => resolve(),
60
- icons: true,
61
- full: false,
62
43
  }),
63
44
  ),
64
45
  [open],
65
46
  );
66
-
67
47
  const modal = useCallback(
68
48
  (
69
49
  message: ReactNode,
70
50
  color: PopupColor = "primary",
71
- icons = false,
72
- full = false,
51
+ icons: boolean = false,
52
+ full: boolean = false,
73
53
  ): Promise<void> =>
74
54
  new Promise((resolve) =>
75
55
  open({
76
56
  type: "modal",
77
57
  message,
78
58
  color,
79
- icons,
80
- full,
81
59
  onConfirm: () => resolve(),
82
60
  onCancel: () => resolve(),
61
+ icons,
62
+ full,
63
+ }),
64
+ ),
65
+ [open],
66
+ );
67
+ const confirm = useCallback(
68
+ (message: string, color: PopupColor = "primary"): Promise<boolean> =>
69
+ new Promise((resolve) =>
70
+ open({
71
+ type: "confirm",
72
+ message,
73
+ color,
74
+ onConfirm: () => resolve(true),
75
+ onCancel: () => resolve(false),
83
76
  }),
84
77
  ),
85
78
  [open],
86
79
  );
87
-
88
- const PopupComponent = () => {
80
+ const prompt = useCallback(
81
+ (message: string, color: PopupColor = "primary"): Promise<string | null> =>
82
+ new Promise((resolve) =>
83
+ open({
84
+ type: "prompt",
85
+ message,
86
+ color,
87
+ onConfirm: (value) => resolve(value ?? ""),
88
+ onCancel: () => resolve(null),
89
+ }),
90
+ ),
91
+ [open],
92
+ );
93
+ // ✅ Actualiza la ref en cada render cuando el modal está abierto
94
+ // Esto permite que cambios en el children del padre se reflejen
95
+ const updateMessage = useCallback((message: ReactNode) => {
96
+ messageRef.current = message;
97
+ // Fuerza re-render del PopupComponent
98
+ setPopup((prev) => ({ ...prev }));
99
+ }, []);
100
+ const PopupComponent = useCallback(() => {
89
101
  if (!popup.visible) return null;
90
-
91
102
  return (
92
103
  <PopupOverlay
93
- popup={popup}
104
+ popup={{ ...popup, message: messageRef.current }}
94
105
  onClose={close}
95
- onInputChange={(v) =>
96
- setPopup((prev) => ({
97
- ...prev,
98
- inputValue: v,
99
- }))
100
- }
106
+ onInputChange={(v) => setPopup((prev) => ({ ...prev, inputValue: v }))}
101
107
  />
102
108
  );
103
- };
104
-
109
+ }, [popup, close]); // messageRef no necesita estar aquí, es mutable
105
110
  return {
106
111
  alert,
107
112
  confirm,
108
113
  prompt,
109
114
  modal,
115
+ PopupComponent,
110
116
  close,
111
117
  updateMessage,
112
- PopupComponent,
113
118
  };
114
119
  }