@underverse-ui/underverse 0.2.113 → 0.2.115

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
@@ -11642,17 +11642,20 @@ var SIZE_STYLES = {
11642
11642
  sm: {
11643
11643
  track: "h-1",
11644
11644
  thumb: "w-3 h-3",
11645
- container: "py-1"
11645
+ container: "py-1",
11646
+ tooltip: "text-xs px-2 py-1"
11646
11647
  },
11647
11648
  md: {
11648
11649
  track: "h-2",
11649
11650
  thumb: "w-4 h-4",
11650
- container: "py-2"
11651
+ container: "py-2",
11652
+ tooltip: "text-sm px-2.5 py-1.5"
11651
11653
  },
11652
11654
  lg: {
11653
11655
  track: "h-3",
11654
11656
  thumb: "w-5 h-5",
11655
- container: "py-3"
11657
+ container: "py-3",
11658
+ tooltip: "text-sm px-3 py-2"
11656
11659
  }
11657
11660
  };
11658
11661
  var clamp5 = (n, min, max) => Math.min(max, Math.max(min, n));
@@ -11685,6 +11688,9 @@ var Slider = React35.forwardRef(
11685
11688
  disabled = false,
11686
11689
  orientation = "horizontal",
11687
11690
  noFocus = true,
11691
+ showTooltip = true,
11692
+ tooltipClassName,
11693
+ useGradient = true,
11688
11694
  ...props
11689
11695
  }, ref) => {
11690
11696
  const isRange = mode === "range";
@@ -11697,6 +11703,8 @@ var Slider = React35.forwardRef(
11697
11703
  });
11698
11704
  const [activeThumb, setActiveThumb] = React35.useState(null);
11699
11705
  const dragRef = React35.useRef(null);
11706
+ const [isHovering, setIsHovering] = React35.useState(false);
11707
+ const [isDragging, setIsDragging] = React35.useState(false);
11700
11708
  const isControlled = value !== void 0;
11701
11709
  const currentValue = isControlled ? value : internalValue;
11702
11710
  const isRangeControlled = rangeValue !== void 0;
@@ -11775,6 +11783,7 @@ var Slider = React35.forwardRef(
11775
11783
  const distToMax = Math.abs(nextValue - curMax);
11776
11784
  const thumb = distToMin <= distToMax ? "min" : "max";
11777
11785
  setActiveThumb(thumb);
11786
+ setIsDragging(true);
11778
11787
  dragRef.current = { pointerId: e.pointerId, thumb };
11779
11788
  try {
11780
11789
  e.currentTarget.setPointerCapture(e.pointerId);
@@ -11799,6 +11808,7 @@ var Slider = React35.forwardRef(
11799
11808
  if (!drag) return;
11800
11809
  if (e.pointerId !== drag.pointerId) return;
11801
11810
  dragRef.current = null;
11811
+ setIsDragging(false);
11802
11812
  onMouseUp?.();
11803
11813
  onTouchEnd?.();
11804
11814
  try {
@@ -11808,135 +11818,198 @@ var Slider = React35.forwardRef(
11808
11818
  };
11809
11819
  if (orientation === "vertical") {
11810
11820
  }
11821
+ const Tooltip2 = ({ value: value2, position }) => {
11822
+ const shouldShow = showTooltip && !disabled && (isHovering || isDragging);
11823
+ const displayVal = formatValue ? formatValue(value2) : value2.toString();
11824
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
11825
+ "div",
11826
+ {
11827
+ className: cn(
11828
+ "absolute pointer-events-none transition-all duration-200 ease-out",
11829
+ "bg-popover text-popover-foreground rounded-lg shadow-lg border border-border",
11830
+ "whitespace-nowrap font-medium -translate-x-1/2 z-50",
11831
+ sizeStyles8.tooltip,
11832
+ shouldShow ? "opacity-100 -translate-y-10 scale-100" : "opacity-0 -translate-y-8 scale-95",
11833
+ tooltipClassName
11834
+ ),
11835
+ style: {
11836
+ left: `${position}%`,
11837
+ bottom: "100%"
11838
+ },
11839
+ children: [
11840
+ displayVal,
11841
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute left-1/2 -translate-x-1/2 top-full w-0 h-0 border-4 border-transparent border-t-border" }),
11842
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("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" })
11843
+ ]
11844
+ }
11845
+ );
11846
+ };
11811
11847
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("w-full space-y-2", containerClassName), children: [
11812
11848
  (label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex items-center justify-between", children: [
11813
11849
  label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { className: cn("text-sm font-medium text-foreground", labelClassName), children: label }),
11814
11850
  showValue && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: cn("text-xs font-mono text-muted-foreground min-w-8 text-right", valueClassName), children: displayValue })
11815
11851
  ] }),
