@underverse-ui/underverse 0.2.107 → 0.2.109

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
@@ -3970,7 +3970,7 @@ var Popover = ({
3970
3970
  "div",
3971
3971
  {
3972
3972
  className: cn(
3973
- "rounded-2xl border bg-popover text-popover-foreground shadow-md",
3973
+ "rounded-2xl md:rounded-3xl border bg-popover text-popover-foreground shadow-md",
3974
3974
  "backdrop-blur-sm bg-popover/95 border-border/60 p-4",
3975
3975
  contentClassName
3976
3976
  ),
@@ -5105,98 +5105,108 @@ var Combobox = ({
5105
5105
  `${itemValue}-${index}`
5106
5106
  );
5107
5107
  };
5108
- const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { "data-combobox-dropdown": true, "data-state": open ? "open" : "closed", role: "listbox", id: `${resolvedId}-listbox`, className: "w-full", children: [
5109
- enableSearch && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "relative p-2.5 border-b border-border/30", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", children: [
5110
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground/60 transition-colors peer-focus:text-primary" }),
5111
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5112
- "input",
5113
- {
5114
- ref: inputRef,
5115
- value: query,
5116
- onChange: (e) => {
5117
- setQuery(e.target.value);
5118
- setActiveIndex(null);
5119
- },
5120
- onKeyDown: (e) => {
5121
- if (e.key === "ArrowDown") {
5122
- e.preventDefault();
5123
- setActiveIndex((prev) => {
5124
- const next = prev === null ? 0 : prev + 1;
5125
- return next >= filteredOptions.length ? 0 : next;
5126
- });
5127
- } else if (e.key === "ArrowUp") {
5128
- e.preventDefault();
5129
- setActiveIndex((prev) => {
5130
- const next = prev === null ? filteredOptions.length - 1 : prev - 1;
5131
- return next < 0 ? filteredOptions.length - 1 : next;
5132
- });
5133
- } else if (e.key === "Enter") {
5134
- e.preventDefault();
5135
- if (activeIndex !== null && filteredOptions[activeIndex] && !getOptionDisabled(filteredOptions[activeIndex])) {
5136
- handleSelect(filteredOptions[activeIndex]);
5137
- }
5138
- } else if (e.key === "Escape") {
5139
- e.preventDefault();
5140
- setOpen(false);
5108
+ const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5109
+ "div",
5110
+ {
5111
+ "data-combobox-dropdown": true,
5112
+ "data-state": open ? "open" : "closed",
5113
+ role: "listbox",
5114
+ id: `${resolvedId}-listbox`,
5115
+ className: "w-full rounded-2xl md:rounded-3xl overflow-hidden",
5116
+ children: [
5117
+ enableSearch && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "relative p-2.5 border-b border-border/30", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", children: [
5118
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground/60 transition-colors peer-focus:text-primary" }),
5119
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5120
+ "input",
5121
+ {
5122
+ ref: inputRef,
5123
+ value: query,
5124
+ onChange: (e) => {
5125
+ setQuery(e.target.value);
5126
+ setActiveIndex(null);
5127
+ },
5128
+ onKeyDown: (e) => {
5129
+ if (e.key === "ArrowDown") {
5130
+ e.preventDefault();
5131
+ setActiveIndex((prev) => {
5132
+ const next = prev === null ? 0 : prev + 1;
5133
+ return next >= filteredOptions.length ? 0 : next;
5134
+ });
5135
+ } else if (e.key === "ArrowUp") {
5136
+ e.preventDefault();
5137
+ setActiveIndex((prev) => {
5138
+ const next = prev === null ? filteredOptions.length - 1 : prev - 1;
5139
+ return next < 0 ? filteredOptions.length - 1 : next;
5140
+ });
5141
+ } else if (e.key === "Enter") {
5142
+ e.preventDefault();
5143
+ if (activeIndex !== null && filteredOptions[activeIndex] && !getOptionDisabled(filteredOptions[activeIndex])) {
5144
+ handleSelect(filteredOptions[activeIndex]);
5145
+ }
5146
+ } else if (e.key === "Escape") {
5147
+ e.preventDefault();
5148
+ setOpen(false);
5149
+ }
5150
+ },
5151
+ placeholder: searchPlaceholder,
5152
+ className: cn(
5153
+ "peer w-full rounded-xl bg-muted/40 py-2.5 pl-9 pr-3 text-sm",
5154
+ "border border-transparent",
5155
+ "focus:outline-none focus:bg-background focus:border-primary/30 focus:ring-2 focus:ring-primary/10",
5156
+ "transition-all duration-200",
5157
+ "placeholder:text-muted-foreground/50"
5158
+ ),
5159
+ "aria-autocomplete": "list",
5160
+ "aria-activedescendant": activeIndex != null ? `combobox-item-${activeIndex}` : void 0
5141
5161
  }
5142
- },
5143
- placeholder: searchPlaceholder,
5144
- className: cn(
5145
- "peer w-full rounded-xl bg-muted/40 py-2.5 pl-9 pr-3 text-sm",
5146
- "border border-transparent",
5147
- "focus:outline-none focus:bg-background focus:border-primary/30 focus:ring-2 focus:ring-primary/10",
5148
- "transition-all duration-200",
5149
- "placeholder:text-muted-foreground/50"
5150
5162
  ),
5151
- "aria-autocomplete": "list",
5152
- "aria-activedescendant": activeIndex != null ? `combobox-item-${activeIndex}` : void 0
5153
- }
5154
- ),
5155
- query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5156
- "button",
5157
- {
5158
- type: "button",
5159
- onClick: () => setQuery(""),
5160
- className: "absolute right-3 top-1/2 -translate-y-1/2 p-0.5 rounded-md hover:bg-muted text-muted-foreground hover:text-foreground transition-colors",
5161
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-3.5 w-3.5" })
5162
- }
5163
- )
5164
- ] }) }),
5165
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "overflow-y-auto overscroll-contain", style: { maxHeight }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "p-1.5", children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-3 animate-in fade-in-0 zoom-in-95 duration-300", children: [
5166
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "w-10 h-10 rounded-full border-2 border-primary/20 border-t-primary animate-spin" }) }),
5167
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-sm text-muted-foreground", children: loadingText })
5168
- ] }) }) : filteredOptions.length > 0 ? groupedOptions ? (
5169
- // Render grouped options with global index tracking
5170
- (() => {
5171
- let globalIndex = 0;
5172
- return Object.entries(groupedOptions).map(([group, items]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn(globalIndex > 0 && "mt-2 pt-2 border-t border-border/30"), children: [
5173
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: group }),
5174
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "space-y-0.5", children: items.map((item) => {
5175
- const index = globalIndex++;
5176
- return renderOptionItem(item, index);
5177
- }) })
5178
- ] }, group));
5179
- })()
5180
- ) : (
5181
- // Render flat options
5182
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "space-y-0.5", children: filteredOptions.map((item, index) => renderOptionItem(item, index)) })
5183
- ) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-3 animate-in fade-in-0 zoom-in-95 duration-300", children: [
5184
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "w-12 h-12 rounded-full bg-muted/50 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.SearchX, { className: "h-6 w-6 text-muted-foreground/60" }) }),
5185
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-1", children: [
5186
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "block text-sm font-medium text-foreground", children: emptyText }),
5187
- query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "block text-xs text-muted-foreground", children: "Try a different search term" })
5188
- ] }),
5189
- query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5190
- "button",
5191
- {
5192
- type: "button",
5193
- onClick: () => setQuery(""),
5194
- className: "px-3 py-1.5 text-xs font-medium text-primary bg-primary/10 rounded-full hover:bg-primary/20 transition-colors",
5195
- children: "Clear search"
5196
- }
5197
- )
5198
- ] }) }) }) })
5199
- ] });
5163
+ query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5164
+ "button",
5165
+ {
5166
+ type: "button",
5167
+ onClick: () => setQuery(""),
5168
+ className: "absolute right-3 top-1/2 -translate-y-1/2 p-0.5 rounded-md hover:bg-muted text-muted-foreground hover:text-foreground transition-colors",
5169
+ children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.X, { className: "h-3.5 w-3.5" })
5170
+ }
5171
+ )
5172
+ ] }) }),
5173
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "overflow-y-auto overscroll-contain", style: { maxHeight }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "p-1.5", children: loading2 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-3 animate-in fade-in-0 zoom-in-95 duration-300", children: [
5174
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "relative", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "w-10 h-10 rounded-full border-2 border-primary/20 border-t-primary animate-spin" }) }),
5175
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "text-sm text-muted-foreground", children: loadingText })
5176
+ ] }) }) : filteredOptions.length > 0 ? groupedOptions ? (
5177
+ // Render grouped options with global index tracking
5178
+ (() => {
5179
+ let globalIndex = 0;
5180
+ return Object.entries(groupedOptions).map(([group, items]) => /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: cn(globalIndex > 0 && "mt-2 pt-2 border-t border-border/30"), children: [
5181
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-1.5 text-xs font-semibold text-muted-foreground uppercase tracking-wider", children: group }),
5182
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "space-y-0.5", children: items.map((item) => {
5183
+ const index = globalIndex++;
5184
+ return renderOptionItem(item, index);
5185
+ }) })
5186
+ ] }, group));
5187
+ })()
5188
+ ) : (
5189
+ // Render flat options
5190
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("ul", { className: "space-y-0.5", children: filteredOptions.map((item, index) => renderOptionItem(item, index)) })
5191
+ ) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "px-3 py-10 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex flex-col items-center gap-3 animate-in fade-in-0 zoom-in-95 duration-300", children: [
5192
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "w-12 h-12 rounded-full bg-muted/50 flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_lucide_react12.SearchX, { className: "h-6 w-6 text-muted-foreground/60" }) }),
5193
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "space-y-1", children: [
5194
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "block text-sm font-medium text-foreground", children: emptyText }),
5195
+ query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "block text-xs text-muted-foreground", children: "Try a different search term" })
5196
+ ] }),
5197
+ query && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5198
+ "button",
5199
+ {
5200
+ type: "button",
5201
+ onClick: () => setQuery(""),
5202
+ className: "px-3 py-1.5 text-xs font-medium text-primary bg-primary/10 rounded-full hover:bg-primary/20 transition-colors",
5203
+ children: "Clear search"
5204
+ }
5205
+ )
5206
+ ] }) }) }) })
5207
+ ]
5208
+ }
5209
+ );
5200
5210
  const sizeStyles8 = {
5201
5211
  sm: "h-8 py-1.5 text-sm md:h-7 md:text-xs",
5202
5212
  md: "h-10 py-2 text-sm",
@@ -5209,7 +5219,7 @@ var Combobox = ({
5209
5219
  filled: "border-0 bg-muted/50 hover:bg-muted/80"
5210
5220
  };
5211
5221
  const labelSize = size === "sm" ? "text-xs" : size === "lg" ? "text-base" : "text-sm";
5212
- const radiusClass = size === "sm" ? "rounded-lg" : "rounded-xl";
5222
+ const radiusClass = "rounded-full";
5213
5223
  const verticalGap = size === "sm" ? "space-y-1.5" : "space-y-2";
5214
5224
  const triggerButtonBaseProps = {
5215
5225
  ref: triggerRef,
@@ -5314,12 +5324,12 @@ var Combobox = ({
5314
5324
  placement: "bottom-start",
5315
5325
  matchTriggerWidth: true,
5316
5326
  className: "z-9999",
5317
- contentClassName: "p-0",
5327
+ contentClassName: "p-0 overflow-hidden rounded-2xl md:rounded-3xl",
5318
5328
  children: dropdownBody
5319
5329
  }
5320
5330
  ) : /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative", children: [
5321
5331
  triggerButtonInline,
5322
- open && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "absolute left-0 top-full mt-1 z-50 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "rounded-2xl border text-popover-foreground shadow-md backdrop-blur-sm bg-popover/95 border-border/60", children: dropdownBody }) })
5332
+ open && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "absolute left-0 top-full mt-1 z-50 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "rounded-2xl md:rounded-3xl overflow-hidden border text-popover-foreground shadow-md backdrop-blur-sm bg-popover/95 border-border/60", children: dropdownBody }) })
5323
5333
  ] }),
