@wow-two-beta/ui 0.0.69 → 0.0.70

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.
@@ -1,4 +1,4 @@
1
- import { Kbd, MONTHS_LONG, WEEKDAYS_SHORT } from './chunk-EKGOQL75.js';
1
+ import { Kbd, zonedAtHour, formatZonedTime, minutesBetween, nowZoned, today, daysBetween, isWeekend, addDays, MONTHS_LONG, WEEKDAYS_SHORT, isToday, maxZoned, minZoned, isZonedDayInRange, isZonedOnDay } from './chunk-SIAFOCT4.js';
2
2
  import { Inline } from './chunk-WKVWOAQV.js';
3
3
  import { useClipboard, useControlled, useReducedMotion } from './chunk-RNHY33US.js';
4
4
  import { Icon } from './chunk-D7ZFCHX5.js';
@@ -8,6 +8,7 @@ import { cn } from './chunk-D4ZT36AZ.js';
8
8
  import { forwardRef, useState, useEffect, Children, isValidElement, Fragment as Fragment$1, createContext, useId, useMemo, useCallback, useContext, useRef, useImperativeHandle, useLayoutEffect } from 'react';
9
9
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
10
10
  import { TrendingUp, TrendingDown, Check, Copy, ChevronDown, ChevronLeft, ChevronRight, Plus, Minus, Maximize, Pause, Play, VolumeX, Volume2, Captions, CaptionsOff, PictureInPicture2, Minimize, ZoomOut, ZoomIn, Download, SmilePlus, X, AlertTriangle, CheckCheck, Clock, ArrowUp, ArrowDown, ArrowUpDown } from 'lucide-react';
11
+ import { Temporal } from '@js-temporal/polyfill';
11
12
 
12
13
  // src/display/heading/Heading.variants.ts
