@underverse-ui/underverse 0.2.113 → 0.2.114

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
  );