@underverse-ui/underverse 0.2.107 → 0.2.108
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 +413 -84
- 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 +502 -173
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7110,6 +7110,14 @@ function WheelColumn({
|
|
|
7110
7110
|
const wheelDeltaRef = React25.useRef(0);
|
|
7111
7111
|
const scrollEndTimeoutRef = React25.useRef(null);
|
|
7112
7112
|
const suppressScrollSelectUntilRef = React25.useRef(0);
|
|
7113
|
+
const suppressItemClickUntilRef = React25.useRef(0);
|
|
7114
|
+
const dragRef = React25.useRef(null);
|
|
7115
|
+
const draggingRef = React25.useRef(false);
|
|
7116
|
+
const inertialRef = React25.useRef(false);
|
|
7117
|
+
const inertiaRafRef = React25.useRef(null);
|
|
7118
|
+
const inertiaVelocityRef = React25.useRef(0);
|
|
7119
|
+
const inertiaLastTimeRef = React25.useRef(0);
|
|
7120
|
+
const moveSamplesRef = React25.useRef([]);
|
|
7113
7121
|
const loop = true;
|
|
7114
7122
|
const ui = React25.useMemo(() => {
|
|
7115
7123
|
if (size === "sm") {
|
|
@@ -7180,6 +7188,10 @@ function WheelColumn({
|
|
|
7180
7188
|
window.clearTimeout(scrollEndTimeoutRef.current);
|
|
7181
7189
|
scrollEndTimeoutRef.current = null;
|
|
7182
7190
|
}
|
|
7191
|
+
if (inertiaRafRef.current != null) {
|
|
7192
|
+
cancelAnimationFrame(inertiaRafRef.current);
|
|
7193
|
+
inertiaRafRef.current = null;
|
|
7194
|
+
}
|
|
7183
7195
|
cancelAnimationFrame(rafRef.current);
|
|
7184
7196
|
};
|
|
7185
7197
|
}, [animate, baseOffset, extendedItems.length, getNearestVirtualIndex, itemHeight, loop, scrollRef, valueIndex]);
|
|
@@ -7277,6 +7289,138 @@ function WheelColumn({
|
|
|
7277
7289
|
const from = lastVirtualIndexRef.current ?? fallback;
|
|
7278
7290
|
return getNearestVirtualIndex(valueIndex, from);
|
|
7279
7291
|
}, [baseOffset, getNearestVirtualIndex, items.length, loop, valueIndex]);
|
|
7292
|
+
const commitFromScrollTop = React25.useCallback(
|
|
7293
|
+
(behavior) => {
|
|
7294
|
+
const el = scrollRef.current;
|
|
7295
|
+
if (!el) return;
|
|
7296
|
+
if (items.length <= 0) return;
|
|
7297
|
+
const len = items.length;
|
|
7298
|
+
const maxVirtual = Math.max(0, extendedItems.length - 1);
|
|
7299
|
+
const idxVirtual = clamp3(Math.round(el.scrollTop / itemHeight), 0, maxVirtual);
|
|
7300
|
+
const realIndex = (idxVirtual % len + len) % len;
|
|
7301
|
+
const snappedVirtual = loop ? getNearestVirtualIndex(realIndex, idxVirtual) : realIndex;
|
|
7302
|
+
lastVirtualIndexRef.current = snappedVirtual;
|
|
7303
|
+
suppressScrollSelectUntilRef.current = Date.now() + 350;
|
|
7304
|
+
if (behavior === "auto") el.scrollTop = snappedVirtual * itemHeight;
|
|
7305
|
+
else el.scrollTo({ top: snappedVirtual * itemHeight, behavior });
|
|
7306
|
+
onSelect(items[realIndex]);
|
|
7307
|
+
if (loop) {
|
|
7308
|
+
const min = len;
|
|
7309
|
+
const max = len * 2 - 1;
|
|
7310
|
+
let centered = snappedVirtual;
|
|
7311
|
+
if (centered < min) centered += len;
|
|
7312
|
+
if (centered > max) centered -= len;
|
|
7313
|
+
if (centered !== snappedVirtual) {
|
|
7314
|
+
lastVirtualIndexRef.current = centered;
|
|
7315
|
+
el.scrollTop = centered * itemHeight;
|
|
7316
|
+
}
|
|
7317
|
+
}
|
|
7318
|
+
},
|
|
7319
|
+
[extendedItems.length, getNearestVirtualIndex, itemHeight, items, loop, onSelect, scrollRef]
|
|
7320
|
+
);
|
|
7321
|
+
const onPointerDown = (e) => {
|
|
7322
|
+
if (e.pointerType !== "mouse") return;
|
|
7323
|
+
if (e.button !== 0) return;
|
|
7324
|
+
const el = scrollRef.current;
|
|
7325
|
+
if (!el) return;
|
|
7326
|
+
e.preventDefault();
|
|
7327
|
+
setFocusedColumn(column);
|
|
7328
|
+
draggingRef.current = true;
|
|
7329
|
+
inertialRef.current = false;
|
|
7330
|
+
if (inertiaRafRef.current != null) {
|
|
7331
|
+
cancelAnimationFrame(inertiaRafRef.current);
|
|
7332
|
+
inertiaRafRef.current = null;
|
|
7333
|
+
}
|
|
7334
|
+
if (scrollEndTimeoutRef.current != null) {
|
|
7335
|
+
window.clearTimeout(scrollEndTimeoutRef.current);
|
|
7336
|
+
scrollEndTimeoutRef.current = null;
|
|
7337
|
+
}
|
|
7338
|
+
dragRef.current = { pointerId: e.pointerId, startY: e.clientY, startScrollTop: el.scrollTop, moved: false };
|
|
7339
|
+
moveSamplesRef.current = [{ t: performance.now(), top: el.scrollTop }];
|
|
7340
|
+
try {
|
|
7341
|
+
el.setPointerCapture(e.pointerId);
|
|
7342
|
+
} catch {
|
|
7343
|
+
}
|
|
7344
|
+
};
|
|
7345
|
+
const onPointerMove = (e) => {
|
|
7346
|
+
const el = scrollRef.current;
|
|
7347
|
+
const drag = dragRef.current;
|
|
7348
|
+
if (!el || !drag) return;
|
|
7349
|
+
if (e.pointerId !== drag.pointerId) return;
|
|
7350
|
+
e.preventDefault();
|
|
7351
|
+
const dy = e.clientY - drag.startY;
|
|
7352
|
+
if (!drag.moved && Math.abs(dy) < 4) return;
|
|
7353
|
+
if (!drag.moved) {
|
|
7354
|
+
drag.moved = true;
|
|
7355
|
+
suppressItemClickUntilRef.current = Date.now() + 400;
|
|
7356
|
+
}
|
|
7357
|
+
suppressScrollSelectUntilRef.current = Date.now() + 500;
|
|
7358
|
+
el.scrollTop = drag.startScrollTop - dy;
|
|
7359
|
+
const now = performance.now();
|
|
7360
|
+
const samples = moveSamplesRef.current;
|
|
7361
|
+
samples.push({ t: now, top: el.scrollTop });
|
|
7362
|
+
while (samples.length > 6 && samples[0] && now - samples[0].t > 120) samples.shift();
|
|
7363
|
+
while (samples.length > 8) samples.shift();
|
|
7364
|
+
if (samples.length >= 2) {
|
|
7365
|
+
const oldest = samples[0];
|
|
7366
|
+
const dt = now - oldest.t;
|
|
7367
|
+
if (dt > 0) inertiaVelocityRef.current = (el.scrollTop - oldest.top) / dt;
|
|
7368
|
+
}
|
|
7369
|
+
};
|
|
7370
|
+
const startInertia = React25.useCallback(() => {
|
|
7371
|
+
const el = scrollRef.current;
|
|
7372
|
+
if (!el) return;
|
|
7373
|
+
if (items.length <= 0) return;
|
|
7374
|
+
inertialRef.current = true;
|
|
7375
|
+
suppressItemClickUntilRef.current = Date.now() + 600;
|
|
7376
|
+
inertiaLastTimeRef.current = performance.now();
|
|
7377
|
+
const len = items.length;
|
|
7378
|
+
const cycle = len * itemHeight;
|
|
7379
|
+
const frictionPerFrame = 0.92;
|
|
7380
|
+
const tick = () => {
|
|
7381
|
+
const now = performance.now();
|
|
7382
|
+
const last = inertiaLastTimeRef.current || now;
|
|
7383
|
+
const dt = Math.min(48, Math.max(0, now - last));
|
|
7384
|
+
inertiaLastTimeRef.current = now;
|
|
7385
|
+
let v = inertiaVelocityRef.current;
|
|
7386
|
+
el.scrollTop += v * dt;
|
|
7387
|
+
if (loop && cycle > 0) {
|
|
7388
|
+
if (el.scrollTop < cycle * 0.5) el.scrollTop += cycle;
|
|
7389
|
+
else if (el.scrollTop > cycle * 2.5) el.scrollTop -= cycle;
|
|
7390
|
+
}
|
|
7391
|
+
const decay = Math.pow(frictionPerFrame, dt / 16);
|
|
7392
|
+
v *= decay;
|
|
7393
|
+
inertiaVelocityRef.current = v;
|
|
7394
|
+
if (Math.abs(v) < 0.03) {
|
|
7395
|
+
inertialRef.current = false;
|
|
7396
|
+
inertiaRafRef.current = null;
|
|
7397
|
+
commitFromScrollTop("smooth");
|
|
7398
|
+
return;
|
|
7399
|
+
}
|
|
7400
|
+
inertiaRafRef.current = requestAnimationFrame(tick);
|
|
7401
|
+
};
|
|
7402
|
+
inertiaRafRef.current = requestAnimationFrame(tick);
|
|
7403
|
+
}, [commitFromScrollTop, itemHeight, items.length, loop, scrollRef]);
|
|
7404
|
+
const endDrag = (pointerId) => {
|
|
7405
|
+
const el = scrollRef.current;
|
|
7406
|
+
const drag = dragRef.current;
|
|
7407
|
+
if (!el || !drag) return;
|
|
7408
|
+
if (pointerId !== drag.pointerId) return;
|
|
7409
|
+
dragRef.current = null;
|
|
7410
|
+
draggingRef.current = false;
|
|
7411
|
+
try {
|
|
7412
|
+
el.releasePointerCapture(pointerId);
|
|
7413
|
+
} catch {
|
|
7414
|
+
}
|
|
7415
|
+
const v = inertiaVelocityRef.current;
|
|
7416
|
+
const shouldFlick = drag.moved && Math.abs(v) >= 0.35;
|
|
7417
|
+
if (shouldFlick) {
|
|
7418
|
+
startInertia();
|
|
7419
|
+
} else {
|
|
7420
|
+
inertialRef.current = false;
|
|
7421
|
+
commitFromScrollTop("smooth");
|
|
7422
|
+
}
|
|
7423
|
+
};
|
|
7280
7424
|
return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("flex-1", ui.columnWidth), children: [
|
|
7281
7425
|
/* @__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
7426
|
/* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "relative rounded-xl bg-muted/30 overflow-hidden", style: { height }, children: [
|
|
@@ -7296,6 +7440,7 @@ function WheelColumn({
|
|
|
7296
7440
|
className: cn(
|
|
7297
7441
|
"h-full overflow-y-auto overscroll-contain snap-y snap-mandatory",
|
|
7298
7442
|
"scrollbar-none",
|
|
7443
|
+
"select-none cursor-grab active:cursor-grabbing",
|
|
7299
7444
|
"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
7445
|
),
|
|
7301
7446
|
style: { paddingTop: paddingY, paddingBottom: paddingY },
|
|
@@ -7304,7 +7449,15 @@ function WheelColumn({
|
|
|
7304
7449
|
tabIndex: focused ? 0 : -1,
|
|
7305
7450
|
onKeyDown: (e) => onKeyDown(e, column),
|
|
7306
7451
|
onFocus: () => setFocusedColumn(column),
|
|
7307
|
-
onScroll:
|
|
7452
|
+
onScroll: () => {
|
|
7453
|
+
if (draggingRef.current) return;
|
|
7454
|
+
if (inertialRef.current) return;
|
|
7455
|
+
handleScroll();
|
|
7456
|
+
},
|
|
7457
|
+
onPointerDown,
|
|
7458
|
+
onPointerMove,
|
|
7459
|
+
onPointerUp: (e) => endDrag(e.pointerId),
|
|
7460
|
+
onPointerCancel: (e) => endDrag(e.pointerId),
|
|
7308
7461
|
children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { children: extendedItems.map((n, index) => {
|
|
7309
7462
|
const dist = Math.abs(index - currentVirtual);
|
|
7310
7463
|
const distForVisual = Math.min(dist, 2);
|
|
@@ -7329,6 +7482,7 @@ function WheelColumn({
|
|
|
7329
7482
|
opacity
|
|
7330
7483
|
},
|
|
7331
7484
|
onClick: () => {
|
|
7485
|
+
if (Date.now() < suppressItemClickUntilRef.current) return;
|
|
7332
7486
|
const el = scrollRef.current;
|
|
7333
7487
|
if (!el) return;
|
|
7334
7488
|
suppressScrollSelectUntilRef.current = Date.now() + 350;
|
|
@@ -11320,16 +11474,22 @@ var SIZE_STYLES = {
|
|
|
11320
11474
|
container: "py-3"
|
|
11321
11475
|
}
|
|
11322
11476
|
};
|
|
11477
|
+
var clamp5 = (n, min, max) => Math.min(max, Math.max(min, n));
|
|
11323
11478
|
var Slider = React34.forwardRef(
|
|
11324
11479
|
({
|
|
11325
11480
|
className,
|
|
11481
|
+
mode = "single",
|
|
11326
11482
|
value,
|
|
11327
11483
|
defaultValue = 0,
|
|
11484
|
+
rangeValue,
|
|
11485
|
+
defaultRangeValue,
|
|
11328
11486
|
min = 0,
|
|
11329
11487
|
max = 100,
|
|
11330
11488
|
step = 1,
|
|
11331
11489
|
onChange,
|
|
11332
11490
|
onValueChange,
|
|
11491
|
+
onRangeChange,
|
|
11492
|
+
onRangeValueChange,
|
|
11333
11493
|
onMouseUp,
|
|
11334
11494
|
onTouchEnd,
|
|
11335
11495
|
label,
|
|
@@ -11346,20 +11506,125 @@ var Slider = React34.forwardRef(
|
|
|
11346
11506
|
noFocus = true,
|
|
11347
11507
|
...props
|
|
11348
11508
|
}, ref) => {
|
|
11509
|
+
const isRange = mode === "range";
|
|
11510
|
+
const trackRef = React34.useRef(null);
|
|
11349
11511
|
const [internalValue, setInternalValue] = React34.useState(defaultValue);
|
|
11512
|
+
const [internalRange, setInternalRange] = React34.useState(() => {
|
|
11513
|
+
if (defaultRangeValue) return defaultRangeValue;
|
|
11514
|
+
const v = clamp5(defaultValue, min, max);
|
|
11515
|
+
return [min, v];
|
|
11516
|
+
});
|
|
11517
|
+
const [activeThumb, setActiveThumb] = React34.useState(null);
|
|
11518
|
+
const dragRef = React34.useRef(null);
|
|
11350
11519
|
const isControlled = value !== void 0;
|
|
11351
11520
|
const currentValue = isControlled ? value : internalValue;
|
|
11352
|
-
const
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11521
|
+
const isRangeControlled = rangeValue !== void 0;
|
|
11522
|
+
const currentRange = isRangeControlled ? rangeValue : internalRange;
|
|
11523
|
+
const rangeMin = clamp5(currentRange[0] ?? min, min, max);
|
|
11524
|
+
const rangeMax = clamp5(currentRange[1] ?? max, min, max);
|
|
11525
|
+
const normalizedRange = rangeMin <= rangeMax ? [rangeMin, rangeMax] : [rangeMax, rangeMin];
|
|
11526
|
+
const handleSingleChange = React34.useCallback(
|
|
11527
|
+
(e) => {
|
|
11528
|
+
const newValue = Number(e.target.value);
|
|
11529
|
+
if (!isControlled) {
|
|
11530
|
+
setInternalValue(newValue);
|
|
11531
|
+
}
|
|
11532
|
+
onChange?.(newValue);
|
|
11533
|
+
onValueChange?.(newValue);
|
|
11534
|
+
},
|
|
11535
|
+
[isControlled, onChange, onValueChange]
|
|
11536
|
+
);
|
|
11537
|
+
const emitRange = React34.useCallback(
|
|
11538
|
+
(next) => {
|
|
11539
|
+
onRangeChange?.(next);
|
|
11540
|
+
onRangeValueChange?.(next);
|
|
11541
|
+
},
|
|
11542
|
+
[onRangeChange, onRangeValueChange]
|
|
11543
|
+
);
|
|
11544
|
+
const handleRangeChange = React34.useCallback(
|
|
11545
|
+
(thumb) => (e) => {
|
|
11546
|
+
const nextVal = Number(e.target.value);
|
|
11547
|
+
const [curMin, curMax] = normalizedRange;
|
|
11548
|
+
const next = thumb === "min" ? [Math.min(nextVal, curMax), curMax] : [curMin, Math.max(nextVal, curMin)];
|
|
11549
|
+
if (!isRangeControlled) setInternalRange(next);
|
|
11550
|
+
emitRange(next);
|
|
11551
|
+
},
|
|
11552
|
+
[emitRange, isRangeControlled, normalizedRange]
|
|
11553
|
+
);
|
|
11554
|
+
const denom = Math.max(1e-9, max - min);
|
|
11555
|
+
const percentage = (currentValue - min) / denom * 100;
|
|
11556
|
+
const rangeStartPct = (normalizedRange[0] - min) / denom * 100;
|
|
11557
|
+
const rangeEndPct = (normalizedRange[1] - min) / denom * 100;
|
|
11558
|
+
const sizeStyles8 = SIZE_STYLES[size];
|
|
11559
|
+
const displayValue = React34.useMemo(() => {
|
|
11560
|
+
if (isRange) {
|
|
11561
|
+
const a = formatValue ? formatValue(normalizedRange[0]) : normalizedRange[0].toString();
|
|
11562
|
+
const b = formatValue ? formatValue(normalizedRange[1]) : normalizedRange[1].toString();
|
|
11563
|
+
return `${a} \u2013 ${b}`;
|
|
11564
|
+
}
|
|
11565
|
+
return formatValue ? formatValue(currentValue) : currentValue.toString();
|
|
11566
|
+
}, [currentValue, formatValue, isRange, normalizedRange]);
|
|
11567
|
+
const quantize = React34.useCallback(
|
|
11568
|
+
(v) => {
|
|
11569
|
+
const stepped = Math.round((v - min) / step) * step + min;
|
|
11570
|
+
const fixed = Number(stepped.toFixed(10));
|
|
11571
|
+
return clamp5(fixed, min, max);
|
|
11572
|
+
},
|
|
11573
|
+
[max, min, step]
|
|
11574
|
+
);
|
|
11575
|
+
const valueFromClientX = React34.useCallback(
|
|
11576
|
+
(clientX) => {
|
|
11577
|
+
const el = trackRef.current;
|
|
11578
|
+
if (!el) return min;
|
|
11579
|
+
const rect = el.getBoundingClientRect();
|
|
11580
|
+
const x = clamp5(clientX - rect.left, 0, rect.width);
|
|
11581
|
+
const ratio = rect.width <= 0 ? 0 : x / rect.width;
|
|
11582
|
+
return quantize(min + ratio * (max - min));
|
|
11583
|
+
},
|
|
11584
|
+
[max, min, quantize]
|
|
11585
|
+
);
|
|
11586
|
+
const startRangeDrag = (e) => {
|
|
11587
|
+
if (!isRange) return;
|
|
11588
|
+
if (disabled) return;
|
|
11589
|
+
if (orientation !== "horizontal") return;
|
|
11590
|
+
if (e.button !== 0) return;
|
|
11591
|
+
const nextValue = valueFromClientX(e.clientX);
|
|
11592
|
+
const [curMin, curMax] = normalizedRange;
|
|
11593
|
+
const distToMin = Math.abs(nextValue - curMin);
|
|
11594
|
+
const distToMax = Math.abs(nextValue - curMax);
|
|
11595
|
+
const thumb = distToMin <= distToMax ? "min" : "max";
|
|
11596
|
+
setActiveThumb(thumb);
|
|
11597
|
+
dragRef.current = { pointerId: e.pointerId, thumb };
|
|
11598
|
+
try {
|
|
11599
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
11600
|
+
} catch {
|
|
11601
|
+
}
|
|
11602
|
+
const next = thumb === "min" ? [Math.min(nextValue, curMax), curMax] : [curMin, Math.max(nextValue, curMin)];
|
|
11603
|
+
if (!isRangeControlled) setInternalRange(next);
|
|
11604
|
+
emitRange(next);
|
|
11605
|
+
};
|
|
11606
|
+
const moveRangeDrag = (e) => {
|
|
11607
|
+
const drag = dragRef.current;
|
|
11608
|
+
if (!drag) return;
|
|
11609
|
+
if (e.pointerId !== drag.pointerId) return;
|
|
11610
|
+
const nextValue = valueFromClientX(e.clientX);
|
|
11611
|
+
const [curMin, curMax] = normalizedRange;
|
|
11612
|
+
const next = drag.thumb === "min" ? [Math.min(nextValue, curMax), curMax] : [curMin, Math.max(nextValue, curMin)];
|
|
11613
|
+
if (!isRangeControlled) setInternalRange(next);
|
|
11614
|
+
emitRange(next);
|
|
11615
|
+
};
|
|
11616
|
+
const endRangeDrag = (e) => {
|
|
11617
|
+
const drag = dragRef.current;
|
|
11618
|
+
if (!drag) return;
|
|
11619
|
+
if (e.pointerId !== drag.pointerId) return;
|
|
11620
|
+
dragRef.current = null;
|
|
11621
|
+
onMouseUp?.();
|
|
11622
|
+
onTouchEnd?.();
|
|
11623
|
+
try {
|
|
11624
|
+
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
11625
|
+
} catch {
|
|
11356
11626
|
}
|
|
11357
|
-
onChange?.(newValue);
|
|
11358
|
-
onValueChange?.(newValue);
|
|
11359
11627
|
};
|
|
11360
|
-
const percentage = (currentValue - min) / (max - min) * 100;
|
|
11361
|
-
const sizeStyles8 = SIZE_STYLES[size];
|
|
11362
|
-
const displayValue = formatValue ? formatValue(currentValue) : currentValue.toString();
|
|
11363
11628
|
if (orientation === "vertical") {
|
|
11364
11629
|
}
|
|
11365
11630
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: cn("w-full space-y-2", containerClassName), children: [
|
|
@@ -11367,65 +11632,129 @@ var Slider = React34.forwardRef(
|
|
|
11367
11632
|
label && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("label", { className: cn("text-sm font-medium text-foreground", labelClassName), children: label }),
|
|
11368
11633
|
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
11634
|
] }),
|
|
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",
|
|
11635
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { ref: trackRef, className: cn("relative flex items-center", sizeStyles8.container), children: [
|
|
11636
|
+
/* @__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)(
|
|
11637
|
+
"div",
|
|
11374
11638
|
{
|
|
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
|
|
11639
|
+
className: "absolute top-0 h-full bg-primary rounded-full",
|
|
11640
|
+
style: { left: `${rangeStartPct}%`, width: `${Math.max(0, rangeEndPct - rangeStartPct)}%` }
|
|
11427
11641
|
}
|
|
11428
|
-
)
|
|
11642
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "absolute left-0 top-0 h-full bg-primary rounded-full", style: { width: `${percentage}%` } }) }),
|
|
11643
|
+
(() => {
|
|
11644
|
+
const baseInputClassName = cn(
|
|
11645
|
+
// Base styles
|
|
11646
|
+
"absolute w-full h-full appearance-none bg-transparent cursor-pointer",
|
|
11647
|
+
!noFocus && "focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-background rounded-full",
|
|
11648
|
+
noFocus && "outline-none ring-0 focus:outline-none focus:ring-0 focus-visible:outline-none",
|
|
11649
|
+
// Webkit styles for thumb
|
|
11650
|
+
"[&::-webkit-slider-thumb]:appearance-none",
|
|
11651
|
+
"[&::-webkit-slider-thumb]:bg-primary",
|
|
11652
|
+
"[&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-background",
|
|
11653
|
+
"[&::-webkit-slider-thumb]:rounded-full",
|
|
11654
|
+
"[&::-webkit-slider-thumb]:shadow-md",
|
|
11655
|
+
"[&::-webkit-slider-thumb]:cursor-pointer",
|
|
11656
|
+
"[&::-webkit-slider-thumb]:transition-all [&::-webkit-slider-thumb]:duration-150",
|
|
11657
|
+
size === "sm" && "[&::-webkit-slider-thumb]:w-3 [&::-webkit-slider-thumb]:h-3",
|
|
11658
|
+
size === "md" && "[&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:h-4",
|
|
11659
|
+
size === "lg" && "[&::-webkit-slider-thumb]:w-5 [&::-webkit-slider-thumb]:h-5",
|
|
11660
|
+
// Firefox styles for thumb
|
|
11661
|
+
"[&::-moz-range-thumb]:bg-primary",
|
|
11662
|
+
"[&::-moz-range-thumb]:border-2 [&::-moz-range-thumb]:border-background",
|
|
11663
|
+
"[&::-moz-range-thumb]:rounded-full",
|
|
11664
|
+
"[&::-moz-range-thumb]:shadow-md",
|
|
11665
|
+
"[&::-moz-range-thumb]:cursor-pointer",
|
|
11666
|
+
"[&::-moz-range-thumb]:transition-all [&::-moz-range-thumb]:duration-150",
|
|
11667
|
+
size === "sm" && "[&::-moz-range-thumb]:w-3 [&::-moz-range-thumb]:h-3",
|
|
11668
|
+
size === "md" && "[&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:h-4",
|
|
11669
|
+
size === "lg" && "[&::-moz-range-thumb]:w-5 [&::-moz-range-thumb]:h-5",
|
|
11670
|
+
// Remove default track in Firefox
|
|
11671
|
+
"[&::-moz-range-track]:bg-transparent",
|
|
11672
|
+
"[&::-moz-range-track]:border-transparent",
|
|
11673
|
+
// Hover effects
|
|
11674
|
+
"hover:[&::-webkit-slider-thumb]:scale-110 hover:[&::-webkit-slider-thumb]:shadow-lg",
|
|
11675
|
+
"hover:[&::-moz-range-thumb]:scale-110 hover:[&::-moz-range-thumb]:shadow-lg",
|
|
11676
|
+
// Disabled styles
|
|
11677
|
+
disabled && [
|
|
11678
|
+
"cursor-not-allowed opacity-50",
|
|
11679
|
+
"[&::-webkit-slider-thumb]:cursor-not-allowed [&::-webkit-slider-thumb]:opacity-50",
|
|
11680
|
+
"[&::-moz-range-thumb]:cursor-not-allowed [&::-moz-range-thumb]:opacity-50"
|
|
11681
|
+
],
|
|
11682
|
+
className,
|
|
11683
|
+
thumbClassName
|
|
11684
|
+
);
|
|
11685
|
+
if (!isRange) {
|
|
11686
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
11687
|
+
"input",
|
|
11688
|
+
{
|
|
11689
|
+
ref,
|
|
11690
|
+
type: "range",
|
|
11691
|
+
min,
|
|
11692
|
+
max,
|
|
11693
|
+
step,
|
|
11694
|
+
value: currentValue,
|
|
11695
|
+
onChange: handleSingleChange,
|
|
11696
|
+
onMouseUp,
|
|
11697
|
+
onTouchEnd,
|
|
11698
|
+
disabled,
|
|
11699
|
+
className: baseInputClassName,
|
|
11700
|
+
...props
|
|
11701
|
+
}
|
|
11702
|
+
);
|
|
11703
|
+
}
|
|
11704
|
+
const minZ = activeThumb === "min" ? "z-20" : "z-10";
|
|
11705
|
+
const maxZ = activeThumb === "max" ? "z-20" : "z-10";
|
|
11706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_jsx_runtime41.Fragment, { children: [
|
|
11707
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
11708
|
+
"div",
|
|
11709
|
+
{
|
|
11710
|
+
className: cn("absolute inset-0 z-30", disabled ? "cursor-not-allowed" : "cursor-pointer"),
|
|
11711
|
+
onPointerDown: startRangeDrag,
|
|
11712
|
+
onPointerMove: moveRangeDrag,
|
|
11713
|
+
onPointerUp: endRangeDrag,
|
|
11714
|
+
onPointerCancel: endRangeDrag
|
|
11715
|
+
}
|
|
11716
|
+
),
|
|
11717
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
11718
|
+
"input",
|
|
11719
|
+
{
|
|
11720
|
+
ref,
|
|
11721
|
+
type: "range",
|
|
11722
|
+
min,
|
|
11723
|
+
max,
|
|
11724
|
+
step,
|
|
11725
|
+
value: normalizedRange[0],
|
|
11726
|
+
onChange: handleRangeChange("min"),
|
|
11727
|
+
onMouseUp,
|
|
11728
|
+
onTouchEnd,
|
|
11729
|
+
disabled,
|
|
11730
|
+
"aria-label": "Minimum value",
|
|
11731
|
+
onPointerDown: () => setActiveThumb("min"),
|
|
11732
|
+
onFocus: () => setActiveThumb("min"),
|
|
11733
|
+
className: cn(baseInputClassName, minZ, "pointer-events-none"),
|
|
11734
|
+
...props
|
|
11735
|
+
}
|
|
11736
|
+
),
|
|
11737
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
11738
|
+
"input",
|
|
11739
|
+
{
|
|
11740
|
+
type: "range",
|
|
11741
|
+
min,
|
|
11742
|
+
max,
|
|
11743
|
+
step,
|
|
11744
|
+
value: normalizedRange[1],
|
|
11745
|
+
onChange: handleRangeChange("max"),
|
|
11746
|
+
onMouseUp,
|
|
11747
|
+
onTouchEnd,
|
|
11748
|
+
disabled,
|
|
11749
|
+
"aria-label": "Maximum value",
|
|
11750
|
+
onPointerDown: () => setActiveThumb("max"),
|
|
11751
|
+
onFocus: () => setActiveThumb("max"),
|
|
11752
|
+
className: cn(baseInputClassName, maxZ, "pointer-events-none"),
|
|
11753
|
+
...props
|
|
11754
|
+
}
|
|
11755
|
+
)
|
|
11756
|
+
] });
|
|
11757
|
+
})()
|
|
11429
11758
|
] })
|
|
11430
11759
|
] });
|
|
11431
11760
|
}
|
|
@@ -13691,7 +14020,7 @@ var Timeline_default = Timeline;
|
|
|
13691
14020
|
var React42 = __toESM(require("react"), 1);
|
|
13692
14021
|
var import_lucide_react29 = require("lucide-react");
|
|
13693
14022
|
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
13694
|
-
var
|
|
14023
|
+
var clamp6 = (n, min, max) => Math.max(min, Math.min(max, n));
|
|
13695
14024
|
function hexToRgb(hex) {
|
|
13696
14025
|
const str = hex.replace(/^#/, "").trim();
|
|
13697
14026
|
if (str.length === 3) {
|
|
@@ -13709,7 +14038,7 @@ function hexToRgb(hex) {
|
|
|
13709
14038
|
return null;
|
|
13710
14039
|
}
|
|
13711
14040
|
function rgbToHex(r, g, b) {
|
|
13712
|
-
return `#${[r, g, b].map((v) =>
|
|
14041
|
+
return `#${[r, g, b].map((v) => clamp6(Math.round(v), 0, 255).toString(16).padStart(2, "0")).join("")}`;
|
|
13713
14042
|
}
|
|
13714
14043
|
function rgbToHsl(r, g, b) {
|
|
13715
14044
|
r /= 255;
|
|
@@ -13770,10 +14099,10 @@ function parseAnyColor(input) {
|
|
|
13770
14099
|
}
|
|
13771
14100
|
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
14101
|
if (rgbaMatch) {
|
|
13773
|
-
const r =
|
|
13774
|
-
const g =
|
|
13775
|
-
const b =
|
|
13776
|
-
const a = rgbaMatch[4] != null ?
|
|
14102
|
+
const r = clamp6(parseInt(rgbaMatch[1], 10), 0, 255);
|
|
14103
|
+
const g = clamp6(parseInt(rgbaMatch[2], 10), 0, 255);
|
|
14104
|
+
const b = clamp6(parseInt(rgbaMatch[3], 10), 0, 255);
|
|
14105
|
+
const a = rgbaMatch[4] != null ? clamp6(parseFloat(rgbaMatch[4]), 0, 1) : 1;
|
|
13777
14106
|
return { r, g, b, a };
|
|
13778
14107
|
}
|
|
13779
14108
|
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 +14110,7 @@ function parseAnyColor(input) {
|
|
|
13781
14110
|
const h = parseFloat(hslaMatch[1]);
|
|
13782
14111
|
const sl = parseFloat(hslaMatch[2]);
|
|
13783
14112
|
const l = parseFloat(hslaMatch[3]);
|
|
13784
|
-
const a = hslaMatch[4] != null ?
|
|
14113
|
+
const a = hslaMatch[4] != null ? clamp6(parseFloat(hslaMatch[4]), 0, 1) : 1;
|
|
13785
14114
|
const rgb = hslToRgb(h, sl, l);
|
|
13786
14115
|
return { ...rgb, a };
|
|
13787
14116
|
}
|
|
@@ -13794,12 +14123,12 @@ function formatOutput({ r, g, b, a }, withAlpha, format) {
|
|
|
13794
14123
|
if (format === "hsl" || format === "hsla") {
|
|
13795
14124
|
const hsl = rgbToHsl(r, g, b);
|
|
13796
14125
|
if (format === "hsla" || withAlpha) {
|
|
13797
|
-
return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${
|
|
14126
|
+
return `hsla(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%, ${clamp6(a, 0, 1)})`;
|
|
13798
14127
|
}
|
|
13799
14128
|
return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s)}%, ${Math.round(hsl.l)}%)`;
|
|
13800
14129
|
}
|
|
13801
14130
|
if (withAlpha || a !== 1) {
|
|
13802
|
-
return `rgba(${
|
|
14131
|
+
return `rgba(${clamp6(r, 0, 255)}, ${clamp6(g, 0, 255)}, ${clamp6(b, 0, 255)}, ${clamp6(a, 0, 1)})`;
|
|
13803
14132
|
}
|
|
13804
14133
|
return rgbToHex(r, g, b);
|
|
13805
14134
|
}
|
|
@@ -13933,7 +14262,7 @@ function ColorPicker({
|
|
|
13933
14262
|
emit(next);
|
|
13934
14263
|
};
|
|
13935
14264
|
const setAlpha = (aPct) => {
|
|
13936
|
-
const a =
|
|
14265
|
+
const a = clamp6(aPct / 100, 0, 1);
|
|
13937
14266
|
const next = { ...rgba, a };
|
|
13938
14267
|
setRgba(next);
|
|
13939
14268
|
emit(next);
|
|
@@ -18594,7 +18923,7 @@ function toNullableNumber(value) {
|
|
|
18594
18923
|
}
|
|
18595
18924
|
return null;
|
|
18596
18925
|
}
|
|
18597
|
-
function
|
|
18926
|
+
function clamp7(value, min, max) {
|
|
18598
18927
|
return Math.min(max, Math.max(min, value));
|
|
18599
18928
|
}
|
|
18600
18929
|
function ResizableImageNodeView(props) {
|
|
@@ -18656,18 +18985,18 @@ function ResizableImageNodeView(props) {
|
|
|
18656
18985
|
let nextH = drag.startH;
|
|
18657
18986
|
if (event.ctrlKey) {
|
|
18658
18987
|
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
18659
|
-
nextW =
|
|
18660
|
-
nextH =
|
|
18988
|
+
nextW = clamp7(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
18989
|
+
nextH = clamp7(nextW / drag.aspect, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
18661
18990
|
} else {
|
|
18662
|
-
nextH =
|
|
18663
|
-
nextW =
|
|
18991
|
+
nextH = clamp7(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
18992
|
+
nextW = clamp7(nextH * drag.aspect, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
18664
18993
|
}
|
|
18665
18994
|
} else {
|
|
18666
18995
|
if (!drag.axis && (Math.abs(dx) > AXIS_LOCK_THRESHOLD_PX || Math.abs(dy) > AXIS_LOCK_THRESHOLD_PX)) {
|
|
18667
18996
|
drag.axis = Math.abs(dx) >= Math.abs(dy) ? "x" : "y";
|
|
18668
18997
|
}
|
|
18669
|
-
if (drag.axis === "x") nextW =
|
|
18670
|
-
if (drag.axis === "y") nextH =
|
|
18998
|
+
if (drag.axis === "x") nextW = clamp7(drag.startW + dx, MIN_IMAGE_SIZE_PX, drag.maxW);
|
|
18999
|
+
if (drag.axis === "y") nextH = clamp7(drag.startH + dy, MIN_IMAGE_SIZE_PX, Number.POSITIVE_INFINITY);
|
|
18671
19000
|
}
|
|
18672
19001
|
drag.lastW = nextW;
|
|
18673
19002
|
drag.lastH = nextH;
|