@gobrand/calendar-core 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,651 @@
1
+ // src/utils.ts
2
+ import { Temporal } from "@js-temporal/polyfill";
3
+ function functionalUpdate(updater, input) {
4
+ return typeof updater === "function" ? updater(input) : updater;
5
+ }
6
+ function createCalendarAccessor(accessor) {
7
+ return accessor;
8
+ }
9
+ function nextMonth(month) {
10
+ return month.add({ months: 1 });
11
+ }
12
+ function previousMonth(month) {
13
+ return month.subtract({ months: 1 });
14
+ }
15
+ function nextWeek(date) {
16
+ return date.add({ weeks: 1 });
17
+ }
18
+ function previousWeek(date) {
19
+ return date.subtract({ weeks: 1 });
20
+ }
21
+ function nextDay(date) {
22
+ return date.add({ days: 1 });
23
+ }
24
+ function previousDay(date) {
25
+ return date.subtract({ days: 1 });
26
+ }
27
+ function goToToday() {
28
+ const today = Temporal.Now.plainDateISO();
29
+ return { year: today.year, month: today.month };
30
+ }
31
+ function getWeekdays(weekStartsOn = 1, locale = "en-US", format = "short") {
32
+ const referenceDate = Temporal.PlainDate.from("2023-01-02");
33
+ const days = [];
34
+ for (let i = 0; i < 7; i++) {
35
+ const offset = (weekStartsOn - 1 + i + 7) % 7;
36
+ const date = referenceDate.add({ days: offset });
37
+ days.push(date.toLocaleString(locale, { weekday: format }));
38
+ }
39
+ return days;
40
+ }
41
+ function getMonthName(month, locale = "en-US") {
42
+ return month.toPlainDate({ day: 1 }).toLocaleString(locale, { month: "long" });
43
+ }
44
+ function formatTime(time, locale = "en-US") {
45
+ const date = Temporal.PlainDate.from("2023-01-01");
46
+ const dateTime = date.toPlainDateTime(time);
47
+ return dateTime.toLocaleString(locale, { hour: "numeric", minute: "2-digit" });
48
+ }
49
+ function getTimeSlotHeight(slotDuration, hourHeight) {
50
+ return slotDuration / 60 * hourHeight;
51
+ }
52
+ function getEventPosition(eventStart, eventEnd, dayStart, hourHeight) {
53
+ const startTime = eventStart.toPlainTime();
54
+ const endTime = eventEnd.toPlainTime();
55
+ const startMinutes = startTime.hour * 60 + startTime.minute;
56
+ const endMinutes = endTime.hour * 60 + endTime.minute;
57
+ const dayStartMinutes = dayStart * 60;
58
+ const top = (startMinutes - dayStartMinutes) / 60 * hourHeight;
59
+ const height = (endMinutes - startMinutes) / 60 * hourHeight;
60
+ return { top, height };
61
+ }
62
+ function convertToTimezone(dateTime, timeZone) {
63
+ return dateTime.withTimeZone(timeZone);
64
+ }
65
+ function getTimezoneOffset(dateTime) {
66
+ return dateTime.offsetNanoseconds / 36e11 >= 0 ? `+${Math.floor(dateTime.offsetNanoseconds / 36e11)}` : `${Math.floor(dateTime.offsetNanoseconds / 36e11)}`;
67
+ }
68
+ function createZonedDateTime(date, time, timeZone) {
69
+ return date.toZonedDateTime({ timeZone, plainTime: time });
70
+ }
71
+ function getCurrentTimeZone() {
72
+ return Temporal.Now.timeZoneId();
73
+ }
74
+ function getMonthRange(timeZone = getCurrentTimeZone(), weekStartsOn = 1) {
75
+ const today = Temporal.Now.zonedDateTimeISO(timeZone).toPlainDate();
76
+ const firstOfMonth = today.with({ day: 1 });
77
+ const lastOfMonth = today.with({ day: today.daysInMonth });
78
+ const startDayOfWeek = firstOfMonth.dayOfWeek;
79
+ const daysToSubtract = (startDayOfWeek - weekStartsOn + 7) % 7;
80
+ const start = firstOfMonth.subtract({ days: daysToSubtract });
81
+ const endDayOfWeek = lastOfMonth.dayOfWeek;
82
+ const daysToAdd = (weekStartsOn + 6 - endDayOfWeek) % 7;
83
+ const end = lastOfMonth.add({ days: daysToAdd });
84
+ return { start, end };
85
+ }
86
+ function getWeekRange(timeZone = getCurrentTimeZone(), weekStartsOn = 1) {
87
+ const today = Temporal.Now.zonedDateTimeISO(timeZone).toPlainDate();
88
+ const dayOfWeek = today.dayOfWeek;
89
+ const daysToSubtract = (dayOfWeek - weekStartsOn + 7) % 7;
90
+ const start = today.subtract({ days: daysToSubtract });
91
+ const end = start.add({ days: 6 });
92
+ return { start, end };
93
+ }
94
+ function getDayRange(timeZone = getCurrentTimeZone()) {
95
+ const today = Temporal.Now.zonedDateTimeISO(timeZone).toPlainDate();
96
+ return { start: today, end: today };
97
+ }
98
+
99
+ // src/utils/buildMonth.ts
100
+ import { Temporal as Temporal2 } from "@js-temporal/polyfill";
101
+ function buildMonth(year, month, options) {
102
+ const weekStartsOn = options?.weekStartsOn ?? 1;
103
+ const today = options?.today ?? Temporal2.Now.plainDateISO();
104
+ const data = options?.data ?? [];
105
+ const accessor = options?.accessor;
106
+ const yearMonth = Temporal2.PlainYearMonth.from({ year, month });
107
+ const firstOfMonth = yearMonth.toPlainDate({ day: 1 });
108
+ const lastOfMonth = yearMonth.toPlainDate({ day: yearMonth.daysInMonth });
109
+ const itemsByDate = /* @__PURE__ */ new Map();
110
+ if (accessor) {
111
+ for (const item of data) {
112
+ const date = accessor.getDate(item);
113
+ const key = date.toString();
114
+ const existing = itemsByDate.get(key) ?? [];
115
+ itemsByDate.set(key, [...existing, item]);
116
+ }
117
+ }
118
+ let startDate = firstOfMonth;
119
+ const firstDayOfWeek = firstOfMonth.dayOfWeek;
120
+ const daysToSubtract = (firstDayOfWeek - weekStartsOn + 7) % 7;
121
+ if (daysToSubtract > 0) {
122
+ startDate = firstOfMonth.subtract({ days: daysToSubtract });
123
+ }
124
+ const weeks = [];
125
+ let currentDate = startDate;
126
+ while (currentDate.month !== lastOfMonth.month || currentDate.day <= lastOfMonth.day || weeks.length === 0 || weeks[weeks.length - 1].length < 7) {
127
+ if (weeks.length === 0 || weeks[weeks.length - 1].length === 7) {
128
+ weeks.push([]);
129
+ }
130
+ const dateKey = currentDate.toString();
131
+ weeks[weeks.length - 1].push({
132
+ date: currentDate,
133
+ isCurrentMonth: currentDate.month === month,
134
+ isToday: Temporal2.PlainDate.compare(currentDate, today) === 0,
135
+ items: itemsByDate.get(dateKey) ?? []
136
+ });
137
+ currentDate = currentDate.add({ days: 1 });
138
+ if (weeks.length >= 6 && weeks[weeks.length - 1].length === 7) {
139
+ break;
140
+ }
141
+ }
142
+ return {
143
+ weeks,
144
+ month: yearMonth
145
+ };
146
+ }
147
+
148
+ // src/utils/buildWeek.ts
149
+ import { Temporal as Temporal4 } from "@js-temporal/polyfill";
150
+
151
+ // src/utils/buildDay.ts
152
+ import { Temporal as Temporal3 } from "@js-temporal/polyfill";
153
+ function buildDay(date, options) {
154
+ const startHour = options?.startHour ?? 0;
155
+ const endHour = options?.endHour ?? 24;
156
+ const slotDuration = options?.slotDuration ?? 30;
157
+ const today = options?.today ?? Temporal3.Now.plainDateISO();
158
+ const data = options?.data ?? [];
159
+ const accessor = options?.accessor;
160
+ const dayItems = [];
161
+ if (accessor) {
162
+ for (const item of data) {
163
+ const itemDate = accessor.getDate(item);
164
+ if (Temporal3.PlainDate.compare(itemDate, date) === 0) {
165
+ dayItems.push(item);
166
+ }
167
+ }
168
+ }
169
+ const timeSlots = [];
170
+ let currentHour = startHour;
171
+ let currentMinute = 0;
172
+ while (currentHour < endHour) {
173
+ const slotStart = Temporal3.PlainTime.from({ hour: currentHour, minute: currentMinute });
174
+ let nextMinute = currentMinute + slotDuration;
175
+ let nextHour = currentHour;
176
+ if (nextMinute >= 60) {
177
+ nextHour += Math.floor(nextMinute / 60);
178
+ nextMinute = nextMinute % 60;
179
+ }
180
+ const slotItems = [];
181
+ if (accessor?.getStart) {
182
+ for (const item of dayItems) {
183
+ const itemStart = accessor.getStart(item);
184
+ const itemTime = itemStart.toPlainTime();
185
+ const slotEndHour = nextHour >= 24 ? 0 : nextHour;
186
+ const slotEndMinute = nextHour >= 24 ? 0 : nextMinute;
187
+ const slotEnd = Temporal3.PlainTime.from({ hour: slotEndHour, minute: slotEndMinute });
188
+ const isAfterStart = Temporal3.PlainTime.compare(itemTime, slotStart) >= 0;
189
+ const isBeforeEnd = nextHour >= 24 ? Temporal3.PlainTime.compare(itemTime, slotEnd) > 0 : Temporal3.PlainTime.compare(itemTime, slotEnd) < 0;
190
+ if (isAfterStart && isBeforeEnd) {
191
+ slotItems.push(item);
192
+ }
193
+ }
194
+ }
195
+ timeSlots.push({
196
+ hour: currentHour,
197
+ minute: currentMinute,
198
+ time: slotStart,
199
+ items: slotItems
200
+ });
201
+ currentMinute += slotDuration;
202
+ if (currentMinute >= 60) {
203
+ currentHour += Math.floor(currentMinute / 60);
204
+ currentMinute = currentMinute % 60;
205
+ }
206
+ }
207
+ return {
208
+ date,
209
+ isToday: Temporal3.PlainDate.compare(date, today) === 0,
210
+ timeSlots,
211
+ items: dayItems
212
+ };
213
+ }
214
+
215
+ // src/utils/buildWeek.ts
216
+ function buildWeek(date, options) {
217
+ const weekStartsOn = options?.weekStartsOn ?? 1;
218
+ const startHour = options?.startHour;
219
+ const endHour = options?.endHour;
220
+ const slotDuration = options?.slotDuration;
221
+ const today = options?.today ?? Temporal4.Now.plainDateISO();
222
+ const data = options?.data ?? [];
223
+ const accessor = options?.accessor;
224
+ const hasTimeSlots = startHour !== void 0 && endHour !== void 0 && slotDuration !== void 0;
225
+ const itemsByDate = /* @__PURE__ */ new Map();
226
+ if (accessor) {
227
+ for (const item of data) {
228
+ const date2 = accessor.getDate(item);
229
+ const key = date2.toString();
230
+ const existing = itemsByDate.get(key) ?? [];
231
+ itemsByDate.set(key, [...existing, item]);
232
+ }
233
+ }
234
+ const dayOfWeek = date.dayOfWeek;
235
+ const daysToSubtract = (dayOfWeek - weekStartsOn + 7) % 7;
236
+ const weekStart = date.subtract({ days: daysToSubtract });
237
+ const days = [];
238
+ for (let i = 0; i < 7; i++) {
239
+ const currentDate = weekStart.add({ days: i });
240
+ const dateKey = currentDate.toString();
241
+ let timeSlots = void 0;
242
+ if (hasTimeSlots) {
243
+ const dayView = buildDay(currentDate, {
244
+ startHour,
245
+ endHour,
246
+ slotDuration,
247
+ today,
248
+ data,
249
+ accessor
250
+ });
251
+ timeSlots = dayView.timeSlots;
252
+ }
253
+ days.push({
254
+ date: currentDate,
255
+ isToday: Temporal4.PlainDate.compare(currentDate, today) === 0,
256
+ items: itemsByDate.get(dateKey) ?? [],
257
+ timeSlots
258
+ });
259
+ }
260
+ const weekEnd = weekStart.add({ days: 6 });
261
+ return {
262
+ days,
263
+ weekStart,
264
+ weekEnd
265
+ };
266
+ }
267
+
268
+ // src/utils/dateRanges.ts
269
+ import { Temporal as Temporal5 } from "@js-temporal/polyfill";
270
+ function getMonthDateRange(date, timeZone, options) {
271
+ const weekStartsOn = options?.weekStartsOn ?? 1;
272
+ const bounds = options?.bounds ?? "calendar";
273
+ const firstOfMonth = date.with({ day: 1 });
274
+ const lastOfMonth = date.with({ day: date.daysInMonth });
275
+ let start;
276
+ let end;
277
+ if (bounds === "calendar") {
278
+ const startDayOfWeek = firstOfMonth.dayOfWeek;
279
+ const daysToSubtract = (startDayOfWeek - weekStartsOn + 7) % 7;
280
+ start = firstOfMonth.subtract({ days: daysToSubtract });
281
+ const endDayOfWeek = lastOfMonth.dayOfWeek;
282
+ const daysToAdd = (weekStartsOn + 6 - endDayOfWeek) % 7;
283
+ end = lastOfMonth.add({ days: daysToAdd });
284
+ } else {
285
+ start = firstOfMonth;
286
+ end = lastOfMonth;
287
+ }
288
+ const startZoned = start.toZonedDateTime({
289
+ timeZone,
290
+ plainTime: Temporal5.PlainTime.from("00:00:00")
291
+ });
292
+ const endZoned = end.toZonedDateTime({
293
+ timeZone,
294
+ plainTime: Temporal5.PlainTime.from("23:59:59.999")
295
+ });
296
+ return { start: startZoned, end: endZoned };
297
+ }
298
+ function getWeekDateRange(date, timeZone, options) {
299
+ const weekStartsOn = options?.weekStartsOn ?? 1;
300
+ const dayOfWeek = date.dayOfWeek;
301
+ const daysToSubtract = (dayOfWeek - weekStartsOn + 7) % 7;
302
+ const start = date.subtract({ days: daysToSubtract });
303
+ const end = start.add({ days: 6 });
304
+ const startZoned = start.toZonedDateTime({
305
+ timeZone,
306
+ plainTime: Temporal5.PlainTime.from("00:00:00")
307
+ });
308
+ const endZoned = end.toZonedDateTime({
309
+ timeZone,
310
+ plainTime: Temporal5.PlainTime.from("23:59:59.999")
311
+ });
312
+ return { start: startZoned, end: endZoned };
313
+ }
314
+ function getDayDateRange(date, timeZone) {
315
+ const startZoned = date.toZonedDateTime({
316
+ timeZone,
317
+ plainTime: Temporal5.PlainTime.from("00:00:00")
318
+ });
319
+ const endZoned = date.toZonedDateTime({
320
+ timeZone,
321
+ plainTime: Temporal5.PlainTime.from("23:59:59.999")
322
+ });
323
+ return { start: startZoned, end: endZoned };
324
+ }
325
+
326
+ // src/core/calendar.ts
327
+ import { Temporal as Temporal6 } from "@js-temporal/polyfill";
328
+ import { Store } from "@tanstack/store";
329
+ function computeDateRange(view, referenceDate, timeZone, weekStartsOn = 1) {
330
+ let start;
331
+ let end;
332
+ if (view === "month") {
333
+ const firstOfMonth = referenceDate.with({ day: 1 });
334
+ const lastOfMonth = referenceDate.with({ day: referenceDate.daysInMonth });
335
+ const startDayOfWeek = firstOfMonth.dayOfWeek;
336
+ const daysToSubtract = (startDayOfWeek - weekStartsOn + 7) % 7;
337
+ start = firstOfMonth.subtract({ days: daysToSubtract });
338
+ const endDayOfWeek = lastOfMonth.dayOfWeek;
339
+ const daysToAdd = (weekStartsOn + 6 - endDayOfWeek) % 7;
340
+ end = lastOfMonth.add({ days: daysToAdd });
341
+ } else if (view === "week") {
342
+ const dayOfWeek = referenceDate.dayOfWeek;
343
+ const daysToSubtract = (dayOfWeek - weekStartsOn + 7) % 7;
344
+ start = referenceDate.subtract({ days: daysToSubtract });
345
+ end = start.add({ days: 6 });
346
+ } else {
347
+ start = referenceDate;
348
+ end = referenceDate;
349
+ }
350
+ const startZoned = start.toZonedDateTime({
351
+ timeZone,
352
+ plainTime: Temporal6.PlainTime.from("00:00:00")
353
+ });
354
+ const endZoned = end.toZonedDateTime({
355
+ timeZone,
356
+ plainTime: Temporal6.PlainTime.from("23:59:59.999")
357
+ });
358
+ return { start: startZoned, end: endZoned };
359
+ }
360
+ function createCalendar(options) {
361
+ const configuredViews = Object.keys(options.views);
362
+ const defaultView = configuredViews[0];
363
+ const timeZone = options.timeZone || Temporal6.Now.timeZoneId();
364
+ const monthView = options.views.month;
365
+ const weekView = options.views.week;
366
+ const weekStartsOn = monthView?.weekStartsOn ?? weekView?.weekStartsOn ?? 1;
367
+ const initialReferenceDate = options.state?.referenceDate || Temporal6.Now.plainDateISO();
368
+ const initialView = options.state?.currentView || defaultView;
369
+ const initialDateRange = computeDateRange(
370
+ initialView,
371
+ initialReferenceDate,
372
+ timeZone,
373
+ weekStartsOn
374
+ );
375
+ const resolvedOptions = {
376
+ state: {
377
+ referenceDate: initialReferenceDate,
378
+ currentView: initialView,
379
+ dateRange: initialDateRange
380
+ },
381
+ onStateChange: () => {
382
+ },
383
+ ...options
384
+ };
385
+ let _options = resolvedOptions;
386
+ const store = new Store({
387
+ referenceDate: initialReferenceDate,
388
+ currentView: initialView,
389
+ dateRange: initialDateRange,
390
+ ...resolvedOptions.state
391
+ });
392
+ const getMonthImpl = () => {
393
+ const state = store.state;
394
+ const { year, month } = state.referenceDate;
395
+ const monthView2 = _options.views.month;
396
+ if (!monthView2) throw new Error("Month view not configured");
397
+ return buildMonth(year, month, {
398
+ weekStartsOn: monthView2.weekStartsOn,
399
+ data: _options.data,
400
+ accessor: monthView2.accessor
401
+ });
402
+ };
403
+ const getWeekImpl = () => {
404
+ const state = store.state;
405
+ const weekView2 = _options.views.week;
406
+ if (!weekView2) throw new Error("Week view not configured");
407
+ return buildWeek(state.referenceDate, {
408
+ weekStartsOn: weekView2.weekStartsOn,
409
+ startHour: weekView2.startHour,
410
+ endHour: weekView2.endHour,
411
+ slotDuration: weekView2.slotDuration,
412
+ data: _options.data,
413
+ accessor: weekView2.accessor
414
+ });
415
+ };
416
+ const getDayImpl = () => {
417
+ const state = store.state;
418
+ const dayView = _options.views.day;
419
+ if (!dayView) throw new Error("Day view not configured");
420
+ return buildDay(state.referenceDate, {
421
+ startHour: dayView.startHour,
422
+ endHour: dayView.endHour,
423
+ slotDuration: dayView.slotDuration,
424
+ data: _options.data,
425
+ accessor: dayView.accessor
426
+ });
427
+ };
428
+ const setStateImpl = (updater) => {
429
+ const partialState = typeof updater === "function" ? updater(store.state) : updater;
430
+ const newState = {
431
+ ...store.state,
432
+ ...partialState
433
+ };
434
+ const currentView = newState.currentView || defaultView;
435
+ const dateRange = computeDateRange(
436
+ currentView,
437
+ newState.referenceDate,
438
+ timeZone,
439
+ weekStartsOn
440
+ );
441
+ const stateWithDateRange = {
442
+ ...newState,
443
+ dateRange
444
+ };
445
+ store.setState(() => stateWithDateRange);
446
+ if (_options.onStateChange) {
447
+ _options.onStateChange(stateWithDateRange);
448
+ }
449
+ };
450
+ const nextMonthImpl = () => {
451
+ setStateImpl((old) => {
452
+ const current = Temporal6.PlainYearMonth.from({
453
+ year: old.referenceDate.year,
454
+ month: old.referenceDate.month
455
+ });
456
+ const next = nextMonth(current);
457
+ return {
458
+ referenceDate: next.toPlainDate({ day: 1 })
459
+ };
460
+ });
461
+ };
462
+ const previousMonthImpl = () => {
463
+ setStateImpl((old) => {
464
+ const current = Temporal6.PlainYearMonth.from({
465
+ year: old.referenceDate.year,
466
+ month: old.referenceDate.month
467
+ });
468
+ const prev = previousMonth(current);
469
+ return {
470
+ referenceDate: prev.toPlainDate({ day: 1 })
471
+ };
472
+ });
473
+ };
474
+ const nextWeekImpl = () => {
475
+ setStateImpl((old) => ({
476
+ referenceDate: nextWeek(old.referenceDate)
477
+ }));
478
+ };
479
+ const previousWeekImpl = () => {
480
+ setStateImpl((old) => ({
481
+ referenceDate: previousWeek(old.referenceDate)
482
+ }));
483
+ };
484
+ const nextDayImpl = () => {
485
+ setStateImpl((old) => ({
486
+ referenceDate: nextDay(old.referenceDate)
487
+ }));
488
+ };
489
+ const previousDayImpl = () => {
490
+ setStateImpl((old) => ({
491
+ referenceDate: previousDay(old.referenceDate)
492
+ }));
493
+ };
494
+ const calendar = {
495
+ getMonth: getMonthImpl,
496
+ getWeek: getWeekImpl,
497
+ getDay: getDayImpl,
498
+ getTitle(view, locales, options2) {
499
+ switch (view) {
500
+ case "month": {
501
+ const month = getMonthImpl();
502
+ const date = month.month.toPlainDate({ day: 1 });
503
+ return date.toLocaleString(locales, {
504
+ month: "long",
505
+ year: "numeric",
506
+ ...options2
507
+ });
508
+ }
509
+ case "week": {
510
+ const week = getWeekImpl();
511
+ const startOptions = {
512
+ month: "short",
513
+ day: "numeric",
514
+ ...options2
515
+ };
516
+ const endOptions = {
517
+ month: "short",
518
+ day: "numeric",
519
+ year: "numeric",
520
+ ...options2
521
+ };
522
+ const start = week.weekStart.toLocaleString(locales, startOptions);
523
+ const end = week.weekEnd.toLocaleString(locales, endOptions);
524
+ return `${start} - ${end}`;
525
+ }
526
+ case "day": {
527
+ const day = getDayImpl();
528
+ return day.date.toLocaleString(locales, {
529
+ weekday: "long",
530
+ month: "long",
531
+ day: "numeric",
532
+ year: "numeric",
533
+ ...options2
534
+ });
535
+ }
536
+ }
537
+ },
538
+ getState() {
539
+ return store.state;
540
+ },
541
+ setState: setStateImpl,
542
+ nextMonth: nextMonthImpl,
543
+ previousMonth: previousMonthImpl,
544
+ goToMonth(year, month) {
545
+ setStateImpl(() => ({
546
+ referenceDate: Temporal6.PlainDate.from({ year, month, day: 1 })
547
+ }));
548
+ },
549
+ nextWeek: nextWeekImpl,
550
+ previousWeek: previousWeekImpl,
551
+ nextDay: nextDayImpl,
552
+ previousDay: previousDayImpl,
553
+ goToToday() {
554
+ setStateImpl(() => ({
555
+ referenceDate: Temporal6.Now.plainDateISO()
556
+ }));
557
+ },
558
+ goToDate(date) {
559
+ setStateImpl(() => ({
560
+ referenceDate: date
561
+ }));
562
+ },
563
+ next(view) {
564
+ switch (view) {
565
+ case "month":
566
+ nextMonthImpl();
567
+ break;
568
+ case "week":
569
+ nextWeekImpl();
570
+ break;
571
+ case "day":
572
+ nextDayImpl();
573
+ break;
574
+ }
575
+ },
576
+ previous(view) {
577
+ switch (view) {
578
+ case "month":
579
+ previousMonthImpl();
580
+ break;
581
+ case "week":
582
+ previousWeekImpl();
583
+ break;
584
+ case "day":
585
+ previousDayImpl();
586
+ break;
587
+ }
588
+ },
589
+ get views() {
590
+ return configuredViews;
591
+ },
592
+ get currentView() {
593
+ return store.state.currentView || defaultView;
594
+ },
595
+ setCurrentView(view) {
596
+ setStateImpl((old) => ({
597
+ ...old,
598
+ currentView: view
599
+ }));
600
+ },
601
+ get dateRange() {
602
+ return store.state.dateRange;
603
+ },
604
+ get options() {
605
+ return _options;
606
+ },
607
+ setOptions(updater) {
608
+ _options = functionalUpdate(updater, _options);
609
+ },
610
+ store
611
+ };
612
+ return calendar;
613
+ }
614
+
615
+ // src/createCalendarViews.ts
616
+ function createCalendarViews() {
617
+ return (views) => {
618
+ return views;
619
+ };
620
+ }
621
+ export {
622
+ buildDay,
623
+ buildMonth,
624
+ buildWeek,
625
+ convertToTimezone,
626
+ createCalendar,
627
+ createCalendarAccessor,
628
+ createCalendarViews,
629
+ createZonedDateTime,
630
+ formatTime,
631
+ functionalUpdate,
632
+ getCurrentTimeZone,
633
+ getDayDateRange,
634
+ getDayRange,
635
+ getEventPosition,
636
+ getMonthDateRange,
637
+ getMonthName,
638
+ getMonthRange,
639
+ getTimeSlotHeight,
640
+ getTimezoneOffset,
641
+ getWeekDateRange,
642
+ getWeekRange,
643
+ getWeekdays,
644
+ goToToday,
645
+ nextDay,
646
+ nextMonth,
647
+ nextWeek,
648
+ previousDay,
649
+ previousMonth,
650
+ previousWeek
651
+ };
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@gobrand/calendar-core",
3
+ "version": "0.0.3",
4
+ "description": "Lightweight utility library for building calendars using the Temporal API",
5
+ "private": false,
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "type": "module",
10
+ "main": "./dist/index.js",
11
+ "module": "./dist/index.js",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "require": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "https://github.com/go-brand/calendar.git",
29
+ "directory": "packages/core"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/go-brand/calendar/issues"
33
+ },
34
+ "homepage": "https://github.com/go-brand/calendar#readme",
35
+ "scripts": {
36
+ "build": "tsup src/index.ts --format esm,cjs --dts",
37
+ "test": "vitest",
38
+ "typecheck": "tsc --noEmit"
39
+ },
40
+ "dependencies": {
41
+ "@js-temporal/polyfill": "^0.5.1",
42
+ "@tanstack/store": "^0.8.0"
43
+ },
44
+ "devDependencies": {
45
+ "@vitest/coverage-v8": "^4.0.17",
46
+ "tsup": "^8.3.5",
47
+ "typescript": "^5.7.3",
48
+ "vitest": "^2.1.8"
49
+ },
50
+ "keywords": [
51
+ "temporal",
52
+ "calendar",
53
+ "date",
54
+ "datetime",
55
+ "time",
56
+ "temporal-api",
57
+ "month",
58
+ "week",
59
+ "year"
60
+ ]
61
+ }