@sesionario/blocks 1.9.0 → 1.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var React6 = require('react');
4
+ var React7 = require('react');
5
5
  var lucideReact = require('lucide-react');
6
6
  var clsx = require('clsx');
7
7
  var tailwindMerge = require('tailwind-merge');
@@ -44,7 +44,7 @@ function _interopNamespace(e) {
44
44
  return Object.freeze(n);
45
45
  }
46
46
 
47
- var React6__namespace = /*#__PURE__*/_interopNamespace(React6);
47
+ var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
48
48
  var AlertDialogPrimitive__namespace = /*#__PURE__*/_interopNamespace(AlertDialogPrimitive);
49
49
  var DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespace(DropdownMenuPrimitive);
50
50
  var SliderPrimitive__namespace = /*#__PURE__*/_interopNamespace(SliderPrimitive);
@@ -55,9 +55,9 @@ var RPNInput__namespace = /*#__PURE__*/_interopNamespace(RPNInput);
55
55
  var flags__default = /*#__PURE__*/_interopDefault(flags);
56
56
  var ScrollAreaPrimitive__namespace = /*#__PURE__*/_interopNamespace(ScrollAreaPrimitive);
57
57
 
58
- var LanguageContext = React6.createContext(null);
58
+ var LanguageContext = React7.createContext(null);
59
59
  function useLanguageContext() {
60
- return React6.useContext(LanguageContext);
60
+ return React7.useContext(LanguageContext);
61
61
  }
