@underverse-ui/underverse 0.2.87 → 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.js CHANGED
@@ -7627,6 +7627,18 @@ function getZonedParts(date, timeZone) {
7627
7627
  second: get("second")
7628
7628
  };
7629
7629
  }
7630
+ function getIsoWeekInfo(date, timeZone) {
7631
+ const p = getZonedParts(date, timeZone);
7632
+ const target = new Date(Date.UTC(p.year, p.month - 1, p.day));
7633
+ const dayNr = (target.getUTCDay() + 6) % 7;
7634
+ target.setUTCDate(target.getUTCDate() - dayNr + 3);
7635
+ const isoYear = target.getUTCFullYear();
7636
+ const firstThursday = new Date(Date.UTC(isoYear, 0, 4));
7637
+ const firstDayNr = (firstThursday.getUTCDay() + 6) % 7;
7638
+ firstThursday.setUTCDate(firstThursday.getUTCDate() - firstDayNr + 3);
7639
+ const week = 1 + Math.round((target.getTime() - firstThursday.getTime()) / (7 * 24 * 60 * 60 * 1e3));
7640
+ return { year: isoYear, week };
7641
+ }
7630
7642
  function partsToUtcMs(p) {
7631
7643
  return Date.UTC(p.year, p.month - 1, p.day, p.hour, p.minute, p.second);
7632
7644
  }
@@ -8071,13 +8083,34 @@ function CalendarTimeline({
8071
8083
  }
8072
8084
  return map;
8073
8085
  }, [normalizedEvents]);
8086
+ const resourceById = React28.useMemo(() => {
8087
+ const map = /* @__PURE__ */ new Map();
8088
+ for (const r of resources) map.set(r.id, r);
8089
+ return map;
8090
+ }, [resources]);
8074
8091
  const leftRef = React28.useRef(null);
8075
8092
  const bodyRef = React28.useRef(null);
8076
8093
  const headerRef = React28.useRef(null);
8077
8094
  useHorizontalScrollSync({ bodyRef, headerRef, leftRef });
8078
8095
  const title = React28.useMemo(() => {
8079
- return formatters?.monthTitle?.(activeDate, { locale: resolvedLocale, timeZone: resolvedTimeZone }) ?? defaultMonthTitle(activeDate, resolvedLocale, resolvedTimeZone);
8080
- }, [activeDate, formatters, resolvedLocale, resolvedTimeZone]);
8096
+ if (activeView === "month") {
8097
+ return formatters?.monthTitle?.(activeDate, { locale: resolvedLocale, timeZone: resolvedTimeZone }) ?? defaultMonthTitle(activeDate, resolvedLocale, resolvedTimeZone);
8098
+ }
8099
+ if (activeView === "week") {
8100
+ const { week } = getIsoWeekInfo(range.start, resolvedTimeZone);
8101
+ const fmt2 = getDtf(resolvedLocale, resolvedTimeZone, { month: "short", day: "numeric" });
8102
+ const fmtYear = getDtf(resolvedLocale, resolvedTimeZone, { year: "numeric" });
8103
+ const endInclusive = new Date(range.end.getTime() - 1);
8104
+ const a = fmt2.format(range.start);
8105
+ const b = fmt2.format(endInclusive);
8106
+ const ya = fmtYear.format(range.start);
8107
+ const yb = fmtYear.format(endInclusive);
8108
+ const rangeText = ya === yb ? `${a} \u2013 ${b}, ${ya}` : `${a}, ${ya} \u2013 ${b}, ${yb}`;
8109
+ return `${l.week} ${week} \u2022 ${rangeText}`;
8110
+ }
8111
+ const fmt = getDtf(resolvedLocale, resolvedTimeZone, { weekday: "long", year: "numeric", month: "long", day: "numeric" });
8112
+ return fmt.format(range.start);
8113
+ }, [activeDate, activeView, formatters, l.week, range.end, range.start, resolvedLocale, resolvedTimeZone]);
8081
8114
  const densityClass = sizeConfig.densityClass;
8082
8115
  const eventHeight = sizeConfig.eventHeight;
8083
8116
  const laneGap = sizeConfig.laneGap;
@@ -8103,10 +8136,9 @@ function CalendarTimeline({
8103
8136
  const body = bodyRef.current;
8104
8137
  if (!body) return null;
8105
8138
  const el = document.elementFromPoint(clientX, clientY);
8106
- const timelineEl = el?.closest?.("[data-uv-ct-timeline]");
8107
- if (!timelineEl) return null;
8108
- const timelineRect = timelineEl.getBoundingClientRect();
8109
- const x = clientX - timelineRect.left + body.scrollLeft;
8139
+ if (!el || !body.contains(el)) return null;
8140
+ const bodyRect = body.getBoundingClientRect();
8141
+ const x = clientX - bodyRect.left + body.scrollLeft;
8110
8142
  const slotIdx = clamp3(Math.floor(x / slotWidth), 0, Math.max(0, slots.length - 1));
8111
8143
  const rowEl = el?.closest?.("[data-uv-ct-row]");
8112
8144
  const rid = rowEl?.dataset?.uvCtRow ?? null;
@@ -8494,7 +8526,14 @@ function CalendarTimeline({
8494
8526
  ev.title ? /* @__PURE__ */ jsx33("span", { className: "font-semibold text-[11px] truncate leading-tight", children: ev.title }) : null,
8495
8527
  /* @__PURE__ */ jsx33("span", { className: "text-[10px] opacity-70 truncate ml-auto", children: timeText })
8496
8528
  ] });
8497
- return /* @__PURE__ */ jsxs28(
8529
+ const resource = resourceById.get(ev.resourceId);
8530
+ const tooltipTitle = ev.title || ev.id;
8531
+ const tooltipContent = /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-0.5", children: [
8532
+ /* @__PURE__ */ jsx33("div", { className: "font-semibold", children: tooltipTitle }),
8533
+ /* @__PURE__ */ jsx33("div", { className: "text-xs opacity-80", children: timeText }),
8534
+ resource?.label ? /* @__PURE__ */ jsx33("div", { className: "text-xs opacity-70", children: resource.label }) : null
8535
+ ] });
8536
+ return /* @__PURE__ */ jsx33(Tooltip, { content: tooltipContent, placement: "top", delay: { open: 250, close: 0 }, children: /* @__PURE__ */ jsxs28(
8498
8537
  "div",
8499
8538
  {
8500
8539
  className: cn(
@@ -8539,9 +8578,8 @@ function CalendarTimeline({
8539
8578
  ] }) : null,
8540
8579
  node
8541
8580
  ]
8542
- },
8543
- ev.id
8544
- );
8581
+ }
8582
+ ) }, ev.id);
8545
8583
  }),
8546
8584
  preview && preview.resourceId === r.id && !preview.eventId ? (() => {
8547
8585
  const startIdx = binarySearchLastLE(slotStarts, preview.start);