framepexls-ui-lib 0.1.12 → 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.
- package/dist/ActionIconButton.d.mts +1 -0
- package/dist/ActionIconButton.d.ts +1 -0
- package/dist/ActionIconButton.js +12 -9
- package/dist/ActionIconButton.mjs +13 -10
- package/dist/AppTopbar.d.mts +8 -9
- package/dist/AppTopbar.d.ts +8 -9
- package/dist/AppTopbar.js +31 -5
- package/dist/AppTopbar.mjs +21 -5
- package/dist/AvatarGroup.d.mts +14 -0
- package/dist/AvatarGroup.d.ts +14 -0
- package/dist/AvatarGroup.js +77 -0
- package/dist/AvatarGroup.mjs +47 -0
- package/dist/AvatarSquare.d.mts +2 -5
- package/dist/AvatarSquare.d.ts +2 -5
- package/dist/AvatarSquare.js +52 -3
- package/dist/AvatarSquare.mjs +52 -3
- package/dist/Badge.d.mts +2 -1
- package/dist/Badge.d.ts +2 -1
- package/dist/Badge.js +3 -1
- package/dist/Badge.mjs +3 -1
- package/dist/BadgeCluster.js +3 -3
- package/dist/BadgeCluster.mjs +3 -3
- package/dist/Button.d.mts +3 -4
- package/dist/Button.d.ts +3 -4
- package/dist/Button.js +97 -9
- package/dist/Button.mjs +87 -9
- package/dist/CalendarPanel.js +20 -3
- package/dist/CalendarPanel.mjs +10 -3
- package/dist/Card.d.mts +6 -0
- package/dist/Card.d.ts +6 -0
- package/dist/Card.js +52 -0
- package/dist/Card.mjs +22 -0
- package/dist/CheckboxPillsGroup.d.mts +2 -1
- package/dist/CheckboxPillsGroup.d.ts +2 -1
- package/dist/CheckboxPillsGroup.js +8 -4
- package/dist/CheckboxPillsGroup.mjs +8 -4
- package/dist/ColumnSelector.js +16 -2
- package/dist/ColumnSelector.mjs +6 -2
- package/dist/ComboSelect.d.mts +0 -2
- package/dist/ComboSelect.d.ts +0 -2
- package/dist/ComboSelect.js +8 -4
- package/dist/ComboSelect.mjs +8 -4
- package/dist/DateTimeField.d.mts +0 -5
- package/dist/DateTimeField.d.ts +0 -5
- package/dist/DateTimeField.js +17 -8
- package/dist/DateTimeField.mjs +17 -8
- package/dist/Dialog.d.mts +2 -5
- package/dist/Dialog.d.ts +2 -5
- package/dist/Dialog.js +21 -22
- package/dist/Dialog.mjs +21 -22
- package/dist/Drawer.d.mts +38 -0
- package/dist/Drawer.d.ts +38 -0
- package/dist/Drawer.js +139 -0
- package/dist/Drawer.mjs +102 -0
- package/dist/Dropdown.d.mts +0 -3
- package/dist/Dropdown.d.ts +0 -3
- package/dist/Dropdown.js +61 -42
- package/dist/Dropdown.mjs +51 -42
- package/dist/Input.d.mts +2 -0
- package/dist/Input.d.ts +2 -0
- package/dist/Input.js +20 -5
- package/dist/Input.mjs +20 -5
- package/dist/Link.d.mts +15 -0
- package/dist/Link.d.ts +15 -0
- package/dist/Link.js +93 -0
- package/dist/Link.mjs +63 -0
- package/dist/MediaCard.d.mts +15 -0
- package/dist/MediaCard.d.ts +15 -0
- package/dist/MediaCard.js +153 -0
- package/dist/MediaCard.mjs +123 -0
- package/dist/MediaSelector.d.mts +48 -0
- package/dist/MediaSelector.d.ts +48 -0
- package/dist/MediaSelector.js +225 -0
- package/dist/MediaSelector.mjs +195 -0
- package/dist/Money.d.mts +2 -1
- package/dist/Money.d.ts +2 -1
- package/dist/Money.js +26 -2
- package/dist/Money.mjs +26 -2
- package/dist/MultiComboSelect.js +6 -11
- package/dist/MultiComboSelect.mjs +6 -11
- package/dist/OrderButton.js +13 -1
- package/dist/OrderButton.mjs +3 -1
- package/dist/Pagination.d.mts +2 -1
- package/dist/Pagination.d.ts +2 -1
- package/dist/Pagination.js +40 -3
- package/dist/Pagination.mjs +30 -3
- package/dist/ReviewHistory.js +3 -9
- package/dist/ReviewHistory.mjs +3 -9
- package/dist/SearchInput.js +17 -42
- package/dist/SearchInput.mjs +17 -42
- package/dist/Select.js +5 -2
- package/dist/Select.mjs +5 -2
- package/dist/Sidebar.d.mts +2 -3
- package/dist/Sidebar.d.ts +2 -3
- package/dist/Sidebar.js +132 -24
- package/dist/Sidebar.mjs +132 -24
- package/dist/Steps.d.mts +0 -2
- package/dist/Steps.d.ts +0 -2
- package/dist/Steps.js +19 -6
- package/dist/Steps.mjs +9 -6
- package/dist/Table.js +3 -1
- package/dist/Table.mjs +3 -1
- package/dist/TimePanel.js +21 -7
- package/dist/TimePanel.mjs +11 -7
- package/dist/TimePopover.js +32 -15
- package/dist/TimePopover.mjs +32 -15
- package/dist/TimeRangeField.js +13 -6
- package/dist/TimeRangeField.mjs +13 -6
- package/dist/Toast.d.mts +53 -0
- package/dist/Toast.d.ts +53 -0
- package/dist/Toast.js +273 -0
- package/dist/Toast.mjs +238 -0
- package/dist/Tooltip.d.mts +15 -0
- package/dist/Tooltip.d.ts +15 -0
- package/dist/Tooltip.js +135 -0
- package/dist/Tooltip.mjs +105 -0
- package/dist/UploadCard.d.mts +27 -0
- package/dist/UploadCard.d.ts +27 -0
- package/dist/UploadCard.js +143 -0
- package/dist/UploadCard.mjs +113 -0
- package/dist/index.d.mts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +30 -1
- package/dist/index.mjs +58 -39
- 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 };
|
package/dist/Tooltip.js
ADDED
|
@@ -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
|
+
}
|