framepexls-ui-lib 0.1.13 → 0.1.14

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.
Files changed (123) hide show
  1. package/dist/ActionIconButton.d.mts +1 -0
  2. package/dist/ActionIconButton.d.ts +1 -0
  3. package/dist/ActionIconButton.js +12 -9
  4. package/dist/ActionIconButton.mjs +13 -10
  5. package/dist/AppTopbar.js +23 -6
  6. package/dist/AppTopbar.mjs +13 -6
  7. package/dist/AvatarGroup.d.mts +14 -0
  8. package/dist/AvatarGroup.d.ts +14 -0
  9. package/dist/AvatarGroup.js +77 -0
  10. package/dist/AvatarGroup.mjs +47 -0
  11. package/dist/AvatarSquare.d.mts +2 -5
  12. package/dist/AvatarSquare.d.ts +2 -5
  13. package/dist/AvatarSquare.js +52 -3
  14. package/dist/AvatarSquare.mjs +52 -3
  15. package/dist/Badge.d.mts +2 -1
  16. package/dist/Badge.d.ts +2 -1
  17. package/dist/Badge.js +3 -1
  18. package/dist/Badge.mjs +3 -1
  19. package/dist/BadgeCluster.js +3 -3
  20. package/dist/BadgeCluster.mjs +3 -3
  21. package/dist/Button.d.mts +3 -4
  22. package/dist/Button.d.ts +3 -4
  23. package/dist/Button.js +96 -8
  24. package/dist/Button.mjs +86 -8
  25. package/dist/CalendarPanel.js +20 -3
  26. package/dist/CalendarPanel.mjs +10 -3
  27. package/dist/Card.d.mts +6 -0
  28. package/dist/Card.d.ts +6 -0
  29. package/dist/Card.js +52 -0
  30. package/dist/Card.mjs +22 -0
  31. package/dist/CheckboxPillsGroup.d.mts +2 -1
  32. package/dist/CheckboxPillsGroup.d.ts +2 -1
  33. package/dist/CheckboxPillsGroup.js +8 -4
  34. package/dist/CheckboxPillsGroup.mjs +8 -4
  35. package/dist/ColumnSelector.js +16 -2
  36. package/dist/ColumnSelector.mjs +6 -2
  37. package/dist/ComboSelect.d.mts +0 -2
  38. package/dist/ComboSelect.d.ts +0 -2
  39. package/dist/ComboSelect.js +8 -4
  40. package/dist/ComboSelect.mjs +8 -4
  41. package/dist/DateTimeField.d.mts +0 -5
  42. package/dist/DateTimeField.d.ts +0 -5
  43. package/dist/DateTimeField.js +17 -8
  44. package/dist/DateTimeField.mjs +17 -8
  45. package/dist/Dialog.d.mts +2 -5
  46. package/dist/Dialog.d.ts +2 -5
  47. package/dist/Dialog.js +21 -22
  48. package/dist/Dialog.mjs +21 -22
  49. package/dist/Drawer.d.mts +38 -0
  50. package/dist/Drawer.d.ts +38 -0
  51. package/dist/Drawer.js +139 -0
  52. package/dist/Drawer.mjs +102 -0
  53. package/dist/Dropdown.d.mts +0 -3
  54. package/dist/Dropdown.d.ts +0 -3
  55. package/dist/Dropdown.js +61 -42
  56. package/dist/Dropdown.mjs +51 -42
  57. package/dist/Input.d.mts +2 -0
  58. package/dist/Input.d.ts +2 -0
  59. package/dist/Input.js +20 -5
  60. package/dist/Input.mjs +20 -5
  61. package/dist/Link.d.mts +15 -0
  62. package/dist/Link.d.ts +15 -0
  63. package/dist/Link.js +93 -0
  64. package/dist/Link.mjs +63 -0
  65. package/dist/MediaCard.d.mts +15 -0
  66. package/dist/MediaCard.d.ts +15 -0
  67. package/dist/MediaCard.js +153 -0
  68. package/dist/MediaCard.mjs +123 -0
  69. package/dist/MediaSelector.d.mts +48 -0
  70. package/dist/MediaSelector.d.ts +48 -0
  71. package/dist/MediaSelector.js +225 -0
  72. package/dist/MediaSelector.mjs +195 -0
  73. package/dist/Money.d.mts +2 -1
  74. package/dist/Money.d.ts +2 -1
  75. package/dist/Money.js +26 -2
  76. package/dist/Money.mjs +26 -2
  77. package/dist/MultiComboSelect.js +6 -11
  78. package/dist/MultiComboSelect.mjs +6 -11
  79. package/dist/OrderButton.js +13 -1
  80. package/dist/OrderButton.mjs +3 -1
  81. package/dist/Pagination.d.mts +2 -1
  82. package/dist/Pagination.d.ts +2 -1
  83. package/dist/Pagination.js +40 -3
  84. package/dist/Pagination.mjs +30 -3
  85. package/dist/ReviewHistory.js +3 -9
  86. package/dist/ReviewHistory.mjs +3 -9
  87. package/dist/SearchInput.js +17 -42
  88. package/dist/SearchInput.mjs +17 -42
  89. package/dist/Select.js +5 -2
  90. package/dist/Select.mjs +5 -2
  91. package/dist/Sidebar.d.mts +2 -3
  92. package/dist/Sidebar.d.ts +2 -3
  93. package/dist/Sidebar.js +132 -24
  94. package/dist/Sidebar.mjs +132 -24
  95. package/dist/Steps.d.mts +0 -2
  96. package/dist/Steps.d.ts +0 -2
  97. package/dist/Steps.js +19 -6
  98. package/dist/Steps.mjs +9 -6
  99. package/dist/Table.js +3 -1
  100. package/dist/Table.mjs +3 -1
  101. package/dist/TimePanel.js +21 -7
  102. package/dist/TimePanel.mjs +11 -7
  103. package/dist/TimePopover.js +32 -15
  104. package/dist/TimePopover.mjs +32 -15
  105. package/dist/TimeRangeField.js +13 -6
  106. package/dist/TimeRangeField.mjs +13 -6
  107. package/dist/Toast.d.mts +53 -0
  108. package/dist/Toast.d.ts +53 -0
  109. package/dist/Toast.js +273 -0
  110. package/dist/Toast.mjs +238 -0
  111. package/dist/Tooltip.d.mts +15 -0
  112. package/dist/Tooltip.d.ts +15 -0
  113. package/dist/Tooltip.js +135 -0
  114. package/dist/Tooltip.mjs +105 -0
  115. package/dist/UploadCard.d.mts +27 -0
  116. package/dist/UploadCard.d.ts +27 -0
  117. package/dist/UploadCard.js +143 -0
  118. package/dist/UploadCard.mjs +113 -0
  119. package/dist/index.d.mts +10 -1
  120. package/dist/index.d.ts +10 -1
  121. package/dist/index.js +30 -1
  122. package/dist/index.mjs +58 -39
  123. package/package.json +1 -1
