@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 +534 -189
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +623 -278
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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)(
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
e
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
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
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
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 =
|
|
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:
|
|
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)(
|
|
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-
|
|
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
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
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)(
|
|
11372
|
-
|
|
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
|
-
|
|
11376
|
-
|
|
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-
|
|
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
|
|
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) =>
|
|
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 =
|
|
13774
|
-
const g =
|
|
13775
|
-
const b =
|
|
13776
|
-
const a = rgbaMatch[4] != null ?
|
|
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 ?
|
|
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)}%, ${
|
|
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(${
|
|
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 =
|
|
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-
|
|
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
|
|
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 =
|
|
18660
|
-
nextH =
|
|
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 =
|
|
18663
|
-
nextW =
|
|
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 =
|
|
18670
|
-
if (drag.axis === "y") nextH =
|
|
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;
|