next-recomponents 2.0.3 → 2.0.5

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.3",
3
+ "version": "2.0.5",
4
4
  "description": "description nueva",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,149 +1,27 @@
1
- "use client";
2
- import { useState } from "react";
3
-
4
- function usePopup() {
5
- const [popup, setPopup] = useState<{
6
- type: "alert" | "confirm" | "prompt";
7
- message: string;
8
- visible: boolean;
9
- inputValue: string;
10
- onConfirm?: (value?: string) => void;
11
- onCancel?: () => void;
12
- }>({ type: "alert", message: "", visible: false, inputValue: "" });
13
-
14
- function alert(message: string): Promise<void> {
15
- return new Promise((resolve) => {
16
- setPopup({
17
- type: "alert",
18
- message,
19
- visible: true,
20
- inputValue: "",
21
- onConfirm: () => resolve(),
22
- });
23
- });
24
- }
25
-
26
- function confirm(message: string): Promise<boolean> {
27
- return new Promise((resolve) => {
28
- setPopup({
29
- type: "confirm",
30
- message,
31
- visible: true,
32
- inputValue: "",
33
- onConfirm: () => resolve(true),
34
- onCancel: () => resolve(false),
35
- });
36
- });
37
- }
38
-
39
- function prompt(message: string): Promise<string | null> {
40
- return new Promise((resolve) => {
41
- setPopup({
42
- type: "prompt",
43
- message,
44
- visible: true,
45
- inputValue: "",
46
- onConfirm: (value) => resolve(value ?? ""),
47
- onCancel: () => resolve(null),
48
- });
49
- });
50
- }
51
-
52
- function close(confirmed: boolean, value?: string) {
53
- setPopup((prev) => {
54
- if (confirmed) prev.onConfirm?.(value);
55
- else prev.onCancel?.();
56
- return { ...prev, visible: false, inputValue: "" };
57
- });
58
- }
59
-
60
- const PopupComponent = popup.visible ? (
1
+ import { catColor } from "../button/colors";
2
+
3
+ interface Props extends React.HTMLAttributes<HTMLDivElement> {
4
+ color?:
5
+ | "white"
6
+ | "primary"
7
+ | "secondary"
8
+ | "info"
9
+ | "danger"
10
+ | "warning"
11
+ | "success";
12
+ children: React.ReactNode;
13
+ }
14
+ export default function Alert({
15
+ color = "primary",
16
+ children,
17
+ ...props
18
+ }: Props) {
19
+ return (
61
20
  <div
62
- style={{
63
- position: "fixed",
64
- top: 0,
65
- left: 0,
66
- width: "100%",
67
- height: "100%",
68
- background: "rgba(0,0,0,0.5)",
69
- display: "flex",
70
- alignItems: "center",
71
- justifyContent: "center",
72
- zIndex: 1000,
73
- }}
21
+ className={[catColor[color], "p-2 rounded shadow border"].join(" ")}
22
+ {...props}
74
23
  >
75
- <div
76
- style={{
77
- background: "#fff",
78
- padding: "24px 32px",
79
- borderRadius: "8px",
80
- minWidth: "300px",
81
- textAlign: "center",
82
- boxShadow: "0 4px 20px rgba(0,0,0,0.2)",
83
- }}
84
- >
85
- <p style={{ margin: "0 0 16px", fontSize: "16px" }}>{popup.message}</p>
86
-
87
- {popup.type === "prompt" && (
88
- <input
89
- autoFocus
90
- type="text"
91
- value={popup.inputValue}
92
- onChange={(e) =>
93
- setPopup((prev) => ({ ...prev, inputValue: e.target.value }))
94
- }
95
- onKeyDown={(e) =>
96
- e.key === "Enter" && close(true, popup.inputValue)
97
- }
98
- style={{
99
- width: "100%",
100
- padding: "8px 12px",
101
- marginBottom: "16px",
102
- border: "1px solid #d1d5db",
103
- borderRadius: "6px",
104
- fontSize: "14px",
105
- boxSizing: "border-box",
106
- }}
107
- />
108
- )}
109
-
110
- <div style={{ display: "flex", gap: "8px", justifyContent: "center" }}>
111
- {(popup.type === "confirm" || popup.type === "prompt") && (
112
- <button
113
- onClick={() => close(false)}
114
- style={{
115
- padding: "8px 24px",
116
- background: "#e5e7eb",
117
- color: "#374151",
118
- border: "none",
119
- borderRadius: "6px",
120
- cursor: "pointer",
121
- fontSize: "14px",
122
- }}
123
- >
124
- Cancelar
125
- </button>
126
- )}
127
- <button
128
- onClick={() => close(true, popup.inputValue)}
129
- style={{
130
- padding: "8px 24px",
131
- background: "#3b82f6",
132
- color: "#fff",
133
- border: "none",
134
- borderRadius: "6px",
135
- cursor: "pointer",
136
- fontSize: "14px",
137
- }}
138
- >
139
- OK
140
- </button>
141
- </div>
142
- </div>
24
+ {children}
143
25
  </div>
144
- ) : null;
145
-
146
- return { alert, confirm, prompt, PopupComponent };
26
+ );
147
27
  }
148
-
149
- export default usePopup;
package/src/index.tsx CHANGED
@@ -1,3 +1,4 @@
1
+ export { default as Alert } from "./alert";
1
2
  export { default as Button } from "./button";
2
3
  export { default as Container } from "./container";
3
4
  export { default as Form } from "./form";
@@ -17,4 +18,4 @@ export { default as MyCalendar } from "./calendar";
17
18
  export { useFormValues } from "./form";
18
19
  export { default as DocumentViewer } from "./doc-viewer";
19
20
  export { default as Table3 } from "./table3";
20
- export { default as usePopup } from "./alert";
21
+ export { default as usePopup } from "./pop";
@@ -0,0 +1,253 @@
1
+ "use client";
2
+ import { useState } from "react";
3
+
4
+ type Color =
5
+ | "white"
6
+ | "primary"
7
+ | "secondary"
8
+ | "info"
9
+ | "danger"
10
+ | "warning"
11
+ | "success";
12
+
13
+ // ─── Color tokens ─────────────────────────────────────────────────────────────
14
+
15
+ const COLOR_CONFIG: Record<
16
+ Color,
17
+ {
18
+ bg: string;
19
+ iconBg: string;
20
+ iconText: string;
21
+ border: string;
22
+ confirm: string;
23
+ label: string;
24
+ }
25
+ > = {
26
+ primary: {
27
+ bg: "from-blue-50 to-indigo-50",
28
+ iconBg: "bg-blue-100",
29
+ iconText: "text-blue-600",
30
+ border: "border-blue-200",
31
+ confirm: "bg-blue-600 hover:bg-blue-700 focus:ring-blue-300",
32
+ label: "ℹ",
33
+ },
34
+ info: {
35
+ bg: "from-sky-50 to-cyan-50",
36
+ iconBg: "bg-sky-100",
37
+ iconText: "text-sky-600",
38
+ border: "border-sky-200",
39
+ confirm: "bg-sky-600 hover:bg-sky-700 focus:ring-sky-300",
40
+ label: "ℹ",
41
+ },
42
+ success: {
43
+ bg: "from-emerald-50 to-green-50",
44
+ iconBg: "bg-emerald-100",
45
+ iconText: "text-emerald-600",
46
+ border: "border-emerald-200",
47
+ confirm: "bg-emerald-600 hover:bg-emerald-700 focus:ring-emerald-300",
48
+ label: "✓",
49
+ },
50
+ warning: {
51
+ bg: "from-amber-50 to-yellow-50",
52
+ iconBg: "bg-amber-100",
53
+ iconText: "text-amber-600",
54
+ border: "border-amber-200",
55
+ confirm: "bg-amber-500 hover:bg-amber-600 focus:ring-amber-300",
56
+ label: "⚠",
57
+ },
58
+ danger: {
59
+ bg: "from-red-50 to-rose-50",
60
+ iconBg: "bg-red-100",
61
+ iconText: "text-red-600",
62
+ border: "border-red-200",
63
+ confirm: "bg-red-600 hover:bg-red-700 focus:ring-red-300",
64
+ label: "✕",
65
+ },
66
+ secondary: {
67
+ bg: "from-slate-50 to-gray-50",
68
+ iconBg: "bg-slate-100",
69
+ iconText: "text-slate-600",
70
+ border: "border-slate-200",
71
+ confirm: "bg-slate-700 hover:bg-slate-800 focus:ring-slate-300",
72
+ label: "◎",
73
+ },
74
+ white: {
75
+ bg: "from-gray-50 to-white",
76
+ iconBg: "bg-gray-100",
77
+ iconText: "text-gray-500",
78
+ border: "border-gray-200",
79
+ confirm: "bg-gray-700 hover:bg-gray-800 focus:ring-gray-300",
80
+ label: "◎",
81
+ },
82
+ };
83
+
84
+ // ─── Types ────────────────────────────────────────────────────────────────────
85
+
86
+ interface PopupState {
87
+ type: "alert" | "confirm" | "prompt";
88
+ message: string;
89
+ visible: boolean;
90
+ inputValue: string;
91
+ onConfirm?: (value?: string) => void;
92
+ onCancel?: () => void;
93
+ color: Color;
94
+ }
95
+
96
+ // ─── Hook ─────────────────────────────────────────────────────────────────────
97
+
98
+ export default function usePopup() {
99
+ const [popup, setPopup] = useState<PopupState>({
100
+ type: "alert",
101
+ message: "",
102
+ visible: false,
103
+ inputValue: "",
104
+ color: "primary",
105
+ });
106
+
107
+ function alert(message: string, color: Color = "primary"): Promise<void> {
108
+ return new Promise((resolve) => {
109
+ setPopup({
110
+ type: "alert",
111
+ message,
112
+ visible: true,
113
+ inputValue: "",
114
+ onConfirm: () => resolve(),
115
+ color,
116
+ });
117
+ });
118
+ }
119
+
120
+ function confirm(
121
+ message: string,
122
+ color: Color = "primary",
123
+ ): Promise<boolean> {
124
+ return new Promise((resolve) => {
125
+ setPopup({
126
+ type: "confirm",
127
+ message,
128
+ visible: true,
129
+ inputValue: "",
130
+ onConfirm: () => resolve(true),
131
+ onCancel: () => resolve(false),
132
+ color,
133
+ });
134
+ });
135
+ }
136
+
137
+ function prompt(
138
+ message: string,
139
+ color: Color = "primary",
140
+ ): Promise<string | null> {
141
+ return new Promise((resolve) => {
142
+ setPopup({
143
+ type: "prompt",
144
+ message,
145
+ visible: true,
146
+ inputValue: "",
147
+ onConfirm: (value) => resolve(value ?? ""),
148
+ onCancel: () => resolve(null),
149
+ color,
150
+ });
151
+ });
152
+ }
153
+
154
+ function close(confirmed: boolean, value?: string) {
155
+ setPopup((prev) => {
156
+ if (confirmed) prev.onConfirm?.(value);
157
+ else prev.onCancel?.();
158
+ return { ...prev, visible: false, inputValue: "" };
159
+ });
160
+ }
161
+
162
+ const c = COLOR_CONFIG[popup.color];
163
+
164
+ const PopupComponent = popup.visible ? (
165
+ <div
166
+ className="fixed inset-0 flex items-center justify-center z-[1000]"
167
+ style={{ background: "rgba(15,23,42,0.45)", backdropFilter: "blur(2px)" }}
168
+ onClick={(e) => e.target === e.currentTarget && close(false)}
169
+ >
170
+ <div
171
+ className={`
172
+ bg-gradient-to-br ${c.bg} border ${c.border}
173
+ rounded-2xl shadow-2xl w-full max-w-sm mx-4
174
+ animate-[fadeInScale_0.18s_ease-out]
175
+ `}
176
+ style={{ animation: "fadeInScale 0.18s ease-out" }}
177
+ >
178
+ <style>{`
179
+ @keyframes fadeInScale {
180
+ from { opacity: 0; transform: scale(0.93) translateY(8px); }
181
+ to { opacity: 1; transform: scale(1) translateY(0); }
182
+ }
183
+ `}</style>
184
+
185
+ {/* Icon + Message */}
186
+ <div className="flex flex-col items-center gap-3 px-8 pt-8 pb-5 text-center">
187
+ <div
188
+ className={`w-12 h-12 rounded-full ${c.iconBg} flex items-center justify-center`}
189
+ >
190
+ <span className={`text-xl font-bold ${c.iconText}`}>{c.label}</span>
191
+ </div>
192
+ <p className="text-gray-800 text-[15px] font-medium leading-snug">
193
+ {popup.message}
194
+ </p>
195
+ </div>
196
+
197
+ {/* Prompt input */}
198
+ {popup.type === "prompt" && (
199
+ <div className="px-8 pb-2">
200
+ <input
201
+ autoFocus
202
+ type="text"
203
+ value={popup.inputValue}
204
+ onChange={(e) =>
205
+ setPopup((prev) => ({ ...prev, inputValue: e.target.value }))
206
+ }
207
+ onKeyDown={(e) =>
208
+ e.key === "Enter" && close(true, popup.inputValue)
209
+ }
210
+ className={`
211
+ w-full px-3 py-2 rounded-lg border ${c.border} bg-white
212
+ text-sm text-gray-800 outline-none
213
+ focus:ring-2 ${c.confirm.includes("blue") ? "focus:ring-blue-200" : "focus:ring-gray-200"}
214
+ transition
215
+ `}
216
+ placeholder="Escribe aquí..."
217
+ />
218
+ </div>
219
+ )}
220
+
221
+ {/* Divider */}
222
+ <div className={`border-t ${c.border} mx-0 mt-4`} />
223
+
224
+ {/* Actions */}
225
+ <div className="flex gap-2 px-6 py-4 justify-end">
226
+ {(popup.type === "confirm" || popup.type === "prompt") && (
227
+ <button
228
+ onClick={() => close(false)}
229
+ className="
230
+ px-4 py-2 rounded-lg text-sm font-medium
231
+ bg-white border border-gray-200 text-gray-600
232
+ hover:bg-gray-50 transition
233
+ "
234
+ >
235
+ Cancelar
236
+ </button>
237
+ )}
238
+ <button
239
+ onClick={() => close(true, popup.inputValue)}
240
+ className={`
241
+ px-5 py-2 rounded-lg text-sm font-semibold text-white
242
+ ${c.confirm} transition focus:outline-none focus:ring-2
243
+ `}
244
+ >
245
+ Aceptar
246
+ </button>
247
+ </div>
248
+ </div>
249
+ </div>
250
+ ) : null;
251
+
252
+ return { alert, confirm, prompt, PopupComponent };
253
+ }