11816
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { ref: trackRef, className: cn("relative flex items-center", sizeStyles8.container), children: [
11817
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("w-full rounded-full bg-secondary relative overflow-hidden", sizeStyles8.track, trackClassName), children: isRange ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11818
- "div",
11819
- {
11820
- className: "absolute top-0 h-full bg-primary rounded-full",
11821
- style: { left: `${rangeStartPct}%`, width: `${Math.max(0, rangeEndPct - rangeStartPct)}%` }
11822
- }
11823
- ) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute left-0 top-0 h-full bg-primary rounded-full", style: { width: `${percentage}%` } }) }),
11824
- (() => {
11825
- const baseInputClassName = cn(
11826
- // Base styles
11827
- "absolute w-full h-full appearance-none bg-transparent cursor-pointer",
11828
- !noFocus && "focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background rounded-full",
11829
- noFocus && "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none",
11830
- // Webkit styles for thumb
11831
- "[&::-webkit-slider-thumb]:appearance-none",
11832
- "[&::-webkit-slider-thumb]:bg-primary",
11833
- "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background",
11834
- "[&::-webkit-slider-thumb]:rounded-full",
11835
- "[&::-webkit-slider-thumb]:shadow-md",
11836
- "[&::-webkit-slider-thumb]:cursor-pointer",
11837
- "[&::-webkit-slider-thumb]:transition-all [&::-webkit-slider-thumb]:duration-150",
11838
- size === "sm" && "[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3",
11839
- size === "md" && "[&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
11840
- size === "lg" && "[&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5",
11841
- // Firefox styles for thumb
11842
- "[&::-moz-range-thumb]:bg-primary",
11843
- "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background",
11844
- "[&::-moz-range-thumb]:rounded-full",
11845
- "[&::-moz-range-thumb]:shadow-md",
11846
- "[&::-moz-range-thumb]:cursor-pointer",
11847
- "[&::-moz-range-thumb]:transition-all [&::-moz-range-thumb]:duration-150",
11848
- size === "sm" && "[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3",
11849
- size === "md" && "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4",
11850
- size === "lg" && "[&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5",
11851
- // Remove default track in Firefox
11852
- "[&::-moz-range-track]:bg-transparent",
11853
- "[&::-moz-range-track]:border-transparent",
11854
- // Hover effects
11855
- "hover:[&::-webkit-slider-thumb]:scale-110 hover:[&::-webkit-slider-thumb]:shadow-lg",
11856
- "hover:[&::-moz-range-thumb]:scale-110 hover:[&::-moz-range-thumb]:shadow-lg",
11857
- // Disabled styles
11858
- disabled && [
11859
- "cursor-not-allowed opacity-50",
11860
- "[&::-webkit-slider-thumb]:cursor-not-allowed [&::-webkit-slider-thumb]:opacity-50",
11861
- "[&::-moz-range-thumb]:cursor-not-allowed [&::-moz-range-thumb]:opacity-50"
11862
- ],
11863
- className,
11864
- thumbClassName
11865
- );
11866
- if (!isRange) {
11867
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11868
- "input",
11869
- {
11870
- ref,
11871
- type: "range",
11872
- min,
11873
- max,
11874
- step,
11875
- value: currentValue,
11876
- onChange: handleSingleChange,
11877
- onMouseUp,
11878
- onTouchEnd,
11879
- disabled,
11880
- className: baseInputClassName,
11881
- ...props
11882
- }
11883
- );
11884
- }
11885
- const minZ = activeThumb === "min" ? "z-20" : "z-10";
11886
- const maxZ = activeThumb === "max" ? "z-20" : "z-10";
11887
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
11888
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11852
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
11853
+ "div",
11854
+ {
11855
+ ref: trackRef,
11856
+ className: cn("relative flex items-center", sizeStyles8.container),
11857
+ onMouseEnter: () => setIsHovering(true),
11858
+ onMouseLeave: () => setIsHovering(false),
11859
+ children: [
11860
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("w-full rounded-full bg-secondary relative overflow-hidden shadow-inner", sizeStyles8.track, trackClassName), children: isRange ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11889
11861
  "div",
11890
11862
  {
11891
- className: cn("absolute inset-0 z-30", disabled ? "cursor-not-allowed" : "cursor-pointer"),
11892
- onPointerDown: startRangeDrag,
11893
- onPointerMove: moveRangeDrag,
11894
- onPointerUp: endRangeDrag,
11895
- onPointerCancel: endRangeDrag
11863
+ className: cn(
11864
+ "absolute top-0 h-full rounded-full transition-all duration-150",
11865
+ useGradient ? "bg-linear-to-r from-primary via-primary to-primary/80 shadow-[0_0_8px_rgba(var(--primary-rgb,147,51,234),0.3)]" : "bg-primary"
11866
+ ),
11867
+ style: { left: `${rangeStartPct}%`, width: `${Math.max(0, rangeEndPct - rangeStartPct)}%` }
11896
11868
  }
11897
- ),
11898
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11899
- "input",
11869
+ ) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11870
+ "div",
11900
11871
  {
11901
- ref,
11902
- type: "range",
11903
- min,
11904
- max,
11905
- step,
11906
- value: normalizedRange[0],
11907
- onChange: handleRangeChange("min"),
11908
- onMouseUp,
11909
- onTouchEnd,
11910
- disabled,
11911
- "aria-label": "Minimum value",
11912
- onPointerDown: () => setActiveThumb("min"),
11913
- onFocus: () => setActiveThumb("min"),
11914
- className: cn(baseInputClassName, minZ, "pointer-events-none"),
11915
- ...props
11872
+ className: cn(
11873
+ "absolute left-0 top-0 h-full rounded-full transition-all duration-150",
11874
+ useGradient ? "bg-linear-to-r from-primary via-primary to-primary/80 shadow-[0_0_8px_rgba(var(--primary-rgb,147,51,234),0.3)]" : "bg-primary"
11875
+ ),
11876
+ style: { width: `${percentage}%` }
11916
11877
  }
11917
- ),
11918
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11919
- "input",
11920
- {
11921
- type: "range",
11922
- min,
11923
- max,
11924
- step,
11925
- value: normalizedRange[1],
11926
- onChange: handleRangeChange("max"),
11927
- onMouseUp,
11928
- onTouchEnd,
11929
- disabled,
11930
- "aria-label": "Maximum value",
11931
- onPointerDown: () => setActiveThumb("max"),
11932
- onFocus: () => setActiveThumb("max"),
11933
- className: cn(baseInputClassName, maxZ, "pointer-events-none"),
11934
- ...props
11878
+ ) }),
11879
+ !isRange && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Tooltip2, { value: currentValue, position: percentage }),
11880
+ isRange && /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
11881
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Tooltip2, { value: normalizedRange[0], position: rangeStartPct }),
11882
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Tooltip2, { value: normalizedRange[1], position: rangeEndPct })
11883
+ ] }),
11884
+ (() => {
11885
+ const baseInputClassName = cn(
11886
+ // Base styles
11887
+ "absolute w-full h-full appearance-none bg-transparent cursor-pointer",
11888
+ !noFocus && "focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background rounded-full",
11889
+ noFocus && "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none",
11890
+ // Webkit styles for thumb
11891
+ "[&::-webkit-slider-thumb]:appearance-none",
11892
+ "[&::-webkit-slider-thumb]:bg-linear-to-br [&::-webkit-slider-thumb]:from-primary [&::-webkit-slider-thumb]:to-primary/80",
11893
+ "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background",
11894
+ "[&::-webkit-slider-thumb]:rounded-full",
11895
+ "[&::-webkit-slider-thumb]:shadow-[0_2px_8px_rgba(0,0,0,0.15),0_0_0_1px_rgba(0,0,0,0.05)]",
11896
+ "[&::-webkit-slider-thumb]:cursor-pointer",
11897
+ "[&::-webkit-slider-thumb]:transition-all [&::-webkit-slider-thumb]:duration-200 [&::-webkit-slider-thumb]:ease-out",
11898
+ size === "sm" && "[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3",
11899
+ size === "md" && "[&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
11900
+ size === "lg" && "[&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5",
11901
+ // Firefox styles for thumb
11902
+ "[&::-moz-range-thumb]:bg-linear-to-br [&::-moz-range-thumb]:from-primary [&::-moz-range-thumb]:to-primary/80",
11903
+ "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background",
11904
+ "[&::-moz-range-thumb]:rounded-full",
11905
+ "[&::-moz-range-thumb]:shadow-[0_2px_8px_rgba(0,0,0,0.15),0_0_0_1px_rgba(0,0,0,0.05)]",
11906
+ "[&::-moz-range-thumb]:cursor-pointer",
11907
+ "[&::-moz-range-thumb]:transition-all [&::-moz-range-thumb]:duration-200 [&::-moz-range-thumb]:ease-out",
11908
+ size === "sm" && "[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3",
11909
+ size === "md" && "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4",
11910
+ size === "lg" && "[&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5",
11911
+ // Remove default track in Firefox
11912
+ "[&::-moz-range-track]:bg-transparent",
11913
+ "[&::-moz-range-track]:border-transparent",
11914
+ // Hover effects - Enhanced premium look
11915
+ "hover:[&::-webkit-slider-thumb]:scale-110 hover:[&::-webkit-slider-thumb]:shadow-[0_4px_16px_rgba(0,0,0,0.2),0_0_12px_rgba(var(--primary-rgb,147,51,234),0.4)]",
11916
+ "hover:[&::-moz-range-thumb]:scale-110 hover:[&::-moz-range-thumb]:shadow-[0_4px_16px_rgba(0,0,0,0.2),0_0_12px_rgba(var(--primary-rgb,147,51,234),0.4)]",
11917
+ // Active/dragging effects
11918
+ "active:[&::-webkit-slider-thumb]:scale-105 active:[&::-webkit-slider-thumb]:shadow-[0_2px_12px_rgba(0,0,0,0.25),0_0_16px_rgba(var(--primary-rgb,147,51,234),0.5)]",
11919
+ "active:[&::-moz-range-thumb]:scale-105 active:[&::-moz-range-thumb]:shadow-[0_2px_12px_rgba(0,0,0,0.25),0_0_16px_rgba(var(--primary-rgb,147,51,234),0.5)]",
11920
+ // Disabled styles
11921
+ disabled && [
11922
+ "cursor-not-allowed opacity-50",
11923
+ "[&::-webkit-slider-thumb]:cursor-not-allowed [&::-webkit-slider-thumb]:opacity-50 [&::-webkit-slider-thumb]:shadow-none",
11924
+ "[&::-moz-range-thumb]:cursor-not-allowed [&::-moz-range-thumb]:opacity-50 [&::-moz-range-thumb]:shadow-none"
11925
+ ],
11926
+ className,
11927
+ thumbClassName
11928
+ );
11929
+ if (!isRange) {
11930
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11931
+ "input",
11932
+ {
11933
+ ref,
11934
+ type: "range",
11935
+ min,
11936
+ max,
11937
+ step,
11938
+ value: currentValue,
11939
+ onChange: handleSingleChange,
11940
+ onMouseDown: () => setIsDragging(true),
11941
+ onMouseUp: () => {
11942
+ setIsDragging(false);
11943
+ onMouseUp?.();
11944
+ },
11945
+ onTouchStart: () => setIsDragging(true),
11946
+ onTouchEnd: () => {
11947
+ setIsDragging(false);
11948
+ onTouchEnd?.();
11949
+ },
11950
+ disabled,
11951
+ className: baseInputClassName,
11952
+ ...props
11953
+ }
11954
+ );
11935
11955
  }
11936
- )
11937
- ] });
11938
- })()
11939
- ] })
11956
+ const minZ = activeThumb === "min" ? "z-20" : "z-10";
11957
+ const maxZ = activeThumb === "max" ? "z-20" : "z-10";
11958
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
11959
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11960
+ "div",
11961
+ {
11962
+ className: cn("absolute inset-0 z-30", disabled ? "cursor-not-allowed" : "cursor-pointer"),
11963
+ onPointerDown: startRangeDrag,
11964
+ onPointerMove: moveRangeDrag,
11965
+ onPointerUp: endRangeDrag,
11966
+ onPointerCancel: endRangeDrag
11967
+ }
11968
+ ),
11969
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11970
+ "input",
11971
+ {
11972
+ ref,
11973
+ type: "range",
11974
+ min,
11975
+ max,
11976
+ step,
11977
+ value: normalizedRange[0],
11978
+ onChange: handleRangeChange("min"),
11979
+ onMouseUp,
11980
+ onTouchEnd,
11981
+ disabled,
11982
+ "aria-label": "Minimum value",
11983
+ onPointerDown: () => setActiveThumb("min"),
11984
+ onFocus: () => setActiveThumb("min"),
11985
+ className: cn(baseInputClassName, minZ, "pointer-events-none"),
11986
+ ...props
11987
+ }
11988
+ ),
11989
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11990
+ "input",
11991
+ {
11992
+ type: "range",
11993
+ min,
11994
+ max,
11995
+ step,
11996
+ value: normalizedRange[1],
11997
+ onChange: handleRangeChange("max"),
11998
+ onMouseUp,
11999
+ onTouchEnd,
12000
+ disabled,
12001
+ "aria-label": "Maximum value",
12002
+ onPointerDown: () => setActiveThumb("max"),
12003
+ onFocus: () => setActiveThumb("max"),
12004
+ className: cn(baseInputClassName, maxZ, "pointer-events-none"),
12005
+ ...props
12006
+ }
12007
+ )
12008
+ ] });
12009
+ })()
12010
+ ]
12011
+ }
12012
+ )
11940
12013
  ] });