62
62
  function cn(...inputs) {
63
63
  return tailwindMerge.twMerge(clsx.clsx(inputs));
@@ -464,13 +464,13 @@ function ExpandableText({
464
464
  className,
465
465
  textClassName
466
466
  }) {
467
- const [expanded, setExpanded] = React6.useState(false);
468
- const [overflowing, setOverflowing] = React6.useState(false);
469
- const contentRef = React6.useRef(null);
470
- React6.useEffect(() => {
467
+ const [expanded, setExpanded] = React7.useState(false);
468
+ const [overflowing, setOverflowing] = React7.useState(false);
469
+ const contentRef = React7.useRef(null);
470
+ React7.useEffect(() => {
471
471
  setExpanded(false);
472
472
  }, [children]);
473
- React6.useLayoutEffect(() => {
473
+ React7.useLayoutEffect(() => {
474
474
  const el = contentRef.current;
475
475
  if (!el) return;
476
476
  const measure = () => {
@@ -521,6 +521,9 @@ function ExpandableText({
521
521
  var MIN_SCALE = 1;
522
522
  var MAX_SCALE = 4;
523
523
  var DOUBLE_TAP_MS = 300;
524
+ var SWIPE_LOCK_PX = 8;
525
+ var SWIPE_COMMIT_PX = 56;
526
+ var SWIPE_SNAP_MS = 180;
524
527
  var IDENTITY = { scale: 1, tx: 0, ty: 0 };
525
528
  function clamp(value, min, max) {
526
529
  return Math.min(max, Math.max(min, value));
@@ -538,6 +541,10 @@ function zoomToward(prev, nextScale, originX, originY) {
538
541
  function pointerDistance(a, b) {
539
542
  return Math.hypot(b.x - a.x, b.y - a.y);
540
543
  }
544
+ function prefersReducedMotion() {
545
+ if (typeof window === "undefined" || !window.matchMedia) return false;
546
+ return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
547
+ }
541
548
  function ImageLightbox({
542
549
  images,
543
550
  index,
@@ -550,20 +557,29 @@ function ImageLightbox({
550
557
  const previousLabel = labels?.previous ?? "Anterior";
551
558
  const nextLabel = labels?.next ?? "Siguiente";
552
559
  const hasMultiple = images.length > 1;
553
- const [transform, setTransform] = React6.useState(IDENTITY);
554
- const transformRef = React6.useRef(transform);
560
+ const [transform, setTransform] = React7.useState(IDENTITY);
561
+ const transformRef = React7.useRef(transform);
555
562
  transformRef.current = transform;
556
- const stageRef = React6.useRef(null);
557
- const pointersRef = React6.useRef(/* @__PURE__ */ new Map());
558
- const pinchStartRef = React6.useRef(null);
559
- const panRef = React6.useRef(null);
560
- const lastTapRef = React6.useRef(
563
+ const [isSwipeDragging, setIsSwipeDragging] = React7.useState(false);
564
+ const [snapBack, setSnapBack] = React7.useState(false);
565
+ const stageRef = React7.useRef(null);
566
+ const pointersRef = React7.useRef(/* @__PURE__ */ new Map());
567
+ const pinchStartRef = React7.useRef(null);
568
+ const panRef = React7.useRef(null);
569
+ const swipeRef = React7.useRef(null);
570
+ const lastTapRef = React7.useRef(
561
571
  null
562
572
  );
563
- const resetZoom = React6.useCallback(() => {
573
+ const indexRef = React7.useRef(index);
574
+ indexRef.current = index;
575
+ const imagesLengthRef = React7.useRef(images.length);
576
+ imagesLengthRef.current = images.length;
577
+ const resetZoom = React7.useCallback(() => {
564
578
  setTransform(IDENTITY);
579
+ setIsSwipeDragging(false);
580
+ setSnapBack(false);
565
581
  }, []);
566
- React6.useEffect(() => {
582
+ React7.useEffect(() => {
567
583
  resetZoom();
568
584
  }, [index, images[index], resetZoom]);
569
585
  function goPrev() {
@@ -572,7 +588,7 @@ function ImageLightbox({
572
588
  function goNext() {
573
589
  onIndexChange((index + 1) % images.length);
574
590
  }
575
- React6.useEffect(() => {
591
+ React7.useEffect(() => {
576
592
  function handleKeyDown(e) {
577
593
  if (e.key === "Escape") {
578
594
  onClose();
@@ -588,14 +604,14 @@ function ImageLightbox({
588
604
  window.addEventListener("keydown", handleKeyDown);
589
605
  return () => window.removeEventListener("keydown", handleKeyDown);
590
606
  }, [index, images.length, hasMultiple, onClose, onIndexChange]);
591
- React6.useEffect(() => {
607
+ React7.useEffect(() => {
592
608
  const previousOverflow = document.body.style.overflow;
593
609
  document.body.style.overflow = "hidden";
594
610
  return () => {
595
611
  document.body.style.overflow = previousOverflow;
596
612
  };
597
613
  }, []);
598
- const stageOrigin = React6.useCallback((clientX, clientY) => {
614
+ const stageOrigin = React7.useCallback((clientX, clientY) => {
599
615
  const stage = stageRef.current;
600
616
  if (!stage) return { x: 0, y: 0 };
601
617
  const rect = stage.getBoundingClientRect();
@@ -604,7 +620,7 @@ function ImageLightbox({
604
620
  y: clientY - rect.top - rect.height / 2
605
621
  };
606
622
  }, []);
607
- React6.useEffect(() => {
623
+ React7.useEffect(() => {
608
624
  const stage = stageRef.current;
609
625
  if (!stage) return;
610
626
  const handleWheel = (e) => {
@@ -618,6 +634,10 @@ function ImageLightbox({
618
634
  stage.addEventListener("wheel", handleWheel, { passive: false });
619
635
  return () => stage.removeEventListener("wheel", handleWheel);
620
636
  }, [stageOrigin]);
637
+ function clearSwipe() {
638
+ swipeRef.current = null;
639
+ setIsSwipeDragging(false);
640
+ }
621
641
  function beginPinch() {
622
642
  const pts = [...pointersRef.current.values()];
623
643
  const [a, b] = pts;
@@ -632,13 +652,18 @@ function ImageLightbox({
632
652
  transform: { ...transformRef.current }
633
653
  };
634
654
  panRef.current = null;
655
+ clearSwipe();
656
+ setSnapBack(false);
635
657
  }
636
658
  function onPointerDown(e) {
637
659
  e.stopPropagation();
638
660
  const stage = stageRef.current;
639
661
  if (!stage) return;
640
- stage.setPointerCapture(e.pointerId);
662
+ if (typeof stage.setPointerCapture === "function") {
663
+ stage.setPointerCapture(e.pointerId);
664
+ }
641
665
  pointersRef.current.set(e.pointerId, { x: e.clientX, y: e.clientY });
666
+ setSnapBack(false);
642
667
  if (pointersRef.current.size === 2) {
643
668
  beginPinch();
644
669
  return;
@@ -652,6 +677,17 @@ function ImageLightbox({
652
677
  originTy: transformRef.current.ty,
653
678
  moved: false
654
679
  };
680
+ return;
681
+ }
682
+ if (hasMultiple) {
683
+ swipeRef.current = {
684
+ pointerId: e.pointerId,
685
+ startX: e.clientX,
686
+ startY: e.clientY,
687
+ moved: false,
688
+ axis: null
689
+ };
690
+ setIsSwipeDragging(true);
655
691
  }
656
692
  }
657
693
  function onPointerMove(e) {
@@ -676,19 +712,62 @@ function ImageLightbox({
676
712
  }
677
713
  const pan = panRef.current;
678
714
  if (pan && pan.pointerId === e.pointerId) {
679
- const dx = e.clientX - pan.startX;
680
- const dy = e.clientY - pan.startY;
681
- if (Math.abs(dx) > 2 || Math.abs(dy) > 2) pan.moved = true;
715
+ const dx2 = e.clientX - pan.startX;
716
+ const dy2 = e.clientY - pan.startY;
717
+ if (Math.abs(dx2) > 2 || Math.abs(dy2) > 2) pan.moved = true;
682
718
  setTransform((prev) => ({
683
719
  ...prev,
684
- tx: pan.originTx + dx,
685
- ty: pan.originTy + dy
720
+ tx: pan.originTx + dx2,
721
+ ty: pan.originTy + dy2
686
722
  }));
723
+ return;
724
+ }
725
+ const swipe = swipeRef.current;
726
+ if (!swipe || swipe.pointerId !== e.pointerId) return;
727
+ const dx = e.clientX - swipe.startX;
728
+ const dy = e.clientY - swipe.startY;
729
+ if (Math.abs(dx) > 2 || Math.abs(dy) > 2) swipe.moved = true;
730
+ if (swipe.axis === null) {
731
+ const absX = Math.abs(dx);
732
+ const absY = Math.abs(dy);
733
+ if (absX < SWIPE_LOCK_PX && absY < SWIPE_LOCK_PX) return;
734
+ swipe.axis = absX >= absY ? "x" : "y";
735
+ if (swipe.axis === "y") {
736
+ clearSwipe();
737
+ setTransform(IDENTITY);
738
+ return;
739
+ }
740
+ }
741
+ if (swipe.axis === "x") {
742
+ setTransform({ scale: MIN_SCALE, tx: dx, ty: 0 });
687
743
  }
688
744
  }
745
+ function finishSwipe(e) {
746
+ const swipe = swipeRef.current;
747
+ if (!swipe || swipe.pointerId !== e.pointerId) return false;
748
+ const dx = e.clientX - swipe.startX;
749
+ const wasMoved = swipe.moved;
750
+ const axis = swipe.axis;
751
+ clearSwipe();
752
+ if (axis === "x" && Math.abs(dx) >= SWIPE_COMMIT_PX) {
753
+ const length = imagesLengthRef.current;
754
+ const current = indexRef.current;
755
+ if (dx < 0) {
756
+ onIndexChange((current + 1) % length);
757
+ } else {
758
+ onIndexChange((current - 1 + length) % length);
759
+ }
760
+ return true;
761
+ }
762
+ if (wasMoved || transformRef.current.tx !== 0) {
763
+ if (!prefersReducedMotion()) setSnapBack(true);
764
+ setTransform(IDENTITY);
765
+ }
766
+ return wasMoved;
767
+ }
689
768
  function onPointerUp(e) {
690
769
  const stage = stageRef.current;
691
- if (stage?.hasPointerCapture(e.pointerId)) {
770
+ if (stage && typeof stage.hasPointerCapture === "function" && stage.hasPointerCapture(e.pointerId) && typeof stage.releasePointerCapture === "function") {
692
771
  stage.releasePointerCapture(e.pointerId);
693
772
  }
694
773
  pointersRef.current.delete(e.pointerId);
@@ -709,6 +788,8 @@ function ImageLightbox({
709
788
  };
710
789
  }
711
790
  }
791
+ const swipeHandled = finishSwipe(e);
792
+ if (swipeHandled) return;
712
793
  const pan = panRef.current;
713
794
  if (pan && pan.pointerId === e.pointerId) {
714
795
  const wasMoved = pan.moved;
@@ -730,6 +811,7 @@ function ImageLightbox({
730
811
  e.stopPropagation();
731
812
  }
732
813
  const { scale, tx, ty } = transform;
814
+ const transition = snapBack && !isSwipeDragging && !prefersReducedMotion() ? `transform ${SWIPE_SNAP_MS}ms ease-out` : void 0;
733
815
  return reactDom.createPortal(
734
816
  /* @__PURE__ */ jsxRuntime.jsxs(
735
817
  "div",
@@ -769,6 +851,7 @@ function ImageLightbox({
769
851
  ref: stageRef,
770
852
  className: "relative flex max-h-full max-w-full touch-none items-center justify-center",
771
853
  "data-scale": scale,
854
+ "data-swipe-dragging": isSwipeDragging ? "true" : "false",
772
855
  onClick: stopDialogClose,
773
856
  onPointerDown,
774
857
  onPointerMove,
@@ -783,8 +866,10 @@ function ImageLightbox({
783
866
  className: "max-h-[calc(100dvh-2rem)] max-w-full select-none rounded-lg object-contain",
784
867
  style: {
785
868
  transform: `translate(${tx}px, ${ty}px) scale(${scale})`,
869
+ transition,
786
870
  cursor: scale > MIN_SCALE ? "grab" : "default"
787
- }
871
+ },
872
+ onTransitionEnd: () => setSnapBack(false)
788
873
  }
789
874
  )
790
875
  }
@@ -967,18 +1052,18 @@ function ThemeSwitcher({
967
1052
  labels: userLabels
968
1053
  }) {
969
1054
  const { theme, setTheme } = nextThemes.useTheme();
970
- const [mounted, setMounted] = React6.useState(false);
1055
+ const [mounted, setMounted] = React7.useState(false);
971
1056
  const reduceMotion = framerMotion.useReducedMotion();
972
1057
  const sizes = sizeClasses[size];
973
1058
  const shapeClass = shapeClasses[shape];
974
1059
  const labels = { ...defaultLabels, ...userLabels };
975
- const handleThemeClick = React6.useCallback(
1060
+ const handleThemeClick = React7.useCallback(
976
1061
  (themeKey) => {
977
1062
  setTheme(themeKey);
978
1063
  },
979
1064
  [setTheme]
980
1065
  );
981
- React6.useEffect(() => {
1066
+ React7.useEffect(() => {
982
1067
  setMounted(true);
983
1068
  }, []);
984
1069
  if (!mounted) {
@@ -1520,7 +1605,7 @@ function Slider({
1520
1605
  max = 100,
1521
1606
  ...props
1522
1607
  }) {
1523
- const _values = React6__namespace.useMemo(
1608
+ const _values = React7__namespace.useMemo(
1524
1609
  () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
1525
1610
  [value, defaultValue, min, max]
1526
1611
  );
@@ -1614,18 +1699,18 @@ function AvatarEditor({
1614
1699
  className,
1615
1700
  controlSize = "default"
1616
1701
  }) {
1617
- const canvasRef = React6.useRef(null);
1618
- const fileInputRef = React6.useRef(null);
1619
- const containerRef = React6.useRef(null);
1620
- const [image, setImage] = React6.useState(null);
1621
- const [imageLoaded, setImageLoaded] = React6.useState(false);
1622
- const [zoom, setZoom] = React6.useState(1);
1623
- const [rotation, setRotation] = React6.useState(0);
1624
- const [position, setPosition] = React6.useState({ x: 0, y: 0 });
1625
- const [isDragging, setIsDragging] = React6.useState(false);
1626
- const [dragStart, setDragStart] = React6.useState({ x: 0, y: 0 });
1627
- const [showGrid, setShowGrid] = React6.useState(initialShowGrid);
1628
- const generateOutput = React6.useCallback(() => {
1702
+ const canvasRef = React7.useRef(null);
1703
+ const fileInputRef = React7.useRef(null);
1704
+ const containerRef = React7.useRef(null);
1705
+ const [image, setImage] = React7.useState(null);
1706
+ const [imageLoaded, setImageLoaded] = React7.useState(false);
1707
+ const [zoom, setZoom] = React7.useState(1);
1708
+ const [rotation, setRotation] = React7.useState(0);
1709
+ const [position, setPosition] = React7.useState({ x: 0, y: 0 });
1710
+ const [isDragging, setIsDragging] = React7.useState(false);
1711
+ const [dragStart, setDragStart] = React7.useState({ x: 0, y: 0 });
1712
+ const [showGrid, setShowGrid] = React7.useState(initialShowGrid);
1713
+ const generateOutput = React7.useCallback(() => {
1629
1714
  if (!canvasRef.current || !image) return null;
1630
1715
  const outputCanvas = document.createElement("canvas");
1631
1716
  outputCanvas.width = outputSize;
@@ -1636,7 +1721,7 @@ function AvatarEditor({
1636
1721
  const mimeType = `image/${outputFormat}`;
1637
1722
  return outputCanvas.toDataURL(mimeType, outputQuality);
1638
1723
  }, [image, outputSize, outputFormat, outputQuality]);
1639
- React6.useEffect(() => {
1724
+ React7.useEffect(() => {
1640
1725
  if (!canvasRef.current || !image || !imageLoaded) return;
1641
1726
  const canvas = canvasRef.current;
1642
1727
  const ctx = canvas.getContext("2d");
@@ -1704,12 +1789,12 @@ function AvatarEditor({
1704
1789
  generateOutput,
1705
1790
  onChange
1706
1791
  ]);
1707
- const resetTransforms = React6.useCallback(() => {
1792
+ const resetTransforms = React7.useCallback(() => {
1708
1793
  setZoom(1);
1709
1794
  setRotation(0);
1710
1795
  setPosition({ x: 0, y: 0 });
1711
1796
  }, []);
1712
- const handleFileSelect = React6.useCallback(
1797
+ const handleFileSelect = React7.useCallback(
1713
1798
  (e) => {
1714
1799
  const file = e.target.files?.[0];
1715
1800
  if (!file) return;
@@ -1728,7 +1813,7 @@ function AvatarEditor({
1728
1813
  },
1729
1814
  [resetTransforms]
1730
1815
  );
1731
- const handleMouseDown = React6.useCallback(
1816
+ const handleMouseDown = React7.useCallback(
1732
1817
  (e) => {
1733
1818
  if (!imageLoaded) return;
1734
1819
  setIsDragging(true);
@@ -1736,7 +1821,7 @@ function AvatarEditor({
1736
1821
  },
1737
1822
  [imageLoaded, position]
1738
1823
  );
1739
- const handleMouseMove = React6.useCallback(
1824
+ const handleMouseMove = React7.useCallback(
1740
1825
  (e) => {
1741
1826
  if (!isDragging) return;
1742
1827
  setPosition({
@@ -1746,10 +1831,10 @@ function AvatarEditor({
1746
1831
  },
1747
1832
  [isDragging, dragStart]
1748
1833
  );
1749
- const handleMouseUp = React6.useCallback(() => {
1834
+ const handleMouseUp = React7.useCallback(() => {
1750
1835
  setIsDragging(false);
1751
1836
  }, []);
1752
- const handleTouchStart = React6.useCallback(
1837
+ const handleTouchStart = React7.useCallback(
1753
1838
  (e) => {
1754
1839
  if (!imageLoaded) return;
1755
1840
  const touch = e.touches[0];
@@ -1761,7 +1846,7 @@ function AvatarEditor({
1761
1846
  },
1762
1847
  [imageLoaded, position]
1763
1848
  );
1764
- const handleTouchMove = React6.useCallback(
1849
+ const handleTouchMove = React7.useCallback(
1765
1850
  (e) => {
1766
1851
  if (!isDragging) return;
1767
1852
  const touch = e.touches[0];
@@ -1772,7 +1857,7 @@ function AvatarEditor({
1772
1857
  },
1773
1858
  [isDragging, dragStart]
1774
1859
  );
1775
- const handleDiscard = React6.useCallback(() => {
1860
+ const handleDiscard = React7.useCallback(() => {
1776
1861
  setImage(null);
1777
1862
  setImageLoaded(false);
1778
1863
  resetTransforms();
@@ -2321,8 +2406,8 @@ function DrawerTitle({
2321
2406
  );
2322
2407
  }
2323
2408
  function useMediaQuery(query) {
2324
- const [matches, setMatches] = React6.useState(false);
2325
- React6.useEffect(() => {
2409
+ const [matches, setMatches] = React7.useState(false);
2410
+ React7.useEffect(() => {
2326
2411
  const media = window.matchMedia(query);
2327
2412
  if (media.matches !== matches) {
2328
2413
  setMatches(media.matches);
@@ -2351,13 +2436,13 @@ function AvatarEditorDialog({
2351
2436
  errorMessage = "Failed to save avatar. Please try again.",
2352
2437
  className
2353
2438
  }) {
2354
- const [isOpen, setIsOpen] = React6.useState(false);
2355
- const [editedValue, setEditedValue] = React6.useState(value ?? null);
2356
- const [isSaving, setIsSaving] = React6.useState(false);
2357
- const [feedback, setFeedback] = React6.useState(null);
2439
+ const [isOpen, setIsOpen] = React7.useState(false);
2440
+ const [editedValue, setEditedValue] = React7.useState(value ?? null);
2441
+ const [isSaving, setIsSaving] = React7.useState(false);
2442
+ const [feedback, setFeedback] = React7.useState(null);
2358
2443
  const isMobile = useMediaQuery("(max-width: 640px)");
2359
2444
  const caption = (placeholder ?? "").trim();
2360
- const handleOpenChange = React6.useCallback(
2445
+ const handleOpenChange = React7.useCallback(
2361
2446
  (open) => {
2362
2447
  if (open) {
2363
2448
  setEditedValue(value ?? null);
@@ -2367,7 +2452,7 @@ function AvatarEditorDialog({
2367
2452
  },
2368
2453
  [value]
2369
2454
  );
2370
- const handleAccept = React6.useCallback(async () => {
2455
+ const handleAccept = React7.useCallback(async () => {
2371
2456
  if (!editedValue) return;
2372
2457
  setIsSaving(true);
2373
2458
  setFeedback(null);
@@ -2649,22 +2734,22 @@ function EmojiPicker({
2649
2734
  recentLimit = 24,
2650
2735
  storageKey = "blocks-emoji"
2651
2736
  }) {
2652
- const strings = React6__namespace.useMemo(
2737
+ const strings = React7__namespace.useMemo(
2653
2738
  () => ({ ...DEFAULT_LABELS[locale], ...labels }),
2654
2739
  [locale, labels]
2655
2740
  );
2656
- const titles = React6__namespace.useMemo(
2741
+ const titles = React7__namespace.useMemo(
2657
2742
  () => ({ ...DEFAULT_TITLES[locale], ...labels?.categoryTitles }),
2658
2743
  [locale, labels]
2659
2744
  );
2660
- const [query, setQuery] = React6__namespace.useState("");
2661
- const [skinTone, setSkinTone] = React6__namespace.useState(() => {
2745
+ const [query, setQuery] = React7__namespace.useState("");
2746
+ const [skinTone, setSkinTone] = React7__namespace.useState(() => {
2662
2747
  const raw = readStored(storageKey, "tone");
2663
2748
  const parsed = raw != null ? Number.parseInt(raw, 10) : 0;
2664
2749
  return parsed >= 0 && parsed <= 5 ? parsed : 0;
2665
2750
  });
2666
- const [toneOpen, setToneOpen] = React6__namespace.useState(false);
2667
- const [recents, setRecents] = React6__namespace.useState(() => {
2751
+ const [toneOpen, setToneOpen] = React7__namespace.useState(false);
2752
+ const [recents, setRecents] = React7__namespace.useState(() => {
2668
2753
  const raw = readStored(storageKey, "recent");
2669
2754
  if (!raw) return [];
2670
2755
  try {
@@ -2674,13 +2759,13 @@ function EmojiPicker({
2674
2759
  return [];
2675
2760
  }
2676
2761
  });
2677
- const [focusIndex, setFocusIndex] = React6__namespace.useState(-1);
2678
- const scrollRef = React6__namespace.useRef(null);
2679
- const sectionRefs = React6__namespace.useRef(
2762
+ const [focusIndex, setFocusIndex] = React7__namespace.useState(-1);
2763
+ const scrollRef = React7__namespace.useRef(null);
2764
+ const sectionRefs = React7__namespace.useRef(
2680
2765
  /* @__PURE__ */ new Map()
2681
2766
  );
2682
2767
  const normalizedQuery = normalizeEmojiQuery(query);
2683
- const sections = React6__namespace.useMemo(() => {
2768
+ const sections = React7__namespace.useMemo(() => {
2684
2769
  if (normalizedQuery) return [];
2685
2770
  const result = [];
2686
2771
  if (recents.length > 0) {
@@ -2699,7 +2784,7 @@ function EmojiPicker({
2699
2784
  }
2700
2785
  return result;
2701
2786
  }, [normalizedQuery, recents, titles]);
2702
- const searchResults = React6__namespace.useMemo(() => {
2787
+ const searchResults = React7__namespace.useMemo(() => {
2703
2788
  if (!normalizedQuery) return [];
2704
2789
  const out = [];
2705
2790
  for (const category of EMOJI_CATEGORIES) {
@@ -2709,21 +2794,21 @@ function EmojiPicker({
2709
2794
  }
2710
2795
  return out;
2711
2796
  }, [normalizedQuery]);
2712
- const flatList = React6__namespace.useMemo(() => {
2797
+ const flatList = React7__namespace.useMemo(() => {
2713
2798
  if (normalizedQuery) return searchResults;
2714
2799
  return sections.flatMap((s) => s.emojis);
2715
2800
  }, [normalizedQuery, searchResults, sections]);
2716
- React6__namespace.useEffect(() => {
2801
+ React7__namespace.useEffect(() => {
2717
2802
  setFocusIndex(-1);
2718
2803
  }, [normalizedQuery]);
2719
- React6__namespace.useEffect(() => {
2804
+ React7__namespace.useEffect(() => {
2720
2805
  if (focusIndex < 0) return;
2721
2806
  const el = scrollRef.current?.querySelector(
2722
2807
  `[data-emoji-index="${focusIndex}"]`
2723
2808
  );
2724
2809
  el?.focus();
2725
2810
  }, [focusIndex]);
2726
- const commitRecent = React6__namespace.useCallback(
2811
+ const commitRecent = React7__namespace.useCallback(
2727
2812
  (glyph) => {
2728
2813
  setRecents((prev) => {
2729
2814
  const next = [glyph, ...prev.filter((e) => e !== glyph)].slice(
@@ -2736,14 +2821,14 @@ function EmojiPicker({
2736
2821
  },
2737
2822
  [recentLimit, storageKey]
2738
2823
  );
2739
- const handleSelect = React6__namespace.useCallback(
2824
+ const handleSelect = React7__namespace.useCallback(
2740
2825
  (glyph) => {
2741
2826
  commitRecent(glyph);
2742
2827
  onSelect(glyph);
2743
2828
  },
2744
2829
  [commitRecent, onSelect]
2745
2830
  );
2746
- const chooseTone = React6__namespace.useCallback(
2831
+ const chooseTone = React7__namespace.useCallback(
2747
2832
  (tone) => {
2748
2833
  setSkinTone(tone);
2749
2834
  setToneOpen(false);
@@ -3049,17 +3134,17 @@ function EmojiPickerPopover({
3049
3134
  locale = "en",
3050
3135
  ...pickerProps
3051
3136
  }) {
3052
- const [internalOpen, setInternalOpen] = React6__namespace.useState(false);
3137
+ const [internalOpen, setInternalOpen] = React7__namespace.useState(false);
3053
3138
  const isControlled = open !== void 0;
3054
3139
  const isOpen = isControlled ? open : internalOpen;
3055
- const setOpen = React6__namespace.useCallback(
3140
+ const setOpen = React7__namespace.useCallback(
3056
3141
  (next) => {
3057
3142
  if (!isControlled) setInternalOpen(next);
3058
3143
  onOpenChange?.(next);
3059
3144
  },
3060
3145
  [isControlled, onOpenChange]
3061
3146
  );
3062
- const handleSelect = React6__namespace.useCallback(
3147
+ const handleSelect = React7__namespace.useCallback(
3063
3148
  (emoji) => {
3064
3149
  onSelect(emoji);
3065
3150
  if (!keepOpenOnSelect) setOpen(false);
@@ -3092,8 +3177,10 @@ function insertAtCaret(element, value, text) {
3092
3177
  caret: start + text.length
3093
3178
  };
3094
3179
  }
3095
- var wrapperClassName = "relative w-full rounded-md border border-input bg-transparent shadow-xs transition-[color,box-shadow] focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50 has-[[aria-invalid=true]]:border-destructive has-[[aria-invalid=true]]:ring-destructive/20 has-[:disabled]:opacity-50 dark:bg-input/30 dark:has-[[aria-invalid=true]]:ring-destructive/40";
3096
- var fieldResetClassName = "border-0 bg-transparent shadow-none focus-visible:border-transparent focus-visible:ring-0 dark:bg-transparent";
3180
+
3181
+ // src/components/emoji/emoji-field-shared.ts
3182
+ var emojiFieldWrapperClassName = "relative w-full rounded-md border border-input bg-transparent shadow-xs transition-[color,box-shadow] focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50 has-[[aria-invalid=true]]:border-destructive has-[[aria-invalid=true]]:ring-destructive/20 has-[:disabled]:opacity-50 dark:bg-input/30 dark:has-[[aria-invalid=true]]:ring-destructive/40";
3183
+ var emojiFieldResetClassName = "border-0 bg-transparent shadow-none focus-visible:border-transparent focus-visible:ring-0 dark:bg-transparent";
3097
3184
  function mergeRefs(...refs) {
3098
3185
  return (node) => {
3099
3186
  for (const ref of refs) {
@@ -3117,7 +3204,7 @@ function emitChange(element, nextValue, onChange) {
3117
3204
  });
3118
3205
  }
3119
3206
  function useEmojiInsert(fieldRef, value, onChange) {
3120
- return React6__namespace.useCallback(
3207
+ return React7__namespace.useCallback(
3121
3208
  (emoji) => {
3122
3209
  const el = fieldRef.current;
3123
3210
  const current = value !== void 0 && value !== null ? String(value) : el?.value ?? "";
@@ -3138,7 +3225,7 @@ function useEmojiInsert(fieldRef, value, onChange) {
3138
3225
  [fieldRef, value, onChange]
3139
3226
  );
3140
3227
  }
3141
- var EmojiTextarea = React6__namespace.forwardRef(
3228
+ var EmojiTextarea = React7__namespace.forwardRef(
3142
3229
  function EmojiTextarea2({
3143
3230
  className,
3144
3231
  locale = "en",
@@ -3158,10 +3245,10 @@ var EmojiTextarea = React6__namespace.forwardRef(
3158
3245
  emojiTriggerClassName,
3159
3246
  ...props
3160
3247
  }, ref) {
3161
- const fieldRef = React6__namespace.useRef(null);
3248
+ const fieldRef = React7__namespace.useRef(null);
3162
3249
  const handleEmojiSelect = useEmojiInsert(fieldRef, value, onChange);
3163
3250
  const pickerDisabled = Boolean(disabled || readOnly);
3164
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(wrapperClassName, className), children: [
3251
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(emojiFieldWrapperClassName, className), children: [
3165
3252
  /* @__PURE__ */ jsxRuntime.jsx(
3166
3253
  "textarea",
3167
3254
  {
@@ -3173,7 +3260,7 @@ var EmojiTextarea = React6__namespace.forwardRef(
3173
3260
  onChange,
3174
3261
  className: cn(
3175
3262
  "placeholder:text-muted-foreground flex min-h-20 w-full rounded-md px-3 py-2 pb-9 pr-10 text-base outline-none transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
3176
- fieldResetClassName,
3263
+ emojiFieldResetClassName,
3177
3264
  className
3178
3265
  ),
3179
3266
  ...props
@@ -3204,7 +3291,7 @@ var EmojiTextarea = React6__namespace.forwardRef(
3204
3291
  }
3205
3292
  );
3206
3293
  EmojiTextarea.displayName = "EmojiTextarea";
3207
- var EmojiInput = React6__namespace.forwardRef(
3294
+ var EmojiInput = React7__namespace.forwardRef(
3208
3295
  function EmojiInput2({
3209
3296
  className,
3210
3297
  locale = "en",
@@ -3225,10 +3312,10 @@ var EmojiInput = React6__namespace.forwardRef(
3225
3312
  emojiTriggerClassName,
3226
3313
  ...props
3227
3314
  }, ref) {
3228
- const fieldRef = React6__namespace.useRef(null);
3315
+ const fieldRef = React7__namespace.useRef(null);
3229
3316
  const handleEmojiSelect = useEmojiInsert(fieldRef, value, onChange);
3230
3317
  const pickerDisabled = Boolean(disabled || readOnly);
3231
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(wrapperClassName, className), children: [
3318
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(emojiFieldWrapperClassName, className), children: [
3232
3319
  /* @__PURE__ */ jsxRuntime.jsx(
3233
3320
  "input",
3234
3321
  {
@@ -3241,7 +3328,7 @@ var EmojiInput = React6__namespace.forwardRef(
3241
3328
  onChange,
3242
3329
  className: cn(
3243
3330
  "placeholder:text-muted-foreground flex h-9 w-full min-w-0 rounded-md px-3 py-1 pr-10 text-base outline-none transition-[color,box-shadow] selection:bg-primary selection:text-primary-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
3244
- fieldResetClassName,
3331
+ emojiFieldResetClassName,
3245
3332
  className
3246
3333
  ),
3247
3334
  ...props
@@ -3433,27 +3520,27 @@ function useHlsPlayback({
3433
3520
  onError,
3434
3521
  onPlayingChange
3435
3522
  }) {
3436
- const videoRef = React6__namespace.useRef(null);
3437
- const hlsRef = React6__namespace.useRef(null);
3438
- const [state, setState] = React6__namespace.useState("idle");
3439
- const [qualities, setQualities] = React6__namespace.useState([]);
3440
- const [activeLevel, setActiveLevel] = React6__namespace.useState(-1);
3441
- const [autoplayState, setAutoplayState] = React6__namespace.useState("none");
3442
- const [error, setError] = React6__namespace.useState(null);
3443
- const [reloadKey, setReloadKey] = React6__namespace.useState(0);
3444
- const onErrorRef = React6__namespace.useRef(onError);
3445
- const onPlayingChangeRef = React6__namespace.useRef(onPlayingChange);
3446
- React6__namespace.useEffect(() => {
3523
+ const videoRef = React7__namespace.useRef(null);
3524
+ const hlsRef = React7__namespace.useRef(null);
3525
+ const [state, setState] = React7__namespace.useState("idle");
3526
+ const [qualities, setQualities] = React7__namespace.useState([]);
3527
+ const [activeLevel, setActiveLevel] = React7__namespace.useState(-1);
3528
+ const [autoplayState, setAutoplayState] = React7__namespace.useState("none");
3529
+ const [error, setError] = React7__namespace.useState(null);
3530
+ const [reloadKey, setReloadKey] = React7__namespace.useState(0);
3531
+ const onErrorRef = React7__namespace.useRef(onError);
3532
+ const onPlayingChangeRef = React7__namespace.useRef(onPlayingChange);
3533
+ React7__namespace.useEffect(() => {
3447
3534
  onErrorRef.current = onError;
3448
3535
  onPlayingChangeRef.current = onPlayingChange;
3449
3536
  }, [onError, onPlayingChange]);
3450
- const retry = React6__namespace.useCallback(() => {
3537
+ const retry = React7__namespace.useCallback(() => {
3451
3538
  setError(null);
3452
3539
  setState("loading");
3453
3540
  setAutoplayState("none");
3454
3541
  setReloadKey((k) => k + 1);
3455
3542
  }, []);
3456
- React6__namespace.useEffect(() => {
3543
+ React7__namespace.useEffect(() => {
3457
3544
  const media = videoRef.current;
3458
3545
  if (!media || !src || !active) {
3459
3546
  setState("idle");
@@ -3665,7 +3752,7 @@ function useHlsPlayback({
3665
3752
  destroyHls();
3666
3753
  };
3667
3754
  }, [src, mode, active, autoPlay, muted, reloadKey]);
3668
- const setLevel = React6__namespace.useCallback((index) => {
3755
+ const setLevel = React7__namespace.useCallback((index) => {
3669
3756
  const hls = hlsRef.current;
3670
3757
  if (!hls) return;
3671
3758
  hls.nextLevel = index;
@@ -3710,6 +3797,19 @@ var PLAYBACK_RATES = [0.75, 1, 1.25, 1.5, 2];
3710
3797
  var CONTROLS_HIDE_MS = 3e3;
3711
3798
  var LIVE_EDGE_THRESHOLD_S = 8;
3712
3799
  var SEEK_STEP_S = 5;
3800
+ function asWebkitVideo(video) {
3801
+ return video;
3802
+ }
3803
+ function hasWebkitVideoFullscreen(video) {
3804
+ const webkit = asWebkitVideo(video);
3805
+ return typeof webkit?.webkitEnterFullscreen === "function";
3806
+ }
3807
+ function hasStandardFullscreen() {
3808
+ if (typeof document === "undefined") return false;
3809
+ if (document.fullscreenEnabled) return true;
3810
+ const doc = document;
3811
+ return !!doc.webkitFullscreenEnabled;
3812
+ }
3713
3813
  function formatTime(seconds) {
3714
3814
  if (!Number.isFinite(seconds) || seconds < 0) return "0:00";
3715
3815
  const total = Math.floor(seconds);
@@ -3735,12 +3835,12 @@ function VideoPlayer({
3735
3835
  className
3736
3836
  }) {
3737
3837
  const t = { ...DEFAULT_LABELS2, ...labels };
3738
- const containerRef = React6__namespace.useRef(null);
3739
- const firstPlayFiredRef = React6__namespace.useRef(false);
3740
- const [userStarted, setUserStarted] = React6__namespace.useState(false);
3838
+ const containerRef = React7__namespace.useRef(null);
3839
+ const firstPlayFiredRef = React7__namespace.useRef(false);
3840
+ const [userStarted, setUserStarted] = React7__namespace.useState(false);
3741
3841
  const active = autoPlay || !poster || userStarted;
3742
3842
  const autoplayActive = autoPlay || userStarted;
3743
- const handlePlayingChange = React6__namespace.useCallback(
3843
+ const handlePlayingChange = React7__namespace.useCallback(
3744
3844
  (playing) => {
3745
3845
  setIsPlaying(playing);
3746
3846
  if (playing && !firstPlayFiredRef.current) {
@@ -3769,25 +3869,25 @@ function VideoPlayer({
3769
3869
  onError,
3770
3870
  onPlayingChange: handlePlayingChange
3771
3871
  });
3772
- const [isPlaying, setIsPlaying] = React6__namespace.useState(false);
3773
- const [isMuted, setIsMuted] = React6__namespace.useState(muted);
3774
- const [volume, setVolume] = React6__namespace.useState(1);
3775
- const [currentTime, setCurrentTime] = React6__namespace.useState(0);
3776
- const [duration, setDuration] = React6__namespace.useState(0);
3777
- const [buffered, setBuffered] = React6__namespace.useState(0);
3778
- const [isFullscreen, setIsFullscreen] = React6__namespace.useState(false);
3779
- const [pipActive, setPipActive] = React6__namespace.useState(false);
3780
- const [controlsVisible, setControlsVisible] = React6__namespace.useState(true);
3781
- const [playbackRate, setPlaybackRate] = React6__namespace.useState(1);
3782
- const [openMenu, setOpenMenu] = React6__namespace.useState(
3872
+ const [isPlaying, setIsPlaying] = React7__namespace.useState(false);
3873
+ const [isMuted, setIsMuted] = React7__namespace.useState(muted);
3874
+ const [volume, setVolume] = React7__namespace.useState(1);
3875
+ const [currentTime, setCurrentTime] = React7__namespace.useState(0);
3876
+ const [duration, setDuration] = React7__namespace.useState(0);
3877
+ const [buffered, setBuffered] = React7__namespace.useState(0);
3878
+ const [isFullscreen, setIsFullscreen] = React7__namespace.useState(false);
3879
+ const [pipActive, setPipActive] = React7__namespace.useState(false);
3880
+ const [controlsVisible, setControlsVisible] = React7__namespace.useState(true);
3881
+ const [playbackRate, setPlaybackRate] = React7__namespace.useState(1);
3882
+ const [openMenu, setOpenMenu] = React7__namespace.useState(
3783
3883
  null
3784
3884
  );
3785
- const [behindLive, setBehindLive] = React6__namespace.useState(false);
3786
- const hideTimerRef = React6__namespace.useRef(null);
3885
+ const [behindLive, setBehindLive] = React7__namespace.useState(false);
3886
+ const [webkitFullscreenSupported, setWebkitFullscreenSupported] = React7__namespace.useState(false);
3887
+ const hideTimerRef = React7__namespace.useRef(null);
3787
3888
  const pipSupported = typeof document !== "undefined" && "pictureInPictureEnabled" in document && document.pictureInPictureEnabled;
3788
- const fullscreenSupported = typeof document !== "undefined" && (!!document.fullscreenEnabled || // Safari
3789
- "webkitFullscreenEnabled" in document);
3790
- React6__namespace.useEffect(() => {
3889
+ const fullscreenSupported = hasStandardFullscreen() || webkitFullscreenSupported;
3890
+ React7__namespace.useEffect(() => {
3791
3891
  const video = videoRef.current;
3792
3892
  if (!video || !active) return;
3793
3893
  const onTimeUpdate = () => {
@@ -3820,12 +3920,27 @@ function VideoPlayer({
3820
3920
  video.removeEventListener("ratechange", onRate);
3821
3921
  };
3822
3922
  }, [videoRef, active, mode]);
3823
- React6__namespace.useEffect(() => {
3923
+ React7__namespace.useEffect(() => {
3924
+ setWebkitFullscreenSupported(hasWebkitVideoFullscreen(videoRef.current));
3925
+ }, [videoRef, active]);
3926
+ React7__namespace.useEffect(() => {
3824
3927
  const onFsChange = () => setIsFullscreen(document.fullscreenElement === containerRef.current);
3825
3928
  document.addEventListener("fullscreenchange", onFsChange);
3826
3929
  return () => document.removeEventListener("fullscreenchange", onFsChange);
3827
3930
  }, []);
3828
- React6__namespace.useEffect(() => {
3931
+ React7__namespace.useEffect(() => {
3932
+ const video = asWebkitVideo(videoRef.current);
3933
+ if (!video) return;
3934
+ const onBegin = () => setIsFullscreen(true);
3935
+ const onEnd = () => setIsFullscreen(false);
3936
+ video.addEventListener("webkitbeginfullscreen", onBegin);
3937
+ video.addEventListener("webkitendfullscreen", onEnd);
3938
+ return () => {
3939
+ video.removeEventListener("webkitbeginfullscreen", onBegin);
3940
+ video.removeEventListener("webkitendfullscreen", onEnd);
3941
+ };
3942
+ }, [videoRef, active]);
3943
+ React7__namespace.useEffect(() => {
3829
3944
  const video = videoRef.current;
3830
3945
  if (!video) return;
3831
3946
  const onEnter = () => setPipActive(true);
@@ -3837,18 +3952,18 @@ function VideoPlayer({
3837
3952
  video.removeEventListener("leavepictureinpicture", onLeave);
3838
3953
  };
3839
3954
  }, [videoRef]);
3840
- const scheduleHide = React6__namespace.useCallback(() => {
3955
+ const scheduleHide = React7__namespace.useCallback(() => {
3841
3956
  if (hideTimerRef.current) clearTimeout(hideTimerRef.current);
3842
3957
  hideTimerRef.current = setTimeout(() => {
3843
3958
  setControlsVisible(false);
3844
3959
  setOpenMenu(null);
3845
3960
  }, CONTROLS_HIDE_MS);
3846
3961
  }, []);
3847
- const revealControls = React6__namespace.useCallback(() => {
3962
+ const revealControls = React7__namespace.useCallback(() => {
3848
3963
  setControlsVisible(true);
3849
3964
  scheduleHide();
3850
3965
  }, [scheduleHide]);
3851
- React6__namespace.useEffect(() => {
3966
+ React7__namespace.useEffect(() => {
3852
3967
  return () => {
3853
3968
  if (hideTimerRef.current) clearTimeout(hideTimerRef.current);
3854
3969
  };
@@ -3889,11 +4004,21 @@ function VideoPlayer({
3889
4004
  }
3890
4005
  function toggleFullscreen() {
3891
4006
  const el = containerRef.current;
3892
- if (!el) return;
3893
- if (document.fullscreenElement === el) {
4007
+ const video = asWebkitVideo(videoRef.current);
4008
+ if (el && document.fullscreenElement === el) {
3894
4009
  void document.exitFullscreen();
3895
- } else {
3896
- void el.requestFullscreen?.();
4010
+ return;
4011
+ }
4012
+ if (video?.webkitDisplayingFullscreen && video.webkitExitFullscreen) {
4013
+ video.webkitExitFullscreen();
4014
+ return;
4015
+ }
4016
+ if (el && hasStandardFullscreen() && typeof el.requestFullscreen === "function") {
4017
+ void el.requestFullscreen();
4018
+ return;
4019
+ }
4020
+ if (video && typeof video.webkitEnterFullscreen === "function") {
4021
+ video.webkitEnterFullscreen();
3897
4022
  }
3898
4023
  }
3899
4024
  function togglePip() {
@@ -4301,8 +4426,8 @@ function MenuItem({
4301
4426
  );
4302
4427
  }
4303
4428
  function usePlaybackStats(statsUrl, { intervalMs = 15e3, enabled = true } = {}) {
4304
- const [stats, setStats] = React6__namespace.useState({});
4305
- React6__namespace.useEffect(() => {
4429
+ const [stats, setStats] = React7__namespace.useState({});
4430
+ React7__namespace.useEffect(() => {
4306
4431
  if (!statsUrl || !enabled) return;
4307
4432
  let cancelled = false;
4308
4433
  const controller = new AbortController();
@@ -4332,16 +4457,16 @@ function usePlaybackStats(statsUrl, { intervalMs = 15e3, enabled = true } = {})
4332
4457
  return stats;
4333
4458
  }
4334
4459
  function useDebouncedValue(value, delayMs) {
4335
- const [debounced, setDebounced] = React6.useState(value);
4336
- React6.useEffect(() => {
4460
+ const [debounced, setDebounced] = React7.useState(value);
4461
+ React7.useEffect(() => {
4337
4462
  const id = window.setTimeout(() => setDebounced(value), delayMs);
4338
4463
  return () => window.clearTimeout(id);
4339
4464
  }, [value, delayMs]);
4340
4465
  return debounced;
4341
4466
  }
4342
4467
  function useDebouncedValueStrict(value, delayMs) {
4343
- const [debounced, setDebounced] = React6.useState(void 0);
4344
- React6.useEffect(() => {
4468
+ const [debounced, setDebounced] = React7.useState(void 0);
4469
+ React7.useEffect(() => {
4345
4470
  setDebounced(void 0);
4346
4471
  const id = window.setTimeout(() => setDebounced(value), delayMs);
4347
4472
  return () => window.clearTimeout(id);
@@ -4349,8 +4474,8 @@ function useDebouncedValueStrict(value, delayMs) {
4349
4474
  return debounced;
4350
4475
  }
4351
4476
  function useMediaQuery2(query) {
4352
- const [matches, setMatches] = React6.useState(false);
4353
- React6.useEffect(() => {
4477
+ const [matches, setMatches] = React7.useState(false);
4478
+ React7.useEffect(() => {
4354
4479
  if (typeof window === "undefined" || !window.matchMedia) return;
4355
4480
  const mql = window.matchMedia(query);
4356
4481
  const onChange = () => setMatches(mql.matches);
@@ -4362,9 +4487,9 @@ function useMediaQuery2(query) {
4362
4487
  }
4363
4488
  function useSearchHotkey(options = {}) {
4364
4489
  const { defaultOpen = false, disabled = false } = options;
4365
- const [open, setOpen] = React6.useState(defaultOpen);
4366
- const toggle = React6.useCallback(() => setOpen((prev) => !prev), []);
4367
- React6.useEffect(() => {
4490
+ const [open, setOpen] = React7.useState(defaultOpen);
4491
+ const toggle = React7.useCallback(() => setOpen((prev) => !prev), []);
4492
+ React7.useEffect(() => {
4368
4493
  if (disabled) return;
4369
4494
  function handleKeyDown(event) {
4370
4495
  if (event.key.toLowerCase() !== "k") return;
@@ -4779,26 +4904,26 @@ function SearchablePicker(props) {
4779
4904
  const labels = { ...defaultLabels3, ...userLabels };
4780
4905
  const resolvedEmptyLabel = emptyLabel ?? labels.emptyOption;
4781
4906
  const isMobile = useMediaQuery2("(max-width: 767px)");
4782
- const generatedId = React6.useId();
4907
+ const generatedId = React7.useId();
4783
4908
  const triggerId = id ?? generatedId;
4784
- const [uncontrolledOpen, setUncontrolledOpen] = React6.useState(false);
4909
+ const [uncontrolledOpen, setUncontrolledOpen] = React7.useState(false);
4785
4910
  const open = openProp ?? uncontrolledOpen;
4786
- const setOpen = React6.useCallback(
4911
+ const setOpen = React7.useCallback(
4787
4912
  (next) => {
4788
4913
  onOpenChange?.(next);
4789
4914
  if (openProp === void 0) setUncontrolledOpen(next);
4790
4915
  },
4791
4916
  [onOpenChange, openProp]
4792
4917
  );
4793
- const [query, setQuery] = React6.useState("");
4794
- const [remoteItems, setRemoteItems] = React6.useState([]);
4795
- const [isLoading, setIsLoading] = React6.useState(false);
4796
- const [hasError, setHasError] = React6.useState(false);
4797
- const [isLoadingMore, setIsLoadingMore] = React6.useState(false);
4918
+ const [query, setQuery] = React7.useState("");
4919
+ const [remoteItems, setRemoteItems] = React7.useState([]);
4920
+ const [isLoading, setIsLoading] = React7.useState(false);
4921
+ const [hasError, setHasError] = React7.useState(false);
4922
+ const [isLoadingMore, setIsLoadingMore] = React7.useState(false);
4798
4923
  const debouncedQuery = useDebouncedValue(query, debounceMs);
4799
- const requestIdRef = React6.useRef(0);
4800
- const knownItemsRef = React6.useRef(/* @__PURE__ */ new Map());
4801
- const rememberItems = React6.useCallback(
4924
+ const requestIdRef = React7.useRef(0);
4925
+ const knownItemsRef = React7.useRef(/* @__PURE__ */ new Map());
4926
+ const rememberItems = React7.useCallback(
4802
4927
  (items) => {
4803
4928
  for (const item of items) {
4804
4929
  knownItemsRef.current.set(getOptionValue(item), item);
@@ -4806,12 +4931,12 @@ function SearchablePicker(props) {
4806
4931
  },
4807
4932
  [getOptionValue]
4808
4933
  );
4809
- React6.useEffect(() => {
4934
+ React7.useEffect(() => {
4810
4935
  if (options) rememberItems(options);
4811
4936
  if (pinned?.recommended) rememberItems(pinned.recommended);
4812
4937
  if (pinned?.recent) rememberItems(pinned.recent);
4813
4938
  }, [options, pinned, rememberItems]);
4814
- React6.useEffect(() => {
4939
+ React7.useEffect(() => {
4815
4940
  if (!open) {
4816
4941
  setQuery("");
4817
4942
  setRemoteItems([]);
@@ -4821,7 +4946,7 @@ function SearchablePicker(props) {
4821
4946
  }, [open]);
4822
4947
  const trimmedDebounced = debouncedQuery.trim();
4823
4948
  const shouldFetch = Boolean(fetchOptions) && open && trimmedDebounced.length >= minQueryLength && (trimmedDebounced.length > 0 || !options);
4824
- React6.useEffect(() => {
4949
+ React7.useEffect(() => {
4825
4950
  if (!shouldFetch || !fetchOptions) {
4826
4951
  if (!trimmedDebounced) {
4827
4952
  setRemoteItems([]);
@@ -4846,7 +4971,7 @@ function SearchablePicker(props) {
4846
4971
  setIsLoading(false);
4847
4972
  });
4848
4973
  }, [shouldFetch, fetchOptions, trimmedDebounced, rememberItems]);
4849
- const selectedValues = React6.useMemo(() => {
4974
+ const selectedValues = React7.useMemo(() => {
4850
4975
  if (mode === "multiple") {
4851
4976
  const multiValue = props.value ?? [];
4852
4977
  return new Set(multiValue);
@@ -4855,12 +4980,12 @@ function SearchablePicker(props) {
4855
4980
  return singleValue ? /* @__PURE__ */ new Set([singleValue]) : /* @__PURE__ */ new Set();
4856
4981
  }, [mode, props]);
4857
4982
  const selectedValueKey = mode === "multiple" ? (props.value ?? []).join("\0") : props.value ?? "";
4858
- const selectedItems = React6.useMemo(() => {
4983
+ const selectedItems = React7.useMemo(() => {
4859
4984
  const values = mode === "multiple" ? selectedValueKey ? selectedValueKey.split("\0") : [] : selectedValueKey ? [selectedValueKey] : [];
4860
4985
  return values.map((value) => knownItemsRef.current.get(value)).filter((item) => item !== void 0);
4861
4986
  }, [mode, selectedValueKey, options, pinned, remoteItems]);
4862
4987
  const queryForFilter = query.trim();
4863
- const recommended = React6.useMemo(() => {
4988
+ const recommended = React7.useMemo(() => {
4864
4989
  if (queryForFilter) return [];
4865
4990
  const pinnedValues = /* @__PURE__ */ new Set();
4866
4991
  const items = dedupeByValue(
@@ -4869,7 +4994,7 @@ function SearchablePicker(props) {
4869
4994
  for (const entry of items) pinnedValues.add(entry.value);
4870
4995
  return items;
4871
4996
  }, [queryForFilter, pinned?.recommended, getOptionValue, getOptionLabel]);
4872
- const recent = React6.useMemo(() => {
4997
+ const recent = React7.useMemo(() => {
4873
4998
  if (queryForFilter) return [];
4874
4999
  const exclude = new Set(recommended.map((e) => e.value));
4875
5000
  return dedupeByValue(
@@ -4883,13 +5008,13 @@ function SearchablePicker(props) {
4883
5008
  getOptionValue,
4884
5009
  getOptionLabel
4885
5010
  ]);
4886
- const pinnedValueSet = React6.useMemo(() => {
5011
+ const pinnedValueSet = React7.useMemo(() => {
4887
5012
  const set = /* @__PURE__ */ new Set();
4888
5013
  for (const entry of recommended) set.add(entry.value);
4889
5014
  for (const entry of recent) set.add(entry.value);
4890
5015
  return set;
4891
5016
  }, [recommended, recent]);
4892
- const results = React6.useMemo(() => {
5017
+ const results = React7.useMemo(() => {
4893
5018
  const usingRemote = Boolean(fetchOptions) && trimmedDebounced.length >= minQueryLength && (trimmedDebounced.length > 0 || !options);
4894
5019
  if (usingRemote) {
4895
5020
  return dedupeByValue(
@@ -4915,7 +5040,7 @@ function SearchablePicker(props) {
4915
5040
  pinnedValueSet
4916
5041
  ]);
4917
5042
  const closeOnSelect = keepOpenOnSelect !== void 0 ? !keepOpenOnSelect : mode === "single";
4918
- const handleSelectEmpty = React6.useCallback(() => {
5043
+ const handleSelectEmpty = React7.useCallback(() => {
4919
5044
  if (mode === "single") {
4920
5045
  props.onValueChange?.(
4921
5046
  null
@@ -4923,7 +5048,7 @@ function SearchablePicker(props) {
4923
5048
  }
4924
5049
  if (closeOnSelect) setOpen(false);
4925
5050
  }, [mode, props, closeOnSelect, setOpen]);
4926
- const handleSelectItem = React6.useCallback(
5051
+ const handleSelectItem = React7.useCallback(
4927
5052
  (value) => {
4928
5053
  if (mode === "multiple") {
4929
5054
  const current = props.value ?? [];
@@ -4946,7 +5071,7 @@ function SearchablePicker(props) {
4946
5071
  },
4947
5072
  [mode, props, maxSelected, closeOnSelect, setOpen]
4948
5073
  );
4949
- const handleClear = React6.useCallback(
5074
+ const handleClear = React7.useCallback(
4950
5075
  (event) => {
4951
5076
  event.preventDefault();
4952
5077
  event.stopPropagation();
@@ -4960,7 +5085,7 @@ function SearchablePicker(props) {
4960
5085
  },
4961
5086
  [mode, props]
4962
5087
  );
4963
- const handleLoadMore = React6.useCallback(async () => {
5088
+ const handleLoadMore = React7.useCallback(async () => {
4964
5089
  if (!onLoadMore || isLoadingMore) return;
4965
5090
  setIsLoadingMore(true);
4966
5091
  try {
@@ -4969,7 +5094,7 @@ function SearchablePicker(props) {
4969
5094
  setIsLoadingMore(false);
4970
5095
  }
4971
5096
  }, [onLoadMore, isLoadingMore]);
4972
- const triggerLabel = React6.useMemo(() => {
5097
+ const triggerLabel = React7.useMemo(() => {
4973
5098
  if (renderValue) {
4974
5099
  if (mode === "multiple") {
4975
5100
  return renderValue(selectedItems);
@@ -5151,20 +5276,20 @@ function SearchCommand({
5151
5276
  className
5152
5277
  }) {
5153
5278
  const labels = { ...defaultLabels4, ...userLabels };
5154
- const [query, setQuery] = React6.useState("");
5155
- const [hits, setHits] = React6.useState([]);
5156
- const [isLoading, setIsLoading] = React6.useState(false);
5157
- const [hasError, setHasError] = React6.useState(false);
5279
+ const [query, setQuery] = React7.useState("");
5280
+ const [hits, setHits] = React7.useState([]);
5281
+ const [isLoading, setIsLoading] = React7.useState(false);
5282
+ const [hasError, setHasError] = React7.useState(false);
5158
5283
  const debouncedQuery = useDebouncedValue(query, debounceMs);
5159
- const requestIdRef = React6.useRef(0);
5160
- React6.useEffect(() => {
5284
+ const requestIdRef = React7.useRef(0);
5285
+ React7.useEffect(() => {
5161
5286
  if (!open) {
5162
5287
  setQuery("");
5163
5288
  setHits([]);
5164
5289
  setHasError(false);
5165
5290
  }
5166
5291
  }, [open]);
5167
- React6.useEffect(() => {
5292
+ React7.useEffect(() => {
5168
5293
  const trimmed = debouncedQuery.trim();
5169
5294
  if (trimmed.length < minQueryLength) {
5170
5295
  setHits([]);
@@ -5187,13 +5312,13 @@ function SearchCommand({
5187
5312
  setIsLoading(false);
5188
5313
  });
5189
5314
  }, [debouncedQuery, minQueryLength, fetchResults]);
5190
- const filteredFeatures = React6.useMemo(() => {
5315
+ const filteredFeatures = React7.useMemo(() => {
5191
5316
  if (!query.trim()) return features;
5192
5317
  return features.filter(
5193
5318
  (feature) => fuzzyMatch(query, feature.label) || feature.keywords?.some((keyword) => fuzzyMatch(query, keyword))
5194
5319
  );
5195
5320
  }, [features, query]);
5196
- const groupedHits = React6.useMemo(() => groupHitsByType(hits), [hits]);
5321
+ const groupedHits = React7.useMemo(() => groupHitsByType(hits), [hits]);
5197
5322
  function handleSelect(selection) {
5198
5323
  onSelect(selection);
5199
5324
  onOpenChange(false);
@@ -5327,7 +5452,7 @@ function ScrollBar({
5327
5452
  );
5328
5453
  }
5329
5454
  var phoneInputGroupClass = "flex h-9 w-full gap-0 overflow-hidden rounded-md border border-input bg-transparent shadow-xs transition-[color,box-shadow] [--PhoneInputCountrySelect-marginRight:0] focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50 dark:bg-input/30 [&_.PhoneInputCountry]:mr-0";
5330
- var PhoneInput = React6__namespace.forwardRef(
5455
+ var PhoneInput = React7__namespace.forwardRef(
5331
5456
  ({ className, onChange, value, defaultCountry = "MX", ...props }, ref) => {
5332
5457
  return /* @__PURE__ */ jsxRuntime.jsx(
5333
5458
  RPNInput__namespace.default,
@@ -5347,7 +5472,7 @@ var PhoneInput = React6__namespace.forwardRef(
5347
5472
  }
5348
5473
  );
5349
5474
  PhoneInput.displayName = "PhoneInput";
5350
- var InputComponent = React6__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5475
+ var InputComponent = React7__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
5351
5476
  Input,
5352
5477
  {
5353
5478
  className: cn(
@@ -5365,9 +5490,9 @@ var CountrySelect = ({
5365
5490
  options: countryList,
5366
5491
  onChange
5367
5492
  }) => {
5368
- const scrollAreaRef = React6__namespace.useRef(null);
5369
- const [searchValue, setSearchValue] = React6__namespace.useState("");
5370
- const [isOpen, setIsOpen] = React6__namespace.useState(false);
5493
+ const scrollAreaRef = React7__namespace.useRef(null);
5494
+ const [searchValue, setSearchValue] = React7__namespace.useState("");
5495
+ const [isOpen, setIsOpen] = React7__namespace.useState(false);
5371
5496
  return /* @__PURE__ */ jsxRuntime.jsxs(
5372
5497
  Popover,
5373
5498
  {
@@ -5548,8 +5673,8 @@ var MEXICO_STATE_PATHS = {
5548
5673
  };
5549
5674
  function MexicoMap({ selected, onToggle, className }) {
5550
5675
  const isInteractive = typeof onToggle === "function";
5551
- const selectedSet = React6__namespace.useMemo(() => new Set(selected), [selected]);
5552
- const handleKeyDown = React6__namespace.useCallback(
5676
+ const selectedSet = React7__namespace.useMemo(() => new Set(selected), [selected]);
5677
+ const handleKeyDown = React7__namespace.useCallback(
5553
5678
  (event, id) => {
5554
5679
  if (!onToggle) return;
5555
5680
  if (event.key === "Enter" || event.key === " ") {
@@ -6031,6 +6156,121 @@ function ChatMessageList({
6031
6156
  /* @__PURE__ */ jsxRuntime.jsx(MessageScrollerButton, {})
6032
6157
  ] }) });
6033
6158
  }
6159
+ var MessageComposer = React7__namespace.forwardRef(function MessageComposer2({
6160
+ className,
6161
+ locale = "en",
6162
+ disabled,
6163
+ readOnly,
6164
+ value,
6165
+ onChange,
6166
+ onSubmit,
6167
+ onKeyDown,
6168
+ sendLabel,
6169
+ sendDisabled = false,
6170
+ sendButtonClassName,
6171
+ sendButtonSize = "sm",
6172
+ triggerLabel,
6173
+ keepOpenOnSelect,
6174
+ open,
6175
+ onOpenChange,
6176
+ side = "top",
6177
+ align = "end",
6178
+ labels,
6179
+ recentLimit,
6180
+ storageKey,
6181
+ emojiTriggerClassName,
6182
+ rows = 2,
6183
+ ...props
6184
+ }, ref) {
6185
+ const formRef = React7__namespace.useRef(null);
6186
+ const fieldRef = React7__namespace.useRef(null);
6187
+ const handleEmojiSelect = useEmojiInsert(fieldRef, value, onChange);
6188
+ const pickerDisabled = Boolean(disabled || readOnly);
6189
+ const draft = value !== void 0 && value !== null ? String(value) : "";
6190
+ const canSubmit = Boolean(draft.trim()) && !sendDisabled && !disabled && !readOnly;
6191
+ const handleSubmit = React7__namespace.useCallback(
6192
+ (event) => {
6193
+ event.preventDefault();
6194
+ if (!canSubmit) return;
6195
+ onSubmit(event);
6196
+ },
6197
+ [canSubmit, onSubmit]
6198
+ );
6199
+ const handleKeyDown = React7__namespace.useCallback(
6200
+ (event) => {
6201
+ onKeyDown?.(event);
6202
+ if (event.defaultPrevented) return;
6203
+ if (event.key !== "Enter" || event.shiftKey) return;
6204
+ if (event.nativeEvent.isComposing || event.keyCode === 229) return;
6205
+ event.preventDefault();
6206
+ if (!canSubmit) return;
6207
+ formRef.current?.requestSubmit();
6208
+ },
6209
+ [canSubmit, onKeyDown]
6210
+ );
6211
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6212
+ "form",
6213
+ {
6214
+ ref: formRef,
6215
+ className: cn(emojiFieldWrapperClassName, "flex flex-col", className),
6216
+ onSubmit: handleSubmit,
6217
+ children: [
6218
+ /* @__PURE__ */ jsxRuntime.jsx(
6219
+ "textarea",
6220
+ {
6221
+ "data-slot": "textarea",
6222
+ ref: mergeRefs(fieldRef, ref),
6223
+ disabled,
6224
+ readOnly,
6225
+ value,
6226
+ onChange,
6227
+ onKeyDown: handleKeyDown,
6228
+ rows,
6229
+ className: cn(
6230
+ "placeholder:text-muted-foreground flex min-h-10 w-full resize-none rounded-md px-3 pt-2 pb-1 text-base outline-none transition-[color,box-shadow] disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
6231
+ emojiFieldResetClassName
6232
+ ),
6233
+ ...props
6234
+ }
6235
+ ),
6236
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 px-1.5 pb-1.5", children: [
6237
+ /* @__PURE__ */ jsxRuntime.jsx(
6238
+ EmojiPickerPopover,
6239
+ {
6240
+ locale,
6241
+ onSelect: handleEmojiSelect,
6242
+ disabled: pickerDisabled,
6243
+ triggerLabel,
6244
+ keepOpenOnSelect,
6245
+ open,
6246
+ onOpenChange,
6247
+ side,
6248
+ align,
6249
+ labels,
6250
+ recentLimit,
6251
+ storageKey,
6252
+ triggerClassName: cn(
6253
+ "size-7 text-muted-foreground",
6254
+ emojiTriggerClassName
6255
+ )
6256
+ }
6257
+ ),
6258
+ /* @__PURE__ */ jsxRuntime.jsx(
6259
+ Button,
6260
+ {
6261
+ type: "submit",
6262
+ size: sendButtonSize,
6263
+ disabled: !canSubmit,
6264
+ className: sendButtonClassName,
6265
+ children: sendLabel
6266
+ }
6267
+ )
6268
+ ] })
6269
+ ]
6270
+ }
6271
+ );
6272
+ });
6273
+ MessageComposer.displayName = "MessageComposer";
6034
6274
  var RECONNECT_DELAY_MS = 2e3;
6035
6275
  function useSupportConversation({
6036
6276
  client,
@@ -6041,21 +6281,21 @@ function useSupportConversation({
6041
6281
  onConversationReady,
6042
6282
  onIncomingMessage
6043
6283
  }) {
6044
- const [conversationId, setConversationId] = React6.useState(
6284
+ const [conversationId, setConversationId] = React7.useState(
6045
6285
  conversationIdProp
6046
6286
  );
6047
- const [messages, setMessages] = React6.useState([]);
6048
- const [loading, setLoading] = React6.useState(false);
6049
- const [sending, setSending] = React6.useState(false);
6050
- const [error, setError] = React6.useState(null);
6051
- const socketRef = React6.useRef(null);
6052
- const reconnectRef = React6.useRef(null);
6053
- const closedByUser = React6.useRef(false);
6054
- const onReadyRef = React6.useRef(onConversationReady);
6055
- const onIncomingRef = React6.useRef(onIncomingMessage);
6287
+ const [messages, setMessages] = React7.useState([]);
6288
+ const [loading, setLoading] = React7.useState(false);
6289
+ const [sending, setSending] = React7.useState(false);
6290
+ const [error, setError] = React7.useState(null);
6291
+ const socketRef = React7.useRef(null);
6292
+ const reconnectRef = React7.useRef(null);
6293
+ const closedByUser = React7.useRef(false);
6294
+ const onReadyRef = React7.useRef(onConversationReady);
6295
+ const onIncomingRef = React7.useRef(onIncomingMessage);
6056
6296
  onReadyRef.current = onConversationReady;
6057
6297
  onIncomingRef.current = onIncomingMessage;
6058
- const load = React6.useCallback(async () => {
6298
+ const load = React7.useCallback(async () => {
6059
6299
  if (!enabled) return;
6060
6300
  setLoading(true);
6061
6301
  setError(null);
@@ -6081,10 +6321,10 @@ function useSupportConversation({
6081
6321
  setLoading(false);
6082
6322
  }
6083
6323
  }, [client, conversationIdProp, enabled, open]);
6084
- React6.useEffect(() => {
6324
+ React7.useEffect(() => {
6085
6325
  void load();
6086
6326
  }, [load]);
6087
- React6.useEffect(() => {
6327
+ React7.useEffect(() => {
6088
6328
  closedByUser.current = false;
6089
6329
  if (!enabled || !conversationId) return;
6090
6330
  let cancelled = false;
@@ -6130,7 +6370,7 @@ function useSupportConversation({
6130
6370
  socketRef.current = null;
6131
6371
  };
6132
6372
  }, [conversationId, enabled, getWsUrl]);
6133
- const send = React6.useCallback(
6373
+ const send = React7.useCallback(
6134
6374
  async (text) => {
6135
6375
  const trimmed = text.trim();
6136
6376
  if (!conversationId || !trimmed || sending) return;
@@ -6162,9 +6402,9 @@ function useSupportConversation({
6162
6402
  reload: load
6163
6403
  };
6164
6404
  }
6165
- var SupportMessengerContext = React6.createContext(null);
6405
+ var SupportMessengerContext = React7.createContext(null);
6166
6406
  function useSupportMessenger() {
6167
- const ctx = React6.useContext(SupportMessengerContext);
6407
+ const ctx = React7.useContext(SupportMessengerContext);
6168
6408
  if (!ctx) {
6169
6409
  throw new Error(
6170
6410
  "useSupportMessenger must be used within SupportMessengerProvider"
@@ -6173,7 +6413,7 @@ function useSupportMessenger() {
6173
6413
  return ctx;
6174
6414
  }
6175
6415
  function useSupportMessengerOptional() {
6176
- return React6.useContext(SupportMessengerContext);
6416
+ return React7.useContext(SupportMessengerContext);
6177
6417
  }
6178
6418
  function ThreadPanel({
6179
6419
  thread,
@@ -6188,7 +6428,7 @@ function ThreadPanel({
6188
6428
  onConversationReady,
6189
6429
  className
6190
6430
  }) {
6191
- const [draft, setDraft] = React6.useState("");
6431
+ const [draft, setDraft] = React7.useState("");
6192
6432
  const { messages, loading, sending, error, send } = useSupportConversation({
6193
6433
  client,
6194
6434
  getWsUrl,
@@ -6251,23 +6491,22 @@ function ThreadPanel({
6251
6491
  emptyDescription: labels.emptyThread
6252
6492
  }
6253
6493
  ) }),
6254
- /* @__PURE__ */ jsxRuntime.jsxs("form", { className: "flex gap-2 border-t p-3", onSubmit, children: [
6255
- /* @__PURE__ */ jsxRuntime.jsx(
6256
- EmojiTextarea,
6257
- {
6258
- locale: emojiLocale,
6259
- value: draft,
6260
- onChange: (e) => setDraft(e.target.value.slice(0, 2e3)),
6261
- placeholder: labels.placeholder,
6262
- "aria-label": labels.placeholder,
6263
- disabled: loading || sending,
6264
- maxLength: 2e3,
6265
- rows: 2,
6266
- className: "min-h-10 flex-1"
6267
- }
6268
- ),
6269
- /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", disabled: !draft.trim() || sending || loading, children: labels.send })
6270
- ] })
6494
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t p-3", children: /* @__PURE__ */ jsxRuntime.jsx(
6495
+ MessageComposer,
6496
+ {
6497
+ locale: emojiLocale,
6498
+ value: draft,
6499
+ onChange: (e) => setDraft(e.target.value.slice(0, 2e3)),
6500
+ onSubmit,
6501
+ sendLabel: labels.send,
6502
+ placeholder: labels.placeholder,
6503
+ "aria-label": labels.placeholder,
6504
+ disabled: loading || sending,
6505
+ sendDisabled: loading || sending,
6506
+ maxLength: 2e3,
6507
+ rows: 2
6508
+ }
6509
+ ) })
6271
6510
  ]
6272
6511
  }
6273
6512
  );
@@ -6283,9 +6522,9 @@ function ListPanel({
6283
6522
  searchThreshold,
6284
6523
  className
6285
6524
  }) {
6286
- const [query, setQuery] = React6.useState("");
6525
+ const [query, setQuery] = React7.useState("");
6287
6526
  const showSearch = items.length >= searchThreshold;
6288
- const filtered = React6.useMemo(() => {
6527
+ const filtered = React7.useMemo(() => {
6289
6528
  const q = query.trim().toLowerCase();
6290
6529
  if (!q) return items;
6291
6530
  return items.filter(
@@ -6389,32 +6628,32 @@ function SupportMessengerProvider({
6389
6628
  className
6390
6629
  }) {
6391
6630
  const isMobile = useMediaQuery2("(max-width: 767px)");
6392
- const [listOpen, setListOpen] = React6.useState(false);
6393
- const [threads, setThreads] = React6.useState([]);
6394
- const [mobileThreadKey, setMobileThreadKey] = React6.useState(null);
6395
- const totalUnread = React6.useMemo(
6631
+ const [listOpen, setListOpen] = React7.useState(false);
6632
+ const [threads, setThreads] = React7.useState([]);
6633
+ const [mobileThreadKey, setMobileThreadKey] = React7.useState(null);
6634
+ const totalUnread = React7.useMemo(
6396
6635
  () => items.reduce((sum, item) => sum + (item.unreadCount ?? 0), 0),
6397
6636
  [items]
6398
6637
  );
6399
- React6.useEffect(() => {
6638
+ React7.useEffect(() => {
6400
6639
  if (!forceMinimized) return;
6401
6640
  setListOpen(false);
6402
6641
  setThreads([]);
6403
6642
  setMobileThreadKey(null);
6404
6643
  }, [forceMinimized]);
6405
- const openList = React6.useCallback(() => {
6644
+ const openList = React7.useCallback(() => {
6406
6645
  setListOpen(true);
6407
6646
  void onRefreshItems?.();
6408
6647
  }, [onRefreshItems]);
6409
- const closeList = React6.useCallback(() => setListOpen(false), []);
6410
- const toggleList = React6.useCallback(() => {
6648
+ const closeList = React7.useCallback(() => setListOpen(false), []);
6649
+ const toggleList = React7.useCallback(() => {
6411
6650
  setListOpen((prev) => {
6412
6651
  const next = !prev;
6413
6652
  if (next) void onRefreshItems?.();
6414
6653
  return next;
6415
6654
  });
6416
6655
  }, [onRefreshItems]);
6417
- const openThread = React6.useCallback((req) => {
6656
+ const openThread = React7.useCallback((req) => {
6418
6657
  setListOpen(false);
6419
6658
  setThreads((prev) => {
6420
6659
  const existing = prev.find((t) => t.key === req.key);
@@ -6429,16 +6668,16 @@ function SupportMessengerProvider({
6429
6668
  });
6430
6669
  setMobileThreadKey(req.key);
6431
6670
  }, []);
6432
- const closeThread = React6.useCallback((key) => {
6671
+ const closeThread = React7.useCallback((key) => {
6433
6672
  setThreads((prev) => prev.filter((t) => t.key !== key));
6434
6673
  setMobileThreadKey((prev) => prev === key ? null : prev);
6435
6674
  }, []);
6436
- const closeAll = React6.useCallback(() => {
6675
+ const closeAll = React7.useCallback(() => {
6437
6676
  setListOpen(false);
6438
6677
  setThreads([]);
6439
6678
  setMobileThreadKey(null);
6440
6679
  }, []);
6441
- const ctx = React6.useMemo(
6680
+ const ctx = React7.useMemo(
6442
6681
  () => ({
6443
6682
  listOpen,
6444
6683
  openList,
@@ -6463,7 +6702,7 @@ function SupportMessengerProvider({
6463
6702
  totalUnread
6464
6703
  ]
6465
6704
  );
6466
- const handleSelectItem = React6.useCallback(
6705
+ const handleSelectItem = React7.useCallback(
6467
6706
  (item) => {
6468
6707
  openThread({
6469
6708
  key: item.key,
@@ -6693,6 +6932,7 @@ exports.MarkerContent = MarkerContent;
6693
6932
  exports.MarkerIcon = MarkerIcon;
6694
6933
  exports.Message = Message;
6695
6934
  exports.MessageAvatar = MessageAvatar;
6935
+ exports.MessageComposer = MessageComposer;
6696
6936
  exports.MessageContent = MessageContent;
6697
6937
  exports.MessageFooter = MessageFooter;
6698
6938
  exports.MessageGroup = MessageGroup;