package/dist/Toast.js ADDED
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var Toast_exports = {};
31
+ __export(Toast_exports, {
32
+ ToastProvider: () => ToastProvider,
33
+ default: () => Toast_default,
34
+ useToast: () => useToast
35
+ });
36
+ module.exports = __toCommonJS(Toast_exports);
37
+ var import_jsx_runtime = require("react/jsx-runtime");
38
+ var import_react = __toESM(require("react"));
39
+ var import_react_dom = require("react-dom");
40
+ var import_framer_motion = require("framer-motion");
41
+ var import_Button = __toESM(require("./Button"));
42
+ const ToastCtx = import_react.default.createContext(null);
43
+ function useToast() {
44
+ const ctx = import_react.default.useContext(ToastCtx);
45
+ if (!ctx) throw new Error("useToast debe usarse dentro de <ToastProvider />");
46
+ return ctx;
47
+ }
48
+ function genId() {
49
+ return Math.random().toString(36).slice(2) + Date.now().toString(36);
50
+ }
51
+ const typeAccent = {
52
+ default: {
53
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "9" }) }),
54
+ className: "text-slate-600 dark:text-slate-300",
55
+ border: "border-slate-200 dark:border-white/10",
56
+ progress: "bg-slate-300/70 dark:bg-white/30"
57
+ },
58
+ success: {
59
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M20 6L9 17l-5-5" }) }),
60
+ className: "text-emerald-600 dark:text-emerald-400",
61
+ border: "border-emerald-200 dark:border-emerald-500/30",
62
+ progress: "bg-emerald-500/60"
63
+ },
64
+ error: {
65
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
66
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 8v5M12 16h.01" }),
67
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0z" })
68
+ ] }),
69
+ className: "text-rose-600 dark:text-rose-400",
70
+ border: "border-rose-200 dark:border-rose-500/30",
71
+ progress: "bg-rose-500/60"
72
+ },
73
+ warning: {
74
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
75
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 9v4m0 4h.01" }),
76
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" })
77
+ ] }),
78
+ className: "text-amber-600 dark:text-amber-400",
79
+ border: "border-amber-200 dark:border-amber-500/30",
80
+ progress: "bg-amber-500/60"
81
+ },
82
+ info: {
83
+ icon: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
84
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M13 16h-1v-4h-1" }),
85
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M12 8h.01" }),
86
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "9" })
87
+ ] }),
88
+ className: "text-sky-600 dark:text-sky-400",
89
+ border: "border-sky-200 dark:border-sky-500/30",
90
+ progress: "bg-sky-500/60"
91
+ }
92
+ };
93
+ function useIsomorphicLayoutEffect(effect, deps) {
94
+ const useIso = typeof window !== "undefined" ? import_react.default.useLayoutEffect : import_react.default.useEffect;
95
+ return useIso(effect, deps);
96
+ }
97
+ function ToastView({ item, onClose, placement }) {
98
+ var _a;
99
+ const [hovered, setHovered] = import_react.default.useState(false);
100
+ const [remaining, setRemaining] = import_react.default.useState(item.duration);
101
+ const [startTs, setStartTs] = import_react.default.useState(null);
102
+ import_react.default.useEffect(() => {
103
+ if (hovered) return;
104
+ if (item.duration <= 0) return;
105
+ const now = Date.now();
106
+ setStartTs(now);
107
+ const id = setTimeout(() => onClose(), remaining);
108
+ return () => clearTimeout(id);
109
+ }, [hovered, remaining, item.duration, onClose]);
110
+ const onMouseEnter = () => {
111
+ setHovered(true);
112
+ if (startTs) {
113
+ const elapsed = Date.now() - startTs;
114
+ setRemaining((r) => Math.max(0, r - elapsed));
115
+ setStartTs(null);
116
+ }
117
+ };
118
+ const onMouseLeave = () => setHovered(false);
119
+ const direction = placement.startsWith("top") ? -1 : 1;
120
+ const accent = typeAccent[item.type];
121
+ const role = item.type === "error" || item.type === "warning" ? "alert" : "status";
122
+ const progressPct = item.duration > 0 ? Math.max(0, Math.min(100, (remaining != null ? remaining : 0) / item.duration * 100)) : 0;
123
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
124
+ import_framer_motion.motion.div,
125
+ {
126
+ role,
127
+ "aria-live": role === "alert" ? "assertive" : "polite",
128
+ initial: { opacity: 0, y: 12 * direction },
129
+ animate: { opacity: 1, y: 0 },
130
+ exit: { opacity: 0, y: 12 * direction },
131
+ transition: { type: "spring", stiffness: 260, damping: 26 },
132
+ onMouseEnter,
133
+ onMouseLeave,
134
+ className: [
135
+ "pointer-events-auto relative w-[380px] max-w-[92vw] overflow-hidden rounded-xl border bg-white p-3 pr-10 shadow-lg dark:bg-[#0f0d0e]",
136
+ accent.border
137
+ ].join(" "),
138
+ children: [
139
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-start gap-3", children: [
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: ["mt-0.5 shrink-0", accent.className].join(" "), children: (_a = item.icon) != null ? _a : accent.icon }),
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "min-w-0 flex-1", children: [
142
+ item.title && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-[13px] font-semibold text-slate-900 dark:text-white", children: item.title }),
143
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-0.5 text-[13px] leading-snug text-slate-600 dark:text-slate-300", children: item.description }),
144
+ item.action && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "mt-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
145
+ import_Button.default,
146
+ {
147
+ unstyled: true,
148
+ onClick: () => {
149
+ var _a2, _b;
150
+ (_b = (_a2 = item.action) == null ? void 0 : _a2.onClick) == null ? void 0 : _b.call(_a2);
151
+ onClose();
152
+ },
153
+ className: [
154
+ "inline-flex items-center rounded-lg px-2 py-1 text-xs font-medium",
155
+ "text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-white/10"
156
+ ].join(" "),
157
+ children: item.action.label
158
+ }
159
+ ) })
160
+ ] }),
161
+ item.dismissible && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
162
+ import_Button.default,
163
+ {
164
+ unstyled: true,
165
+ "aria-label": "Cerrar",
166
+ onClick: onClose,
167
+ className: "absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-lg text-slate-500 hover:bg-slate-100 hover:text-slate-700 dark:text-slate-300 dark:hover:bg-white/10",
168
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M6 6l12 12M18 6L6 18" }) })
169
+ }
170
+ )
171
+ ] }),
172
+ item.duration > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "absolute inset-x-0 bottom-0", children: [
173
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: ["h-0.5 w-full bg-transparent"].join(" ") }),
174
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
175
+ "div",
176
+ {
177
+ className: ["absolute bottom-0 left-0 h-0.5", accent.progress].join(" "),
178
+ style: { width: `${progressPct}%`, transition: hovered ? void 0 : "width 120ms linear" }
179
+ }
180
+ )
181
+ ] })
182
+ ]
183
+ }
184
+ );
185
+ }
186
+ function getContainerClasses(placement) {
187
+ const base = "pointer-events-none fixed z-[2000] flex gap-2 p-4";
188
+ switch (placement) {
189
+ case "top-left":
190
+ return `${base} left-0 top-0 flex-col items-start`;
191
+ case "top-center":
192
+ return `${base} left-1/2 top-0 -translate-x-1/2 transform flex-col items-center`;
193
+ case "top-right":
194
+ return `${base} right-0 top-0 flex-col items-end`;
195
+ case "bottom-left":
196
+ return `${base} bottom-0 left-0 flex-col-reverse items-start`;
197
+ case "bottom-center":
198
+ return `${base} bottom-0 left-1/2 -translate-x-1/2 transform flex-col-reverse items-center`;
199
+ case "bottom-right":
200
+ default:
201
+ return `${base} bottom-0 right-0 flex-col-reverse items-end`;
202
+ }
203
+ }
204
+ function ToastProvider({ placement = "top-right", max = 4, duration = 5e3, children }) {
205
+ const [toasts, setToasts] = import_react.default.useState([]);
206
+ const [mounted, setMounted] = import_react.default.useState(false);
207
+ const portalRoot = typeof document !== "undefined" ? document.body : null;
208
+ const remove = import_react.default.useCallback((id) => {
209
+ setToasts((arr) => arr.filter((t) => t.id !== id));
210
+ }, []);
211
+ const clear = import_react.default.useCallback(() => setToasts([]), []);
212
+ const update = import_react.default.useCallback((id, patch) => {
213
+ setToasts((arr) => arr.map((t) => t.id === id ? { ...t, ...patch } : t));
214
+ }, []);
215
+ const add = import_react.default.useCallback(
216
+ (input) => {
217
+ var _a, _b, _c, _d, _e, _f, _g;
218
+ const id = (_a = input.id) != null ? _a : genId();
219
+ const item = {
220
+ id,
221
+ title: (_b = input.title) != null ? _b : void 0,
222
+ description: (_c = input.description) != null ? _c : void 0,
223
+ type: (_d = input.type) != null ? _d : "default",
224
+ duration: typeof input.duration === "number" ? input.duration : duration,
225
+ dismissible: (_e = input.dismissible) != null ? _e : true,
226
+ icon: (_f = input.icon) != null ? _f : void 0,
227
+ action: (_g = input.action) != null ? _g : void 0,
228
+ createdAt: Date.now()
229
+ };
230
+ setToasts((prev) => {
231
+ const next = [item, ...prev];
232
+ if (next.length > max) next.splice(max);
233
+ return next;
234
+ });
235
+ return id;
236
+ },
237
+ [duration, max]
238
+ );
239
+ const sugar = import_react.default.useMemo(() => {
240
+ const wrap = (type) => (msg, opts) => {
241
+ if (typeof msg === "string") {
242
+ return add({ description: msg, type, ...opts != null ? opts : {} });
243
+ }
244
+ return add({ ...msg, type });
245
+ };
246
+ return {
247
+ success: wrap("success"),
248
+ error: wrap("error"),
249
+ warning: wrap("warning"),
250
+ info: wrap("info")
251
+ };
252
+ }, [add]);
253
+ const ctx = import_react.default.useMemo(
254
+ () => ({ add, remove, clear, update, ...sugar }),
255
+ [add, remove, clear, update, sugar]
256
+ );
257
+ import_react.default.useEffect(() => {
258
+ setMounted(true);
259
+ }, []);
260
+ const container = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: getContainerClasses(placement), "aria-live": "polite", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_framer_motion.AnimatePresence, { initial: false, children: toasts.map((t) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToastView, { item: t, onClose: () => remove(t.id), placement }, t.id)) }) });
261
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(ToastCtx.Provider, { value: ctx, children: [
262
+ children,
263
+ mounted && portalRoot ? (0, import_react_dom.createPortal)(container, portalRoot) : null
264
+ ] });
265
+ }
266
+ var Toast_default = {
267
+ Provider: ToastProvider
268
+ };
269
+ // Annotate the CommonJS export names for ESM import in node:
270
+ 0 && (module.exports = {
271
+ ToastProvider,
272
+ useToast
273
+ });
package/dist/Toast.mjs ADDED
@@ -0,0 +1,238 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import React from "react";
4
+ import { createPortal } from "react-dom";
5
+ import { AnimatePresence, motion } from "framer-motion";
6
+ import Button from "./Button";
7
+ const ToastCtx = React.createContext(null);
8
+ function useToast() {
9
+ const ctx = React.useContext(ToastCtx);
10
+ if (!ctx) throw new Error("useToast debe usarse dentro de <ToastProvider />");
11
+ return ctx;
12
+ }
13
+ function genId() {
14
+ return Math.random().toString(36).slice(2) + Date.now().toString(36);
15
+ }
16
+ const typeAccent = {
17
+ default: {
18
+ icon: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" }) }),
19
+ className: "text-slate-600 dark:text-slate-300",
20
+ border: "border-slate-200 dark:border-white/10",
21
+ progress: "bg-slate-300/70 dark:bg-white/30"
22
+ },
23
+ success: {
24
+ icon: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M20 6L9 17l-5-5" }) }),
25
+ className: "text-emerald-600 dark:text-emerald-400",
26
+ border: "border-emerald-200 dark:border-emerald-500/30",
27
+ progress: "bg-emerald-500/60"
28
+ },
29
+ error: {
30
+ icon: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
31
+ /* @__PURE__ */ jsx("path", { d: "M12 8v5M12 16h.01" }),
32
+ /* @__PURE__ */ jsx("path", { d: "M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0z" })
33
+ ] }),
34
+ className: "text-rose-600 dark:text-rose-400",
35
+ border: "border-rose-200 dark:border-rose-500/30",
36
+ progress: "bg-rose-500/60"
37
+ },
38
+ warning: {
39
+ icon: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
40
+ /* @__PURE__ */ jsx("path", { d: "M12 9v4m0 4h.01" }),
41
+ /* @__PURE__ */ jsx("path", { d: "M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" })
42
+ ] }),
43
+ className: "text-amber-600 dark:text-amber-400",
44
+ border: "border-amber-200 dark:border-amber-500/30",
45
+ progress: "bg-amber-500/60"
46
+ },
47
+ info: {
48
+ icon: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", className: "h-5 w-5", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
49
+ /* @__PURE__ */ jsx("path", { d: "M13 16h-1v-4h-1" }),
50
+ /* @__PURE__ */ jsx("path", { d: "M12 8h.01" }),
51
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "9" })
52
+ ] }),
53
+ className: "text-sky-600 dark:text-sky-400",
54
+ border: "border-sky-200 dark:border-sky-500/30",
55
+ progress: "bg-sky-500/60"
56
+ }
57
+ };
58
+ function useIsomorphicLayoutEffect(effect, deps) {
59
+ const useIso = typeof window !== "undefined" ? React.useLayoutEffect : React.useEffect;
60
+ return useIso(effect, deps);
61
+ }
62
+ function ToastView({ item, onClose, placement }) {
63
+ var _a;
64
+ const [hovered, setHovered] = React.useState(false);
65
+ const [remaining, setRemaining] = React.useState(item.duration);
66
+ const [startTs, setStartTs] = React.useState(null);
67
+ React.useEffect(() => {
68
+ if (hovered) return;
69
+ if (item.duration <= 0) return;
70
+ const now = Date.now();
71
+ setStartTs(now);
72
+ const id = setTimeout(() => onClose(), remaining);
73
+ return () => clearTimeout(id);
74
+ }, [hovered, remaining, item.duration, onClose]);
75
+ const onMouseEnter = () => {
76
+ setHovered(true);
77
+ if (startTs) {
78
+ const elapsed = Date.now() - startTs;
79
+ setRemaining((r) => Math.max(0, r - elapsed));
80
+ setStartTs(null);
81
+ }
82
+ };
83
+ const onMouseLeave = () => setHovered(false);
84
+ const direction = placement.startsWith("top") ? -1 : 1;
85
+ const accent = typeAccent[item.type];
86
+ const role = item.type === "error" || item.type === "warning" ? "alert" : "status";
87
+ const progressPct = item.duration > 0 ? Math.max(0, Math.min(100, (remaining != null ? remaining : 0) / item.duration * 100)) : 0;
88
+ return /* @__PURE__ */ jsxs(
89
+ motion.div,
90
+ {
91
+ role,
92
+ "aria-live": role === "alert" ? "assertive" : "polite",
93
+ initial: { opacity: 0, y: 12 * direction },
94
+ animate: { opacity: 1, y: 0 },
95
+ exit: { opacity: 0, y: 12 * direction },
96
+ transition: { type: "spring", stiffness: 260, damping: 26 },
97
+ onMouseEnter,
98
+ onMouseLeave,
99
+ className: [
100
+ "pointer-events-auto relative w-[380px] max-w-[92vw] overflow-hidden rounded-xl border bg-white p-3 pr-10 shadow-lg dark:bg-[#0f0d0e]",
101
+ accent.border
102
+ ].join(" "),
103
+ children: [
104
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
105
+ /* @__PURE__ */ jsx("div", { className: ["mt-0.5 shrink-0", accent.className].join(" "), children: (_a = item.icon) != null ? _a : accent.icon }),
106
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
107
+ item.title && /* @__PURE__ */ jsx("div", { className: "text-[13px] font-semibold text-slate-900 dark:text-white", children: item.title }),
108
+ item.description && /* @__PURE__ */ jsx("div", { className: "mt-0.5 text-[13px] leading-snug text-slate-600 dark:text-slate-300", children: item.description }),
109
+ item.action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsx(
110
+ Button,
111
+ {
112
+ unstyled: true,
113
+ onClick: () => {
114
+ var _a2, _b;
115
+ (_b = (_a2 = item.action) == null ? void 0 : _a2.onClick) == null ? void 0 : _b.call(_a2);
116
+ onClose();
117
+ },
118
+ className: [
119
+ "inline-flex items-center rounded-lg px-2 py-1 text-xs font-medium",
120
+ "text-slate-700 hover:bg-slate-100 dark:text-slate-200 dark:hover:bg-white/10"
121
+ ].join(" "),
122
+ children: item.action.label
123
+ }
124
+ ) })
125
+ ] }),
126
+ item.dismissible && /* @__PURE__ */ jsx(
127
+ Button,
128
+ {
129
+ unstyled: true,
130
+ "aria-label": "Cerrar",
131
+ onClick: onClose,
132
+ className: "absolute right-2 top-2 inline-flex h-7 w-7 items-center justify-center rounded-lg text-slate-500 hover:bg-slate-100 hover:text-slate-700 dark:text-slate-300 dark:hover:bg-white/10",
133
+ children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "h-4 w-4", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsx("path", { d: "M6 6l12 12M18 6L6 18" }) })
134
+ }
135
+ )
136
+ ] }),
137
+ item.duration > 0 && /* @__PURE__ */ jsxs("div", { className: "absolute inset-x-0 bottom-0", children: [
138
+ /* @__PURE__ */ jsx("div", { className: ["h-0.5 w-full bg-transparent"].join(" ") }),
139
+ /* @__PURE__ */ jsx(
140
+ "div",
141
+ {
142
+ className: ["absolute bottom-0 left-0 h-0.5", accent.progress].join(" "),
143
+ style: { width: `${progressPct}%`, transition: hovered ? void 0 : "width 120ms linear" }
144
+ }
145
+ )
146
+ ] })
147
+ ]
148
+ }
149
+ );
150
+ }
151
+ function getContainerClasses(placement) {
152
+ const base = "pointer-events-none fixed z-[2000] flex gap-2 p-4";
153
+ switch (placement) {
154
+ case "top-left":
155
+ return `${base} left-0 top-0 flex-col items-start`;
156
+ case "top-center":
157
+ return `${base} left-1/2 top-0 -translate-x-1/2 transform flex-col items-center`;
158
+ case "top-right":
159
+ return `${base} right-0 top-0 flex-col items-end`;
160
+ case "bottom-left":
161
+ return `${base} bottom-0 left-0 flex-col-reverse items-start`;
162
+ case "bottom-center":
163
+ return `${base} bottom-0 left-1/2 -translate-x-1/2 transform flex-col-reverse items-center`;
164
+ case "bottom-right":
165
+ default:
166
+ return `${base} bottom-0 right-0 flex-col-reverse items-end`;
167
+ }
168
+ }
169
+ function ToastProvider({ placement = "top-right", max = 4, duration = 5e3, children }) {
170
+ const [toasts, setToasts] = React.useState([]);
171
+ const [mounted, setMounted] = React.useState(false);
172
+ const portalRoot = typeof document !== "undefined" ? document.body : null;
173
+ const remove = React.useCallback((id) => {
174
+ setToasts((arr) => arr.filter((t) => t.id !== id));
175
+ }, []);
176
+ const clear = React.useCallback(() => setToasts([]), []);
177
+ const update = React.useCallback((id, patch) => {
178
+ setToasts((arr) => arr.map((t) => t.id === id ? { ...t, ...patch } : t));
179
+ }, []);
180
+ const add = React.useCallback(
181
+ (input) => {
182
+ var _a, _b, _c, _d, _e, _f, _g;
183
+ const id = (_a = input.id) != null ? _a : genId();
184
+ const item = {
185
+ id,
186
+ title: (_b = input.title) != null ? _b : void 0,
187
+ description: (_c = input.description) != null ? _c : void 0,
188
+ type: (_d = input.type) != null ? _d : "default",
189
+ duration: typeof input.duration === "number" ? input.duration : duration,
190
+ dismissible: (_e = input.dismissible) != null ? _e : true,
191
+ icon: (_f = input.icon) != null ? _f : void 0,
192
+ action: (_g = input.action) != null ? _g : void 0,
193
+ createdAt: Date.now()
194
+ };
195
+ setToasts((prev) => {
196
+ const next = [item, ...prev];
197
+ if (next.length > max) next.splice(max);
198
+ return next;
199
+ });
200
+ return id;
201
+ },
202
+ [duration, max]
203
+ );
204
+ const sugar = React.useMemo(() => {
205
+ const wrap = (type) => (msg, opts) => {
206
+ if (typeof msg === "string") {
207
+ return add({ description: msg, type, ...opts != null ? opts : {} });
208
+ }
209
+ return add({ ...msg, type });
210
+ };
211
+ return {
212
+ success: wrap("success"),
213
+ error: wrap("error"),
214
+ warning: wrap("warning"),
215
+ info: wrap("info")
216
+ };
217
+ }, [add]);
218
+ const ctx = React.useMemo(
219
+ () => ({ add, remove, clear, update, ...sugar }),
220
+ [add, remove, clear, update, sugar]
221
+ );
222
+ React.useEffect(() => {
223
+ setMounted(true);
224
+ }, []);
225
+ const container = /* @__PURE__ */ jsx("div", { className: getContainerClasses(placement), "aria-live": "polite", children: /* @__PURE__ */ jsx(AnimatePresence, { initial: false, children: toasts.map((t) => /* @__PURE__ */ jsx(ToastView, { item: t, onClose: () => remove(t.id), placement }, t.id)) }) });
226
+ return /* @__PURE__ */ jsxs(ToastCtx.Provider, { value: ctx, children: [
227
+ children,
228
+ mounted && portalRoot ? createPortal(container, portalRoot) : null
229
+ ] });
230
+ }
231
+ var Toast_default = {
232
+ Provider: ToastProvider
233
+ };
234
+ export {
235
+ ToastProvider,
236
+ Toast_default as default,
237
+ useToast
238
+ };
@@ -0,0 +1,15 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+
4
+ type Placement = "top" | "bottom" | "left" | "right";
5
+ type TooltipProps = {
6
+ content: React__default.ReactNode;
7
+ placement?: Placement;
8
+ delay?: number;
9
+ offset?: number;
10
+ className?: string;
11
+ children: React__default.ReactElement;
12
+ };
13
+ declare function Tooltip({ content, placement, delay, offset, className, children }: TooltipProps): react_jsx_runtime.JSX.Element;
14
+
15
+ export { type TooltipProps, Tooltip as default };
@@ -0,0 +1,15 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React__default from 'react';
3
+
4
+ type Placement = "top" | "bottom" | "left" | "right";
5
+ type TooltipProps = {
6
+ content: React__default.ReactNode;
7
+ placement?: Placement;
8
+ delay?: number;
9
+ offset?: number;
10
+ className?: string;
11
+ children: React__default.ReactElement;
12
+ };
13
+ declare function Tooltip({ content, placement, delay, offset, className, children }: TooltipProps): react_jsx_runtime.JSX.Element;
14
+
15
+ export { type TooltipProps, Tooltip as default };
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var Tooltip_exports = {};
31
+ __export(Tooltip_exports, {
32
+ default: () => Tooltip
33
+ });
34
+ module.exports = __toCommonJS(Tooltip_exports);
35
+ var import_jsx_runtime = require("react/jsx-runtime");
36
+ var import_react = __toESM(require("react"));
37
+ var import_react_dom = require("react-dom");
38
+ function Tooltip({ content, placement = "top", delay = 80, offset = 8, className = "", children }) {
39
+ const [open, setOpen] = import_react.default.useState(false);
40
+ const [pos, setPos] = import_react.default.useState(null);
41
+ const [id] = import_react.default.useState(() => Math.random().toString(36).slice(2));
42
+ const ref = import_react.default.useRef(null);
43
+ const timer = import_react.default.useRef(null);
44
+ const attach = (el) => {
45
+ ref.current = el;
46
+ };
47
+ const compute = import_react.default.useCallback(() => {
48
+ const el = ref.current;
49
+ if (!el) return;
50
+ const r = el.getBoundingClientRect();
51
+ const scrollX = window.scrollX;
52
+ const scrollY = window.scrollY;
53
+ let top = 0, left = 0;
54
+ if (placement === "top") {
55
+ top = r.top + scrollY - offset;
56
+ left = r.left + scrollX + r.width / 2;
57
+ } else if (placement === "bottom") {
58
+ top = r.bottom + scrollY + offset;
59
+ left = r.left + scrollX + r.width / 2;
60
+ } else if (placement === "left") {
61
+ top = r.top + scrollY + r.height / 2;
62
+ left = r.left + scrollX - offset;
63
+ } else {
64
+ top = r.top + scrollY + r.height / 2;
65
+ left = r.right + scrollX + offset;
66
+ }
67
+ setPos({ top, left });
68
+ }, [placement, offset]);
69
+ import_react.default.useEffect(() => {
70
+ if (!open) return;
71
+ compute();
72
+ const onScroll = () => compute();
73
+ const onResize = () => compute();
74
+ window.addEventListener("scroll", onScroll, true);
75
+ window.addEventListener("resize", onResize);
76
+ return () => {
77
+ window.removeEventListener("scroll", onScroll, true);
78
+ window.removeEventListener("resize", onResize);
79
+ };
80
+ }, [open, compute]);
81
+ const show = () => {
82
+ if (timer.current) window.clearTimeout(timer.current);
83
+ timer.current = window.setTimeout(() => setOpen(true), delay);
84
+ };
85
+ const hide = () => {
86
+ if (timer.current) window.clearTimeout(timer.current);
87
+ setOpen(false);
88
+ };
89
+ const triggerProps = {
90
+ ref: attach,
91
+ onMouseEnter: (e) => {
92
+ var _a, _b;
93
+ show();
94
+ (_b = (_a = children.props).onMouseEnter) == null ? void 0 : _b.call(_a, e);
95
+ },
96
+ onMouseLeave: (e) => {
97
+ var _a, _b;
98
+ hide();
99
+ (_b = (_a = children.props).onMouseLeave) == null ? void 0 : _b.call(_a, e);
100
+ },
101
+ onFocus: (e) => {
102
+ var _a, _b;
103
+ show();
104
+ (_b = (_a = children.props).onFocus) == null ? void 0 : _b.call(_a, e);
105
+ },
106
+ onBlur: (e) => {
107
+ var _a, _b;
108
+ hide();
109
+ (_b = (_a = children.props).onBlur) == null ? void 0 : _b.call(_a, e);
110
+ },
111
+ "aria-describedby": open ? id : void 0
112
+ };
113
+ const body = open && pos && typeof document !== "undefined" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
114
+ "div",
115
+ {
116
+ id,
117
+ role: "tooltip",
118
+ className: [
119
+ "pointer-events-none fixed z-[2000] max-w-xs rounded-xl border border-slate-200/80 bg-slate-900/95 px-2.5 py-1.5 text-[12px] text-white shadow-xl backdrop-blur",
120
+ "dark:border-white/10 dark:bg-white/10",
121
+ className != null ? className : ""
122
+ ].join(" "),
123
+ style: {
124
+ top: placement === "top" || placement === "bottom" ? pos.top : pos.top,
125
+ left: placement === "top" || placement === "bottom" ? pos.left : pos.left,
126
+ transform: placement === "top" || placement === "bottom" ? "translate(-50%, -100%)" : placement === "left" ? "translate(-100%, -50%)" : "translate(0, -50%)"
127
+ },
128
+ children: content
129
+ }
130
+ ) : null;
131
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
132
+ import_react.default.cloneElement(children, triggerProps),
133
+ body ? (0, import_react_dom.createPortal)(body, document.body) : null
134
+ ] });
135
+ }