@sesionario/blocks 1.8.0 → 1.10.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/index.cjs +758 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -3
- package/dist/index.d.ts +92 -3
- package/dist/index.js +758 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import * as React6 from 'react';
|
|
3
|
-
import { createContext, useContext, useState, useRef, useEffect, useLayoutEffect, useCallback, useMemo } from 'react';
|
|
3
|
+
import { createContext, useContext, useState, useRef, useEffect, useLayoutEffect, useCallback, useId, useMemo } from 'react';
|
|
4
4
|
import { ChevronsUpDown, CheckIcon, Smile, SearchIcon, Search, Clock, Flag, Hash, Lightbulb, Trophy, Plane, Apple, Leaf, Hand, Loader2, AlertTriangle, Inbox, X, ChevronLeft, ChevronRight, Monitor, Sun, Moon, Building2, Check, Plus, Languages, Upload, Move, ZoomOut, ZoomIn, RotateCcw, RotateCw, Grid3X3, RefreshCw, User, Pencil, Play, AlertCircle, VolumeX, Pause, Volume1, Volume2, Settings, PictureInPicture2, Minimize, Maximize, BadgeCheck, ArrowDownIcon, MessageCircleDashedIcon, MessageCircle, XIcon } from 'lucide-react';
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -490,6 +490,9 @@ function ExpandableText({
|
|
|
490
490
|
var MIN_SCALE = 1;
|
|
491
491
|
var MAX_SCALE = 4;
|
|
492
492
|
var DOUBLE_TAP_MS = 300;
|
|
493
|
+
var SWIPE_LOCK_PX = 8;
|
|
494
|
+
var SWIPE_COMMIT_PX = 56;
|
|
495
|
+
var SWIPE_SNAP_MS = 180;
|
|
493
496
|
var IDENTITY = { scale: 1, tx: 0, ty: 0 };
|
|
494
497
|
function clamp(value, min, max) {
|
|
495
498
|
return Math.min(max, Math.max(min, value));
|
|
@@ -507,6 +510,10 @@ function zoomToward(prev, nextScale, originX, originY) {
|
|
|
507
510
|
function pointerDistance(a, b) {
|
|
508
511
|
return Math.hypot(b.x - a.x, b.y - a.y);
|
|
509
512
|
}
|
|
513
|
+
function prefersReducedMotion() {
|
|
514
|
+
if (typeof window === "undefined" || !window.matchMedia) return false;
|
|
515
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
516
|
+
}
|
|
510
517
|
function ImageLightbox({
|
|
511
518
|
images,
|
|
512
519
|
index,
|
|
@@ -522,15 +529,24 @@ function ImageLightbox({
|
|
|
522
529
|
const [transform, setTransform] = useState(IDENTITY);
|
|
523
530
|
const transformRef = useRef(transform);
|
|
524
531
|
transformRef.current = transform;
|
|
532
|
+
const [isSwipeDragging, setIsSwipeDragging] = useState(false);
|
|
533
|
+
const [snapBack, setSnapBack] = useState(false);
|
|
525
534
|
const stageRef = useRef(null);
|
|
526
535
|
const pointersRef = useRef(/* @__PURE__ */ new Map());
|
|
527
536
|
const pinchStartRef = useRef(null);
|
|
528
537
|
const panRef = useRef(null);
|
|
538
|
+
const swipeRef = useRef(null);
|
|
529
539
|
const lastTapRef = useRef(
|
|
530
540
|
null
|
|
531
541
|
);
|
|
542
|
+
const indexRef = useRef(index);
|
|
543
|
+
indexRef.current = index;
|
|
544
|
+
const imagesLengthRef = useRef(images.length);
|
|
545
|
+
imagesLengthRef.current = images.length;
|
|
532
546
|
const resetZoom = useCallback(() => {
|
|
533
547
|
setTransform(IDENTITY);
|
|
548
|
+
setIsSwipeDragging(false);
|
|
549
|
+
setSnapBack(false);
|
|
534
550
|
}, []);
|
|
535
551
|
useEffect(() => {
|
|
536
552
|
resetZoom();
|
|
@@ -587,6 +603,10 @@ function ImageLightbox({
|
|
|
587
603
|
stage.addEventListener("wheel", handleWheel, { passive: false });
|
|
588
604
|
return () => stage.removeEventListener("wheel", handleWheel);
|
|
589
605
|
}, [stageOrigin]);
|
|
606
|
+
function clearSwipe() {
|
|
607
|
+
swipeRef.current = null;
|
|
608
|
+
setIsSwipeDragging(false);
|
|
609
|
+
}
|
|
590
610
|
function beginPinch() {
|
|
591
611
|
const pts = [...pointersRef.current.values()];
|
|
592
612
|
const [a, b] = pts;
|
|
@@ -601,13 +621,18 @@ function ImageLightbox({
|
|
|
601
621
|
transform: { ...transformRef.current }
|
|
602
622
|
};
|
|
603
623
|
panRef.current = null;
|
|
624
|
+
clearSwipe();
|
|
625
|
+
setSnapBack(false);
|
|
604
626
|
}
|
|
605
627
|
function onPointerDown(e) {
|
|
606
628
|
e.stopPropagation();
|
|
607
629
|
const stage = stageRef.current;
|
|
608
630
|
if (!stage) return;
|
|
609
|
-
stage.setPointerCapture
|
|
631
|
+
if (typeof stage.setPointerCapture === "function") {
|
|
632
|
+
stage.setPointerCapture(e.pointerId);
|
|
633
|
+
}
|
|
610
634
|
pointersRef.current.set(e.pointerId, { x: e.clientX, y: e.clientY });
|
|
635
|
+
setSnapBack(false);
|
|
611
636
|
if (pointersRef.current.size === 2) {
|
|
612
637
|
beginPinch();
|
|
613
638
|
return;
|
|
@@ -621,6 +646,17 @@ function ImageLightbox({
|
|
|
621
646
|
originTy: transformRef.current.ty,
|
|
622
647
|
moved: false
|
|
623
648
|
};
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
if (hasMultiple) {
|
|
652
|
+
swipeRef.current = {
|
|
653
|
+
pointerId: e.pointerId,
|
|
654
|
+
startX: e.clientX,
|
|
655
|
+
startY: e.clientY,
|
|
656
|
+
moved: false,
|
|
657
|
+
axis: null
|
|
658
|
+
};
|
|
659
|
+
setIsSwipeDragging(true);
|
|
624
660
|
}
|
|
625
661
|
}
|
|
626
662
|
function onPointerMove(e) {
|
|
@@ -645,19 +681,62 @@ function ImageLightbox({
|
|
|
645
681
|
}
|
|
646
682
|
const pan = panRef.current;
|
|
647
683
|
if (pan && pan.pointerId === e.pointerId) {
|
|
648
|
-
const
|
|
649
|
-
const
|
|
650
|
-
if (Math.abs(
|
|
684
|
+
const dx2 = e.clientX - pan.startX;
|
|
685
|
+
const dy2 = e.clientY - pan.startY;
|
|
686
|
+
if (Math.abs(dx2) > 2 || Math.abs(dy2) > 2) pan.moved = true;
|
|
651
687
|
setTransform((prev) => ({
|
|
652
688
|
...prev,
|
|
653
|
-
tx: pan.originTx +
|
|
654
|
-
ty: pan.originTy +
|
|
689
|
+
tx: pan.originTx + dx2,
|
|
690
|
+
ty: pan.originTy + dy2
|
|
655
691
|
}));
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
const swipe = swipeRef.current;
|
|
695
|
+
if (!swipe || swipe.pointerId !== e.pointerId) return;
|
|
696
|
+
const dx = e.clientX - swipe.startX;
|
|
697
|
+
const dy = e.clientY - swipe.startY;
|
|
698
|
+
if (Math.abs(dx) > 2 || Math.abs(dy) > 2) swipe.moved = true;
|
|
699
|
+
if (swipe.axis === null) {
|
|
700
|
+
const absX = Math.abs(dx);
|
|
701
|
+
const absY = Math.abs(dy);
|
|
702
|
+
if (absX < SWIPE_LOCK_PX && absY < SWIPE_LOCK_PX) return;
|
|
703
|
+
swipe.axis = absX >= absY ? "x" : "y";
|
|
704
|
+
if (swipe.axis === "y") {
|
|
705
|
+
clearSwipe();
|
|
706
|
+
setTransform(IDENTITY);
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
if (swipe.axis === "x") {
|
|
711
|
+
setTransform({ scale: MIN_SCALE, tx: dx, ty: 0 });
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
function finishSwipe(e) {
|
|
715
|
+
const swipe = swipeRef.current;
|
|
716
|
+
if (!swipe || swipe.pointerId !== e.pointerId) return false;
|
|
717
|
+
const dx = e.clientX - swipe.startX;
|
|
718
|
+
const wasMoved = swipe.moved;
|
|
719
|
+
const axis = swipe.axis;
|
|
720
|
+
clearSwipe();
|
|
721
|
+
if (axis === "x" && Math.abs(dx) >= SWIPE_COMMIT_PX) {
|
|
722
|
+
const length = imagesLengthRef.current;
|
|
723
|
+
const current = indexRef.current;
|
|
724
|
+
if (dx < 0) {
|
|
725
|
+
onIndexChange((current + 1) % length);
|
|
726
|
+
} else {
|
|
727
|
+
onIndexChange((current - 1 + length) % length);
|
|
728
|
+
}
|
|
729
|
+
return true;
|
|
656
730
|
}
|
|
731
|
+
if (wasMoved || transformRef.current.tx !== 0) {
|
|
732
|
+
if (!prefersReducedMotion()) setSnapBack(true);
|
|
733
|
+
setTransform(IDENTITY);
|
|
734
|
+
}
|
|
735
|
+
return wasMoved;
|
|
657
736
|
}
|
|
658
737
|
function onPointerUp(e) {
|
|
659
738
|
const stage = stageRef.current;
|
|
660
|
-
if (stage
|
|
739
|
+
if (stage && typeof stage.hasPointerCapture === "function" && stage.hasPointerCapture(e.pointerId) && typeof stage.releasePointerCapture === "function") {
|
|
661
740
|
stage.releasePointerCapture(e.pointerId);
|
|
662
741
|
}
|
|
663
742
|
pointersRef.current.delete(e.pointerId);
|
|
@@ -678,6 +757,8 @@ function ImageLightbox({
|
|
|
678
757
|
};
|
|
679
758
|
}
|
|
680
759
|
}
|
|
760
|
+
const swipeHandled = finishSwipe(e);
|
|
761
|
+
if (swipeHandled) return;
|
|
681
762
|
const pan = panRef.current;
|
|
682
763
|
if (pan && pan.pointerId === e.pointerId) {
|
|
683
764
|
const wasMoved = pan.moved;
|
|
@@ -699,6 +780,7 @@ function ImageLightbox({
|
|
|
699
780
|
e.stopPropagation();
|
|
700
781
|
}
|
|
701
782
|
const { scale, tx, ty } = transform;
|
|
783
|
+
const transition = snapBack && !isSwipeDragging && !prefersReducedMotion() ? `transform ${SWIPE_SNAP_MS}ms ease-out` : void 0;
|
|
702
784
|
return createPortal(
|
|
703
785
|
/* @__PURE__ */ jsxs(
|
|
704
786
|
"div",
|
|
@@ -738,6 +820,7 @@ function ImageLightbox({
|
|
|
738
820
|
ref: stageRef,
|
|
739
821
|
className: "relative flex max-h-full max-w-full touch-none items-center justify-center",
|
|
740
822
|
"data-scale": scale,
|
|
823
|
+
"data-swipe-dragging": isSwipeDragging ? "true" : "false",
|
|
741
824
|
onClick: stopDialogClose,
|
|
742
825
|
onPointerDown,
|
|
743
826
|
onPointerMove,
|
|
@@ -752,8 +835,10 @@ function ImageLightbox({
|
|
|
752
835
|
className: "max-h-[calc(100dvh-2rem)] max-w-full select-none rounded-lg object-contain",
|
|
753
836
|
style: {
|
|
754
837
|
transform: `translate(${tx}px, ${ty}px) scale(${scale})`,
|
|
838
|
+
transition,
|
|
755
839
|
cursor: scale > MIN_SCALE ? "grab" : "default"
|
|
756
|
-
}
|
|
840
|
+
},
|
|
841
|
+
onTransitionEnd: () => setSnapBack(false)
|
|
757
842
|
}
|
|
758
843
|
)
|
|
759
844
|
}
|
|
@@ -1380,7 +1465,7 @@ function LanguageSwitcher({
|
|
|
1380
1465
|
const sizes = sizeClasses2[size];
|
|
1381
1466
|
const shapeClass = shapeClasses2[shape];
|
|
1382
1467
|
const reduceMotion = useReducedMotion();
|
|
1383
|
-
const
|
|
1468
|
+
const defaultLabels5 = {
|
|
1384
1469
|
language: labels.language ?? "Language"
|
|
1385
1470
|
};
|
|
1386
1471
|
if (variant === "mini") {
|
|
@@ -1390,7 +1475,7 @@ function LanguageSwitcher({
|
|
|
1390
1475
|
{
|
|
1391
1476
|
variant: "ghost",
|
|
1392
1477
|
size: "icon",
|
|
1393
|
-
"aria-label":
|
|
1478
|
+
"aria-label": defaultLabels5.language,
|
|
1394
1479
|
className: cn(sizes.buttonMini, shapeClass, className),
|
|
1395
1480
|
children: /* @__PURE__ */ jsx(Languages, { className: sizes.iconMini })
|
|
1396
1481
|
}
|
|
@@ -3679,6 +3764,19 @@ var PLAYBACK_RATES = [0.75, 1, 1.25, 1.5, 2];
|
|
|
3679
3764
|
var CONTROLS_HIDE_MS = 3e3;
|
|
3680
3765
|
var LIVE_EDGE_THRESHOLD_S = 8;
|
|
3681
3766
|
var SEEK_STEP_S = 5;
|
|
3767
|
+
function asWebkitVideo(video) {
|
|
3768
|
+
return video;
|
|
3769
|
+
}
|
|
3770
|
+
function hasWebkitVideoFullscreen(video) {
|
|
3771
|
+
const webkit = asWebkitVideo(video);
|
|
3772
|
+
return typeof webkit?.webkitEnterFullscreen === "function";
|
|
3773
|
+
}
|
|
3774
|
+
function hasStandardFullscreen() {
|
|
3775
|
+
if (typeof document === "undefined") return false;
|
|
3776
|
+
if (document.fullscreenEnabled) return true;
|
|
3777
|
+
const doc = document;
|
|
3778
|
+
return !!doc.webkitFullscreenEnabled;
|
|
3779
|
+
}
|
|
3682
3780
|
function formatTime(seconds) {
|
|
3683
3781
|
if (!Number.isFinite(seconds) || seconds < 0) return "0:00";
|
|
3684
3782
|
const total = Math.floor(seconds);
|
|
@@ -3752,10 +3850,10 @@ function VideoPlayer({
|
|
|
3752
3850
|
null
|
|
3753
3851
|
);
|
|
3754
3852
|
const [behindLive, setBehindLive] = React6.useState(false);
|
|
3853
|
+
const [webkitFullscreenSupported, setWebkitFullscreenSupported] = React6.useState(false);
|
|
3755
3854
|
const hideTimerRef = React6.useRef(null);
|
|
3756
3855
|
const pipSupported = typeof document !== "undefined" && "pictureInPictureEnabled" in document && document.pictureInPictureEnabled;
|
|
3757
|
-
const fullscreenSupported =
|
|
3758
|
-
"webkitFullscreenEnabled" in document);
|
|
3856
|
+
const fullscreenSupported = hasStandardFullscreen() || webkitFullscreenSupported;
|
|
3759
3857
|
React6.useEffect(() => {
|
|
3760
3858
|
const video = videoRef.current;
|
|
3761
3859
|
if (!video || !active) return;
|
|
@@ -3789,11 +3887,26 @@ function VideoPlayer({
|
|
|
3789
3887
|
video.removeEventListener("ratechange", onRate);
|
|
3790
3888
|
};
|
|
3791
3889
|
}, [videoRef, active, mode]);
|
|
3890
|
+
React6.useEffect(() => {
|
|
3891
|
+
setWebkitFullscreenSupported(hasWebkitVideoFullscreen(videoRef.current));
|
|
3892
|
+
}, [videoRef, active]);
|
|
3792
3893
|
React6.useEffect(() => {
|
|
3793
3894
|
const onFsChange = () => setIsFullscreen(document.fullscreenElement === containerRef.current);
|
|
3794
3895
|
document.addEventListener("fullscreenchange", onFsChange);
|
|
3795
3896
|
return () => document.removeEventListener("fullscreenchange", onFsChange);
|
|
3796
3897
|
}, []);
|
|
3898
|
+
React6.useEffect(() => {
|
|
3899
|
+
const video = asWebkitVideo(videoRef.current);
|
|
3900
|
+
if (!video) return;
|
|
3901
|
+
const onBegin = () => setIsFullscreen(true);
|
|
3902
|
+
const onEnd = () => setIsFullscreen(false);
|
|
3903
|
+
video.addEventListener("webkitbeginfullscreen", onBegin);
|
|
3904
|
+
video.addEventListener("webkitendfullscreen", onEnd);
|
|
3905
|
+
return () => {
|
|
3906
|
+
video.removeEventListener("webkitbeginfullscreen", onBegin);
|
|
3907
|
+
video.removeEventListener("webkitendfullscreen", onEnd);
|
|
3908
|
+
};
|
|
3909
|
+
}, [videoRef, active]);
|
|
3797
3910
|
React6.useEffect(() => {
|
|
3798
3911
|
const video = videoRef.current;
|
|
3799
3912
|
if (!video) return;
|
|
@@ -3858,11 +3971,21 @@ function VideoPlayer({
|
|
|
3858
3971
|
}
|
|
3859
3972
|
function toggleFullscreen() {
|
|
3860
3973
|
const el = containerRef.current;
|
|
3861
|
-
|
|
3862
|
-
if (document.fullscreenElement === el) {
|
|
3974
|
+
const video = asWebkitVideo(videoRef.current);
|
|
3975
|
+
if (el && document.fullscreenElement === el) {
|
|
3863
3976
|
void document.exitFullscreen();
|
|
3864
|
-
|
|
3865
|
-
|
|
3977
|
+
return;
|
|
3978
|
+
}
|
|
3979
|
+
if (video?.webkitDisplayingFullscreen && video.webkitExitFullscreen) {
|
|
3980
|
+
video.webkitExitFullscreen();
|
|
3981
|
+
return;
|
|
3982
|
+
}
|
|
3983
|
+
if (el && hasStandardFullscreen() && typeof el.requestFullscreen === "function") {
|
|
3984
|
+
void el.requestFullscreen();
|
|
3985
|
+
return;
|
|
3986
|
+
}
|
|
3987
|
+
if (video && typeof video.webkitEnterFullscreen === "function") {
|
|
3988
|
+
video.webkitEnterFullscreen();
|
|
3866
3989
|
}
|
|
3867
3990
|
}
|
|
3868
3991
|
function togglePip() {
|
|
@@ -4317,6 +4440,18 @@ function useDebouncedValueStrict(value, delayMs) {
|
|
|
4317
4440
|
}, [value, delayMs]);
|
|
4318
4441
|
return debounced;
|
|
4319
4442
|
}
|
|
4443
|
+
function useMediaQuery2(query) {
|
|
4444
|
+
const [matches, setMatches] = useState(false);
|
|
4445
|
+
useEffect(() => {
|
|
4446
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
4447
|
+
const mql = window.matchMedia(query);
|
|
4448
|
+
const onChange = () => setMatches(mql.matches);
|
|
4449
|
+
onChange();
|
|
4450
|
+
mql.addEventListener("change", onChange);
|
|
4451
|
+
return () => mql.removeEventListener("change", onChange);
|
|
4452
|
+
}, [query]);
|
|
4453
|
+
return matches;
|
|
4454
|
+
}
|
|
4320
4455
|
function useSearchHotkey(options = {}) {
|
|
4321
4456
|
const { defaultOpen = false, disabled = false } = options;
|
|
4322
4457
|
const [open, setOpen] = useState(defaultOpen);
|
|
@@ -4334,6 +4469,22 @@ function useSearchHotkey(options = {}) {
|
|
|
4334
4469
|
}, [disabled]);
|
|
4335
4470
|
return { open, setOpen, toggle };
|
|
4336
4471
|
}
|
|
4472
|
+
|
|
4473
|
+
// src/components/search/fuzzy.ts
|
|
4474
|
+
function normalize(value) {
|
|
4475
|
+
return value.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
4476
|
+
}
|
|
4477
|
+
function fuzzyMatch(query, target) {
|
|
4478
|
+
const q = normalize(query.trim());
|
|
4479
|
+
if (!q) return true;
|
|
4480
|
+
const t = normalize(target);
|
|
4481
|
+
if (t.includes(q)) return true;
|
|
4482
|
+
let qi = 0;
|
|
4483
|
+
for (let ti = 0; ti < t.length && qi < q.length; ti++) {
|
|
4484
|
+
if (t[ti] === q[qi]) qi++;
|
|
4485
|
+
}
|
|
4486
|
+
return qi === q.length;
|
|
4487
|
+
}
|
|
4337
4488
|
function Command({
|
|
4338
4489
|
className,
|
|
4339
4490
|
...props
|
|
@@ -4451,6 +4602,19 @@ function CommandGroup({
|
|
|
4451
4602
|
}
|
|
4452
4603
|
);
|
|
4453
4604
|
}
|
|
4605
|
+
function CommandSeparator({
|
|
4606
|
+
className,
|
|
4607
|
+
...props
|
|
4608
|
+
}) {
|
|
4609
|
+
return /* @__PURE__ */ jsx(
|
|
4610
|
+
Command$1.Separator,
|
|
4611
|
+
{
|
|
4612
|
+
"data-slot": "command-separator",
|
|
4613
|
+
className: cn("-mx-1 h-px bg-border", className),
|
|
4614
|
+
...props
|
|
4615
|
+
}
|
|
4616
|
+
);
|
|
4617
|
+
}
|
|
4454
4618
|
function CommandItem({
|
|
4455
4619
|
className,
|
|
4456
4620
|
...props
|
|
@@ -4467,23 +4631,584 @@ function CommandItem({
|
|
|
4467
4631
|
}
|
|
4468
4632
|
);
|
|
4469
4633
|
}
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4634
|
+
function OptionRow({
|
|
4635
|
+
entry,
|
|
4636
|
+
selected,
|
|
4637
|
+
onSelect,
|
|
4638
|
+
renderOption
|
|
4639
|
+
}) {
|
|
4640
|
+
return /* @__PURE__ */ jsxs(
|
|
4641
|
+
CommandItem,
|
|
4642
|
+
{
|
|
4643
|
+
value: entry.value,
|
|
4644
|
+
keywords: [entry.label],
|
|
4645
|
+
onSelect,
|
|
4646
|
+
"data-checked": selected || void 0,
|
|
4647
|
+
children: [
|
|
4648
|
+
renderOption ? renderOption(entry.item, { selected }) : /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: entry.label }),
|
|
4649
|
+
/* @__PURE__ */ jsx(
|
|
4650
|
+
CheckIcon,
|
|
4651
|
+
{
|
|
4652
|
+
className: cn(
|
|
4653
|
+
"ml-auto size-4 shrink-0",
|
|
4654
|
+
selected ? "opacity-100" : "opacity-0"
|
|
4655
|
+
)
|
|
4656
|
+
}
|
|
4657
|
+
)
|
|
4658
|
+
]
|
|
4659
|
+
},
|
|
4660
|
+
entry.value
|
|
4661
|
+
);
|
|
4474
4662
|
}
|
|
4475
|
-
function
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4663
|
+
function SearchablePickerList({
|
|
4664
|
+
query,
|
|
4665
|
+
onQueryChange,
|
|
4666
|
+
labels,
|
|
4667
|
+
isLoading,
|
|
4668
|
+
hasError,
|
|
4669
|
+
recommended,
|
|
4670
|
+
recent,
|
|
4671
|
+
results,
|
|
4672
|
+
selectedValues,
|
|
4673
|
+
mode,
|
|
4674
|
+
allowEmpty,
|
|
4675
|
+
emptyLabel,
|
|
4676
|
+
onSelectEmpty,
|
|
4677
|
+
onSelectItem,
|
|
4678
|
+
renderOption,
|
|
4679
|
+
createOption,
|
|
4680
|
+
onLoadMore,
|
|
4681
|
+
hasMore,
|
|
4682
|
+
isLoadingMore,
|
|
4683
|
+
listClassName
|
|
4684
|
+
}) {
|
|
4685
|
+
const hasPinned = recommended.length > 0 || recent.length > 0;
|
|
4686
|
+
const hasResults = results.length > 0;
|
|
4687
|
+
const showEmpty = !isLoading && !hasError && !hasPinned && !hasResults && !(allowEmpty && mode === "single");
|
|
4688
|
+
return /* @__PURE__ */ jsxs(Command, { shouldFilter: false, className: "flex h-full min-h-0 flex-col", children: [
|
|
4689
|
+
/* @__PURE__ */ jsx(
|
|
4690
|
+
CommandInput,
|
|
4691
|
+
{
|
|
4692
|
+
placeholder: labels.searchPlaceholder,
|
|
4693
|
+
value: query,
|
|
4694
|
+
onValueChange: onQueryChange
|
|
4695
|
+
}
|
|
4696
|
+
),
|
|
4697
|
+
/* @__PURE__ */ jsxs(CommandList, { className: cn("min-h-0 flex-1", listClassName), children: [
|
|
4698
|
+
isLoading ? /* @__PURE__ */ jsxs(
|
|
4699
|
+
"div",
|
|
4700
|
+
{
|
|
4701
|
+
className: "flex items-center justify-center gap-2 py-6 text-sm text-muted-foreground",
|
|
4702
|
+
role: "status",
|
|
4703
|
+
children: [
|
|
4704
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": true }),
|
|
4705
|
+
labels.loading
|
|
4706
|
+
]
|
|
4707
|
+
}
|
|
4708
|
+
) : null,
|
|
4709
|
+
hasError && !isLoading ? /* @__PURE__ */ jsx(
|
|
4710
|
+
"div",
|
|
4711
|
+
{
|
|
4712
|
+
className: "py-6 text-center text-sm text-destructive",
|
|
4713
|
+
role: "alert",
|
|
4714
|
+
children: labels.error
|
|
4715
|
+
}
|
|
4716
|
+
) : null,
|
|
4717
|
+
showEmpty ? /* @__PURE__ */ jsx(CommandEmpty, { children: labels.empty }) : null,
|
|
4718
|
+
allowEmpty && mode === "single" && !query.trim() ? /* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsxs(
|
|
4719
|
+
CommandItem,
|
|
4720
|
+
{
|
|
4721
|
+
value: "__empty__",
|
|
4722
|
+
onSelect: () => onSelectEmpty?.(),
|
|
4723
|
+
"data-checked": !selectedValues.size || void 0,
|
|
4724
|
+
children: [
|
|
4725
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-muted-foreground", children: emptyLabel }),
|
|
4726
|
+
/* @__PURE__ */ jsx(
|
|
4727
|
+
CheckIcon,
|
|
4728
|
+
{
|
|
4729
|
+
className: cn(
|
|
4730
|
+
"ml-auto size-4 shrink-0",
|
|
4731
|
+
selectedValues.size === 0 ? "opacity-100" : "opacity-0"
|
|
4732
|
+
)
|
|
4733
|
+
}
|
|
4734
|
+
)
|
|
4735
|
+
]
|
|
4736
|
+
}
|
|
4737
|
+
) }) : null,
|
|
4738
|
+
recommended.length > 0 ? /* @__PURE__ */ jsx(CommandGroup, { heading: labels.recommended, children: recommended.map((entry) => /* @__PURE__ */ jsx(
|
|
4739
|
+
OptionRow,
|
|
4740
|
+
{
|
|
4741
|
+
entry,
|
|
4742
|
+
selected: selectedValues.has(entry.value),
|
|
4743
|
+
onSelect: () => onSelectItem(entry.value),
|
|
4744
|
+
renderOption
|
|
4745
|
+
},
|
|
4746
|
+
`rec-${entry.value}`
|
|
4747
|
+
)) }) : null,
|
|
4748
|
+
recent.length > 0 ? /* @__PURE__ */ jsx(CommandGroup, { heading: labels.recent, children: recent.map((entry) => /* @__PURE__ */ jsx(
|
|
4749
|
+
OptionRow,
|
|
4750
|
+
{
|
|
4751
|
+
entry,
|
|
4752
|
+
selected: selectedValues.has(entry.value),
|
|
4753
|
+
onSelect: () => onSelectItem(entry.value),
|
|
4754
|
+
renderOption
|
|
4755
|
+
},
|
|
4756
|
+
`recent-${entry.value}`
|
|
4757
|
+
)) }) : null,
|
|
4758
|
+
hasPinned && hasResults ? /* @__PURE__ */ jsx(CommandSeparator, {}) : null,
|
|
4759
|
+
hasResults ? /* @__PURE__ */ jsx(CommandGroup, { heading: hasPinned ? labels.results : void 0, children: results.map((entry) => /* @__PURE__ */ jsx(
|
|
4760
|
+
OptionRow,
|
|
4761
|
+
{
|
|
4762
|
+
entry,
|
|
4763
|
+
selected: selectedValues.has(entry.value),
|
|
4764
|
+
onSelect: () => onSelectItem(entry.value),
|
|
4765
|
+
renderOption
|
|
4766
|
+
},
|
|
4767
|
+
`res-${entry.value}`
|
|
4768
|
+
)) }) : null,
|
|
4769
|
+
hasMore && onLoadMore ? /* @__PURE__ */ jsx("div", { className: "p-2", children: /* @__PURE__ */ jsx(
|
|
4770
|
+
Button,
|
|
4771
|
+
{
|
|
4772
|
+
type: "button",
|
|
4773
|
+
variant: "ghost",
|
|
4774
|
+
size: "sm",
|
|
4775
|
+
className: "w-full",
|
|
4776
|
+
disabled: isLoadingMore,
|
|
4777
|
+
onClick: () => void onLoadMore(),
|
|
4778
|
+
children: isLoadingMore ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4779
|
+
/* @__PURE__ */ jsx(Loader2, { className: "size-4 animate-spin", "aria-hidden": true }),
|
|
4780
|
+
labels.loading
|
|
4781
|
+
] }) : labels.loadMore
|
|
4782
|
+
}
|
|
4783
|
+
) }) : null,
|
|
4784
|
+
createOption ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4785
|
+
/* @__PURE__ */ jsx(CommandSeparator, {}),
|
|
4786
|
+
/* @__PURE__ */ jsx(CommandGroup, { children: /* @__PURE__ */ jsx(
|
|
4787
|
+
CommandItem,
|
|
4788
|
+
{
|
|
4789
|
+
value: "__create__",
|
|
4790
|
+
onSelect: () => createOption.onSelect(),
|
|
4791
|
+
children: createOption.label
|
|
4792
|
+
}
|
|
4793
|
+
) })
|
|
4794
|
+
] }) : null
|
|
4795
|
+
] })
|
|
4796
|
+
] });
|
|
4485
4797
|
}
|
|
4486
4798
|
var defaultLabels3 = {
|
|
4799
|
+
placeholder: "Seleccionar\u2026",
|
|
4800
|
+
searchPlaceholder: "Buscar\u2026",
|
|
4801
|
+
empty: "No se encontraron resultados",
|
|
4802
|
+
loading: "Cargando\u2026",
|
|
4803
|
+
error: "No se pudo cargar la lista",
|
|
4804
|
+
recommended: "Recomendados",
|
|
4805
|
+
recent: "Recientes",
|
|
4806
|
+
results: "Resultados",
|
|
4807
|
+
done: "Listo",
|
|
4808
|
+
cancel: "Cancelar",
|
|
4809
|
+
clear: "Limpiar",
|
|
4810
|
+
selectedCount: (count) => count === 1 ? "1 seleccionado" : `${count} seleccionados`,
|
|
4811
|
+
emptyOption: "Ninguno",
|
|
4812
|
+
loadMore: "Cargar m\xE1s",
|
|
4813
|
+
dialogTitle: "Seleccionar"
|
|
4814
|
+
};
|
|
4815
|
+
function toListItems(items, getOptionValue, getOptionLabel) {
|
|
4816
|
+
if (!items?.length) return [];
|
|
4817
|
+
return items.map((item) => ({
|
|
4818
|
+
item,
|
|
4819
|
+
value: getOptionValue(item),
|
|
4820
|
+
label: getOptionLabel(item)
|
|
4821
|
+
}));
|
|
4822
|
+
}
|
|
4823
|
+
function dedupeByValue(items, exclude = /* @__PURE__ */ new Set()) {
|
|
4824
|
+
const seen = new Set(exclude);
|
|
4825
|
+
const out = [];
|
|
4826
|
+
for (const entry of items) {
|
|
4827
|
+
if (seen.has(entry.value)) continue;
|
|
4828
|
+
seen.add(entry.value);
|
|
4829
|
+
out.push(entry);
|
|
4830
|
+
}
|
|
4831
|
+
return out;
|
|
4832
|
+
}
|
|
4833
|
+
function matchesQuery(entry, query, getOptionKeywords) {
|
|
4834
|
+
if (!query.trim()) return true;
|
|
4835
|
+
if (fuzzyMatch(query, entry.label)) return true;
|
|
4836
|
+
return getOptionKeywords?.(entry.item)?.some(
|
|
4837
|
+
(keyword) => fuzzyMatch(query, keyword)
|
|
4838
|
+
) ?? false;
|
|
4839
|
+
}
|
|
4840
|
+
function SearchablePicker(props) {
|
|
4841
|
+
const {
|
|
4842
|
+
options,
|
|
4843
|
+
fetchOptions,
|
|
4844
|
+
getOptionValue,
|
|
4845
|
+
getOptionLabel,
|
|
4846
|
+
getOptionKeywords,
|
|
4847
|
+
renderOption,
|
|
4848
|
+
renderValue,
|
|
4849
|
+
pinned,
|
|
4850
|
+
labels: userLabels,
|
|
4851
|
+
minQueryLength = 0,
|
|
4852
|
+
debounceMs = 200,
|
|
4853
|
+
disabled,
|
|
4854
|
+
open: openProp,
|
|
4855
|
+
onOpenChange,
|
|
4856
|
+
clearable,
|
|
4857
|
+
allowEmpty,
|
|
4858
|
+
emptyLabel,
|
|
4859
|
+
keepOpenOnSelect,
|
|
4860
|
+
maxSelected,
|
|
4861
|
+
createOption,
|
|
4862
|
+
onLoadMore,
|
|
4863
|
+
hasMore,
|
|
4864
|
+
className,
|
|
4865
|
+
triggerClassName: triggerClassName2,
|
|
4866
|
+
id,
|
|
4867
|
+
"aria-labelledby": ariaLabelledBy,
|
|
4868
|
+
"aria-label": ariaLabel
|
|
4869
|
+
} = props;
|
|
4870
|
+
const mode = props.mode ?? "single";
|
|
4871
|
+
const labels = { ...defaultLabels3, ...userLabels };
|
|
4872
|
+
const resolvedEmptyLabel = emptyLabel ?? labels.emptyOption;
|
|
4873
|
+
const isMobile = useMediaQuery2("(max-width: 767px)");
|
|
4874
|
+
const generatedId = useId();
|
|
4875
|
+
const triggerId = id ?? generatedId;
|
|
4876
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(false);
|
|
4877
|
+
const open = openProp ?? uncontrolledOpen;
|
|
4878
|
+
const setOpen = useCallback(
|
|
4879
|
+
(next) => {
|
|
4880
|
+
onOpenChange?.(next);
|
|
4881
|
+
if (openProp === void 0) setUncontrolledOpen(next);
|
|
4882
|
+
},
|
|
4883
|
+
[onOpenChange, openProp]
|
|
4884
|
+
);
|
|
4885
|
+
const [query, setQuery] = useState("");
|
|
4886
|
+
const [remoteItems, setRemoteItems] = useState([]);
|
|
4887
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
4888
|
+
const [hasError, setHasError] = useState(false);
|
|
4889
|
+
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
|
4890
|
+
const debouncedQuery = useDebouncedValue(query, debounceMs);
|
|
4891
|
+
const requestIdRef = useRef(0);
|
|
4892
|
+
const knownItemsRef = useRef(/* @__PURE__ */ new Map());
|
|
4893
|
+
const rememberItems = useCallback(
|
|
4894
|
+
(items) => {
|
|
4895
|
+
for (const item of items) {
|
|
4896
|
+
knownItemsRef.current.set(getOptionValue(item), item);
|
|
4897
|
+
}
|
|
4898
|
+
},
|
|
4899
|
+
[getOptionValue]
|
|
4900
|
+
);
|
|
4901
|
+
useEffect(() => {
|
|
4902
|
+
if (options) rememberItems(options);
|
|
4903
|
+
if (pinned?.recommended) rememberItems(pinned.recommended);
|
|
4904
|
+
if (pinned?.recent) rememberItems(pinned.recent);
|
|
4905
|
+
}, [options, pinned, rememberItems]);
|
|
4906
|
+
useEffect(() => {
|
|
4907
|
+
if (!open) {
|
|
4908
|
+
setQuery("");
|
|
4909
|
+
setRemoteItems([]);
|
|
4910
|
+
setHasError(false);
|
|
4911
|
+
setIsLoading(false);
|
|
4912
|
+
}
|
|
4913
|
+
}, [open]);
|
|
4914
|
+
const trimmedDebounced = debouncedQuery.trim();
|
|
4915
|
+
const shouldFetch = Boolean(fetchOptions) && open && trimmedDebounced.length >= minQueryLength && (trimmedDebounced.length > 0 || !options);
|
|
4916
|
+
useEffect(() => {
|
|
4917
|
+
if (!shouldFetch || !fetchOptions) {
|
|
4918
|
+
if (!trimmedDebounced) {
|
|
4919
|
+
setRemoteItems([]);
|
|
4920
|
+
setHasError(false);
|
|
4921
|
+
setIsLoading(false);
|
|
4922
|
+
}
|
|
4923
|
+
return;
|
|
4924
|
+
}
|
|
4925
|
+
const requestId = ++requestIdRef.current;
|
|
4926
|
+
setIsLoading(true);
|
|
4927
|
+
setHasError(false);
|
|
4928
|
+
fetchOptions(trimmedDebounced).then((result) => {
|
|
4929
|
+
if (requestIdRef.current !== requestId) return;
|
|
4930
|
+
setRemoteItems(result);
|
|
4931
|
+
rememberItems(result);
|
|
4932
|
+
}).catch(() => {
|
|
4933
|
+
if (requestIdRef.current !== requestId) return;
|
|
4934
|
+
setRemoteItems([]);
|
|
4935
|
+
setHasError(true);
|
|
4936
|
+
}).finally(() => {
|
|
4937
|
+
if (requestIdRef.current !== requestId) return;
|
|
4938
|
+
setIsLoading(false);
|
|
4939
|
+
});
|
|
4940
|
+
}, [shouldFetch, fetchOptions, trimmedDebounced, rememberItems]);
|
|
4941
|
+
const selectedValues = useMemo(() => {
|
|
4942
|
+
if (mode === "multiple") {
|
|
4943
|
+
const multiValue = props.value ?? [];
|
|
4944
|
+
return new Set(multiValue);
|
|
4945
|
+
}
|
|
4946
|
+
const singleValue = props.value;
|
|
4947
|
+
return singleValue ? /* @__PURE__ */ new Set([singleValue]) : /* @__PURE__ */ new Set();
|
|
4948
|
+
}, [mode, props]);
|
|
4949
|
+
const selectedValueKey = mode === "multiple" ? (props.value ?? []).join("\0") : props.value ?? "";
|
|
4950
|
+
const selectedItems = useMemo(() => {
|
|
4951
|
+
const values = mode === "multiple" ? selectedValueKey ? selectedValueKey.split("\0") : [] : selectedValueKey ? [selectedValueKey] : [];
|
|
4952
|
+
return values.map((value) => knownItemsRef.current.get(value)).filter((item) => item !== void 0);
|
|
4953
|
+
}, [mode, selectedValueKey, options, pinned, remoteItems]);
|
|
4954
|
+
const queryForFilter = query.trim();
|
|
4955
|
+
const recommended = useMemo(() => {
|
|
4956
|
+
if (queryForFilter) return [];
|
|
4957
|
+
const pinnedValues = /* @__PURE__ */ new Set();
|
|
4958
|
+
const items = dedupeByValue(
|
|
4959
|
+
toListItems(pinned?.recommended, getOptionValue, getOptionLabel)
|
|
4960
|
+
);
|
|
4961
|
+
for (const entry of items) pinnedValues.add(entry.value);
|
|
4962
|
+
return items;
|
|
4963
|
+
}, [queryForFilter, pinned?.recommended, getOptionValue, getOptionLabel]);
|
|
4964
|
+
const recent = useMemo(() => {
|
|
4965
|
+
if (queryForFilter) return [];
|
|
4966
|
+
const exclude = new Set(recommended.map((e) => e.value));
|
|
4967
|
+
return dedupeByValue(
|
|
4968
|
+
toListItems(pinned?.recent, getOptionValue, getOptionLabel),
|
|
4969
|
+
exclude
|
|
4970
|
+
);
|
|
4971
|
+
}, [
|
|
4972
|
+
queryForFilter,
|
|
4973
|
+
pinned?.recent,
|
|
4974
|
+
recommended,
|
|
4975
|
+
getOptionValue,
|
|
4976
|
+
getOptionLabel
|
|
4977
|
+
]);
|
|
4978
|
+
const pinnedValueSet = useMemo(() => {
|
|
4979
|
+
const set = /* @__PURE__ */ new Set();
|
|
4980
|
+
for (const entry of recommended) set.add(entry.value);
|
|
4981
|
+
for (const entry of recent) set.add(entry.value);
|
|
4982
|
+
return set;
|
|
4983
|
+
}, [recommended, recent]);
|
|
4984
|
+
const results = useMemo(() => {
|
|
4985
|
+
const usingRemote = Boolean(fetchOptions) && trimmedDebounced.length >= minQueryLength && (trimmedDebounced.length > 0 || !options);
|
|
4986
|
+
if (usingRemote) {
|
|
4987
|
+
return dedupeByValue(
|
|
4988
|
+
toListItems(remoteItems, getOptionValue, getOptionLabel),
|
|
4989
|
+
queryForFilter ? /* @__PURE__ */ new Set() : pinnedValueSet
|
|
4990
|
+
);
|
|
4991
|
+
}
|
|
4992
|
+
const staticItems = toListItems(options, getOptionValue, getOptionLabel);
|
|
4993
|
+
const filtered = staticItems.filter(
|
|
4994
|
+
(entry) => matchesQuery(entry, queryForFilter, getOptionKeywords)
|
|
4995
|
+
);
|
|
4996
|
+
return dedupeByValue(filtered, queryForFilter ? /* @__PURE__ */ new Set() : pinnedValueSet);
|
|
4997
|
+
}, [
|
|
4998
|
+
fetchOptions,
|
|
4999
|
+
trimmedDebounced,
|
|
5000
|
+
minQueryLength,
|
|
5001
|
+
options,
|
|
5002
|
+
remoteItems,
|
|
5003
|
+
getOptionValue,
|
|
5004
|
+
getOptionLabel,
|
|
5005
|
+
getOptionKeywords,
|
|
5006
|
+
queryForFilter,
|
|
5007
|
+
pinnedValueSet
|
|
5008
|
+
]);
|
|
5009
|
+
const closeOnSelect = keepOpenOnSelect !== void 0 ? !keepOpenOnSelect : mode === "single";
|
|
5010
|
+
const handleSelectEmpty = useCallback(() => {
|
|
5011
|
+
if (mode === "single") {
|
|
5012
|
+
props.onValueChange?.(
|
|
5013
|
+
null
|
|
5014
|
+
);
|
|
5015
|
+
}
|
|
5016
|
+
if (closeOnSelect) setOpen(false);
|
|
5017
|
+
}, [mode, props, closeOnSelect, setOpen]);
|
|
5018
|
+
const handleSelectItem = useCallback(
|
|
5019
|
+
(value) => {
|
|
5020
|
+
if (mode === "multiple") {
|
|
5021
|
+
const current = props.value ?? [];
|
|
5022
|
+
const onChange = props.onValueChange;
|
|
5023
|
+
const exists = current.includes(value);
|
|
5024
|
+
if (exists) {
|
|
5025
|
+
onChange?.(current.filter((v) => v !== value));
|
|
5026
|
+
} else if (maxSelected !== void 0 && current.length >= maxSelected) {
|
|
5027
|
+
return;
|
|
5028
|
+
} else {
|
|
5029
|
+
onChange?.([...current, value]);
|
|
5030
|
+
}
|
|
5031
|
+
if (closeOnSelect) setOpen(false);
|
|
5032
|
+
return;
|
|
5033
|
+
}
|
|
5034
|
+
props.onValueChange?.(
|
|
5035
|
+
value
|
|
5036
|
+
);
|
|
5037
|
+
if (closeOnSelect) setOpen(false);
|
|
5038
|
+
},
|
|
5039
|
+
[mode, props, maxSelected, closeOnSelect, setOpen]
|
|
5040
|
+
);
|
|
5041
|
+
const handleClear = useCallback(
|
|
5042
|
+
(event) => {
|
|
5043
|
+
event.preventDefault();
|
|
5044
|
+
event.stopPropagation();
|
|
5045
|
+
if (mode === "multiple") {
|
|
5046
|
+
props.onValueChange?.(
|
|
5047
|
+
[]
|
|
5048
|
+
);
|
|
5049
|
+
} else {
|
|
5050
|
+
props.onValueChange?.(null);
|
|
5051
|
+
}
|
|
5052
|
+
},
|
|
5053
|
+
[mode, props]
|
|
5054
|
+
);
|
|
5055
|
+
const handleLoadMore = useCallback(async () => {
|
|
5056
|
+
if (!onLoadMore || isLoadingMore) return;
|
|
5057
|
+
setIsLoadingMore(true);
|
|
5058
|
+
try {
|
|
5059
|
+
await onLoadMore();
|
|
5060
|
+
} finally {
|
|
5061
|
+
setIsLoadingMore(false);
|
|
5062
|
+
}
|
|
5063
|
+
}, [onLoadMore, isLoadingMore]);
|
|
5064
|
+
const triggerLabel = useMemo(() => {
|
|
5065
|
+
if (renderValue) {
|
|
5066
|
+
if (mode === "multiple") {
|
|
5067
|
+
return renderValue(selectedItems);
|
|
5068
|
+
}
|
|
5069
|
+
return renderValue(selectedItems[0] ?? null);
|
|
5070
|
+
}
|
|
5071
|
+
if (mode === "multiple") {
|
|
5072
|
+
const count = selectedValues.size;
|
|
5073
|
+
if (count === 0) {
|
|
5074
|
+
return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: labels.placeholder });
|
|
5075
|
+
}
|
|
5076
|
+
if (selectedItems.length === 1) {
|
|
5077
|
+
return getOptionLabel(selectedItems[0]);
|
|
5078
|
+
}
|
|
5079
|
+
return labels.selectedCount(count);
|
|
5080
|
+
}
|
|
5081
|
+
if (selectedValues.size === 0) {
|
|
5082
|
+
return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: allowEmpty ? resolvedEmptyLabel : labels.placeholder });
|
|
5083
|
+
}
|
|
5084
|
+
if (selectedItems[0]) {
|
|
5085
|
+
return getOptionLabel(selectedItems[0]);
|
|
5086
|
+
}
|
|
5087
|
+
const only = [...selectedValues][0];
|
|
5088
|
+
return only ?? labels.placeholder;
|
|
5089
|
+
}, [
|
|
5090
|
+
renderValue,
|
|
5091
|
+
mode,
|
|
5092
|
+
selectedItems,
|
|
5093
|
+
selectedValues,
|
|
5094
|
+
labels,
|
|
5095
|
+
getOptionLabel,
|
|
5096
|
+
allowEmpty,
|
|
5097
|
+
resolvedEmptyLabel
|
|
5098
|
+
]);
|
|
5099
|
+
const showClear = clearable && !disabled && (mode === "multiple" ? selectedValues.size > 0 : selectedValues.size > 0);
|
|
5100
|
+
const list = /* @__PURE__ */ jsx(
|
|
5101
|
+
SearchablePickerList,
|
|
5102
|
+
{
|
|
5103
|
+
query,
|
|
5104
|
+
onQueryChange: setQuery,
|
|
5105
|
+
labels,
|
|
5106
|
+
isLoading,
|
|
5107
|
+
hasError,
|
|
5108
|
+
recommended,
|
|
5109
|
+
recent,
|
|
5110
|
+
results,
|
|
5111
|
+
selectedValues,
|
|
5112
|
+
mode,
|
|
5113
|
+
allowEmpty,
|
|
5114
|
+
emptyLabel: resolvedEmptyLabel,
|
|
5115
|
+
onSelectEmpty: handleSelectEmpty,
|
|
5116
|
+
onSelectItem: handleSelectItem,
|
|
5117
|
+
renderOption,
|
|
5118
|
+
createOption,
|
|
5119
|
+
onLoadMore: onLoadMore ? handleLoadMore : void 0,
|
|
5120
|
+
hasMore,
|
|
5121
|
+
isLoadingMore,
|
|
5122
|
+
listClassName: isMobile ? "max-h-[min(50vh,360px)]" : "max-h-72"
|
|
5123
|
+
}
|
|
5124
|
+
);
|
|
5125
|
+
const triggerButton = /* @__PURE__ */ jsxs(
|
|
5126
|
+
Button,
|
|
5127
|
+
{
|
|
5128
|
+
type: "button",
|
|
5129
|
+
variant: "outline",
|
|
5130
|
+
role: "combobox",
|
|
5131
|
+
id: triggerId,
|
|
5132
|
+
"aria-expanded": open,
|
|
5133
|
+
"aria-labelledby": ariaLabelledBy,
|
|
5134
|
+
"aria-label": ariaLabel ?? labels.placeholder,
|
|
5135
|
+
disabled,
|
|
5136
|
+
className: cn("w-full justify-between font-normal", triggerClassName2),
|
|
5137
|
+
children: [
|
|
5138
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: triggerLabel }),
|
|
5139
|
+
/* @__PURE__ */ jsx(ChevronsUpDown, { className: "ml-2 size-4 shrink-0 opacity-50", "aria-hidden": true })
|
|
5140
|
+
]
|
|
5141
|
+
}
|
|
5142
|
+
);
|
|
5143
|
+
const clearButton = showClear ? /* @__PURE__ */ jsx(
|
|
5144
|
+
Button,
|
|
5145
|
+
{
|
|
5146
|
+
type: "button",
|
|
5147
|
+
variant: "ghost",
|
|
5148
|
+
size: "icon-sm",
|
|
5149
|
+
"aria-label": labels.clear,
|
|
5150
|
+
disabled,
|
|
5151
|
+
className: "shrink-0",
|
|
5152
|
+
onClick: handleClear,
|
|
5153
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4" })
|
|
5154
|
+
}
|
|
5155
|
+
) : null;
|
|
5156
|
+
if (isMobile) {
|
|
5157
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex w-full items-center gap-1", className), children: [
|
|
5158
|
+
/* @__PURE__ */ jsx(
|
|
5159
|
+
"div",
|
|
5160
|
+
{
|
|
5161
|
+
className: "min-w-0 flex-1",
|
|
5162
|
+
onClick: () => {
|
|
5163
|
+
if (!disabled) setOpen(true);
|
|
5164
|
+
},
|
|
5165
|
+
children: triggerButton
|
|
5166
|
+
}
|
|
5167
|
+
),
|
|
5168
|
+
clearButton,
|
|
5169
|
+
/* @__PURE__ */ jsx(Drawer, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(DrawerContent, { className: "max-h-[90vh]", children: [
|
|
5170
|
+
/* @__PURE__ */ jsx(DrawerHeader, { className: "text-left", children: /* @__PURE__ */ jsx(DrawerTitle, { children: labels.dialogTitle }) }),
|
|
5171
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-hidden px-2 pb-2", children: list }),
|
|
5172
|
+
mode === "multiple" ? /* @__PURE__ */ jsxs(DrawerFooter, { className: "flex-row gap-2", children: [
|
|
5173
|
+
/* @__PURE__ */ jsx(
|
|
5174
|
+
Button,
|
|
5175
|
+
{
|
|
5176
|
+
type: "button",
|
|
5177
|
+
variant: "outline",
|
|
5178
|
+
className: "flex-1",
|
|
5179
|
+
onClick: () => setOpen(false),
|
|
5180
|
+
children: labels.cancel
|
|
5181
|
+
}
|
|
5182
|
+
),
|
|
5183
|
+
/* @__PURE__ */ jsx(
|
|
5184
|
+
Button,
|
|
5185
|
+
{
|
|
5186
|
+
type: "button",
|
|
5187
|
+
className: "flex-1",
|
|
5188
|
+
onClick: () => setOpen(false),
|
|
5189
|
+
children: labels.done
|
|
5190
|
+
}
|
|
5191
|
+
)
|
|
5192
|
+
] }) : null
|
|
5193
|
+
] }) })
|
|
5194
|
+
] });
|
|
5195
|
+
}
|
|
5196
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex w-full items-center gap-1", className), children: [
|
|
5197
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, modal: true, children: [
|
|
5198
|
+
/* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: triggerButton }),
|
|
5199
|
+
/* @__PURE__ */ jsx(
|
|
5200
|
+
PopoverContent,
|
|
5201
|
+
{
|
|
5202
|
+
className: "w-[var(--radix-popover-trigger-width)] min-w-[240px] p-0",
|
|
5203
|
+
align: "start",
|
|
5204
|
+
children: list
|
|
5205
|
+
}
|
|
5206
|
+
)
|
|
5207
|
+
] }) }),
|
|
5208
|
+
clearButton
|
|
5209
|
+
] });
|
|
5210
|
+
}
|
|
5211
|
+
var defaultLabels4 = {
|
|
4487
5212
|
placeholder: "Buscar en toda la plataforma\u2026",
|
|
4488
5213
|
dialogTitle: "Buscar",
|
|
4489
5214
|
dialogDescription: "Busca funcionalidades, eventos, documentos y m\xE1s",
|
|
@@ -4517,7 +5242,7 @@ function SearchCommand({
|
|
|
4517
5242
|
debounceMs = 200,
|
|
4518
5243
|
className
|
|
4519
5244
|
}) {
|
|
4520
|
-
const labels = { ...
|
|
5245
|
+
const labels = { ...defaultLabels4, ...userLabels };
|
|
4521
5246
|
const [query, setQuery] = useState("");
|
|
4522
5247
|
const [hits, setHits] = useState([]);
|
|
4523
5248
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -5398,18 +6123,6 @@ function ChatMessageList({
|
|
|
5398
6123
|
/* @__PURE__ */ jsx(MessageScrollerButton, {})
|
|
5399
6124
|
] }) });
|
|
5400
6125
|
}
|
|
5401
|
-
function useMediaQuery2(query) {
|
|
5402
|
-
const [matches, setMatches] = useState(false);
|
|
5403
|
-
useEffect(() => {
|
|
5404
|
-
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
5405
|
-
const mql = window.matchMedia(query);
|
|
5406
|
-
const onChange = () => setMatches(mql.matches);
|
|
5407
|
-
onChange();
|
|
5408
|
-
mql.addEventListener("change", onChange);
|
|
5409
|
-
return () => mql.removeEventListener("change", onChange);
|
|
5410
|
-
}, [query]);
|
|
5411
|
-
return matches;
|
|
5412
|
-
}
|
|
5413
6126
|
var RECONNECT_DELAY_MS = 2e3;
|
|
5414
6127
|
function useSupportConversation({
|
|
5415
6128
|
client,
|
|
@@ -6028,6 +6741,6 @@ function createSupportChatClient(basePath = "/api/chat-svc") {
|
|
|
6028
6741
|
};
|
|
6029
6742
|
}
|
|
6030
6743
|
|
|
6031
|
-
export { AvatarEditor, AvatarEditorDialog, Bubble, BubbleContent, BubbleGroup, BubbleReactions, ChatMessageList, ConfirmDestructiveDialog, EmojiInput, EmojiPicker, EmojiPickerPopover, EmojiTextarea, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyState, EmptyTitle, ErrorState, ExpandableText, ImageLightbox, LanguageContext, LanguageSwitcher, LoadingState, MEXICO_STATES, MEXICO_STATE_PATHS, Marker, MarkerContent, MarkerIcon, Message, MessageAvatar, MessageContent, MessageFooter, MessageGroup, MessageHeader, MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, MexicoMap, OrgSwitcher, PhoneInput, SearchCommand, SupportMessengerProvider, ThemeSwitcher, VerifiedProfessionalBadge, VideoPlayer, avatarFallbackStyle, bubbleVariants, cn, createLiveHlsConfig, createSupportChatClient, createVodHlsConfig, defaultLanguages, describePlaybackError, fuzzyMatch, getAvatarColors, getInitials, insertAtCaret, markerVariants, normalizeEmojiQuery, shouldRetryLiveEdge404, useDebouncedValue, useDebouncedValueStrict, useHlsPlayback, useLanguageContext, usePlaybackStats, useSearchHotkey, useSupportConversation, useSupportMessenger, useSupportMessengerOptional };
|
|
6744
|
+
export { AvatarEditor, AvatarEditorDialog, Bubble, BubbleContent, BubbleGroup, BubbleReactions, ChatMessageList, ConfirmDestructiveDialog, EmojiInput, EmojiPicker, EmojiPickerPopover, EmojiTextarea, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyState, EmptyTitle, ErrorState, ExpandableText, ImageLightbox, LanguageContext, LanguageSwitcher, LoadingState, MEXICO_STATES, MEXICO_STATE_PATHS, Marker, MarkerContent, MarkerIcon, Message, MessageAvatar, MessageContent, MessageFooter, MessageGroup, MessageHeader, MessageScroller, MessageScrollerButton, MessageScrollerContent, MessageScrollerItem, MessageScrollerProvider, MessageScrollerViewport, MexicoMap, OrgSwitcher, PhoneInput, SearchCommand, SearchablePicker, SupportMessengerProvider, ThemeSwitcher, VerifiedProfessionalBadge, VideoPlayer, avatarFallbackStyle, bubbleVariants, cn, createLiveHlsConfig, createSupportChatClient, createVodHlsConfig, defaultLanguages, describePlaybackError, fuzzyMatch, getAvatarColors, getInitials, insertAtCaret, markerVariants, normalizeEmojiQuery, shouldRetryLiveEdge404, useDebouncedValue, useDebouncedValueStrict, useHlsPlayback, useLanguageContext, useMediaQuery2 as useMediaQuery, usePlaybackStats, useSearchHotkey, useSupportConversation, useSupportMessenger, useSupportMessengerOptional };
|
|
6032
6745
|
//# sourceMappingURL=index.js.map
|
|
6033
6746
|
//# sourceMappingURL=index.js.map
|