next-recomponents 2.0.31 → 2.0.33

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-recomponents",
3
- "version": "2.0.31",
3
+ "version": "2.0.33",
4
4
  "description": "description nueva",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,5 +1,7 @@
1
- // Modal.tsx
2
- import React, { ReactElement, cloneElement, useEffect } from "react";
1
+ "use client";
2
+
3
+ import React, { ReactElement, cloneElement, useEffect, useMemo } from "react";
4
+
3
5
  import usePopup from "../pop";
4
6
 
5
7
  export type PopupColor =
@@ -25,27 +27,36 @@ export default function Modal({
25
27
  title?: string;
26
28
  }) {
27
29
  const pop = usePopup();
30
+
28
31
  const hide = () => pop.close(false);
29
32
 
30
- // Inyectamos hide en children
31
- const childrenWithHide = cloneElement(children, { hide });
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]);
32
40
 
41
+ // actualizar SOLO si el modal está abierto
33
42
  useEffect(() => {
34
- pop.updateMessage(childrenWithHide);
35
- }, [children]); // children como dep para detectar cambios del padre
43
+ pop.updateMessage(content);
44
+ }, [content]);
36
45
 
37
46
  const props = button?.props;
38
- const onClick = props?.onClick;
47
+ const originalOnClick = props?.onClick;
39
48
 
40
49
  return (
41
50
  <>
42
51
  {cloneElement(button, {
43
- onClick: (e) => {
44
- onClick?.(e as any);
45
- pop.modal(childrenWithHide, color, false, true);
52
+ onClick: async (e) => {
53
+ originalOnClick?.(e as any);
54
+
55
+ await pop.modal(content, color, false, true);
46
56
  },
47
57
  })}
48
- {pop.PopupComponent}
58
+
59
+ <pop.PopupComponent />
49
60
  </>
50
61
  );
51
62
  }
package/src/pop/index.tsx CHANGED
@@ -1,31 +1,29 @@
1
- // usePopup.ts - Solución definitiva
2
1
  "use client";
3
2
 
4
- import { useState, useCallback, useRef, type ReactNode } from "react";
3
+ import { useState, useCallback, type ReactNode } from "react";
5
4
  import { PopupColor, PopupState } from "./types";
6
5
  import { PopupOverlay } from "./overlay";
7
6
 
