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/dist/index.d.mts +13 -5
- package/dist/index.d.ts +13 -5
- package/dist/index.js +594 -471
- package/dist/index.mjs +544 -422
- package/package.json +1 -1
- package/src/alert/index.tsx +23 -145
- package/src/index.tsx +2 -1
- package/src/pop/index.tsx +253 -0
- package/src/table/index.tsx +348 -241
package/package.json
CHANGED
package/src/alert/index.tsx
CHANGED
|
@@ -1,149 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
63
|
-
|
|
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
|
-
|
|
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
|
-
)
|
|
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 "./
|
|
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
|
+
}
|