5324
5334
  (helperText || error) && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("p", { className: cn("text-xs transition-colors duration-200 flex items-center gap-1.5", error ? "text-destructive" : "text-muted-foreground"), children: [
5325
5335
  error && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 20 20", fill: "currentColor", className: "w-3.5 h-3.5 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
@@ -6154,7 +6164,7 @@ var DatePicker = ({
6154
6164
  contentClassName: cn(
6155
6165
  "p-0",
6156
6166
  "backdrop-blur-xl bg-popover/95 border-border/40 shadow-2xl",
6157
- "rounded-2xl",
6167
+ "rounded-2xl md:rounded-3xl",
6158
6168
  // Keep usable on small viewports (wheel scroll should stay within the popover if it overflows)
6159
6169
  "max-w-[calc(100vw-1rem)] max-h-[calc(100vh-6rem)] overflow-auto overscroll-contain",
6160
6170
  size === "sm" ? "p-4" : "p-5",
@@ -6457,7 +6467,7 @@ var DateRangePicker = ({ startDate, endDate, onChange, placeholder = "Select dat
6457
6467
  contentClassName: cn(
6458
6468
  "p-0",
6459
6469
  "backdrop-blur-xl bg-popover/95 border-border/40 shadow-2xl",
6460
- "rounded-2xl",
6470
+ "rounded-2xl md:rounded-3xl",
6461
6471
  "max-w-[calc(100vw-1rem)] max-h-[calc(100vh-6rem)] overflow-auto overscroll-contain",
6462
6472
  size === "sm" ? "p-3" : "p-5",
6463
6473
  "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-300"
@@ -7110,6 +7120,14 @@ function WheelColumn({
7110
7120
  const wheelDeltaRef = React25.useRef(0);
7111
7121
  const scrollEndTimeoutRef = React25.useRef(null);
7112
7122
  const suppressScrollSelectUntilRef = React25.useRef(0);
7123
+ const suppressItemClickUntilRef = React25.useRef(0);
7124
+ const dragRef = React25.useRef(null);
7125
+ const draggingRef = React25.useRef(false);
7126
+ const inertialRef = React25.useRef(false);
7127
+ const inertiaRafRef = React25.useRef(null);
7128
+ const inertiaVelocityRef = React25.useRef(0);
7129
+ const inertiaLastTimeRef = React25.useRef(0);
7130
+ const moveSamplesRef = React25.useRef([]);
7113
7131
  const loop = true;
7114
7132
  const ui = React25.useMemo(() => {
7115
7133
  if (size === "sm") {
@@ -7180,6 +7198,10 @@ function WheelColumn({
7180
7198
  window.clearTimeout(scrollEndTimeoutRef.current);
7181
7199
  scrollEndTimeoutRef.current = null;
7182
7200
  }
7201
+ if (inertiaRafRef.current != null) {
7202
+ cancelAnimationFrame(inertiaRafRef.current);
7203
+ inertiaRafRef.current = null;
7204
+ }
7183
7205
  cancelAnimationFrame(rafRef.current);
7184
7206
  };
7185
7207
  }, [animate, baseOffset, extendedItems.length, getNearestVirtualIndex, itemHeight, loop, scrollRef, valueIndex]);
@@ -7277,6 +7299,138 @@ function WheelColumn({
7277
7299
  const from = lastVirtualIndexRef.current ?? fallback;
7278
7300
  return getNearestVirtualIndex(valueIndex, from);
7279
7301
  }, [baseOffset, getNearestVirtualIndex, items.length, loop, valueIndex]);
7302
+ const commitFromScrollTop = React25.useCallback(
7303
+ (behavior) => {
7304
+ const el = scrollRef.current;
7305
+ if (!el) return;
7306
+ if (items.length <= 0) return;
7307
+ const len = items.length;
7308
+ const maxVirtual = Math.max(0, extendedItems.length - 1);
7309
+ const idxVirtual = clamp3(Math.round(el.scrollTop / itemHeight), 0, maxVirtual);
7310
+ const realIndex = (idxVirtual % len + len) % len;
7311
+ const snappedVirtual = loop ? getNearestVirtualIndex(realIndex, idxVirtual) : realIndex;
7312
+ lastVirtualIndexRef.current = snappedVirtual;
7313
+ suppressScrollSelectUntilRef.current = Date.now() + 350;
7314
+ if (behavior === "auto") el.scrollTop = snappedVirtual * itemHeight;
7315
+ else el.scrollTo({ top: snappedVirtual * itemHeight, behavior });
7316
+ onSelect(items[realIndex]);
7317
+ if (loop) {
7318
+ const min = len;
7319
+ const max = len * 2 - 1;
7320
+ let centered = snappedVirtual;
7321
+ if (centered < min) centered += len;
7322
+ if (centered > max) centered -= len;
7323
+ if (centered !== snappedVirtual) {
7324
+ lastVirtualIndexRef.current = centered;
7325
+ el.scrollTop = centered * itemHeight;
7326
+ }
7327
+ }
7328
+ },
7329
+ [extendedItems.length, getNearestVirtualIndex, itemHeight, items, loop, onSelect, scrollRef]
7330
+ );
7331
+ const onPointerDown = (e) => {
7332
+ if (e.pointerType !== "mouse") return;
7333
+ if (e.button !== 0) return;
7334
+ const el = scrollRef.current;
7335
+ if (!el) return;
7336
+ e.preventDefault();
7337
+ setFocusedColumn(column);
7338
+ draggingRef.current = true;
7339
+ inertialRef.current = false;
7340
+ if (inertiaRafRef.current != null) {
7341
+ cancelAnimationFrame(inertiaRafRef.current);
7342
+ inertiaRafRef.current = null;
7343
+ }
7344
+ if (scrollEndTimeoutRef.current != null) {
7345
+ window.clearTimeout(scrollEndTimeoutRef.current);
7346
+ scrollEndTimeoutRef.current = null;
7347
+ }
7348
+ dragRef.current = { pointerId: e.pointerId, startY: e.clientY, startScrollTop: el.scrollTop, moved: false };
7349
+ moveSamplesRef.current = [{ t: performance.now(), top: el.scrollTop }];
7350
+ try {
7351
+ el.setPointerCapture(e.pointerId);
7352
+ } catch {
7353
+ }
7354
+ };
7355
+ const onPointerMove = (e) => {
7356
+ const el = scrollRef.current;
7357
+ const drag = dragRef.current;
7358
+ if (!el || !drag) return;
7359
+ if (e.pointerId !== drag.pointerId) return;
7360
+ e.preventDefault();
7361
+ const dy = e.clientY - drag.startY;
7362
+ if (!drag.moved && Math.abs(dy) < 4) return;
7363
+ if (!drag.moved) {
7364
+ drag.moved = true;
7365
+ suppressItemClickUntilRef.current = Date.now() + 400;
7366
+ }
7367
+ suppressScrollSelectUntilRef.current = Date.now() + 500;
7368
+ el.scrollTop = drag.startScrollTop - dy;
7369
+ const now = performance.now();
7370
+ const samples = moveSamplesRef.current;
7371
+ samples.push({ t: now, top: el.scrollTop });
7372
+ while (samples.length > 6 && samples[0] && now - samples[0].t > 120) samples.shift();
7373
+ while (samples.length > 8) samples.shift();
7374
+ if (samples.length >= 2) {
7375
+ const oldest = samples[0];
7376
+ const dt = now - oldest.t;
7377
+ if (dt > 0) inertiaVelocityRef.current = (el.scrollTop - oldest.top) / dt;
7378
+ }
7379
+ };
7380
+ const startInertia = React25.useCallback(() => {
7381
+ const el = scrollRef.current;
7382
+ if (!el) return;
7383
+ if (items.length <= 0) return;
7384
+ inertialRef.current = true;
7385
+ suppressItemClickUntilRef.current = Date.now() + 600;
7386
+ inertiaLastTimeRef.current = performance.now();
7387
+ const len = items.length;
7388
+ const cycle = len * itemHeight;
7389
+ const frictionPerFrame = 0.92;
7390
+ const tick = () => {
7391
+ const now = performance.now();
7392
+ const last = inertiaLastTimeRef.current || now;
7393
+ const dt = Math.min(48, Math.max(0, now - last));
7394
+ inertiaLastTimeRef.current = now;
7395
+ let v = inertiaVelocityRef.current;
7396
+ el.scrollTop += v * dt;
7397
+ if (loop && cycle > 0) {
7398
+ if (el.scrollTop < cycle * 0.5) el.scrollTop += cycle;
7399
+ else if (el.scrollTop > cycle * 2.5) el.scrollTop -= cycle;
7400
+ }
7401
+ const decay = Math.pow(frictionPerFrame, dt / 16);
7402
+ v *= decay;
7403
+ inertiaVelocityRef.current = v;
7404
+ if (Math.abs(v) < 0.03) {
7405
+ inertialRef.current = false;
7406
+ inertiaRafRef.current = null;
7407
+ commitFromScrollTop("smooth");
7408
+ return;
7409
+ }
7410
+ inertiaRafRef.current = requestAnimationFrame(tick);
7411
+ };
7412
+ inertiaRafRef.current = requestAnimationFrame(tick);
7413
+ }, [commitFromScrollTop, itemHeight, items.length, loop, scrollRef]);
7414
+ const endDrag = (pointerId) => {
7415
+ const el = scrollRef.current;
7416
+ const drag = dragRef.current;
7417
+ if (!el || !drag) return;
7418
+ if (pointerId !== drag.pointerId) return;
7419
+ dragRef.current = null;
7420
+ draggingRef.current = false;
7421
+ try {
7422
+ el.releasePointerCapture(pointerId);
7423
+ } catch {
7424
+ }
7425
+ const v = inertiaVelocityRef.current;
7426
+ const shouldFlick = drag.moved && Math.abs(v) >= 0.35;
7427
+ if (shouldFlick) {
7428
+ startInertia();
7429
+ } else {
7430
+ inertialRef.current = false;
7431
+ commitFromScrollTop("smooth");
7432
+ }
7433
+ };
7280
7434
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("flex-1", ui.columnWidth), children: [
7281
7435
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cn(ui.label, "font-bold uppercase tracking-wider text-muted-foreground/70 text-center"), children: labelText }),
7282
7436
  /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "relative rounded-xl bg-muted/30 overflow-hidden", style: { height }, children: [
@@ -7296,6 +7450,7 @@ function WheelColumn({
7296
7450
  className: cn(
7297
7451
  "h-full overflow-y-auto overscroll-contain snap-y snap-mandatory",
7298
7452
  "scrollbar-none",
7453
+ "select-none cursor-grab active:cursor-grabbing",
7299
7454
  "focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background rounded-xl"
7300
7455
  ),
7301
7456
  style: { paddingTop: paddingY, paddingBottom: paddingY },
@@ -7304,7 +7459,15 @@ function WheelColumn({
7304
7459
  tabIndex: focused ? 0 : -1,
7305
7460
  onKeyDown: (e) => onKeyDown(e, column),
7306
7461
  onFocus: () => setFocusedColumn(column),
7307
- onScroll: handleScroll,
7462
+ onScroll: () => {
7463
+ if (draggingRef.current) return;
7464
+ if (inertialRef.current) return;
7465
+ handleScroll();
7466
+ },
7467
+ onPointerDown,
7468
+ onPointerMove,
7469
+ onPointerUp: (e) => endDrag(e.pointerId),
7470
+ onPointerCancel: (e) => endDrag(e.pointerId),
7308
7471
  children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { children: extendedItems.map((n, index) => {
7309
7472
  const dist = Math.abs(index - currentVirtual);
7310
7473
  const distForVisual = Math.min(dist, 2);
@@ -7329,6 +7492,7 @@ function WheelColumn({
7329
7492
  opacity
7330
7493
  },
7331
7494
  onClick: () => {
7495
+ if (Date.now() < suppressItemClickUntilRef.current) return;
7332
7496
  const el = scrollRef.current;
7333
7497
  if (!el) return;
7334
7498
  suppressScrollSelectUntilRef.current = Date.now() + 350;
@@ -7950,7 +8114,13 @@ function TimePicker({
7950
8114
  label,
7951
8115
  required && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive ml-1", children: "*" })
7952
8116
  ] }) }),
7953
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: cn(panelSz.contentPadding, "rounded-2xl border border-border/60 bg-card/95 backdrop-blur-sm shadow-xl", className), children: timePickerContent })
8117
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
8118
+ "div",
8119
+ {
8120
+ className: cn(panelSz.contentPadding, "rounded-2xl md:rounded-3xl border border-border/60 bg-card/95 backdrop-blur-sm shadow-xl", className),
8121
+ children: timePickerContent
8122
+ }
8123
+ )
7954
8124
  ] });
7955
8125
  }
7956
8126
  return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "w-full", ...rest, children: [
@@ -7981,7 +8151,7 @@ function TimePicker({
7981
8151
  contentWidth: matchTriggerWidth ? void 0 : contentWidth,
7982
8152
  contentClassName: cn(
7983
8153
  panelSz.contentPadding,
7984
- "rounded-2xl border bg-popover/98 backdrop-blur-md shadow-2xl",
8154
+ "rounded-2xl md:rounded-3xl border bg-popover/98 backdrop-blur-md shadow-2xl",
7985
8155
  error && "border-destructive/40",
7986
8156
  success && "border-success/40",
7987
8157
  !error && !success && "border-border/60",
@@ -8162,7 +8332,7 @@ var DateTimePicker = ({
8162
8332
  }
8163
8333
  ),
8164
8334
  contentClassName: cn(
8165
- "w-auto p-0 rounded-2xl",
8335
+ "w-auto p-0 rounded-2xl md:rounded-3xl",
8166
8336
  // Keep the popover usable on small viewports
8167
8337
  "max-w-[calc(100vw-1rem)] max-h-[calc(100vh-6rem)] overflow-auto"
8168
8338
  ),
@@ -10772,7 +10942,7 @@ var MultiCombobox = ({
10772
10942
  item.value
10773
10943
  );
10774
10944
  };
10775
- const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { "data-combobox-dropdown": true, "data-state": open ? "open" : "closed", className: "w-full", children: [
10945
+ const dropdownBody = /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { "data-combobox-dropdown": true, "data-state": open ? "open" : "closed", className: "w-full rounded-2xl md:rounded-3xl overflow-hidden", children: [
10776
10946
  value.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "px-3 py-2 border-b border-border/40 flex items-center justify-between bg-muted/30", children: [
10777
10947
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("span", { className: "text-xs font-medium text-muted-foreground", children: [
10778
10948
  value.length,
@@ -10876,7 +11046,7 @@ var MultiCombobox = ({
10876
11046
  "aria-controls": listboxId,
10877
11047
  "aria-invalid": !!error,
10878
11048
  className: cn(
10879
- "group flex w-full items-center gap-2 rounded-2xl min-h-10 transition-all duration-200",
11049
+ "group flex w-full items-center gap-2 rounded-full min-h-10 transition-all duration-200",
10880
11050
  "px-3 py-2",
10881
11051
  variantStyles6[variant],
10882
11052
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 focus-visible:border-primary",
@@ -11010,7 +11180,7 @@ var MultiCombobox = ({
11010
11180
  placement: "bottom-start",
11011
11181
  matchTriggerWidth: true,
11012
11182
  className: "z-9999",
11013
- contentClassName: "p-0",
11183
+ contentClassName: "p-0 overflow-hidden rounded-2xl md:rounded-3xl",
11014
11184
  children: dropdownBody
11015
11185
  }
11016
11186
  ),
@@ -11320,16 +11490,22 @@ var SIZE_STYLES = {
11320
11490
  container: "py-3"
11321
11491
  }
11322
11492
  };
11493
+ var clamp5 = (n, min, max) => Math.min(max, Math.max(min, n));
11323
11494
  var Slider = React34.forwardRef(
11324
11495
  ({
11325
11496
  className,
11497
+ mode = "single",
11326
11498
  value,
11327
11499
  defaultValue = 0,
11500
+ rangeValue,
11501
+ defaultRangeValue,
11328
11502
  min = 0,
11329
11503
  max = 100,
11330
11504
  step = 1,
11331
11505
  onChange,
11332
11506
  onValueChange,
11507
+ onRangeChange,
11508
+ onRangeValueChange,
11333
11509
  onMouseUp,
11334
11510
  onTouchEnd,
11335
11511
  label,
@@ -11346,20 +11522,125 @@ var Slider = React34.forwardRef(
11346
11522
  noFocus = true,
11347
11523
  ...props
11348
11524
  }, ref) => {
11525
+ const isRange = mode === "range";
11526
+ const trackRef = React34.useRef(null);
11349
11527
  const [internalValue, setInternalValue] = React34.useState(defaultValue);
11528
+ const [internalRange, setInternalRange] = React34.useState(() => {
11529
+ if (defaultRangeValue) return defaultRangeValue;
11530
+ const v = clamp5(defaultValue, min, max);
11531
+ return [min, v];
11532
+ });
11533
+ const [activeThumb, setActiveThumb] = React34.useState(null);
11534
+ const dragRef = React34.useRef(null);
11350
11535
  const isControlled = value !== void 0;
11351
11536
  const currentValue = isControlled ? value : internalValue;
11352
- const handleChange = (e) => {
11353
- const newValue = Number(e.target.value);
11354
- if (!isControlled) {
11355
- setInternalValue(newValue);
11537
+ const isRangeControlled = rangeValue !== void 0;
11538
+ const currentRange = isRangeControlled ? rangeValue : internalRange;
11539
+ const rangeMin = clamp5(currentRange[0] ?? min, min, max);
11540
+ const rangeMax = clamp5(currentRange[1] ?? max, min, max);
11541
+ const normalizedRange = rangeMin <= rangeMax ? [rangeMin, rangeMax] : [rangeMax, rangeMin];
11542
+ const handleSingleChange = React34.useCallback(
11543
+ (e) => {
11544
+ const newValue = Number(e.target.value);
11545
+ if (!isControlled) {
11546
+ setInternalValue(newValue);
11547
+ }
11548
+ onChange?.(newValue);
11549
+ onValueChange?.(newValue);
11550
+ },
11551
+ [isControlled, onChange, onValueChange]
11552
+ );
11553
+ const emitRange = React34.useCallback(
11554
+ (next) => {
11555
+ onRangeChange?.(next);
11556
+ onRangeValueChange?.(next);
11557
+ },
11558
+ [onRangeChange, onRangeValueChange]
11559
+ );
11560
+ const handleRangeChange = React34.useCallback(
11561
+ (thumb) => (e) => {
11562
+ const nextVal = Number(e.target.value);
11563
+ const [curMin, curMax] = normalizedRange;
11564
+ const next = thumb === "min" ? [Math.min(nextVal, curMax), curMax] : [curMin, Math.max(nextVal, curMin)];
11565
+ if (!isRangeControlled) setInternalRange(next);
11566
+ emitRange(next);
11567
+ },
11568
+ [emitRange, isRangeControlled, normalizedRange]
11569
+ );
11570
+ const denom = Math.max(1e-9, max - min);
11571
+ const percentage = (currentValue - min) / denom * 100;
11572
+ const rangeStartPct = (normalizedRange[0] - min) / denom * 100;
11573
+ const rangeEndPct = (normalizedRange[1] - min) / denom * 100;
11574
+ const sizeStyles8 = SIZE_STYLES[size];
11575
+ const displayValue = React34.useMemo(() => {
11576
+ if (isRange) {
11577
+ const a = formatValue ? formatValue(normalizedRange[0]) : normalizedRange[0].toString();
11578
+ const b = formatValue ? formatValue(normalizedRange[1]) : normalizedRange[1].toString();
11579
+ return `${a} \u2013 ${b}`;
11580
+ }
11581
+ return formatValue ? formatValue(currentValue) : currentValue.toString();
11582
+ }, [currentValue, formatValue, isRange, normalizedRange]);
11583
+ const quantize = React34.useCallback(
11584
+ (v) => {
11585
+ const stepped = Math.round((v - min) / step) * step + min;
11586
+ const fixed = Number(stepped.toFixed(10));
11587
+ return clamp5(fixed, min, max);
11588
+ },
11589
+ [max, min, step]
11590
+ );
11591
+ const valueFromClientX = React34.useCallback(
11592
+ (clientX) => {
11593
+ const el = trackRef.current;
11594
+ if (!el) return min;
11595
+ const rect = el.getBoundingClientRect();
11596
+ const x = clamp5(clientX - rect.left, 0, rect.width);
11597
+ const ratio = rect.width <= 0 ? 0 : x / rect.width;
11598
+ return quantize(min + ratio * (max - min));
11599
+ },
11600
+ [max, min, quantize]
11601
+ );
11602
+ const startRangeDrag = (e) => {
11603
+ if (!isRange) return;
11604
+ if (disabled) return;
11605
+ if (orientation !== "horizontal") return;
11606
+ if (e.button !== 0) return;
11607
+ const nextValue = valueFromClientX(e.clientX);
11608
+ const [curMin, curMax] = normalizedRange;
11609
+ const distToMin = Math.abs(nextValue - curMin);
11610
+ const distToMax = Math.abs(nextValue - curMax);
11611
+ const thumb = distToMin <= distToMax ? "min" : "max";
11612
+ setActiveThumb(thumb);
11613
+ dragRef.current = { pointerId: e.pointerId, thumb };
11614
+ try {
11615
+ e.currentTarget.setPointerCapture(e.pointerId);
11616
+ } catch {
11617
+ }
11618
+ const next = thumb === "min" ? [Math.min(nextValue, curMax), curMax] : [curMin, Math.max(nextValue, curMin)];
11619
+ if (!isRangeControlled) setInternalRange(next);
11620
+ emitRange(next);
11621
+ };
11622
+ const moveRangeDrag = (e) => {
11623
+ const drag = dragRef.current;
11624
+ if (!drag) return;
11625
+ if (e.pointerId !== drag.pointerId) return;
11626
+ const nextValue = valueFromClientX(e.clientX);
11627
+ const [curMin, curMax] = normalizedRange;
11628
+ const next = drag.thumb === "min" ? [Math.min(nextValue, curMax), curMax] : [curMin, Math.max(nextValue, curMin)];
11629
+ if (!isRangeControlled) setInternalRange(next);
11630
+ emitRange(next);
11631
+ };
11632
+ const endRangeDrag = (e) => {
11633
+ const drag = dragRef.current;
11634
+ if (!drag) return;
11635
+ if (e.pointerId !== drag.pointerId) return;
11636
+ dragRef.current = null;
11637
+ onMouseUp?.();
11638
+ onTouchEnd?.();
11639
+ try {
11640
+ e.currentTarget.releasePointerCapture(e.pointerId);
11641
+ } catch {
11356
11642
  }
11357
- onChange?.(newValue);
11358
- onValueChange?.(newValue);
11359
11643
  };
11360
- const percentage = (currentValue - min) / (max - min) * 100;
11361
- const sizeStyles8 = SIZE_STYLES[size];
11362
- const displayValue = formatValue ? formatValue(currentValue) : currentValue.toString();
11363
11644
  if (orientation === "vertical") {
11364
11645
  }
11365
11646
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("w-full space-y-2", containerClassName), children: [
@@ -11367,65 +11648,129 @@ var Slider = React34.forwardRef(
11367
11648
  label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { className: cn("text-sm font-medium text-foreground", labelClassName), children: label }),
11368
11649
  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 })
11369
11650
  ] }),
11370
- /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("relative flex items-center", sizeStyles8.container), children: [
11371
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: cn("w-full rounded-full bg-secondary relative overflow-hidden", sizeStyles8.track, trackClassName), children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute left-0 top-0 h-full bg-primary rounded-full", style: { width: `${percentage}%` } }) }),
11372
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11373
- "input",
11651
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { ref: trackRef, className: cn("relative flex items-center", sizeStyles8.container), children: [
11652
+ /* @__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)(
11653
+ "div",
11374
11654
  {
11375
- ref,
11376
- type: "range",
11377
- min,
11378
- max,
11379
- step,
11380
- value: currentValue,
11381
- onChange: handleChange,
11382
- onMouseUp,
11383
- onTouchEnd,
11384
- disabled,
11385
- className: cn(
11386
- // Base styles
11387
- "absolute w-full h-full appearance-none bg-transparent cursor-pointer",
11388
- !noFocus && "focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background rounded-full",
11389
- noFocus && "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none",
11390
- // Webkit styles for thumb
11391
- "[&::-webkit-slider-thumb]:appearance-none",
11392
- "[&::-webkit-slider-thumb]:bg-primary",
11393
- "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background",
11394
- "[&::-webkit-slider-thumb]:rounded-full",
11395
- "[&::-webkit-slider-thumb]:shadow-md",
11396
- "[&::-webkit-slider-thumb]:cursor-pointer",
11397
- "[&::-webkit-slider-thumb]:transition-all [&::-webkit-slider-thumb]:duration-150",
11398
- size === "sm" && "[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3",
11399
- size === "md" && "[&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
11400
- size === "lg" && "[&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5",
11401
- // Firefox styles for thumb
11402
- "[&::-moz-range-thumb]:bg-primary",
11403
- "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background",
11404
- "[&::-moz-range-thumb]:rounded-full",
11405
- "[&::-moz-range-thumb]:shadow-md",
11406
- "[&::-moz-range-thumb]:cursor-pointer",
11407
- "[&::-moz-range-thumb]:transition-all [&::-moz-range-thumb]:duration-150",
11408
- size === "sm" && "[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3",
11409
- size === "md" && "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4",
11410
- size === "lg" && "[&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5",
11411
- // Remove default track in Firefox
11412
- "[&::-moz-range-track]:bg-transparent",
11413
- "[&::-moz-range-track]:border-transparent",
11414
- // Hover effects
11415
- "hover:[&::-webkit-slider-thumb]:scale-110 hover:[&::-webkit-slider-thumb]:shadow-lg",
11416
- "hover:[&::-moz-range-thumb]:scale-110 hover:[&::-moz-range-thumb]:shadow-lg",
11417
- // Disabled styles
11418
- disabled && [
11419
- "cursor-not-allowed opacity-50",
11420
- "[&::-webkit-slider-thumb]:cursor-not-allowed [&::-webkit-slider-thumb]:opacity-50",
11421
- "[&::-moz-range-thumb]:cursor-not-allowed [&::-moz-range-thumb]:opacity-50"
11422
- ],
11423
- className,
11424
- thumbClassName
11425
- ),
11426
- ...props
11655
+ className: "absolute top-0 h-full bg-primary rounded-full",
11656
+ style: { left: `${rangeStartPct}%`, width: `${Math.max(0, rangeEndPct - rangeStartPct)}%` }
11427
11657
  }
11428
- )
11658
+ ) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute left-0 top-0 h-full bg-primary rounded-full", style: { width: `${percentage}%` } }) }),
11659
+ (() => {
11660
+ const baseInputClassName = cn(
11661
+ // Base styles
11662
+ "absolute w-full h-full appearance-none bg-transparent cursor-pointer",
11663
+ !noFocus && "focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background rounded-full",
11664
+ noFocus && "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none",
11665
+ // Webkit styles for thumb
11666
+ "[&::-webkit-slider-thumb]:appearance-none",
11667
+ "[&::-webkit-slider-thumb]:bg-primary",
11668
+ "[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background",
11669
+ "[&::-webkit-slider-thumb]:rounded-full",
11670
+ "[&::-webkit-slider-thumb]:shadow-md",
11671
+ "[&::-webkit-slider-thumb]:cursor-pointer",
11672
+ "[&::-webkit-slider-thumb]:transition-all [&::-webkit-slider-thumb]:duration-150",
11673
+ size === "sm" && "[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3",
11674
+ size === "md" && "[&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
11675
+ size === "lg" && "[&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5",
11676
+ // Firefox styles for thumb
11677
+ "[&::-moz-range-thumb]:bg-primary",
11678
+ "[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background",
11679
+ "[&::-moz-range-thumb]:rounded-full",
11680
+ "[&::-moz-range-thumb]:shadow-md",
11681
+ "[&::-moz-range-thumb]:cursor-pointer",
11682
+ "[&::-moz-range-thumb]:transition-all [&::-moz-range-thumb]:duration-150",
11683
+ size === "sm" && "[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3",
11684
+ size === "md" && "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4",
11685
+ size === "lg" && "[&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5",
11686
+ // Remove default track in Firefox
11687
+ "[&::-moz-range-track]:bg-transparent",
11688
+ "[&::-moz-range-track]:border-transparent",
11689
+ // Hover effects
11690
+ "hover:[&::-webkit-slider-thumb]:scale-110 hover:[&::-webkit-slider-thumb]:shadow-lg",
11691
+ "hover:[&::-moz-range-thumb]:scale-110 hover:[&::-moz-range-thumb]:shadow-lg",
11692
+ // Disabled styles
11693
+ disabled && [
11694
+ "cursor-not-allowed opacity-50",
11695
+ "[&::-webkit-slider-thumb]:cursor-not-allowed [&::-webkit-slider-thumb]:opacity-50",
11696
+ "[&::-moz-range-thumb]:cursor-not-allowed [&::-moz-range-thumb]:opacity-50"
11697
+ ],
11698
+ className,
11699
+ thumbClassName
11700
+ );
11701
+ if (!isRange) {
11702
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11703
+ "input",
11704
+ {
11705
+ ref,
11706
+ type: "range",
11707
+ min,
11708
+ max,
11709
+ step,
11710
+ value: currentValue,
11711
+ onChange: handleSingleChange,
11712
+ onMouseUp,
11713
+ onTouchEnd,
11714
+ disabled,
11715
+ className: baseInputClassName,
11716
+ ...props
11717
+ }
11718
+ );
11719
+ }
11720
+ const minZ = activeThumb === "min" ? "z-20" : "z-10";
11721
+ const maxZ = activeThumb === "max" ? "z-20" : "z-10";
11722
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
11723
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11724
+ "div",
11725
+ {
11726
+ className: cn("absolute inset-0 z-30", disabled ? "cursor-not-allowed" : "cursor-pointer"),
11727
+ onPointerDown: startRangeDrag,
11728
+ onPointerMove: moveRangeDrag,
11729
+ onPointerUp: endRangeDrag,
11730
+ onPointerCancel: endRangeDrag
11731
+ }
11732
+ ),
11733
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11734
+ "input",
11735
+ {
11736
+ ref,
11737
+ type: "range",
11738
+ min,
11739
+ max,
11740
+ step,
11741
+ value: normalizedRange[0],
11742
+ onChange: handleRangeChange("min"),
11743
+ onMouseUp,
11744
+ onTouchEnd,
11745
+ disabled,
11746
+ "aria-label": "Minimum value",
11747
+ onPointerDown: () => setActiveThumb("min"),
11748
+ onFocus: () => setActiveThumb("min"),
11749
+ className: cn(baseInputClassName, minZ, "pointer-events-none"),
11750
+ ...props
11751
+ }
11752
+ ),
11753
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
11754
+ "input",
11755
+ {
11756
+ type: "range",
11757
+ min,
11758
+ max,
11759
+ step,
11760
+ value: normalizedRange[1],
11761
+ onChange: handleRangeChange("max"),
11762
+ onMouseUp,
11763
+ onTouchEnd,
11764
+ disabled,
11765
+ "aria-label": "Maximum value",
11766
+ onPointerDown: () => setActiveThumb("max"),
11767
+ onFocus: () => setActiveThumb("max"),
11768
+ className: cn(baseInputClassName, maxZ, "pointer-events-none"),
11769
+ ...props
11770
+ }
11771
+ )
11772
+ ] });
11773
+ })()
11429
11774
  ] })
11430
11775
  ] });
11431
11776
  }
@@ -12079,7 +12424,7 @@ function CategoryTreeSelect(props) {
12079
12424
  // Modern trigger button styling
12080
12425
  "group flex w-full items-center justify-between px-3 py-2.5",
12081
12426
  "bg-background/80 backdrop-blur-sm border border-border/60",
12082
- "rounded-2xl h-11 text-sm",
12427
+ "rounded-full h-11 text-sm",
12083
12428
  "hover:bg-accent/10 hover:border-primary/40 hover:shadow-lg hover:shadow-primary/5 hover:-translate-y-0.5",
12084
12429
  "transition-all duration-300 ease-out",
12085
12430
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
@@ -12112,7 +12457,7 @@ function CategoryTreeSelect(props) {
12112
12457
  {
12113
12458
  className: cn(
12114
12459
  "absolute z-20 mt-2 w-full max-h-80 overflow-auto",
12115
- "rounded-2xl border border-border/40 bg-popover/95 text-popover-foreground",
12460
+ "rounded-2xl md:rounded-3xl overflow-hidden border border-border/40 bg-popover/95 text-popover-foreground",
12116
12461
  "shadow-2xl backdrop-blur-xl",
12117
12462
  "p-2",
12118
12463
  "animate-in fade-in-0 zoom-in-95 slide-in-from-top-2 duration-300"
@@ -13691,7 +14036,7 @@ var Timeline_default = Timeline;
13691
14036
  var React42 = __toESM(require("react"), 1);
13692
14037
  var import_lucide_react29 = require("lucide-react");
13693
14038
  var import_jsx_runtime50 = require("react/jsx-runtime");
13694
- var clamp5 = (n, min, max) => Math.max(min, Math.min(max, n));
14039
+ var clamp6 = (n, min, max) => Math.max(min, Math.min(max, n));
13695
14040
  function hexToRgb(hex) {
13696
14041
  const str = hex.replace(/^#/, "").trim();
13697
14042
  if (str.length === 3) {
@@ -13709,7 +14054,7 @@ function hexToRgb(hex) {
13709
14054
  return null;
13710
14055
  }
13711
14056
  function rgbToHex(r, g, b) {
13712
- return `#${[r, g, b].map((v) => clamp5(Math.round(v), 0, 255).toString(16).padStart(2, "0")).join("")}`;
14057
+ return `#${[r, g, b].map((v) => clamp6(Math.round(v), 0, 255).toString(16).padStart(2, "0")).join("")}`;
13713
14058
  }
13714
14059
  function rgbToHsl(r, g, b) {
13715
14060
  r /= 255;
@@ -13770,10 +14115,10 @@ function parseAnyColor(input) {
13770
14115
  }
13771
14116
  const rgbaMatch = s.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})(?:\s*,\s*(\d*\.?\d+))?\s*\)/i);
13772
14117
  if (rgbaMatch) {
13773
- const r = clamp5(parseInt(rgbaMatch[1], 10), 0, 255);
13774
- const g = clamp5(parseInt(rgbaMatch[2], 10), 0, 255);
13775
- const b = clamp5(parseInt(rgbaMatch[3], 10), 0, 255);
13776
- const a = rgbaMatch[4] != null ? clamp5(parseFloat(rgbaMatch[4]), 0, 1) : 1;
14118
+ const r = clamp6(parseInt(rgbaMatch[1], 10), 0, 255);
14119
+ const g = clamp6(parseInt(rgbaMatch[2], 10), 0, 255);
14120
+ const b = clamp6(parseInt(rgbaMatch[3], 10), 0, 255);
14121
+ const a = rgbaMatch[4] != null ? clamp6(parseFloat(rgbaMatch[4]), 0, 1) : 1;
13777
14122
  return { r, g, b, a };
13778
14123
  }
13779
14124
  const hslaMatch = s.match(/hsla?\(\s*(\d{1,3}(?:\.\d+)?)\s*,?\s*(\d{1,3}(?:\.\d+)?)%?\s*,?\s*(\d{1,3}(?:\.\d+)?)%?(?:\s*,?\s*(\d*\.?\d+))?\s*\)/i);
@@ -13781,7 +14126,7 @@ function parseAnyColor(input) {
13781
14126
  const h = parseFloat(hslaMatch[1]);
13782
14127
  const sl = parseFloat(hslaMatch[2]);
13783
14128
  const l = parseFloat(hslaMatch[3]);
13784
- const a = hslaMatch[4] != null ? clamp5(parseFloat(hslaMatch[4]), 0, 1) : 1;
14129
+ const a = hslaMatch[4] != null ? clamp6(parseFloat(hslaMatch[4]), 0, 1) : 1;
13785
14130
  const rgb = hslToRgb(h, sl, l);
13786
14131
  return { ...rgb, a };
13787
14132
  }
@@ -13794,12 +14139,12 @@ function formatOutput({ r, g, b, a }, withAlpha, format) {
13794
14139
  if (format === "hsl" || format === "hsla") {
13795
14140
  const hsl = rgbToHsl(r, g, b);
13796
14141
  if (format === "hsla" || withAlpha) {
13797
- return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${clamp5(a, 0, 1)})`;
14142
+ return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${clamp6(a, 0, 1)})`;
13798
14143
  }
13799
14144
  return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
13800
14145
  }
13801
14146
  if (withAlpha || a !== 1) {
13802
- return `rgba(${clamp5(r, 0, 255)}, ${clamp5(g, 0, 255)}, ${clamp5(b, 0, 255)}, ${clamp5(a, 0, 1)})`;
14147
+ return `rgba(${clamp6(r, 0, 255)}, ${clamp6(g, 0, 255)}, ${clamp6(b, 0, 255)}, ${clamp6(a, 0, 1)})`;
13803
14148
  }
13804
14149
  return rgbToHex(r, g, b);
13805
14150
  }
@@ -13933,7 +14278,7 @@ function ColorPicker({
13933
14278
  emit(next);
13934
14279
  };
13935
14280
  const setAlpha = (aPct) => {
13936
- const a = clamp5(aPct / 100, 0, 1);
14281
+ const a = clamp6(aPct / 100, 0, 1);
13937
14282
  const next = { ...rgba, a };
13938
14283
  setRgba(next);
13939
14284
  emit(next);
@@ -14012,7 +14357,7 @@ function ColorPicker({
14012
14357
  placement: "bottom-start",
14013
14358
  matchTriggerWidth: variant === "minimal",
14014
14359
  contentWidth: contentWidthByVariant[variant],
14015
- contentClassName: cn("p-3 rounded-xl border border-border bg-card shadow-lg", contentClassName),
14360
+ contentClassName: cn("p-3 rounded-2xl md:rounded-3xl border border-border bg-card shadow-lg", contentClassName),
14016
14361
  children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "space-y-3", children: [
14017
14362
  variant !== "minimal" && /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "flex items-center gap-2", children: [
14018
14363
  /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
@@ -18594,7 +18939,7 @@ function toNullableNumber(value) {
18594
18939
  }
18595
18940
  return null;
18596
18941
  }
18597
- function clamp6(value, min, max) {
18942
+ function clamp7(value, min, max) {
18598
18943
  return Math.min(max, Math.max(min, value));
18599
18944
  }
18600
18945
  function ResizableImageNodeView(props) {
@@ -18656,18 +19001,18 @@ function ResizableImageNodeView(props) {
18656
19001
  let nextH = drag.startH;
18657
19002
  if (event.ctrlKey) {
18658
19003
  if (Math.abs(dx) >= Math.abs(dy)) {
18659
- nextW = clamp6(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
18660
- nextH = clamp6(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
19004
+ nextW = clamp7(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
19005
+ nextH = clamp7(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18661
19006
  } else {
18662
- nextH = clamp6(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18663
- nextW = clamp6(nextH * drag.aspect, MIN_IMAGE_SIZE_PX, drag.maxW);
19007
+ nextH = clamp7(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
19008
+ nextW = clamp7(nextH * drag.aspect, MIN_IMAGE_SIZE_PX, drag.maxW);
18664
19009
  }
18665
19010
  } else {
18666
19011
  if (!drag.axis && (Math.abs(dx) > AXIS_LOCK_THRESHOLD_PX || Math.abs(dy) > AXIS_LOCK_THRESHOLD_PX)) {
18667
19012
  drag.axis = Math.abs(dx) >= Math.abs(dy) ? "x" : "y";
18668
19013
  }
18669
- if (drag.axis === "x") nextW = clamp6(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
18670
- if (drag.axis === "y") nextH = clamp6(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
19014
+ if (drag.axis === "x") nextW = clamp7(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
19015
+ if (drag.axis === "y") nextH = clamp7(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
18671
19016
  }
18672
19017
  drag.lastW = nextW;
18673
19018
  drag.lastH = nextH;