8
- type PopupStateWithoutMessage = Omit<PopupState, "message">;
9
-
10
- const INITIAL_STATE: PopupStateWithoutMessage = {
7
+ const INITIAL_STATE: PopupState = {
11
8
  type: "alert",
12
9
  visible: false,
13
10
  inputValue: "",
14
11
  color: "primary",
15
12
  icons: true,
16
13
  full: false,
14
+ message: null,
17
15
  };
18
16
 
19
17
  export default function usePopup() {
20
- const [popup, setPopup] = useState<PopupStateWithoutMessage>(INITIAL_STATE);
21
- // El message vive FUERA del estado para no quedar congelado
22
- const messageRef = useRef<ReactNode>(null);
18
+ const [popup, setPopup] = useState<PopupState>(INITIAL_STATE);
23
19
 
24
20
  const open = useCallback(
25
21
  (partial: Omit<PopupState, "visible" | "inputValue">) => {
26
- const { message, ...rest } = partial;
27
- messageRef.current = message as any;
28
- setPopup({ ...rest, visible: true, inputValue: "" });
22
+ setPopup({
23
+ ...partial,
24
+ visible: true,
25
+ inputValue: "",
26
+ });
29
27
  },
30
28
  [],
31
29
  );
@@ -34,10 +32,22 @@ export default function usePopup() {
34
32
  setPopup((prev) => {
35
33
  if (confirmed) prev.onConfirm?.(value);
36
34
  else prev.onCancel?.();
37
- return { ...prev, visible: false, inputValue: "" };
35
+
36
+ return {
37
+ ...prev,
38
+ visible: false,
39
+ inputValue: "",
40
+ };
38
41
  });
39
42
  }, []);
40
43
 
44
+ const updateMessage = useCallback((message: ReactNode) => {
45
+ setPopup((prev) => ({
46
+ ...prev,
47
+ message,
48
+ }));
49
+ }, []);
50
+
41
51
  const alert = useCallback(
42
52
  (message: string, color: PopupColor = "primary"): Promise<void> =>
43
53
  new Promise((resolve) =>
@@ -47,6 +57,8 @@ export default function usePopup() {
47
57
  color,
48
58
  onConfirm: () => resolve(),
49
59
  onCancel: () => resolve(),
60
+ icons: true,
61
+ full: false,
50
62
  }),
51
63
  ),
52
64
  [open],
@@ -56,74 +68,47 @@ export default function usePopup() {
56
68
  (
57
69
  message: ReactNode,
58
70
  color: PopupColor = "primary",
59
- icons: boolean = false,
60
- full: boolean = false,
71
+ icons = false,
72
+ full = false,
61
73
  ): Promise<void> =>
62
74
  new Promise((resolve) =>
63
75
  open({
64
76
  type: "modal",
65
77
  message,
66
78
  color,
67
- onConfirm: () => resolve(),
68
- onCancel: () => resolve(),
69
79
  icons,
70
80
  full,
81
+ onConfirm: () => resolve(),
82
+ onCancel: () => resolve(),
71
83
  }),
72
84
  ),
73
85
  [open],
74
86
  );
75
87
 
76
- const confirm = useCallback(
77
- (message: string, color: PopupColor = "primary"): Promise<boolean> =>
78
- new Promise((resolve) =>
79
- open({
80
- type: "confirm",
81
- message,
82
- color,
83
- onConfirm: () => resolve(true),
84
- onCancel: () => resolve(false),
85
- }),
86
- ),
87
- [open],
88
- );
89
-
90
- const prompt = useCallback(
91
- (message: string, color: PopupColor = "primary"): Promise<string | null> =>
92
- new Promise((resolve) =>
93
- open({
94
- type: "prompt",
95
- message,
96
- color,
97
- onConfirm: (value) => resolve(value ?? ""),
98
- onCancel: () => resolve(null),
99
- }),
100
- ),
101
- [open],
102
- );
103
-
104
- // ✅ Actualiza la ref en cada render cuando el modal está abierto
105
- // Esto permite que cambios en el children del padre se reflejen
106
- const updateMessage = useCallback((message: ReactNode) => {
107
- messageRef.current = message;
108
- // Fuerza re-render del PopupComponent
109
- setPopup((prev) => ({ ...prev }));
110
- }, []);
88
+ const PopupComponent = () => {
89
+ if (!popup.visible) return null;
111
90
 
112
- const PopupComponent = popup.visible ? (
113
- <PopupOverlay
114
- popup={{ ...popup, message: messageRef.current }}
115
- onClose={close}
116
- onInputChange={(v) => setPopup((prev) => ({ ...prev, inputValue: v }))}
117
- />
118
- ) : null;
91
+ return (
92
+ <PopupOverlay
93
+ popup={popup}
94
+ onClose={close}
95
+ onInputChange={(v) =>
96
+ setPopup((prev) => ({
97
+ ...prev,
98
+ inputValue: v,
99
+ }))
100
+ }
101
+ />
102
+ );
103
+ };
119
104
 
120
105
  return {
121
106
  alert,
122
107
  confirm,
123
108
  prompt,
124
109
  modal,
125
- PopupComponent,
126
110
  close,
127
111
  updateMessage,
112
+ PopupComponent,
128
113
  };
129
114
  }
@@ -222,6 +222,7 @@ function ModalDialog({
222
222
  React.cloneElement(
223
223
  modal as React.ReactElement,
224
224
  {
225
+ key: selectedRow.id,
225
226
  row: selectedRow,
226
227
  hide: onClose,
227
228
  } as any,