@underverse-ui/underverse 0.2.86 → 0.2.88
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 +129 -81
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +129 -81
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7802,6 +7802,18 @@ function getZonedParts(date, timeZone) {
|
|
|
7802
7802
|
second: get("second")
|
|
7803
7803
|
};
|
|
7804
7804
|
}
|
|
7805
|
+
function getIsoWeekInfo(date, timeZone) {
|
|
7806
|
+
const p = getZonedParts(date, timeZone);
|
|
7807
|
+
const target = new Date(Date.UTC(p.year, p.month - 1, p.day));
|
|
7808
|
+
const dayNr = (target.getUTCDay() + 6) % 7;
|
|
7809
|
+
target.setUTCDate(target.getUTCDate() - dayNr + 3);
|
|
7810
|
+
const isoYear = target.getUTCFullYear();
|
|
7811
|
+
const firstThursday = new Date(Date.UTC(isoYear, 0, 4));
|
|
7812
|
+
const firstDayNr = (firstThursday.getUTCDay() + 6) % 7;
|
|
7813
|
+
firstThursday.setUTCDate(firstThursday.getUTCDate() - firstDayNr + 3);
|
|
7814
|
+
const week = 1 + Math.round((target.getTime() - firstThursday.getTime()) / (7 * 24 * 60 * 60 * 1e3));
|
|
7815
|
+
return { year: isoYear, week };
|
|
7816
|
+
}
|
|
7805
7817
|
function partsToUtcMs(p) {
|
|
7806
7818
|
return Date.UTC(p.year, p.month - 1, p.day, p.hour, p.minute, p.second);
|
|
7807
7819
|
}
|
|
@@ -7891,41 +7903,48 @@ function intervalPack(items) {
|
|
|
7891
7903
|
// ../../components/ui/CalendarTimeline/hooks.ts
|
|
7892
7904
|
var React27 = __toESM(require("react"), 1);
|
|
7893
7905
|
function useHorizontalScrollSync(args) {
|
|
7894
|
-
const { bodyRef, headerRef } = args;
|
|
7906
|
+
const { bodyRef, headerRef, leftRef } = args;
|
|
7895
7907
|
React27.useEffect(() => {
|
|
7896
7908
|
const body = bodyRef.current;
|
|
7897
7909
|
const header = headerRef.current;
|
|
7910
|
+
const left = leftRef?.current ?? null;
|
|
7898
7911
|
if (!body || !header) return;
|
|
7899
7912
|
let raf = 0;
|
|
7900
7913
|
let syncing = false;
|
|
7901
|
-
const
|
|
7914
|
+
const syncFrom = (source) => {
|
|
7902
7915
|
if (syncing) return;
|
|
7903
7916
|
syncing = true;
|
|
7904
|
-
header
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
7916
|
-
};
|
|
7917
|
-
const onHeaderScroll = () => {
|
|
7917
|
+
if (source === "header") {
|
|
7918
|
+
const x = header.scrollLeft;
|
|
7919
|
+
if (body.scrollLeft !== x) body.scrollLeft = x;
|
|
7920
|
+
} else if (source === "left" && left) {
|
|
7921
|
+
const y = left.scrollTop;
|
|
7922
|
+
if (body.scrollTop !== y) body.scrollTop = y;
|
|
7923
|
+
} else {
|
|
7924
|
+
const x = body.scrollLeft;
|
|
7925
|
+
const y = body.scrollTop;
|
|
7926
|
+
if (header.scrollLeft !== x) header.scrollLeft = x;
|
|
7927
|
+
if (left && left.scrollTop !== y) left.scrollTop = y;
|
|
7928
|
+
}
|
|
7918
7929
|
cancelAnimationFrame(raf);
|
|
7919
|
-
raf = requestAnimationFrame(
|
|
7930
|
+
raf = requestAnimationFrame(() => {
|
|
7931
|
+
syncing = false;
|
|
7932
|
+
});
|
|
7920
7933
|
};
|
|
7934
|
+
const onBodyScroll = () => syncFrom("body");
|
|
7935
|
+
const onHeaderScroll = () => syncFrom("header");
|
|
7936
|
+
const onLeftScroll = () => syncFrom("left");
|
|
7937
|
+
syncFrom("body");
|
|
7921
7938
|
body.addEventListener("scroll", onBodyScroll, { passive: true });
|
|
7922
7939
|
header.addEventListener("scroll", onHeaderScroll, { passive: true });
|
|
7940
|
+
left?.addEventListener("scroll", onLeftScroll, { passive: true });
|
|
7923
7941
|
return () => {
|
|
7924
7942
|
cancelAnimationFrame(raf);
|
|
7925
7943
|
body.removeEventListener("scroll", onBodyScroll);
|
|
7926
7944
|
header.removeEventListener("scroll", onHeaderScroll);
|
|
7945
|
+
left?.removeEventListener("scroll", onLeftScroll);
|
|
7927
7946
|
};
|
|
7928
|
-
}, [bodyRef, headerRef]);
|
|
7947
|
+
}, [bodyRef, headerRef, leftRef]);
|
|
7929
7948
|
}
|
|
7930
7949
|
function useVirtualRows(args) {
|
|
7931
7950
|
const { enabled, overscan, rowHeight, itemCount, scrollRef } = args;
|
|
@@ -8239,12 +8258,34 @@ function CalendarTimeline({
|
|
|
8239
8258
|
}
|
|
8240
8259
|
return map;
|
|
8241
8260
|
}, [normalizedEvents]);
|
|
8261
|
+
const resourceById = React28.useMemo(() => {
|
|
8262
|
+
const map = /* @__PURE__ */ new Map();
|
|
8263
|
+
for (const r of resources) map.set(r.id, r);
|
|
8264
|
+
return map;
|
|
8265
|
+
}, [resources]);
|
|
8266
|
+
const leftRef = React28.useRef(null);
|
|
8242
8267
|
const bodyRef = React28.useRef(null);
|
|
8243
8268
|
const headerRef = React28.useRef(null);
|
|
8244
|
-
useHorizontalScrollSync({ bodyRef, headerRef });
|
|
8269
|
+
useHorizontalScrollSync({ bodyRef, headerRef, leftRef });
|
|
8245
8270
|
const title = React28.useMemo(() => {
|
|
8246
|
-
|
|
8247
|
-
|
|
8271
|
+
if (activeView === "month") {
|
|
8272
|
+
return formatters?.monthTitle?.(activeDate, { locale: resolvedLocale, timeZone: resolvedTimeZone }) ?? defaultMonthTitle(activeDate, resolvedLocale, resolvedTimeZone);
|
|
8273
|
+
}
|
|
8274
|
+
if (activeView === "week") {
|
|
8275
|
+
const { week } = getIsoWeekInfo(range.start, resolvedTimeZone);
|
|
8276
|
+
const fmt2 = getDtf(resolvedLocale, resolvedTimeZone, { month: "short", day: "numeric" });
|
|
8277
|
+
const fmtYear = getDtf(resolvedLocale, resolvedTimeZone, { year: "numeric" });
|
|
8278
|
+
const endInclusive = new Date(range.end.getTime() - 1);
|
|
8279
|
+
const a = fmt2.format(range.start);
|
|
8280
|
+
const b = fmt2.format(endInclusive);
|
|
8281
|
+
const ya = fmtYear.format(range.start);
|
|
8282
|
+
const yb = fmtYear.format(endInclusive);
|
|
8283
|
+
const rangeText = ya === yb ? `${a} \u2013 ${b}, ${ya}` : `${a}, ${ya} \u2013 ${b}, ${yb}`;
|
|
8284
|
+
return `${l.week} ${week} \u2022 ${rangeText}`;
|
|
8285
|
+
}
|
|
8286
|
+
const fmt = getDtf(resolvedLocale, resolvedTimeZone, { weekday: "long", year: "numeric", month: "long", day: "numeric" });
|
|
8287
|
+
return fmt.format(range.start);
|
|
8288
|
+
}, [activeDate, activeView, formatters, l.week, range.end, range.start, resolvedLocale, resolvedTimeZone]);
|
|
8248
8289
|
const densityClass = sizeConfig.densityClass;
|
|
8249
8290
|
const eventHeight = sizeConfig.eventHeight;
|
|
8250
8291
|
const laneGap = sizeConfig.laneGap;
|
|
@@ -8270,10 +8311,9 @@ function CalendarTimeline({
|
|
|
8270
8311
|
const body = bodyRef.current;
|
|
8271
8312
|
if (!body) return null;
|
|
8272
8313
|
const el = document.elementFromPoint(clientX, clientY);
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
const
|
|
8276
|
-
const x = clientX - timelineRect.left + body.scrollLeft;
|
|
8314
|
+
if (!el || !body.contains(el)) return null;
|
|
8315
|
+
const bodyRect = body.getBoundingClientRect();
|
|
8316
|
+
const x = clientX - bodyRect.left + body.scrollLeft;
|
|
8277
8317
|
const slotIdx = clamp3(Math.floor(x / slotWidth), 0, Math.max(0, slots.length - 1));
|
|
8278
8318
|
const rowEl = el?.closest?.("[data-uv-ct-row]");
|
|
8279
8319
|
const rid = rowEl?.dataset?.uvCtRow ?? null;
|
|
@@ -8587,49 +8627,51 @@ function CalendarTimeline({
|
|
|
8587
8627
|
...rest,
|
|
8588
8628
|
children: [
|
|
8589
8629
|
Header,
|
|
8590
|
-
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
8591
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8596
|
-
|
|
8597
|
-
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
|
|
8601
|
-
|
|
8602
|
-
|
|
8603
|
-
|
|
8604
|
-
|
|
8605
|
-
|
|
8606
|
-
|
|
8607
|
-
|
|
8608
|
-
|
|
8609
|
-
|
|
8610
|
-
|
|
8611
|
-
|
|
8612
|
-
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
children:
|
|
8624
|
-
|
|
8625
|
-
|
|
8626
|
-
|
|
8627
|
-
|
|
8628
|
-
|
|
8629
|
-
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8630
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex min-h-0", children: [
|
|
8631
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
8632
|
+
"div",
|
|
8633
|
+
{
|
|
8634
|
+
ref: leftRef,
|
|
8635
|
+
className: "shrink-0 overflow-y-auto overflow-x-hidden scrollbar-none",
|
|
8636
|
+
style: { width: effectiveResourceColumnWidth, minWidth: effectiveResourceColumnWidth },
|
|
8637
|
+
children: [
|
|
8638
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { style: { height: topSpacer } }),
|
|
8639
|
+
rows.slice(startRow, endRow).map((row, idx) => {
|
|
8640
|
+
const rowIndex = startRow + idx;
|
|
8641
|
+
if (row.kind === "group") {
|
|
8642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { style: { height: effectiveRowHeight }, children: renderGroupRow(row.group) }, `lg_${row.group.id}_${rowIndex}`);
|
|
8643
|
+
}
|
|
8644
|
+
const r = row.resource;
|
|
8645
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { style: { height: effectiveRowHeight }, children: ResourceCell(r) }, `lr_${r.id}_${rowIndex}`);
|
|
8646
|
+
}),
|
|
8647
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { style: { height: bottomSpacer } })
|
|
8648
|
+
]
|
|
8649
|
+
}
|
|
8650
|
+
),
|
|
8651
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
8652
|
+
"div",
|
|
8653
|
+
{
|
|
8654
|
+
ref: bodyRef,
|
|
8655
|
+
className: "relative flex-1 overflow-auto scrollbar-thin scrollbar-thumb-muted scrollbar-track-transparent",
|
|
8656
|
+
onPointerMove,
|
|
8657
|
+
onPointerUp,
|
|
8658
|
+
children: [
|
|
8659
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { style: { height: topSpacer } }),
|
|
8660
|
+
rows.slice(startRow, endRow).map((row, idx) => {
|
|
8661
|
+
const rowIndex = startRow + idx;
|
|
8662
|
+
if (row.kind === "group") {
|
|
8663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "flex", style: { height: effectiveRowHeight }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "border-b border-border/30 bg-linear-to-r from-muted/15 to-muted/5", style: { width: gridWidth, minWidth: gridWidth } }) }, `rg_${row.group.id}_${rowIndex}`);
|
|
8664
|
+
}
|
|
8665
|
+
const r = row.resource;
|
|
8666
|
+
const layout = layoutsByResource.get(r.id) ?? { visible: [], hidden: [] };
|
|
8667
|
+
const canMore = layout.hidden.length > 0 && !!onMoreClick;
|
|
8668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
8669
|
+
"div",
|
|
8670
|
+
{
|
|
8671
|
+
className: "group/row hover:bg-muted/5 transition-colors duration-150",
|
|
8672
|
+
style: { height: effectiveRowHeight },
|
|
8673
|
+
"data-uv-ct-row": r.id,
|
|
8674
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "relative shrink-0", style: { width: gridWidth, minWidth: gridWidth, height: "100%" }, children: [
|
|
8633
8675
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "absolute inset-0", onPointerDown: onPointerDownCell, "data-uv-ct-timeline": true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "absolute inset-0 flex", children: slots.map((s, i2) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
|
|
8634
8676
|
"div",
|
|
8635
8677
|
{
|
|
@@ -8659,7 +8701,14 @@ function CalendarTimeline({
|
|
|
8659
8701
|
ev.title ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "font-semibold text-[11px] truncate leading-tight", children: ev.title }) : null,
|
|
8660
8702
|
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-[10px] opacity-70 truncate ml-auto", children: timeText })
|
|
8661
8703
|
] });
|
|
8662
|
-
|
|
8704
|
+
const resource = resourceById.get(ev.resourceId);
|
|
8705
|
+
const tooltipTitle = ev.title || ev.id;
|
|
8706
|
+
const tooltipContent = /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
|
|
8707
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "font-semibold", children: tooltipTitle }),
|
|
8708
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "text-xs opacity-80", children: timeText }),
|
|
8709
|
+
resource?.label ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "text-xs opacity-70", children: resource.label }) : null
|
|
8710
|
+
] });
|
|
8711
|
+
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Tooltip, { content: tooltipContent, placement: "top", delay: { open: 250, close: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
|
|
8663
8712
|
"div",
|
|
8664
8713
|
{
|
|
8665
8714
|
className: cn(
|
|
@@ -8704,9 +8753,8 @@ function CalendarTimeline({
|
|
|
8704
8753
|
] }) : null,
|
|
8705
8754
|
node
|
|
8706
8755
|
]
|
|
8707
|
-
}
|
|
8708
|
-
|
|
8709
|
-
);
|
|
8756
|
+
}
|
|
8757
|
+
) }, ev.id);
|
|
8710
8758
|
}),
|
|
8711
8759
|
preview && preview.resourceId === r.id && !preview.eventId ? (() => {
|
|
8712
8760
|
const startIdx = binarySearchLastLE(slotStarts, preview.start);
|
|
@@ -8741,15 +8789,15 @@ function CalendarTimeline({
|
|
|
8741
8789
|
}
|
|
8742
8790
|
) : null
|
|
8743
8791
|
] })
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
)
|
|
8748
|
-
|
|
8749
|
-
|
|
8750
|
-
|
|
8751
|
-
|
|
8752
|
-
)
|
|
8792
|
+
},
|
|
8793
|
+
`rr_${r.id}_${rowIndex}`
|
|
8794
|
+
);
|
|
8795
|
+
}),
|
|
8796
|
+
/* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { style: { height: bottomSpacer } })
|
|
8797
|
+
]
|
|
8798
|
+
}
|
|
8799
|
+
)
|
|
8800
|
+
] })
|
|
8753
8801
|
]
|
|
8754
8802
|
}
|
|
8755
8803
|
);
|