@sesionario/blocks 1.40.1-rc.1 → 1.41.0-rc.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +326 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +56 -10
- package/dist/index.d.ts +56 -10
- package/dist/index.js +325 -70
- package/dist/index.js.map +1 -1
- package/dist/livo.cjs +10 -0
- package/dist/livo.cjs.map +1 -1
- package/dist/livo.d.cts +1 -0
- package/dist/livo.d.ts +1 -0
- package/dist/livo.js +10 -0
- package/dist/livo.js.map +1 -1
- package/dist/office.cjs +1 -1
- package/dist/office.cjs.map +1 -1
- package/dist/office.js +1 -1
- package/dist/office.js.map +1 -1
- package/dist/pdf.cjs +1 -1
- package/dist/pdf.cjs.map +1 -1
- package/dist/pdf.js +1 -1
- package/dist/pdf.js.map +1 -1
- package/dist/theme.cjs +1 -0
- package/dist/theme.css +8 -0
- package/dist/theme.css.map +1 -0
- package/dist/theme.js +1 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -311,7 +311,7 @@ function AlertDialogOverlay({
|
|
|
311
311
|
{
|
|
312
312
|
"data-slot": "alert-dialog-overlay",
|
|
313
313
|
className: cn(
|
|
314
|
-
"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
|
314
|
+
"fixed inset-0 z-50 bg-black/50 dark:bg-black/80 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0",
|
|
315
315
|
className
|
|
316
316
|
),
|
|
317
317
|
...props
|
|
@@ -1174,31 +1174,54 @@ function useZoomPanGestures(options = {}) {
|
|
|
1174
1174
|
clearSnapBack
|
|
1175
1175
|
};
|
|
1176
1176
|
}
|
|
1177
|
+
var STATIC_BLUR_FILTER = "blur(20px)";
|
|
1177
1178
|
function isBrokenImage(img) {
|
|
1178
1179
|
return img.complete && img.naturalWidth === 0;
|
|
1179
1180
|
}
|
|
1181
|
+
function resolveBlurDataUrl(value) {
|
|
1182
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1183
|
+
}
|
|
1180
1184
|
function SafeImage({
|
|
1181
1185
|
src,
|
|
1182
1186
|
fallback,
|
|
1183
1187
|
alt = "",
|
|
1184
1188
|
onError,
|
|
1189
|
+
onLoad,
|
|
1190
|
+
blurDataUrl,
|
|
1191
|
+
style,
|
|
1185
1192
|
...imgProps
|
|
1186
1193
|
}) {
|
|
1187
1194
|
const [failed, setFailed] = React2.useState(false);
|
|
1195
|
+
const [loaded, setLoaded] = React2.useState(false);
|
|
1188
1196
|
const imgRef = React2.useRef(null);
|
|
1189
1197
|
const resolvedSrc = typeof src === "string" && src.length > 0 ? src : null;
|
|
1198
|
+
const resolvedBlur = resolveBlurDataUrl(blurDataUrl);
|
|
1190
1199
|
React2.useLayoutEffect(() => {
|
|
1191
1200
|
setFailed(false);
|
|
1201
|
+
setLoaded(false);
|
|
1192
1202
|
}, [resolvedSrc]);
|
|
1193
1203
|
React2.useLayoutEffect(() => {
|
|
1194
1204
|
const img = imgRef.current;
|
|
1195
|
-
if (img
|
|
1205
|
+
if (!img) return;
|
|
1206
|
+
if (isBrokenImage(img)) {
|
|
1196
1207
|
setFailed(true);
|
|
1208
|
+
return;
|
|
1197
1209
|
}
|
|
1198
|
-
|
|
1210
|
+
if (resolvedBlur && img.complete && img.naturalWidth > 0) {
|
|
1211
|
+
setLoaded(true);
|
|
1212
|
+
}
|
|
1213
|
+
}, [resolvedSrc, failed, resolvedBlur]);
|
|
1199
1214
|
if (!resolvedSrc || failed) {
|
|
1200
1215
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: fallback });
|
|
1201
1216
|
}
|
|
1217
|
+
const paintedStyle = resolvedBlur === null ? style : {
|
|
1218
|
+
...style,
|
|
1219
|
+
backgroundImage: `url(${JSON.stringify(resolvedBlur)})`,
|
|
1220
|
+
backgroundSize: "cover",
|
|
1221
|
+
backgroundPosition: "center",
|
|
1222
|
+
backgroundRepeat: "no-repeat",
|
|
1223
|
+
...loaded || prefersReducedMotion() ? {} : { filter: STATIC_BLUR_FILTER }
|
|
1224
|
+
};
|
|
1202
1225
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1203
1226
|
"img",
|
|
1204
1227
|
{
|
|
@@ -1206,6 +1229,11 @@ function SafeImage({
|
|
|
1206
1229
|
ref: imgRef,
|
|
1207
1230
|
src: resolvedSrc,
|
|
1208
1231
|
alt,
|
|
1232
|
+
style: paintedStyle,
|
|
1233
|
+
onLoad: (event) => {
|
|
1234
|
+
if (resolvedBlur) setLoaded(true);
|
|
1235
|
+
onLoad?.(event);
|
|
1236
|
+
},
|
|
1209
1237
|
onError: (event) => {
|
|
1210
1238
|
setFailed(true);
|
|
1211
1239
|
onError?.(event);
|
|
@@ -1215,6 +1243,7 @@ function SafeImage({
|
|
|
1215
1243
|
}
|
|
1216
1244
|
function ImageLightbox({
|
|
1217
1245
|
images,
|
|
1246
|
+
blurDataUrls,
|
|
1218
1247
|
index,
|
|
1219
1248
|
onIndexChange,
|
|
1220
1249
|
onClose,
|
|
@@ -1340,6 +1369,7 @@ function ImageLightbox({
|
|
|
1340
1369
|
{
|
|
1341
1370
|
src: images[index],
|
|
1342
1371
|
alt: "",
|
|
1372
|
+
blurDataUrl: blurDataUrls?.[index] ?? null,
|
|
1343
1373
|
draggable: false,
|
|
1344
1374
|
className: "max-h-[calc(100dvh-2rem)] max-w-full select-none rounded-lg object-contain",
|
|
1345
1375
|
style: {
|
|
@@ -1472,6 +1502,7 @@ function MediaCarousel({
|
|
|
1472
1502
|
{
|
|
1473
1503
|
src: item.src,
|
|
1474
1504
|
alt: item.alt ?? "",
|
|
1505
|
+
blurDataUrl: item.blurDataUrl,
|
|
1475
1506
|
draggable: false,
|
|
1476
1507
|
className: "max-h-full max-w-full select-none object-contain",
|
|
1477
1508
|
style: {
|
|
@@ -1575,7 +1606,7 @@ function DialogOverlay({
|
|
|
1575
1606
|
{
|
|
1576
1607
|
"data-slot": "dialog-overlay",
|
|
1577
1608
|
className: cn(
|
|
1578
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
|
1609
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50 dark:bg-black/80",
|
|
1579
1610
|
className
|
|
1580
1611
|
),
|
|
1581
1612
|
...props
|
|
@@ -1707,6 +1738,79 @@ function MediaViewerDialog({
|
|
|
1707
1738
|
}
|
|
1708
1739
|
) });
|
|
1709
1740
|
}
|
|
1741
|
+
|
|
1742
|
+
// src/components/media/blurDataUrl.ts
|
|
1743
|
+
var BLUR_LONG_EDGE_PX = 16;
|
|
1744
|
+
var BLUR_DATA_URL_MAX_CHARS = 1024;
|
|
1745
|
+
var JPEG_DATA_URL_PREFIX = "data:image/jpeg;base64,";
|
|
1746
|
+
var JPEG_QUALITIES = [0.7, 0.5, 0.35, 0.2];
|
|
1747
|
+
function longEdgeSteps(start) {
|
|
1748
|
+
const steps = [];
|
|
1749
|
+
let edge = start;
|
|
1750
|
+
while (edge >= 2) {
|
|
1751
|
+
steps.push(edge);
|
|
1752
|
+
edge = Math.floor(edge / 2);
|
|
1753
|
+
}
|
|
1754
|
+
return steps;
|
|
1755
|
+
}
|
|
1756
|
+
function sizeForLongEdge(width, height, longEdge) {
|
|
1757
|
+
const longest = Math.max(width, height);
|
|
1758
|
+
const scale = longEdge / longest;
|
|
1759
|
+
return {
|
|
1760
|
+
width: Math.max(1, Math.round(width * scale)),
|
|
1761
|
+
height: Math.max(1, Math.round(height * scale))
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1764
|
+
function acceptableBlurDataUrl(value) {
|
|
1765
|
+
return value.startsWith(JPEG_DATA_URL_PREFIX) && value.length > JPEG_DATA_URL_PREFIX.length && value.length <= BLUR_DATA_URL_MAX_CHARS;
|
|
1766
|
+
}
|
|
1767
|
+
async function decodeBlob(blob) {
|
|
1768
|
+
if (typeof createImageBitmap !== "function") {
|
|
1769
|
+
throw new Error("createImageBitmap unavailable");
|
|
1770
|
+
}
|
|
1771
|
+
const bitmap = await createImageBitmap(blob);
|
|
1772
|
+
return {
|
|
1773
|
+
source: bitmap,
|
|
1774
|
+
width: bitmap.width,
|
|
1775
|
+
height: bitmap.height,
|
|
1776
|
+
release() {
|
|
1777
|
+
bitmap.close();
|
|
1778
|
+
}
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1781
|
+
async function blurDataUrlFromBlob(blob) {
|
|
1782
|
+
if (typeof document === "undefined") return null;
|
|
1783
|
+
let decoded;
|
|
1784
|
+
try {
|
|
1785
|
+
decoded = await decodeBlob(blob);
|
|
1786
|
+
} catch {
|
|
1787
|
+
return null;
|
|
1788
|
+
}
|
|
1789
|
+
try {
|
|
1790
|
+
if (Math.min(decoded.width, decoded.height) <= 0) return null;
|
|
1791
|
+
const canvas = document.createElement("canvas");
|
|
1792
|
+
for (const edge of longEdgeSteps(BLUR_LONG_EDGE_PX)) {
|
|
1793
|
+
const size = sizeForLongEdge(decoded.width, decoded.height, edge);
|
|
1794
|
+
canvas.width = size.width;
|
|
1795
|
+
canvas.height = size.height;
|
|
1796
|
+
const context = canvas.getContext("2d");
|
|
1797
|
+
if (!context) return null;
|
|
1798
|
+
context.drawImage(decoded.source, 0, 0, size.width, size.height);
|
|
1799
|
+
for (const quality of JPEG_QUALITIES) {
|
|
1800
|
+
let url;
|
|
1801
|
+
try {
|
|
1802
|
+
url = canvas.toDataURL("image/jpeg", quality);
|
|
1803
|
+
} catch {
|
|
1804
|
+
return null;
|
|
1805
|
+
}
|
|
1806
|
+
if (acceptableBlurDataUrl(url)) return url;
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
return null;
|
|
1810
|
+
} finally {
|
|
1811
|
+
decoded.release();
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1710
1814
|
var miniMenuContentClassName = "max-h-none overflow-x-visible overflow-y-visible";
|
|
1711
1815
|
var miniMenuContentDefaults = {
|
|
1712
1816
|
sideOffset: 8,
|
|
@@ -3626,9 +3730,17 @@ function AvatarEditor({
|
|
|
3626
3730
|
);
|
|
3627
3731
|
}
|
|
3628
3732
|
function Drawer({
|
|
3733
|
+
repositionInputs = false,
|
|
3629
3734
|
...props
|
|
3630
3735
|
}) {
|
|
3631
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3736
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3737
|
+
vaul.Drawer.Root,
|
|
3738
|
+
{
|
|
3739
|
+
"data-slot": "drawer",
|
|
3740
|
+
repositionInputs,
|
|
3741
|
+
...props
|
|
3742
|
+
}
|
|
3743
|
+
);
|
|
3632
3744
|
}
|
|
3633
3745
|
function DrawerPortal({
|
|
3634
3746
|
...props
|
|
@@ -3649,7 +3761,7 @@ function DrawerOverlay({
|
|
|
3649
3761
|
{
|
|
3650
3762
|
"data-slot": "drawer-overlay",
|
|
3651
3763
|
className: cn(
|
|
3652
|
-
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
|
|
3764
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50 dark:bg-black/80",
|
|
3653
3765
|
className
|
|
3654
3766
|
),
|
|
3655
3767
|
...props
|
|
@@ -4225,7 +4337,7 @@ function EmojiPicker({
|
|
|
4225
4337
|
onKeyDown: handleSearchKeyDown,
|
|
4226
4338
|
placeholder: strings.searchPlaceholder,
|
|
4227
4339
|
"aria-label": strings.searchAriaLabel,
|
|
4228
|
-
className: "border-input bg-background focus-visible:border-ring focus-visible:ring-ring/50 h-9 w-full rounded-md border py-2 pr-3 pl-8 text-
|
|
4340
|
+
className: "border-input bg-background focus-visible:border-ring focus-visible:ring-ring/50 h-9 w-full rounded-md border py-2 pr-3 pl-8 text-base outline-none focus-visible:ring-[3px] md:text-sm"
|
|
4229
4341
|
}
|
|
4230
4342
|
)
|
|
4231
4343
|
] }),
|
|
@@ -4713,6 +4825,41 @@ function useMediaQuery2(query) {
|
|
|
4713
4825
|
}, [query]);
|
|
4714
4826
|
return matches;
|
|
4715
4827
|
}
|
|
4828
|
+
function readMetrics() {
|
|
4829
|
+
if (typeof window === "undefined") {
|
|
4830
|
+
return { height: 0, offsetTop: 0, keyboardInset: 0 };
|
|
4831
|
+
}
|
|
4832
|
+
const vv = window.visualViewport;
|
|
4833
|
+
if (!vv) {
|
|
4834
|
+
return {
|
|
4835
|
+
height: window.innerHeight,
|
|
4836
|
+
offsetTop: 0,
|
|
4837
|
+
keyboardInset: 0
|
|
4838
|
+
};
|
|
4839
|
+
}
|
|
4840
|
+
return {
|
|
4841
|
+
height: vv.height,
|
|
4842
|
+
offsetTop: vv.offsetTop,
|
|
4843
|
+
keyboardInset: Math.max(0, window.innerHeight - vv.height - vv.offsetTop)
|
|
4844
|
+
};
|
|
4845
|
+
}
|
|
4846
|
+
function useVisualViewportMetrics() {
|
|
4847
|
+
const [metrics, setMetrics] = React2.useState(readMetrics);
|
|
4848
|
+
React2.useEffect(() => {
|
|
4849
|
+
const vv = window.visualViewport;
|
|
4850
|
+
const update = () => setMetrics(readMetrics());
|
|
4851
|
+
update();
|
|
4852
|
+
vv?.addEventListener("resize", update);
|
|
4853
|
+
vv?.addEventListener("scroll", update);
|
|
4854
|
+
window.addEventListener("resize", update);
|
|
4855
|
+
return () => {
|
|
4856
|
+
vv?.removeEventListener("resize", update);
|
|
4857
|
+
vv?.removeEventListener("scroll", update);
|
|
4858
|
+
window.removeEventListener("resize", update);
|
|
4859
|
+
};
|
|
4860
|
+
}, []);
|
|
4861
|
+
return metrics;
|
|
4862
|
+
}
|
|
4716
4863
|
function useSearchHotkey(options = {}) {
|
|
4717
4864
|
const { defaultOpen = false, disabled = false } = options;
|
|
4718
4865
|
const [open, setOpen] = React2.useState(defaultOpen);
|
|
@@ -5204,6 +5351,24 @@ function Command({
|
|
|
5204
5351
|
}
|
|
5205
5352
|
);
|
|
5206
5353
|
}
|
|
5354
|
+
function useCommandDialogScrollLock(open) {
|
|
5355
|
+
React2__namespace.useEffect(() => {
|
|
5356
|
+
if (!open) return;
|
|
5357
|
+
const onTouchMove = (event) => {
|
|
5358
|
+
const target = event.target;
|
|
5359
|
+
if (!(target instanceof Element)) {
|
|
5360
|
+
event.preventDefault();
|
|
5361
|
+
return;
|
|
5362
|
+
}
|
|
5363
|
+
if (target.closest('[data-slot="command-list"]')) return;
|
|
5364
|
+
event.preventDefault();
|
|
5365
|
+
};
|
|
5366
|
+
document.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
5367
|
+
return () => {
|
|
5368
|
+
document.removeEventListener("touchmove", onTouchMove);
|
|
5369
|
+
};
|
|
5370
|
+
}, [open]);
|
|
5371
|
+
}
|
|
5207
5372
|
function CommandDialog({
|
|
5208
5373
|
title = "Command Palette",
|
|
5209
5374
|
description = "Search for a command to run...",
|
|
@@ -5213,6 +5378,9 @@ function CommandDialog({
|
|
|
5213
5378
|
commandProps,
|
|
5214
5379
|
...props
|
|
5215
5380
|
}) {
|
|
5381
|
+
const { height: viewportHeight } = useVisualViewportMetrics();
|
|
5382
|
+
useCommandDialogScrollLock(props.open);
|
|
5383
|
+
const mobileMaxHeight = viewportHeight > 0 ? Math.max(280, viewportHeight - 16) : void 0;
|
|
5216
5384
|
return /* @__PURE__ */ jsxRuntime.jsxs(Dialog, { ...props, children: [
|
|
5217
5385
|
/* @__PURE__ */ jsxRuntime.jsxs(DialogHeader, { className: "sr-only", children: [
|
|
5218
5386
|
/* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { children: title }),
|
|
@@ -5221,12 +5389,22 @@ function CommandDialog({
|
|
|
5221
5389
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5222
5390
|
DialogContent,
|
|
5223
5391
|
{
|
|
5224
|
-
className: cn(
|
|
5392
|
+
className: cn(
|
|
5393
|
+
"flex flex-col gap-0 overflow-hidden p-0",
|
|
5394
|
+
// iOS: top-pin in the visual viewport, near full-bleed width,
|
|
5395
|
+
// fill available height so the list (not the page) scrolls.
|
|
5396
|
+
"max-sm:top-[max(0.5rem,env(safe-area-inset-top))] max-sm:right-2 max-sm:left-2 max-sm:w-auto max-sm:max-w-none max-sm:translate-x-0 max-sm:translate-y-0",
|
|
5397
|
+
"max-sm:h-[var(--command-dialog-max-height,calc(100dvh-1rem))] max-sm:max-h-[var(--command-dialog-max-height,calc(100dvh-1rem))]",
|
|
5398
|
+
className
|
|
5399
|
+
),
|
|
5400
|
+
style: mobileMaxHeight ? {
|
|
5401
|
+
["--command-dialog-max-height"]: `${mobileMaxHeight}px`
|
|
5402
|
+
} : void 0,
|
|
5225
5403
|
showCloseButton,
|
|
5226
5404
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5227
5405
|
Command,
|
|
5228
5406
|
{
|
|
5229
|
-
className: "**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5",
|
|
5407
|
+
className: "flex h-full min-h-0 flex-col **:data-[slot=command-input-wrapper]:h-12 **:data-[slot=command-list]:max-sm:max-h-none **:data-[slot=command-list]:max-sm:min-h-0 **:data-[slot=command-list]:max-sm:flex-1 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]]:px-2 [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5",
|
|
5230
5408
|
...commandProps,
|
|
5231
5409
|
children
|
|
5232
5410
|
}
|
|
@@ -5243,7 +5421,7 @@ function CommandInput({
|
|
|
5243
5421
|
"div",
|
|
5244
5422
|
{
|
|
5245
5423
|
"data-slot": "command-input-wrapper",
|
|
5246
|
-
className: "flex h-9 items-center gap-2 border-b px-3",
|
|
5424
|
+
className: "flex h-9 shrink-0 items-center gap-2 border-b px-3",
|
|
5247
5425
|
children: [
|
|
5248
5426
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.SearchIcon, { className: "size-4 shrink-0 opacity-50" }),
|
|
5249
5427
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -5251,7 +5429,8 @@ function CommandInput({
|
|
|
5251
5429
|
{
|
|
5252
5430
|
"data-slot": "command-input",
|
|
5253
5431
|
className: cn(
|
|
5254
|
-
|
|
5432
|
+
// text-base (≥16px) on mobile prevents iOS Safari focus zoom
|
|
5433
|
+
"flex h-10 w-full rounded-md bg-transparent py-3 text-base outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
5255
5434
|
className
|
|
5256
5435
|
),
|
|
5257
5436
|
...props
|
|
@@ -5270,7 +5449,7 @@ function CommandList({
|
|
|
5270
5449
|
{
|
|
5271
5450
|
"data-slot": "command-list",
|
|
5272
5451
|
className: cn(
|
|
5273
|
-
"max-h-[300px] scroll-py-1 overflow-x-hidden overflow-y-auto",
|
|
5452
|
+
"max-h-[min(300px,calc(100dvh-12rem))] scroll-py-1 overflow-x-hidden overflow-y-auto overscroll-contain touch-pan-y",
|
|
5274
5453
|
className
|
|
5275
5454
|
),
|
|
5276
5455
|
...props
|
|
@@ -5543,6 +5722,7 @@ function matchesQuery(entry, query, getOptionKeywords) {
|
|
|
5543
5722
|
function SearchablePicker(props) {
|
|
5544
5723
|
const {
|
|
5545
5724
|
options,
|
|
5725
|
+
selectedItems: selectedItemsProp,
|
|
5546
5726
|
fetchOptions,
|
|
5547
5727
|
getOptionValue,
|
|
5548
5728
|
getOptionLabel,
|
|
@@ -5601,11 +5781,16 @@ function SearchablePicker(props) {
|
|
|
5601
5781
|
},
|
|
5602
5782
|
[getOptionValue]
|
|
5603
5783
|
);
|
|
5784
|
+
if (options?.length) rememberItems(options);
|
|
5785
|
+
if (selectedItemsProp?.length) rememberItems(selectedItemsProp);
|
|
5786
|
+
if (pinned?.recommended?.length) rememberItems(pinned.recommended);
|
|
5787
|
+
if (pinned?.recent?.length) rememberItems(pinned.recent);
|
|
5604
5788
|
React2.useEffect(() => {
|
|
5605
5789
|
if (options) rememberItems(options);
|
|
5790
|
+
if (selectedItemsProp) rememberItems(selectedItemsProp);
|
|
5606
5791
|
if (pinned?.recommended) rememberItems(pinned.recommended);
|
|
5607
5792
|
if (pinned?.recent) rememberItems(pinned.recent);
|
|
5608
|
-
}, [options, pinned, rememberItems]);
|
|
5793
|
+
}, [options, selectedItemsProp, pinned, rememberItems]);
|
|
5609
5794
|
React2.useEffect(() => {
|
|
5610
5795
|
if (!open) {
|
|
5611
5796
|
setQuery("");
|
|
@@ -5653,7 +5838,7 @@ function SearchablePicker(props) {
|
|
|
5653
5838
|
const selectedItems = React2.useMemo(() => {
|
|
5654
5839
|
const values = mode === "multiple" ? selectedValueKey ? selectedValueKey.split("\0") : [] : selectedValueKey ? [selectedValueKey] : [];
|
|
5655
5840
|
return values.map((value) => knownItemsRef.current.get(value)).filter((item) => item !== void 0);
|
|
5656
|
-
}, [mode, selectedValueKey, options, pinned, remoteItems]);
|
|
5841
|
+
}, [mode, selectedValueKey, options, selectedItemsProp, pinned, remoteItems]);
|
|
5657
5842
|
const queryForFilter = query.trim();
|
|
5658
5843
|
const recommended = React2.useMemo(() => {
|
|
5659
5844
|
if (queryForFilter) return [];
|
|
@@ -5757,13 +5942,27 @@ function SearchablePicker(props) {
|
|
|
5757
5942
|
);
|
|
5758
5943
|
const handleLoadMore = React2.useCallback(async () => {
|
|
5759
5944
|
if (!onLoadMore || isLoadingMore) return;
|
|
5945
|
+
const requestId = requestIdRef.current;
|
|
5760
5946
|
setIsLoadingMore(true);
|
|
5761
5947
|
try {
|
|
5762
|
-
await onLoadMore();
|
|
5948
|
+
const more = await onLoadMore();
|
|
5949
|
+
if (requestIdRef.current !== requestId || !Array.isArray(more)) return;
|
|
5950
|
+
setRemoteItems((prev) => {
|
|
5951
|
+
const seen = new Set(prev.map((item) => getOptionValue(item)));
|
|
5952
|
+
const next = [...prev];
|
|
5953
|
+
for (const item of more) {
|
|
5954
|
+
const value = getOptionValue(item);
|
|
5955
|
+
if (seen.has(value)) continue;
|
|
5956
|
+
seen.add(value);
|
|
5957
|
+
next.push(item);
|
|
5958
|
+
}
|
|
5959
|
+
return next;
|
|
5960
|
+
});
|
|
5961
|
+
rememberItems(more);
|
|
5763
5962
|
} finally {
|
|
5764
|
-
setIsLoadingMore(false);
|
|
5963
|
+
if (requestIdRef.current === requestId) setIsLoadingMore(false);
|
|
5765
5964
|
}
|
|
5766
|
-
}, [onLoadMore, isLoadingMore]);
|
|
5965
|
+
}, [onLoadMore, isLoadingMore, getOptionValue, rememberItems]);
|
|
5767
5966
|
const triggerLabel = React2.useMemo(() => {
|
|
5768
5967
|
if (renderValue) {
|
|
5769
5968
|
if (mode === "multiple") {
|
|
@@ -5897,7 +6096,7 @@ function SearchablePicker(props) {
|
|
|
5897
6096
|
] });
|
|
5898
6097
|
}
|
|
5899
6098
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex w-full items-center gap-1", className), children: [
|
|
5900
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, modal:
|
|
6099
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open, onOpenChange: setOpen, modal: false, children: [
|
|
5901
6100
|
/* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: triggerButton }),
|
|
5902
6101
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5903
6102
|
PopoverContent,
|
|
@@ -7228,14 +7427,26 @@ function ChatMessageList({
|
|
|
7228
7427
|
messages,
|
|
7229
7428
|
currentUserId,
|
|
7230
7429
|
emptyTitle = "Sin mensajes",
|
|
7231
|
-
emptyDescription = "Escribe para iniciar la conversaci\xF3n."
|
|
7430
|
+
emptyDescription = "Escribe para iniciar la conversaci\xF3n.",
|
|
7431
|
+
compactEmpty = false
|
|
7232
7432
|
}) {
|
|
7233
7433
|
if (messages.length === 0) {
|
|
7234
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7235
|
-
|
|
7236
|
-
|
|
7237
|
-
|
|
7238
|
-
|
|
7434
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7435
|
+
"div",
|
|
7436
|
+
{
|
|
7437
|
+
className: compactEmpty ? "flex h-full flex-col items-center justify-center gap-1 px-4 py-3 text-center" : "flex h-full flex-col items-center justify-center gap-2 p-6 text-center",
|
|
7438
|
+
children: [
|
|
7439
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7440
|
+
lucideReact.MessageCircleDashedIcon,
|
|
7441
|
+
{
|
|
7442
|
+
className: compactEmpty ? "size-5 text-muted-foreground" : "size-8 text-muted-foreground"
|
|
7443
|
+
}
|
|
7444
|
+
),
|
|
7445
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-medium", children: emptyTitle }),
|
|
7446
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: emptyDescription })
|
|
7447
|
+
]
|
|
7448
|
+
}
|
|
7449
|
+
);
|
|
7239
7450
|
}
|
|
7240
7451
|
return /* @__PURE__ */ jsxRuntime.jsx(MessageScrollerProvider, { autoScroll: true, children: /* @__PURE__ */ jsxRuntime.jsxs(MessageScroller, { children: [
|
|
7241
7452
|
/* @__PURE__ */ jsxRuntime.jsx(MessageScrollerViewport, { children: /* @__PURE__ */ jsxRuntime.jsx(MessageScrollerContent, { className: "gap-4 p-4", children: messages.map((m) => {
|
|
@@ -7311,6 +7522,9 @@ var MessageComposer = React2__namespace.forwardRef(function MessageComposer2({
|
|
|
7311
7522
|
event.preventDefault();
|
|
7312
7523
|
if (!canSubmit) return;
|
|
7313
7524
|
onSubmit(event);
|
|
7525
|
+
requestAnimationFrame(() => {
|
|
7526
|
+
fieldRef.current?.focus({ preventScroll: true });
|
|
7527
|
+
});
|
|
7314
7528
|
},
|
|
7315
7529
|
[canSubmit, onSubmit]
|
|
7316
7530
|
);
|
|
@@ -7385,6 +7599,10 @@ var MessageComposer = React2__namespace.forwardRef(function MessageComposer2({
|
|
|
7385
7599
|
size: sendButtonSize,
|
|
7386
7600
|
disabled: !canSubmit,
|
|
7387
7601
|
className: sendButtonClassName,
|
|
7602
|
+
onPointerDown: (event) => {
|
|
7603
|
+
if (event.button !== 0) return;
|
|
7604
|
+
event.preventDefault();
|
|
7605
|
+
},
|
|
7388
7606
|
children: sendLabel
|
|
7389
7607
|
}
|
|
7390
7608
|
)
|
|
@@ -7578,7 +7796,7 @@ function ThreadPanel({
|
|
|
7578
7796
|
className
|
|
7579
7797
|
),
|
|
7580
7798
|
children: [
|
|
7581
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-
|
|
7799
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 border-b bg-primary/10 px-2 py-2", children: [
|
|
7582
7800
|
showBack && onBack ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7583
7801
|
Button,
|
|
7584
7802
|
{
|
|
@@ -7590,7 +7808,24 @@ function ThreadPanel({
|
|
|
7590
7808
|
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "size-4" })
|
|
7591
7809
|
}
|
|
7592
7810
|
) : null,
|
|
7811
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7812
|
+
"span",
|
|
7813
|
+
{
|
|
7814
|
+
className: "flex size-8 shrink-0 items-center justify-center overflow-hidden rounded-full bg-primary text-[11px] font-semibold text-primary-foreground",
|
|
7815
|
+
style: thread.avatarUrl ? void 0 : avatarFallbackStyle(thread.title),
|
|
7816
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7817
|
+
SafeImage,
|
|
7818
|
+
{
|
|
7819
|
+
src: thread.avatarUrl,
|
|
7820
|
+
alt: "",
|
|
7821
|
+
className: "size-full object-cover",
|
|
7822
|
+
fallback: getInitials(thread.eyebrow ?? thread.title)
|
|
7823
|
+
}
|
|
7824
|
+
)
|
|
7825
|
+
}
|
|
7826
|
+
),
|
|
7593
7827
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 px-1", children: [
|
|
7828
|
+
thread.eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-[11px] font-semibold tracking-wide text-primary", children: thread.eyebrow }) : null,
|
|
7594
7829
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-sm font-semibold", children: thread.title }),
|
|
7595
7830
|
thread.subtitle ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "truncate text-xs text-muted-foreground", children: thread.subtitle }) : null
|
|
7596
7831
|
] }),
|
|
@@ -7611,7 +7846,8 @@ function ThreadPanel({
|
|
|
7611
7846
|
{
|
|
7612
7847
|
messages,
|
|
7613
7848
|
currentUserId,
|
|
7614
|
-
emptyDescription: labels.emptyThread
|
|
7849
|
+
emptyDescription: labels.emptyThread,
|
|
7850
|
+
compactEmpty: true
|
|
7615
7851
|
}
|
|
7616
7852
|
) }),
|
|
7617
7853
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t p-3", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -7624,7 +7860,7 @@ function ThreadPanel({
|
|
|
7624
7860
|
sendLabel: labels.send,
|
|
7625
7861
|
placeholder: labels.placeholder,
|
|
7626
7862
|
"aria-label": labels.placeholder,
|
|
7627
|
-
disabled: loading
|
|
7863
|
+
disabled: loading,
|
|
7628
7864
|
sendDisabled: loading || sending,
|
|
7629
7865
|
maxLength: 2e3,
|
|
7630
7866
|
rows: 2
|
|
@@ -7662,7 +7898,7 @@ function ListPanel({
|
|
|
7662
7898
|
className
|
|
7663
7899
|
),
|
|
7664
7900
|
children: [
|
|
7665
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b px-3 py-2", children: [
|
|
7901
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b bg-primary/10 px-3 py-2", children: [
|
|
7666
7902
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-semibold", children: labels.listTitle }),
|
|
7667
7903
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7668
7904
|
Button,
|
|
@@ -7695,11 +7931,11 @@ function ListPanel({
|
|
|
7695
7931
|
value: query,
|
|
7696
7932
|
onChange: (e) => setQuery(e.target.value),
|
|
7697
7933
|
placeholder: labels.searchPlaceholder ?? "Buscar\u2026",
|
|
7698
|
-
className: "h-
|
|
7934
|
+
className: "h-9 w-full rounded-md border bg-transparent pr-2 pl-8 text-base outline-none focus-visible:ring-2 focus-visible:ring-ring md:h-8 md:text-sm"
|
|
7699
7935
|
}
|
|
7700
7936
|
)
|
|
7701
7937
|
] }) }) : null,
|
|
7702
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "min-h-0 flex-1 overflow-y-auto p-1", children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("li", { className: "px-3 py-
|
|
7938
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: "min-h-0 flex-1 overflow-y-auto p-1", children: filtered.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("li", { className: "px-3 py-4 text-center text-xs text-muted-foreground", children: labels.emptyList }) : filtered.map((item) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7703
7939
|
"button",
|
|
7704
7940
|
{
|
|
7705
7941
|
type: "button",
|
|
@@ -7723,6 +7959,7 @@ function ListPanel({
|
|
|
7723
7959
|
}
|
|
7724
7960
|
),
|
|
7725
7961
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 flex-1", children: [
|
|
7962
|
+
item.eyebrow ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-[11px] font-semibold tracking-wide text-primary", children: item.eyebrow }) : null,
|
|
7726
7963
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-sm font-medium", children: item.title }),
|
|
7727
7964
|
item.subtitle ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block truncate text-xs text-muted-foreground", children: item.subtitle }) : null
|
|
7728
7965
|
] }),
|
|
@@ -7752,10 +7989,13 @@ function SupportMessengerProvider({
|
|
|
7752
7989
|
className
|
|
7753
7990
|
}) {
|
|
7754
7991
|
const isMobile = useMediaQuery2("(max-width: 767px)");
|
|
7992
|
+
const { height: viewportHeight, keyboardInset } = useVisualViewportMetrics();
|
|
7755
7993
|
const dockRef = React2.useRef(null);
|
|
7756
7994
|
const [listOpen, setListOpen] = React2.useState(false);
|
|
7757
7995
|
const [threads, setThreads] = React2.useState([]);
|
|
7758
7996
|
const [mobileThreadKey, setMobileThreadKey] = React2.useState(null);
|
|
7997
|
+
const mobileSheetOpen = listOpen || Boolean(mobileThreadKey);
|
|
7998
|
+
const mobileSheetHeight = viewportHeight > 0 ? Math.max(240, Math.min(viewportHeight * 0.85, viewportHeight)) : void 0;
|
|
7759
7999
|
const totalUnread = React2.useMemo(
|
|
7760
8000
|
() => items.reduce((sum, item) => sum + (item.unreadCount ?? 0), 0),
|
|
7761
8001
|
[items]
|
|
@@ -7848,6 +8088,8 @@ function SupportMessengerProvider({
|
|
|
7848
8088
|
key: item.key,
|
|
7849
8089
|
title: item.title,
|
|
7850
8090
|
subtitle: item.subtitle,
|
|
8091
|
+
eyebrow: item.eyebrow,
|
|
8092
|
+
avatarUrl: item.avatarUrl,
|
|
7851
8093
|
conversationId: item.conversationId,
|
|
7852
8094
|
open: item.open
|
|
7853
8095
|
});
|
|
@@ -7897,48 +8139,61 @@ function SupportMessengerProvider({
|
|
|
7897
8139
|
isMobile ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
7898
8140
|
Drawer,
|
|
7899
8141
|
{
|
|
7900
|
-
open:
|
|
8142
|
+
open: mobileSheetOpen,
|
|
7901
8143
|
onOpenChange: (open) => {
|
|
7902
8144
|
if (!open) closeAll();
|
|
7903
8145
|
},
|
|
7904
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
{
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
|
|
7917
|
-
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7922
|
-
|
|
7923
|
-
|
|
7924
|
-
|
|
7925
|
-
|
|
7926
|
-
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
-
|
|
7931
|
-
|
|
7932
|
-
|
|
7933
|
-
|
|
7934
|
-
|
|
7935
|
-
|
|
7936
|
-
|
|
7937
|
-
|
|
7938
|
-
|
|
7939
|
-
|
|
7940
|
-
|
|
7941
|
-
|
|
8146
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8147
|
+
DrawerContent,
|
|
8148
|
+
{
|
|
8149
|
+
className: "pointer-events-auto mx-auto flex max-h-[85dvh] max-w-lg flex-col",
|
|
8150
|
+
style: {
|
|
8151
|
+
// Lift above the software keyboard without Vaul's
|
|
8152
|
+
// repositionInputs focus hack (see drawer.tsx).
|
|
8153
|
+
bottom: keyboardInset,
|
|
8154
|
+
height: mobileSheetHeight ?? "85dvh",
|
|
8155
|
+
maxHeight: viewportHeight > 0 ? viewportHeight : "85dvh"
|
|
8156
|
+
},
|
|
8157
|
+
children: activeMobileThread ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8158
|
+
/* @__PURE__ */ jsxRuntime.jsx(DrawerHeader, { className: "sr-only", children: /* @__PURE__ */ jsxRuntime.jsx(DrawerTitle, { children: activeMobileThread.title }) }),
|
|
8159
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8160
|
+
ThreadPanel,
|
|
8161
|
+
{
|
|
8162
|
+
thread: activeMobileThread,
|
|
8163
|
+
client,
|
|
8164
|
+
getWsUrl,
|
|
8165
|
+
currentUserId,
|
|
8166
|
+
labels,
|
|
8167
|
+
emojiLocale,
|
|
8168
|
+
showBack: true,
|
|
8169
|
+
onBack: () => {
|
|
8170
|
+
closeThread(activeMobileThread.key);
|
|
8171
|
+
setListOpen(true);
|
|
8172
|
+
},
|
|
8173
|
+
onClose: closeAll,
|
|
8174
|
+
onConversationReady: () => void onRefreshItems?.(),
|
|
8175
|
+
className: "h-full rounded-none border-0 shadow-none"
|
|
8176
|
+
}
|
|
8177
|
+
)
|
|
8178
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8179
|
+
/* @__PURE__ */ jsxRuntime.jsx(DrawerHeader, { className: "sr-only", children: /* @__PURE__ */ jsxRuntime.jsx(DrawerTitle, { children: labels.listTitle }) }),
|
|
8180
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8181
|
+
ListPanel,
|
|
8182
|
+
{
|
|
8183
|
+
items,
|
|
8184
|
+
labels,
|
|
8185
|
+
tabs,
|
|
8186
|
+
activeTab,
|
|
8187
|
+
onTabChange,
|
|
8188
|
+
onSelect: handleSelectItem,
|
|
8189
|
+
onClose: closeAll,
|
|
8190
|
+
searchThreshold,
|
|
8191
|
+
className: "h-full rounded-none border-0 shadow-none"
|
|
8192
|
+
}
|
|
8193
|
+
)
|
|
8194
|
+
] })
|
|
8195
|
+
}
|
|
8196
|
+
)
|
|
7942
8197
|
}
|
|
7943
8198
|
) : null,
|
|
7944
8199
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -8953,6 +9208,7 @@ exports.ZOOM_PAN_MIN_SCALE = ZOOM_PAN_MIN_SCALE;
|
|
|
8953
9208
|
exports.ZOOM_PAN_SWIPE_COMMIT_PX = ZOOM_PAN_SWIPE_COMMIT_PX;
|
|
8954
9209
|
exports.ZOOM_PAN_SWIPE_SNAP_MS = ZOOM_PAN_SWIPE_SNAP_MS;
|
|
8955
9210
|
exports.avatarFallbackStyle = avatarFallbackStyle;
|
|
9211
|
+
exports.blurDataUrlFromBlob = blurDataUrlFromBlob;
|
|
8956
9212
|
exports.bubbleVariants = bubbleVariants;
|
|
8957
9213
|
exports.cn = cn;
|
|
8958
9214
|
exports.createSupportChatClient = createSupportChatClient;
|
|
@@ -8983,6 +9239,7 @@ exports.useSearchHotkey = useSearchHotkey;
|
|
|
8983
9239
|
exports.useSupportConversation = useSupportConversation;
|
|
8984
9240
|
exports.useSupportMessenger = useSupportMessenger;
|
|
8985
9241
|
exports.useSupportMessengerOptional = useSupportMessengerOptional;
|
|
9242
|
+
exports.useVisualViewportMetrics = useVisualViewportMetrics;
|
|
8986
9243
|
exports.useZoomPanGestures = useZoomPanGestures;
|
|
8987
9244
|
exports.zoomToward = zoomToward;
|
|
8988
9245
|
//# sourceMappingURL=index.cjs.map
|