11941
12014
  }
11942
12015
  );
@@ -12466,8 +12539,9 @@ function CategoryTreeSelect(props) {
12466
12539
  /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
12467
12540
  "div",
12468
12541
  {
12542
+ onClick: () => !viewOnly && handleSelect(category.id, category),
12469
12543
  className: cn(
12470
- "relative flex items-center gap-2.5 px-3 py-2.5 transition-all duration-200 rounded-lg",
12544
+ "relative flex items-center gap-2.5 px-3 py-2.5 min-h-11 transition-all duration-200 rounded-lg",
12471
12545
  // Không phân biệt parent/child - đồng bộ màu
12472
12546
  !viewOnly && "cursor-pointer",
12473
12547
  !viewOnly && !isSelected && "hover:bg-accent/50",
@@ -12486,9 +12560,9 @@ function CategoryTreeSelect(props) {
12486
12560
  },
12487
12561
  className: cn(
12488
12562
  "p-1.5 rounded-lg transition-all duration-200",
12489
- "hover:bg-accent hover:scale-110 active:scale-95",
12563
+ "hover:scale-110 active:scale-95",
12490
12564
  "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50",
12491
- isExpanded && "bg-accent/50 text-primary"
12565
+ isExpanded && "text-primary"
12492
12566
  ),
12493
12567
  children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: cn("transition-transform duration-200", isExpanded && "rotate-90"), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.ChevronRight, { className: "w-4 h-4" }) })
