@underverse-ui/underverse 1.0.59 → 1.0.61

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
@@ -3503,11 +3503,11 @@ var ToastProvider = ({ children, position = "top-right", maxToasts = 5 }) => {
3503
3503
  ] });
3504
3504
  };
3505
3505
  var ToastComponent = ({ toast, onRemove }) => {
3506
- const [isVisible, setIsVisible] = useState7(false);
3506
+ const [isVisible, setIsVisible] = useState7(true);
3507
3507
  const [progress, setProgress] = useState7(100);
3508
3508
  const [paused, setPaused] = useState7(false);
3509
3509
  const total = toast.duration && toast.duration > 0 ? toast.duration : 5e3;
3510
- const endTsRef = useRef4(Date.now() + total);
3510
+ const endTsRef = useRef4(0);
3511
3511
  const remainingRef = useRef4(total);
3512
3512
  const pausedRef = useRef4(false);
3513
3513
  const handleRemove = useCallback3(() => {
@@ -3515,7 +3515,6 @@ var ToastComponent = ({ toast, onRemove }) => {
3515
3515
  setTimeout(() => onRemove(toast.id), 150);
3516
3516
  }, [onRemove, toast.id]);
3517
3517
  useEffect2(() => {
3518
- setIsVisible(true);
3519
3518
  if (toast.duration === 0) return;
3520
3519
  remainingRef.current = total;
3521
3520
  endTsRef.current = Date.now() + total;
@@ -3536,29 +3535,25 @@ var ToastComponent = ({ toast, onRemove }) => {
3536
3535
  icon: CheckCircle2,
3537
3536
  containerClassName: "bg-success/5 border-success/30",
3538
3537
  iconClassName: "text-success",
3539
- iconBgClassName: "bg-success/15",
3540
- accentBarClassName: "bg-success"
3538
+ iconBgClassName: "bg-success/15"
3541
3539
  },
3542
3540
  error: {
3543
3541
  icon: AlertCircle2,
3544
3542
  containerClassName: "bg-destructive/5 border-destructive/30",
3545
3543
  iconClassName: "text-destructive",
3546
- iconBgClassName: "bg-destructive/15",
3547
- accentBarClassName: "bg-destructive"
3544
+ iconBgClassName: "bg-destructive/15"
3548
3545
  },
3549
3546
  warning: {
3550
3547
  icon: AlertTriangle2,
3551
3548
  containerClassName: "bg-warning/5 border-warning/30",
3552
3549
  iconClassName: "text-warning",
3553
- iconBgClassName: "bg-warning/15",
3554
- accentBarClassName: "bg-warning"
3550
+ iconBgClassName: "bg-warning/15"
3555
3551
  },
3556
3552
  info: {
3557
3553
  icon: Info,
3558
3554
  containerClassName: "bg-info/5 border-info/30",
3559
3555
  iconClassName: "text-info",
3560
- iconBgClassName: "bg-info/15",
3561
- accentBarClassName: "bg-info"
3556
+ iconBgClassName: "bg-info/15"
3562
3557
  }
3563
3558
  };
3564
3559
  const config = typeConfig[toast.type];
@@ -3567,7 +3562,7 @@ var ToastComponent = ({ toast, onRemove }) => {
3567
3562
  "div",
3568
3563
  {
3569
3564
  className: cn(
3570
- "relative w-80 rounded-r-xl border border-l-0 backdrop-blur-md transition-all duration-300 pointer-events-auto overflow-hidden",
3565
+ "relative w-80 rounded-xl border backdrop-blur-md transition-all duration-300 pointer-events-auto overflow-hidden",
3571
3566
  "bg-card shadow-xl",
3572
3567
  "animate-in slide-in-from-right-full",
3573
3568
  config.containerClassName,
@@ -3588,8 +3583,7 @@ var ToastComponent = ({ toast, onRemove }) => {
3588
3583
  setPaused(false);
3589
3584
  },
3590
3585
  children: [
3591
- /* @__PURE__ */ jsx16("div", { className: cn("absolute left-0 top-0 bottom-0 w-1", config.accentBarClassName) }),
3592
- /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-3 p-4 pl-5", children: [
3586
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-3 p-4", children: [
3593
3587
  /* @__PURE__ */ jsx16("div", { className: cn("flex items-center justify-center w-8 h-8 rounded-full shrink-0", config.iconBgClassName), children: /* @__PURE__ */ jsx16(Icon, { className: cn("h-4 w-4", config.iconClassName) }) }),
3594
3588
  /* @__PURE__ */ jsxs12("div", { className: "flex-1 space-y-1", children: [
3595
3589
  toast.title && /* @__PURE__ */ jsx16("h4", { className: "font-medium text-sm leading-none", children: toast.title }),
@@ -3641,6 +3635,18 @@ var Toast_default = ToastProvider;
3641
3635
  // src/components/Tooltip.tsx
3642
3636
  import * as React14 from "react";
3643
3637
  import { createPortal as createPortal2 } from "react-dom";
3638
+
3639
+ // src/hooks/useHydrated.ts
3640
+ import { useSyncExternalStore } from "react";
3641
+ var subscribe = () => () => {
3642
+ };
3643
+ var getSnapshot = () => true;
3644
+ var getServerSnapshot = () => false;
3645
+ function useHydrated() {
3646
+ return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
3647
+ }
3648
+
3649
+ // src/components/Tooltip.tsx
3644
3650
  import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
3645
3651
  var variantStyles3 = {
3646
3652
  default: "bg-popover text-popover-foreground border-border/50",
@@ -3649,17 +3655,6 @@ var variantStyles3 = {
3649
3655
  error: "bg-destructive text-destructive-foreground border-destructive/20",
3650
3656
  success: "bg-success text-success-foreground border-success/20"
3651
3657
  };
3652
- function assignRef(ref, value) {
3653
- if (!ref) return;
3654
- if (typeof ref === "function") {
3655
- ref(value);
3656
- return;
3657
- }
3658
- try {
3659
- ref.current = value;
3660
- } catch {
3661
- }
3662
- }
3663
3658
  var clamp = (value, min, max) => Math.max(min, Math.min(max, value));
3664
3659
  function getTransformOrigin(side) {
3665
3660
  switch (side) {
@@ -3715,19 +3710,24 @@ var Tooltip = ({
3715
3710
  variant = "default"
3716
3711
  }) => {
3717
3712
  const [isOpen, setIsOpen] = React14.useState(false);
3718
- const [isMounted, setIsMounted] = React14.useState(false);
3713
+ const isMounted = useHydrated();
3719
3714
  const triggerRef = React14.useRef(null);
3720
3715
  const positionerRef = React14.useRef(null);
3721
3716
  const panelRef = React14.useRef(null);
3722
3717
  const timeoutRef = React14.useRef(void 0);
3723
3718
  const lastAppliedRef = React14.useRef(null);
3724
- React14.useEffect(() => {
3725
- setIsMounted(true);
3726
- }, []);
3719
+ const triggerSelector = React14.useId();
3727
3720
  const delayOpen = typeof delay === "object" ? delay.open || 700 : delay;
3728
3721
  const delayClose = typeof delay === "object" ? delay.close || 300 : delay;
3729
3722
  const offset = 8;
3730
3723
  const padding = 8;
3724
+ React14.useLayoutEffect(() => {
3725
+ if (typeof document === "undefined") return;
3726
+ const triggerEl = document.querySelector(`[data-underverse-tooltip-trigger="${triggerSelector}"]`);
3727
+ if (triggerEl) {
3728
+ triggerRef.current = triggerEl;
3729
+ }
3730
+ }, [children, triggerSelector]);
3731
3731
  const updatePosition = React14.useCallback(() => {
3732
3732
  const triggerEl = triggerRef.current;
3733
3733
  const positionerEl = positionerRef.current;
@@ -3827,28 +3827,36 @@ var Tooltip = ({
3827
3827
  return children;
3828
3828
  }
3829
3829
  return /* @__PURE__ */ jsxs13(Fragment3, { children: [
3830
- React14.cloneElement(children, {
3831
- ref: (node) => {
3832
- triggerRef.current = node;
3833
- assignRef(children.props?.ref, node);
3834
- },
3835
- onMouseEnter: (e) => {
3836
- handleMouseEnter();
3837
- if (typeof children.props?.onMouseEnter === "function") children.props.onMouseEnter(e);
3838
- },
3839
- onMouseLeave: (e) => {
3840
- handleMouseLeave();
3841
- if (typeof children.props?.onMouseLeave === "function") children.props.onMouseLeave(e);
3842
- },
3843
- onFocus: (e) => {
3844
- handleFocus();
3845
- if (typeof children.props?.onFocus === "function") children.props.onFocus(e);
3846
- },
3847
- onBlur: (e) => {
3848
- handleBlur();
3849
- if (typeof children.props?.onBlur === "function") children.props.onBlur(e);
3850
- }
3851
- }),
3830
+ (() => {
3831
+ const TriggerComponent = children.type;
3832
+ const triggerProps = children.props;
3833
+ return /* @__PURE__ */ jsx17(
3834
+ TriggerComponent,
3835
+ {
3836
+ ...triggerProps,
3837
+ "data-underverse-tooltip-trigger": triggerSelector,
3838
+ onMouseEnter: (e) => {
3839
+ triggerRef.current = e.currentTarget;
3840
+ handleMouseEnter();
3841
+ if (typeof triggerProps.onMouseEnter === "function") triggerProps.onMouseEnter(e);
3842
+ },
3843
+ onMouseLeave: (e) => {
3844
+ triggerRef.current = e.currentTarget;
3845
+ handleMouseLeave();
3846
+ if (typeof triggerProps.onMouseLeave === "function") triggerProps.onMouseLeave(e);
3847
+ },
3848
+ onFocus: (e) => {
3849
+ triggerRef.current = e.currentTarget;
3850
+ handleFocus();
3851
+ if (typeof triggerProps.onFocus === "function") triggerProps.onFocus(e);
3852
+ },
3853
+ onBlur: (e) => {
3854
+ handleBlur();
3855
+ if (typeof triggerProps.onBlur === "function") triggerProps.onBlur(e);
3856
+ }
3857
+ }
3858
+ );
3859
+ })(),
3852
3860
  isMounted && isOpen && createPortal2(
3853
3861
  /* @__PURE__ */ jsx17(
3854
3862
  "div",
@@ -4086,17 +4094,6 @@ function getAnimationStyles() {
4086
4094
 
4087
4095
  // src/components/Popover.tsx
4088
4096
  import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
4089
- function assignRef2(ref, value) {
4090
- if (!ref) return;
4091
- if (typeof ref === "function") {
4092
- ref(value);
4093
- return;
4094
- }
4095
- try {
4096
- ref.current = value;
4097
- } catch {
4098
- }
4099
- }
4100
4097
  function getTransformOrigin2(side, align) {
4101
4098
  if (side === "top") return `${align === "end" ? "right" : "left"} bottom`;
4102
4099
  if (side === "bottom") return `${align === "end" ? "right" : "left"} top`;
@@ -4208,7 +4205,15 @@ var Popover = ({
4208
4205
  );
4209
4206
  const offset = 4;
4210
4207
  const padding = 8;
4208
+ const triggerSelector = React15.useId();
4211
4209
  const initialPlacement = React15.useMemo(() => normalizePlacement(placement), [placement]);
4210
+ React15.useLayoutEffect(() => {
4211
+ if (typeof document === "undefined") return;
4212
+ const triggerEl = document.querySelector(`[data-underverse-popover-trigger="${triggerSelector}"]`);
4213
+ if (triggerEl) {
4214
+ triggerRef.current = triggerEl;
4215
+ }
4216
+ }, [triggerSelector, trigger]);
4212
4217
  const updatePosition = React15.useCallback(() => {
4213
4218
  const triggerEl = triggerRef.current;
4214
4219
  const positionerEl = positionerRef.current;
@@ -4386,27 +4391,36 @@ var Popover = ({
4386
4391
  ) : null;
4387
4392
  return /* @__PURE__ */ jsxs14(Fragment4, { children: [
4388
4393
  (() => {
4389
- const triggerEl = trigger;
4390
- return React15.cloneElement(triggerEl, {
4391
- ref: (node) => {
4392
- triggerRef.current = node;
4393
- assignRef2(triggerEl.props?.ref, node);
4394
- },
4395
- onClick: (e) => {
4396
- e.preventDefault();
4397
- e.stopPropagation();
4398
- handleTriggerClick();
4399
- if (triggerEl.props && typeof triggerEl.props.onClick === "function") {
4400
- triggerEl.props.onClick(e);
4401
- }
4402
- },
4403
- "aria-expanded": isOpen,
4404
- "aria-haspopup": triggerEl.props?.["aria-haspopup"] ?? "dialog",
4405
- className: cn(
4406
- triggerEl.props?.className,
4407
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
4408
- )
4409
- });
4394
+ const TriggerComponent = trigger.type;
4395
+ const triggerProps = trigger.props;
4396
+ return /* @__PURE__ */ jsx18(
4397
+ TriggerComponent,
4398
+ {
4399
+ ...triggerProps,
4400
+ "data-underverse-popover-trigger": triggerSelector,
4401
+ onClick: (e) => {
4402
+ triggerRef.current = e.currentTarget;
4403
+ e.preventDefault();
4404
+ e.stopPropagation();
4405
+ handleTriggerClick();
4406
+ if (typeof triggerProps.onClick === "function") {
4407
+ triggerProps.onClick(e);
4408
+ }
4409
+ },
4410
+ onFocus: (e) => {
4411
+ triggerRef.current = e.currentTarget;
4412
+ if (typeof triggerProps.onFocus === "function") {
4413
+ triggerProps.onFocus(e);
4414
+ }
4415
+ },
4416
+ "aria-expanded": isOpen,
4417
+ "aria-haspopup": triggerProps["aria-haspopup"] ?? "dialog",
4418
+ className: cn(
4419
+ triggerProps.className,
4420
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
4421
+ )
4422
+ }
4423
+ );
4410
4424
  })(),
4411
4425
  popoverContent
4412
4426
  ] });
@@ -5165,6 +5179,20 @@ var VerticalTabs = ({ sidebarWidth = "w-48", className, ...props }) => {
5165
5179
  // src/components/DropdownMenu.tsx
5166
5180
  import React20, { useState as useState15 } from "react";
5167
5181
  import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
5182
+ function useResettingIndex(resetToken) {
5183
+ const [state, setState] = React20.useState({ resetToken, index: -1 });
5184
+ const activeIndex = Object.is(state.resetToken, resetToken) ? state.index : -1;
5185
+ const setActiveIndex = React20.useCallback((nextIndex) => {
5186
+ setState((prev) => {
5187
+ const prevIndex = Object.is(prev.resetToken, resetToken) ? prev.index : -1;
5188
+ return {
5189
+ resetToken,
5190
+ index: typeof nextIndex === "function" ? nextIndex(prevIndex) : nextIndex
5191
+ };
5192
+ });
5193
+ }, [resetToken]);
5194
+ return [activeIndex, setActiveIndex];
5195
+ }
5168
5196
  var DropdownMenu = ({
5169
5197
  trigger,
5170
5198
  children,
@@ -5178,16 +5206,13 @@ var DropdownMenu = ({
5178
5206
  items
5179
5207
  }) => {
5180
5208
  const [internalOpen, setInternalOpen] = useState15(false);
5209
+ const open = isOpen !== void 0 ? isOpen : internalOpen;
5210
+ const setOpen = onOpenChange || setInternalOpen;
5181
5211
  const triggerRef = React20.useRef(null);
5182
5212
  const menuRef = React20.useRef(null);
5183
5213
  const itemsRef = React20.useRef([]);
5184
- const [activeIndex, setActiveIndex] = useState15(-1);
5214
+ const [activeIndex, setActiveIndex] = useResettingIndex(open);
5185
5215
  useShadCNAnimations();
5186
- const open = isOpen !== void 0 ? isOpen : internalOpen;
5187
- const setOpen = onOpenChange || setInternalOpen;
5188
- React20.useEffect(() => {
5189
- if (open) setActiveIndex(-1);
5190
- }, [open]);
5191
5216
  React20.useEffect(() => {
5192
5217
  if (!open) return;
5193
5218
  const handleKeyNav = (e) => {
@@ -5224,7 +5249,7 @@ var DropdownMenu = ({
5224
5249
  return () => {
5225
5250
  document.removeEventListener("keydown", handleKeyNav);
5226
5251
  };
5227
- }, [open, activeIndex]);
5252
+ }, [open, activeIndex, setActiveIndex]);
5228
5253
  const handleItemClick = (itemOnClick) => {
5229
5254
  itemOnClick();
5230
5255
  if (closeOnSelect) {
@@ -5262,36 +5287,48 @@ var DropdownMenu = ({
5262
5287
  index
5263
5288
  );
5264
5289
  }) : children });
5265
- const enhancedTrigger = React20.cloneElement(trigger, {
5266
- ref: triggerRef,
5267
- "aria-haspopup": "menu",
5268
- "aria-expanded": open,
5269
- onKeyDown: (e) => {
5270
- if (disabled) return;
5271
- if (e.key === "ArrowDown") {
5272
- e.preventDefault();
5273
- setOpen(true);
5274
- requestAnimationFrame(() => itemsRef.current.find((el) => el && !el.disabled)?.focus());
5275
- } else if (e.key === "ArrowUp") {
5276
- e.preventDefault();
5277
- setOpen(true);
5278
- requestAnimationFrame(() => {
5279
- const enabled = itemsRef.current.filter((el) => el && !el.disabled);
5280
- enabled[enabled.length - 1]?.focus();
5281
- });
5282
- } else if (e.key === "Escape") {
5283
- e.preventDefault();
5284
- setOpen(false);
5285
- }
5286
- if (typeof trigger.props?.onKeyDown === "function") {
5287
- trigger.props.onKeyDown(e);
5288
- }
5289
- },
5290
- className: cn(
5291
- trigger.props?.className,
5292
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
5293
- )
5294
- });
5290
+ const TriggerComponent = trigger.type;
5291
+ const triggerProps = trigger.props;
5292
+ const enhancedTrigger = /* @__PURE__ */ jsx24(
5293
+ TriggerComponent,
5294
+ {
5295
+ ...triggerProps,
5296
+ "aria-haspopup": "menu",
5297
+ "aria-expanded": open,
5298
+ onKeyDown: (e) => {
5299
+ triggerRef.current = e.currentTarget;
5300
+ if (disabled) return;
5301
+ if (e.key === "ArrowDown") {
5302
+ e.preventDefault();
5303
+ setOpen(true);
5304
+ requestAnimationFrame(() => itemsRef.current.find((el) => el && !el.disabled)?.focus());
5305
+ } else if (e.key === "ArrowUp") {
5306
+ e.preventDefault();
5307
+ setOpen(true);
5308
+ requestAnimationFrame(() => {
5309
+ const enabled = itemsRef.current.filter((el) => el && !el.disabled);
5310
+ enabled[enabled.length - 1]?.focus();
5311
+ });
5312
+ } else if (e.key === "Escape") {
5313
+ e.preventDefault();
5314
+ setOpen(false);
5315
+ }
5316
+ if (typeof triggerProps.onKeyDown === "function") {
5317
+ triggerProps.onKeyDown(e);
5318
+ }
5319
+ },
5320
+ onFocus: (e) => {
5321
+ triggerRef.current = e.currentTarget;
5322
+ if (typeof triggerProps.onFocus === "function") {
5323
+ triggerProps.onFocus(e);
5324
+ }
5325
+ },
5326
+ className: cn(
5327
+ triggerProps.className,
5328
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background"
5329
+ )
5330
+ }
5331
+ );
5295
5332
  return /* @__PURE__ */ jsx24(
5296
5333
  Popover,
5297
5334
  {
@@ -5376,7 +5413,7 @@ import { ChevronLeft, ChevronRight as ChevronRight2, ChevronsLeft, ChevronsRight
5376
5413
 
5377
5414
  // src/components/Combobox.tsx
5378
5415
  import * as React22 from "react";
5379
- import { useId as useId3 } from "react";
5416
+ import { useId as useId5 } from "react";
5380
5417
  import { ChevronDown, Search as Search3, SearchX, Check as Check3, X as X8 } from "lucide-react";
5381
5418
 
5382
5419
  // src/components/OverlayScrollbarProvider.tsx
@@ -5659,7 +5696,7 @@ var Combobox = ({
5659
5696
  const inputRef = React22.useRef(null);
5660
5697
  const optionsViewportRef = React22.useRef(null);
5661
5698
  useOverlayScrollbarTarget(optionsViewportRef, { enabled: useOverlayScrollbar });
5662
- const autoId = useId3();
5699
+ const autoId = useId5();
5663
5700
  const resolvedId = id ? String(id) : `combobox-${autoId}`;
5664
5701
  const labelId = label ? `${resolvedId}-label` : void 0;
5665
5702
  const enableSearch = options.length > 10;
@@ -6687,7 +6724,7 @@ function formatDateSmart(date, locale = "en") {
6687
6724
  // src/components/DatePicker.tsx
6688
6725
  import { Calendar, ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight3, Sparkles as Sparkles2, X as XIcon } from "lucide-react";
6689
6726
  import * as React26 from "react";
6690
- import { useId as useId4 } from "react";
6727
+ import { useId as useId6 } from "react";
6691
6728
  import { Fragment as Fragment6, jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
6692
6729
  var DatePicker = ({
6693
6730
  id,
@@ -7086,7 +7123,7 @@ var DatePicker = ({
7086
7123
  )
7087
7124
  ] })
7088
7125
  ] });
7089
- const autoId = useId4();
7126
+ const autoId = useId6();
7090
7127
  const resolvedId = id ? String(id) : `datepicker-${autoId}`;
7091
7128
  const labelId = label ? `${resolvedId}-label` : void 0;
7092
7129
  const labelSize = sizeStyles8[size].label;
@@ -7773,10 +7810,8 @@ function WheelColumn({
7773
7810
  };
7774
7811
  const currentVirtual = React27.useMemo(() => {
7775
7812
  if (!loop || items.length <= 0) return valueIndex;
7776
- const fallback = baseOffset + valueIndex;
7777
- const from = lastVirtualIndexRef.current ?? fallback;
7778
- return getNearestVirtualIndex(valueIndex, from);
7779
- }, [baseOffset, getNearestVirtualIndex, items.length, loop, valueIndex]);
7813
+ return baseOffset + valueIndex;
7814
+ }, [baseOffset, items.length, loop, valueIndex]);
7780
7815
  const commitFromScrollTop = React27.useCallback(
7781
7816
  (behavior) => {
7782
7817
  const el = scrollRef.current;
@@ -9213,10 +9248,8 @@ function WheelColumn2({
9213
9248
  };
9214
9249
  const currentVirtual = React29.useMemo(() => {
9215
9250
  if (!loop || items.length <= 0) return valueIndex;
9216
- const fallback = baseOffset + valueIndex;
9217
- const from = lastVirtualIndexRef.current ?? fallback;
9218
- return getNearestVirtualIndex(valueIndex, from);
9219
- }, [baseOffset, getNearestVirtualIndex, items.length, loop, valueIndex]);
9251
+ return baseOffset + valueIndex;
9252
+ }, [baseOffset, items.length, loop, valueIndex]);
9220
9253
  const commitFromScrollTop = React29.useCallback(
9221
9254
  (behavior) => {
9222
9255
  const el = scrollRef.current;
@@ -13276,7 +13309,7 @@ function CalendarTimeline({
13276
13309
 
13277
13310
  // src/components/MultiCombobox.tsx
13278
13311
  import * as React37 from "react";
13279
- import { useId as useId5 } from "react";
13312
+ import { useId as useId7 } from "react";
13280
13313
  import { ChevronDown as ChevronDown4, Search as Search4, Check as Check6, SearchX as SearchX2, Loader2 as Loader24, X as X12, Sparkles as Sparkles3 } from "lucide-react";
13281
13314
  import { Fragment as Fragment13, jsx as jsx42, jsxs as jsxs34 } from "react/jsx-runtime";
13282
13315
  var MultiCombobox = ({
@@ -13405,7 +13438,7 @@ var MultiCombobox = ({
13405
13438
  outline: "border-2 border-input bg-transparent hover:border-primary",
13406
13439
  ghost: "border border-transparent bg-muted/50 hover:bg-muted"
13407
13440
  };
13408
- const autoId = useId5();
13441
+ const autoId = useId7();
13409
13442
  const resolvedId = id ? String(id) : `multicombobox-${autoId}`;
13410
13443
  const labelId = label ? `${resolvedId}-label` : void 0;
13411
13444
  const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
@@ -14033,6 +14066,36 @@ var SIZE_STYLES = {
14033
14066
  }
14034
14067
  };
14035
14068
  var clamp6 = (n, min, max) => Math.min(max, Math.max(min, n));
14069
+ function SliderTooltip({
14070
+ displayValue,
14071
+ position,
14072
+ visible,
14073
+ sizeClassName,
14074
+ tooltipClassName
14075
+ }) {
14076
+ return /* @__PURE__ */ jsxs36(
14077
+ "div",
14078
+ {
14079
+ className: cn(
14080
+ "absolute pointer-events-none transition-all duration-200 ease-out",
14081
+ "bg-popover text-popover-foreground rounded-lg shadow-lg border border-border/50",
14082
+ "whitespace-nowrap font-medium -translate-x-1/2 z-50",
14083
+ sizeClassName,
14084
+ visible ? "opacity-100 -translate-y-10 scale-100" : "opacity-0 -translate-y-8 scale-95",
14085
+ tooltipClassName
14086
+ ),
14087
+ style: {
14088
+ left: `${position}%`,
14089
+ bottom: "100%"
14090
+ },
14091
+ children: [
14092
+ displayValue,
14093
+ /* @__PURE__ */ jsx44("div", { className: "absolute left-1/2 -translate-x-1/2 top-full w-0 h-0 border-4 border-transparent border-t-border" }),
14094
+ /* @__PURE__ */ jsx44("div", { className: "absolute left-1/2 -translate-x-1/2 top-full w-0 h-0 border-[3px] border-transparent border-t-popover -mt-px" })
14095
+ ]
14096
+ }
14097
+ );
14098
+ }
14036
14099
  var Slider = React39.forwardRef(
14037
14100
  ({
14038
14101
  className,
@@ -14122,6 +14185,7 @@ var Slider = React39.forwardRef(
14122
14185
  const rangeStartPct = (normalizedRange[0] - min) / denom * 100;
14123
14186
  const rangeEndPct = (normalizedRange[1] - min) / denom * 100;
14124
14187
  const sizeStyles8 = SIZE_STYLES[size];
14188
+ const tooltipVisible = showTooltip && !disabled && (isHovering || isDragging);
14125
14189
  const displayValue = React39.useMemo(() => {
14126
14190
  if (isRange) {
14127
14191
  const a = formatValue ? formatValue(normalizedRange[0]) : normalizedRange[0].toString();
@@ -14195,32 +14259,6 @@ var Slider = React39.forwardRef(
14195
14259
  };
14196
14260
  if (orientation === "vertical") {
14197
14261
  }
14198
- const Tooltip2 = ({ value: value2, position }) => {
14199
- const shouldShow = showTooltip && !disabled && (isHovering || isDragging);
14200
- const displayVal = formatValue ? formatValue(value2) : value2.toString();
14201
- return /* @__PURE__ */ jsxs36(
14202
- "div",
14203
- {
14204
- className: cn(
14205
- "absolute pointer-events-none transition-all duration-200 ease-out",
14206
- "bg-popover text-popover-foreground rounded-lg shadow-lg border border-border/50",
14207
- "whitespace-nowrap font-medium -translate-x-1/2 z-50",
14208
- sizeStyles8.tooltip,
14209
- shouldShow ? "opacity-100 -translate-y-10 scale-100" : "opacity-0 -translate-y-8 scale-95",
14210
- tooltipClassName
14211
- ),
14212
- style: {
14213
- left: `${position}%`,
14214
- bottom: "100%"
14215
- },
14216
- children: [
14217
- displayVal,
14218
- /* @__PURE__ */ jsx44("div", { className: "absolute left-1/2 -translate-x-1/2 top-full w-0 h-0 border-4 border-transparent border-t-border" }),
14219
- /* @__PURE__ */ jsx44("div", { className: "absolute left-1/2 -translate-x-1/2 top-full w-0 h-0 border-[3px] border-transparent border-t-popover -mt-px" })
14220
- ]
14221
- }
14222
- );
14223
- };
14224
14262
  return /* @__PURE__ */ jsxs36("div", { className: cn("w-full space-y-2", containerClassName), children: [
14225
14263
  (label || showValue) && /* @__PURE__ */ jsxs36("div", { className: "flex items-center justify-between", children: [
14226
14264
  label && /* @__PURE__ */ jsx44("label", { className: cn("text-sm font-medium text-foreground", labelClassName), children: label }),
@@ -14253,10 +14291,37 @@ var Slider = React39.forwardRef(
14253
14291
  style: { width: `${percentage}%` }
14254
14292
  }
14255
14293
  ) }),
14256
- !isRange && /* @__PURE__ */ jsx44(Tooltip2, { value: currentValue, position: percentage }),
14294
+ !isRange && /* @__PURE__ */ jsx44(
14295
+ SliderTooltip,
14296
+ {
14297
+ displayValue: formatValue ? formatValue(currentValue) : currentValue.toString(),
14298
+ position: percentage,
14299
+ visible: tooltipVisible,
14300
+ sizeClassName: sizeStyles8.tooltip,
14301
+ tooltipClassName
14302
+ }
14303
+ ),
14257
14304
  isRange && /* @__PURE__ */ jsxs36(Fragment14, { children: [
14258
- /* @__PURE__ */ jsx44(Tooltip2, { value: normalizedRange[0], position: rangeStartPct }),
14259
- /* @__PURE__ */ jsx44(Tooltip2, { value: normalizedRange[1], position: rangeEndPct })
14305
+ /* @__PURE__ */ jsx44(
14306
+ SliderTooltip,
14307
+ {
14308
+ displayValue: formatValue ? formatValue(normalizedRange[0]) : normalizedRange[0].toString(),
14309
+ position: rangeStartPct,
14310
+ visible: tooltipVisible,
14311
+ sizeClassName: sizeStyles8.tooltip,
14312
+ tooltipClassName
14313
+ }
14314
+ ),
14315
+ /* @__PURE__ */ jsx44(
14316
+ SliderTooltip,
14317
+ {
14318
+ displayValue: formatValue ? formatValue(normalizedRange[1]) : normalizedRange[1].toString(),
14319
+ position: rangeEndPct,
14320
+ visible: tooltipVisible,
14321
+ sizeClassName: sizeStyles8.tooltip,
14322
+ tooltipClassName
14323
+ }
14324
+ )
14260
14325
  ] }),
14261
14326
  (() => {
14262
14327
  const baseInputClassName = cn(
@@ -14829,7 +14894,7 @@ function OverlayControls({
14829
14894
  }
14830
14895
 
14831
14896
  // src/components/CategoryTreeSelect.tsx
14832
- import { useEffect as useEffect23, useId as useId7, useMemo as useMemo17, useRef as useRef17, useState as useState29 } from "react";
14897
+ import { useEffect as useEffect23, useId as useId9, useMemo as useMemo17, useRef as useRef17, useState as useState29 } from "react";
14833
14898
  import { ChevronRight as ChevronRight6, ChevronDown as ChevronDown5, FolderTree, Layers, Search as Search5, SearchX as SearchX3, X as X13 } from "lucide-react";
14834
14899
  import { jsx as jsx46, jsxs as jsxs38 } from "react/jsx-runtime";
14835
14900
  var defaultLabels = {
@@ -14838,6 +14903,16 @@ var defaultLabels = {
14838
14903
  searchPlaceholder: "Search...",
14839
14904
  noResultsText: "No results found"
14840
14905
  };
14906
+ function getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline) {
14907
+ if (!(viewOnly || inline) || !defaultExpanded) return /* @__PURE__ */ new Set();
14908
+ const parentIds = /* @__PURE__ */ new Set();
14909
+ for (const category of categories) {
14910
+ if (typeof category.parent_id === "number") {
14911
+ parentIds.add(category.parent_id);
14912
+ }
14913
+ }
14914
+ return parentIds;
14915
+ }
14841
14916
  function CategoryTreeSelect(props) {
14842
14917
  const {
14843
14918
  id,
@@ -14863,12 +14938,12 @@ function CategoryTreeSelect(props) {
14863
14938
  singleSelect = false
14864
14939
  } = props;
14865
14940
  const [isOpen, setIsOpen] = useState29(false);
14866
- const [expandedNodes, setExpandedNodes] = useState29(/* @__PURE__ */ new Set());
14941
+ const [expandedNodes, setExpandedNodes] = useState29(() => getInitialExpandedNodes(categories, defaultExpanded, viewOnly, inline));
14867
14942
  const [query, setQuery] = useState29("");
14868
14943
  const searchInputRef = useRef17(null);
14869
14944
  const dropdownViewportRef = useRef17(null);
14870
14945
  useOverlayScrollbarTarget(dropdownViewportRef, { enabled: useOverlayScrollbar });
14871
- const autoId = useId7();
14946
+ const autoId = useId9();
14872
14947
  const resolvedId = id ? String(id) : `category-tree-select-${autoId}`;
14873
14948
  const labelId = label ? `${resolvedId}-label` : void 0;
14874
14949
  const helperId = helperText && !error ? `${resolvedId}-helper` : void 0;
@@ -14937,21 +15012,12 @@ function CategoryTreeSelect(props) {
14937
15012
  }
14938
15013
  return visible;
14939
15014
  }, [byId, categories, childrenMap, isSearchMode, normalizedQuery]);
14940
- useEffect23(() => {
14941
- if (!isOpen) setQuery("");
14942
- }, [isOpen]);
14943
15015
  useEffect23(() => {
14944
15016
  if (!isOpen) return;
14945
15017
  if (!isSearchEnabled) return;
14946
15018
  const t = setTimeout(() => searchInputRef.current?.focus(), 50);
14947
15019
  return () => clearTimeout(t);
14948
15020
  }, [isOpen, isSearchEnabled]);
14949
- useEffect23(() => {
14950
- if ((viewOnly || inline) && defaultExpanded) {
14951
- const allParentIds = categories.filter((c) => childrenMap.has(c.id)).map((c) => c.id);
14952
- setExpandedNodes(new Set(allParentIds));
14953
- }
14954
- }, [viewOnly, inline, defaultExpanded, categories, childrenMap]);
14955
15021
  const toggleExpand = (id2) => {
14956
15022
  if (isSearchMode) return;
14957
15023
  const newExpanded = new Set(expandedNodes);
@@ -14975,7 +15041,7 @@ function CategoryTreeSelect(props) {
14975
15041
  onChange(categoryId);
14976
15042
  }
14977
15043
  if (!inline) {
14978
- setIsOpen(false);
15044
+ handleOpenChange(false);
14979
15045
  }
14980
15046
  } else {
14981
15047
  const onChange = props.onChange;
@@ -15113,17 +15179,16 @@ function CategoryTreeSelect(props) {
15113
15179
  if (!isSearchMode) return parentCategories;
15114
15180
  return parentCategories.filter((c) => visibleIds?.has(c.id));
15115
15181
  }, [isSearchMode, parentCategories, visibleIds]);
15116
- const effectiveChildrenMap = useMemo17(() => {
15117
- if (!isSearchMode || !visibleIds) return childrenMap;
15118
- const next = /* @__PURE__ */ new Map();
15182
+ let effectiveChildrenMap = childrenMap;
15183
+ if (isSearchMode && visibleIds) {
15184
+ effectiveChildrenMap = /* @__PURE__ */ new Map();
15119
15185
  for (const [parentId, children] of childrenMap.entries()) {
15120
- next.set(
15186
+ effectiveChildrenMap.set(
15121
15187
  parentId,
15122
15188
  children.filter((child) => visibleIds.has(child.id))
15123
15189
  );
15124
15190
  }
15125
- return next;
15126
- }, [childrenMap, isSearchMode, visibleIds]);
15191
+ }
15127
15192
  const renderTreeContent = () => /* @__PURE__ */ jsx46("div", { className: "space-y-0.5 overflow-x-hidden", children: effectiveParentCategories.length === 0 ? /* @__PURE__ */ jsxs38("div", { className: "flex flex-col items-center justify-center py-8 text-center", children: [
15128
15193
  /* @__PURE__ */ jsx46("div", { className: "w-12 h-12 rounded-2xl bg-muted/50 flex items-center justify-center mb-3", children: isSearchMode ? /* @__PURE__ */ jsx46(SearchX3, { className: "w-6 h-6 text-muted-foreground/50" }) : /* @__PURE__ */ jsx46(Layers, { className: "w-6 h-6 text-muted-foreground/50" }) }),
15129
15194
  /* @__PURE__ */ jsx46("span", { className: "text-sm text-muted-foreground", children: isSearchMode ? mergedLabels.noResultsText : mergedLabels.emptyText })
@@ -15232,7 +15297,13 @@ function CategoryTreeSelect(props) {
15232
15297
  event.preventDefault();
15233
15298
  event.stopPropagation();
15234
15299
  clearSelection();
15235
- setIsOpen(false);
15300
+ handleOpenChange(false);
15301
+ };
15302
+ const handleOpenChange = (nextOpen) => {
15303
+ setIsOpen(nextOpen);
15304
+ if (!nextOpen) {
15305
+ setQuery("");
15306
+ }
15236
15307
  };
15237
15308
  let displayText;
15238
15309
  if (singleSelect) {
@@ -15265,7 +15336,7 @@ function CategoryTreeSelect(props) {
15265
15336
  Popover,
15266
15337
  {
15267
15338
  open: isOpen,
15268
- onOpenChange: setIsOpen,
15339
+ onOpenChange: handleOpenChange,
15269
15340
  disabled,
15270
15341
  placement: "bottom-start",
15271
15342
  matchTriggerWidth: true,
@@ -18310,7 +18381,7 @@ var MusicPlayer = ({
18310
18381
  var MusicPlayer_default = MusicPlayer;
18311
18382
 
18312
18383
  // src/components/Grid.tsx
18313
- import React49, { useId as useId8 } from "react";
18384
+ import React49, { useId as useId10 } from "react";
18314
18385
  import { Fragment as Fragment20, jsx as jsx56, jsxs as jsxs48 } from "react/jsx-runtime";
18315
18386
  var BP_MIN = {
18316
18387
  sm: 640,
@@ -18375,7 +18446,7 @@ var GridRoot = React49.forwardRef(
18375
18446
  children,
18376
18447
  ...rest
18377
18448
  }, ref) => {
18378
- const id = useId8().replace(/[:]/g, "");
18449
+ const id = useId10().replace(/[:]/g, "");
18379
18450
  const baseClass = `uv-grid-${id}`;
18380
18451
  const baseCols = toTemplateCols(columns, minColumnWidth);
18381
18452
  const baseRows = toTemplateRows(rows);
@@ -18498,13 +18569,9 @@ var Grid = Object.assign(GridRoot, { Item: GridItem });
18498
18569
  var Grid_default = Grid;
18499
18570
 
18500
18571
  // src/components/ClientOnly.tsx
18501
- import { useEffect as useEffect28, useState as useState38 } from "react";
18502
18572
  import { Fragment as Fragment21, jsx as jsx57 } from "react/jsx-runtime";
18503
18573
  function ClientOnly({ children, fallback = null }) {
18504
- const [hasMounted, setHasMounted] = useState38(false);
18505
- useEffect28(() => {
18506
- setHasMounted(true);
18507
- }, []);
18574
+ const hasMounted = useHydrated();
18508
18575
  if (!hasMounted) {
18509
18576
  return /* @__PURE__ */ jsx57(Fragment21, { children: fallback });
18510
18577
  }
@@ -18607,7 +18674,7 @@ var TABLE_CONTAINER_BASE_CLASS = [
18607
18674
  "bg-card text-card-foreground shadow-sm",
18608
18675
  "backdrop-blur-sm transition-all duration-300"
18609
18676
  ].join(" ");
18610
- function assignRef3(ref, value) {
18677
+ function assignRef(ref, value) {
18611
18678
  if (typeof ref === "function") {
18612
18679
  ref(value);
18613
18680
  return;
@@ -18624,7 +18691,7 @@ var TableContainer = React50.forwardRef(({ className, useOverlayScrollbar = fals
18624
18691
  {
18625
18692
  ref: (node) => {
18626
18693
  containerRef.current = node;
18627
- assignRef3(ref, node);
18694
+ assignRef(ref, node);
18628
18695
  },
18629
18696
  className: cn(TABLE_CONTAINER_BASE_CLASS, className),
18630
18697
  ...props
@@ -19376,39 +19443,40 @@ import React57 from "react";
19376
19443
 
19377
19444
  // src/components/DataTable/hooks/usePageSizeStorage.ts
19378
19445
  import React56 from "react";
19446
+ function readStoredPageSize(storageKey) {
19447
+ if (typeof window === "undefined" || !storageKey) return null;
19448
+ try {
19449
+ const saved = localStorage.getItem(`datatable_${storageKey}_pageSize`);
19450
+ if (!saved) return null;
19451
+ const parsed = parseInt(saved, 10);
19452
+ return !isNaN(parsed) && parsed > 0 ? parsed : null;
19453
+ } catch {
19454
+ return null;
19455
+ }
19456
+ }
19379
19457
  function usePageSizeStorage({ pageSize, storageKey }) {
19380
- const loadedFromStorage = React56.useRef(false);
19381
- const [curPageSize, setCurPageSize] = React56.useState(() => {
19382
- if (typeof window === "undefined" || !storageKey) return pageSize;
19383
- try {
19384
- const saved = localStorage.getItem(`datatable_${storageKey}_pageSize`);
19385
- if (saved) {
19386
- const parsed = parseInt(saved, 10);
19387
- if (!isNaN(parsed) && parsed > 0) {
19388
- loadedFromStorage.current = true;
19389
- return parsed;
19390
- }
19391
- }
19392
- } catch {
19393
- }
19394
- return pageSize;
19458
+ const storedPageSize = React56.useMemo(() => readStoredPageSize(storageKey), [storageKey]);
19459
+ const [overrideState, setOverrideState] = React56.useState({
19460
+ storageKey,
19461
+ pageSize: null
19395
19462
  });
19396
- const hasMounted = React56.useRef(false);
19397
- React56.useEffect(() => {
19398
- hasMounted.current = true;
19399
- }, []);
19400
- React56.useEffect(() => {
19401
- if (typeof window === "undefined" || !storageKey) return;
19402
- if (!hasMounted.current) return;
19403
- try {
19404
- localStorage.setItem(`datatable_${storageKey}_pageSize`, String(curPageSize));
19405
- } catch {
19406
- }
19407
- }, [curPageSize, storageKey]);
19408
- React56.useEffect(() => {
19409
- if (storageKey && loadedFromStorage.current) return;
19410
- setCurPageSize(pageSize);
19411
- }, [pageSize, storageKey]);
19463
+ const overridePageSize = overrideState.storageKey === storageKey ? overrideState.pageSize : null;
19464
+ const persistedPageSize = storageKey ? overridePageSize ?? storedPageSize : null;
19465
+ const loadedFromStorage = persistedPageSize != null;
19466
+ const curPageSize = storageKey ? persistedPageSize ?? pageSize : overridePageSize ?? pageSize;
19467
+ const setCurPageSize = React56.useCallback(
19468
+ (nextPageSize) => {
19469
+ const baseValue = storageKey ? persistedPageSize ?? pageSize : overridePageSize ?? pageSize;
19470
+ const resolved = typeof nextPageSize === "function" ? nextPageSize(baseValue) : nextPageSize;
19471
+ setOverrideState({ storageKey, pageSize: resolved });
19472
+ if (!storageKey || typeof window === "undefined") return;
19473
+ try {
19474
+ localStorage.setItem(`datatable_${storageKey}_pageSize`, String(resolved));
19475
+ } catch {
19476
+ }
19477
+ },
19478
+ [overridePageSize, pageSize, persistedPageSize, storageKey]
19479
+ );
19412
19480
  return { curPageSize, setCurPageSize, loadedFromStorage };
19413
19481
  }
19414
19482
 
@@ -20071,7 +20139,7 @@ function AccessDenied({
20071
20139
 
20072
20140
  // src/components/ThemeToggleHeadless.tsx
20073
20141
  import { Moon as Moon2, Sun as Sun2, Monitor } from "lucide-react";
20074
- import { useEffect as useEffect30, useRef as useRef22, useState as useState39 } from "react";
20142
+ import { useRef as useRef22, useState as useState38 } from "react";
20075
20143
  import { createPortal as createPortal6 } from "react-dom";
20076
20144
  import { Fragment as Fragment23, jsx as jsx68, jsxs as jsxs59 } from "react/jsx-runtime";
20077
20145
  function ThemeToggleHeadless({
@@ -20080,17 +20148,16 @@ function ThemeToggleHeadless({
20080
20148
  labels,
20081
20149
  className
20082
20150
  }) {
20083
- const [isOpen, setIsOpen] = useState39(false);
20084
- const [mounted, setMounted] = useState39(false);
20151
+ const [isOpen, setIsOpen] = useState38(false);
20152
+ const isHydrated = useHydrated();
20085
20153
  const triggerRef = useRef22(null);
20086
- const [dropdownPosition, setDropdownPosition] = useState39(null);
20087
- useEffect30(() => setMounted(true), []);
20154
+ const [dropdownPosition, setDropdownPosition] = useState38(null);
20088
20155
  const themes = [
20089
20156
  { value: "light", label: labels?.light ?? "Light", icon: Sun2 },
20090
20157
  { value: "dark", label: labels?.dark ?? "Dark", icon: Moon2 },
20091
20158
  { value: "system", label: labels?.system ?? "System", icon: Monitor }
20092
20159
  ];
20093
- const current = mounted ? themes.find((t) => t.value === theme) || themes[2] : themes[2];
20160
+ const current = isHydrated ? themes.find((t) => t.value === theme) || themes[2] : themes[2];
20094
20161
  const CurrentIcon = current.icon;
20095
20162
  const calculatePosition = () => {
20096
20163
  const rect = triggerRef.current?.getBoundingClientRect();
@@ -20173,7 +20240,7 @@ function ThemeToggleHeadless({
20173
20240
  }
20174
20241
 
20175
20242
  // src/components/LanguageSwitcherHeadless.tsx
20176
- import { useRef as useRef23, useState as useState40 } from "react";
20243
+ import { useRef as useRef23, useState as useState39 } from "react";
20177
20244
  import { createPortal as createPortal7 } from "react-dom";
20178
20245
  import { Globe } from "lucide-react";
20179
20246
  import { Fragment as Fragment24, jsx as jsx69, jsxs as jsxs60 } from "react/jsx-runtime";
@@ -20184,8 +20251,8 @@ function LanguageSwitcherHeadless({
20184
20251
  labels,
20185
20252
  className
20186
20253
  }) {
20187
- const [isOpen, setIsOpen] = useState40(false);
20188
- const [dropdownPosition, setDropdownPosition] = useState40(null);
20254
+ const [isOpen, setIsOpen] = useState39(false);
20255
+ const [dropdownPosition, setDropdownPosition] = useState39(null);
20189
20256
  const triggerButtonRef = useRef23(null);
20190
20257
  const currentLanguage = locales.find((l) => l.code === currentLocale) || locales[0];
20191
20258
  const calculatePosition = () => {
@@ -20724,7 +20791,7 @@ function useLocale() {
20724
20791
  }
20725
20792
 
20726
20793
  // src/components/UEditor/UEditor.tsx
20727
- import React71, { useEffect as useEffect37, useImperativeHandle as useImperativeHandle3, useMemo as useMemo22, useRef as useRef30 } from "react";
20794
+ import React71, { useEffect as useEffect34, useImperativeHandle as useImperativeHandle3, useMemo as useMemo22, useRef as useRef30 } from "react";
20728
20795
  import { useEditor, EditorContent } from "@tiptap/react";
20729
20796
 
20730
20797
  // src/components/UEditor/extensions.ts
@@ -20765,7 +20832,7 @@ import { common, createLowlight } from "lowlight";
20765
20832
  import { Extension } from "@tiptap/core";
20766
20833
  import Suggestion from "@tiptap/suggestion";
20767
20834
  import { ReactRenderer } from "@tiptap/react";
20768
- import { forwardRef as forwardRef13, useEffect as useEffect31, useImperativeHandle, useRef as useRef24, useState as useState41 } from "react";
20835
+ import React63, { forwardRef as forwardRef13, useEffect as useEffect29, useImperativeHandle, useRef as useRef24 } from "react";
20769
20836
  import {
20770
20837
  FileCode as FileCode2,
20771
20838
  Heading1,
@@ -20807,13 +20874,24 @@ var DEFAULT_MESSAGES = {
20807
20874
  table: "Table",
20808
20875
  tableDesc: "Insert a table"
20809
20876
  };
20877
+ function useResettingIndex2(resetToken) {
20878
+ const [state, setState] = React63.useState({ resetToken, index: 0 });
20879
+ const selectedIndex = Object.is(state.resetToken, resetToken) ? state.index : 0;
20880
+ const setSelectedIndex = React63.useCallback((nextIndex) => {
20881
+ setState((prev) => {
20882
+ const prevIndex = Object.is(prev.resetToken, resetToken) ? prev.index : 0;
20883
+ return {
20884
+ resetToken,
20885
+ index: typeof nextIndex === "function" ? nextIndex(prevIndex) : nextIndex
20886
+ };
20887
+ });
20888
+ }, [resetToken]);
20889
+ return [selectedIndex, setSelectedIndex];
20890
+ }
20810
20891
  var CommandList = forwardRef13((props, ref) => {
20811
- const [selectedIndex, setSelectedIndex] = useState41(0);
20892
+ const [selectedIndex, setSelectedIndex] = useResettingIndex2(props.items);
20812
20893
  const listRef = useRef24(null);
20813
- useEffect31(() => {
20814
- setSelectedIndex(0);
20815
- }, [props.items]);
20816
- useEffect31(() => {
20894
+ useEffect29(() => {
20817
20895
  const selectedElement = listRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
20818
20896
  selectedElement?.scrollIntoView({ block: "nearest" });
20819
20897
  }, [selectedIndex, props.items]);
@@ -21138,7 +21216,7 @@ import { Extension as Extension3 } from "@tiptap/core";
21138
21216
  import Suggestion2 from "@tiptap/suggestion";
21139
21217
  import { ReactRenderer as ReactRenderer2 } from "@tiptap/react";
21140
21218
  import { PluginKey } from "@tiptap/pm/state";
21141
- import { forwardRef as forwardRef14, useEffect as useEffect32, useImperativeHandle as useImperativeHandle2, useState as useState42 } from "react";
21219
+ import React64, { forwardRef as forwardRef14, useImperativeHandle as useImperativeHandle2 } from "react";
21142
21220
  import { Smile } from "lucide-react";
21143
21221
  import tippy2 from "tippy.js";
21144
21222
 
@@ -21909,11 +21987,22 @@ var EMOJI_LIST = [
21909
21987
 
21910
21988
  // src/components/UEditor/emoji-suggestion.tsx
21911
21989
  import { jsx as jsx72, jsxs as jsxs62 } from "react/jsx-runtime";
21990
+ function useResettingIndex3(resetToken) {
21991
+ const [state, setState] = React64.useState({ resetToken, index: 0 });
21992
+ const selectedIndex = Object.is(state.resetToken, resetToken) ? state.index : 0;
21993
+ const setSelectedIndex = React64.useCallback((nextIndex) => {
21994
+ setState((prev) => {
21995
+ const prevIndex = Object.is(prev.resetToken, resetToken) ? prev.index : 0;
21996
+ return {
21997
+ resetToken,
21998
+ index: typeof nextIndex === "function" ? nextIndex(prevIndex) : nextIndex
21999
+ };
22000
+ });
22001
+ }, [resetToken]);
22002
+ return [selectedIndex, setSelectedIndex];
22003
+ }
21912
22004
  var EmojiList = forwardRef14((props, ref) => {
21913
- const [selectedIndex, setSelectedIndex] = useState42(0);
21914
- useEffect32(() => {
21915
- setSelectedIndex(0);
21916
- }, [props.items]);
22005
+ const [selectedIndex, setSelectedIndex] = useResettingIndex3(props.items);
21917
22006
  useImperativeHandle2(ref, () => ({
21918
22007
  onKeyDown: ({ event }) => {
21919
22008
  if (event.key === "ArrowUp") {
@@ -22119,7 +22208,7 @@ var UEditorPlaceholder = Extension4.create({
22119
22208
  });
22120
22209
 
22121
22210
  // src/components/UEditor/resizable-image.tsx
22122
- import { useEffect as useEffect33, useRef as useRef25, useState as useState43 } from "react";
22211
+ import { useEffect as useEffect30, useRef as useRef25, useState as useState41 } from "react";
22123
22212
  import Image3 from "@tiptap/extension-image";
22124
22213
  import { mergeAttributes } from "@tiptap/core";
22125
22214
  import { NodeViewWrapper, ReactNodeViewRenderer } from "@tiptap/react";
@@ -22141,13 +22230,13 @@ function ResizableImageNodeView(props) {
22141
22230
  const { node, selected, updateAttributes, editor, getPos } = props;
22142
22231
  const wrapperRef = useRef25(null);
22143
22232
  const imgRef = useRef25(null);
22144
- const [isHovered, setIsHovered] = useState43(false);
22145
- const [isResizing, setIsResizing] = useState43(false);
22233
+ const [isHovered, setIsHovered] = useState41(false);
22234
+ const [isResizing, setIsResizing] = useState41(false);
22146
22235
  const widthAttr = toNullableNumber(node.attrs["width"]);
22147
22236
  const heightAttr = toNullableNumber(node.attrs["height"]);
22148
22237
  const textAlign = String(node.attrs["textAlign"] ?? "");
22149
22238
  const dragStateRef = useRef25(null);
22150
- useEffect33(() => {
22239
+ useEffect30(() => {
22151
22240
  const img = imgRef.current;
22152
22241
  if (!img) return;
22153
22242
  img.style.width = widthAttr ? `${widthAttr}px` : "";
@@ -22478,7 +22567,7 @@ function buildUEditorExtensions({
22478
22567
  }
22479
22568
 
22480
22569
  // src/components/UEditor/toolbar.tsx
22481
- import React69, { useRef as useRef28, useState as useState46 } from "react";
22570
+ import React69, { useRef as useRef28, useState as useState44 } from "react";
22482
22571
  import {
22483
22572
  AlignCenter,
22484
22573
  AlignJustify,
@@ -22579,7 +22668,7 @@ var EditorColorPalette = ({
22579
22668
  ] });
22580
22669
 
22581
22670
  // src/components/UEditor/inputs.tsx
22582
- import { useEffect as useEffect34, useRef as useRef26, useState as useState44 } from "react";
22671
+ import { useEffect as useEffect31, useRef as useRef26, useState as useState42 } from "react";
22583
22672
  import { Check as Check10, X as X18 } from "lucide-react";
22584
22673
  import { jsx as jsx75, jsxs as jsxs65 } from "react/jsx-runtime";
22585
22674
  function normalizeUrl(raw) {
@@ -22595,9 +22684,9 @@ var LinkInput = ({
22595
22684
  initialUrl = ""
22596
22685
  }) => {
22597
22686
  const t = useSmartTranslations("UEditor");
22598
- const [url, setUrl] = useState44(initialUrl);
22687
+ const [url, setUrl] = useState42(initialUrl);
22599
22688
  const inputRef = useRef26(null);
22600
- useEffect34(() => {
22689
+ useEffect31(() => {
22601
22690
  inputRef.current?.focus();
22602
22691
  inputRef.current?.select();
22603
22692
  }, []);
@@ -22624,10 +22713,10 @@ var LinkInput = ({
22624
22713
  };
22625
22714
  var ImageInput = ({ onSubmit, onCancel }) => {
22626
22715
  const t = useSmartTranslations("UEditor");
22627
- const [url, setUrl] = useState44("");
22628
- const [alt, setAlt] = useState44("");
22716
+ const [url, setUrl] = useState42("");
22717
+ const [alt, setAlt] = useState42("");
22629
22718
  const inputRef = useRef26(null);
22630
- useEffect34(() => {
22719
+ useEffect31(() => {
22631
22720
  inputRef.current?.focus();
22632
22721
  }, []);
22633
22722
  const handleSubmit = (e) => {
@@ -22680,7 +22769,7 @@ var ImageInput = ({ onSubmit, onCancel }) => {
22680
22769
  };
22681
22770
 
22682
22771
  // src/components/UEditor/emoji-picker.tsx
22683
- import { useState as useState45, useMemo as useMemo20, useRef as useRef27, useEffect as useEffect35 } from "react";
22772
+ import { useState as useState43, useMemo as useMemo20, useRef as useRef27, useEffect as useEffect32 } from "react";
22684
22773
  import { Search as Search6, X as X19, Smile as Smile2, Leaf, Utensils, Dumbbell, Lightbulb, Hash, Flag } from "lucide-react";
22685
22774
  import { jsx as jsx76, jsxs as jsxs66 } from "react/jsx-runtime";
22686
22775
  var CATEGORY_ICONS = {
@@ -22694,8 +22783,8 @@ var CATEGORY_ICONS = {
22694
22783
  };
22695
22784
  var EmojiPicker = ({ onSelect, onClose }) => {
22696
22785
  const t = useSmartTranslations("UEditor");
22697
- const [search, setSearch] = useState45("");
22698
- const [activeCategory, setActiveCategory] = useState45(EMOJI_LIST[0]?.id || "");
22786
+ const [search, setSearch] = useState43("");
22787
+ const [activeCategory, setActiveCategory] = useState43(EMOJI_LIST[0]?.id || "");
22699
22788
  const scrollContainerRef = useRef27(null);
22700
22789
  const categoryRefs = useRef27({});
22701
22790
  const isUserScrolling = useRef27(false);
@@ -22713,7 +22802,7 @@ var EmojiPicker = ({ onSelect, onClose }) => {
22713
22802
  onSelect(emoji);
22714
22803
  setSearch("");
22715
22804
  };
22716
- useEffect35(() => {
22805
+ useEffect32(() => {
22717
22806
  if (search) return;
22718
22807
  const container = scrollContainerRef.current;
22719
22808
  if (!container) return;
@@ -22753,7 +22842,7 @@ var EmojiPicker = ({ onSelect, onClose }) => {
22753
22842
  isUserScrolling.current = true;
22754
22843
  }, 500);
22755
22844
  };
22756
- useEffect35(() => {
22845
+ useEffect32(() => {
22757
22846
  isUserScrolling.current = true;
22758
22847
  }, []);
22759
22848
  return /* @__PURE__ */ jsxs66("div", { className: "w-96 bg-card border border-border/50 rounded-2xl shadow-xl overflow-hidden flex flex-col max-h-128", children: [
@@ -22910,10 +22999,10 @@ var EditorToolbar = ({
22910
22999
  }) => {
22911
23000
  const t = useSmartTranslations("UEditor");
22912
23001
  const { textColors, highlightColors } = useEditorColors();
22913
- const [showImageInput, setShowImageInput] = useState46(false);
23002
+ const [showImageInput, setShowImageInput] = useState44(false);
22914
23003
  const fileInputRef = useRef28(null);
22915
- const [isUploadingImage, setIsUploadingImage] = useState46(false);
22916
- const [imageUploadError, setImageUploadError] = useState46(null);
23004
+ const [isUploadingImage, setIsUploadingImage] = useState44(false);
23005
+ const [imageUploadError, setImageUploadError] = useState44(null);
22917
23006
  const insertImageFiles = async (files) => {
22918
23007
  if (files.length === 0) return;
22919
23008
  setIsUploadingImage(true);
@@ -23361,7 +23450,7 @@ var EditorToolbar = ({
23361
23450
  };
23362
23451
 
23363
23452
  // src/components/UEditor/menus.tsx
23364
- import { useCallback as useCallback17, useEffect as useEffect36, useMemo as useMemo21, useRef as useRef29, useState as useState47 } from "react";
23453
+ import React70, { useCallback as useCallback17, useEffect as useEffect33, useMemo as useMemo21, useRef as useRef29, useState as useState45 } from "react";
23365
23454
  import { createPortal as createPortal8 } from "react-dom";
23366
23455
  import {
23367
23456
  Bold as BoldIcon2,
@@ -23387,9 +23476,23 @@ import {
23387
23476
  Strikethrough as StrikethroughIcon2
23388
23477
  } from "lucide-react";
23389
23478
  import { jsx as jsx78, jsxs as jsxs68 } from "react/jsx-runtime";
23479
+ function useResettingIndex4(resetToken) {
23480
+ const [state, setState] = React70.useState({ resetToken, index: 0 });
23481
+ const selectedIndex = Object.is(state.resetToken, resetToken) ? state.index : 0;
23482
+ const setSelectedIndex = React70.useCallback((nextIndex) => {
23483
+ setState((prev) => {
23484
+ const prevIndex = Object.is(prev.resetToken, resetToken) ? prev.index : 0;
23485
+ return {
23486
+ resetToken,
23487
+ index: typeof nextIndex === "function" ? nextIndex(prevIndex) : nextIndex
23488
+ };
23489
+ });
23490
+ }, [resetToken]);
23491
+ return [selectedIndex, setSelectedIndex];
23492
+ }
23390
23493
  var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
23391
23494
  const t = useSmartTranslations("UEditor");
23392
- const [selectedIndex, setSelectedIndex] = useState47(0);
23495
+ const [selectedIndex, setSelectedIndex] = useResettingIndex4(filterText);
23393
23496
  const menuRef = useRef29(null);
23394
23497
  const allCommands = useMemo21(
23395
23498
  () => [
@@ -23467,13 +23570,10 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
23467
23570
  const lowerFilter = filterText.toLowerCase();
23468
23571
  return allCommands.filter((cmd) => cmd.label.toLowerCase().includes(lowerFilter) || cmd.description.toLowerCase().includes(lowerFilter));
23469
23572
  }, [allCommands, filterText]);
23470
- useEffect36(() => {
23471
- setSelectedIndex(0);
23472
- }, [filterText]);
23473
- useEffect36(() => {
23573
+ useEffect33(() => {
23474
23574
  const selectedElement = menuRef.current?.querySelector(`[data-index="${selectedIndex}"]`);
23475
23575
  selectedElement?.scrollIntoView({ block: "nearest" });
23476
- }, [selectedIndex]);
23576
+ }, [commands, selectedIndex, setSelectedIndex]);
23477
23577
  const selectCommand = useCallback17(
23478
23578
  (index) => {
23479
23579
  const command = commands[index];
@@ -23484,7 +23584,7 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
23484
23584
  },
23485
23585
  [commands, onClose]
23486
23586
  );
23487
- useEffect36(() => {
23587
+ useEffect33(() => {
23488
23588
  const handleKeyDown = (e) => {
23489
23589
  if (commands.length === 0) return;
23490
23590
  if (e.key === "ArrowDown") {
@@ -23503,7 +23603,7 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
23503
23603
  };
23504
23604
  document.addEventListener("keydown", handleKeyDown);
23505
23605
  return () => document.removeEventListener("keydown", handleKeyDown);
23506
- }, [commands, selectedIndex, selectCommand, onClose]);
23606
+ }, [commands, onClose, selectCommand, selectedIndex, setSelectedIndex]);
23507
23607
  if (commands.length === 0) {
23508
23608
  return /* @__PURE__ */ jsx78("div", { className: "w-72 p-4 text-center text-muted-foreground text-sm", children: t("slashCommand.noResults") });
23509
23609
  }
@@ -23544,7 +23644,7 @@ var SlashCommandMenu = ({ editor, onClose, filterText = "" }) => {
23544
23644
  };
23545
23645
  var FloatingMenuContent = ({ editor }) => {
23546
23646
  const t = useSmartTranslations("UEditor");
23547
- const [showCommands, setShowCommands] = useState47(false);
23647
+ const [showCommands, setShowCommands] = useState45(false);
23548
23648
  if (showCommands) {
23549
23649
  return /* @__PURE__ */ jsx78(SlashCommandMenu, { editor, onClose: () => setShowCommands(false) });
23550
23650
  }
@@ -23567,12 +23667,12 @@ var BubbleMenuContent = ({
23567
23667
  }) => {
23568
23668
  const t = useSmartTranslations("UEditor");
23569
23669
  const { textColors, highlightColors } = useEditorColors();
23570
- const [showLinkInput, setShowLinkInput] = useState47(false);
23571
- const [showEditorColorPalette, setShowEditorColorPalette] = useState47(false);
23572
- useEffect36(() => {
23670
+ const [showLinkInput, setShowLinkInput] = useState45(false);
23671
+ const [showEditorColorPalette, setShowEditorColorPalette] = useState45(false);
23672
+ useEffect33(() => {
23573
23673
  onKeepOpenChange?.(showLinkInput);
23574
23674
  }, [onKeepOpenChange, showLinkInput]);
23575
- useEffect36(() => {
23675
+ useEffect33(() => {
23576
23676
  if (!showLinkInput) return;
23577
23677
  const close = () => setShowLinkInput(false);
23578
23678
  editor.on("selectionUpdate", close);
@@ -23695,15 +23795,15 @@ var BubbleMenuContent = ({
23695
23795
  ] });
23696
23796
  };
23697
23797
  var CustomBubbleMenu = ({ editor }) => {
23698
- const [isVisible, setIsVisible] = useState47(false);
23699
- const [position, setPosition] = useState47({ top: 0, left: 0 });
23798
+ const [isVisible, setIsVisible] = useState45(false);
23799
+ const [position, setPosition] = useState45({ top: 0, left: 0 });
23700
23800
  const menuRef = useRef29(null);
23701
23801
  const keepOpenRef = useRef29(false);
23702
23802
  const setKeepOpen = useCallback17((next) => {
23703
23803
  keepOpenRef.current = next;
23704
23804
  if (next) setIsVisible(true);
23705
23805
  }, []);
23706
- useEffect36(() => {
23806
+ useEffect33(() => {
23707
23807
  const updatePosition = () => {
23708
23808
  const { state, view } = editor;
23709
23809
  const { from, to, empty } = state.selection;
@@ -23756,9 +23856,9 @@ var CustomBubbleMenu = ({ editor }) => {
23756
23856
  );
23757
23857
  };
23758
23858
  var CustomFloatingMenu = ({ editor }) => {
23759
- const [isVisible, setIsVisible] = useState47(false);
23760
- const [position, setPosition] = useState47({ top: 0, left: 0 });
23761
- useEffect36(() => {
23859
+ const [isVisible, setIsVisible] = useState45(false);
23860
+ const [position, setPosition] = useState45({ top: 0, left: 0 });
23861
+ useEffect33(() => {
23762
23862
  const updatePosition = () => {
23763
23863
  const { state, view } = editor;
23764
23864
  const { $from, empty } = state.selection;
@@ -24241,7 +24341,7 @@ var UEditor = React71.forwardRef(({
24241
24341
  }),
24242
24342
  [content, editor, uploadImageForSave]
24243
24343
  );
24244
- useEffect37(() => {
24344
+ useEffect34(() => {
24245
24345
  if (editor && content !== editor.getHTML()) {
24246
24346
  if (editor.isEmpty && content) {
24247
24347
  editor.commands.setContent(content);