@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 +14 -1
- package/dist/calendar/Calendar.svelte +20 -5
- package/dist/calendar/Calendar.svelte.d.ts +7 -0
- package/dist/core/clock.svelte.d.ts +1 -1
- package/dist/core/clock.svelte.js +8 -4
- package/dist/core/timezone.d.ts +12 -0
- package/dist/core/timezone.js +31 -0
- package/dist/headless/create-calendar.svelte.js +12 -6
- package/dist/headless/types.d.ts +2 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/views/agenda/AgendaDay.svelte +1 -1
- package/dist/views/agenda/AgendaWeek.svelte +1 -1
- package/dist/views/mobile/MobileDay.svelte +1 -1
- package/dist/views/mobile/MobileWeek.svelte +1 -1
- package/dist/views/month/MonthGrid.svelte +1 -1
- package/dist/views/planner/PlannerDay.svelte +1 -1
- package/dist/views/planner/PlannerWeek.svelte +1 -1
- package/dist/views/shared/context.svelte.d.ts +1 -0
- package/dist/views/shared/context.svelte.js +1 -0
- package/package.json +1 -1
- package/widget/widget.js +562 -23
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
|
-
|
|
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
|
|
86
|
-
const
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
24
|
-
|
|
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 =
|
|
32
|
+
tick = now();
|
|
29
33
|
const sd = sod(tick);
|
|
30
34
|
if (sd !== today)
|
|
31
35
|
today = sd;
|
package/dist/core/timezone.d.ts
CHANGED
|
@@ -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;
|
package/dist/core/timezone.js
CHANGED
|
@@ -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
|
|
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?.(
|
|
306
|
+
oneventcreate?.(timezone
|
|
307
|
+
? { start: fromZonedTime(start, timezone), end: fromZonedTime(end, timezone) }
|
|
308
|
+
: { start, end });
|
|
303
309
|
}
|
|
304
310
|
return result;
|
|
305
311
|
}
|
package/dist/headless/types.d.ts
CHANGED
|
@@ -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
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
|
|
6426
|
-
|
|
6427
|
-
|
|
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,
|
|
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
|
|
11298
|
-
const
|
|
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
|
|
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
|
-
|
|
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();
|