12494
12568
  }
@@ -12496,57 +12570,14 @@ function CategoryTreeSelect(props) {
12496
12570
  viewOnly ? (
12497
12571
  // View-only mode: just display the name with folder icon
12498
12572
  /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-2.5", children: [
12499
- hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.FolderTree, { className: "w-4 h-4 text-muted-foreground/60" }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "w-1.5 h-1.5 rounded-full bg-muted-foreground/40" }),
12573
+ category.icon ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "w-4 h-4 flex items-center justify-center text-muted-foreground/60", children: category.icon }) : hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.FolderTree, { className: "w-4 h-4 text-muted-foreground/60" }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "w-1.5 h-1.5 rounded-full bg-muted-foreground/40" }),
12500
12574
  /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "text-sm font-medium", children: category.name })
12501
12575
  ] })
12502
- ) : singleSelect ? (
12503
- // Single select mode: radio-style indicator
12504
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { onClick: () => handleSelect(category.id, category), className: "flex items-center gap-2.5 flex-1", children: [
12505
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
12506
- "div",
12507
- {
12508
- className: cn(
12509
- "w-5 h-5 border-2 rounded-full flex items-center justify-center transition-all duration-200",
12510
- isSelected ? "border-primary bg-primary/10 shadow-sm shadow-primary/20" : "border-muted-foreground/30 hover:border-primary/50"
12511
- ),
12512
- children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "w-2.5 h-2.5 rounded-full bg-linear-to-br from-primary to-primary/80 shadow-sm" })
12513
- }
12514
- ),
12515
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
12516
- "span",
12517
- {
12518
- className: cn(
12519
- "text-sm transition-all duration-200",
12520
- isSelected ? "font-semibold text-primary" : "text-foreground/80 hover:text-foreground"
12521
- ),
12522
- children: category.name
12523
- }
12524
- ),
12525
- hasChildren && !isSelected && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "ml-auto text-[10px] font-medium text-muted-foreground/50 bg-muted/50 px-1.5 py-0.5 rounded-md", children: children.length })
12526
- ] })
12527
12576
  ) : (
12528
- // Multi select mode: checkbox-style indicator
12529
- /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { onClick: () => handleSelect(category.id, category), className: "flex items-center gap-2.5 flex-1", children: [
12530
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
12531
- "div",
12532
- {
12533
- className: cn(
12534
- "w-5 h-5 border-2 rounded-lg flex items-center justify-center transition-all duration-200",
12535
- isSelected ? "bg-linear-to-br from-primary to-primary/80 border-primary shadow-sm shadow-primary/25" : "border-muted-foreground/30 hover:border-primary/50 hover:bg-primary/5"
12536
- ),
12537
- children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react24.Check, { className: "w-3 h-3 text-primary-foreground", strokeWidth: 3 })
12538
- }
12539
- ),
12540
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
12541
- "span",
12542
- {
12543
- className: cn(
12544
- "text-sm transition-all duration-200",
12545
- isSelected ? "font-semibold text-primary" : "text-foreground/80 hover:text-foreground"
12546
- ),
12547
- children: category.name
12548
- }
12549
- ),
12577
+ // Single/Multi select mode: icon + text + badge
12578
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "flex items-center gap-2.5 flex-1", children: [
12579
+ category.icon && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "w-4 h-4 flex items-center justify-center text-current", children: category.icon }),
12580
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: cn("text-sm transition-all duration-200", isSelected ? "font-semibold text-primary" : "text-foreground/80"), children: category.name }),
12550
12581
  hasChildren && !isSelected && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "ml-auto text-[10px] font-medium text-muted-foreground/50 bg-muted/50 px-1.5 py-0.5 rounded-md", children: children.length })