13
14
  var headingVariants = tv({
@@ -1747,6 +1748,14 @@ function defaultCompare(a, b) {
1747
1748
  if (a === null || a === void 0) return 1;
1748
1749
  if (b === null || b === void 0) return -1;
1749
1750
  if (typeof a === "number" && typeof b === "number") return a - b;
1751
+ if (a instanceof Temporal.PlainDate && b instanceof Temporal.PlainDate)
1752
+ return Temporal.PlainDate.compare(a, b);
1753
+ if (a instanceof Temporal.PlainTime && b instanceof Temporal.PlainTime)
1754
+ return Temporal.PlainTime.compare(a, b);
1755
+ if (a instanceof Temporal.PlainDateTime && b instanceof Temporal.PlainDateTime)
1756
+ return Temporal.PlainDateTime.compare(a, b);
1757
+ if (a instanceof Temporal.ZonedDateTime && b instanceof Temporal.ZonedDateTime)
1758
+ return Temporal.ZonedDateTime.compare(a, b);
1750
1759
  if (a instanceof Date && b instanceof Date) return a.getTime() - b.getTime();
1751
1760
  return String(a).localeCompare(String(b));
1752
1761
  }
@@ -2438,16 +2447,10 @@ var TONE_CLASSES = {
2438
2447
  };
2439
2448
  var DEFAULT_MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
2440
2449
  var DEFAULT_WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
2441
- function formatDate(d) {
2442
- const y = d.getFullYear();
2443
- const m = String(d.getMonth() + 1).padStart(2, "0");
2444
- const day = String(d.getDate()).padStart(2, "0");
2445
- return `${y}-${m}-${day}`;
2446
- }
2447
2450
  var HeatmapCalendar = forwardRef(
2448
2451
  function HeatmapCalendar2({
2449
2452
  values,
2450
- year = (/* @__PURE__ */ new Date()).getFullYear(),
2453
+ year = Temporal.Now.plainDateISO().year,
2451
2454
  weekStart = 0,
2452
2455
  cellSize = 12,
2453
2456
  gap = 2,
@@ -2461,37 +2464,37 @@ var HeatmapCalendar = forwardRef(
2461
2464
  ...rest
2462
2465
  }, ref) {
2463
2466
  const valueMap = useMemo(() => {
2464
- if (values instanceof Map) return values;
2465
- return new Map(Object.entries(values));
2467
+ const map = /* @__PURE__ */ new Map();
2468
+ for (const [date, value] of values) map.set(date.toString(), value);
2469
+ return map;
2466
2470
  }, [values]);
2467
2471
  const { columns, monthMarkers, maxValue } = useMemo(() => {
2468
- const start = new Date(year, 0, 1);
2469
- const end = new Date(year, 11, 31);
2470
- const cur = new Date(start);
2471
- const wd = cur.getDay();
2472
- const offset = (wd - weekStart + 7) % 7;
2473
- cur.setDate(cur.getDate() - offset);
2472
+ const start = Temporal.PlainDate.from({ year, month: 1, day: 1 });
2473
+ const end = Temporal.PlainDate.from({ year, month: 12, day: 31 });
2474
+ const sundayIdx = start.dayOfWeek % 7;
2475
+ const offset = (sundayIdx - weekStart + 7) % 7;
2476
+ let cur = start.subtract({ days: offset });
2474
2477
  const cols = [];
2475
2478
  let column = [];
2476
2479
  const months = [];
2477
2480
  let lastSeenMonth = -1;
2478
2481
  let max = 0;
2479
- while (cur <= end || column.length > 0) {
2480
- const inYear = cur.getFullYear() === year;
2481
- const key = formatDate(cur);
2482
+ while (Temporal.PlainDate.compare(cur, end) <= 0 || column.length > 0) {
2483
+ const inYear = cur.year === year;
2484
+ const key = cur.toString();
2482
2485
  const v = valueMap.get(key) ?? 0;
2483
2486
  if (v > max) max = v;
2484
- column.push({ date: new Date(cur), inYear, value: v });
2485
- if (inYear && cur.getMonth() !== lastSeenMonth) {
2486
- lastSeenMonth = cur.getMonth();
2487
- months.push({ month: cur.getMonth(), col: cols.length });
2487
+ column.push({ date: cur, key, inYear, value: v });
2488
+ if (inYear && cur.month - 1 !== lastSeenMonth) {
2489
+ lastSeenMonth = cur.month - 1;
2490
+ months.push({ month: cur.month - 1, col: cols.length });
2488
2491
  }
2489
2492
  if (column.length === 7) {
2490
2493
  cols.push(column);
2491
2494
  column = [];
2492
2495
  }
2493
- cur.setDate(cur.getDate() + 1);
2494
- if (cur > end && column.length === 0) break;
2496
+ cur = cur.add({ days: 1 });
2497
+ if (Temporal.PlainDate.compare(cur, end) > 0 && column.length === 0) break;
2495
2498
  }
2496
2499
  if (column.length > 0) cols.push(column);
2497
2500
  return { columns: cols, monthMarkers: months, maxValue: max };
@@ -2539,7 +2542,6 @@ var HeatmapCalendar = forwardRef(
2539
2542
  }
2540
2543
  ),
2541
2544
  /* @__PURE__ */ jsx("div", { className: "flex", style: { gap }, children: columns.map((col, colIdx) => /* @__PURE__ */ jsx("div", { className: "flex flex-col", style: { gap }, children: col.map((cell, rowIdx) => {
2542
- const dateStr = formatDate(cell.date);
2543
2545
  const level = bucket(cell.value);
2544
2546
  const interactive = cell.inYear && onCellClick != null;
2545
2547
  const Tag = interactive ? "button" : "div";
@@ -2547,11 +2549,11 @@ var HeatmapCalendar = forwardRef(
2547
2549
  Tag,
2548
2550
  {
2549
2551
  type: interactive ? "button" : void 0,
2550
- "aria-label": `${dateStr}: ${cell.value}`,
2552
+ "aria-label": `${cell.key}: ${cell.value}`,
2551
2553
  "aria-valuenow": level,
2552
2554
  "aria-valuemin": 0,
2553
2555
  "aria-valuemax": levelCount - 1,
2554
- onClick: interactive ? () => onCellClick?.(dateStr, cell.value) : void 0,
2556
+ onClick: interactive ? () => onCellClick?.(cell.date, cell.value) : void 0,
2555
2557
  style: { width: cellSize, height: cellSize },
2556
2558
  className: cn(
2557
2559
  "rounded-[2px] transition-colors",
@@ -3840,18 +3842,10 @@ var PDFViewer = forwardRef(function PDFViewer2({
3840
3842
  }
3841
3843
  );
3842
3844
  });
3843
- function dateAtHour(base, hour, minute = 0) {
3844
- const c = new Date(base);
3845
- c.setHours(hour, minute, 0, 0);
3846
- return c;
3847
- }
3848
- function diffMinutes(a, b) {
3849
- return (b.getTime() - a.getTime()) / 6e4;
3850
- }
3851
3845
  var ScheduleView = forwardRef(function ScheduleView2({
3852
3846
  resources,
3853
3847
  bookings,
3854
- date = /* @__PURE__ */ new Date(),
3848
+ date = nowZoned(),
3855
3849
  hourRange = [8, 20],
3856
3850
  slotMinutes = 30,
3857
3851
  onBookingClick,
@@ -3863,7 +3857,10 @@ var ScheduleView = forwardRef(function ScheduleView2({
3863
3857
  const [startHour, endHour] = hourRange;
3864
3858
  const totalMinutes = (endHour - startHour) * 60;
3865
3859
  const slotCount = Math.ceil(totalMinutes / slotMinutes);
3866
- const dayStart = useMemo(() => dateAtHour(date, startHour), [date, startHour]);
3860
+ const dayStart = useMemo(
3861
+ () => zonedAtHour(date.toPlainDate(), startHour, date.timeZoneId),
3862
+ [date, startHour]
3863
+ );
3867
3864
  const bookingsByResource = useMemo(() => {
3868
3865
  const map = /* @__PURE__ */ new Map();
3869
3866
  for (const b of bookings) {
@@ -3886,7 +3883,7 @@ var ScheduleView = forwardRef(function ScheduleView2({
3886
3883
  ...rest,
3887
3884
  children: [
3888
3885
  /* @__PURE__ */ jsxs("div", { className: "sticky top-0 z-raised flex border-b border-border bg-muted/40", children: [
3889
- /* @__PURE__ */ jsx("div", { className: "w-32 shrink-0 border-r border-border px-3 py-2 text-xs font-medium text-muted-foreground", children: date.toLocaleDateString(void 0, { weekday: "short", month: "short", day: "numeric" }) }),
3886
+ /* @__PURE__ */ jsx("div", { className: "w-32 shrink-0 border-r border-border px-3 py-2 text-xs font-medium text-muted-foreground", children: date.toLocaleString(void 0, { weekday: "short", month: "short", day: "numeric" }) }),
3890
3887
  /* @__PURE__ */ jsx("div", { className: "flex-1 grid", style: { gridTemplateColumns: `repeat(${endHour - startHour}, 1fr)` }, children: Array.from({ length: endHour - startHour }, (_, i) => /* @__PURE__ */ jsxs("div", { className: "border-l border-border px-2 py-1 text-xs text-muted-foreground tabular-nums", children: [
3891
3888
  String((startHour + i) % 24).padStart(2, "0"),
3892
3889
  ":00"
@@ -3912,13 +3909,12 @@ var ScheduleView = forwardRef(function ScheduleView2({
3912
3909
  className: "absolute inset-0 grid",
3913
3910
  style: { gridTemplateColumns: `repeat(${slotCount}, 1fr)` },
3914
3911
  children: Array.from({ length: slotCount }, (_, i) => {
3915
- const slotTime = new Date(dayStart);
3916
- slotTime.setMinutes(slotTime.getMinutes() + i * slotMinutes);
3912
+ const slotTime = dayStart.add({ minutes: i * slotMinutes });
3917
3913
  return /* @__PURE__ */ jsx(
3918
3914
  "button",
3919
3915
  {
3920
3916
  type: "button",
3921
- "aria-label": `Empty slot at ${slotTime.toLocaleTimeString()}`,
3917
+ "aria-label": `Empty slot at ${formatZonedTime(slotTime)}`,
3922
3918
  onClick: () => onSlotClick(resource.id, slotTime),
3923
3919
  className: "hover:bg-primary-soft/30"
3924
3920
  },
@@ -3928,8 +3924,8 @@ var ScheduleView = forwardRef(function ScheduleView2({
3928
3924
  }
3929
3925
  ),
3930
3926
  items.map((booking) => {
3931
- const offsetMin = Math.max(0, diffMinutes(dayStart, booking.start));
3932
- const durMin = Math.max(15, diffMinutes(booking.start, booking.end));
3927
+ const offsetMin = Math.max(0, minutesBetween(dayStart, booking.start));
3928
+ const durMin = Math.max(15, minutesBetween(booking.start, booking.end));
3933
3929
  const left = offsetMin / totalMinutes * 100;
3934
3930
  const width = durMin / totalMinutes * 100;
3935
3931
  const color = booking.color ?? resource.color;
@@ -3938,7 +3934,7 @@ var ScheduleView = forwardRef(function ScheduleView2({
3938
3934
  {
3939
3935
  type: "button",
3940
3936
  role: "button",
3941
- "aria-label": `${resource.label} ${booking.start.toLocaleTimeString()} \u2013 ${booking.end.toLocaleTimeString()}: ${booking.label ?? ""}`,
3937
+ "aria-label": `${resource.label} ${formatZonedTime(booking.start)} \u2013 ${formatZonedTime(booking.end)}: ${booking.label ?? ""}`,
3942
3938
  onClick: (e) => {
3943
3939
  e.stopPropagation();
3944
3940
  onBookingClick?.(booking);
@@ -3957,9 +3953,9 @@ var ScheduleView = forwardRef(function ScheduleView2({
3957
3953
  children: renderBooking ? renderBooking(booking) : /* @__PURE__ */ jsxs(Fragment, { children: [
3958
3954
  /* @__PURE__ */ jsx("div", { className: "truncate", children: booking.label ?? booking.id }),
3959
3955
  /* @__PURE__ */ jsxs("div", { className: "text-[10px] opacity-70 tabular-nums", children: [
3960
- booking.start.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }),
3956
+ formatZonedTime(booking.start),
3961
3957
  " \u2013 ",
3962
- booking.end.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })
3958
+ formatZonedTime(booking.end)
3963
3959
  ] })
3964
3960
  ] })
3965
3961
  },
@@ -3973,21 +3969,17 @@ var ScheduleView = forwardRef(function ScheduleView2({
3973
3969
  }
3974
3970
  );
3975
3971
  });
3976
- var MS_PER_DAY = 24 * 60 * 60 * 1e3;
3977
- function startOfDayLocal(d) {
3978
- const c = new Date(d);
3979
- c.setHours(0, 0, 0, 0);
3980
- return c;
3972
+ function minDate(a, b) {
3973
+ return Temporal.PlainDate.compare(a, b) <= 0 ? a : b;
3981
3974
  }
3982
- function dayDiff(a, b) {
3983
- return Math.round((startOfDayLocal(b).getTime() - startOfDayLocal(a).getTime()) / MS_PER_DAY);
3975
+ function maxDate(a, b) {
3976
+ return Temporal.PlainDate.compare(a, b) >= 0 ? a : b;
3984
3977
  }
3985
3978
  function* eachDay(from, to) {
3986
- const cur = startOfDayLocal(from);
3987
- const end = startOfDayLocal(to);
3988
- while (cur <= end) {
3989
- yield new Date(cur);
3990
- cur.setDate(cur.getDate() + 1);
3979
+ let cur = from;
3980
+ while (Temporal.PlainDate.compare(cur, to) <= 0) {
3981
+ yield cur;
3982
+ cur = addDays(cur, 1);
3991
3983
  }
3992
3984
  }
3993
3985
  var Gantt = forwardRef(function Gantt2({
@@ -4006,20 +3998,19 @@ var Gantt = forwardRef(function Gantt2({
4006
3998
  }, ref) {
4007
3999
  const { from, to, totalDays } = useMemo(() => {
4008
4000
  if (tasks.length === 0) {
4009
- const now = /* @__PURE__ */ new Date();
4001
+ const now = today();
4010
4002
  return { from: now, to: now, totalDays: 1 };
4011
4003
  }
4012
- const minStart = fromProp ?? new Date(Math.min(...tasks.map((t) => t.start.getTime())));
4013
- const maxEnd = toProp ?? new Date(Math.max(...tasks.map((t) => t.end.getTime())));
4004
+ const minStart = fromProp ?? tasks.map((t) => t.start).reduce(minDate);
4005
+ const maxEnd = toProp ?? tasks.map((t) => t.end).reduce(maxDate);
4014
4006
  return {
4015
- from: startOfDayLocal(minStart),
4016
- to: startOfDayLocal(maxEnd),
4017
- totalDays: dayDiff(minStart, maxEnd) + 1
4007
+ from: minStart,
4008
+ to: maxEnd,
4009
+ totalDays: daysBetween(minStart, maxEnd) + 1
4018
4010
  };
4019
4011
  }, [tasks, fromProp, toProp]);
4020
4012
  const headerDates = useMemo(() => Array.from(eachDay(from, to)), [from, to]);
4021
- const today = startOfDayLocal(/* @__PURE__ */ new Date());
4022
- const todayOffset = dayDiff(from, today);
4013
+ const todayOffset = daysBetween(from, today());
4023
4014
  const todayInRange = todayOffset >= 0 && todayOffset < totalDays;
4024
4015
  const taskIndex = useMemo(() => new Map(tasks.map((t, i) => [t.id, i])), [tasks]);
4025
4016
  const timelineWidth = totalDays * cellWidth;
@@ -4047,28 +4038,28 @@ var Gantt = forwardRef(function Gantt2({
4047
4038
  /* @__PURE__ */ jsxs("div", { className: "relative flex-1 overflow-x-auto", style: { minWidth: 0 }, children: [
4048
4039
  /* @__PURE__ */ jsxs("div", { style: { width: timelineWidth }, children: [
4049
4040
  /* @__PURE__ */ jsx("div", { className: "flex border-b border-border", style: { height: rowHeight }, children: headerDates.map((d, i) => {
4050
- const isWeekend = d.getDay() === 0 || d.getDay() === 6;
4051
- const isFirstOfMonth = d.getDate() === 1;
4041
+ const weekend = isWeekend(d);
4042
+ const isFirstOfMonth = d.day === 1;
4052
4043
  return /* @__PURE__ */ jsxs(
4053
4044
  "div",
4054
4045
  {
4055
4046
  className: cn(
4056
4047
  "border-r border-border text-[10px] tabular-nums",
4057
- isWeekend && hasWeekends && "bg-muted/40",
4048
+ weekend && hasWeekends && "bg-muted/40",
4058
4049
  isFirstOfMonth && "border-l-2 border-l-border-strong"
4059
4050
  ),
4060
4051
  style: { width: cellWidth },
4061
4052
  children: [
4062
- isFirstOfMonth && /* @__PURE__ */ jsx("div", { className: "border-b border-border bg-muted px-1 py-0.5 text-center font-medium text-muted-foreground", children: d.toLocaleDateString(void 0, { month: "short", year: "2-digit" }) }),
4063
- /* @__PURE__ */ jsx("div", { className: "px-1 py-0.5 text-center text-muted-foreground", children: d.getDate() })
4053
+ isFirstOfMonth && /* @__PURE__ */ jsx("div", { className: "border-b border-border bg-muted px-1 py-0.5 text-center font-medium text-muted-foreground", children: d.toLocaleString(void 0, { month: "short", year: "2-digit" }) }),
4054
+ /* @__PURE__ */ jsx("div", { className: "px-1 py-0.5 text-center text-muted-foreground", children: d.day })
4064
4055
  ]
4065
4056
  },
4066
4057
  i
4067
4058
  );
4068
4059
  }) }),
4069
4060
  tasks.map((task) => {
4070
- const offset = dayDiff(from, task.start);
4071
- const length = Math.max(1, dayDiff(task.start, task.end) + 1);
4061
+ const offset = daysBetween(from, task.start);
4062
+ const length = Math.max(1, daysBetween(task.start, task.end) + 1);
4072
4063
  const left = offset * cellWidth;
4073
4064
  const width = length * cellWidth;
4074
4065
  const progress = task.progress ?? 0;
@@ -4079,14 +4070,14 @@ var Gantt = forwardRef(function Gantt2({
4079
4070
  style: { height: rowHeight },
4080
4071
  children: [
4081
4072
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 flex pointer-events-none", children: headerDates.map((d, i) => {
4082
- const isWeekend = d.getDay() === 0 || d.getDay() === 6;
4073
+ const weekend = isWeekend(d);
4083
4074
  return /* @__PURE__ */ jsx(
4084
4075
  "div",
4085
4076
  {
4086
4077
  style: { width: cellWidth },
4087
4078
  className: cn(
4088
4079
  "border-r border-border/60",
4089
- isWeekend && hasWeekends && "bg-muted/30"
4080
+ weekend && hasWeekends && "bg-muted/30"
4090
4081
  )
4091
4082
  },
4092
4083
  i
@@ -4097,7 +4088,7 @@ var Gantt = forwardRef(function Gantt2({
4097
4088
  {
4098
4089
  type: "button",
4099
4090
  role: "button",
4100
- "aria-label": `${typeof task.label === "string" ? task.label : task.id}: ${task.start.toLocaleDateString()} \u2013 ${task.end.toLocaleDateString()}`,
4091
+ "aria-label": `${typeof task.label === "string" ? task.label : task.id}: ${task.start.toLocaleString()} \u2013 ${task.end.toLocaleString()}`,
4101
4092
  onClick: () => onTaskClick?.(task),
4102
4093
  style: {
4103
4094
  left: left + 4,
@@ -4146,9 +4137,9 @@ var Gantt = forwardRef(function Gantt2({
4146
4137
  if (fromIdx == null || toIdx == null) return null;
4147
4138
  const fromTask = tasks[fromIdx];
4148
4139
  const toTask = tasks[toIdx];
4149
- const fromX = (dayDiff(from, fromTask.end) + 1) * cellWidth;
4140
+ const fromX = (daysBetween(from, fromTask.end) + 1) * cellWidth;
4150
4141
  const fromY = fromIdx * rowHeight + rowHeight / 2;
4151
- const toX = dayDiff(from, toTask.start) * cellWidth;
4142
+ const toX = daysBetween(from, toTask.start) * cellWidth;
4152
4143
  const toY = toIdx * rowHeight + rowHeight / 2;
4153
4144
  const midX = Math.max(fromX + 8, (fromX + toX) / 2);
4154
4145
  const path = `M ${fromX} ${fromY} L ${midX} ${fromY} L ${midX} ${toY} L ${toX - 4} ${toY}`;
@@ -4164,7 +4155,7 @@ var Gantt = forwardRef(function Gantt2({
4164
4155
  ] }, i);
4165
4156
  }),
4166
4157
  milestones.map((m) => {
4167
- const x = dayDiff(from, m.date) * cellWidth + cellWidth / 2;
4158
+ const x = daysBetween(from, m.date) * cellWidth + cellWidth / 2;
4168
4159
  return /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx(
4169
4160
  "polygon",
4170
4161
  {
@@ -4194,38 +4185,10 @@ var Gantt = forwardRef(function Gantt2({
4194
4185
  }
4195
4186
  );
4196
4187
  });
4197
- function startOfDay(d) {
4198
- const c = new Date(d);
4199
- c.setHours(0, 0, 0, 0);
4200
- return c;
4201
- }
4202
- function isSameDay(a, b) {
4203
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
4204
- }
4205
- function isToday(d) {
4206
- return isSameDay(d, /* @__PURE__ */ new Date());
4207
- }
4208
- function addDays(d, n) {
4209
- const c = new Date(d);
4210
- c.setDate(c.getDate() + n);
4211
- return c;
4212
- }
4213
- function addMonths(d, n) {
4214
- const c = new Date(d);
4215
- c.setMonth(d.getMonth() + n, d.getDate());
4216
- return c;
4217
- }
4218
4188
  function startOfWeek(d, weekStart) {
4219
- const c = startOfDay(d);
4220
- const diff = (c.getDay() - weekStart + 7) % 7;
4221
- c.setDate(c.getDate() - diff);
4222
- return c;
4223
- }
4224
- function isInRange(d, start, end) {
4225
- return d >= startOfDay(start) && d <= startOfDay(end);
4226
- }
4227
- function minutesSince(reference, target) {
4228
- return (target.getTime() - reference.getTime()) / 6e4;
4189
+ const sundayIdx = d.dayOfWeek % 7;
4190
+ const diff = (sundayIdx - weekStart + 7) % 7;
4191
+ return d.subtract({ days: diff });
4229
4192
  }
4230
4193
  var EventCalendar = forwardRef(
4231
4194
  function EventCalendar2({
@@ -4250,57 +4213,60 @@ var EventCalendar = forwardRef(
4250
4213
  });
4251
4214
  const [date, setDate] = useControlled({
4252
4215
  controlled: dateProp,
4253
- default: defaultDate ?? /* @__PURE__ */ new Date(),
4216
+ default: defaultDate ?? nowZoned(),
4254
4217
  onChange: onDateChange
4255
4218
  });
4219
+ const focusDay = useMemo(() => date.toPlainDate(), [date]);
4256
4220
  const sortedEvents = useMemo(
4257
- () => [...events].sort((a, b) => a.start.getTime() - b.start.getTime()),
4221
+ () => [...events].sort(
4222
+ (a, b) => Temporal.ZonedDateTime.compare(a.start, b.start)
4223
+ ),
4258
4224
  [events]
4259
4225
  );
4260
4226
  const goPrev = () => {
4261
4227
  switch (view) {
4262
4228
  case "month":
4263
- setDate(addMonths(date, -1));
4229
+ setDate(date.add({ months: -1 }));
4264
4230
  break;
4265
4231
  case "week":
4266
- setDate(addDays(date, -7));
4232
+ setDate(date.add({ days: -7 }));
4267
4233
  break;
4268
4234
  case "day":
4269
4235
  case "agenda":
4270
- setDate(addDays(date, -1));
4236
+ setDate(date.add({ days: -1 }));
4271
4237
  break;
4272
4238
  }
4273
4239
  };
4274
4240
  const goNext = () => {
4275
4241
  switch (view) {
4276
4242
  case "month":
4277
- setDate(addMonths(date, 1));
4243
+ setDate(date.add({ months: 1 }));
4278
4244
  break;
4279
4245
  case "week":
4280
- setDate(addDays(date, 7));
4246
+ setDate(date.add({ days: 7 }));
4281
4247
  break;
4282
4248
  case "day":
4283
4249
  case "agenda":
4284
- setDate(addDays(date, 1));
4250
+ setDate(date.add({ days: 1 }));
4285
4251
  break;
4286
4252
  }
4287
4253
  };
4288
- const goToday = () => setDate(/* @__PURE__ */ new Date());
4254
+ const goToday = () => setDate(nowZoned());
4289
4255
  const title = useMemo(() => {
4290
4256
  switch (view) {
4291
4257
  case "month":
4292
- return `${MONTHS_LONG[date.getMonth()]} ${date.getFullYear()}`;
4258
+ return `${MONTHS_LONG[focusDay.month - 1]} ${focusDay.year}`;
4293
4259
  case "week": {
4294
- const ws = startOfWeek(date, weekStart);
4260
+ const ws = startOfWeek(focusDay, weekStart);
4295
4261
  const we = addDays(ws, 6);
4296
- return `${ws.toLocaleDateString(void 0, { month: "short", day: "numeric" })} \u2013 ${we.toLocaleDateString(void 0, { month: "short", day: "numeric", year: "numeric" })}`;
4262
+ return `${ws.toLocaleString(void 0, { month: "short", day: "numeric" })} \u2013 ${we.toLocaleString(void 0, { month: "short", day: "numeric", year: "numeric" })}`;
4297
4263
  }
4298
4264
  case "day":
4299
- return date.toLocaleDateString(void 0, { weekday: "long", month: "long", day: "numeric", year: "numeric" });
4265
+ return focusDay.toLocaleString(void 0, { weekday: "long", month: "long", day: "numeric", year: "numeric" });
4300
4266
  case "agenda":
4301
- return `Upcoming from ${date.toLocaleDateString(void 0, { month: "short", day: "numeric" })}`;
4267
+ return `Upcoming from ${focusDay.toLocaleString(void 0, { month: "short", day: "numeric" })}`;
4302
4268
  }
4303
- }, [view, date, weekStart]);
4269
+ }, [view, focusDay, weekStart]);
4304
4270
  return /* @__PURE__ */ jsxs(
4305
4271
  "div",
4306
4272
  {
@@ -4359,7 +4325,8 @@ var EventCalendar = forwardRef(
4359
4325
  view === "month" && /* @__PURE__ */ jsx(
4360
4326
  MonthView,
4361
4327
  {
4362
- date,
4328
+ focusDay,
4329
+ timeZone: date.timeZoneId,
4363
4330
  events: sortedEvents,
4364
4331
  weekStart,
4365
4332
  onEventClick,
@@ -4369,10 +4336,10 @@ var EventCalendar = forwardRef(
4369
4336
  view === "week" && /* @__PURE__ */ jsx(
4370
4337
  TimeGridView,
4371
4338
  {
4372
- date,
4339
+ timeZone: date.timeZoneId,
4373
4340
  events: sortedEvents,
4374
4341
  days: 7,
4375
- firstDay: startOfWeek(date, weekStart),
4342
+ firstDay: startOfWeek(focusDay, weekStart),
4376
4343
  hourRange,
4377
4344
  onEventClick,
4378
4345
  onSlotClick
@@ -4381,33 +4348,32 @@ var EventCalendar = forwardRef(
4381
4348
  view === "day" && /* @__PURE__ */ jsx(
4382
4349
  TimeGridView,
4383
4350
  {
4384
- date,
4351
+ timeZone: date.timeZoneId,
4385
4352
  events: sortedEvents,
4386
4353
  days: 1,
4387
- firstDay: startOfDay(date),
4354
+ firstDay: focusDay,
4388
4355
  hourRange,
4389
4356
  onEventClick,
4390
4357
  onSlotClick
4391
4358
  }
4392
4359
  ),
4393
- view === "agenda" && /* @__PURE__ */ jsx(AgendaView, { date, events: sortedEvents, onEventClick })
4360
+ view === "agenda" && /* @__PURE__ */ jsx(AgendaView, { focusDay, events: sortedEvents, onEventClick })
4394
4361
  ] })
4395
4362
  ]
4396
4363
  }
4397
4364
  );
4398
4365
  }
4399
4366
  );
4400
- function MonthView({ date, events, weekStart, onEventClick, onSlotClick }) {
4367
+ function MonthView({ focusDay, timeZone, events, weekStart, onEventClick, onSlotClick }) {
4401
4368
  const weekdayHeaders = Array.from({ length: 7 }, (_, i) => WEEKDAYS_SHORT[(i + weekStart) % 7]);
4402
- const month = date.getMonth();
4403
- const first = new Date(date.getFullYear(), month, 1);
4404
- const lead = (first.getDay() - weekStart + 7) % 7;
4405
- const gridStart = addDays(first, -lead);
4369
+ const month = focusDay.month;
4370
+ const first = focusDay.with({ day: 1 });
4371
+ const gridStart = startOfWeek(first, weekStart);
4406
4372
  const cells = Array.from({ length: 42 }, (_, i) => {
4407
- const d = addDays(gridStart, i);
4408
- return { date: d, outOfMonth: d.getMonth() !== month };
4373
+ const day = gridStart.add({ days: i });
4374
+ return { day, outOfMonth: day.month !== month };
4409
4375
  });
4410
- const eventsForDay = (d) => events.filter((e) => isInRange(d, e.start, e.end));
4376
+ const eventsForDay = (day) => events.filter((e) => isZonedDayInRange(startOfCellInstant(day, timeZone), e.start, e.end));
4411
4377
  return /* @__PURE__ */ jsxs("div", { className: "grid h-full grid-cols-7 border-l border-t border-border", children: [
4412
4378
  weekdayHeaders.map((wd) => /* @__PURE__ */ jsx(
4413
4379
  "div",
@@ -4418,14 +4384,14 @@ function MonthView({ date, events, weekStart, onEventClick, onSlotClick }) {
4418
4384
  wd
4419
4385
  )),
4420
4386
  cells.map((cell, i) => {
4421
- const cellEvents = eventsForDay(cell.date);
4387
+ const cellEvents = eventsForDay(cell.day);
4422
4388
  return /* @__PURE__ */ jsxs(
4423
4389
  "div",
4424
4390
  {
4425
4391
  className: cn(
4426
4392
  "flex flex-col border-b border-r border-border p-1 text-xs",
4427
4393
  cell.outOfMonth && "bg-muted/20",
4428
- isToday(cell.date) && "bg-primary-soft/20"
4394
+ isToday(cell.day) && "bg-primary-soft/20"
4429
4395
  ),
4430
4396
  style: { minHeight: 96 },
4431
4397
  children: [
@@ -4433,14 +4399,14 @@ function MonthView({ date, events, weekStart, onEventClick, onSlotClick }) {
4433
4399
  "button",
4434
4400
  {
4435
4401
  type: "button",
4436
- onClick: () => onSlotClick?.(cell.date),
4402
+ onClick: () => onSlotClick?.(cell.day),
4437
4403
  className: cn(
4438
4404
  "mb-1 self-start rounded-sm px-1 text-xs tabular-nums transition-colors",
4439
4405
  cell.outOfMonth ? "text-muted-foreground" : "text-foreground",
4440
- isToday(cell.date) && "bg-primary text-primary-foreground",
4406
+ isToday(cell.day) && "bg-primary text-primary-foreground",
4441
4407
  "hover:bg-muted"
4442
4408
  ),
4443
- children: cell.date.getDate()
4409
+ children: cell.day.day
4444
4410
  }
4445
4411
  ),
4446
4412
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
@@ -4457,7 +4423,7 @@ function MonthView({ date, events, weekStart, onEventClick, onSlotClick }) {
4457
4423
  "truncate rounded-sm px-1.5 py-0.5 text-left text-[11px] font-medium transition-colors hover:brightness-95",
4458
4424
  !e.color && "bg-primary-soft text-primary-soft-foreground"
4459
4425
  ),
4460
- "aria-label": `${typeof e.title === "string" ? e.title : e.id} at ${e.start.toLocaleTimeString()}`,
4426
+ "aria-label": `${typeof e.title === "string" ? e.title : e.id} at ${formatZonedTime(e.start)}`,
4461
4427
  children: [
4462
4428
  e.isAllDay ? "\u2022 " : "",
4463
4429
  e.title ?? "(no title)"
@@ -4478,13 +4444,17 @@ function MonthView({ date, events, weekStart, onEventClick, onSlotClick }) {
4478
4444
  })
4479
4445
  ] });
4480
4446
  }
4481
- function TimeGridView({ events, days, firstDay, hourRange, onEventClick, onSlotClick }) {
4447
+ function startOfCellInstant(day, timeZone) {
4448
+ return zonedAtHour(day, 0, timeZone);
4449
+ }
4450
+ function TimeGridView({ timeZone, events, days, firstDay, hourRange, onEventClick, onSlotClick }) {
4482
4451
  const [startHour, endHour] = hourRange;
4483
4452
  const visibleHours = endHour - startHour;
4484
4453
  const HOUR_PX = 48;
4485
- const dayDates = Array.from({ length: days }, (_, i) => addDays(firstDay, i));
4486
- const eventsForDay = (d) => events.filter((e) => !e.isAllDay && isSameDay(d, e.start));
4487
- const allDayForDay = (d) => events.filter((e) => e.isAllDay && isInRange(d, e.start, e.end));
4454
+ const dayDates = Array.from({ length: days }, (_, i) => firstDay.add({ days: i }));
4455
+ const eventsForDay = (day) => events.filter((e) => !e.isAllDay && isZonedOnDay(e.start, day));
4456
+ const allDayForDay = (day) => events.filter((e) => e.isAllDay && isZonedDayInRange(startOfCellInstant(day, timeZone), e.start, e.end));
4457
+ const now = nowZoned();
4488
4458
  return /* @__PURE__ */ jsxs("div", { className: "flex", children: [
4489
4459
  /* @__PURE__ */ jsxs("div", { className: "w-14 shrink-0 border-r border-border", children: [
4490
4460
  /* @__PURE__ */ jsx("div", { className: "h-6 border-b border-border bg-muted/40" }),
@@ -4510,7 +4480,7 @@ function TimeGridView({ events, days, firstDay, hourRange, onEventClick, onSlotC
4510
4480
  "h-6 border-b border-r border-border bg-muted/40 px-2 text-xs font-medium",
4511
4481
  isToday(d) && "bg-primary-soft/30"
4512
4482
  ),
4513
- children: d.toLocaleDateString(void 0, { weekday: "short", day: "numeric" })
4483
+ children: d.toLocaleString(void 0, { weekday: "short", day: "numeric" })
4514
4484
  },
4515
4485
  `h-${i}`
4516
4486
  )),
@@ -4543,8 +4513,8 @@ function TimeGridView({ events, days, firstDay, hourRange, onEventClick, onSlotC
4543
4513
  }),
4544
4514
  dayDates.map((d, di) => {
4545
4515
  const list = eventsForDay(d);
4546
- const dayStart = new Date(d);
4547
- dayStart.setHours(startHour, 0, 0, 0);
4516
+ const dayStart = zonedAtHour(d, startHour, timeZone);
4517
+ const dayEnd = zonedAtHour(d, endHour, timeZone);
4548
4518
  return /* @__PURE__ */ jsxs(
4549
4519
  "div",
4550
4520
  {
@@ -4561,8 +4531,7 @@ function TimeGridView({ events, days, firstDay, hourRange, onEventClick, onSlotC
4561
4531
  i
4562
4532
  )),
4563
4533
  isToday(d) && (() => {
4564
- const now = /* @__PURE__ */ new Date();
4565
- const minutes = now.getHours() * 60 + now.getMinutes() - startHour * 60;
4534
+ const minutes = minutesBetween(dayStart, now);
4566
4535
  if (minutes < 0 || minutes > visibleHours * 60) return null;
4567
4536
  const top = minutes / 60 * HOUR_PX;
4568
4537
  return /* @__PURE__ */ jsx(
@@ -4575,12 +4544,10 @@ function TimeGridView({ events, days, firstDay, hourRange, onEventClick, onSlotC
4575
4544
  );
4576
4545
  })(),
4577
4546
  list.map((e) => {
4578
- const start = e.start < dayStart ? dayStart : e.start;
4579
- const dayEnd = new Date(d);
4580
- dayEnd.setHours(endHour, 0, 0, 0);
4581
- const end = e.end > dayEnd ? dayEnd : e.end;
4582
- const topMin = minutesSince(dayStart, start);
4583
- const durMin = Math.max(15, minutesSince(start, end));
4547
+ const start = maxZoned(e.start, dayStart);
4548
+ const end = minZoned(e.end, dayEnd);
4549
+ const topMin = minutesBetween(dayStart, start);
4550
+ const durMin = Math.max(15, minutesBetween(start, end));
4584
4551
  const top = topMin / 60 * HOUR_PX;
4585
4552
  const height = durMin / 60 * HOUR_PX;
4586
4553
  return /* @__PURE__ */ jsxs(
@@ -4604,7 +4571,7 @@ function TimeGridView({ events, days, firstDay, hourRange, onEventClick, onSlotC
4604
4571
  ),
4605
4572
  children: [
4606
4573
  /* @__PURE__ */ jsx("div", { className: "truncate", children: e.title ?? "(no title)" }),
4607
- /* @__PURE__ */ jsx("div", { className: "text-[10px] opacity-80 tabular-nums", children: start.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }) })
4574
+ /* @__PURE__ */ jsx("div", { className: "text-[10px] opacity-80 tabular-nums", children: formatZonedTime(start) })
4608
4575
  ]
4609
4576
  },
4610
4577
  e.id
@@ -4618,12 +4585,16 @@ function TimeGridView({ events, days, firstDay, hourRange, onEventClick, onSlotC
4618
4585
  ] }) })
4619
4586
  ] });
4620
4587
  }
4621
- function AgendaView({ date, events, onEventClick }) {
4622
- const horizon = addDays(date, 30);
4623
- const upcoming = events.filter((e) => e.end >= date && e.start <= horizon);
4588
+ function AgendaView({ focusDay, events, onEventClick }) {
4589
+ const horizon = focusDay.add({ days: 30 });
4590
+ const upcoming = events.filter((e) => {
4591
+ const startDay = e.start.toPlainDate();
4592
+ const endDay = e.end.toPlainDate();
4593
+ return Temporal.PlainDate.compare(endDay, focusDay) >= 0 && Temporal.PlainDate.compare(startDay, horizon) <= 0;
4594
+ });
4624
4595
  const groups = /* @__PURE__ */ new Map();
4625
4596
  for (const e of upcoming) {
4626
- const key = e.start.toDateString();
4597
+ const key = e.start.toPlainDate().toString();
4627
4598
  const list = groups.get(key);
4628
4599
  if (list) list.push(e);
4629
4600
  else groups.set(key, [e]);
@@ -4632,16 +4603,16 @@ function AgendaView({ date, events, onEventClick }) {
4632
4603
  return /* @__PURE__ */ jsx("div", { className: "p-6 text-center text-sm text-muted-foreground", children: "No upcoming events." });
4633
4604
  }
4634
4605
  return /* @__PURE__ */ jsx("ul", { className: "divide-y divide-border", children: Array.from(groups.entries()).map(([key, list]) => {
4635
- const groupDate = list[0].start;
4606
+ const groupDay = list[0].start.toPlainDate();
4636
4607
  return /* @__PURE__ */ jsxs("li", { className: "px-4 py-3", children: [
4637
4608
  /* @__PURE__ */ jsx(
4638
4609
  "div",
4639
4610
  {
4640
4611
  className: cn(
4641
4612
  "mb-2 text-xs font-semibold uppercase text-muted-foreground",
4642
- isToday(groupDate) && "text-primary"
4613
+ isToday(groupDay) && "text-primary"
4643
4614
  ),
4644
- children: groupDate.toLocaleDateString(void 0, {
4615
+ children: groupDay.toLocaleString(void 0, {
4645
4616
  weekday: "long",
4646
4617
  month: "short",
4647
4618
  day: "numeric"
@@ -4665,7 +4636,7 @@ function AgendaView({ date, events, onEventClick }) {
4665
4636
  ),
4666
4637
  /* @__PURE__ */ jsxs("span", { className: "flex-1", children: [
4667
4638
  /* @__PURE__ */ jsx("span", { className: "block text-sm font-medium", children: e.title ?? "(no title)" }),
4668
- /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground tabular-nums", children: e.isAllDay ? "All day" : `${e.start.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })} \u2013 ${e.end.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}` })
4639
+ /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground tabular-nums", children: e.isAllDay ? "All day" : `${formatZonedTime(e.start)} \u2013 ${formatZonedTime(e.end)}` })
4669
4640
  ] })
4670
4641
  ]
4671
4642
  }
@@ -5966,5 +5937,5 @@ var Sortable = Object.assign(SortableRoot, {
5966
5937
  });
5967
5938
 
5968
5939
  export { Accordion2 as Accordion, AccordionContent, AccordionItem, AccordionTrigger, ActivityFeed, ActivityItem, AnimatedNumber, AnnotationMarker, AudioPlayer, AudioWaveform, Avatar, AvatarGroup, Badge, BadgeOverlay, Card, Carousel2 as Carousel, CarouselDot, CarouselDots, CarouselNext, CarouselPrev, CarouselSlide, CarouselSlides, CarouselViewport, ChatBubble, Code, Collapsible2 as Collapsible, CollapsibleContent, CollapsibleTrigger, Comment, CommentThread, Confetti, CountBadge, CountUp, DataGrid, DataTable, DaySeparator, DescriptionList, DiffViewer, EmptyState, EventCalendar, Eyebrow, FeatureCard, Gantt, GradientText, Heading, HeatmapCalendar, Highlight, Image, InfoRow, KeyboardShortcut, List2 as List, ListItem, Mark, Marquee, MessageList, MetaInline, MetricChip, NodeEditor, NotificationDot, PDFViewer, PricingCard, Quote, ReactionBar, ScheduleView, ScrollReveal, SectionHeader, Separator, Snippet, Sortable, Sparkline, Stat, Status, StepCard, SwipeActions, Table2 as Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeaderCell, TableRow, Tabs2 as Tabs, TabsList, TabsPanel, TabsTab, Text, ThreadView, Tilt, Timeline2 as Timeline, TimelineDescription, TimelineItem, TimelineTitle, Tree2 as Tree, TreeGroup, TreeItem, Typewriter, VideoPlayer, avatarVariants, badgeVariants, codeVariants, headingVariants, textVariants };
5969
- //# sourceMappingURL=chunk-X3JVVEUJ.js.map
5970
- //# sourceMappingURL=chunk-X3JVVEUJ.js.map
5940
+ //# sourceMappingURL=chunk-UFTKE5U7.js.map
5941
+ //# sourceMappingURL=chunk-UFTKE5U7.js.map