@sesionario/blocks 1.10.0 → 1.12.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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import * as React6 from 'react';
2
+ import * as React7 from 'react';
3
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';
@@ -1574,7 +1574,7 @@ function Slider({
1574
1574
  max = 100,
1575
1575
  ...props
1576
1576
  }) {
1577
- const _values = React6.useMemo(
1577
+ const _values = React7.useMemo(
1578
1578
  () => Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max],
1579
1579
  [value, defaultValue, min, max]
1580
1580
  );
@@ -2703,22 +2703,22 @@ function EmojiPicker({
2703
2703
  recentLimit = 24,
2704
2704
  storageKey = "blocks-emoji"
2705
2705
  }) {
2706
- const strings = React6.useMemo(
2706
+ const strings = React7.useMemo(
2707
2707
  () => ({ ...DEFAULT_LABELS[locale], ...labels }),
2708
2708
  [locale, labels]
2709
2709
  );
2710
- const titles = React6.useMemo(
2710
+ const titles = React7.useMemo(
2711
2711
  () => ({ ...DEFAULT_TITLES[locale], ...labels?.categoryTitles }),
2712
2712
  [locale, labels]
2713
2713
  );
2714
- const [query, setQuery] = React6.useState("");
2715
- const [skinTone, setSkinTone] = React6.useState(() => {
2714
+ const [query, setQuery] = React7.useState("");
2715
+ const [skinTone, setSkinTone] = React7.useState(() => {
2716
2716
  const raw = readStored(storageKey, "tone");
2717
2717
  const parsed = raw != null ? Number.parseInt(raw, 10) : 0;
2718
2718
  return parsed >= 0 && parsed <= 5 ? parsed : 0;
2719
2719
  });
2720
- const [toneOpen, setToneOpen] = React6.useState(false);
2721
- const [recents, setRecents] = React6.useState(() => {
2720
+ const [toneOpen, setToneOpen] = React7.useState(false);
2721
+ const [recents, setRecents] = React7.useState(() => {
2722
2722
  const raw = readStored(storageKey, "recent");
2723
2723
  if (!raw) return [];
2724
2724
  try {
@@ -2728,13 +2728,13 @@ function EmojiPicker({
2728
2728
  return [];
2729
2729
  }
2730
2730
  });
2731
- const [focusIndex, setFocusIndex] = React6.useState(-1);
2732
- const scrollRef = React6.useRef(null);
2733
- const sectionRefs = React6.useRef(
2731
+ const [focusIndex, setFocusIndex] = React7.useState(-1);
2732
+ const scrollRef = React7.useRef(null);
2733
+ const sectionRefs = React7.useRef(
2734
2734
  /* @__PURE__ */ new Map()
2735
2735
  );
2736
2736
  const normalizedQuery = normalizeEmojiQuery(query);
2737
- const sections = React6.useMemo(() => {
2737
+ const sections = React7.useMemo(() => {
2738
2738
  if (normalizedQuery) return [];
2739
2739
  const result = [];
2740
2740
  if (recents.length > 0) {
@@ -2753,7 +2753,7 @@ function EmojiPicker({
2753
2753
  }
2754
2754
  return result;
2755
2755
  }, [normalizedQuery, recents, titles]);
2756
- const searchResults = React6.useMemo(() => {
2756
+ const searchResults = React7.useMemo(() => {
2757
2757
  if (!normalizedQuery) return [];
2758
2758
  const out = [];
2759
2759
  for (const category of EMOJI_CATEGORIES) {
@@ -2763,21 +2763,21 @@ function EmojiPicker({
2763
2763
  }
2764
2764
  return out;
2765
2765
  }, [normalizedQuery]);
2766
- const flatList = React6.useMemo(() => {
2766
+ const flatList = React7.useMemo(() => {
2767
2767
  if (normalizedQuery) return searchResults;
2768
2768
  return sections.flatMap((s) => s.emojis);
2769
2769
  }, [normalizedQuery, searchResults, sections]);
2770
- React6.useEffect(() => {
2770
+ React7.useEffect(() => {
2771
2771
  setFocusIndex(-1);
2772
2772
  }, [normalizedQuery]);
2773
- React6.useEffect(() => {
2773
+ React7.useEffect(() => {
2774
2774
  if (focusIndex < 0) return;
2775
2775
  const el = scrollRef.current?.querySelector(
2776
2776
  `[data-emoji-index="${focusIndex}"]`
2777
2777
  );
2778
2778
  el?.focus();
2779
2779
  }, [focusIndex]);
2780
- const commitRecent = React6.useCallback(
2780
+ const commitRecent = React7.useCallback(
2781
2781
  (glyph) => {
2782
2782
  setRecents((prev) => {
2783
2783
  const next = [glyph, ...prev.filter((e) => e !== glyph)].slice(
@@ -2790,14 +2790,14 @@ function EmojiPicker({
2790
2790
  },
2791
2791
  [recentLimit, storageKey]
2792
2792
  );
2793
- const handleSelect = React6.useCallback(
2793
+ const handleSelect = React7.useCallback(
2794
2794
  (glyph) => {
2795
2795
  commitRecent(glyph);
2796
2796
  onSelect(glyph);
2797
2797
  },
2798
2798
  [commitRecent, onSelect]
2799
2799
  );
2800
- const chooseTone = React6.useCallback(
2800
+ const chooseTone = React7.useCallback(
2801
2801
  (tone) => {
2802
2802
  setSkinTone(tone);
2803
2803
  setToneOpen(false);
@@ -2957,8 +2957,8 @@ function EmojiPicker({
2957
2957
  {
2958
2958
  ref: scrollRef,
2959
2959
  onKeyDown: handleGridKeyDown,
2960
- className: "h-64 overflow-x-hidden overflow-y-auto p-2",
2961
- children: normalizedQuery ? searchResults.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground py-8 text-center text-sm", children: strings.noResults }) : /* @__PURE__ */ jsx(
2960
+ className: "h-64 overflow-x-hidden overflow-y-auto px-2 pb-2",
2961
+ children: normalizedQuery ? searchResults.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground py-8 text-center text-sm", children: strings.noResults }) : /* @__PURE__ */ jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsx(
2962
2962
  EmojiGrid,
2963
2963
  {
2964
2964
  emojis: searchResults,
@@ -2967,7 +2967,7 @@ function EmojiPicker({
2967
2967
  skinTone,
2968
2968
  onSelect: handleSelect
2969
2969
  }
2970
- ) : sections.map((section) => {
2970
+ ) }) : sections.map((section) => {
2971
2971
  const startIndex = flatOffset;
2972
2972
  flatOffset += section.emojis.length;
2973
2973
  return /* @__PURE__ */ jsxs(
@@ -2978,7 +2978,7 @@ function EmojiPicker({
2978
2978
  },
2979
2979
  className: "mb-2",
2980
2980
  children: [
2981
- /* @__PURE__ */ jsx("h3", { className: "text-muted-foreground bg-popover sticky top-0 z-[1] px-1 py-1 text-xs font-medium", children: section.title }),
2981
+ /* @__PURE__ */ jsx("h3", { className: "text-muted-foreground bg-popover sticky top-0 z-[1] -mx-2 px-3 pt-2 pb-1 text-xs font-medium", children: section.title }),
2982
2982
  /* @__PURE__ */ jsx(
2983
2983
  "div",
2984
2984
  {
@@ -3099,21 +3099,21 @@ function EmojiPickerPopover({
3099
3099
  align = "end",
3100
3100
  open,
3101
3101
  onOpenChange,
3102
- keepOpenOnSelect = false,
3102
+ keepOpenOnSelect = true,
3103
3103
  locale = "en",
3104
3104
  ...pickerProps
3105
3105
  }) {
3106
- const [internalOpen, setInternalOpen] = React6.useState(false);
3106
+ const [internalOpen, setInternalOpen] = React7.useState(false);
3107
3107
  const isControlled = open !== void 0;
3108
3108
  const isOpen = isControlled ? open : internalOpen;
3109
- const setOpen = React6.useCallback(
3109
+ const setOpen = React7.useCallback(
3110
3110
  (next) => {
3111
3111
  if (!isControlled) setInternalOpen(next);
3112
3112
  onOpenChange?.(next);
3113
3113
  },
3114
3114
  [isControlled, onOpenChange]
3115
3115
  );
3116
- const handleSelect = React6.useCallback(
3116
+ const handleSelect = React7.useCallback(
3117
3117
  (emoji) => {
3118
3118
  onSelect(emoji);
3119
3119
  if (!keepOpenOnSelect) setOpen(false);
@@ -3133,7 +3133,16 @@ function EmojiPickerPopover({
3133
3133
  children: /* @__PURE__ */ jsx(Smile, { className: "size-5" })
3134
3134
  }
3135
3135
  ) }),
3136
- /* @__PURE__ */ jsx(PopoverContent, { side, align, className: "w-auto p-0", children: /* @__PURE__ */ jsx(EmojiPicker, { onSelect: handleSelect, locale, ...pickerProps }) })
3136
+ /* @__PURE__ */ jsx(
3137
+ PopoverContent,
3138
+ {
3139
+ side,
3140
+ align,
3141
+ className: "w-auto p-0",
3142
+ onFocusOutside: (e) => e.preventDefault(),
3143
+ children: /* @__PURE__ */ jsx(EmojiPicker, { onSelect: handleSelect, locale, ...pickerProps })
3144
+ }
3145
+ )
3137
3146
  ] });
3138
3147
  }
3139
3148
 
@@ -3146,8 +3155,10 @@ function insertAtCaret(element, value, text) {
3146
3155
  caret: start + text.length
3147
3156
  };
3148
3157
  }
3149
- 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";
3150
- var fieldResetClassName = "border-0 bg-transparent shadow-none focus-visible:border-transparent focus-visible:ring-0 dark:bg-transparent";
3158
+
3159
+ // src/components/emoji/emoji-field-shared.ts
3160
+ 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";
3161
+ var emojiFieldResetClassName = "border-0 bg-transparent shadow-none focus-visible:border-transparent focus-visible:ring-0 dark:bg-transparent";
3151
3162
  function mergeRefs(...refs) {
3152
3163
  return (node) => {
3153
3164
  for (const ref of refs) {
@@ -3171,7 +3182,7 @@ function emitChange(element, nextValue, onChange) {
3171
3182
  });
3172
3183
  }
3173
3184
  function useEmojiInsert(fieldRef, value, onChange) {
3174
- return React6.useCallback(
3185
+ return React7.useCallback(
3175
3186
  (emoji) => {
3176
3187
  const el = fieldRef.current;
3177
3188
  const current = value !== void 0 && value !== null ? String(value) : el?.value ?? "";
@@ -3192,7 +3203,7 @@ function useEmojiInsert(fieldRef, value, onChange) {
3192
3203
  [fieldRef, value, onChange]
3193
3204
  );
3194
3205
  }
3195
- var EmojiTextarea = React6.forwardRef(
3206
+ var EmojiTextarea = React7.forwardRef(
3196
3207
  function EmojiTextarea2({
3197
3208
  className,
3198
3209
  locale = "en",
@@ -3212,10 +3223,10 @@ var EmojiTextarea = React6.forwardRef(
3212
3223
  emojiTriggerClassName,
3213
3224
  ...props
3214
3225
  }, ref) {
3215
- const fieldRef = React6.useRef(null);
3226
+ const fieldRef = React7.useRef(null);
3216
3227
  const handleEmojiSelect = useEmojiInsert(fieldRef, value, onChange);
3217
3228
  const pickerDisabled = Boolean(disabled || readOnly);
3218
- return /* @__PURE__ */ jsxs("div", { className: cn(wrapperClassName, className), children: [
3229
+ return /* @__PURE__ */ jsxs("div", { className: cn(emojiFieldWrapperClassName, className), children: [
3219
3230
  /* @__PURE__ */ jsx(
3220
3231
  "textarea",
3221
3232
  {
@@ -3227,7 +3238,7 @@ var EmojiTextarea = React6.forwardRef(
3227
3238
  onChange,
3228
3239
  className: cn(
3229
3240
  "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",
3230
- fieldResetClassName,
3241
+ emojiFieldResetClassName,
3231
3242
  className
3232
3243
  ),
3233
3244
  ...props
@@ -3258,7 +3269,7 @@ var EmojiTextarea = React6.forwardRef(
3258
3269
  }
3259
3270
  );
3260
3271
  EmojiTextarea.displayName = "EmojiTextarea";
3261
- var EmojiInput = React6.forwardRef(
3272
+ var EmojiInput = React7.forwardRef(
3262
3273
  function EmojiInput2({
3263
3274
  className,
3264
3275
  locale = "en",
@@ -3279,10 +3290,10 @@ var EmojiInput = React6.forwardRef(
3279
3290
  emojiTriggerClassName,
3280
3291
  ...props
3281
3292
  }, ref) {
3282
- const fieldRef = React6.useRef(null);
3293
+ const fieldRef = React7.useRef(null);
3283
3294
  const handleEmojiSelect = useEmojiInsert(fieldRef, value, onChange);
3284
3295
  const pickerDisabled = Boolean(disabled || readOnly);
3285
- return /* @__PURE__ */ jsxs("div", { className: cn(wrapperClassName, className), children: [
3296
+ return /* @__PURE__ */ jsxs("div", { className: cn(emojiFieldWrapperClassName, className), children: [
3286
3297
  /* @__PURE__ */ jsx(
3287
3298
  "input",
3288
3299
  {
@@ -3295,7 +3306,7 @@ var EmojiInput = React6.forwardRef(
3295
3306
  onChange,
3296
3307
  className: cn(
3297
3308
  "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",
3298
- fieldResetClassName,
3309
+ emojiFieldResetClassName,
3299
3310
  className
3300
3311
  ),
3301
3312
  ...props
@@ -3487,27 +3498,27 @@ function useHlsPlayback({
3487
3498
  onError,
3488
3499
  onPlayingChange
3489
3500
  }) {
3490
- const videoRef = React6.useRef(null);
3491
- const hlsRef = React6.useRef(null);
3492
- const [state, setState] = React6.useState("idle");
3493
- const [qualities, setQualities] = React6.useState([]);
3494
- const [activeLevel, setActiveLevel] = React6.useState(-1);
3495
- const [autoplayState, setAutoplayState] = React6.useState("none");
3496
- const [error, setError] = React6.useState(null);
3497
- const [reloadKey, setReloadKey] = React6.useState(0);
3498
- const onErrorRef = React6.useRef(onError);
3499
- const onPlayingChangeRef = React6.useRef(onPlayingChange);
3500
- React6.useEffect(() => {
3501
+ const videoRef = React7.useRef(null);
3502
+ const hlsRef = React7.useRef(null);
3503
+ const [state, setState] = React7.useState("idle");
3504
+ const [qualities, setQualities] = React7.useState([]);
3505
+ const [activeLevel, setActiveLevel] = React7.useState(-1);
3506
+ const [autoplayState, setAutoplayState] = React7.useState("none");
3507
+ const [error, setError] = React7.useState(null);
3508
+ const [reloadKey, setReloadKey] = React7.useState(0);
3509
+ const onErrorRef = React7.useRef(onError);
3510
+ const onPlayingChangeRef = React7.useRef(onPlayingChange);
3511
+ React7.useEffect(() => {
3501
3512
  onErrorRef.current = onError;
3502
3513
  onPlayingChangeRef.current = onPlayingChange;
3503
3514
  }, [onError, onPlayingChange]);
3504
- const retry = React6.useCallback(() => {
3515
+ const retry = React7.useCallback(() => {
3505
3516
  setError(null);
3506
3517
  setState("loading");
3507
3518
  setAutoplayState("none");
3508
3519
  setReloadKey((k) => k + 1);
3509
3520
  }, []);
3510
- React6.useEffect(() => {
3521
+ React7.useEffect(() => {
3511
3522
  const media = videoRef.current;
3512
3523
  if (!media || !src || !active) {
3513
3524
  setState("idle");
@@ -3719,7 +3730,7 @@ function useHlsPlayback({
3719
3730
  destroyHls();
3720
3731
  };
3721
3732
  }, [src, mode, active, autoPlay, muted, reloadKey]);
3722
- const setLevel = React6.useCallback((index) => {
3733
+ const setLevel = React7.useCallback((index) => {
3723
3734
  const hls = hlsRef.current;
3724
3735
  if (!hls) return;
3725
3736
  hls.nextLevel = index;
@@ -3802,12 +3813,12 @@ function VideoPlayer({
3802
3813
  className
3803
3814
  }) {
3804
3815
  const t = { ...DEFAULT_LABELS2, ...labels };
3805
- const containerRef = React6.useRef(null);
3806
- const firstPlayFiredRef = React6.useRef(false);
3807
- const [userStarted, setUserStarted] = React6.useState(false);
3816
+ const containerRef = React7.useRef(null);
3817
+ const firstPlayFiredRef = React7.useRef(false);
3818
+ const [userStarted, setUserStarted] = React7.useState(false);
3808
3819
  const active = autoPlay || !poster || userStarted;
3809
3820
  const autoplayActive = autoPlay || userStarted;
3810
- const handlePlayingChange = React6.useCallback(
3821
+ const handlePlayingChange = React7.useCallback(
3811
3822
  (playing) => {
3812
3823
  setIsPlaying(playing);
3813
3824
  if (playing && !firstPlayFiredRef.current) {
@@ -3836,25 +3847,25 @@ function VideoPlayer({
3836
3847
  onError,
3837
3848
  onPlayingChange: handlePlayingChange
3838
3849
  });
3839
- const [isPlaying, setIsPlaying] = React6.useState(false);
3840
- const [isMuted, setIsMuted] = React6.useState(muted);
3841
- const [volume, setVolume] = React6.useState(1);
3842
- const [currentTime, setCurrentTime] = React6.useState(0);
3843
- const [duration, setDuration] = React6.useState(0);
3844
- const [buffered, setBuffered] = React6.useState(0);
3845
- const [isFullscreen, setIsFullscreen] = React6.useState(false);
3846
- const [pipActive, setPipActive] = React6.useState(false);
3847
- const [controlsVisible, setControlsVisible] = React6.useState(true);
3848
- const [playbackRate, setPlaybackRate] = React6.useState(1);
3849
- const [openMenu, setOpenMenu] = React6.useState(
3850
+ const [isPlaying, setIsPlaying] = React7.useState(false);
3851
+ const [isMuted, setIsMuted] = React7.useState(muted);
3852
+ const [volume, setVolume] = React7.useState(1);
3853
+ const [currentTime, setCurrentTime] = React7.useState(0);
3854
+ const [duration, setDuration] = React7.useState(0);
3855
+ const [buffered, setBuffered] = React7.useState(0);
3856
+ const [isFullscreen, setIsFullscreen] = React7.useState(false);
3857
+ const [pipActive, setPipActive] = React7.useState(false);
3858
+ const [controlsVisible, setControlsVisible] = React7.useState(true);
3859
+ const [playbackRate, setPlaybackRate] = React7.useState(1);
3860
+ const [openMenu, setOpenMenu] = React7.useState(
3850
3861
  null
3851
3862
  );
3852
- const [behindLive, setBehindLive] = React6.useState(false);
3853
- const [webkitFullscreenSupported, setWebkitFullscreenSupported] = React6.useState(false);
3854
- const hideTimerRef = React6.useRef(null);
3863
+ const [behindLive, setBehindLive] = React7.useState(false);
3864
+ const [webkitFullscreenSupported, setWebkitFullscreenSupported] = React7.useState(false);
3865
+ const hideTimerRef = React7.useRef(null);
3855
3866
  const pipSupported = typeof document !== "undefined" && "pictureInPictureEnabled" in document && document.pictureInPictureEnabled;
3856
3867
  const fullscreenSupported = hasStandardFullscreen() || webkitFullscreenSupported;
3857
- React6.useEffect(() => {
3868
+ React7.useEffect(() => {
3858
3869
  const video = videoRef.current;
3859
3870
  if (!video || !active) return;
3860
3871
  const onTimeUpdate = () => {
@@ -3887,15 +3898,15 @@ function VideoPlayer({
3887
3898
  video.removeEventListener("ratechange", onRate);
3888
3899
  };
3889
3900
  }, [videoRef, active, mode]);
3890
- React6.useEffect(() => {
3901
+ React7.useEffect(() => {
3891
3902
  setWebkitFullscreenSupported(hasWebkitVideoFullscreen(videoRef.current));
3892
3903
  }, [videoRef, active]);
3893
- React6.useEffect(() => {
3904
+ React7.useEffect(() => {
3894
3905
  const onFsChange = () => setIsFullscreen(document.fullscreenElement === containerRef.current);
3895
3906
  document.addEventListener("fullscreenchange", onFsChange);
3896
3907
  return () => document.removeEventListener("fullscreenchange", onFsChange);
3897
3908
  }, []);
3898
- React6.useEffect(() => {
3909
+ React7.useEffect(() => {
3899
3910
  const video = asWebkitVideo(videoRef.current);
3900
3911
  if (!video) return;
3901
3912
  const onBegin = () => setIsFullscreen(true);
@@ -3907,7 +3918,7 @@ function VideoPlayer({
3907
3918
  video.removeEventListener("webkitendfullscreen", onEnd);
3908
3919
  };
3909
3920
  }, [videoRef, active]);
3910
- React6.useEffect(() => {
3921
+ React7.useEffect(() => {
3911
3922
  const video = videoRef.current;
3912
3923
  if (!video) return;
3913
3924
  const onEnter = () => setPipActive(true);
@@ -3919,18 +3930,18 @@ function VideoPlayer({
3919
3930
  video.removeEventListener("leavepictureinpicture", onLeave);
3920
3931
  };
3921
3932
  }, [videoRef]);
3922
- const scheduleHide = React6.useCallback(() => {
3933
+ const scheduleHide = React7.useCallback(() => {
3923
3934
  if (hideTimerRef.current) clearTimeout(hideTimerRef.current);
3924
3935
  hideTimerRef.current = setTimeout(() => {
3925
3936
  setControlsVisible(false);
3926
3937
  setOpenMenu(null);
3927
3938
  }, CONTROLS_HIDE_MS);
3928
3939
  }, []);
3929
- const revealControls = React6.useCallback(() => {
3940
+ const revealControls = React7.useCallback(() => {
3930
3941
  setControlsVisible(true);
3931
3942
  scheduleHide();
3932
3943
  }, [scheduleHide]);
3933
- React6.useEffect(() => {
3944
+ React7.useEffect(() => {
3934
3945
  return () => {
3935
3946
  if (hideTimerRef.current) clearTimeout(hideTimerRef.current);
3936
3947
  };
@@ -4393,8 +4404,8 @@ function MenuItem({
4393
4404
  );
4394
4405
  }
4395
4406
  function usePlaybackStats(statsUrl, { intervalMs = 15e3, enabled = true } = {}) {
4396
- const [stats, setStats] = React6.useState({});
4397
- React6.useEffect(() => {
4407
+ const [stats, setStats] = React7.useState({});
4408
+ React7.useEffect(() => {
4398
4409
  if (!statsUrl || !enabled) return;
4399
4410
  let cancelled = false;
4400
4411
  const controller = new AbortController();
@@ -5419,7 +5430,7 @@ function ScrollBar({
5419
5430
  );
5420
5431
  }
5421
5432
  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";
5422
- var PhoneInput = React6.forwardRef(
5433
+ var PhoneInput = React7.forwardRef(
5423
5434
  ({ className, onChange, value, defaultCountry = "MX", ...props }, ref) => {
5424
5435
  return /* @__PURE__ */ jsx(
5425
5436
  RPNInput.default,
@@ -5439,7 +5450,7 @@ var PhoneInput = React6.forwardRef(
5439
5450
  }
5440
5451
  );
5441
5452
  PhoneInput.displayName = "PhoneInput";
5442
- var InputComponent = React6.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5453
+ var InputComponent = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
5443
5454
  Input,
5444
5455
  {
5445
5456
  className: cn(
@@ -5457,9 +5468,9 @@ var CountrySelect = ({
5457
5468
  options: countryList,
5458
5469
  onChange
5459
5470
  }) => {
5460
- const scrollAreaRef = React6.useRef(null);
5461
- const [searchValue, setSearchValue] = React6.useState("");
5462
- const [isOpen, setIsOpen] = React6.useState(false);
5471
+ const scrollAreaRef = React7.useRef(null);
5472
+ const [searchValue, setSearchValue] = React7.useState("");
5473
+ const [isOpen, setIsOpen] = React7.useState(false);
5463
5474
  return /* @__PURE__ */ jsxs(
5464
5475
  Popover,
5465
5476
  {
@@ -5640,8 +5651,8 @@ var MEXICO_STATE_PATHS = {
5640
5651
  };
5641
5652
  function MexicoMap({ selected, onToggle, className }) {
5642
5653
  const isInteractive = typeof onToggle === "function";
5643
- const selectedSet = React6.useMemo(() => new Set(selected), [selected]);
5644
- const handleKeyDown = React6.useCallback(
5654
+ const selectedSet = React7.useMemo(() => new Set(selected), [selected]);
5655
+ const handleKeyDown = React7.useCallback(
5645
5656
  (event, id) => {
5646
5657
  if (!onToggle) return;
5647
5658
  if (event.key === "Enter" || event.key === " ") {
@@ -6123,6 +6134,130 @@ function ChatMessageList({
6123
6134
  /* @__PURE__ */ jsx(MessageScrollerButton, {})
6124
6135
  ] }) });
6125
6136
  }
6137
+ var MessageComposer = React7.forwardRef(function MessageComposer2({
6138
+ className,
6139
+ locale = "en",
6140
+ disabled,
6141
+ readOnly,
6142
+ value,
6143
+ onChange,
6144
+ onSubmit,
6145
+ onKeyDown,
6146
+ sendLabel,
6147
+ sendDisabled = false,
6148
+ allowEmptySubmit = false,
6149
+ sendButtonClassName,
6150
+ sendButtonSize = "sm",
6151
+ submitOnEnter = true,
6152
+ tools,
6153
+ attachments,
6154
+ triggerLabel,
6155
+ keepOpenOnSelect,
6156
+ open,
6157
+ onOpenChange,
6158
+ side = "top",
6159
+ align = "end",
6160
+ labels,
6161
+ recentLimit,
6162
+ storageKey,
6163
+ emojiTriggerClassName,
6164
+ rows = 2,
6165
+ ...props
6166
+ }, ref) {
6167
+ const formRef = React7.useRef(null);
6168
+ const fieldRef = React7.useRef(null);
6169
+ const handleEmojiSelect = useEmojiInsert(fieldRef, value, onChange);
6170
+ const pickerDisabled = Boolean(disabled || readOnly);
6171
+ const draft = value !== void 0 && value !== null ? String(value) : "";
6172
+ const canSubmit = (allowEmptySubmit || Boolean(draft.trim())) && !sendDisabled && !disabled && !readOnly;
6173
+ const handleSubmit = React7.useCallback(
6174
+ (event) => {
6175
+ event.preventDefault();
6176
+ if (!canSubmit) return;
6177
+ onSubmit(event);
6178
+ },
6179
+ [canSubmit, onSubmit]
6180
+ );
6181
+ const handleKeyDown = React7.useCallback(
6182
+ (event) => {
6183
+ onKeyDown?.(event);
6184
+ if (event.defaultPrevented) return;
6185
+ if (!submitOnEnter) return;
6186
+ if (event.key !== "Enter" || event.shiftKey) return;
6187
+ if (event.nativeEvent.isComposing || event.keyCode === 229) return;
6188
+ event.preventDefault();
6189
+ if (!canSubmit) return;
6190
+ formRef.current?.requestSubmit();
6191
+ },
6192
+ [canSubmit, onKeyDown, submitOnEnter]
6193
+ );
6194
+ return /* @__PURE__ */ jsxs(
6195
+ "form",
6196
+ {
6197
+ ref: formRef,
6198
+ className: cn(emojiFieldWrapperClassName, "flex flex-col", className),
6199
+ onSubmit: handleSubmit,
6200
+ children: [
6201
+ /* @__PURE__ */ jsx(
6202
+ "textarea",
6203
+ {
6204
+ "data-slot": "textarea",
6205
+ ref: mergeRefs(fieldRef, ref),
6206
+ disabled,
6207
+ readOnly,
6208
+ value,
6209
+ onChange,
6210
+ onKeyDown: handleKeyDown,
6211
+ rows,
6212
+ className: cn(
6213
+ "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",
6214
+ emojiFieldResetClassName
6215
+ ),
6216
+ ...props
6217
+ }
6218
+ ),
6219
+ attachments ? /* @__PURE__ */ jsx("div", { className: "border-t px-2 py-2", children: attachments }) : null,
6220
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 px-1.5 pb-1.5", children: [
6221
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-0.5", children: [
6222
+ /* @__PURE__ */ jsx(
6223
+ EmojiPickerPopover,
6224
+ {
6225
+ locale,
6226
+ onSelect: handleEmojiSelect,
6227
+ disabled: pickerDisabled,
6228
+ triggerLabel,
6229
+ keepOpenOnSelect,
6230
+ open,
6231
+ onOpenChange,
6232
+ side,
6233
+ align,
6234
+ labels,
6235
+ recentLimit,
6236
+ storageKey,
6237
+ triggerClassName: cn(
6238
+ "size-7 text-muted-foreground",
6239
+ emojiTriggerClassName
6240
+ )
6241
+ }
6242
+ ),
6243
+ tools
6244
+ ] }),
6245
+ /* @__PURE__ */ jsx(
6246
+ Button,
6247
+ {
6248
+ type: "submit",
6249
+ size: sendButtonSize,
6250
+ disabled: !canSubmit,
6251
+ className: sendButtonClassName,
6252
+ children: sendLabel
6253
+ }
6254
+ )
6255
+ ] })
6256
+ ]
6257
+ }
6258
+ );
6259
+ });
6260
+ MessageComposer.displayName = "MessageComposer";
6126
6261
  var RECONNECT_DELAY_MS = 2e3;
6127
6262
  function useSupportConversation({
6128
6263
  client,
@@ -6343,23 +6478,22 @@ function ThreadPanel({
6343
6478
  emptyDescription: labels.emptyThread
6344
6479
  }
6345
6480
  ) }),
6346
- /* @__PURE__ */ jsxs("form", { className: "flex gap-2 border-t p-3", onSubmit, children: [
6347
- /* @__PURE__ */ jsx(
6348
- EmojiTextarea,
6349
- {
6350
- locale: emojiLocale,
6351
- value: draft,
6352
- onChange: (e) => setDraft(e.target.value.slice(0, 2e3)),
6353
- placeholder: labels.placeholder,
6354
- "aria-label": labels.placeholder,
6355
- disabled: loading || sending,
6356
- maxLength: 2e3,
6357
- rows: 2,
6358
- className: "min-h-10 flex-1"
6359
- }
6360
- ),
6361
- /* @__PURE__ */ jsx(Button, { type: "submit", disabled: !draft.trim() || sending || loading, children: labels.send })
6362
- ] })
6481
+ /* @__PURE__ */ jsx("div", { className: "border-t p-3", children: /* @__PURE__ */ jsx(
6482
+ MessageComposer,
6483
+ {
6484
+ locale: emojiLocale,
6485
+ value: draft,
6486
+ onChange: (e) => setDraft(e.target.value.slice(0, 2e3)),
6487
+ onSubmit,
6488
+ sendLabel: labels.send,
6489
+ placeholder: labels.placeholder,
6490
+ "aria-label": labels.placeholder,
6491
+ disabled: loading || sending,
6492
+ sendDisabled: loading || sending,
6493
+ maxLength: 2e3,
6494
+ rows: 2
6495
+ }
6496
+ ) })
6363
6497
  ]
6364
6498
  }
6365
6499
  );
@@ -6741,6 +6875,6 @@ function createSupportChatClient(basePath = "/api/chat-svc") {
6741
6875
  };
6742
6876
  }
6743
6877
 
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 };
6878
+ 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, MessageComposer, 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 };
6745
6879
  //# sourceMappingURL=index.js.map
6746
6880
  //# sourceMappingURL=index.js.map