12551
12582
  ] })
12552
12583
  )
@@ -12577,7 +12608,19 @@ function CategoryTreeSelect(props) {
12577
12608
  );
12578
12609
  }
12579
12610
  const selectedCount = valueArray.length;
12580
- const displayText = singleSelect ? selectedCount > 0 ? categories.find((c) => c.id === valueArray[0])?.name || placeholder : placeholder : selectedCount > 0 ? mergedLabels.selectedText(selectedCount) : placeholder;
12611
+ let displayText;
12612
+ if (singleSelect) {
12613
+ displayText = selectedCount > 0 ? categories.find((c) => c.id === valueArray[0])?.name || placeholder : placeholder;
12614
+ } else {
12615
+ if (selectedCount === 0) {
12616
+ displayText = placeholder;
12617
+ } else if (selectedCount <= 3) {
12618
+ const selectedNames = valueArray.map((id) => categories.find((c) => c.id === id)?.name).filter(Boolean).join(", ");
12619
+ displayText = selectedNames || placeholder;
12620
+ } else {
12621
+ displayText = mergedLabels.selectedText(selectedCount);
12622
+ }
12623
+ }
12581
12624
  return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: cn("relative", className), children: [
12582
12625
  /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
12583
12626
  "button",
@@ -12622,7 +12665,7 @@ function CategoryTreeSelect(props) {
12622
12665
  {
12623
12666
  className: cn(
12624
12667
  "absolute z-20 mt-2 w-full max-h-80 overflow-auto",
12625
- "rounded-2xl md:rounded-3xl overflow-hidden border border-border/40 bg-popover/95 text-popover-foreground",
12668
+ "rounded-2xl md:rounded-3xl border border-border/40 bg-popover/95 text-popover-foreground",
12626
12669
  "shadow-2xl backdrop-blur-xl",
12627
12670
  "p-2",
12628
12671
  "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-300"