kalendly 0.1.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.
@@ -0,0 +1,894 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/react-native/index.tsx
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Calendar: () => Calendar,
24
+ CalendarEngine: () => CalendarEngine,
25
+ DAYS: () => DAYS,
26
+ DatePopup: () => DatePopup,
27
+ MONTHS: () => MONTHS,
28
+ calendarStyles: () => calendarStyles,
29
+ formatDateForDisplay: () => formatDateForDisplay,
30
+ generateCalendarDates: () => generateCalendarDates,
31
+ generateYears: () => generateYears,
32
+ getCellClasses: () => getCellClasses,
33
+ getEventsForDate: () => getEventsForDate,
34
+ getMonthYearText: () => getMonthYearText,
35
+ getPopupPositionClass: () => getPopupPositionClass,
36
+ hasEvents: () => hasEvents,
37
+ isSameDay: () => isSameDay,
38
+ isToday: () => isToday,
39
+ normalizeDate: () => normalizeDate
40
+ });
41
+ module.exports = __toCommonJS(index_exports);
42
+
43
+ // src/react-native/components/Calendar.tsx
44
+ var import_react = require("react");
45
+ var import_react_native3 = require("react-native");
46
+
47
+ // src/core/utils.ts
48
+ var MONTHS = [
49
+ "Jan",
50
+ "Feb",
51
+ "Mar",
52
+ "Apr",
53
+ "May",
54
+ "Jun",
55
+ "Jul",
56
+ "Aug",
57
+ "Sep",
58
+ "Oct",
59
+ "Nov",
60
+ "Dec"
61
+ ];
62
+ var DAYS = [
63
+ "Sunday",
64
+ "Monday",
65
+ "Tuesday",
66
+ "Wednesday",
67
+ "Thursday",
68
+ "Friday",
69
+ "Saturday"
70
+ ];
71
+ function normalizeDate(date) {
72
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
73
+ }
74
+ function isSameDay(date1, date2) {
75
+ return normalizeDate(date1).getTime() === normalizeDate(date2).getTime();
76
+ }
77
+ function isToday(date) {
78
+ return isSameDay(date, /* @__PURE__ */ new Date());
79
+ }
80
+ function generateYears(minYear, maxYear) {
81
+ const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
82
+ const min = minYear ?? currentYear - 30;
83
+ const max = maxYear ?? currentYear + 10;
84
+ return Array.from({ length: max - min + 1 }, (_, i) => min + i);
85
+ }
86
+ function getEventsForDate(events, date) {
87
+ const normalizedTargetDate = normalizeDate(date);
88
+ return events.filter((event) => {
89
+ const eventDate = normalizeDate(new Date(event.date));
90
+ return eventDate.getTime() === normalizedTargetDate.getTime();
91
+ });
92
+ }
93
+ function hasEvents(events, date) {
94
+ return getEventsForDate(events, date).length > 0;
95
+ }
96
+ function generateCalendarDates(year, month, events = [], weekStartsOn = 0) {
97
+ const firstDay = new Date(year, month, 1);
98
+ const lastDay = new Date(year, month + 1, 0);
99
+ const daysInMonth = lastDay.getDate();
100
+ let firstDayOfWeek = firstDay.getDay();
101
+ if (weekStartsOn === 1) {
102
+ firstDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;
103
+ }
104
+ const dates = [];
105
+ let day = 1;
106
+ for (let week = 0; week < 6; week++) {
107
+ const weekDates = [];
108
+ for (let dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
109
+ if (week === 0 && dayOfWeek < firstDayOfWeek) {
110
+ weekDates.push(null);
111
+ } else if (day > daysInMonth) {
112
+ weekDates.push(null);
113
+ } else {
114
+ const currentDate = new Date(year, month, day);
115
+ const dateEvents = getEventsForDate(events, currentDate);
116
+ weekDates.push({
117
+ date: currentDate,
118
+ isCurrentMonth: true,
119
+ isToday: isToday(currentDate),
120
+ hasEvents: dateEvents.length > 0,
121
+ events: dateEvents
122
+ });
123
+ day++;
124
+ }
125
+ }
126
+ dates.push(weekDates);
127
+ if (day > daysInMonth && weekDates.every((date) => date === null)) {
128
+ break;
129
+ }
130
+ }
131
+ return dates;
132
+ }
133
+ function getPopupPositionClass(selectedDayIndex) {
134
+ if (selectedDayIndex === null) return "popup-center-bottom";
135
+ if (selectedDayIndex < 3) {
136
+ return "popup-right";
137
+ } else if (selectedDayIndex > 4) {
138
+ return "popup-left";
139
+ } else {
140
+ return "popup-center-bottom";
141
+ }
142
+ }
143
+ function getCellClasses(calendarDate) {
144
+ if (!calendarDate) return [];
145
+ const classes = [];
146
+ if (calendarDate.isToday) {
147
+ classes.push("schedule--current--exam");
148
+ }
149
+ if (calendarDate.hasEvents) {
150
+ classes.push("has--event");
151
+ }
152
+ return classes;
153
+ }
154
+ function formatDateForDisplay(date) {
155
+ return `${DAYS[date.getDay()]} ${date.getDate()}`;
156
+ }
157
+ function getMonthYearText(year, month) {
158
+ return `${MONTHS[month]} ${year}`;
159
+ }
160
+
161
+ // src/core/calendar-engine.ts
162
+ var CalendarEngine = class {
163
+ constructor(config) {
164
+ this.listeners = /* @__PURE__ */ new Set();
165
+ this.config = config;
166
+ const initialDate = config.initialDate || /* @__PURE__ */ new Date();
167
+ this.state = {
168
+ currentYear: initialDate.getFullYear(),
169
+ currentMonth: initialDate.getMonth(),
170
+ currentDate: initialDate.getDate(),
171
+ selectedDate: null,
172
+ selectedDayIndex: null,
173
+ tasks: []
174
+ };
175
+ }
176
+ /**
177
+ * Subscribe to state changes
178
+ */
179
+ subscribe(listener) {
180
+ this.listeners.add(listener);
181
+ return () => this.listeners.delete(listener);
182
+ }
183
+ /**
184
+ * Notify all listeners of state changes
185
+ */
186
+ notify() {
187
+ this.listeners.forEach((listener) => listener());
188
+ }
189
+ /**
190
+ * Get current state
191
+ */
192
+ getState() {
193
+ return { ...this.state };
194
+ }
195
+ /**
196
+ * Get view model with computed properties
197
+ */
198
+ getViewModel() {
199
+ const calendarDates = generateCalendarDates(
200
+ this.state.currentYear,
201
+ this.state.currentMonth,
202
+ this.config.events,
203
+ this.config.weekStartsOn
204
+ );
205
+ return {
206
+ ...this.state,
207
+ months: MONTHS,
208
+ days: DAYS,
209
+ years: generateYears(this.config.minYear, this.config.maxYear),
210
+ monthAndYearText: getMonthYearText(
211
+ this.state.currentYear,
212
+ this.state.currentMonth
213
+ ),
214
+ scheduleDay: this.state.selectedDate ? formatDateForDisplay(this.state.selectedDate) : "",
215
+ calendarDates,
216
+ popupPositionClass: getPopupPositionClass(this.state.selectedDayIndex)
217
+ };
218
+ }
219
+ /**
220
+ * Get actions object
221
+ */
222
+ getActions() {
223
+ return {
224
+ next: this.next.bind(this),
225
+ previous: this.previous.bind(this),
226
+ jump: this.jump.bind(this),
227
+ selectDate: this.selectDate.bind(this),
228
+ updateTasks: this.updateTasks.bind(this)
229
+ };
230
+ }
231
+ /**
232
+ * Navigate to next month
233
+ */
234
+ next() {
235
+ if (this.state.currentMonth === 11) {
236
+ this.state.currentMonth = 0;
237
+ this.state.currentYear++;
238
+ } else {
239
+ this.state.currentMonth++;
240
+ }
241
+ this.state.selectedDate = null;
242
+ this.state.selectedDayIndex = null;
243
+ this.updateTasks();
244
+ this.notify();
245
+ }
246
+ /**
247
+ * Navigate to previous month
248
+ */
249
+ previous() {
250
+ if (this.state.currentMonth === 0) {
251
+ this.state.currentMonth = 11;
252
+ this.state.currentYear--;
253
+ } else {
254
+ this.state.currentMonth--;
255
+ }
256
+ this.state.selectedDate = null;
257
+ this.state.selectedDayIndex = null;
258
+ this.updateTasks();
259
+ this.notify();
260
+ }
261
+ /**
262
+ * Jump to specific month and year
263
+ */
264
+ jump(year, month) {
265
+ this.state.currentYear = year;
266
+ this.state.currentMonth = month;
267
+ this.state.selectedDate = null;
268
+ this.state.selectedDayIndex = null;
269
+ this.updateTasks();
270
+ this.notify();
271
+ }
272
+ /**
273
+ * Select a specific date
274
+ */
275
+ selectDate(date, dayIndex) {
276
+ this.state.selectedDate = date;
277
+ this.state.selectedDayIndex = dayIndex ?? null;
278
+ this.state.currentDate = date.getDate();
279
+ this.state.currentMonth = date.getMonth();
280
+ this.state.currentYear = date.getFullYear();
281
+ this.updateTasks();
282
+ this.notify();
283
+ }
284
+ /**
285
+ * Update tasks for the currently selected date
286
+ */
287
+ updateTasks() {
288
+ if (!this.state.selectedDate) {
289
+ this.state.tasks = [];
290
+ return;
291
+ }
292
+ this.state.tasks = getEventsForDate(
293
+ this.config.events,
294
+ this.state.selectedDate
295
+ );
296
+ }
297
+ /**
298
+ * Update events configuration
299
+ */
300
+ updateEvents(events) {
301
+ this.config.events = events;
302
+ this.updateTasks();
303
+ this.notify();
304
+ }
305
+ /**
306
+ * Handle date cell click
307
+ */
308
+ handleDateClick(date, dayIndex) {
309
+ this.selectDate(date, dayIndex);
310
+ }
311
+ /**
312
+ * Check if date has events
313
+ */
314
+ hasEventsForDate(date) {
315
+ return getEventsForDate(this.config.events, date).length > 0;
316
+ }
317
+ /**
318
+ * Get events for a specific date
319
+ */
320
+ getEventsForDate(date) {
321
+ return getEventsForDate(this.config.events, date);
322
+ }
323
+ /**
324
+ * Clear selected date
325
+ */
326
+ clearSelection() {
327
+ this.state.selectedDate = null;
328
+ this.state.selectedDayIndex = null;
329
+ this.state.tasks = [];
330
+ this.notify();
331
+ }
332
+ /**
333
+ * Destroy the engine and cleanup listeners
334
+ */
335
+ destroy() {
336
+ this.listeners.clear();
337
+ }
338
+ };
339
+
340
+ // src/react-native/components/DatePopup.tsx
341
+ var import_react_native2 = require("react-native");
342
+
343
+ // src/styles/react-native-styles.ts
344
+ var import_react_native = require("react-native");
345
+ var { width } = import_react_native.Dimensions.get("window");
346
+ var cellSize = (width - 60) / 7;
347
+ var colors = {
348
+ primary: "#fc8917",
349
+ secondary: "#fca045",
350
+ tertiary: "#fdb873",
351
+ text: "#2c3e50",
352
+ border: "#dee2e6",
353
+ todayOutline: "#f7db04",
354
+ eventIndicator: "#1890ff",
355
+ background: "#fff",
356
+ white: "#ffffff"
357
+ };
358
+ var calendarStyles = import_react_native.StyleSheet.create({
359
+ container: {
360
+ flex: 1,
361
+ backgroundColor: colors.background
362
+ },
363
+ titleContainer: {
364
+ paddingVertical: 20,
365
+ alignItems: "center"
366
+ },
367
+ title: {
368
+ fontSize: 24,
369
+ fontWeight: "600",
370
+ color: colors.text
371
+ },
372
+ contentContainer: {
373
+ marginHorizontal: 20,
374
+ marginTop: 20
375
+ },
376
+ card: {
377
+ backgroundColor: colors.background,
378
+ borderRadius: 8,
379
+ shadowColor: "#000",
380
+ shadowOffset: {
381
+ width: 0,
382
+ height: 2
383
+ },
384
+ shadowOpacity: 0.1,
385
+ shadowRadius: 3.84,
386
+ elevation: 5,
387
+ overflow: "hidden"
388
+ },
389
+ cardHeader: {
390
+ backgroundColor: colors.tertiary,
391
+ paddingVertical: 15,
392
+ paddingHorizontal: 20,
393
+ borderBottomWidth: 1,
394
+ borderBottomColor: colors.border
395
+ },
396
+ cardHeaderText: {
397
+ fontSize: 18,
398
+ fontWeight: "500",
399
+ color: colors.text,
400
+ textAlign: "center"
401
+ },
402
+ // Calendar Table Styles
403
+ table: {
404
+ backgroundColor: colors.background
405
+ },
406
+ tableHeader: {
407
+ flexDirection: "row",
408
+ backgroundColor: "rgba(252, 137, 23, 0.1)",
409
+ borderBottomWidth: 2,
410
+ borderBottomColor: colors.border
411
+ },
412
+ tableHeaderCell: {
413
+ flex: 1,
414
+ paddingVertical: 12,
415
+ borderRightWidth: 1,
416
+ borderRightColor: colors.border,
417
+ alignItems: "center",
418
+ justifyContent: "center"
419
+ },
420
+ tableHeaderText: {
421
+ fontSize: 14,
422
+ fontWeight: "600",
423
+ color: colors.text
424
+ },
425
+ tableRow: {
426
+ flexDirection: "row",
427
+ borderBottomWidth: 1,
428
+ borderBottomColor: colors.border
429
+ },
430
+ tableCell: {
431
+ flex: 1,
432
+ height: cellSize,
433
+ borderRightWidth: 1,
434
+ borderRightColor: colors.border,
435
+ alignItems: "center",
436
+ justifyContent: "center",
437
+ position: "relative"
438
+ },
439
+ tableCellText: {
440
+ fontSize: 16,
441
+ color: colors.text
442
+ },
443
+ // Calendar Cell States
444
+ cellToday: {
445
+ borderWidth: 2,
446
+ borderColor: colors.todayOutline
447
+ },
448
+ cellTodayText: {
449
+ fontWeight: "bold"
450
+ },
451
+ cellWithEvents: {
452
+ backgroundColor: "rgba(252, 160, 69, 0.3)"
453
+ },
454
+ eventIndicator: {
455
+ position: "absolute",
456
+ bottom: 2,
457
+ width: 4,
458
+ height: 4,
459
+ backgroundColor: colors.eventIndicator,
460
+ borderRadius: 2
461
+ },
462
+ // Navigation Buttons
463
+ navigationContainer: {
464
+ flexDirection: "row",
465
+ justifyContent: "space-between",
466
+ paddingHorizontal: 20,
467
+ paddingVertical: 20,
468
+ gap: 15
469
+ },
470
+ navigationButton: {
471
+ flex: 1,
472
+ backgroundColor: "transparent",
473
+ borderWidth: 1,
474
+ borderColor: colors.primary,
475
+ borderRadius: 6,
476
+ paddingVertical: 12,
477
+ paddingHorizontal: 16,
478
+ alignItems: "center",
479
+ justifyContent: "center"
480
+ },
481
+ navigationButtonText: {
482
+ color: colors.primary,
483
+ fontSize: 16,
484
+ fontWeight: "500"
485
+ },
486
+ navigationButtonPressed: {
487
+ backgroundColor: colors.primary
488
+ },
489
+ navigationButtonTextPressed: {
490
+ color: colors.white
491
+ },
492
+ // Jump Form
493
+ jumpForm: {
494
+ flexDirection: "row",
495
+ alignItems: "center",
496
+ justifyContent: "center",
497
+ paddingHorizontal: 20,
498
+ paddingBottom: 20,
499
+ gap: 10
500
+ },
501
+ jumpLabel: {
502
+ fontSize: 18,
503
+ fontWeight: "300",
504
+ color: colors.text
505
+ },
506
+ jumpSelect: {
507
+ borderWidth: 1,
508
+ borderColor: colors.border,
509
+ borderRadius: 6,
510
+ paddingHorizontal: 12,
511
+ paddingVertical: 8,
512
+ backgroundColor: colors.background,
513
+ minWidth: 80
514
+ },
515
+ jumpSelectText: {
516
+ fontSize: 16,
517
+ color: colors.text,
518
+ textAlign: "center"
519
+ },
520
+ // Popup Styles
521
+ popupOverlay: {
522
+ position: "absolute",
523
+ top: 0,
524
+ left: 0,
525
+ right: 0,
526
+ bottom: 0,
527
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
528
+ justifyContent: "center",
529
+ alignItems: "center",
530
+ zIndex: 1e3
531
+ },
532
+ popup: {
533
+ backgroundColor: colors.background,
534
+ borderRadius: 12,
535
+ padding: 0,
536
+ width: width * 0.8,
537
+ maxWidth: 300,
538
+ shadowColor: "#000",
539
+ shadowOffset: {
540
+ width: 0,
541
+ height: 4
542
+ },
543
+ shadowOpacity: 0.3,
544
+ shadowRadius: 6,
545
+ elevation: 8
546
+ },
547
+ popupWrapper: {
548
+ backgroundColor: colors.secondary,
549
+ borderRadius: 12,
550
+ padding: 12
551
+ },
552
+ popupBlock: {
553
+ backgroundColor: colors.primary,
554
+ borderRadius: 8,
555
+ paddingVertical: 8,
556
+ paddingHorizontal: 12,
557
+ marginBottom: 10
558
+ },
559
+ popupDay: {
560
+ fontSize: 16,
561
+ fontWeight: "600",
562
+ color: colors.white,
563
+ textAlign: "center"
564
+ },
565
+ eventsList: {
566
+ gap: 6
567
+ },
568
+ eventItem: {
569
+ backgroundColor: colors.tertiary,
570
+ borderRadius: 6,
571
+ padding: 12
572
+ },
573
+ eventItemText: {
574
+ fontSize: 14,
575
+ color: colors.text
576
+ },
577
+ noEventsMessage: {
578
+ backgroundColor: colors.tertiary,
579
+ borderRadius: 6,
580
+ padding: 12,
581
+ alignItems: "center"
582
+ },
583
+ noEventsText: {
584
+ fontSize: 14,
585
+ color: colors.text,
586
+ textAlign: "center"
587
+ },
588
+ popupCloseButton: {
589
+ position: "absolute",
590
+ top: -10,
591
+ right: -10,
592
+ backgroundColor: colors.primary,
593
+ borderRadius: 15,
594
+ width: 30,
595
+ height: 30,
596
+ alignItems: "center",
597
+ justifyContent: "center"
598
+ },
599
+ popupCloseText: {
600
+ color: colors.white,
601
+ fontSize: 16,
602
+ fontWeight: "bold"
603
+ }
604
+ });
605
+
606
+ // src/react-native/components/DatePopup.tsx
607
+ var import_jsx_runtime = require("react/jsx-runtime");
608
+ var DatePopup = ({
609
+ visible,
610
+ selectedDate,
611
+ events,
612
+ scheduleDay,
613
+ onClose,
614
+ renderEvent,
615
+ renderNoEvents,
616
+ showCloseButton = true
617
+ }) => {
618
+ if (!selectedDate) return null;
619
+ const defaultRenderEvent = (event) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: calendarStyles.eventItem, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: calendarStyles.eventItemText, children: event.name }) }, event.id || event.name);
620
+ const defaultRenderNoEvents = () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: calendarStyles.noEventsMessage, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: calendarStyles.noEventsText, children: "No events scheduled for this day." }) });
621
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
622
+ import_react_native2.Modal,
623
+ {
624
+ visible,
625
+ transparent: true,
626
+ animationType: "fade",
627
+ onRequestClose: onClose,
628
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
629
+ import_react_native2.TouchableOpacity,
630
+ {
631
+ style: calendarStyles.popupOverlay,
632
+ activeOpacity: 1,
633
+ onPress: onClose,
634
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
635
+ import_react_native2.TouchableOpacity,
636
+ {
637
+ style: calendarStyles.popup,
638
+ activeOpacity: 1,
639
+ onPress: (e) => e.stopPropagation(),
640
+ children: [
641
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_native2.View, { style: calendarStyles.popupWrapper, children: [
642
+ showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
643
+ import_react_native2.TouchableOpacity,
644
+ {
645
+ style: calendarStyles.popupCloseButton,
646
+ onPress: onClose,
647
+ accessibilityLabel: "Close",
648
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: calendarStyles.popupCloseText, children: "\u2715" })
649
+ }
650
+ ),
651
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: calendarStyles.popupBlock, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: calendarStyles.popupDay, children: scheduleDay }) }),
652
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.ScrollView, { showsVerticalScrollIndicator: false, children: events.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.View, { style: calendarStyles.eventsList, children: events.map(
653
+ (event) => renderEvent ? renderEvent(event) : defaultRenderEvent(event)
654
+ ) }) : renderNoEvents ? renderNoEvents() : defaultRenderNoEvents() })
655
+ ] }),
656
+ showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
657
+ import_react_native2.TouchableOpacity,
658
+ {
659
+ style: calendarStyles.popupCloseButton,
660
+ onPress: onClose,
661
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native2.Text, { style: calendarStyles.popupCloseText, children: "\xD7" })
662
+ }
663
+ )
664
+ ]
665
+ }
666
+ )
667
+ }
668
+ )
669
+ }
670
+ );
671
+ };
672
+
673
+ // src/react-native/components/Calendar.tsx
674
+ var import_jsx_runtime2 = require("react/jsx-runtime");
675
+ var Select = ({
676
+ options,
677
+ selectedValue,
678
+ onValueChange,
679
+ style,
680
+ textStyle
681
+ }) => {
682
+ const selectedOption = options.find((opt) => opt.value === selectedValue);
683
+ const showPicker = () => {
684
+ import_react_native3.Alert.alert(
685
+ "Select Option",
686
+ "",
687
+ options.map((option) => ({
688
+ text: option.label,
689
+ onPress: () => onValueChange(option.value)
690
+ }))
691
+ );
692
+ };
693
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
694
+ import_react_native3.TouchableOpacity,
695
+ {
696
+ style: [calendarStyles.jumpSelect, style],
697
+ onPress: showPicker,
698
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: [calendarStyles.jumpSelectText, textStyle], children: selectedOption?.label })
699
+ }
700
+ );
701
+ };
702
+ var Calendar = ({
703
+ events,
704
+ initialDate,
705
+ minYear,
706
+ maxYear,
707
+ weekStartsOn = 0,
708
+ onDateSelect,
709
+ onEventClick,
710
+ onMonthChange,
711
+ style,
712
+ containerStyle,
713
+ headerStyle,
714
+ headerTextStyle,
715
+ cellStyle,
716
+ cellTextStyle,
717
+ renderEvent,
718
+ renderNoEvents,
719
+ title = "Event Schedule",
720
+ showCloseButton = true
721
+ }) => {
722
+ const engine = (0, import_react.useMemo)(
723
+ () => new CalendarEngine({
724
+ events,
725
+ initialDate,
726
+ minYear,
727
+ maxYear,
728
+ weekStartsOn
729
+ }),
730
+ []
731
+ );
732
+ const [, forceUpdate] = (0, import_react.useState)({});
733
+ const rerender = (0, import_react.useCallback)(() => forceUpdate({}), []);
734
+ (0, import_react.useEffect)(() => {
735
+ const unsubscribe = engine.subscribe(rerender);
736
+ return unsubscribe;
737
+ }, [engine, rerender]);
738
+ (0, import_react.useEffect)(() => {
739
+ engine.updateEvents(events);
740
+ }, [engine, events]);
741
+ const viewModel = engine.getViewModel();
742
+ const actions = engine.getActions();
743
+ const { selectedDate, tasks } = viewModel;
744
+ const handleDatePress = (date, dayIndex) => {
745
+ engine.handleDateClick(date, dayIndex);
746
+ onDateSelect?.(date);
747
+ };
748
+ const handleNext = () => {
749
+ actions.next();
750
+ onMonthChange?.(viewModel.currentYear, viewModel.currentMonth);
751
+ };
752
+ const handlePrevious = () => {
753
+ actions.previous();
754
+ onMonthChange?.(viewModel.currentYear, viewModel.currentMonth);
755
+ };
756
+ const handleMonthChange = (month) => {
757
+ actions.jump(viewModel.currentYear, month);
758
+ onMonthChange?.(viewModel.currentYear, month);
759
+ };
760
+ const handleYearChange = (year) => {
761
+ actions.jump(year, viewModel.currentMonth);
762
+ onMonthChange?.(year, viewModel.currentMonth);
763
+ };
764
+ const closePopup = () => {
765
+ engine.clearSelection();
766
+ };
767
+ const monthOptions = viewModel.months.map((month, index) => ({
768
+ label: month,
769
+ value: index
770
+ }));
771
+ const yearOptions = viewModel.years.map((year) => ({
772
+ label: year.toString(),
773
+ value: year
774
+ }));
775
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.ScrollView, { style: [calendarStyles.container, containerStyle], children: [
776
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: calendarStyles.titleContainer, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: calendarStyles.title, children: title }) }),
777
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: [calendarStyles.contentContainer, style], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: calendarStyles.card, children: [
778
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: [calendarStyles.cardHeader, headerStyle], children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: [calendarStyles.cardHeaderText, headerTextStyle], children: viewModel.monthAndYearText }) }),
779
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: calendarStyles.table, children: [
780
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: calendarStyles.tableHeader, children: viewModel.days.map((day) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: calendarStyles.tableHeaderCell, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: calendarStyles.tableHeaderText, children: day.slice(0, 3) }) }, day)) }),
781
+ viewModel.calendarDates.map((week, weekIndex) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: calendarStyles.tableRow, children: week.map((calendarDate, dayIndex) => {
782
+ const cellClasses = getCellClasses(calendarDate);
783
+ const isToday2 = cellClasses.includes(
784
+ "schedule--current--exam"
785
+ );
786
+ const hasEvents2 = cellClasses.includes("has--event");
787
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
788
+ import_react_native3.TouchableOpacity,
789
+ {
790
+ style: [
791
+ calendarStyles.tableCell,
792
+ cellStyle,
793
+ isToday2 && calendarStyles.cellToday,
794
+ hasEvents2 && calendarStyles.cellWithEvents
795
+ ],
796
+ onPress: () => {
797
+ if (calendarDate) {
798
+ handleDatePress(calendarDate.date, dayIndex);
799
+ }
800
+ },
801
+ disabled: !calendarDate,
802
+ children: calendarDate && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
803
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
804
+ import_react_native3.Text,
805
+ {
806
+ style: [
807
+ calendarStyles.tableCellText,
808
+ cellTextStyle,
809
+ isToday2 && calendarStyles.cellTodayText
810
+ ],
811
+ children: calendarDate.date.getDate()
812
+ }
813
+ ),
814
+ hasEvents2 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.View, { style: calendarStyles.eventIndicator })
815
+ ] })
816
+ },
817
+ `${weekIndex}-${dayIndex}`
818
+ );
819
+ }) }, weekIndex))
820
+ ] }),
821
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: calendarStyles.navigationContainer, children: [
822
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
823
+ import_react_native3.TouchableOpacity,
824
+ {
825
+ style: calendarStyles.navigationButton,
826
+ onPress: handlePrevious,
827
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: calendarStyles.navigationButtonText, children: "Previous" })
828
+ }
829
+ ),
830
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
831
+ import_react_native3.TouchableOpacity,
832
+ {
833
+ style: calendarStyles.navigationButton,
834
+ onPress: handleNext,
835
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: calendarStyles.navigationButtonText, children: "Next" })
836
+ }
837
+ )
838
+ ] }),
839
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_native3.View, { style: calendarStyles.jumpForm, children: [
840
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_native3.Text, { style: calendarStyles.jumpLabel, children: "Jump To:" }),
841
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
842
+ Select,
843
+ {
844
+ options: monthOptions,
845
+ selectedValue: viewModel.currentMonth,
846
+ onValueChange: handleMonthChange
847
+ }
848
+ ),
849
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
850
+ Select,
851
+ {
852
+ options: yearOptions,
853
+ selectedValue: viewModel.currentYear,
854
+ onValueChange: handleYearChange
855
+ }
856
+ )
857
+ ] })
858
+ ] }) }),
859
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
860
+ DatePopup,
861
+ {
862
+ visible: !!selectedDate,
863
+ selectedDate,
864
+ events: tasks,
865
+ scheduleDay: viewModel.scheduleDay,
866
+ onClose: closePopup,
867
+ renderEvent,
868
+ renderNoEvents,
869
+ showCloseButton
870
+ }
871
+ )
872
+ ] });
873
+ };
874
+ // Annotate the CommonJS export names for ESM import in node:
875
+ 0 && (module.exports = {
876
+ Calendar,
877
+ CalendarEngine,
878
+ DAYS,
879
+ DatePopup,
880
+ MONTHS,
881
+ calendarStyles,
882
+ formatDateForDisplay,
883
+ generateCalendarDates,
884
+ generateYears,
885
+ getCellClasses,
886
+ getEventsForDate,
887
+ getMonthYearText,
888
+ getPopupPositionClass,
889
+ hasEvents,
890
+ isSameDay,
891
+ isToday,
892
+ normalizeDate
893
+ });
894
+ //# sourceMappingURL=index.js.map