@underverse-ui/underverse 0.2.101 → 0.2.103
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 +223 -62
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -1
- package/dist/index.d.ts +25 -1
- package/dist/index.js +223 -62
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -8762,6 +8762,9 @@ function CalendarTimeline({
|
|
|
8762
8762
|
autoRowHeight,
|
|
8763
8763
|
enableLayoutResize,
|
|
8764
8764
|
slotMinWidth,
|
|
8765
|
+
adaptiveSlotWidths,
|
|
8766
|
+
dayEventStyle = "span",
|
|
8767
|
+
dayEventMaxWidth,
|
|
8765
8768
|
dayTimeStepMinutes = 60,
|
|
8766
8769
|
dayRangeMode,
|
|
8767
8770
|
workHours,
|
|
@@ -8950,17 +8953,135 @@ function CalendarTimeline({
|
|
|
8950
8953
|
const headerRef = React28.useRef(null);
|
|
8951
8954
|
const bodyClientWidth = useClientWidth(bodyRef);
|
|
8952
8955
|
const slotStarts = React28.useMemo(() => slots.map((s) => s.start), [slots]);
|
|
8953
|
-
const
|
|
8954
|
-
const baseSlotWidth = activeView === "month"
|
|
8956
|
+
const fixedSlotWidth = React28.useMemo(() => {
|
|
8957
|
+
const baseSlotWidth = activeView === "month" || activeView === "day" ? effectiveSlotMinWidth * 3 : effectiveSlotMinWidth;
|
|
8955
8958
|
if (activeView !== "week") return baseSlotWidth;
|
|
8956
8959
|
if (bodyClientWidth <= 0) return baseSlotWidth;
|
|
8957
8960
|
if (slots.length <= 0) return baseSlotWidth;
|
|
8958
8961
|
return Math.max(baseSlotWidth, bodyClientWidth / slots.length);
|
|
8959
8962
|
}, [activeView, bodyClientWidth, effectiveSlotMinWidth, slots.length]);
|
|
8960
|
-
const gridWidth = slots.length * slotWidth;
|
|
8961
8963
|
const normalizedEvents = React28.useMemo(() => {
|
|
8962
8964
|
return normalizeEvents({ events, range, view: activeView, timeZone: resolvedTimeZone });
|
|
8963
8965
|
}, [events, range, activeView, resolvedTimeZone]);
|
|
8966
|
+
const dayHeaderMarks = React28.useMemo(() => {
|
|
8967
|
+
if (activeView !== "day") return null;
|
|
8968
|
+
const n = slots.length;
|
|
8969
|
+
const showTime = new Array(n).fill(false);
|
|
8970
|
+
const showEllipsis = new Array(n).fill(false);
|
|
8971
|
+
for (const ev of normalizedEvents) {
|
|
8972
|
+
const startIdx = binarySearchLastLE(slotStarts, ev._start);
|
|
8973
|
+
const endIdxRaw = binarySearchFirstGE(slotStarts, ev._end);
|
|
8974
|
+
const endIdx = clamp3(endIdxRaw, 0, n - 1);
|
|
8975
|
+
if (startIdx >= 0 && startIdx < n) showTime[startIdx] = true;
|
|
8976
|
+
if (endIdx >= 0 && endIdx < n) showTime[endIdx] = true;
|
|
8977
|
+
const span = endIdx - startIdx;
|
|
8978
|
+
if (span >= 3) {
|
|
8979
|
+
const mid = clamp3(Math.floor((startIdx + endIdx) / 2), 0, n - 1);
|
|
8980
|
+
if (!showTime[mid]) showEllipsis[mid] = true;
|
|
8981
|
+
}
|
|
8982
|
+
}
|
|
8983
|
+
const anchor = showTime.map((v, i) => v || showEllipsis[i]);
|
|
8984
|
+
return { showTime, showEllipsis, anchor };
|
|
8985
|
+
}, [activeView, normalizedEvents, slotStarts, slots.length]);
|
|
8986
|
+
const slotMetrics = React28.useMemo(() => {
|
|
8987
|
+
const n = slots.length;
|
|
8988
|
+
const widths = new Array(n).fill(fixedSlotWidth);
|
|
8989
|
+
const isAdaptiveView = activeView === "month" || activeView === "day";
|
|
8990
|
+
const adaptiveCfg = adaptiveSlotWidths;
|
|
8991
|
+
const adaptiveEnabled = Boolean(adaptiveCfg) && isAdaptiveView;
|
|
8992
|
+
if (!adaptiveEnabled || n === 0) {
|
|
8993
|
+
const lefts2 = new Array(n + 1);
|
|
8994
|
+
lefts2[0] = 0;
|
|
8995
|
+
for (let i = 0; i < n; i++) lefts2[i + 1] = lefts2[i] + widths[i];
|
|
8996
|
+
const gridWidth3 = lefts2[n] ?? 0;
|
|
8997
|
+
const xToSlotIdx3 = (x) => clamp3(Math.floor(x / Math.max(1, fixedSlotWidth)), 0, Math.max(0, n - 1));
|
|
8998
|
+
return { slotWidths: widths, slotLefts: lefts2, slotHasEvent: null, gridWidth: gridWidth3, xToSlotIdx: xToSlotIdx3 };
|
|
8999
|
+
}
|
|
9000
|
+
const cfg = typeof adaptiveCfg === "object" ? adaptiveCfg : {};
|
|
9001
|
+
const mode = cfg.mode ?? "shrink";
|
|
9002
|
+
const defaultEmptySlotWidth = Math.max(18, Math.round(effectiveSlotMinWidth * 0.6));
|
|
9003
|
+
const minEmptySlotWidth = activeView === "month" ? Math.max(24, Math.round(effectiveSlotMinWidth * 0.45)) : 12;
|
|
9004
|
+
const emptySlotWidth = Math.max(minEmptySlotWidth, Math.min(fixedSlotWidth, cfg.emptySlotWidth ?? defaultEmptySlotWidth));
|
|
9005
|
+
const dayAnchorCompression = activeView === "day" && Boolean(dayHeaderMarks?.anchor);
|
|
9006
|
+
if (dayAnchorCompression) {
|
|
9007
|
+
const hasEvent2 = dayHeaderMarks.anchor.slice(0, n);
|
|
9008
|
+
const compressedEmptySlotWidth = clamp3(emptySlotWidth, 12, 20);
|
|
9009
|
+
for (let i = 0; i < n; i++) widths[i] = hasEvent2[i] ? fixedSlotWidth : compressedEmptySlotWidth;
|
|
9010
|
+
const lefts2 = new Array(n + 1);
|
|
9011
|
+
lefts2[0] = 0;
|
|
9012
|
+
for (let i = 0; i < n; i++) lefts2[i + 1] = lefts2[i] + widths[i];
|
|
9013
|
+
const gridWidth3 = lefts2[n] ?? 0;
|
|
9014
|
+
const xToSlotIdx3 = (x) => {
|
|
9015
|
+
const xc = clamp3(x, 0, Math.max(0, gridWidth3 - 1e-3));
|
|
9016
|
+
let lo = 0;
|
|
9017
|
+
let hi = n - 1;
|
|
9018
|
+
while (lo <= hi) {
|
|
9019
|
+
const mid = lo + hi >> 1;
|
|
9020
|
+
const left = lefts2[mid] ?? 0;
|
|
9021
|
+
const right = lefts2[mid + 1] ?? gridWidth3;
|
|
9022
|
+
if (xc < left) hi = mid - 1;
|
|
9023
|
+
else if (xc >= right) lo = mid + 1;
|
|
9024
|
+
else return mid;
|
|
9025
|
+
}
|
|
9026
|
+
return clamp3(lo, 0, Math.max(0, n - 1));
|
|
9027
|
+
};
|
|
9028
|
+
return { slotWidths: widths, slotLefts: lefts2, slotHasEvent: hasEvent2, gridWidth: gridWidth3, xToSlotIdx: xToSlotIdx3 };
|
|
9029
|
+
}
|
|
9030
|
+
const diff = new Array(n + 1).fill(0);
|
|
9031
|
+
for (const ev of normalizedEvents) {
|
|
9032
|
+
const startIdx = binarySearchLastLE(slotStarts, ev._start);
|
|
9033
|
+
const endIdx = clamp3(binarySearchFirstGE(slotStarts, ev._end), startIdx + 1, n);
|
|
9034
|
+
diff[startIdx] = (diff[startIdx] ?? 0) + 1;
|
|
9035
|
+
diff[endIdx] = (diff[endIdx] ?? 0) - 1;
|
|
9036
|
+
}
|
|
9037
|
+
const hasEvent = new Array(n);
|
|
9038
|
+
let running = 0;
|
|
9039
|
+
let eventCount = 0;
|
|
9040
|
+
for (let i = 0; i < n; i++) {
|
|
9041
|
+
running += diff[i] ?? 0;
|
|
9042
|
+
const covered = running > 0;
|
|
9043
|
+
hasEvent[i] = covered;
|
|
9044
|
+
if (covered) eventCount++;
|
|
9045
|
+
}
|
|
9046
|
+
if (eventCount === 0 || eventCount === n) {
|
|
9047
|
+
const lefts2 = new Array(n + 1);
|
|
9048
|
+
lefts2[0] = 0;
|
|
9049
|
+
for (let i = 0; i < n; i++) lefts2[i + 1] = lefts2[i] + widths[i];
|
|
9050
|
+
const gridWidth3 = lefts2[n] ?? 0;
|
|
9051
|
+
const xToSlotIdx3 = (x) => clamp3(Math.floor(x / Math.max(1, fixedSlotWidth)), 0, Math.max(0, n - 1));
|
|
9052
|
+
return { slotWidths: widths, slotLefts: lefts2, slotHasEvent: null, gridWidth: gridWidth3, xToSlotIdx: xToSlotIdx3 };
|
|
9053
|
+
}
|
|
9054
|
+
const emptyCount = n - eventCount;
|
|
9055
|
+
let eventSlotWidth = fixedSlotWidth;
|
|
9056
|
+
if (mode === "redistribute") {
|
|
9057
|
+
const targetTotal = n * fixedSlotWidth;
|
|
9058
|
+
const remaining = Math.max(0, targetTotal - emptyCount * emptySlotWidth);
|
|
9059
|
+
const raw = remaining / Math.max(1, eventCount);
|
|
9060
|
+
const maxEventSlotWidth = cfg.maxEventSlotWidth ?? fixedSlotWidth * 2.5;
|
|
9061
|
+
eventSlotWidth = clamp3(raw, fixedSlotWidth, Math.max(fixedSlotWidth, maxEventSlotWidth));
|
|
9062
|
+
}
|
|
9063
|
+
for (let i = 0; i < n; i++) widths[i] = hasEvent[i] ? eventSlotWidth : emptySlotWidth;
|
|
9064
|
+
const lefts = new Array(n + 1);
|
|
9065
|
+
lefts[0] = 0;
|
|
9066
|
+
for (let i = 0; i < n; i++) lefts[i + 1] = lefts[i] + widths[i];
|
|
9067
|
+
const gridWidth2 = lefts[n] ?? 0;
|
|
9068
|
+
const xToSlotIdx2 = (x) => {
|
|
9069
|
+
const xc = clamp3(x, 0, Math.max(0, gridWidth2 - 1e-3));
|
|
9070
|
+
let lo = 0;
|
|
9071
|
+
let hi = n - 1;
|
|
9072
|
+
while (lo <= hi) {
|
|
9073
|
+
const mid = lo + hi >> 1;
|
|
9074
|
+
const left = lefts[mid] ?? 0;
|
|
9075
|
+
const right = lefts[mid + 1] ?? gridWidth2;
|
|
9076
|
+
if (xc < left) hi = mid - 1;
|
|
9077
|
+
else if (xc >= right) lo = mid + 1;
|
|
9078
|
+
else return mid;
|
|
9079
|
+
}
|
|
9080
|
+
return clamp3(lo, 0, Math.max(0, n - 1));
|
|
9081
|
+
};
|
|
9082
|
+
return { slotWidths: widths, slotLefts: lefts, slotHasEvent: hasEvent, gridWidth: gridWidth2, xToSlotIdx: xToSlotIdx2 };
|
|
9083
|
+
}, [activeView, adaptiveSlotWidths, dayHeaderMarks, effectiveSlotMinWidth, fixedSlotWidth, normalizedEvents, slotStarts, slots.length]);
|
|
9084
|
+
const { slotWidths, slotLefts, slotHasEvent, gridWidth, xToSlotIdx } = slotMetrics;
|
|
8964
9085
|
const eventsByResource = React28.useMemo(() => {
|
|
8965
9086
|
return eventsByResourceId(normalizedEvents);
|
|
8966
9087
|
}, [normalizedEvents]);
|
|
@@ -9209,7 +9330,20 @@ function CalendarTimeline({
|
|
|
9209
9330
|
setCreateStartIdx(startIdx);
|
|
9210
9331
|
setCreateEndIdx(Math.min(slots.length, startIdx + 1));
|
|
9211
9332
|
setCreateOpen(true);
|
|
9212
|
-
}, [
|
|
9333
|
+
}, [
|
|
9334
|
+
activeDate,
|
|
9335
|
+
activeEventSheetOpen,
|
|
9336
|
+
activeView,
|
|
9337
|
+
canCreate,
|
|
9338
|
+
range.end,
|
|
9339
|
+
range.start,
|
|
9340
|
+
resolvedNow,
|
|
9341
|
+
resolvedTimeZone,
|
|
9342
|
+
resources,
|
|
9343
|
+
setEventSheetOpen,
|
|
9344
|
+
slotStarts,
|
|
9345
|
+
slots.length
|
|
9346
|
+
]);
|
|
9213
9347
|
React28.useEffect(() => {
|
|
9214
9348
|
setCreateEndIdx((prev) => Math.min(slots.length, Math.max(prev, createStartIdx + 1)));
|
|
9215
9349
|
}, [createStartIdx, slots.length]);
|
|
@@ -9262,13 +9396,13 @@ function CalendarTimeline({
|
|
|
9262
9396
|
const el = document.elementFromPoint(probeX, probeY);
|
|
9263
9397
|
const x = probeX - bodyRect.left + body.scrollLeft;
|
|
9264
9398
|
const epsilon = opts?.biasLeft ? 0.01 : 0;
|
|
9265
|
-
const slotIdx =
|
|
9399
|
+
const slotIdx = xToSlotIdx(x - epsilon);
|
|
9266
9400
|
const rowEl = el && body.contains(el) ? el.closest?.("[data-uv-ct-row]") ?? null : null;
|
|
9267
9401
|
const rid = rowEl?.dataset?.uvCtRow ?? opts?.fallbackResourceId ?? null;
|
|
9268
9402
|
if (!rid) return null;
|
|
9269
9403
|
return { slotIdx, resourceId: rid, x };
|
|
9270
9404
|
},
|
|
9271
|
-
[
|
|
9405
|
+
[xToSlotIdx]
|
|
9272
9406
|
);
|
|
9273
9407
|
const slotToDate = React28.useCallback(
|
|
9274
9408
|
(slotIdx) => {
|
|
@@ -9285,7 +9419,11 @@ function CalendarTimeline({
|
|
|
9285
9419
|
(clientX, clientY) => {
|
|
9286
9420
|
const drag = dragRef.current;
|
|
9287
9421
|
if (!drag) return;
|
|
9288
|
-
const ctx = getPointerContext(
|
|
9422
|
+
const ctx = getPointerContext(
|
|
9423
|
+
clientX,
|
|
9424
|
+
clientY,
|
|
9425
|
+
drag.mode === "create" ? { biasLeft: true, fallbackResourceId: drag.resourceId } : { fallbackResourceId: drag.resourceId }
|
|
9426
|
+
);
|
|
9289
9427
|
if (!ctx) return;
|
|
9290
9428
|
const { slotIdx } = ctx;
|
|
9291
9429
|
const movedEnough = Math.abs(clientX - drag.startClientX) > 3 || Math.abs(clientY - drag.startClientY) > 3 || slotIdx !== drag.startSlotIdx || ctx.resourceId !== drag.startRowResourceId;
|
|
@@ -9535,16 +9673,24 @@ function CalendarTimeline({
|
|
|
9535
9673
|
"div",
|
|
9536
9674
|
{
|
|
9537
9675
|
className: cn(
|
|
9538
|
-
"shrink-0 border-l
|
|
9676
|
+
"shrink-0 border-l flex items-center justify-center transition-colors duration-150 overflow-hidden",
|
|
9677
|
+
activeView === "day" && dayHeaderMarks?.anchor ? dayHeaderMarks.anchor[idx] ? "border-border/30" : "border-border/10" : "border-border/30",
|
|
9539
9678
|
sizeConfig.slotHeaderClass,
|
|
9540
|
-
s.isToday && "bg-primary/8 border-l-primary/40"
|
|
9679
|
+
activeView !== "day" && s.isToday && "bg-primary/8 border-l-primary/40"
|
|
9541
9680
|
),
|
|
9542
|
-
style: { width:
|
|
9681
|
+
style: { width: slotWidths[idx], minWidth: slotWidths[idx] },
|
|
9543
9682
|
"aria-label": formatters?.ariaSlotLabel?.(s.start, { view: activeView, locale: resolvedLocale, timeZone: resolvedTimeZone }),
|
|
9544
|
-
children:
|
|
9545
|
-
s.
|
|
9546
|
-
|
|
9547
|
-
|
|
9683
|
+
children: (() => {
|
|
9684
|
+
const label = typeof s.label === "string" || typeof s.label === "number" ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "truncate whitespace-nowrap", children: s.label }) : s.label;
|
|
9685
|
+
if (activeView === "day" && dayHeaderMarks) {
|
|
9686
|
+
if (dayHeaderMarks.showEllipsis[idx]) return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-xs text-muted-foreground/70 select-none", children: "\u2026" });
|
|
9687
|
+
if (!dayHeaderMarks.showTime[idx]) return null;
|
|
9688
|
+
}
|
|
9689
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("flex flex-col items-center min-w-0 overflow-hidden", activeView !== "day" && s.isToday && "relative"), children: [
|
|
9690
|
+
activeView !== "day" && s.isToday && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react20.Dot, { className: "absolute -top-2.5 h-4 w-4 text-primary animate-pulse" }),
|
|
9691
|
+
label
|
|
9692
|
+
] });
|
|
9693
|
+
})()
|
|
9548
9694
|
},
|
|
9549
9695
|
`${s.start.toISOString()}_${idx}`
|
|
9550
9696
|
))
|
|
@@ -9597,14 +9743,25 @@ function CalendarTimeline({
|
|
|
9597
9743
|
visible: visible.map((p) => ({
|
|
9598
9744
|
ev: p.ev,
|
|
9599
9745
|
lane: p.lane,
|
|
9600
|
-
left: p.startIdx
|
|
9601
|
-
width: Math.max(1, (p.endIdx - p.startIdx
|
|
9746
|
+
left: slotLefts[p.startIdx] ?? 0,
|
|
9747
|
+
width: Math.max(1, (slotLefts[p.endIdx] ?? 0) - (slotLefts[p.startIdx] ?? 0))
|
|
9602
9748
|
})),
|
|
9603
9749
|
hidden: hidden.map((h) => h.ev)
|
|
9604
9750
|
});
|
|
9605
9751
|
}
|
|
9606
9752
|
return map;
|
|
9607
|
-
}, [
|
|
9753
|
+
}, [
|
|
9754
|
+
eventsByResource,
|
|
9755
|
+
eventHeight,
|
|
9756
|
+
effectiveMaxLanesPerRow,
|
|
9757
|
+
getResourceRowHeight,
|
|
9758
|
+
laneGap,
|
|
9759
|
+
lanePaddingY,
|
|
9760
|
+
preview,
|
|
9761
|
+
slotLefts,
|
|
9762
|
+
slotStarts,
|
|
9763
|
+
slots.length
|
|
9764
|
+
]);
|
|
9608
9765
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
9609
9766
|
"div",
|
|
9610
9767
|
{
|
|
@@ -9662,7 +9819,13 @@ function CalendarTimeline({
|
|
|
9662
9819
|
const rowIndex = startRow + idx;
|
|
9663
9820
|
const h = rowHeightsArray[rowIndex] ?? effectiveRowHeight;
|
|
9664
9821
|
if (row.kind === "group") {
|
|
9665
|
-
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex", style: { height: h }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
9822
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex", style: { height: h }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
9823
|
+
"div",
|
|
9824
|
+
{
|
|
9825
|
+
className: "border-b border-border/30 bg-linear-to-r from-muted/15 to-muted/5",
|
|
9826
|
+
style: { width: gridWidth, minWidth: gridWidth }
|
|
9827
|
+
}
|
|
9828
|
+
) }, `rg_${row.group.id}_${rowIndex}`);
|
|
9666
9829
|
}
|
|
9667
9830
|
const r = row.resource;
|
|
9668
9831
|
const layout = layoutsByResource.get(r.id) ?? { visible: [], hidden: [], baseTop: lanePaddingY, eventHeight };
|
|
@@ -9680,11 +9843,12 @@ function CalendarTimeline({
|
|
|
9680
9843
|
"div",
|
|
9681
9844
|
{
|
|
9682
9845
|
className: cn(
|
|
9683
|
-
"h-full border-l
|
|
9684
|
-
|
|
9846
|
+
"h-full border-l transition-colors duration-100",
|
|
9847
|
+
activeView === "day" && dayHeaderMarks?.anchor ? !dayHeaderMarks.anchor[i2] ? "border-border/10" : "border-border/20" : "border-border/20",
|
|
9848
|
+
activeView !== "day" && s.isToday && "bg-primary/5 border-l-primary/30",
|
|
9685
9849
|
"hover:bg-muted/10"
|
|
9686
9850
|
),
|
|
9687
|
-
style: { width:
|
|
9851
|
+
style: { width: slotWidths[i2], minWidth: slotWidths[i2] }
|
|
9688
9852
|
},
|
|
9689
9853
|
`${r.id}_${i2}`
|
|
9690
9854
|
)) }) }),
|
|
@@ -9728,28 +9892,17 @@ function CalendarTimeline({
|
|
|
9728
9892
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "text-xs opacity-80", children: timeText }),
|
|
9729
9893
|
resource?.label ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "text-xs opacity-70", children: resource.label }) : null
|
|
9730
9894
|
] });
|
|
9895
|
+
const shouldCompact = activeView === "day" && dayEventStyle === "compact";
|
|
9896
|
+
const defaultMaxVisual = clamp3(Math.round(fixedSlotWidth * 1.2), 160, 360);
|
|
9897
|
+
const maxVisual = clamp3(Math.round(dayEventMaxWidth ?? defaultMaxVisual), 80, 1200);
|
|
9898
|
+
const visualWidth = shouldCompact ? Math.min(width, maxVisual) : width;
|
|
9899
|
+
const isClipped = shouldCompact && width > visualWidth + 1;
|
|
9731
9900
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Tooltip, { content: tooltipContent, placement: "top", delay: { open: 250, close: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
9732
9901
|
"div",
|
|
9733
9902
|
{
|
|
9734
|
-
className: cn(
|
|
9735
|
-
"absolute rounded-lg border select-none cursor-pointer",
|
|
9736
|
-
"shadow-sm hover:shadow-md hover:scale-[1.02] hover:z-10",
|
|
9737
|
-
"transition-all duration-150 ease-out",
|
|
9738
|
-
"backdrop-blur-sm",
|
|
9739
|
-
"overflow-hidden",
|
|
9740
|
-
ev.className,
|
|
9741
|
-
isPreview && "ring-2 ring-primary/50 ring-offset-1 ring-offset-background scale-[1.02] z-10"
|
|
9742
|
-
),
|
|
9903
|
+
className: cn("absolute select-none cursor-pointer", isPreview && "z-10"),
|
|
9743
9904
|
"data-uv-ct-event": true,
|
|
9744
|
-
style: {
|
|
9745
|
-
left,
|
|
9746
|
-
top,
|
|
9747
|
-
width,
|
|
9748
|
-
height: layout.eventHeight,
|
|
9749
|
-
background: bg,
|
|
9750
|
-
borderColor: border,
|
|
9751
|
-
borderLeftWidth: 3
|
|
9752
|
-
},
|
|
9905
|
+
style: { left, top, width, height: layout.eventHeight },
|
|
9753
9906
|
role: "button",
|
|
9754
9907
|
tabIndex: 0,
|
|
9755
9908
|
"aria-label": aria,
|
|
@@ -9777,6 +9930,31 @@ function CalendarTimeline({
|
|
|
9777
9930
|
onDoubleClick: () => onEventDoubleClick?.(ev),
|
|
9778
9931
|
onPointerDown: (e) => onPointerDownEvent(e, ev, "move"),
|
|
9779
9932
|
children: [
|
|
9933
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
9934
|
+
"div",
|
|
9935
|
+
{
|
|
9936
|
+
className: cn(
|
|
9937
|
+
"relative h-full rounded-lg border overflow-hidden",
|
|
9938
|
+
"shadow-sm hover:shadow-md hover:scale-[1.02]",
|
|
9939
|
+
"transition-all duration-150 ease-out",
|
|
9940
|
+
"backdrop-blur-sm",
|
|
9941
|
+
ev.className,
|
|
9942
|
+
isPreview && "ring-2 ring-primary/50 ring-offset-1 ring-offset-background scale-[1.02]"
|
|
9943
|
+
),
|
|
9944
|
+
style: {
|
|
9945
|
+
width: visualWidth,
|
|
9946
|
+
maxWidth: "100%",
|
|
9947
|
+
height: "100%",
|
|
9948
|
+
background: bg,
|
|
9949
|
+
borderColor: border,
|
|
9950
|
+
borderLeftWidth: 3
|
|
9951
|
+
},
|
|
9952
|
+
children: [
|
|
9953
|
+
node,
|
|
9954
|
+
isClipped ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-10 bg-linear-to-l from-background/50 to-transparent flex items-center justify-end pr-2", children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-xs text-muted-foreground/80", children: "\u2026" }) }) : null
|
|
9955
|
+
]
|
|
9956
|
+
}
|
|
9957
|
+
),
|
|
9780
9958
|
!isViewOnly && (interactions?.resizableEvents ?? true) && ev.resizable !== false ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
|
|
9781
9959
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
9782
9960
|
"div",
|
|
@@ -9792,8 +9970,7 @@ function CalendarTimeline({
|
|
|
9792
9970
|
onPointerDown: (e) => onPointerDownEvent(e, ev, "resize-end")
|
|
9793
9971
|
}
|
|
9794
9972
|
)
|
|
9795
|
-
] }) : null
|
|
9796
|
-
node
|
|
9973
|
+
] }) : null
|
|
9797
9974
|
]
|
|
9798
9975
|
}
|
|
9799
9976
|
) }, ev.id);
|
|
@@ -9801,8 +9978,8 @@ function CalendarTimeline({
|
|
|
9801
9978
|
preview && preview.resourceId === r.id && !preview.eventId ? (() => {
|
|
9802
9979
|
const startIdx = binarySearchLastLE(slotStarts, preview.start);
|
|
9803
9980
|
const endIdx = clamp3(binarySearchFirstGE(slotStarts, preview.end), startIdx + 1, slots.length);
|
|
9804
|
-
const left = startIdx
|
|
9805
|
-
const width = Math.max(1, (endIdx - startIdx
|
|
9981
|
+
const left = slotLefts[startIdx] ?? 0;
|
|
9982
|
+
const width = Math.max(1, (slotLefts[endIdx] ?? 0) - (slotLefts[startIdx] ?? 0));
|
|
9806
9983
|
return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
9807
9984
|
"div",
|
|
9808
9985
|
{
|
|
@@ -9822,7 +9999,7 @@ function CalendarTimeline({
|
|
|
9822
9999
|
"flex items-center justify-center"
|
|
9823
10000
|
),
|
|
9824
10001
|
style: {
|
|
9825
|
-
left: hoverCell.slotIdx
|
|
10002
|
+
left: (slotLefts[hoverCell.slotIdx] ?? 0) + (slotWidths[hoverCell.slotIdx] ?? fixedSlotWidth) / 2 - 10,
|
|
9826
10003
|
top: clamp3(Math.round(hoverCell.y - 10), 6, Math.max(6, h - 26))
|
|
9827
10004
|
},
|
|
9828
10005
|
"aria-hidden": true,
|
|
@@ -9911,27 +10088,11 @@ function CalendarTimeline({
|
|
|
9911
10088
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
|
|
9912
10089
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "space-y-2", children: [
|
|
9913
10090
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "text-xs text-muted-foreground", children: l.start }),
|
|
9914
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
9915
|
-
Combobox,
|
|
9916
|
-
{
|
|
9917
|
-
options: createStartOptions,
|
|
9918
|
-
value: createStartIdx,
|
|
9919
|
-
onChange: (v) => setCreateStartIdx(Number(v)),
|
|
9920
|
-
placeholder: l.start
|
|
9921
|
-
}
|
|
9922
|
-
)
|
|
10091
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Combobox, { options: createStartOptions, value: createStartIdx, onChange: (v) => setCreateStartIdx(Number(v)), placeholder: l.start })
|
|
9923
10092
|
] }),
|
|
9924
10093
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "space-y-2", children: [
|
|
9925
10094
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "text-xs text-muted-foreground", children: l.end }),
|
|
9926
|
-
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
9927
|
-
Combobox,
|
|
9928
|
-
{
|
|
9929
|
-
options: createEndOptions,
|
|
9930
|
-
value: createEndIdx,
|
|
9931
|
-
onChange: (v) => setCreateEndIdx(Number(v)),
|
|
9932
|
-
placeholder: l.end
|
|
9933
|
-
}
|
|
9934
|
-
)
|
|
10095
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Combobox, { options: createEndOptions, value: createEndIdx, onChange: (v) => setCreateEndIdx(Number(v)), placeholder: l.end })
|
|
9935
10096
|
] })
|
|
9936
10097
|
] }),
|
|
9937
10098
|
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center justify-end gap-2 pt-2", children: [
|