@nomideusz/svelte-calendar 0.8.0 → 0.9.0

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/README.md CHANGED
@@ -706,7 +706,20 @@ Call `resetLabels()` to restore English defaults (`defaultLabels` exports them;
706
706
 
707
707
  ## Timezone Support
708
708
 
709
- Convert events between timezones using the built-in helpers:
709
+ Render the whole calendar in any IANA timezone — events, the now-indicator
710
+ and day boundaries all shift; ranges passed to `oneventcreate`/`oneventmove`
711
+ convert back to real instants:
712
+
713
+ ```svelte
714
+ <Calendar {adapter} timezone="Europe/Warsaw" />
715
+ ```
716
+
717
+ Under the hood the adapter is wrapped with `wrapAdapterWithTimezone` (also
718
+ exported) so views do plain local-time math on a zoned wall-clock plane.
719
+ Known limit shared by every wall-clock calendar: the repeated hour of a DST
720
+ fall-back is ambiguous, writes inside it resolve to one of the two instants.
721
+
722
+ Convert events manually with the built-in helpers:
710
723
 
711
724
  ```ts
712
725
  import { toZonedTime, fromZonedTime, nowInZone } from '@nomideusz/svelte-calendar';
@@ -30,6 +30,7 @@ import Planner from "../views/planner/Planner.svelte";
30
30
  import Agenda from "../views/agenda/Agenda.svelte";
31
31
  import Mobile from "../views/mobile/Mobile.svelte";
32
32
  import MonthGrid from "../views/month/MonthGrid.svelte";
33
+ import { wrapAdapterWithTimezone, toZonedTime, fromZonedTime } from "../core/timezone.js";
33
34
  const MOBILE_BREAKPOINT = 768;
34
35
  const DEFAULT_VIEWS = [
35
36
  { id: "day-planner", label: "Planner", mode: "day", component: Planner },
@@ -80,10 +81,16 @@ let {
80
81
  ondatechange,
81
82
  oneventhover,
82
83
  ondayclick,
83
- onerror
84
+ onerror,
85
+ timezone
84
86
  } = $props();
85
- const effectiveCreate = $derived(readOnly ? void 0 : oneventcreate);
86
- const effectiveMove = $derived(readOnly ? void 0 : oneventmove);
87
+ const unzone = (d) => timezone ? fromZonedTime(d, timezone) : d;
88
+ const effectiveCreate = $derived(
89
+ readOnly || !oneventcreate ? void 0 : (range) => oneventcreate({ start: unzone(range.start), end: unzone(range.end) })
90
+ );
91
+ const effectiveMove = $derived(
92
+ readOnly || !oneventmove ? void 0 : (ev, start, end) => oneventmove(ev, unzone(start), unzone(end))
93
+ );
87
94
  function handleEventClick(ev) {
88
95
  selection.select(ev.id);
89
96
  oneventclick?.(ev);
@@ -114,12 +121,17 @@ onMount(() => {
114
121
  };
115
122
  });
116
123
  const effectiveTheme = $derived(theme === auto && autoTheme !== false ? probedTheme : theme);
117
- const store = $derived(createEventStore(adapter));
124
+ const effectiveAdapter = $derived(
125
+ timezone ? wrapAdapterWithTimezone(adapter, timezone) : adapter
126
+ );
127
+ const store = $derived(createEventStore(effectiveAdapter));
118
128
  const viewState = createViewState(untrack(() => ({
119
129
  view: activeViewId ?? views[0]?.id,
120
130
  mondayStart,
121
- initialDate,
131
+ // Focus lives on the zoned plane too — day boundaries follow the zone.
132
+ initialDate: initialDate && timezone ? toZonedTime(initialDate, timezone) : initialDate,
122
133
  dayCount: days,
134
+ timezone,
123
135
  modeForView: (viewId) => views.find((v) => v.id === viewId)?.mode
124
136
  })));
125
137
  const selection = createSelection();
@@ -223,6 +235,9 @@ setContext("calendar", {
223
235
  get ondayclick() {
224
236
  return ondayclick;
225
237
  },
238
+ get timezone() {
239
+ return timezone;
240
+ },
226
241
  // Config (reactive via getters)
227
242
  get readOnly() {
228
243
  return readOnly;
@@ -116,6 +116,13 @@ interface Props {
116
116
  ondayclick?: (date: Date) => void;
117
117
  /** Surfaced instead of silent console output when loading or mutations fail. */
118
118
  onerror?: (error: Error) => void;
119
+ /**
120
+ * Render the calendar in an IANA timezone (e.g. 'Europe/Warsaw').
121
+ * Events, "now" and day boundaries all shift; ranges passed to
122
+ * oneventcreate/oneventmove convert back to real instants.
123
+ * Default: the viewer's local time.
124
+ */
125
+ timezone?: string;
119
126
  }
120
127
  declare const Calendar: Component<Props, {}, "">;
121
128
  type Calendar = ReturnType<typeof Calendar>;
@@ -18,4 +18,4 @@ export interface Clock {
18
18
  * Must be called during component initialisation (before first await).
19
19
  * Automatically cleans up on unmount via onMount return.
20
20
  */
21
- export declare function createClock(): Clock;
21
+ export declare function createClock(timezone?: string): Clock;
@@ -13,19 +13,23 @@
13
13
  */
14
14
  import { onMount } from 'svelte';
15
15
  import { sod, fmtHM, fmtS, fractionalHour } from './time.js';
16
+ import { toZonedTime } from './timezone.js';
16
17
  /**
17
18
  * Create a shared reactive clock.
18
19
  *
19
20
  * Must be called during component initialisation (before first await).
20
21
  * Automatically cleans up on unmount via onMount return.
21
22
  */
22
- export function createClock() {
23
- let tick = $state(Date.now());
24
- let today = $state(sod(Date.now()));
23
+ export function createClock(timezone) {
24
+ // With a timezone, ticks are "zoned wall-clock" epoch ms — the same plane
25
+ // the wrapped adapter shifts event Dates into. Views stay zone-agnostic.
26
+ const now = () => (timezone ? toZonedTime(Date.now(), timezone).getTime() : Date.now());
27
+ let tick = $state(now());
28
+ let today = $state(sod(tick));
25
29
  let intervalId = null;
26
30
  function start() {
27
31
  intervalId = setInterval(() => {
28
- tick = Date.now();
32
+ tick = now();
29
33
  const sd = sod(tick);
30
34
  if (sd !== today)
31
35
  today = sd;
@@ -20,3 +20,15 @@ export declare function nowInZone(timezone: string): Date;
20
20
  * Returns a locale-aware string.
21
21
  */
22
22
  export declare function formatInTimeZone(date: Date | number, timezone: string, options?: Intl.DateTimeFormatOptions, locale?: string): string;
23
+ /**
24
+ * Wrap a CalendarAdapter so everything it emits is expressed as wall-clock
25
+ * Dates in `timezone`, and everything written through it is converted back to
26
+ * real instants. This is how the Calendar's `timezone` prop works: views keep
27
+ * doing plain local-time math on an already-shifted plane.
28
+ *
29
+ * Known limit shared by every wall-clock calendar UI: during a DST fall-back
30
+ * the repeated hour is ambiguous on the wall clock, so writes made inside it
31
+ * resolve to one of the two instants (date-fns-tz picks the offset).
32
+ */
33
+ import type { CalendarAdapter } from '../adapters/types.js';
34
+ export declare function wrapAdapterWithTimezone(adapter: CalendarAdapter, timezone: string): CalendarAdapter;
@@ -51,3 +51,34 @@ export function formatInTimeZone(date, timezone, options = {}, locale) {
51
51
  timeZone: timezone,
52
52
  }).format(d);
53
53
  }
54
+ export function wrapAdapterWithTimezone(adapter, timezone) {
55
+ const zoneEvent = (ev) => ({
56
+ ...ev,
57
+ start: toZonedTime(ev.start, timezone),
58
+ end: toZonedTime(ev.end, timezone),
59
+ });
60
+ const unzonePartial = (obj) => ({
61
+ ...obj,
62
+ ...(obj.start instanceof Date ? { start: fromZonedTime(obj.start, timezone) } : {}),
63
+ ...(obj.end instanceof Date ? { end: fromZonedTime(obj.end, timezone) } : {}),
64
+ });
65
+ const wrapped = {
66
+ async fetchEvents(range) {
67
+ const events = await adapter.fetchEvents({
68
+ start: fromZonedTime(range.start, timezone),
69
+ end: fromZonedTime(range.end, timezone),
70
+ });
71
+ return events.map(zoneEvent);
72
+ },
73
+ };
74
+ if (adapter.createEvent) {
75
+ wrapped.createEvent = async (event) => zoneEvent(await adapter.createEvent(unzonePartial(event)));
76
+ }
77
+ if (adapter.updateEvent) {
78
+ wrapped.updateEvent = async (id, patch) => zoneEvent(await adapter.updateEvent(id, unzonePartial(patch)));
79
+ }
80
+ if (adapter.deleteEvent) {
81
+ wrapped.deleteEvent = (id) => adapter.deleteEvent(id);
82
+ }
83
+ return wrapped;
84
+ }
@@ -42,15 +42,18 @@
42
42
  import { untrack } from 'svelte';
43
43
  import { createEventStore } from '../engine/event-store.svelte.js';
44
44
  import { createViewState } from '../engine/view-state.svelte.js';
45
+ import { toZonedTime, fromZonedTime, wrapAdapterWithTimezone } from '../core/timezone.js';
45
46
  import { createSelection } from '../engine/selection.svelte.js';
46
47
  import { createDragState } from '../engine/drag.svelte.js';
47
48
  import { createClock } from '../core/clock.svelte.js';
48
49
  import { sod, DAY_MS, HOUR_MS, startOfWeek as sowFn, isAllDay, isMultiDay, segmentForDay, } from '../core/time.js';
49
50
  import { monthLong, weekdayLong, weekdayShort } from '../core/locale.js';
50
51
  export function createCalendar(options) {
51
- const { adapter, mondayStart: initialMondayStart = true, initialDate, locale, visibleHours, snapInterval = 15, equalDays = false, hideDays, blockedSlots, disabledDates, days: initialDayCount = 7, readOnly = false, minDuration, maxDuration, oneventclick, oneventcreate, oneventmove, } = options;
52
+ const { adapter, mondayStart: initialMondayStart = true, initialDate: rawInitialDate, locale, visibleHours, snapInterval = 15, equalDays = false, hideDays, blockedSlots, disabledDates, days: initialDayCount = 7, readOnly = false, minDuration, maxDuration, oneventclick, oneventcreate, oneventmove, } = options;
52
53
  // ── Create engine ────────────────────────────────────
53
- const store = createEventStore(adapter);
54
+ const timezone = options.timezone;
55
+ const initialDate = rawInitialDate && timezone ? toZonedTime(rawInitialDate, timezone) : rawInitialDate;
56
+ const store = createEventStore(timezone ? wrapAdapterWithTimezone(adapter, timezone) : adapter);
54
57
  const viewState = createViewState({
55
58
  view: options.view ?? 'week-planner',
56
59
  mondayStart: initialMondayStart,
@@ -60,7 +63,8 @@ export function createCalendar(options) {
60
63
  });
61
64
  const selection = createSelection();
62
65
  const drag = createDragState();
63
- const clock = createClock();
66
+ const clock = createClock(timezone);
67
+ const unzoneDate = (d) => (timezone ? fromZonedTime(d, timezone) : d);
64
68
  // ── Computed ──────────────────────────────────────────
65
69
  const disabledSet = $derived(new Set(disabledDates?.map((d) => sod(d.getTime())) ?? []));
66
70
  const startHour = visibleHours?.[0] ?? 0;
@@ -281,7 +285,7 @@ export function createCalendar(options) {
281
285
  await store.move(payload.eventId, start, end);
282
286
  const ev = store.byId(payload.eventId);
283
287
  if (ev)
284
- oneventmove?.(ev, start, end);
288
+ oneventmove?.(ev, unzoneDate(start), unzoneDate(end));
285
289
  }
286
290
  catch (e) {
287
291
  const msg = e instanceof Error ? e.message : '';
@@ -290,7 +294,7 @@ export function createCalendar(options) {
290
294
  if (msg.includes('read-only')) {
291
295
  const ev = store.byId(payload.eventId);
292
296
  if (ev)
293
- oneventmove?.(ev, start, end);
297
+ oneventmove?.(ev, unzoneDate(start), unzoneDate(end));
294
298
  }
295
299
  else if (!msg.includes('not found')) {
296
300
  console.warn('[calendar] drag commit failed:', e);
@@ -299,7 +303,9 @@ export function createCalendar(options) {
299
303
  }
300
304
  }
301
305
  else if (mode === 'create') {
302
- oneventcreate?.({ start, end });
306
+ oneventcreate?.(timezone
307
+ ? { start: fromZonedTime(start, timezone), end: fromZonedTime(end, timezone) }
308
+ : { start, end });
303
309
  }
304
310
  return result;
305
311
  }
@@ -22,6 +22,8 @@ export interface HeadlessCalendarOptions {
22
22
  mondayStart?: boolean;
23
23
  /** Initial date to focus on (default: today) */
24
24
  initialDate?: Date;
25
+ /** Render in an IANA timezone; events, "now" and day boundaries shift. */
26
+ timezone?: string;
25
27
  /** BCP 47 locale tag (e.g. 'en-US', 'pl-PL') */
26
28
  locale?: string;
27
29
  /** Visible hour range [startHour, endHour). Default: [0, 24] */
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ export { createClock, startOfWeek, fmtH, fmtTime, fmtDuration, weekdayShort, wee
11
11
  export type { Clock, TimelineEvent, BlockedSlot, DaySegment, CalendarLabels, EventStatus, TextMeasure, TextMeasureOptions, ContentFit, } from './core/index.js';
12
12
  export { auto, neutral, midnight, presets } from './theme/index.js';
13
13
  export { probeHostTheme, observeHostTheme } from './theme/index.js';
14
+ export { wrapAdapterWithTimezone } from './core/timezone.js';
14
15
  export type { PresetName, AutoThemeOptions } from './theme/index.js';
15
16
  export { createCalendar, createAgenda } from './headless/index.js';
16
17
  export type { HeadlessCalendarOptions, HeadlessCalendar, HeadlessDay, HeadlessWeek, TodayQueue, HeaderContext, NavigationContext, AgendaOptions, HeadlessAgenda, } from './headless/index.js';
package/dist/index.js CHANGED
@@ -14,5 +14,6 @@ export { createClock, startOfWeek, fmtH, fmtTime, fmtDuration, weekdayShort, wee
14
14
  // ─── Themes ─────────────────────────────────────────────
15
15
  export { auto, neutral, midnight, presets } from './theme/index.js';
16
16
  export { probeHostTheme, observeHostTheme } from './theme/index.js';
17
+ export { wrapAdapterWithTimezone } from './core/timezone.js';
17
18
  // ─── Headless API ───────────────────────────────────────
18
19
  export { createCalendar, createAgenda } from './headless/index.js';
@@ -16,7 +16,7 @@ let {
16
16
  oneventclick,
17
17
  selectedEventId = null
18
18
  } = $props();
19
- const clock = createClock();
19
+ const clock = createClock(ctx.timezone);
20
20
  const viewState = $derived(ctx.viewState);
21
21
  const equalDays = $derived(ctx.equalDays);
22
22
  const isMobile = $derived(ctx.isMobile);
@@ -16,7 +16,7 @@ let {
16
16
  oneventclick,
17
17
  selectedEventId = null
18
18
  } = $props();
19
- const clock = createClock();
19
+ const clock = createClock(ctx.timezone);
20
20
  const viewState = $derived(ctx.viewState);
21
21
  const equalDays = $derived(ctx.equalDays);
22
22
  const showDates = $derived(ctx.showDates);
@@ -35,7 +35,7 @@ const blockedSlots = $derived(ctx.blockedSlots);
35
35
  const drag = $derived(ctx.drag);
36
36
  const commitDragCtx = $derived(ctx.commitDrag);
37
37
  const SNAP_MS = $derived(ctx.snapInterval * 6e4);
38
- const clock = createClock();
38
+ const clock = createClock(ctx.timezone);
39
39
  const HOUR_HEIGHT = 64;
40
40
  const GUTTER_W = 40;
41
41
  const startHour = $derived(visibleHours?.[0] ?? 0);
@@ -34,7 +34,7 @@ const oneventhover = $derived(ctx.oneventhover);
34
34
  const disabledSet = $derived(ctx.disabledSet);
35
35
  const loadRangeCtx = $derived(ctx.loadRange);
36
36
  const minDuration = $derived(ctx.minDuration);
37
- const clock = createClock();
37
+ const clock = createClock(ctx.timezone);
38
38
  const MAX_EVENTS = 3;
39
39
  const customDays = $derived(viewState?.dayCount ?? 7);
40
40
  const todayMs = $derived(clock.today);
@@ -29,7 +29,7 @@ const oneventhover = $derived(ctx.oneventhover);
29
29
  const ondayclick = $derived(ctx.ondayclick);
30
30
  const eventSnippet = $derived(ctx.eventSnippet);
31
31
  const loadRangeCtx = $derived(ctx.loadRange);
32
- const clock = createClock();
32
+ const clock = createClock(ctx.timezone);
33
33
  const todayMs = $derived(clock.today);
34
34
  const MAX_CHIPS = $derived(isMobile ? 2 : 3);
35
35
  const range = $derived(viewState?.range);
@@ -29,7 +29,7 @@ let {
29
29
  visibleHours
30
30
  } = $props();
31
31
  const ctx = useCalendarContext();
32
- const clock = createClock();
32
+ const clock = createClock(ctx.timezone);
33
33
  const drag = $derived(ctx.drag);
34
34
  const commitDragCtx = $derived(ctx.commitDrag);
35
35
  const viewState = $derived(ctx.viewState);
@@ -32,7 +32,7 @@ let {
32
32
  readOnly = false
33
33
  } = $props();
34
34
  const ctx = useCalendarContext();
35
- const clock = createClock();
35
+ const clock = createClock(ctx.timezone);
36
36
  const ANIM = $derived(prefersReducedMotion.current ? 0 : 180);
37
37
  const [previewSend, previewReceive] = crossfade({ duration: () => prefersReducedMotion.current ? 0 : 160 });
38
38
  const drag = $derived(ctx.drag);
@@ -24,6 +24,7 @@ export interface CalendarContext {
24
24
  readonly maxDuration: number | undefined;
25
25
  readonly oneventhover: ((event: TimelineEvent) => void) | undefined;
26
26
  readonly ondayclick: ((date: Date) => void) | undefined;
27
+ readonly timezone: string | undefined;
27
28
  readonly disabledDates: Date[] | undefined;
28
29
  readonly disabledSet: Set<number>;
29
30
  readonly loadRange: {
@@ -31,6 +31,7 @@ export function useCalendarContext() {
31
31
  get maxDuration() { return raw?.maxDuration; },
32
32
  get oneventhover() { return raw?.oneventhover; },
33
33
  get ondayclick() { return raw?.ondayclick; },
34
+ get timezone() { return raw?.timezone; },
34
35
  get disabledDates() { return raw?.disabledDates; },
35
36
  get disabledSet() { return new Set(raw?.disabledDates?.map(d => sod(d.getTime())) ?? []); },
36
37
  get loadRange() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomideusz/svelte-calendar",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "A themeable Svelte 5 calendar with Day and Week views — Planner and Agenda.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/widget/widget.js CHANGED
@@ -5358,11 +5358,11 @@
5358
5358
  if (date instanceof Date) return new date.constructor(value);
5359
5359
  return new Date(value);
5360
5360
  }
5361
- function toDate(argument, context) {
5361
+ function toDate$1(argument, context) {
5362
5362
  return constructFrom(context || argument, argument);
5363
5363
  }
5364
5364
  function addDays(date, amount, options) {
5365
- const _date = toDate(date, options?.in);
5365
+ const _date = toDate$1(date, options?.in);
5366
5366
  if (isNaN(amount)) return constructFrom(date, NaN);
5367
5367
  if (!amount) return _date;
5368
5368
  _date.setDate(_date.getDate() + amount);
@@ -5375,7 +5375,7 @@
5375
5375
  function startOfWeek$1(date, options) {
5376
5376
  const defaultOptions2 = getDefaultOptions();
5377
5377
  const weekStartsOn = options?.weekStartsOn ?? options?.locale?.options?.weekStartsOn ?? defaultOptions2.weekStartsOn ?? defaultOptions2.locale?.options?.weekStartsOn ?? 0;
5378
- const _date = toDate(date, options?.in);
5378
+ const _date = toDate$1(date, options?.in);
5379
5379
  const day = _date.getDay();
5380
5380
  const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
5381
5381
  _date.setDate(_date.getDate() - diff);
@@ -5383,21 +5383,21 @@
5383
5383
  return _date;
5384
5384
  }
5385
5385
  function startOfDay(date, options) {
5386
- const _date = toDate(date, options?.in);
5386
+ const _date = toDate$1(date, options?.in);
5387
5387
  _date.setHours(0, 0, 0, 0);
5388
5388
  return _date;
5389
5389
  }
5390
5390
  function getDate(date, options) {
5391
- return toDate(date, options?.in).getDate();
5391
+ return toDate$1(date, options?.in).getDate();
5392
5392
  }
5393
5393
  function getHours(date, options) {
5394
- return toDate(date, options?.in).getHours();
5394
+ return toDate$1(date, options?.in).getHours();
5395
5395
  }
5396
5396
  function getMinutes(date, options) {
5397
- return toDate(date, options?.in).getMinutes();
5397
+ return toDate$1(date, options?.in).getMinutes();
5398
5398
  }
5399
5399
  function getSeconds(date) {
5400
- return toDate(date).getSeconds();
5400
+ return toDate$1(date).getSeconds();
5401
5401
  }
5402
5402
  const DAY_MS = 864e5;
5403
5403
  const HOUR_MS = 36e5;
@@ -6307,6 +6307,9 @@
6307
6307
  get ondayclick() {
6308
6308
  return raw?.ondayclick;
6309
6309
  },
6310
+ get timezone() {
6311
+ return raw?.timezone;
6312
+ },
6310
6313
  get disabledDates() {
6311
6314
  return raw?.disabledDates;
6312
6315
  },
@@ -6422,14 +6425,543 @@
6422
6425
  }
6423
6426
  return [transition2(to_send, to_receive, false), transition2(to_receive, to_send, true)];
6424
6427
  }
6425
- function createClock() {
6426
- let tick2 = /* @__PURE__ */ state(proxy(Date.now()));
6427
- let today = /* @__PURE__ */ state(proxy(sod(Date.now())));
6428
+ function tzTokenizeDate(date, timeZone) {
6429
+ const dtf = getDateTimeFormat(timeZone);
6430
+ return "formatToParts" in dtf ? partsOffset(dtf, date) : hackyOffset(dtf, date);
6431
+ }
6432
+ const typeToPos = {
6433
+ year: 0,
6434
+ month: 1,
6435
+ day: 2,
6436
+ hour: 3,
6437
+ minute: 4,
6438
+ second: 5
6439
+ };
6440
+ function partsOffset(dtf, date) {
6441
+ try {
6442
+ const formatted = dtf.formatToParts(date);
6443
+ const filled = [];
6444
+ for (let i = 0; i < formatted.length; i++) {
6445
+ const pos = typeToPos[formatted[i].type];
6446
+ if (pos !== void 0) {
6447
+ filled[pos] = parseInt(formatted[i].value, 10);
6448
+ }
6449
+ }
6450
+ return filled;
6451
+ } catch (error) {
6452
+ if (error instanceof RangeError) {
6453
+ return [NaN];
6454
+ }
6455
+ throw error;
6456
+ }
6457
+ }
6458
+ function hackyOffset(dtf, date) {
6459
+ const formatted = dtf.format(date);
6460
+ const parsed = /(\d+)\/(\d+)\/(\d+),? (\d+):(\d+):(\d+)/.exec(formatted);
6461
+ return [
6462
+ parseInt(parsed[3], 10),
6463
+ parseInt(parsed[1], 10),
6464
+ parseInt(parsed[2], 10),
6465
+ parseInt(parsed[4], 10),
6466
+ parseInt(parsed[5], 10),
6467
+ parseInt(parsed[6], 10)
6468
+ ];
6469
+ }
6470
+ const dtfCache = {};
6471
+ const testDateFormatted = new Intl.DateTimeFormat("en-US", {
6472
+ hourCycle: "h23",
6473
+ timeZone: "America/New_York",
6474
+ year: "numeric",
6475
+ month: "2-digit",
6476
+ day: "2-digit",
6477
+ hour: "2-digit",
6478
+ minute: "2-digit",
6479
+ second: "2-digit"
6480
+ }).format(/* @__PURE__ */ new Date("2014-06-25T04:00:00.123Z"));
6481
+ const hourCycleSupported = testDateFormatted === "06/25/2014, 00:00:00" || testDateFormatted === "‎06‎/‎25‎/‎2014‎ ‎00‎:‎00‎:‎00";
6482
+ function getDateTimeFormat(timeZone) {
6483
+ if (!dtfCache[timeZone]) {
6484
+ dtfCache[timeZone] = hourCycleSupported ? new Intl.DateTimeFormat("en-US", {
6485
+ hourCycle: "h23",
6486
+ timeZone,
6487
+ year: "numeric",
6488
+ month: "numeric",
6489
+ day: "2-digit",
6490
+ hour: "2-digit",
6491
+ minute: "2-digit",
6492
+ second: "2-digit"
6493
+ }) : new Intl.DateTimeFormat("en-US", {
6494
+ hour12: false,
6495
+ timeZone,
6496
+ year: "numeric",
6497
+ month: "numeric",
6498
+ day: "2-digit",
6499
+ hour: "2-digit",
6500
+ minute: "2-digit",
6501
+ second: "2-digit"
6502
+ });
6503
+ }
6504
+ return dtfCache[timeZone];
6505
+ }
6506
+ function newDateUTC(fullYear, month, day, hour, minute, second, millisecond) {
6507
+ const utcDate = /* @__PURE__ */ new Date(0);
6508
+ utcDate.setUTCFullYear(fullYear, month, day);
6509
+ utcDate.setUTCHours(hour, minute, second, millisecond);
6510
+ return utcDate;
6511
+ }
6512
+ const MILLISECONDS_IN_HOUR$1 = 36e5;
6513
+ const MILLISECONDS_IN_MINUTE$1 = 6e4;
6514
+ const patterns$1 = {
6515
+ timezoneZ: /^(Z)$/,
6516
+ timezoneHH: /^([+-]\d{2})$/,
6517
+ timezoneHHMM: /^([+-])(\d{2}):?(\d{2})$/
6518
+ };
6519
+ function tzParseTimezone(timezoneString, date, isUtcDate) {
6520
+ if (!timezoneString) {
6521
+ return 0;
6522
+ }
6523
+ let token = patterns$1.timezoneZ.exec(timezoneString);
6524
+ if (token) {
6525
+ return 0;
6526
+ }
6527
+ let hours;
6528
+ let absoluteOffset;
6529
+ token = patterns$1.timezoneHH.exec(timezoneString);
6530
+ if (token) {
6531
+ hours = parseInt(token[1], 10);
6532
+ if (!validateTimezone(hours)) {
6533
+ return NaN;
6534
+ }
6535
+ return -(hours * MILLISECONDS_IN_HOUR$1);
6536
+ }
6537
+ token = patterns$1.timezoneHHMM.exec(timezoneString);
6538
+ if (token) {
6539
+ hours = parseInt(token[2], 10);
6540
+ const minutes = parseInt(token[3], 10);
6541
+ if (!validateTimezone(hours, minutes)) {
6542
+ return NaN;
6543
+ }
6544
+ absoluteOffset = Math.abs(hours) * MILLISECONDS_IN_HOUR$1 + minutes * MILLISECONDS_IN_MINUTE$1;
6545
+ return token[1] === "+" ? -absoluteOffset : absoluteOffset;
6546
+ }
6547
+ if (isValidTimezoneIANAString(timezoneString)) {
6548
+ date = new Date(date || Date.now());
6549
+ const utcDate = isUtcDate ? date : toUtcDate(date);
6550
+ const offset = calcOffset(utcDate, timezoneString);
6551
+ const fixedOffset = isUtcDate ? offset : fixOffset(date, offset, timezoneString);
6552
+ return -fixedOffset;
6553
+ }
6554
+ return NaN;
6555
+ }
6556
+ function toUtcDate(date) {
6557
+ return newDateUTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
6558
+ }
6559
+ function calcOffset(date, timezoneString) {
6560
+ const tokens = tzTokenizeDate(date, timezoneString);
6561
+ const asUTC = newDateUTC(tokens[0], tokens[1] - 1, tokens[2], tokens[3] % 24, tokens[4], tokens[5], 0).getTime();
6562
+ let asTS = date.getTime();
6563
+ const over = asTS % 1e3;
6564
+ asTS -= over >= 0 ? over : 1e3 + over;
6565
+ return asUTC - asTS;
6566
+ }
6567
+ function fixOffset(date, offset, timezoneString) {
6568
+ const localTS = date.getTime();
6569
+ let utcGuess = localTS - offset;
6570
+ const o2 = calcOffset(new Date(utcGuess), timezoneString);
6571
+ if (offset === o2) {
6572
+ return offset;
6573
+ }
6574
+ utcGuess -= o2 - offset;
6575
+ const o3 = calcOffset(new Date(utcGuess), timezoneString);
6576
+ if (o2 === o3) {
6577
+ return o2;
6578
+ }
6579
+ return Math.max(o2, o3);
6580
+ }
6581
+ function validateTimezone(hours, minutes) {
6582
+ return -23 <= hours && hours <= 23 && (minutes == null || 0 <= minutes && minutes <= 59);
6583
+ }
6584
+ const validIANATimezoneCache = {};
6585
+ function isValidTimezoneIANAString(timeZoneString) {
6586
+ if (validIANATimezoneCache[timeZoneString])
6587
+ return true;
6588
+ try {
6589
+ new Intl.DateTimeFormat(void 0, { timeZone: timeZoneString });
6590
+ validIANATimezoneCache[timeZoneString] = true;
6591
+ return true;
6592
+ } catch (error) {
6593
+ return false;
6594
+ }
6595
+ }
6596
+ function getTimezoneOffsetInMilliseconds(date) {
6597
+ const utcDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));
6598
+ utcDate.setUTCFullYear(date.getFullYear());
6599
+ return +date - +utcDate;
6600
+ }
6601
+ const tzPattern = /(Z|[+-]\d{2}(?::?\d{2})?| UTC| [a-zA-Z]+\/[a-zA-Z_]+(?:\/[a-zA-Z_]+)?)$/;
6602
+ const MILLISECONDS_IN_HOUR = 36e5;
6603
+ const MILLISECONDS_IN_MINUTE = 6e4;
6604
+ const DEFAULT_ADDITIONAL_DIGITS = 2;
6605
+ const patterns = {
6606
+ dateTimePattern: /^([0-9W+-]+)(T| )(.*)/,
6607
+ datePattern: /^([0-9W+-]+)(.*)/,
6608
+ // year tokens
6609
+ YY: /^(\d{2})$/,
6610
+ YYY: [
6611
+ /^([+-]\d{2})$/,
6612
+ // 0 additional digits
6613
+ /^([+-]\d{3})$/,
6614
+ // 1 additional digit
6615
+ /^([+-]\d{4})$/
6616
+ // 2 additional digits
6617
+ ],
6618
+ YYYY: /^(\d{4})/,
6619
+ YYYYY: [
6620
+ /^([+-]\d{4})/,
6621
+ // 0 additional digits
6622
+ /^([+-]\d{5})/,
6623
+ // 1 additional digit
6624
+ /^([+-]\d{6})/
6625
+ // 2 additional digits
6626
+ ],
6627
+ // date tokens
6628
+ MM: /^-(\d{2})$/,
6629
+ DDD: /^-?(\d{3})$/,
6630
+ MMDD: /^-?(\d{2})-?(\d{2})$/,
6631
+ Www: /^-?W(\d{2})$/,
6632
+ WwwD: /^-?W(\d{2})-?(\d{1})$/,
6633
+ HH: /^(\d{2}([.,]\d*)?)$/,
6634
+ HHMM: /^(\d{2}):?(\d{2}([.,]\d*)?)$/,
6635
+ HHMMSS: /^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/,
6636
+ // time zone tokens (to identify the presence of a tz)
6637
+ timeZone: tzPattern
6638
+ };
6639
+ function toDate(argument, options = {}) {
6640
+ if (arguments.length < 1) {
6641
+ throw new TypeError("1 argument required, but only " + arguments.length + " present");
6642
+ }
6643
+ if (argument === null) {
6644
+ return /* @__PURE__ */ new Date(NaN);
6645
+ }
6646
+ const additionalDigits = options.additionalDigits == null ? DEFAULT_ADDITIONAL_DIGITS : Number(options.additionalDigits);
6647
+ if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) {
6648
+ throw new RangeError("additionalDigits must be 0, 1 or 2");
6649
+ }
6650
+ if (argument instanceof Date || typeof argument === "object" && Object.prototype.toString.call(argument) === "[object Date]") {
6651
+ return new Date(argument.getTime());
6652
+ } else if (typeof argument === "number" || Object.prototype.toString.call(argument) === "[object Number]") {
6653
+ return new Date(argument);
6654
+ } else if (!(Object.prototype.toString.call(argument) === "[object String]")) {
6655
+ return /* @__PURE__ */ new Date(NaN);
6656
+ }
6657
+ const dateStrings = splitDateString(argument);
6658
+ const { year, restDateString } = parseYear(dateStrings.date, additionalDigits);
6659
+ const date = parseDate(restDateString, year);
6660
+ if (date === null || isNaN(date.getTime())) {
6661
+ return /* @__PURE__ */ new Date(NaN);
6662
+ }
6663
+ if (date) {
6664
+ const timestamp = date.getTime();
6665
+ let time = 0;
6666
+ let offset;
6667
+ if (dateStrings.time) {
6668
+ time = parseTime(dateStrings.time);
6669
+ if (time === null || isNaN(time)) {
6670
+ return /* @__PURE__ */ new Date(NaN);
6671
+ }
6672
+ }
6673
+ if (dateStrings.timeZone || options.timeZone) {
6674
+ offset = tzParseTimezone(dateStrings.timeZone || options.timeZone, new Date(timestamp + time));
6675
+ if (isNaN(offset)) {
6676
+ return /* @__PURE__ */ new Date(NaN);
6677
+ }
6678
+ } else {
6679
+ offset = getTimezoneOffsetInMilliseconds(new Date(timestamp + time));
6680
+ offset = getTimezoneOffsetInMilliseconds(new Date(timestamp + time + offset));
6681
+ }
6682
+ return new Date(timestamp + time + offset);
6683
+ } else {
6684
+ return /* @__PURE__ */ new Date(NaN);
6685
+ }
6686
+ }
6687
+ function splitDateString(dateString) {
6688
+ const dateStrings = {};
6689
+ let parts = patterns.dateTimePattern.exec(dateString);
6690
+ let timeString;
6691
+ if (!parts) {
6692
+ parts = patterns.datePattern.exec(dateString);
6693
+ if (parts) {
6694
+ dateStrings.date = parts[1];
6695
+ timeString = parts[2];
6696
+ } else {
6697
+ dateStrings.date = null;
6698
+ timeString = dateString;
6699
+ }
6700
+ } else {
6701
+ dateStrings.date = parts[1];
6702
+ timeString = parts[3];
6703
+ }
6704
+ if (timeString) {
6705
+ const token = patterns.timeZone.exec(timeString);
6706
+ if (token) {
6707
+ dateStrings.time = timeString.replace(token[1], "");
6708
+ dateStrings.timeZone = token[1].trim();
6709
+ } else {
6710
+ dateStrings.time = timeString;
6711
+ }
6712
+ }
6713
+ return dateStrings;
6714
+ }
6715
+ function parseYear(dateString, additionalDigits) {
6716
+ if (dateString) {
6717
+ const patternYYY = patterns.YYY[additionalDigits];
6718
+ const patternYYYYY = patterns.YYYYY[additionalDigits];
6719
+ let token = patterns.YYYY.exec(dateString) || patternYYYYY.exec(dateString);
6720
+ if (token) {
6721
+ const yearString = token[1];
6722
+ return {
6723
+ year: parseInt(yearString, 10),
6724
+ restDateString: dateString.slice(yearString.length)
6725
+ };
6726
+ }
6727
+ token = patterns.YY.exec(dateString) || patternYYY.exec(dateString);
6728
+ if (token) {
6729
+ const centuryString = token[1];
6730
+ return {
6731
+ year: parseInt(centuryString, 10) * 100,
6732
+ restDateString: dateString.slice(centuryString.length)
6733
+ };
6734
+ }
6735
+ }
6736
+ return {
6737
+ year: null
6738
+ };
6739
+ }
6740
+ function parseDate(dateString, year) {
6741
+ if (year === null) {
6742
+ return null;
6743
+ }
6744
+ let date;
6745
+ let month;
6746
+ let week;
6747
+ if (!dateString || !dateString.length) {
6748
+ date = /* @__PURE__ */ new Date(0);
6749
+ date.setUTCFullYear(year);
6750
+ return date;
6751
+ }
6752
+ let token = patterns.MM.exec(dateString);
6753
+ if (token) {
6754
+ date = /* @__PURE__ */ new Date(0);
6755
+ month = parseInt(token[1], 10) - 1;
6756
+ if (!validateDate(year, month)) {
6757
+ return /* @__PURE__ */ new Date(NaN);
6758
+ }
6759
+ date.setUTCFullYear(year, month);
6760
+ return date;
6761
+ }
6762
+ token = patterns.DDD.exec(dateString);
6763
+ if (token) {
6764
+ date = /* @__PURE__ */ new Date(0);
6765
+ const dayOfYear = parseInt(token[1], 10);
6766
+ if (!validateDayOfYearDate(year, dayOfYear)) {
6767
+ return /* @__PURE__ */ new Date(NaN);
6768
+ }
6769
+ date.setUTCFullYear(year, 0, dayOfYear);
6770
+ return date;
6771
+ }
6772
+ token = patterns.MMDD.exec(dateString);
6773
+ if (token) {
6774
+ date = /* @__PURE__ */ new Date(0);
6775
+ month = parseInt(token[1], 10) - 1;
6776
+ const day = parseInt(token[2], 10);
6777
+ if (!validateDate(year, month, day)) {
6778
+ return /* @__PURE__ */ new Date(NaN);
6779
+ }
6780
+ date.setUTCFullYear(year, month, day);
6781
+ return date;
6782
+ }
6783
+ token = patterns.Www.exec(dateString);
6784
+ if (token) {
6785
+ week = parseInt(token[1], 10) - 1;
6786
+ if (!validateWeekDate(week)) {
6787
+ return /* @__PURE__ */ new Date(NaN);
6788
+ }
6789
+ return dayOfISOWeekYear(year, week);
6790
+ }
6791
+ token = patterns.WwwD.exec(dateString);
6792
+ if (token) {
6793
+ week = parseInt(token[1], 10) - 1;
6794
+ const dayOfWeek = parseInt(token[2], 10) - 1;
6795
+ if (!validateWeekDate(week, dayOfWeek)) {
6796
+ return /* @__PURE__ */ new Date(NaN);
6797
+ }
6798
+ return dayOfISOWeekYear(year, week, dayOfWeek);
6799
+ }
6800
+ return null;
6801
+ }
6802
+ function parseTime(timeString) {
6803
+ let hours;
6804
+ let minutes;
6805
+ let token = patterns.HH.exec(timeString);
6806
+ if (token) {
6807
+ hours = parseFloat(token[1].replace(",", "."));
6808
+ if (!validateTime(hours)) {
6809
+ return NaN;
6810
+ }
6811
+ return hours % 24 * MILLISECONDS_IN_HOUR;
6812
+ }
6813
+ token = patterns.HHMM.exec(timeString);
6814
+ if (token) {
6815
+ hours = parseInt(token[1], 10);
6816
+ minutes = parseFloat(token[2].replace(",", "."));
6817
+ if (!validateTime(hours, minutes)) {
6818
+ return NaN;
6819
+ }
6820
+ return hours % 24 * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE;
6821
+ }
6822
+ token = patterns.HHMMSS.exec(timeString);
6823
+ if (token) {
6824
+ hours = parseInt(token[1], 10);
6825
+ minutes = parseInt(token[2], 10);
6826
+ const seconds = parseFloat(token[3].replace(",", "."));
6827
+ if (!validateTime(hours, minutes, seconds)) {
6828
+ return NaN;
6829
+ }
6830
+ return hours % 24 * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE + seconds * 1e3;
6831
+ }
6832
+ return null;
6833
+ }
6834
+ function dayOfISOWeekYear(isoWeekYear, week, day) {
6835
+ week = week || 0;
6836
+ day = day || 0;
6837
+ const date = /* @__PURE__ */ new Date(0);
6838
+ date.setUTCFullYear(isoWeekYear, 0, 4);
6839
+ const fourthOfJanuaryDay = date.getUTCDay() || 7;
6840
+ const diff = week * 7 + day + 1 - fourthOfJanuaryDay;
6841
+ date.setUTCDate(date.getUTCDate() + diff);
6842
+ return date;
6843
+ }
6844
+ const DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
6845
+ const DAYS_IN_MONTH_LEAP_YEAR = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
6846
+ function isLeapYearIndex(year) {
6847
+ return year % 400 === 0 || year % 4 === 0 && year % 100 !== 0;
6848
+ }
6849
+ function validateDate(year, month, date) {
6850
+ if (month < 0 || month > 11) {
6851
+ return false;
6852
+ }
6853
+ if (date != null) {
6854
+ if (date < 1) {
6855
+ return false;
6856
+ }
6857
+ const isLeapYear = isLeapYearIndex(year);
6858
+ if (isLeapYear && date > DAYS_IN_MONTH_LEAP_YEAR[month]) {
6859
+ return false;
6860
+ }
6861
+ if (!isLeapYear && date > DAYS_IN_MONTH[month]) {
6862
+ return false;
6863
+ }
6864
+ }
6865
+ return true;
6866
+ }
6867
+ function validateDayOfYearDate(year, dayOfYear) {
6868
+ if (dayOfYear < 1) {
6869
+ return false;
6870
+ }
6871
+ const isLeapYear = isLeapYearIndex(year);
6872
+ if (isLeapYear && dayOfYear > 366) {
6873
+ return false;
6874
+ }
6875
+ if (!isLeapYear && dayOfYear > 365) {
6876
+ return false;
6877
+ }
6878
+ return true;
6879
+ }
6880
+ function validateWeekDate(week, day) {
6881
+ if (week < 0 || week > 52) {
6882
+ return false;
6883
+ }
6884
+ if (day != null && (day < 0 || day > 6)) {
6885
+ return false;
6886
+ }
6887
+ return true;
6888
+ }
6889
+ function validateTime(hours, minutes, seconds) {
6890
+ if (hours < 0 || hours >= 25) {
6891
+ return false;
6892
+ }
6893
+ if (minutes != null && (minutes < 0 || minutes >= 60)) {
6894
+ return false;
6895
+ }
6896
+ if (seconds != null && (seconds < 0 || seconds >= 60)) {
6897
+ return false;
6898
+ }
6899
+ return true;
6900
+ }
6901
+ function toZonedTime$1(date, timeZone, options) {
6902
+ date = toDate(date, options);
6903
+ const offsetMilliseconds = tzParseTimezone(timeZone, date, true);
6904
+ const d = new Date(date.getTime() - offsetMilliseconds);
6905
+ const resultDate = /* @__PURE__ */ new Date(0);
6906
+ resultDate.setFullYear(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
6907
+ resultDate.setHours(d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
6908
+ return resultDate;
6909
+ }
6910
+ function fromZonedTime$1(date, timeZone, options) {
6911
+ if (typeof date === "string" && !date.match(tzPattern)) {
6912
+ return toDate(date, { ...options, timeZone });
6913
+ }
6914
+ date = toDate(date, options);
6915
+ const utc = newDateUTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()).getTime();
6916
+ const offsetMilliseconds = tzParseTimezone(timeZone, new Date(utc));
6917
+ return new Date(utc + offsetMilliseconds);
6918
+ }
6919
+ function toZonedTime(date, timezone) {
6920
+ return toZonedTime$1(date, timezone);
6921
+ }
6922
+ function fromZonedTime(date, timezone) {
6923
+ return fromZonedTime$1(date, timezone);
6924
+ }
6925
+ function wrapAdapterWithTimezone(adapter, timezone) {
6926
+ const zoneEvent = (ev) => ({
6927
+ ...ev,
6928
+ start: toZonedTime(ev.start, timezone),
6929
+ end: toZonedTime(ev.end, timezone)
6930
+ });
6931
+ const unzonePartial = (obj) => ({
6932
+ ...obj,
6933
+ ...obj.start instanceof Date ? { start: fromZonedTime(obj.start, timezone) } : {},
6934
+ ...obj.end instanceof Date ? { end: fromZonedTime(obj.end, timezone) } : {}
6935
+ });
6936
+ const wrapped = {
6937
+ async fetchEvents(range) {
6938
+ const events = await adapter.fetchEvents({
6939
+ start: fromZonedTime(range.start, timezone),
6940
+ end: fromZonedTime(range.end, timezone)
6941
+ });
6942
+ return events.map(zoneEvent);
6943
+ }
6944
+ };
6945
+ if (adapter.createEvent) {
6946
+ wrapped.createEvent = async (event2) => zoneEvent(await adapter.createEvent(unzonePartial(event2)));
6947
+ }
6948
+ if (adapter.updateEvent) {
6949
+ wrapped.updateEvent = async (id, patch) => zoneEvent(await adapter.updateEvent(id, unzonePartial(patch)));
6950
+ }
6951
+ if (adapter.deleteEvent) {
6952
+ wrapped.deleteEvent = (id) => adapter.deleteEvent(id);
6953
+ }
6954
+ return wrapped;
6955
+ }
6956
+ function createClock(timezone) {
6957
+ const now2 = () => timezone ? toZonedTime(Date.now(), timezone).getTime() : Date.now();
6958
+ let tick2 = /* @__PURE__ */ state(proxy(now2()));
6959
+ let today = /* @__PURE__ */ state(proxy(sod(get(tick2))));
6428
6960
  let intervalId = null;
6429
6961
  function start() {
6430
6962
  intervalId = setInterval(
6431
6963
  () => {
6432
- set(tick2, Date.now(), true);
6964
+ set(tick2, now2(), true);
6433
6965
  const sd = sod(get(tick2));
6434
6966
  if (sd !== get(today)) set(today, sd, true);
6435
6967
  },
@@ -6633,7 +7165,7 @@
6633
7165
  const L = /* @__PURE__ */ user_derived(getLabels);
6634
7166
  let height = prop($$props, "height", 3, 520), events = prop($$props, "events", 19, () => []), style = prop($$props, "style", 3, ""), selectedEventId = prop($$props, "selectedEventId", 3, null), readOnly = prop($$props, "readOnly", 3, false);
6635
7167
  const ctx = useCalendarContext();
6636
- const clock = createClock();
7168
+ const clock = createClock(ctx.timezone);
6637
7169
  const drag = /* @__PURE__ */ user_derived(() => ctx.drag);
6638
7170
  const commitDragCtx = /* @__PURE__ */ user_derived(() => ctx.commitDrag);
6639
7171
  const viewState = /* @__PURE__ */ user_derived(() => ctx.viewState);
@@ -7741,7 +8273,7 @@
7741
8273
  const L = /* @__PURE__ */ user_derived(getLabels);
7742
8274
  let mondayStart = prop($$props, "mondayStart", 3, true), height = prop($$props, "height", 3, 520), events = prop($$props, "events", 19, () => []), style = prop($$props, "style", 3, ""), selectedEventId = prop($$props, "selectedEventId", 3, null), readOnly = prop($$props, "readOnly", 3, false);
7743
8275
  const ctx = useCalendarContext();
7744
- const clock = createClock();
8276
+ const clock = createClock(ctx.timezone);
7745
8277
  const ANIM = /* @__PURE__ */ user_derived(() => prefersReducedMotion.current ? 0 : 180);
7746
8278
  const [previewSend, previewReceive] = crossfade({ duration: () => prefersReducedMotion.current ? 0 : 160 });
7747
8279
  const drag = /* @__PURE__ */ user_derived(() => ctx.drag);
@@ -8424,7 +8956,7 @@
8424
8956
  const ctx = useCalendarContext();
8425
8957
  const emptySnippet = /* @__PURE__ */ user_derived(() => ctx.emptySnippet);
8426
8958
  let events = prop($$props, "events", 19, () => []), style = prop($$props, "style", 3, ""), selectedEventId = prop($$props, "selectedEventId", 3, null);
8427
- const clock = createClock();
8959
+ const clock = createClock(ctx.timezone);
8428
8960
  const viewState = /* @__PURE__ */ user_derived(() => ctx.viewState);
8429
8961
  const equalDays = /* @__PURE__ */ user_derived(() => ctx.equalDays);
8430
8962
  const isMobile = /* @__PURE__ */ user_derived(() => ctx.isMobile);
@@ -9418,7 +9950,7 @@
9418
9950
  let mondayStart = prop($$props, "mondayStart", 3, true);
9419
9951
  prop($$props, "height", 3, 520);
9420
9952
  let events = prop($$props, "events", 19, () => []), style = prop($$props, "style", 3, ""), selectedEventId = prop($$props, "selectedEventId", 3, null);
9421
- const clock = createClock();
9953
+ const clock = createClock(ctx.timezone);
9422
9954
  const viewState = /* @__PURE__ */ user_derived(() => ctx.viewState);
9423
9955
  const equalDays = /* @__PURE__ */ user_derived(() => ctx.equalDays);
9424
9956
  const showDates = /* @__PURE__ */ user_derived(() => ctx.showDates);
@@ -10060,7 +10592,7 @@
10060
10592
  const drag = /* @__PURE__ */ user_derived(() => ctx.drag);
10061
10593
  const commitDragCtx = /* @__PURE__ */ user_derived(() => ctx.commitDrag);
10062
10594
  const SNAP_MS = /* @__PURE__ */ user_derived(() => ctx.snapInterval * 6e4);
10063
- const clock = createClock();
10595
+ const clock = createClock(ctx.timezone);
10064
10596
  const HOUR_HEIGHT = 64;
10065
10597
  const GUTTER_W = 40;
10066
10598
  const startHour = /* @__PURE__ */ user_derived(() => $$props.visibleHours?.[0] ?? 0);
@@ -10723,7 +11255,7 @@
10723
11255
  const oneventhover = /* @__PURE__ */ user_derived(() => ctx.oneventhover);
10724
11256
  const disabledSet = /* @__PURE__ */ user_derived(() => ctx.disabledSet);
10725
11257
  const loadRangeCtx = /* @__PURE__ */ user_derived(() => ctx.loadRange);
10726
- const clock = createClock();
11258
+ const clock = createClock(ctx.timezone);
10727
11259
  const MAX_EVENTS = 3;
10728
11260
  const customDays = /* @__PURE__ */ user_derived(() => get(viewState)?.dayCount ?? 7);
10729
11261
  const todayMs = /* @__PURE__ */ user_derived(() => clock.today);
@@ -11034,7 +11566,7 @@
11034
11566
  const ondayclick = /* @__PURE__ */ user_derived(() => ctx.ondayclick);
11035
11567
  const eventSnippet = /* @__PURE__ */ user_derived(() => ctx.eventSnippet);
11036
11568
  const loadRangeCtx = /* @__PURE__ */ user_derived(() => ctx.loadRange);
11037
- const clock = createClock();
11569
+ const clock = createClock(ctx.timezone);
11038
11570
  const todayMs = /* @__PURE__ */ user_derived(() => clock.today);
11039
11571
  const MAX_CHIPS = /* @__PURE__ */ user_derived(() => get(isMobile) ? 2 : 3);
11040
11572
  const range = /* @__PURE__ */ user_derived(() => get(viewState)?.range);
@@ -11294,8 +11826,9 @@
11294
11826
  }
11295
11827
  ];
11296
11828
  let views = prop($$props, "views", 3, DEFAULT_VIEWS), theme = prop($$props, "theme", 3, auto), mondayStart = prop($$props, "mondayStart", 3, true), heightProp = prop($$props, "height", 3, 600), borderRadius = prop($$props, "borderRadius", 3, 12), readOnly = prop($$props, "readOnly", 3, false), snapInterval = prop($$props, "snapInterval", 3, 15), showModePills = prop($$props, "showModePills", 3, true), showNavigation = prop($$props, "showNavigation", 3, true), equalDays = prop($$props, "equalDays", 3, false), showDates = prop($$props, "showDates", 3, true), compact = prop($$props, "compact", 3, false), mobileProp = prop($$props, "mobile", 3, "auto");
11297
- const effectiveCreate = /* @__PURE__ */ user_derived(() => readOnly() ? void 0 : $$props.oneventcreate);
11298
- const effectiveMove = /* @__PURE__ */ user_derived(() => readOnly() ? void 0 : $$props.oneventmove);
11829
+ const unzone = (d) => $$props.timezone ? fromZonedTime(d, $$props.timezone) : d;
11830
+ const effectiveCreate = /* @__PURE__ */ user_derived(() => readOnly() || !$$props.oneventcreate ? void 0 : (range) => $$props.oneventcreate({ start: unzone(range.start), end: unzone(range.end) }));
11831
+ const effectiveMove = /* @__PURE__ */ user_derived(() => readOnly() || !$$props.oneventmove ? void 0 : (ev, start, end) => $$props.oneventmove(ev, unzone(start), unzone(end)));
11299
11832
  function handleEventClick(ev) {
11300
11833
  selection.select(ev.id);
11301
11834
  $$props.oneventclick?.(ev);
@@ -11328,12 +11861,15 @@
11328
11861
  };
11329
11862
  });
11330
11863
  const effectiveTheme = /* @__PURE__ */ user_derived(() => theme() === auto && $$props.autoTheme !== false ? get(probedTheme) : theme());
11331
- const store = /* @__PURE__ */ user_derived(() => createEventStore($$props.adapter));
11864
+ const effectiveAdapter = /* @__PURE__ */ user_derived(() => $$props.timezone ? wrapAdapterWithTimezone($$props.adapter, $$props.timezone) : $$props.adapter);
11865
+ const store = /* @__PURE__ */ user_derived(() => createEventStore(get(effectiveAdapter)));
11332
11866
  const viewState = createViewState(untrack(() => ({
11333
11867
  view: $$props.view ?? views()[0]?.id,
11334
11868
  mondayStart: mondayStart(),
11335
- initialDate: $$props.initialDate,
11869
+ // Focus lives on the zoned plane too — day boundaries follow the zone.
11870
+ initialDate: $$props.initialDate && $$props.timezone ? toZonedTime($$props.initialDate, $$props.timezone) : $$props.initialDate,
11336
11871
  dayCount: $$props.days,
11872
+ timezone: $$props.timezone,
11337
11873
  modeForView: (viewId) => views().find((v) => v.id === viewId)?.mode
11338
11874
  })));
11339
11875
  const selection = createSelection();
@@ -11437,6 +11973,9 @@
11437
11973
  get ondayclick() {
11438
11974
  return $$props.ondayclick;
11439
11975
  },
11976
+ get timezone() {
11977
+ return $$props.timezone;
11978
+ },
11440
11979
  // Config (reactive via getters)
11441
11980
  get readOnly() {
11442
11981
  return readOnly();