@misael703/ui 1.0.1 → 1.2.0
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/chunk-2S6JJYN7.js +209 -0
- package/dist/chunk-2S6JJYN7.js.map +1 -0
- package/dist/{chunk-GDFYAUHT.mjs → chunk-3N4IBCLW.mjs} +11 -29
- package/dist/chunk-3N4IBCLW.mjs.map +1 -0
- package/dist/{chunk-TB6EHWRF.mjs → chunk-3OVWAAGP.mjs} +3 -3
- package/dist/{chunk-TB6EHWRF.mjs.map → chunk-3OVWAAGP.mjs.map} +1 -1
- package/dist/chunk-427NHGTX.js +4 -0
- package/dist/chunk-427NHGTX.js.map +1 -0
- package/dist/chunk-6P2TKRTL.mjs +45 -0
- package/dist/chunk-6P2TKRTL.mjs.map +1 -0
- package/dist/chunk-6RVCYULF.mjs +78 -0
- package/dist/chunk-6RVCYULF.mjs.map +1 -0
- package/dist/chunk-BVQRDAR7.mjs +3 -0
- package/dist/chunk-BVQRDAR7.mjs.map +1 -0
- package/dist/{chunk-TXKFCVCN.mjs → chunk-C35GKQJO.mjs} +3 -3
- package/dist/{chunk-TXKFCVCN.mjs.map → chunk-C35GKQJO.mjs.map} +1 -1
- package/dist/chunk-DPMUWQHL.js +95 -0
- package/dist/chunk-DPMUWQHL.js.map +1 -0
- package/dist/chunk-GIOMV3J7.js +48 -0
- package/dist/chunk-GIOMV3J7.js.map +1 -0
- package/dist/chunk-GLYGO7WX.js +13 -0
- package/dist/chunk-GLYGO7WX.js.map +1 -0
- package/dist/chunk-H3PRT76O.mjs +73 -0
- package/dist/chunk-H3PRT76O.mjs.map +1 -0
- package/dist/{chunk-Z4GRQHIG.mjs → chunk-IEJXZ67E.mjs} +3 -3
- package/dist/{chunk-Z4GRQHIG.mjs.map → chunk-IEJXZ67E.mjs.map} +1 -1
- package/dist/chunk-IMHLJKYR.mjs +176 -0
- package/dist/chunk-IMHLJKYR.mjs.map +1 -0
- package/dist/{chunk-EJJDJJEM.js → chunk-K5S3SV2U.js} +108 -106
- package/dist/chunk-K5S3SV2U.js.map +1 -0
- package/dist/{chunk-ADIKHOEG.js → chunk-KOIRRZRD.js} +72 -6
- package/dist/chunk-KOIRRZRD.js.map +1 -0
- package/dist/{chunk-ZXSSOEIM.js → chunk-LXNHGGAK.js} +4 -4
- package/dist/{chunk-ZXSSOEIM.js.map → chunk-LXNHGGAK.js.map} +1 -1
- package/dist/{chunk-HI3JT6SI.mjs → chunk-MM7VE7YN.mjs} +72 -6
- package/dist/chunk-MM7VE7YN.mjs.map +1 -0
- package/dist/chunk-MUL2FKYF.js +100 -0
- package/dist/chunk-MUL2FKYF.js.map +1 -0
- package/dist/chunk-N2Y2KWX5.mjs +216 -0
- package/dist/chunk-N2Y2KWX5.mjs.map +1 -0
- package/dist/{chunk-CVXS7IHA.js → chunk-N7LFCAAY.js} +112 -113
- package/dist/chunk-N7LFCAAY.js.map +1 -0
- package/dist/chunk-OCLBAGNF.mjs +184 -0
- package/dist/chunk-OCLBAGNF.mjs.map +1 -0
- package/dist/{chunk-QSCJ2CER.mjs → chunk-OHCS5CYV.mjs} +108 -106
- package/dist/chunk-OHCS5CYV.mjs.map +1 -0
- package/dist/{chunk-LUXTZOTJ.js → chunk-OHMFYAB2.js} +4 -4
- package/dist/{chunk-LUXTZOTJ.js.map → chunk-OHMFYAB2.js.map} +1 -1
- package/dist/{chunk-T4R2LSRL.js → chunk-PROKTOL7.js} +3 -2
- package/dist/chunk-PROKTOL7.js.map +1 -0
- package/dist/{chunk-3UHX7ITQ.mjs → chunk-QI4JT3V3.mjs} +29 -34
- package/dist/chunk-QI4JT3V3.mjs.map +1 -0
- package/dist/{chunk-Z3FAKG3E.mjs → chunk-QW2CSXPH.mjs} +3 -2
- package/dist/chunk-QW2CSXPH.mjs.map +1 -0
- package/dist/chunk-QX5GGPV5.mjs +11 -0
- package/dist/chunk-QX5GGPV5.mjs.map +1 -0
- package/dist/{chunk-2RVSLQEA.mjs → chunk-R76SJURE.mjs} +3 -3
- package/dist/{chunk-2RVSLQEA.mjs.map → chunk-R76SJURE.mjs.map} +1 -1
- package/dist/{chunk-E2XOUDAH.js → chunk-REL2RZTI.js} +14 -32
- package/dist/chunk-REL2RZTI.js.map +1 -0
- package/dist/{chunk-R76YER7O.js → chunk-TBAKKSAN.js} +4 -4
- package/dist/{chunk-R76YER7O.js.map → chunk-TBAKKSAN.js.map} +1 -1
- package/dist/chunk-V7MK42GX.js +238 -0
- package/dist/chunk-V7MK42GX.js.map +1 -0
- package/dist/chunk-VR4OXVKE.js +198 -0
- package/dist/chunk-VR4OXVKE.js.map +1 -0
- package/dist/chunk-WLDQP4KD.mjs +75 -0
- package/dist/chunk-WLDQP4KD.mjs.map +1 -0
- package/dist/{chunk-W6YOBPL5.js → chunk-WVN5JJVV.js} +27 -40
- package/dist/chunk-WVN5JJVV.js.map +1 -0
- package/dist/chunk-XMLBKK7X.js +67 -0
- package/dist/chunk-XMLBKK7X.js.map +1 -0
- package/dist/chunk-XXUSZD5I.mjs +26 -0
- package/dist/chunk-XXUSZD5I.mjs.map +1 -0
- package/dist/{chunk-IIYQO6BL.js → chunk-YAORRBMU.js} +29 -34
- package/dist/chunk-YAORRBMU.js.map +1 -0
- package/dist/{chunk-AAQ7KUZH.mjs → chunk-YFLVB62R.mjs} +112 -113
- package/dist/chunk-YFLVB62R.mjs.map +1 -0
- package/dist/{chunk-UIKCTWKG.js → chunk-YRACSKAT.js} +4 -4
- package/dist/{chunk-UIKCTWKG.js.map → chunk-YRACSKAT.js.map} +1 -1
- package/dist/components/AdvancedPickers.js +8 -5
- package/dist/components/AdvancedPickers.mjs +4 -1
- package/dist/components/AppShell.js +3 -3
- package/dist/components/AppShell.mjs +1 -1
- package/dist/components/Comments.js +8 -5
- package/dist/components/Comments.mjs +5 -2
- package/dist/components/Commerce.js +14 -13
- package/dist/components/Commerce.mjs +3 -2
- package/dist/components/ContextMenu.js +5 -2
- package/dist/components/ContextMenu.mjs +4 -1
- package/dist/components/Display2.js +8 -5
- package/dist/components/Display2.mjs +4 -1
- package/dist/components/Display3.js +11 -8
- package/dist/components/Display3.mjs +5 -2
- package/dist/components/Editing.js +8 -7
- package/dist/components/Editing.mjs +3 -2
- package/dist/components/HoverCard.js +4 -2
- package/dist/components/HoverCard.mjs +3 -1
- package/dist/components/Layout.js +20 -18
- package/dist/components/Layout.mjs +3 -1
- package/dist/components/Menubar.js +5 -2
- package/dist/components/Menubar.mjs +4 -1
- package/dist/components/NavigationMenu.js +5 -2
- package/dist/components/NavigationMenu.mjs +4 -1
- package/dist/components/Overlay.js +4 -3
- package/dist/components/Overlay.mjs +2 -1
- package/dist/components/Pickers.js +7 -4
- package/dist/components/Pickers.mjs +4 -1
- package/dist/components/Popover.js +5 -2
- package/dist/components/Popover.mjs +4 -1
- package/dist/components/Portal.d.mts +30 -0
- package/dist/components/Portal.d.ts +30 -0
- package/dist/components/Portal.js +12 -0
- package/dist/components/Portal.js.map +1 -0
- package/dist/components/Portal.mjs +3 -0
- package/dist/components/Portal.mjs.map +1 -0
- package/dist/hooks/index.d.mts +4 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +23 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +6 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/hooks/useDelayedUnmount.d.mts +22 -0
- package/dist/hooks/useDelayedUnmount.d.ts +22 -0
- package/dist/hooks/useDelayedUnmount.js +12 -0
- package/dist/hooks/useDelayedUnmount.js.map +1 -0
- package/dist/hooks/useDelayedUnmount.mjs +3 -0
- package/dist/hooks/useDelayedUnmount.mjs.map +1 -0
- package/dist/hooks/useDismiss.d.mts +23 -0
- package/dist/hooks/useDismiss.d.ts +23 -0
- package/dist/hooks/useDismiss.js +12 -0
- package/dist/hooks/useDismiss.js.map +1 -0
- package/dist/hooks/useDismiss.mjs +3 -0
- package/dist/hooks/useDismiss.mjs.map +1 -0
- package/dist/hooks/usePopoverPosition.d.mts +50 -0
- package/dist/hooks/usePopoverPosition.d.ts +50 -0
- package/dist/hooks/usePopoverPosition.js +12 -0
- package/dist/hooks/usePopoverPosition.js.map +1 -0
- package/dist/hooks/usePopoverPosition.mjs +3 -0
- package/dist/hooks/usePopoverPosition.mjs.map +1 -0
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +95 -78
- package/dist/index.mjs +21 -16
- package/dist/styles.css +1 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
- package/dist/chunk-3UHX7ITQ.mjs.map +0 -1
- package/dist/chunk-5VMZMDJF.js +0 -145
- package/dist/chunk-5VMZMDJF.js.map +0 -1
- package/dist/chunk-7AKN7FDA.mjs +0 -103
- package/dist/chunk-7AKN7FDA.mjs.map +0 -1
- package/dist/chunk-AAQ7KUZH.mjs.map +0 -1
- package/dist/chunk-ADIKHOEG.js.map +0 -1
- package/dist/chunk-CVXS7IHA.js.map +0 -1
- package/dist/chunk-E2XOUDAH.js.map +0 -1
- package/dist/chunk-EJJDJJEM.js.map +0 -1
- package/dist/chunk-GDFYAUHT.mjs.map +0 -1
- package/dist/chunk-HI3JT6SI.mjs.map +0 -1
- package/dist/chunk-HPFJ2A24.js +0 -125
- package/dist/chunk-HPFJ2A24.js.map +0 -1
- package/dist/chunk-IIYQO6BL.js.map +0 -1
- package/dist/chunk-JDOXRLZW.js +0 -138
- package/dist/chunk-JDOXRLZW.js.map +0 -1
- package/dist/chunk-NLCKWF3Y.mjs +0 -88
- package/dist/chunk-NLCKWF3Y.mjs.map +0 -1
- package/dist/chunk-NUURPO3J.mjs +0 -120
- package/dist/chunk-NUURPO3J.mjs.map +0 -1
- package/dist/chunk-OCE4ODTM.mjs +0 -116
- package/dist/chunk-OCE4ODTM.mjs.map +0 -1
- package/dist/chunk-QI6TVWWF.js +0 -121
- package/dist/chunk-QI6TVWWF.js.map +0 -1
- package/dist/chunk-QSCJ2CER.mjs.map +0 -1
- package/dist/chunk-T4R2LSRL.js.map +0 -1
- package/dist/chunk-W6YOBPL5.js.map +0 -1
- package/dist/chunk-YBOTLQ3G.mjs +0 -99
- package/dist/chunk-YBOTLQ3G.mjs.map +0 -1
- package/dist/chunk-Z3FAKG3E.mjs.map +0 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkXMLBKK7X_js = require('./chunk-XMLBKK7X.js');
|
|
4
|
+
var chunkDPMUWQHL_js = require('./chunk-DPMUWQHL.js');
|
|
5
|
+
var chunkGLYGO7WX_js = require('./chunk-GLYGO7WX.js');
|
|
6
|
+
var chunkRQOTH7I7_js = require('./chunk-RQOTH7I7.js');
|
|
7
|
+
var chunkPASF6T4H_js = require('./chunk-PASF6T4H.js');
|
|
8
|
+
var React = require('react');
|
|
9
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
10
|
+
|
|
11
|
+
function _interopNamespace(e) {
|
|
12
|
+
if (e && e.__esModule) return e;
|
|
13
|
+
var n = Object.create(null);
|
|
14
|
+
if (e) {
|
|
15
|
+
Object.keys(e).forEach(function (k) {
|
|
16
|
+
if (k !== 'default') {
|
|
17
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
18
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return e[k]; }
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
n.default = e;
|
|
26
|
+
return Object.freeze(n);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
30
|
+
|
|
31
|
+
function initials(name) {
|
|
32
|
+
if (name.startsWith("+")) return name;
|
|
33
|
+
const parts = name.trim().split(/\s+/).filter(Boolean);
|
|
34
|
+
if (parts.length === 0) return "?";
|
|
35
|
+
if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();
|
|
36
|
+
return parts.slice(0, 2).map((p) => p[0]?.toUpperCase() ?? "").join("");
|
|
37
|
+
}
|
|
38
|
+
function Avatar({ src, alt, name, size = 32, shape = "circle", status, className, style, ...rest }) {
|
|
39
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
40
|
+
"span",
|
|
41
|
+
{
|
|
42
|
+
className: chunkPASF6T4H_js.cx("avatar", `avatar--${shape}`, className),
|
|
43
|
+
style: { width: size, height: size, fontSize: size * 0.42, ...style },
|
|
44
|
+
...rest,
|
|
45
|
+
children: [
|
|
46
|
+
src ? /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: alt ?? name ?? "" }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "avatar__initials", children: name ? initials(name) : "?" }),
|
|
47
|
+
status && /* @__PURE__ */ jsxRuntime.jsx("span", { className: chunkPASF6T4H_js.cx("avatar__status", `avatar__status--${status}`), "aria-label": status })
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
function AvatarGroup({ children, max = 4, size = 32, className }) {
|
|
53
|
+
const arr = React__namespace.Children.toArray(children);
|
|
54
|
+
const shown = arr.slice(0, max);
|
|
55
|
+
const overflow = arr.length - shown.length;
|
|
56
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkPASF6T4H_js.cx("avatar-group", className), children: [
|
|
57
|
+
shown.map((c, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: i === 0 ? 0 : -size * 0.3, zIndex: shown.length - i }, children: c }, i)),
|
|
58
|
+
overflow > 0 && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { name: `+${overflow}`, size, className: "avatar--overflow" })
|
|
59
|
+
] });
|
|
60
|
+
}
|
|
61
|
+
function Menu({ trigger, items, align = "start", className }) {
|
|
62
|
+
const [open, setOpen] = React__namespace.useState(false);
|
|
63
|
+
const [active, setActive] = React__namespace.useState(0);
|
|
64
|
+
const wrapRef = React__namespace.useRef(null);
|
|
65
|
+
const panelRef = React__namespace.useRef(null);
|
|
66
|
+
const itemRefs = React__namespace.useRef([]);
|
|
67
|
+
const enabledIdx = items.map((it, i) => "type" in it ? -1 : it.disabled ? -1 : i).filter((i) => i >= 0);
|
|
68
|
+
const pos = chunkDPMUWQHL_js.usePopoverPosition(wrapRef, panelRef, {
|
|
69
|
+
open,
|
|
70
|
+
side: "bottom",
|
|
71
|
+
align,
|
|
72
|
+
offset: 6
|
|
73
|
+
});
|
|
74
|
+
const focusTrigger = React__namespace.useCallback(() => {
|
|
75
|
+
wrapRef.current?.querySelector('[aria-haspopup="menu"]')?.focus();
|
|
76
|
+
}, []);
|
|
77
|
+
chunkXMLBKK7X_js.useDismiss({
|
|
78
|
+
open,
|
|
79
|
+
onDismiss: () => setOpen(false),
|
|
80
|
+
refs: [wrapRef, panelRef],
|
|
81
|
+
closeOnEscape: false
|
|
82
|
+
});
|
|
83
|
+
React__namespace.useEffect(() => {
|
|
84
|
+
if (open) setActive(0);
|
|
85
|
+
}, [open]);
|
|
86
|
+
React__namespace.useEffect(() => {
|
|
87
|
+
if (!open) return;
|
|
88
|
+
const realIdx = enabledIdx[active];
|
|
89
|
+
if (realIdx != null) itemRefs.current[realIdx]?.focus();
|
|
90
|
+
}, [open, active, enabledIdx]);
|
|
91
|
+
const select = (i) => {
|
|
92
|
+
const it = items[i];
|
|
93
|
+
if (!it || "type" in it || it.disabled) return;
|
|
94
|
+
it.onSelect?.();
|
|
95
|
+
setOpen(false);
|
|
96
|
+
focusTrigger();
|
|
97
|
+
};
|
|
98
|
+
const onPanelKeyDown = (e) => {
|
|
99
|
+
if (e.key === "Escape") {
|
|
100
|
+
e.preventDefault();
|
|
101
|
+
setOpen(false);
|
|
102
|
+
focusTrigger();
|
|
103
|
+
} else if (e.key === "Tab") {
|
|
104
|
+
setOpen(false);
|
|
105
|
+
} else if (e.key === "ArrowDown") {
|
|
106
|
+
e.preventDefault();
|
|
107
|
+
setActive((a) => Math.min(a + 1, enabledIdx.length - 1));
|
|
108
|
+
} else if (e.key === "ArrowUp") {
|
|
109
|
+
e.preventDefault();
|
|
110
|
+
setActive((a) => Math.max(a - 1, 0));
|
|
111
|
+
} else if (e.key === "Home") {
|
|
112
|
+
e.preventDefault();
|
|
113
|
+
setActive(0);
|
|
114
|
+
} else if (e.key === "End") {
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
setActive(Math.max(enabledIdx.length - 1, 0));
|
|
117
|
+
} else if (e.key === "Enter" || e.key === " ") {
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
const realIdx = enabledIdx[active];
|
|
120
|
+
if (realIdx != null) select(realIdx);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const triggerEl = React__namespace.cloneElement(trigger, {
|
|
124
|
+
onClick: (e) => {
|
|
125
|
+
trigger.props.onClick?.(e);
|
|
126
|
+
setOpen((o) => !o);
|
|
127
|
+
},
|
|
128
|
+
onKeyDown: (e) => {
|
|
129
|
+
trigger.props.onKeyDown?.(e);
|
|
130
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
131
|
+
e.preventDefault();
|
|
132
|
+
setOpen(true);
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"aria-haspopup": "menu",
|
|
136
|
+
"aria-expanded": open
|
|
137
|
+
});
|
|
138
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { ref: wrapRef, className: chunkPASF6T4H_js.cx("menu", className), style: { display: "inline-block" }, children: [
|
|
139
|
+
triggerEl,
|
|
140
|
+
open && /* @__PURE__ */ jsxRuntime.jsx(chunkGLYGO7WX_js.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
141
|
+
"div",
|
|
142
|
+
{
|
|
143
|
+
ref: panelRef,
|
|
144
|
+
role: "menu",
|
|
145
|
+
className: "menu__panel",
|
|
146
|
+
onKeyDown: onPanelKeyDown,
|
|
147
|
+
style: {
|
|
148
|
+
position: "absolute",
|
|
149
|
+
top: pos.top,
|
|
150
|
+
left: pos.left,
|
|
151
|
+
visibility: pos.ready ? "visible" : "hidden"
|
|
152
|
+
},
|
|
153
|
+
children: items.map((it, i) => {
|
|
154
|
+
if ("type" in it && it.type === "separator") return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "menu__sep", role: "separator" }, i);
|
|
155
|
+
if ("type" in it && it.type === "label") return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "menu__label", children: it.label }, i);
|
|
156
|
+
const item = it;
|
|
157
|
+
const isActive = enabledIdx[active] === i;
|
|
158
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
159
|
+
"button",
|
|
160
|
+
{
|
|
161
|
+
ref: (el) => {
|
|
162
|
+
itemRefs.current[i] = el;
|
|
163
|
+
},
|
|
164
|
+
type: "button",
|
|
165
|
+
role: "menuitem",
|
|
166
|
+
tabIndex: isActive ? 0 : -1,
|
|
167
|
+
disabled: item.disabled,
|
|
168
|
+
className: chunkPASF6T4H_js.cx("menu__item", isActive && "is-active", item.destructive && "is-destructive"),
|
|
169
|
+
onMouseEnter: () => setActive(enabledIdx.indexOf(i)),
|
|
170
|
+
onClick: () => select(i),
|
|
171
|
+
children: [
|
|
172
|
+
item.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "menu__icon", "aria-hidden": "true", children: item.icon }),
|
|
173
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "menu__body", children: [
|
|
174
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "menu__label-row", children: [
|
|
175
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label }),
|
|
176
|
+
item.shortcut && /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: "menu__kbd", children: item.shortcut })
|
|
177
|
+
] }),
|
|
178
|
+
item.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "menu__desc", children: item.description })
|
|
179
|
+
] })
|
|
180
|
+
]
|
|
181
|
+
},
|
|
182
|
+
i
|
|
183
|
+
);
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
) })
|
|
187
|
+
] });
|
|
188
|
+
}
|
|
189
|
+
function Stat({ label, value, hint, trend, align = "start", className }) {
|
|
190
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkPASF6T4H_js.cx("stat", `stat--${align}`, className), children: [
|
|
191
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "stat__label", children: label }),
|
|
192
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "stat__value", children: value }),
|
|
193
|
+
(hint || trend) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "stat__foot", children: [
|
|
194
|
+
trend && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: chunkPASF6T4H_js.cx("stat__trend", `stat__trend--${trend.dir}`), children: [
|
|
195
|
+
trend.dir === "up" ? /* @__PURE__ */ jsxRuntime.jsx(chunkRQOTH7I7_js.ChevronUp, { size: 12 }) : trend.dir === "down" ? /* @__PURE__ */ jsxRuntime.jsx(chunkRQOTH7I7_js.ChevronDown, { size: 12 }) : "\u2013",
|
|
196
|
+
" ",
|
|
197
|
+
trend.value
|
|
198
|
+
] }),
|
|
199
|
+
hint && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "stat__hint", children: hint })
|
|
200
|
+
] })
|
|
201
|
+
] });
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
exports.Avatar = Avatar;
|
|
205
|
+
exports.AvatarGroup = AvatarGroup;
|
|
206
|
+
exports.Menu = Menu;
|
|
207
|
+
exports.Stat = Stat;
|
|
208
|
+
//# sourceMappingURL=chunk-2S6JJYN7.js.map
|
|
209
|
+
//# sourceMappingURL=chunk-2S6JJYN7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Display2.tsx"],"names":["jsxs","cx","jsx","React","usePopoverPosition","useDismiss","Portal","ChevronUp","ChevronDown"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,SAAS,SAAS,IAAA,EAAc;AAC9B,EAAA,IAAI,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG,OAAO,IAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,KAAK,IAAA,EAAK,CAAE,MAAM,KAAK,CAAA,CAAE,OAAO,OAAO,CAAA;AACrD,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,GAAA;AAC/B,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,KAAA,CAAM,CAAC,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,WAAA,EAAY;AAChE,EAAA,OAAO,MAAM,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA,CAAE,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,GAAG,WAAA,EAAY,IAAK,EAAE,CAAA,CAAE,KAAK,EAAE,CAAA;AACxE;AAEO,SAAS,MAAA,CAAO,EAAE,GAAA,EAAK,GAAA,EAAK,MAAM,IAAA,GAAO,EAAA,EAAI,KAAA,GAAQ,QAAA,EAAU,MAAA,EAAQ,SAAA,EAAW,KAAA,EAAO,GAAG,MAAK,EAAgB;AACtH,EAAA,uBACEA,eAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,WAAWC,mBAAA,CAAG,QAAA,EAAU,CAAA,QAAA,EAAW,KAAK,IAAI,SAAS,CAAA;AAAA,MACrD,KAAA,EAAO,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,MAAM,QAAA,EAAU,IAAA,GAAO,IAAA,EAAM,GAAG,KAAA,EAAM;AAAA,MACnE,GAAG,IAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,GAAA,kCACE,KAAA,EAAA,EAAI,GAAA,EAAU,GAAA,EAAK,GAAA,IAAO,QAAQ,EAAA,EAAI,CAAA,mBAEvCC,cAAA,CAAC,MAAA,EAAA,EAAK,WAAU,kBAAA,EAAoB,QAAA,EAAA,IAAA,GAAO,QAAA,CAAS,IAAI,IAAI,GAAA,EAAI,CAAA;AAAA,QAEjE,MAAA,oBAAUA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAWD,mBAAA,CAAG,gBAAA,EAAkB,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAE,CAAA,EAAG,YAAA,EAAY,MAAA,EAAQ;AAAA;AAAA;AAAA,GACrG;AAEJ;AASO,SAAS,WAAA,CAAY,EAAE,QAAA,EAAU,GAAA,GAAM,GAAG,IAAA,GAAO,EAAA,EAAI,WAAU,EAAqB;AACzF,EAAA,MAAM,GAAA,GAAYE,gBAAA,CAAA,QAAA,CAAS,OAAA,CAAQ,QAAQ,CAAA;AAC3C,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,CAAM,CAAA,EAAG,GAAG,CAAA;AAC9B,EAAA,MAAM,QAAA,GAAW,GAAA,CAAI,MAAA,GAAS,KAAA,CAAM,MAAA;AACpC,EAAA,uCACG,KAAA,EAAA,EAAI,SAAA,EAAWF,mBAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EACzC,QAAA,EAAA;AAAA,IAAA,KAAA,CAAM,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,oCAAO,MAAA,EAAA,EAAa,KAAA,EAAO,EAAE,UAAA,EAAY,CAAA,KAAM,CAAA,GAAI,IAAI,CAAC,IAAA,GAAO,KAAK,MAAA,EAAQ,KAAA,CAAM,SAAS,CAAA,EAAE,EAAI,QAAA,EAAA,CAAA,EAAA,EAAhF,CAAkF,CAAO,CAAA;AAAA,IACxH,QAAA,GAAW,CAAA,oBACVC,cAAA,CAAC,MAAA,EAAA,EAAO,IAAA,EAAM,IAAI,QAAQ,CAAA,CAAA,EAAI,IAAA,EAAY,SAAA,EAAU,kBAAA,EAAmB;AAAA,GAAA,EAE3E,CAAA;AAEJ;AAoBO,SAAS,KAAK,EAAE,OAAA,EAAS,OAAO,KAAA,GAAQ,OAAA,EAAS,WAAU,EAAc;AAC9E,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAUC,0BAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAUA,0BAAS,CAAC,CAAA;AAC5C,EAAA,MAAM,OAAA,GAAgBA,wBAAwB,IAAI,CAAA;AAClD,EAAA,MAAM,QAAA,GAAiBA,wBAAuB,IAAI,CAAA;AAClD,EAAA,MAAM,QAAA,GAAiBA,gBAAA,CAAA,MAAA,CAAwC,EAAE,CAAA;AAIjE,EAAA,MAAM,aAAa,KAAA,CAChB,GAAA,CAAI,CAAC,EAAA,EAAI,CAAA,KAAO,UAAU,EAAA,GAAK,EAAA,GAAK,EAAA,CAAG,QAAA,GAAW,KAAK,CAAE,CAAA,CACzD,OAAO,CAAC,CAAA,KAAM,KAAK,CAAC,CAAA;AAEvB,EAAA,MAAM,GAAA,GAAMC,mCAAA,CAAmB,OAAA,EAAS,QAAA,EAAU;AAAA,IAChD,IAAA;AAAA,IACA,IAAA,EAAM,QAAA;AAAA,IACN,KAAA;AAAA,IACA,MAAA,EAAQ;AAAA,GACT,CAAA;AAED,EAAA,MAAM,YAAA,GAAqBD,6BAAY,MAAM;AAC3C,IAAA,OAAA,CAAQ,OAAA,EAAS,aAAA,CAA2B,wBAAwB,CAAA,EAAG,KAAA,EAAM;AAAA,EAC/E,CAAA,EAAG,EAAE,CAAA;AAIL,EAAAE,2BAAA,CAAW;AAAA,IACT,IAAA;AAAA,IACA,SAAA,EAAW,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,OAAA,EAAS,QAAQ,CAAA;AAAA,IACxB,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAMF,2BAAU,MAAM;AACpB,IAAA,IAAI,IAAA,YAAgB,CAAC,CAAA;AAAA,EACvB,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAMA,2BAAU,MAAM;AACpB,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,OAAA,GAAU,WAAW,MAAM,CAAA;AACjC,IAAA,IAAI,WAAW,IAAA,EAAM,QAAA,CAAS,OAAA,CAAQ,OAAO,GAAG,KAAA,EAAM;AAAA,EACxD,CAAA,EAAG,CAAC,IAAA,EAAM,MAAA,EAAQ,UAAU,CAAC,CAAA;AAE7B,EAAA,MAAM,MAAA,GAAS,CAAC,CAAA,KAAc;AAC5B,IAAA,MAAM,EAAA,GAAK,MAAM,CAAC,CAAA;AAClB,IAAA,IAAI,CAAC,EAAA,IAAM,MAAA,IAAU,EAAA,IAAM,GAAG,QAAA,EAAU;AACxC,IAAA,EAAA,CAAG,QAAA,IAAW;AACd,IAAA,OAAA,CAAQ,KAAK,CAAA;AACb,IAAA,YAAA,EAAa;AAAA,EACf,CAAA;AAEA,EAAA,MAAM,cAAA,GAAiB,CAAC,CAAA,KAA2B;AACjD,IAAA,IAAI,CAAA,CAAE,QAAQ,QAAA,EAAU;AACtB,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,OAAA,CAAQ,KAAK,CAAA;AACb,MAAA,YAAA,EAAa;AAAA,IACf,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,KAAA,EAAO;AAC1B,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,WAAA,EAAa;AAChC,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,SAAA,CAAU,CAAC,MAAM,IAAA,CAAK,GAAA,CAAI,IAAI,CAAA,EAAG,UAAA,CAAW,MAAA,GAAS,CAAC,CAAC,CAAA;AAAA,IACzD,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,SAAA,EAAW;AAC9B,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,SAAA,CAAU,CAAC,CAAA,KAAM,IAAA,CAAK,IAAI,CAAA,GAAI,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IACrC,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,MAAA,EAAQ;AAC3B,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,SAAA,CAAU,CAAC,CAAA;AAAA,IACb,CAAA,MAAA,IAAW,CAAA,CAAE,GAAA,KAAQ,KAAA,EAAO;AAC1B,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,SAAA,CAAU,KAAK,GAAA,CAAI,UAAA,CAAW,MAAA,GAAS,CAAA,EAAG,CAAC,CAAC,CAAA;AAAA,IAC9C,WAAW,CAAA,CAAE,GAAA,KAAQ,OAAA,IAAW,CAAA,CAAE,QAAQ,GAAA,EAAK;AAC7C,MAAA,CAAA,CAAE,cAAA,EAAe;AACjB,MAAA,MAAM,OAAA,GAAU,WAAW,MAAM,CAAA;AACjC,MAAA,IAAI,OAAA,IAAW,IAAA,EAAM,MAAA,CAAO,OAAO,CAAA;AAAA,IACrC;AAAA,EACF,CAAA;AAEA,EAAA,MAAM,SAAA,GAAkBA,8BAAa,OAAA,EAAS;AAAA,IAC5C,OAAA,EAAS,CAAC,CAAA,KAAwB;AAChC,MAAA,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAC,CAAA;AACzB,MAAA,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,IACnB,CAAA;AAAA,IACA,SAAA,EAAW,CAAC,CAAA,KAA2B;AACrC,MAAA,OAAA,CAAQ,KAAA,CAAM,YAAY,CAAC,CAAA;AAC3B,MAAA,IAAI,CAAA,CAAE,QAAQ,WAAA,IAAe,CAAA,CAAE,QAAQ,OAAA,IAAW,CAAA,CAAE,QAAQ,GAAA,EAAK;AAC/D,QAAA,CAAA,CAAE,cAAA,EAAe;AACjB,QAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,MACd;AAAA,IACF,CAAA;AAAA,IACA,eAAA,EAAiB,MAAA;AAAA,IACjB,eAAA,EAAiB;AAAA,GAClB,CAAA;AAED,EAAA,uBACEH,eAAA,CAAC,MAAA,EAAA,EAAK,GAAA,EAAK,OAAA,EAAS,SAAA,EAAWC,mBAAA,CAAG,MAAA,EAAQ,SAAS,CAAA,EAAG,KAAA,EAAO,EAAE,OAAA,EAAS,gBAAe,EACpF,QAAA,EAAA;AAAA,IAAA,SAAA;AAAA,IACA,IAAA,mCACEK,uBAAA,EAAA,EACC,QAAA,kBAAAJ,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,QAAA;AAAA,QACL,IAAA,EAAK,MAAA;AAAA,QACL,SAAA,EAAU,aAAA;AAAA,QACV,SAAA,EAAW,cAAA;AAAA,QACX,KAAA,EAAO;AAAA,UACL,QAAA,EAAU,UAAA;AAAA,UACV,KAAK,GAAA,CAAI,GAAA;AAAA,UACT,MAAM,GAAA,CAAI,IAAA;AAAA,UACV,UAAA,EAAY,GAAA,CAAI,KAAA,GAAQ,SAAA,GAAY;AAAA,SACtC;AAAA,QAEC,QAAA,EAAA,KAAA,CAAM,GAAA,CAAI,CAAC,EAAA,EAAI,CAAA,KAAM;AACpB,UAAA,IAAI,MAAA,IAAU,EAAA,IAAM,EAAA,CAAG,IAAA,KAAS,WAAA,EAAa,uBAAOA,cAAA,CAAC,KAAA,EAAA,EAAY,SAAA,EAAU,WAAA,EAAY,IAAA,EAAK,WAAA,EAAA,EAA9B,CAA0C,CAAA;AACxG,UAAA,IAAI,MAAA,IAAU,EAAA,IAAM,EAAA,CAAG,IAAA,KAAS,OAAA,EAAS,uBAAOA,cAAA,CAAC,KAAA,EAAA,EAAY,SAAA,EAAU,aAAA,EAAe,QAAA,EAAA,EAAA,CAAG,KAAA,EAAA,EAA/B,CAAqC,CAAA;AAC/F,UAAA,MAAM,IAAA,GAAO,EAAA;AACb,UAAA,MAAM,QAAA,GAAW,UAAA,CAAW,MAAM,CAAA,KAAM,CAAA;AACxC,UAAA,uBACEF,eAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,GAAA,EAAK,CAAC,EAAA,KAAO;AAAE,gBAAA,QAAA,CAAS,OAAA,CAAQ,CAAC,CAAA,GAAI,EAAA;AAAA,cAAI,CAAA;AAAA,cACzC,IAAA,EAAK,QAAA;AAAA,cACL,IAAA,EAAK,UAAA;AAAA,cACL,QAAA,EAAU,WAAW,CAAA,GAAI,EAAA;AAAA,cACzB,UAAU,IAAA,CAAK,QAAA;AAAA,cACf,WAAWC,mBAAA,CAAG,YAAA,EAAc,YAAY,WAAA,EAAa,IAAA,CAAK,eAAe,gBAAgB,CAAA;AAAA,cACzF,cAAc,MAAM,SAAA,CAAU,UAAA,CAAW,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,cACnD,OAAA,EAAS,MAAM,MAAA,CAAO,CAAC,CAAA;AAAA,cAEtB,QAAA,EAAA;AAAA,gBAAA,IAAA,CAAK,IAAA,mCAAS,MAAA,EAAA,EAAK,SAAA,EAAU,cAAa,aAAA,EAAY,MAAA,EAAQ,eAAK,IAAA,EAAK,CAAA;AAAA,gCACzED,eAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EACd,QAAA,EAAA;AAAA,kCAAAA,eAAA,CAAC,MAAA,EAAA,EAAK,WAAU,iBAAA,EACd,QAAA,EAAA;AAAA,oCAAAE,cAAA,CAAC,MAAA,EAAA,EAAM,eAAK,KAAA,EAAM,CAAA;AAAA,oBACjB,KAAK,QAAA,oBAAYA,cAAA,CAAC,SAAI,SAAA,EAAU,WAAA,EAAa,eAAK,QAAA,EAAS;AAAA,mBAAA,EAC9D,CAAA;AAAA,kBACC,KAAK,WAAA,oBAAeA,cAAA,CAAC,UAAK,SAAA,EAAU,YAAA,EAAc,eAAK,WAAA,EAAY;AAAA,iBAAA,EACtE;AAAA;AAAA,aAAA;AAAA,YAjBK;AAAA,WAkBP;AAAA,QAEJ,CAAC;AAAA;AAAA,KACH,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAYO,SAAS,IAAA,CAAK,EAAE,KAAA,EAAO,KAAA,EAAO,MAAM,KAAA,EAAO,KAAA,GAAQ,OAAA,EAAS,SAAA,EAAU,EAAc;AACzF,EAAA,uBACEF,eAAA,CAAC,SAAI,SAAA,EAAWC,mBAAA,CAAG,QAAQ,CAAA,MAAA,EAAS,KAAK,CAAA,CAAA,EAAI,SAAS,CAAA,EACpD,QAAA,EAAA;AAAA,oBAAAC,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EAAe,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,oBACrCA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,aAAA,EAAe,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,IAAA,CACnC,IAAA,IAAQ,KAAA,qBACRF,eAAA,CAAC,MAAA,EAAA,EAAK,WAAU,YAAA,EACb,QAAA,EAAA;AAAA,MAAA,KAAA,oBACCA,eAAA,CAAC,UAAK,SAAA,EAAWC,mBAAA,CAAG,eAAe,CAAA,aAAA,EAAgB,KAAA,CAAM,GAAG,CAAA,CAAE,CAAA,EAC3D,QAAA,EAAA;AAAA,QAAA,KAAA,CAAM,GAAA,KAAQ,IAAA,mBAAOC,cAAA,CAACK,0BAAA,EAAA,EAAU,MAAM,EAAA,EAAI,CAAA,GAAK,KAAA,CAAM,GAAA,KAAQ,MAAA,mBAASL,cAAA,CAACM,4BAAA,EAAA,EAAY,IAAA,EAAM,IAAI,CAAA,GAAK,QAAA;AAAA,QAAI,GAAA;AAAA,QAAE,KAAA,CAAM;AAAA,OAAA,EACjH,CAAA;AAAA,MAED,IAAA,oBAAQN,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,cAAc,QAAA,EAAA,IAAA,EAAK;AAAA,KAAA,EAC9C;AAAA,GAAA,EAEJ,CAAA;AAEJ","file":"chunk-2S6JJYN7.js","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { ChevronUp, ChevronDown } from './Icons';\nimport { Portal } from './Portal';\nimport { usePopoverPosition } from '../hooks/usePopoverPosition';\nimport { useDismiss } from '../hooks/useDismiss';\n\n// ---------- Avatar ------------------------------------------------------\nexport interface AvatarProps extends React.HTMLAttributes<HTMLSpanElement> {\n src?: string;\n alt?: string;\n name?: string; // for initials fallback\n size?: 24 | 32 | 40 | 48 | 64;\n shape?: 'circle' | 'square';\n status?: 'online' | 'offline' | 'busy';\n}\n\nfunction initials(name: string) {\n if (name.startsWith('+')) return name;\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '?';\n if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase();\n return parts.slice(0, 2).map((p) => p[0]?.toUpperCase() ?? '').join('');\n}\n\nexport function Avatar({ src, alt, name, size = 32, shape = 'circle', status, className, style, ...rest }: AvatarProps) {\n return (\n <span\n className={cx('avatar', `avatar--${shape}`, className)}\n style={{ width: size, height: size, fontSize: size * 0.42, ...style }}\n {...rest}\n >\n {src ? (\n <img src={src} alt={alt ?? name ?? ''} />\n ) : (\n <span className=\"avatar__initials\">{name ? initials(name) : '?'}</span>\n )}\n {status && <span className={cx('avatar__status', `avatar__status--${status}`)} aria-label={status} />}\n </span>\n );\n}\n\nexport interface AvatarGroupProps {\n children: React.ReactNode;\n max?: number;\n size?: AvatarProps['size'];\n className?: string;\n}\n\nexport function AvatarGroup({ children, max = 4, size = 32, className }: AvatarGroupProps) {\n const arr = React.Children.toArray(children);\n const shown = arr.slice(0, max);\n const overflow = arr.length - shown.length;\n return (\n <div className={cx('avatar-group', className)}>\n {shown.map((c, i) => <span key={i} style={{ marginLeft: i === 0 ? 0 : -size * 0.3, zIndex: shown.length - i }}>{c}</span>)}\n {overflow > 0 && (\n <Avatar name={`+${overflow}`} size={size} className=\"avatar--overflow\" />\n )}\n </div>\n );\n}\n\n// ---------- Menu (dropdown) accesible -----------------------------------\nexport interface MenuItemProps {\n label: React.ReactNode;\n icon?: React.ReactNode;\n description?: React.ReactNode;\n onSelect?: () => void;\n disabled?: boolean;\n destructive?: boolean;\n shortcut?: string;\n}\n\nexport interface MenuProps {\n trigger: React.ReactElement;\n items: Array<MenuItemProps | { type: 'separator' } | { type: 'label'; label: React.ReactNode }>;\n align?: 'start' | 'end';\n className?: string;\n}\n\nexport function Menu({ trigger, items, align = 'start', className }: MenuProps) {\n const [open, setOpen] = React.useState(false);\n const [active, setActive] = React.useState(0);\n const wrapRef = React.useRef<HTMLSpanElement>(null);\n const panelRef = React.useRef<HTMLDivElement>(null);\n const itemRefs = React.useRef<Array<HTMLButtonElement | null>>([]);\n\n // Positions within `items` that are focusable menu items (no\n // separators/labels/disabled). `active` indexes into this list.\n const enabledIdx = items\n .map((it, i) => ('type' in it ? -1 : it.disabled ? -1 : i))\n .filter((i) => i >= 0);\n\n const pos = usePopoverPosition(wrapRef, panelRef, {\n open,\n side: 'bottom',\n align,\n offset: 6,\n });\n\n const focusTrigger = React.useCallback(() => {\n wrapRef.current?.querySelector<HTMLElement>('[aria-haspopup=\"menu\"]')?.focus();\n }, []);\n\n // Outside-click closes; Escape is handled on the panel so it can also\n // return focus to the trigger (WAI-ARIA menu button pattern).\n useDismiss({\n open,\n onDismiss: () => setOpen(false),\n refs: [wrapRef, panelRef],\n closeOnEscape: false,\n });\n\n React.useEffect(() => {\n if (open) setActive(0);\n }, [open]);\n\n React.useEffect(() => {\n if (!open) return;\n const realIdx = enabledIdx[active];\n if (realIdx != null) itemRefs.current[realIdx]?.focus();\n }, [open, active, enabledIdx]);\n\n const select = (i: number) => {\n const it = items[i];\n if (!it || 'type' in it || it.disabled) return;\n it.onSelect?.();\n setOpen(false);\n focusTrigger();\n };\n\n const onPanelKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.preventDefault();\n setOpen(false);\n focusTrigger();\n } else if (e.key === 'Tab') {\n setOpen(false);\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n setActive((a) => Math.min(a + 1, enabledIdx.length - 1));\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setActive((a) => Math.max(a - 1, 0));\n } else if (e.key === 'Home') {\n e.preventDefault();\n setActive(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n setActive(Math.max(enabledIdx.length - 1, 0));\n } else if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n const realIdx = enabledIdx[active];\n if (realIdx != null) select(realIdx);\n }\n };\n\n const triggerEl = React.cloneElement(trigger, {\n onClick: (e: React.MouseEvent) => {\n trigger.props.onClick?.(e);\n setOpen((o) => !o);\n },\n onKeyDown: (e: React.KeyboardEvent) => {\n trigger.props.onKeyDown?.(e);\n if (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setOpen(true);\n }\n },\n 'aria-haspopup': 'menu',\n 'aria-expanded': open,\n });\n\n return (\n <span ref={wrapRef} className={cx('menu', className)} style={{ display: 'inline-block' }}>\n {triggerEl}\n {open && (\n <Portal>\n <div\n ref={panelRef}\n role=\"menu\"\n className=\"menu__panel\"\n onKeyDown={onPanelKeyDown}\n style={{\n position: 'absolute',\n top: pos.top,\n left: pos.left,\n visibility: pos.ready ? 'visible' : 'hidden',\n }}\n >\n {items.map((it, i) => {\n if ('type' in it && it.type === 'separator') return <div key={i} className=\"menu__sep\" role=\"separator\" />;\n if ('type' in it && it.type === 'label') return <div key={i} className=\"menu__label\">{it.label}</div>;\n const item = it as MenuItemProps;\n const isActive = enabledIdx[active] === i;\n return (\n <button\n key={i}\n ref={(el) => { itemRefs.current[i] = el; }}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={isActive ? 0 : -1}\n disabled={item.disabled}\n className={cx('menu__item', isActive && 'is-active', item.destructive && 'is-destructive')}\n onMouseEnter={() => setActive(enabledIdx.indexOf(i))}\n onClick={() => select(i)}\n >\n {item.icon && <span className=\"menu__icon\" aria-hidden=\"true\">{item.icon}</span>}\n <span className=\"menu__body\">\n <span className=\"menu__label-row\">\n <span>{item.label}</span>\n {item.shortcut && <kbd className=\"menu__kbd\">{item.shortcut}</kbd>}\n </span>\n {item.description && <span className=\"menu__desc\">{item.description}</span>}\n </span>\n </button>\n );\n })}\n </div>\n </Portal>\n )}\n </span>\n );\n}\n\n// ---------- Stat / MiniStat ---------------------------------------------\nexport interface StatProps {\n label: React.ReactNode;\n value: React.ReactNode;\n hint?: React.ReactNode;\n trend?: { dir: 'up' | 'down' | 'flat'; value: string };\n align?: 'start' | 'center';\n className?: string;\n}\n\nexport function Stat({ label, value, hint, trend, align = 'start', className }: StatProps) {\n return (\n <div className={cx('stat', `stat--${align}`, className)}>\n <span className=\"stat__label\">{label}</span>\n <span className=\"stat__value\">{value}</span>\n {(hint || trend) && (\n <span className=\"stat__foot\">\n {trend && (\n <span className={cx('stat__trend', `stat__trend--${trend.dir}`)}>\n {trend.dir === 'up' ? <ChevronUp size={12} /> : trend.dir === 'down' ? <ChevronDown size={12} /> : '–'} {trend.value}\n </span>\n )}\n {hint && <span className=\"stat__hint\">{hint}</span>}\n </span>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -1,32 +1,14 @@
|
|
|
1
|
+
import { useDelayedUnmount } from './chunk-XXUSZD5I.mjs';
|
|
1
2
|
import { useLocale } from './chunk-ZRFSTYRL.mjs';
|
|
2
3
|
import { X } from './chunk-CIBJKJV3.mjs';
|
|
3
4
|
import { cx } from './chunk-IEPCH3JB.mjs';
|
|
4
|
-
import * as
|
|
5
|
+
import * as React from 'react';
|
|
5
6
|
import { createPortal } from 'react-dom';
|
|
6
7
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
8
|
|
|
8
|
-
function useDelayedUnmount(open, durationMs) {
|
|
9
|
-
const [mounted, setMounted] = React2.useState(open);
|
|
10
|
-
const [closing, setClosing] = React2.useState(false);
|
|
11
|
-
React2.useEffect(() => {
|
|
12
|
-
if (open) {
|
|
13
|
-
setMounted(true);
|
|
14
|
-
setClosing(false);
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
if (!mounted) return;
|
|
18
|
-
setClosing(true);
|
|
19
|
-
const handle = setTimeout(() => {
|
|
20
|
-
setMounted(false);
|
|
21
|
-
setClosing(false);
|
|
22
|
-
}, durationMs);
|
|
23
|
-
return () => clearTimeout(handle);
|
|
24
|
-
}, [open, durationMs, mounted]);
|
|
25
|
-
return { mounted, closing };
|
|
26
|
-
}
|
|
27
9
|
var EXIT_MS = 200;
|
|
28
10
|
function useEscape(active, onClose, enabled) {
|
|
29
|
-
|
|
11
|
+
React.useEffect(() => {
|
|
30
12
|
if (typeof document === "undefined") return;
|
|
31
13
|
if (!active || !enabled) return;
|
|
32
14
|
const onKey = (e) => {
|
|
@@ -37,7 +19,7 @@ function useEscape(active, onClose, enabled) {
|
|
|
37
19
|
}, [active, enabled, onClose]);
|
|
38
20
|
}
|
|
39
21
|
function useFocusTrap(ref, active) {
|
|
40
|
-
|
|
22
|
+
React.useEffect(() => {
|
|
41
23
|
if (typeof document === "undefined") return;
|
|
42
24
|
if (!active || !ref.current) return;
|
|
43
25
|
const node = ref.current;
|
|
@@ -72,7 +54,7 @@ function useFocusTrap(ref, active) {
|
|
|
72
54
|
var scrollLockCount = 0;
|
|
73
55
|
var originalOverflow = "";
|
|
74
56
|
function useScrollLock(active) {
|
|
75
|
-
|
|
57
|
+
React.useEffect(() => {
|
|
76
58
|
if (typeof document === "undefined") return;
|
|
77
59
|
if (!active) return;
|
|
78
60
|
if (scrollLockCount === 0) {
|
|
@@ -99,8 +81,8 @@ function Modal({
|
|
|
99
81
|
closeOnEsc = true,
|
|
100
82
|
className
|
|
101
83
|
}) {
|
|
102
|
-
const ref =
|
|
103
|
-
const titleId =
|
|
84
|
+
const ref = React.useRef(null);
|
|
85
|
+
const titleId = React.useId();
|
|
104
86
|
const t = useLocale();
|
|
105
87
|
const { mounted, closing } = useDelayedUnmount(open, EXIT_MS);
|
|
106
88
|
useEscape(open, onClose, closeOnEsc);
|
|
@@ -148,8 +130,8 @@ function Drawer({
|
|
|
148
130
|
closeOnEsc = true,
|
|
149
131
|
className
|
|
150
132
|
}) {
|
|
151
|
-
const ref =
|
|
152
|
-
const titleId =
|
|
133
|
+
const ref = React.useRef(null);
|
|
134
|
+
const titleId = React.useId();
|
|
153
135
|
const t = useLocale();
|
|
154
136
|
const { mounted, closing } = useDelayedUnmount(open, EXIT_MS);
|
|
155
137
|
useEscape(open, onClose, closeOnEsc);
|
|
@@ -188,5 +170,5 @@ function Drawer({
|
|
|
188
170
|
}
|
|
189
171
|
|
|
190
172
|
export { Drawer, Modal };
|
|
191
|
-
//# sourceMappingURL=chunk-
|
|
192
|
-
//# sourceMappingURL=chunk-
|
|
173
|
+
//# sourceMappingURL=chunk-3N4IBCLW.mjs.map
|
|
174
|
+
//# sourceMappingURL=chunk-3N4IBCLW.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Overlay.tsx"],"names":[],"mappings":"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","file":"chunk-3N4IBCLW.mjs","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { cx } from '../utils/cx';\nimport { X } from './Icons';\nimport { useLocale } from '../locale/LocaleProvider';\nimport { useDelayedUnmount } from '../hooks/useDelayedUnmount';\n\n// Exit animation duration in ms. Must match the `is-closing` keyframes\n// in src/styles/index.css (`.modal-backdrop`, `.drawer-backdrop`).\nconst EXIT_MS = 200;\n\nexport interface OverlayProps {\n open: boolean;\n onClose: () => void;\n title?: React.ReactNode;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n size?: 'sm' | 'md' | 'lg';\n closeOnBackdrop?: boolean;\n closeOnEsc?: boolean;\n className?: string;\n}\n\nfunction useEscape(active: boolean, onClose: () => void, enabled: boolean) {\n React.useEffect(() => {\n if (typeof document === 'undefined') return;\n if (!active || !enabled) return;\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n document.addEventListener('keydown', onKey);\n return () => document.removeEventListener('keydown', onKey);\n }, [active, enabled, onClose]);\n}\n\nfunction useFocusTrap(ref: React.RefObject<HTMLElement>, active: boolean) {\n React.useEffect(() => {\n if (typeof document === 'undefined') return;\n if (!active || !ref.current) return;\n const node = ref.current;\n const previously = document.activeElement as HTMLElement | null;\n const focusables = () =>\n Array.from(\n node.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])'\n )\n );\n const first = focusables()[0];\n first?.focus();\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n const list = focusables();\n if (list.length === 0) return;\n const f = list[0], l = list[list.length - 1];\n if (e.shiftKey && document.activeElement === f) {\n e.preventDefault(); l.focus();\n } else if (!e.shiftKey && document.activeElement === l) {\n e.preventDefault(); f.focus();\n }\n };\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('keydown', onKey);\n previously?.focus?.();\n };\n }, [active, ref]);\n}\n\n// Lock body scroll while any overlay is open. Stacked overlays share a single\n// counter so closing the inner one doesn't release the lock for the outer one.\nlet scrollLockCount = 0;\nlet originalOverflow = '';\nfunction useScrollLock(active: boolean) {\n React.useEffect(() => {\n if (typeof document === 'undefined') return;\n if (!active) return;\n if (scrollLockCount === 0) {\n originalOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n }\n scrollLockCount++;\n return () => {\n scrollLockCount--;\n if (scrollLockCount === 0) {\n document.body.style.overflow = originalOverflow;\n }\n };\n }, [active]);\n}\n\nexport function Modal({\n open, onClose, title, children, footer, size = 'md',\n closeOnBackdrop = true, closeOnEsc = true, className,\n}: OverlayProps) {\n const ref = React.useRef<HTMLDivElement>(null);\n const titleId = React.useId();\n const t = useLocale();\n // useDelayedUnmount keeps the DOM mounted during exit animation. The\n // a11y/scroll-lock hooks still consume `open` (the user's intent), not\n // `mounted` — we don't want to trap focus or block scroll while\n // animating out.\n const { mounted, closing } = useDelayedUnmount(open, EXIT_MS);\n useEscape(open, onClose, closeOnEsc);\n useFocusTrap(ref, open);\n useScrollLock(open);\n if (!mounted || typeof document === 'undefined') return null;\n return createPortal(\n <div\n className={cx('modal-backdrop', closing && 'is-closing')}\n onClick={() => closeOnBackdrop && onClose()}\n >\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n className={cx('modal', `modal--${size}`, closing && 'is-closing', className)}\n onClick={(e) => e.stopPropagation()}\n >\n {title && (\n <div className=\"modal__header\">\n <div id={titleId} className=\"modal__title\">{title}</div>\n <button type=\"button\" className=\"modal__close\" onClick={onClose} aria-label={t['modal.close']}><X size={18} /></button>\n </div>\n )}\n <div className=\"modal__body\">{children}</div>\n {footer && <div className=\"modal__footer\">{footer}</div>}\n </div>\n </div>,\n document.body\n );\n}\n\nexport interface DrawerProps extends OverlayProps {\n side?: 'left' | 'right';\n}\n\nexport function Drawer({\n open, onClose, title, children, footer, side = 'right',\n closeOnBackdrop = true, closeOnEsc = true, className,\n}: DrawerProps) {\n const ref = React.useRef<HTMLDivElement>(null);\n const titleId = React.useId();\n const t = useLocale();\n const { mounted, closing } = useDelayedUnmount(open, EXIT_MS);\n useEscape(open, onClose, closeOnEsc);\n useFocusTrap(ref, open);\n useScrollLock(open);\n if (!mounted || typeof document === 'undefined') return null;\n return createPortal(\n <div\n className={cx('drawer-backdrop', closing && 'is-closing')}\n onClick={() => closeOnBackdrop && onClose()}\n >\n <div\n ref={ref}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={title ? titleId : undefined}\n className={cx('drawer', `drawer--${side}`, closing && 'is-closing', className)}\n onClick={(e) => e.stopPropagation()}\n >\n {title && (\n <div className=\"drawer__header\">\n <div id={titleId} className=\"drawer__title\">{title}</div>\n <button type=\"button\" className=\"drawer__close\" onClick={onClose} aria-label={t['drawer.close']}><X size={18} /></button>\n </div>\n )}\n <div className=\"drawer__body\">{children}</div>\n {footer && <div className=\"drawer__footer\">{footer}</div>}\n </div>\n </div>,\n document.body\n );\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Avatar } from './chunk-
|
|
1
|
+
import { Avatar } from './chunk-OCLBAGNF.mjs';
|
|
2
2
|
import { format } from './chunk-KKOJI25C.mjs';
|
|
3
3
|
import { useLocale } from './chunk-ZRFSTYRL.mjs';
|
|
4
4
|
import { X, FileText, Download, Trash } from './chunk-CIBJKJV3.mjs';
|
|
@@ -88,5 +88,5 @@ function AttachmentList({ attachments, emptyMessage, className, ...rest }) {
|
|
|
88
88
|
var _internal = { X };
|
|
89
89
|
|
|
90
90
|
export { AttachmentList, CommentThread, _internal };
|
|
91
|
-
//# sourceMappingURL=chunk-
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
91
|
+
//# sourceMappingURL=chunk-3OVWAAGP.mjs.map
|
|
92
|
+
//# sourceMappingURL=chunk-3OVWAAGP.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/Comments.tsx"],"names":[],"mappings":"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","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/components/Comments.tsx"],"names":[],"mappings":"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","file":"chunk-3OVWAAGP.mjs","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { Avatar } from './Display2';\nimport { FileText, Download, Trash, X } from './Icons';\nimport { useLocale } from '../locale/LocaleProvider';\nimport { format } from '../locale/messages';\n\n// ---------- CommentThread ----------------------------------------------\nexport interface CommentItem {\n id: string;\n author: { name: string; avatarSrc?: string };\n body: React.ReactNode;\n timestamp: React.ReactNode;\n internal?: boolean;\n}\n\nexport interface CommentThreadProps extends React.HTMLAttributes<HTMLDivElement> {\n comments: CommentItem[];\n onAdd?: (body: string, internal: boolean) => void;\n placeholder?: string;\n allowInternal?: boolean;\n}\n\nexport function CommentThread({\n comments, onAdd, placeholder,\n allowInternal = false, className, ...rest\n}: CommentThreadProps) {\n const [draft, setDraft] = React.useState('');\n const [internal, setInternal] = React.useState(false);\n const t = useLocale();\n const ph = placeholder ?? t['comments.placeholder'];\n\n const submit = () => {\n if (!draft.trim() || !onAdd) return;\n onAdd(draft, internal);\n setDraft('');\n setInternal(false);\n };\n\n return (\n <div className={cx('comments', className)} {...rest}>\n <ul className=\"comments__list\">\n {comments.map((c) => (\n <li key={c.id} className={cx('comment', c.internal && 'comment--internal')}>\n <Avatar name={c.author.name} src={c.author.avatarSrc} size={32} />\n <div className=\"comment__body\">\n <div className=\"comment__head\">\n <span className=\"comment__author\">{c.author.name}</span>\n <span className=\"comment__time\">{c.timestamp}</span>\n {c.internal && <span className=\"comment__tag\">{t['comments.internalTag']}</span>}\n </div>\n <div className=\"comment__text\">{c.body}</div>\n </div>\n </li>\n ))}\n </ul>\n {onAdd && (\n <div className=\"comments__compose\">\n <textarea\n className=\"textarea\"\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n placeholder={ph}\n rows={3}\n />\n <div className=\"comments__compose-actions\">\n {allowInternal && (\n <label className=\"comments__internal-toggle\">\n <input type=\"checkbox\" checked={internal} onChange={(e) => setInternal(e.target.checked)} />\n <span>{t['comments.internalOnly']}</span>\n </label>\n )}\n <button type=\"button\" className=\"btn btn--primary btn--sm\" disabled={!draft.trim()} onClick={submit}>\n {t['comments.send']}\n </button>\n </div>\n </div>\n )}\n </div>\n );\n}\n\n// ---------- AttachmentList ---------------------------------------------\nexport interface AttachmentItem {\n id: string;\n name: string;\n size?: string; // ya formateado: \"245 KB\"\n url?: string;\n uploadedBy?: string;\n uploadedAt?: React.ReactNode;\n icon?: React.ReactNode;\n onRemove?: () => void;\n}\n\nexport interface AttachmentListProps extends React.HTMLAttributes<HTMLUListElement> {\n attachments: AttachmentItem[];\n emptyMessage?: React.ReactNode;\n}\n\nexport function AttachmentList({ attachments, emptyMessage, className, ...rest }: AttachmentListProps) {\n const t = useLocale();\n const empty = emptyMessage ?? t['attachments.empty'];\n if (attachments.length === 0) {\n return <div className=\"attachments__empty\">{empty}</div>;\n }\n return (\n <ul className={cx('attachments', className)} {...rest}>\n {attachments.map((a) => (\n <li key={a.id} className=\"attachment\">\n <span className=\"attachment__icon\" aria-hidden=\"true\">\n {a.icon ?? <FileText size={20} />}\n </span>\n <div className=\"attachment__body\">\n <div className=\"attachment__name\">{a.name}</div>\n <div className=\"attachment__meta\">\n {a.size && <span>{a.size}</span>}\n {a.uploadedBy && <span>· {a.uploadedBy}</span>}\n {a.uploadedAt && <span>· {a.uploadedAt}</span>}\n </div>\n </div>\n <div className=\"attachment__actions\">\n {a.url && (\n <a href={a.url} download className=\"attachment__action\" aria-label={format(t['attachments.download'], { name: a.name })}>\n <Download size={16} />\n </a>\n )}\n {a.onRemove && (\n <button type=\"button\" className=\"attachment__action attachment__action--danger\" aria-label={format(t['attachments.remove'], { name: a.name })} onClick={a.onRemove}>\n <Trash size={16} />\n </button>\n )}\n </div>\n </li>\n ))}\n </ul>\n );\n}\n\n// re-export para que el bundle no tenga dead imports\nexport const _internal = { X };\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-427NHGTX.js"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
// src/hooks/useDismiss.ts
|
|
4
|
+
function useDismiss({
|
|
5
|
+
open,
|
|
6
|
+
onDismiss,
|
|
7
|
+
refs,
|
|
8
|
+
closeOnEscape = true,
|
|
9
|
+
closeOnOutsideClick = true,
|
|
10
|
+
returnFocusRef
|
|
11
|
+
}) {
|
|
12
|
+
const onDismissRef = React.useRef(onDismiss);
|
|
13
|
+
onDismissRef.current = onDismiss;
|
|
14
|
+
const refsRef = React.useRef(refs);
|
|
15
|
+
refsRef.current = refs;
|
|
16
|
+
React.useEffect(() => {
|
|
17
|
+
if (!open) return;
|
|
18
|
+
const onPointer = (e) => {
|
|
19
|
+
if (!closeOnOutsideClick) return;
|
|
20
|
+
const target = e.target;
|
|
21
|
+
if (refsRef.current.some((r) => r.current?.contains(target))) return;
|
|
22
|
+
onDismissRef.current();
|
|
23
|
+
};
|
|
24
|
+
const onKey = (e) => {
|
|
25
|
+
if (closeOnEscape && e.key === "Escape") onDismissRef.current();
|
|
26
|
+
};
|
|
27
|
+
document.addEventListener("mousedown", onPointer);
|
|
28
|
+
document.addEventListener("keydown", onKey);
|
|
29
|
+
return () => {
|
|
30
|
+
document.removeEventListener("mousedown", onPointer);
|
|
31
|
+
document.removeEventListener("keydown", onKey);
|
|
32
|
+
};
|
|
33
|
+
}, [open, closeOnEscape, closeOnOutsideClick]);
|
|
34
|
+
const wasOpen = React.useRef(false);
|
|
35
|
+
React.useEffect(() => {
|
|
36
|
+
if (wasOpen.current && !open) {
|
|
37
|
+
returnFocusRef?.current?.focus();
|
|
38
|
+
}
|
|
39
|
+
wasOpen.current = open;
|
|
40
|
+
}, [open, returnFocusRef]);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { useDismiss };
|
|
44
|
+
//# sourceMappingURL=chunk-6P2TKRTL.mjs.map
|
|
45
|
+
//# sourceMappingURL=chunk-6P2TKRTL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useDismiss.ts"],"names":[],"mappings":";;;AAqBO,SAAS,UAAA,CAAW;AAAA,EACzB,IAAA;AAAA,EACA,SAAA;AAAA,EACA,IAAA;AAAA,EACA,aAAA,GAAgB,IAAA;AAAA,EAChB,mBAAA,GAAsB,IAAA;AAAA,EACtB;AACF,CAAA,EAA4B;AAC1B,EAAA,MAAM,YAAA,GAAqB,aAAO,SAAS,CAAA;AAC3C,EAAA,YAAA,CAAa,OAAA,GAAU,SAAA;AACvB,EAAA,MAAM,OAAA,GAAgB,aAAO,IAAI,CAAA;AACjC,EAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAElB,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,MAAM,SAAA,GAAY,CAAC,CAAA,KAAwB;AACzC,MAAA,IAAI,CAAC,mBAAA,EAAqB;AAC1B,MAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,MAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,OAAA,EAAS,QAAA,CAAS,MAAM,CAAC,CAAA,EAAG;AAC9D,MAAA,YAAA,CAAa,OAAA,EAAQ;AAAA,IACvB,CAAA;AACA,IAAA,MAAM,KAAA,GAAQ,CAAC,CAAA,KAA2B;AACxC,MAAA,IAAI,aAAA,IAAiB,CAAA,CAAE,GAAA,KAAQ,QAAA,eAAuB,OAAA,EAAQ;AAAA,IAChE,CAAA;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,SAAS,CAAA;AAChD,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,KAAK,CAAA;AAC1C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,SAAS,CAAA;AACnD,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,KAAK,CAAA;AAAA,IAC/C,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,EAAM,aAAA,EAAe,mBAAmB,CAAC,CAAA;AAE7C,EAAA,MAAM,OAAA,GAAgB,aAAO,KAAK,CAAA;AAClC,EAAM,gBAAU,MAAM;AACpB,IAAA,IAAI,OAAA,CAAQ,OAAA,IAAW,CAAC,IAAA,EAAM;AAC5B,MAAA,cAAA,EAAgB,SAAS,KAAA,EAAM;AAAA,IACjC;AACA,IAAA,OAAA,CAAQ,OAAA,GAAU,IAAA;AAAA,EACpB,CAAA,EAAG,CAAC,IAAA,EAAM,cAAc,CAAC,CAAA;AAC3B","file":"chunk-6P2TKRTL.mjs","sourcesContent":["import * as React from 'react';\n\nexport interface UseDismissOptions {\n open: boolean;\n onDismiss: () => void;\n /** Refs whose subtree should NOT count as \"outside\" (trigger + panel). */\n refs: Array<React.RefObject<HTMLElement | null>>;\n closeOnEscape?: boolean;\n closeOnOutsideClick?: boolean;\n /** Focus returns here when the panel closes (usually the trigger). */\n returnFocusRef?: React.RefObject<HTMLElement | null>;\n}\n\n/**\n * Shared dismiss behaviour for floating panels: closes on outside\n * pointer-down and on Escape, and restores focus to the trigger when the\n * panel closes (focus hygiene for keyboard/AT users).\n *\n * `onDismiss` and `refs` are read through refs internally, so callers\n * don't need to memoize them to avoid re-subscribing listeners.\n */\nexport function useDismiss({\n open,\n onDismiss,\n refs,\n closeOnEscape = true,\n closeOnOutsideClick = true,\n returnFocusRef,\n}: UseDismissOptions): void {\n const onDismissRef = React.useRef(onDismiss);\n onDismissRef.current = onDismiss;\n const refsRef = React.useRef(refs);\n refsRef.current = refs;\n\n React.useEffect(() => {\n if (!open) return;\n const onPointer = (e: MouseEvent): void => {\n if (!closeOnOutsideClick) return;\n const target = e.target as Node;\n if (refsRef.current.some((r) => r.current?.contains(target))) return;\n onDismissRef.current();\n };\n const onKey = (e: KeyboardEvent): void => {\n if (closeOnEscape && e.key === 'Escape') onDismissRef.current();\n };\n document.addEventListener('mousedown', onPointer);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onPointer);\n document.removeEventListener('keydown', onKey);\n };\n }, [open, closeOnEscape, closeOnOutsideClick]);\n\n const wasOpen = React.useRef(false);\n React.useEffect(() => {\n if (wasOpen.current && !open) {\n returnFocusRef?.current?.focus();\n }\n wasOpen.current = open;\n }, [open, returnFocusRef]);\n}\n"]}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { useDismiss } from './chunk-6P2TKRTL.mjs';
|
|
2
|
+
import { usePopoverPosition } from './chunk-H3PRT76O.mjs';
|
|
3
|
+
import { Portal } from './chunk-QX5GGPV5.mjs';
|
|
4
|
+
import { cx } from './chunk-IEPCH3JB.mjs';
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function Popover({
|
|
9
|
+
open: controlledOpen,
|
|
10
|
+
defaultOpen = false,
|
|
11
|
+
onOpenChange,
|
|
12
|
+
trigger,
|
|
13
|
+
children,
|
|
14
|
+
placement = "bottom",
|
|
15
|
+
align = "center",
|
|
16
|
+
offset = 8,
|
|
17
|
+
closeOnOutsideClick = true,
|
|
18
|
+
closeOnEscape = true,
|
|
19
|
+
className,
|
|
20
|
+
contentClassName,
|
|
21
|
+
ariaLabel
|
|
22
|
+
}) {
|
|
23
|
+
const [internalOpen, setInternalOpen] = React.useState(defaultOpen);
|
|
24
|
+
const isControlled = controlledOpen !== void 0;
|
|
25
|
+
const open = isControlled ? controlledOpen : internalOpen;
|
|
26
|
+
const triggerRef = React.useRef(null);
|
|
27
|
+
const contentRef = React.useRef(null);
|
|
28
|
+
const setOpen = (next) => {
|
|
29
|
+
if (!isControlled) setInternalOpen(next);
|
|
30
|
+
onOpenChange?.(next);
|
|
31
|
+
};
|
|
32
|
+
const pos = usePopoverPosition(triggerRef, contentRef, {
|
|
33
|
+
open,
|
|
34
|
+
side: placement,
|
|
35
|
+
align,
|
|
36
|
+
offset
|
|
37
|
+
});
|
|
38
|
+
useDismiss({
|
|
39
|
+
open,
|
|
40
|
+
onDismiss: () => setOpen(false),
|
|
41
|
+
refs: [triggerRef, contentRef],
|
|
42
|
+
closeOnEscape,
|
|
43
|
+
closeOnOutsideClick
|
|
44
|
+
});
|
|
45
|
+
return /* @__PURE__ */ jsxs("span", { className: cx("popover", className), children: [
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
"span",
|
|
48
|
+
{
|
|
49
|
+
ref: triggerRef,
|
|
50
|
+
className: "popover__trigger",
|
|
51
|
+
onClick: () => setOpen(!open),
|
|
52
|
+
"aria-haspopup": "dialog",
|
|
53
|
+
"aria-expanded": open,
|
|
54
|
+
children: trigger
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
open && /* @__PURE__ */ jsx(Portal, { children: /* @__PURE__ */ jsx(
|
|
58
|
+
"div",
|
|
59
|
+
{
|
|
60
|
+
ref: contentRef,
|
|
61
|
+
role: "dialog",
|
|
62
|
+
"aria-label": ariaLabel,
|
|
63
|
+
className: cx("popover__content", contentClassName),
|
|
64
|
+
style: {
|
|
65
|
+
position: "absolute",
|
|
66
|
+
top: pos.top,
|
|
67
|
+
left: pos.left,
|
|
68
|
+
visibility: pos.ready ? "visible" : "hidden"
|
|
69
|
+
},
|
|
70
|
+
children
|
|
71
|
+
}
|
|
72
|
+
) })
|
|
73
|
+
] });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export { Popover };
|
|
77
|
+
//# sourceMappingURL=chunk-6RVCYULF.mjs.map
|
|
78
|
+
//# sourceMappingURL=chunk-6RVCYULF.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Popover.tsx"],"names":[],"mappings":";;;;;;;AA0BO,SAAS,OAAA,CAAQ;AAAA,EACtB,IAAA,EAAM,cAAA;AAAA,EACN,WAAA,GAAc,KAAA;AAAA,EACd,YAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA,GAAY,QAAA;AAAA,EACZ,KAAA,GAAQ,QAAA;AAAA,EACR,MAAA,GAAS,CAAA;AAAA,EACT,mBAAA,GAAsB,IAAA;AAAA,EACtB,aAAA,GAAgB,IAAA;AAAA,EAChB,SAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF,CAAA,EAAiB;AACf,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAU,eAAS,WAAW,CAAA;AAClE,EAAA,MAAM,eAAe,cAAA,KAAmB,MAAA;AACxC,EAAA,MAAM,IAAA,GAAO,eAAe,cAAA,GAAiB,YAAA;AAE7C,EAAA,MAAM,UAAA,GAAmB,aAAwB,IAAI,CAAA;AACrD,EAAA,MAAM,UAAA,GAAmB,aAAuB,IAAI,CAAA;AAEpD,EAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAAkB;AACjC,IAAA,IAAI,CAAC,YAAA,EAAc,eAAA,CAAgB,IAAI,CAAA;AACvC,IAAA,YAAA,GAAe,IAAI,CAAA;AAAA,EACrB,CAAA;AAEA,EAAA,MAAM,GAAA,GAAM,kBAAA,CAAmB,UAAA,EAAY,UAAA,EAAY;AAAA,IACrD,IAAA;AAAA,IACA,IAAA,EAAM,SAAA;AAAA,IACN,KAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,UAAA,CAAW;AAAA,IACT,IAAA;AAAA,IACA,SAAA,EAAW,MAAM,OAAA,CAAQ,KAAK,CAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,UAAA,EAAY,UAAU,CAAA;AAAA,IAC7B,aAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EAAA,4BACG,MAAA,EAAA,EAAK,SAAA,EAAW,EAAA,CAAG,SAAA,EAAW,SAAS,CAAA,EACtC,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,UAAA;AAAA,QACL,SAAA,EAAU,kBAAA;AAAA,QACV,OAAA,EAAS,MAAM,OAAA,CAAQ,CAAC,IAAI,CAAA;AAAA,QAC5B,eAAA,EAAc,QAAA;AAAA,QACd,eAAA,EAAe,IAAA;AAAA,QAEd,QAAA,EAAA;AAAA;AAAA,KACH;AAAA,IAIC,IAAA,wBACE,MAAA,EAAA,EACC,QAAA,kBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAK,UAAA;AAAA,QACL,IAAA,EAAK,QAAA;AAAA,QACL,YAAA,EAAY,SAAA;AAAA,QACZ,SAAA,EAAW,EAAA,CAAG,kBAAA,EAAoB,gBAAgB,CAAA;AAAA,QAClD,KAAA,EAAO;AAAA,UACL,QAAA,EAAU,UAAA;AAAA,UACV,KAAK,GAAA,CAAI,GAAA;AAAA,UACT,MAAM,GAAA,CAAI,IAAA;AAAA,UACV,UAAA,EAAY,GAAA,CAAI,KAAA,GAAQ,SAAA,GAAY;AAAA,SACtC;AAAA,QAEC;AAAA;AAAA,KACH,EACF;AAAA,GAAA,EAEJ,CAAA;AAEJ","file":"chunk-6RVCYULF.mjs","sourcesContent":["'use client';\nimport * as React from 'react';\nimport { cx } from '../utils/cx';\nimport { Portal } from './Portal';\nimport { usePopoverPosition } from '../hooks/usePopoverPosition';\nimport { useDismiss } from '../hooks/useDismiss';\n\nexport type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';\nexport type PopoverAlign = 'start' | 'center' | 'end';\n\nexport interface PopoverProps {\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger: React.ReactNode;\n children: React.ReactNode;\n placement?: PopoverPlacement;\n align?: PopoverAlign;\n offset?: number;\n closeOnOutsideClick?: boolean;\n closeOnEscape?: boolean;\n className?: string;\n contentClassName?: string;\n ariaLabel?: string;\n}\n\nexport function Popover({\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n trigger,\n children,\n placement = 'bottom',\n align = 'center',\n offset = 8,\n closeOnOutsideClick = true,\n closeOnEscape = true,\n className,\n contentClassName,\n ariaLabel,\n}: PopoverProps) {\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen);\n const isControlled = controlledOpen !== undefined;\n const open = isControlled ? controlledOpen : internalOpen;\n\n const triggerRef = React.useRef<HTMLSpanElement>(null);\n const contentRef = React.useRef<HTMLDivElement>(null);\n\n const setOpen = (next: boolean) => {\n if (!isControlled) setInternalOpen(next);\n onOpenChange?.(next);\n };\n\n const pos = usePopoverPosition(triggerRef, contentRef, {\n open,\n side: placement,\n align,\n offset,\n });\n\n useDismiss({\n open,\n onDismiss: () => setOpen(false),\n refs: [triggerRef, contentRef],\n closeOnEscape,\n closeOnOutsideClick,\n });\n\n return (\n <span className={cx('popover', className)}>\n <span\n ref={triggerRef}\n className=\"popover__trigger\"\n onClick={() => setOpen(!open)}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n >\n {trigger}\n </span>\n {/* Portaled to document.body so absolute coords (document-relative)\n match the positioning origin and overflow:hidden / transformed\n ancestors don't clip the panel. */}\n {open && (\n <Portal>\n <div\n ref={contentRef}\n role=\"dialog\"\n aria-label={ariaLabel}\n className={cx('popover__content', contentClassName)}\n style={{\n position: 'absolute',\n top: pos.top,\n left: pos.left,\n visibility: pos.ready ? 'visible' : 'hidden',\n }}\n >\n {children}\n </div>\n </Portal>\n )}\n </span>\n );\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-BVQRDAR7.mjs"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Drawer } from './chunk-
|
|
1
|
+
import { Drawer } from './chunk-3N4IBCLW.mjs';
|
|
2
2
|
import { format } from './chunk-KKOJI25C.mjs';
|
|
3
3
|
import { getBrand } from './chunk-5GEWIK4T.mjs';
|
|
4
4
|
import { useLocale } from './chunk-ZRFSTYRL.mjs';
|
|
@@ -422,5 +422,5 @@ function CompareTable({ items, attributes, onRemove, className, ...rest }) {
|
|
|
422
422
|
}
|
|
423
423
|
|
|
424
424
|
export { AddressForm, CartDrawer, CompareTable, FreeShippingProgress, OrderSummary, PriceDisplay, PromoCodeInput, QuantitySelector, Rating, VariantSelector, WishlistButton };
|
|
425
|
-
//# sourceMappingURL=chunk-
|
|
426
|
-
//# sourceMappingURL=chunk-
|
|
425
|
+
//# sourceMappingURL=chunk-C35GKQJO.mjs.map
|
|
426
|
+
//# sourceMappingURL=chunk-C35GKQJO.mjs.map
|