kalendly 0.1.4 → 0.1.6
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 +260 -21
- package/dist/core/index.d.mts +29 -4
- package/dist/core/index.d.ts +29 -4
- package/dist/core/index.js +63 -7
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +62 -7
- package/dist/core/index.mjs.map +1 -1
- package/dist/index.d.mts +50 -7
- package/dist/index.d.ts +50 -7
- package/dist/index.js +1030 -298
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1049 -302
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +30 -4
- package/dist/react/index.d.ts +30 -4
- package/dist/react/index.js +284 -64
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +290 -65
- package/dist/react/index.mjs.map +1 -1
- package/dist/react-native/index.d.mts +31 -4
- package/dist/react-native/index.d.ts +31 -4
- package/dist/react-native/index.js +550 -152
- package/dist/react-native/index.js.map +1 -1
- package/dist/react-native/index.mjs +562 -155
- package/dist/react-native/index.mjs.map +1 -1
- package/dist/styles/calendar.css +325 -5
- package/dist/vanilla/index.d.mts +38 -4
- package/dist/vanilla/index.d.ts +38 -4
- package/dist/vanilla/index.js +319 -96
- package/dist/vanilla/index.js.map +1 -1
- package/dist/vanilla/index.mjs +318 -96
- package/dist/vanilla/index.mjs.map +1 -1
- package/dist/vanilla/index.umd.js +318 -96
- package/dist/vanilla/index.umd.js.map +1 -1
- package/dist/vue/components/Calendar.vue.d.ts +8 -4
- package/dist/vue/components/Calendar.vue.d.ts.map +1 -1
- package/dist/vue/index.d.ts +18 -14
- package/dist/vue/index.d.ts.map +1 -1
- package/dist/vue/index.js +1 -1
- package/dist/vue/index.mjs +397 -278
- package/dist/vue/types.d.ts +2 -1
- package/dist/vue/types.d.ts.map +1 -1
- package/package.json +32 -28
- package/styles.d.ts +1 -0
package/README.md
CHANGED
|
@@ -1,26 +1,39 @@
|
|
|
1
|
-
# kalendly Universal Calendar
|
|
1
|
+
# kalendly Universal Calendar
|
|
2
2
|
|
|
3
|
-
A universal calendar
|
|
3
|
+
A universal calendar component that works seamlessly across React, Vue, and React Native with full TypeScript support.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- 🚀 **Universal**: Works with React, Vue, React Native, and Vanilla JavaScript
|
|
8
|
-
- 📱 **Responsive**: Mobile-friendly design that matches your existing
|
|
8
|
+
- 📱 **Responsive**: Mobile-friendly design that matches your existing UI implementation
|
|
9
9
|
- 🎨 **Customizable**: Easy to theme and customize with CSS variables
|
|
10
10
|
- 🔒 **Type Safe**: Full TypeScript support
|
|
11
11
|
- 📅 **Event Management**: Add, display, and manage events with rich metadata
|
|
12
12
|
- 🔔 **Advanced Features**: Recurring events, reminders, categories, priorities, and collaboration
|
|
13
13
|
- 🌐 **Accessible**: Built with accessibility in mind
|
|
14
14
|
- 📦 **Tree Shakeable**: Import only what you need
|
|
15
|
-
- 🎯 **Design Consistent**: Matches the original Vue calendar design and feel
|
|
16
15
|
|
|
17
|
-
## Live
|
|
16
|
+
## 🎯 Live Demo
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
<div align="center">
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
[](https://kalendly-example.netlify.app/)
|
|
21
|
+
|
|
22
|
+
**[🚀 Try the Interactive Demo →](https://kalendly-example.netlify.app/)**
|
|
23
|
+
|
|
24
|
+
</div>
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
<a href="https://kalendly-example.netlify.app/vanilla">
|
|
28
|
+
<img src="https://img.shields.io/badge/Vanilla_JS-fc8917?style=for-the-badge&logo=javascript&logoColor=white" alt="Vanilla JS Demo"/>
|
|
29
|
+
</a>
|
|
30
|
+
<a href="https://kalendly-example.netlify.app/react">
|
|
31
|
+
<img src="https://img.shields.io/badge/React-61DAFB?style=for-the-badge&logo=react&logoColor=black" alt="React Demo"/>
|
|
32
|
+
</a>
|
|
33
|
+
<a href="https://kalendly-example.netlify.app/vue">
|
|
34
|
+
<img src="https://img.shields.io/badge/Vue-4FC08D?style=for-the-badge&logo=vue.js&logoColor=white" alt="Vue Demo"/>
|
|
35
|
+
</a>
|
|
36
|
+
</p>
|
|
24
37
|
|
|
25
38
|
## Installation
|
|
26
39
|
|
|
@@ -273,17 +286,19 @@ export default App;
|
|
|
273
286
|
|
|
274
287
|
### Props
|
|
275
288
|
|
|
276
|
-
| Prop
|
|
277
|
-
|
|
|
278
|
-
| `events`
|
|
279
|
-
| `initialDate`
|
|
280
|
-
| `minYear`
|
|
281
|
-
| `maxYear`
|
|
282
|
-
| `weekStartsOn`
|
|
283
|
-
| `
|
|
284
|
-
| `
|
|
285
|
-
| `
|
|
286
|
-
| `
|
|
289
|
+
| Prop | Type | Default | Description |
|
|
290
|
+
| -------------------- | --------------------------------------- | ------------------ | --------------------------------------- |
|
|
291
|
+
| `events` | `CalendarEvent[]` | `[]` | Array of events to display |
|
|
292
|
+
| `initialDate` | `Date` | `new Date()` | Initial date to display |
|
|
293
|
+
| `minYear` | `number` | `currentYear - 30` | Minimum selectable year |
|
|
294
|
+
| `maxYear` | `number` | `currentYear + 10` | Maximum selectable year |
|
|
295
|
+
| `weekStartsOn` | `0 \| 1` | `0` | Week start day (0 = Sunday, 1 = Monday) |
|
|
296
|
+
| `useShortMonthNames` | `boolean` | `false` | Use abbreviated month names (Jan, Feb) |
|
|
297
|
+
| `categoryColors` | `CategoryColorMap` | `{}` | Custom colors for event categories |
|
|
298
|
+
| `theme` | `CalendarTheme` | `undefined` | Custom theme colors for the calendar |
|
|
299
|
+
| `onDateSelect` | `(date: Date) => void` | - | Callback when date is selected |
|
|
300
|
+
| `onEventClick` | `(event: CalendarEvent) => void` | - | Callback when event is clicked |
|
|
301
|
+
| `onMonthChange` | `(year: number, month: number) => void` | - | Callback when month changes |
|
|
287
302
|
|
|
288
303
|
### CalendarEvent Interface
|
|
289
304
|
|
|
@@ -397,6 +412,218 @@ const categoryColors = {
|
|
|
397
412
|
<Calendar events={events} categoryColors={categoryColors} />
|
|
398
413
|
```
|
|
399
414
|
|
|
415
|
+
## Theming
|
|
416
|
+
|
|
417
|
+
Kalendly supports custom theming across all frameworks with a **consistent API**. Customize calendar colors to match your brand or create light/dark themes.
|
|
418
|
+
|
|
419
|
+
### CalendarTheme Interface
|
|
420
|
+
|
|
421
|
+
```typescript
|
|
422
|
+
interface CalendarTheme {
|
|
423
|
+
primary?: string; // Primary brand color
|
|
424
|
+
secondary?: string; // Secondary brand color
|
|
425
|
+
tertiary?: string; // Tertiary/accent color
|
|
426
|
+
textColor?: string; // Main text color
|
|
427
|
+
textLight?: string; // Light/secondary text color
|
|
428
|
+
background?: string; // Background color
|
|
429
|
+
cellHover?: string; // Cell hover state color
|
|
430
|
+
borderColor?: string; // Border color
|
|
431
|
+
todayOutline?: string; // Today indicator color
|
|
432
|
+
selectedBg?: string; // Selected date background
|
|
433
|
+
eventIndicator?: string; // Event indicator dot color
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
### Basic Theme Example
|
|
438
|
+
|
|
439
|
+
**React:**
|
|
440
|
+
|
|
441
|
+
```tsx
|
|
442
|
+
import { Calendar } from 'kalendly/react';
|
|
443
|
+
import 'kalendly/styles';
|
|
444
|
+
|
|
445
|
+
function App() {
|
|
446
|
+
return (
|
|
447
|
+
<Calendar
|
|
448
|
+
events={events}
|
|
449
|
+
theme={{
|
|
450
|
+
primary: '#3b82f6',
|
|
451
|
+
secondary: '#60a5fa',
|
|
452
|
+
tertiary: '#93c5fd',
|
|
453
|
+
borderColor: '#e5e7eb',
|
|
454
|
+
todayOutline: '#fbbf24',
|
|
455
|
+
eventIndicator: '#10b981',
|
|
456
|
+
}}
|
|
457
|
+
/>
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
**Vue:**
|
|
463
|
+
|
|
464
|
+
```vue
|
|
465
|
+
<template>
|
|
466
|
+
<Calendar :events="events" :theme="calendarTheme" />
|
|
467
|
+
</template>
|
|
468
|
+
|
|
469
|
+
<script setup lang="ts">
|
|
470
|
+
import { Calendar } from 'kalendly/vue';
|
|
471
|
+
import 'kalendly/styles';
|
|
472
|
+
|
|
473
|
+
const calendarTheme = {
|
|
474
|
+
primary: '#3b82f6',
|
|
475
|
+
secondary: '#60a5fa',
|
|
476
|
+
tertiary: '#93c5fd',
|
|
477
|
+
borderColor: '#e5e7eb',
|
|
478
|
+
todayOutline: '#fbbf24',
|
|
479
|
+
eventIndicator: '#10b981',
|
|
480
|
+
};
|
|
481
|
+
</script>
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**Vanilla JavaScript:**
|
|
485
|
+
|
|
486
|
+
```javascript
|
|
487
|
+
import { createCalendar } from 'kalendly/vanilla';
|
|
488
|
+
import 'kalendly/styles';
|
|
489
|
+
|
|
490
|
+
const calendar = createCalendar({
|
|
491
|
+
container: '#calendar',
|
|
492
|
+
events: events,
|
|
493
|
+
theme: {
|
|
494
|
+
primary: '#3b82f6',
|
|
495
|
+
secondary: '#60a5fa',
|
|
496
|
+
tertiary: '#93c5fd',
|
|
497
|
+
borderColor: '#e5e7eb',
|
|
498
|
+
todayOutline: '#fbbf24',
|
|
499
|
+
eventIndicator: '#10b981',
|
|
500
|
+
},
|
|
501
|
+
});
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
**React Native:**
|
|
505
|
+
|
|
506
|
+
```tsx
|
|
507
|
+
import { Calendar } from 'kalendly/react-native';
|
|
508
|
+
|
|
509
|
+
function App() {
|
|
510
|
+
return (
|
|
511
|
+
<Calendar
|
|
512
|
+
events={events}
|
|
513
|
+
theme={{
|
|
514
|
+
primary: '#3b82f6',
|
|
515
|
+
secondary: '#60a5fa',
|
|
516
|
+
tertiary: '#93c5fd',
|
|
517
|
+
borderColor: '#e5e7eb',
|
|
518
|
+
todayOutline: '#fbbf24',
|
|
519
|
+
eventIndicator: '#10b981',
|
|
520
|
+
}}
|
|
521
|
+
/>
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### Dark Theme Example
|
|
527
|
+
|
|
528
|
+
```typescript
|
|
529
|
+
const darkTheme = {
|
|
530
|
+
primary: '#6366f1',
|
|
531
|
+
secondary: '#818cf8',
|
|
532
|
+
tertiary: '#a5b4fc',
|
|
533
|
+
textColor: '#f9fafb',
|
|
534
|
+
textLight: '#d1d5db',
|
|
535
|
+
background: '#1f2937',
|
|
536
|
+
cellHover: '#374151',
|
|
537
|
+
borderColor: '#4b5563',
|
|
538
|
+
todayOutline: '#fbbf24',
|
|
539
|
+
selectedBg: '#312e81',
|
|
540
|
+
eventIndicator: '#34d399'
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
<Calendar events={events} theme={darkTheme} />
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### Dynamic Theme Switching
|
|
547
|
+
|
|
548
|
+
**React:**
|
|
549
|
+
|
|
550
|
+
```tsx
|
|
551
|
+
import { useState } from 'react';
|
|
552
|
+
import { Calendar } from 'kalendly/react';
|
|
553
|
+
|
|
554
|
+
const themes = {
|
|
555
|
+
blue: { primary: '#3b82f6', secondary: '#60a5fa' },
|
|
556
|
+
purple: { primary: '#8b5cf6', secondary: '#a78bfa' },
|
|
557
|
+
green: { primary: '#10b981', secondary: '#34d399' },
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
function App() {
|
|
561
|
+
const [currentTheme, setCurrentTheme] = useState('blue');
|
|
562
|
+
|
|
563
|
+
return (
|
|
564
|
+
<>
|
|
565
|
+
<button onClick={() => setCurrentTheme('blue')}>Blue</button>
|
|
566
|
+
<button onClick={() => setCurrentTheme('purple')}>Purple</button>
|
|
567
|
+
<button onClick={() => setCurrentTheme('green')}>Green</button>
|
|
568
|
+
|
|
569
|
+
<Calendar events={events} theme={themes[currentTheme]} />
|
|
570
|
+
</>
|
|
571
|
+
);
|
|
572
|
+
}
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
**Vue:**
|
|
576
|
+
|
|
577
|
+
```vue
|
|
578
|
+
<template>
|
|
579
|
+
<div>
|
|
580
|
+
<button @click="currentTheme = 'blue'">Blue</button>
|
|
581
|
+
<button @click="currentTheme = 'purple'">Purple</button>
|
|
582
|
+
<button @click="currentTheme = 'green'">Green</button>
|
|
583
|
+
|
|
584
|
+
<Calendar :events="events" :theme="themes[currentTheme]" />
|
|
585
|
+
</div>
|
|
586
|
+
</template>
|
|
587
|
+
|
|
588
|
+
<script setup lang="ts">
|
|
589
|
+
import { ref } from 'vue';
|
|
590
|
+
import { Calendar } from 'kalendly/vue';
|
|
591
|
+
|
|
592
|
+
const themes = {
|
|
593
|
+
blue: { primary: '#3b82f6', secondary: '#60a5fa' },
|
|
594
|
+
purple: { primary: '#8b5cf6', secondary: '#a78bfa' },
|
|
595
|
+
green: { primary: '#10b981', secondary: '#34d399' },
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
const currentTheme = ref('blue');
|
|
599
|
+
</script>
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
**Vanilla JavaScript:**
|
|
603
|
+
|
|
604
|
+
```javascript
|
|
605
|
+
import { createCalendar } from 'kalendly/vanilla';
|
|
606
|
+
|
|
607
|
+
const themes = {
|
|
608
|
+
blue: { primary: '#3b82f6', secondary: '#60a5fa' },
|
|
609
|
+
purple: { primary: '#8b5cf6', secondary: '#a78bfa' },
|
|
610
|
+
green: { primary: '#10b981', secondary: '#34d399' },
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
const calendar = createCalendar({
|
|
614
|
+
container: '#calendar',
|
|
615
|
+
events: events,
|
|
616
|
+
theme: themes.blue,
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
// Update theme dynamically without recreation
|
|
620
|
+
document.getElementById('purple-btn').addEventListener('click', () => {
|
|
621
|
+
calendar.updateTheme(themes.purple);
|
|
622
|
+
});
|
|
623
|
+
```
|
|
624
|
+
|
|
625
|
+
> **Note:** The `updateTheme()` method is available in Vanilla JavaScript for efficient theme updates without recreating the calendar instance.
|
|
626
|
+
|
|
400
627
|
## Framework-Specific Features
|
|
401
628
|
|
|
402
629
|
### React Props
|
|
@@ -508,7 +735,9 @@ Always include the CSS file:
|
|
|
508
735
|
```css
|
|
509
736
|
:root {
|
|
510
737
|
--calendar-primary-color: #fc8917;
|
|
738
|
+
--calendar-primary-color-rgb: 252, 137, 23;
|
|
511
739
|
--calendar-secondary-color: #fca045;
|
|
740
|
+
--calendar-secondary-color-rgb: 252, 160, 69;
|
|
512
741
|
--calendar-tertiary-color: #fdb873;
|
|
513
742
|
--calendar-text-color: #2c3e50;
|
|
514
743
|
--calendar-border-color: #dee2e6;
|
|
@@ -518,6 +747,8 @@ Always include the CSS file:
|
|
|
518
747
|
}
|
|
519
748
|
```
|
|
520
749
|
|
|
750
|
+
> **Note:** The `-rgb` variables are used for semi-transparent backgrounds (e.g., hover states) and provide compatibility with older browsers (Chrome < 111, Safari iOS < 16.2).
|
|
751
|
+
|
|
521
752
|
### React Native Theming
|
|
522
753
|
|
|
523
754
|
```javascript
|
|
@@ -558,6 +789,10 @@ const actions = engine.getActions();
|
|
|
558
789
|
actions.next();
|
|
559
790
|
actions.previous();
|
|
560
791
|
actions.jump(2025, 5); // June 2025
|
|
792
|
+
actions.goToToday(); // Navigate to current month
|
|
793
|
+
|
|
794
|
+
// Check current view
|
|
795
|
+
const isCurrentMonth = actions.isCurrentMonth(); // true if viewing today's month
|
|
561
796
|
|
|
562
797
|
// Clean up
|
|
563
798
|
unsubscribe();
|
|
@@ -613,6 +848,10 @@ See [CHANGELOG.md](CHANGELOG.md) for detailed release notes and version history.
|
|
|
613
848
|
|
|
614
849
|
### Recent Updates
|
|
615
850
|
|
|
616
|
-
- **v0.1.
|
|
851
|
+
- **v0.1.6** (Upcoming): Navigation enhancements with Today button, month/year picker dropdown, calendar grid improvements showing previous/next month days, and browser compatibility fixes
|
|
852
|
+
- **v0.1.5**: Universal theming system, TypeScript support improvements, integration test enhancements
|
|
853
|
+
- **v0.1.4**: Netlify configuration updates
|
|
854
|
+
- **v0.1.3**: Vue types generation improvements
|
|
855
|
+
- **v0.1.2**: Enhanced event parameters with structured metadata, categories, recurrence, collaboration features
|
|
617
856
|
- **v0.1.1**: Pre-commit hooks and trusted publishing with OIDC
|
|
618
857
|
- **v0.1.0**: Initial release with React, Vue, React Native, and Vanilla JavaScript support
|
package/dist/core/index.d.mts
CHANGED
|
@@ -57,6 +57,8 @@ interface CalendarActions {
|
|
|
57
57
|
next: () => void;
|
|
58
58
|
previous: () => void;
|
|
59
59
|
jump: (year: number, month: number) => void;
|
|
60
|
+
goToToday: () => void;
|
|
61
|
+
isCurrentMonth: () => boolean;
|
|
60
62
|
selectDate: (date: Date) => void;
|
|
61
63
|
updateTasks: () => void;
|
|
62
64
|
}
|
|
@@ -70,7 +72,7 @@ interface CalendarViewModel extends CalendarState {
|
|
|
70
72
|
years: number[];
|
|
71
73
|
monthAndYearText: string;
|
|
72
74
|
scheduleDay: string;
|
|
73
|
-
calendarDates:
|
|
75
|
+
calendarDates: CalendarDate[][];
|
|
74
76
|
popupPositionClass: string;
|
|
75
77
|
}
|
|
76
78
|
type CalendarEventHandler = (event: CalendarEvent) => void;
|
|
@@ -80,12 +82,27 @@ interface CalendarProps {
|
|
|
80
82
|
minYear?: number;
|
|
81
83
|
maxYear?: number;
|
|
82
84
|
weekStartsOn?: 0 | 1;
|
|
85
|
+
useShortMonthNames?: boolean;
|
|
83
86
|
onDateSelect?: (date: Date) => void;
|
|
84
87
|
onEventClick?: CalendarEventHandler;
|
|
85
88
|
onMonthChange?: (year: number, month: number) => void;
|
|
86
89
|
}
|
|
90
|
+
interface CalendarTheme {
|
|
91
|
+
primary?: string;
|
|
92
|
+
secondary?: string;
|
|
93
|
+
tertiary?: string;
|
|
94
|
+
textColor?: string;
|
|
95
|
+
textLight?: string;
|
|
96
|
+
background?: string;
|
|
97
|
+
cellHover?: string;
|
|
98
|
+
borderColor?: string;
|
|
99
|
+
todayOutline?: string;
|
|
100
|
+
selectedBg?: string;
|
|
101
|
+
eventIndicator?: string;
|
|
102
|
+
}
|
|
87
103
|
|
|
88
104
|
declare const MONTHS: string[];
|
|
105
|
+
declare const MONTHS_FULL: string[];
|
|
89
106
|
declare const DAYS: string[];
|
|
90
107
|
declare function normalizeDate(date: Date): Date;
|
|
91
108
|
declare function isSameDay(date1: Date, date2: Date): boolean;
|
|
@@ -93,9 +110,9 @@ declare function isToday(date: Date): boolean;
|
|
|
93
110
|
declare function generateYears(minYear?: number, maxYear?: number): number[];
|
|
94
111
|
declare function getEventsForDate(events: CalendarEvent[], date: Date): CalendarEvent[];
|
|
95
112
|
declare function hasEvents(events: CalendarEvent[], date: Date): boolean;
|
|
96
|
-
declare function generateCalendarDates(year: number, month: number, events?: CalendarEvent[], weekStartsOn?: 0 | 1):
|
|
113
|
+
declare function generateCalendarDates(year: number, month: number, events?: CalendarEvent[], weekStartsOn?: 0 | 1): CalendarDate[][];
|
|
97
114
|
declare function getPopupPositionClass(selectedDayIndex: number | null): string;
|
|
98
|
-
declare function getCellClasses(calendarDate: CalendarDate
|
|
115
|
+
declare function getCellClasses(calendarDate: CalendarDate): string[];
|
|
99
116
|
declare function formatDateForDisplay(date: Date): string;
|
|
100
117
|
declare function getMonthYearText(year: number, month: number): string;
|
|
101
118
|
declare function formatTimeRange(event: CalendarEvent): string;
|
|
@@ -145,6 +162,14 @@ declare class CalendarEngine {
|
|
|
145
162
|
* Jump to specific month and year
|
|
146
163
|
*/
|
|
147
164
|
private jump;
|
|
165
|
+
/**
|
|
166
|
+
* Navigate to current month (today)
|
|
167
|
+
*/
|
|
168
|
+
private goToToday;
|
|
169
|
+
/**
|
|
170
|
+
* Check if currently viewing today's month
|
|
171
|
+
*/
|
|
172
|
+
private isCurrentMonth;
|
|
148
173
|
/**
|
|
149
174
|
* Select a specific date
|
|
150
175
|
*/
|
|
@@ -195,4 +220,4 @@ declare class CalendarEngine {
|
|
|
195
220
|
destroy(): void;
|
|
196
221
|
}
|
|
197
222
|
|
|
198
|
-
export { type CalendarActions, type CalendarConfig, type CalendarDate, CalendarEngine, type CalendarEvent, type CalendarEventHandler, type CalendarProps, type CalendarState, type CalendarViewModel, type CategoryColorMap, DAYS, DEFAULT_CATEGORY_COLORS, MONTHS, type PopupPosition, formatAttendees, formatDateForDisplay, formatTimeRange, generateCalendarDates, generateYears, getCategoryColor, getCellClasses, getDefaultEventColor, getEventsForDate, getMonthYearText, getPopupPositionClass, hasEvents, isSameDay, isToday, isValidHexColor, mergeCategoryColors, normalizeDate, sortEventsByTime };
|
|
223
|
+
export { type CalendarActions, type CalendarConfig, type CalendarDate, CalendarEngine, type CalendarEvent, type CalendarEventHandler, type CalendarProps, type CalendarState, type CalendarTheme, type CalendarViewModel, type CategoryColorMap, DAYS, DEFAULT_CATEGORY_COLORS, MONTHS, MONTHS_FULL, type PopupPosition, formatAttendees, formatDateForDisplay, formatTimeRange, generateCalendarDates, generateYears, getCategoryColor, getCellClasses, getDefaultEventColor, getEventsForDate, getMonthYearText, getPopupPositionClass, hasEvents, isSameDay, isToday, isValidHexColor, mergeCategoryColors, normalizeDate, sortEventsByTime };
|
package/dist/core/index.d.ts
CHANGED
|
@@ -57,6 +57,8 @@ interface CalendarActions {
|
|
|
57
57
|
next: () => void;
|
|
58
58
|
previous: () => void;
|
|
59
59
|
jump: (year: number, month: number) => void;
|
|
60
|
+
goToToday: () => void;
|
|
61
|
+
isCurrentMonth: () => boolean;
|
|
60
62
|
selectDate: (date: Date) => void;
|
|
61
63
|
updateTasks: () => void;
|
|
62
64
|
}
|
|
@@ -70,7 +72,7 @@ interface CalendarViewModel extends CalendarState {
|
|
|
70
72
|
years: number[];
|
|
71
73
|
monthAndYearText: string;
|
|
72
74
|
scheduleDay: string;
|
|
73
|
-
calendarDates:
|
|
75
|
+
calendarDates: CalendarDate[][];
|
|
74
76
|
popupPositionClass: string;
|
|
75
77
|
}
|
|
76
78
|
type CalendarEventHandler = (event: CalendarEvent) => void;
|
|
@@ -80,12 +82,27 @@ interface CalendarProps {
|
|
|
80
82
|
minYear?: number;
|
|
81
83
|
maxYear?: number;
|
|
82
84
|
weekStartsOn?: 0 | 1;
|
|
85
|
+
useShortMonthNames?: boolean;
|
|
83
86
|
onDateSelect?: (date: Date) => void;
|
|
84
87
|
onEventClick?: CalendarEventHandler;
|
|
85
88
|
onMonthChange?: (year: number, month: number) => void;
|
|
86
89
|
}
|
|
90
|
+
interface CalendarTheme {
|
|
91
|
+
primary?: string;
|
|
92
|
+
secondary?: string;
|
|
93
|
+
tertiary?: string;
|
|
94
|
+
textColor?: string;
|
|
95
|
+
textLight?: string;
|
|
96
|
+
background?: string;
|
|
97
|
+
cellHover?: string;
|
|
98
|
+
borderColor?: string;
|
|
99
|
+
todayOutline?: string;
|
|
100
|
+
selectedBg?: string;
|
|
101
|
+
eventIndicator?: string;
|
|
102
|
+
}
|
|
87
103
|
|
|
88
104
|
declare const MONTHS: string[];
|
|
105
|
+
declare const MONTHS_FULL: string[];
|
|
89
106
|
declare const DAYS: string[];
|
|
90
107
|
declare function normalizeDate(date: Date): Date;
|
|
91
108
|
declare function isSameDay(date1: Date, date2: Date): boolean;
|
|
@@ -93,9 +110,9 @@ declare function isToday(date: Date): boolean;
|
|
|
93
110
|
declare function generateYears(minYear?: number, maxYear?: number): number[];
|
|
94
111
|
declare function getEventsForDate(events: CalendarEvent[], date: Date): CalendarEvent[];
|
|
95
112
|
declare function hasEvents(events: CalendarEvent[], date: Date): boolean;
|
|
96
|
-
declare function generateCalendarDates(year: number, month: number, events?: CalendarEvent[], weekStartsOn?: 0 | 1):
|
|
113
|
+
declare function generateCalendarDates(year: number, month: number, events?: CalendarEvent[], weekStartsOn?: 0 | 1): CalendarDate[][];
|
|
97
114
|
declare function getPopupPositionClass(selectedDayIndex: number | null): string;
|
|
98
|
-
declare function getCellClasses(calendarDate: CalendarDate
|
|
115
|
+
declare function getCellClasses(calendarDate: CalendarDate): string[];
|
|
99
116
|
declare function formatDateForDisplay(date: Date): string;
|
|
100
117
|
declare function getMonthYearText(year: number, month: number): string;
|
|
101
118
|
declare function formatTimeRange(event: CalendarEvent): string;
|
|
@@ -145,6 +162,14 @@ declare class CalendarEngine {
|
|
|
145
162
|
* Jump to specific month and year
|
|
146
163
|
*/
|
|
147
164
|
private jump;
|
|
165
|
+
/**
|
|
166
|
+
* Navigate to current month (today)
|
|
167
|
+
*/
|
|
168
|
+
private goToToday;
|
|
169
|
+
/**
|
|
170
|
+
* Check if currently viewing today's month
|
|
171
|
+
*/
|
|
172
|
+
private isCurrentMonth;
|
|
148
173
|
/**
|
|
149
174
|
* Select a specific date
|
|
150
175
|
*/
|
|
@@ -195,4 +220,4 @@ declare class CalendarEngine {
|
|
|
195
220
|
destroy(): void;
|
|
196
221
|
}
|
|
197
222
|
|
|
198
|
-
export { type CalendarActions, type CalendarConfig, type CalendarDate, CalendarEngine, type CalendarEvent, type CalendarEventHandler, type CalendarProps, type CalendarState, type CalendarViewModel, type CategoryColorMap, DAYS, DEFAULT_CATEGORY_COLORS, MONTHS, type PopupPosition, formatAttendees, formatDateForDisplay, formatTimeRange, generateCalendarDates, generateYears, getCategoryColor, getCellClasses, getDefaultEventColor, getEventsForDate, getMonthYearText, getPopupPositionClass, hasEvents, isSameDay, isToday, isValidHexColor, mergeCategoryColors, normalizeDate, sortEventsByTime };
|
|
223
|
+
export { type CalendarActions, type CalendarConfig, type CalendarDate, CalendarEngine, type CalendarEvent, type CalendarEventHandler, type CalendarProps, type CalendarState, type CalendarTheme, type CalendarViewModel, type CategoryColorMap, DAYS, DEFAULT_CATEGORY_COLORS, MONTHS, MONTHS_FULL, type PopupPosition, formatAttendees, formatDateForDisplay, formatTimeRange, generateCalendarDates, generateYears, getCategoryColor, getCellClasses, getDefaultEventColor, getEventsForDate, getMonthYearText, getPopupPositionClass, hasEvents, isSameDay, isToday, isValidHexColor, mergeCategoryColors, normalizeDate, sortEventsByTime };
|
package/dist/core/index.js
CHANGED
|
@@ -24,6 +24,7 @@ __export(index_exports, {
|
|
|
24
24
|
DAYS: () => DAYS,
|
|
25
25
|
DEFAULT_CATEGORY_COLORS: () => DEFAULT_CATEGORY_COLORS,
|
|
26
26
|
MONTHS: () => MONTHS,
|
|
27
|
+
MONTHS_FULL: () => MONTHS_FULL,
|
|
27
28
|
formatAttendees: () => formatAttendees,
|
|
28
29
|
formatDateForDisplay: () => formatDateForDisplay,
|
|
29
30
|
formatTimeRange: () => formatTimeRange,
|
|
@@ -60,6 +61,20 @@ var MONTHS = [
|
|
|
60
61
|
"Nov",
|
|
61
62
|
"Dec"
|
|
62
63
|
];
|
|
64
|
+
var MONTHS_FULL = [
|
|
65
|
+
"January",
|
|
66
|
+
"February",
|
|
67
|
+
"March",
|
|
68
|
+
"April",
|
|
69
|
+
"May",
|
|
70
|
+
"June",
|
|
71
|
+
"July",
|
|
72
|
+
"August",
|
|
73
|
+
"September",
|
|
74
|
+
"October",
|
|
75
|
+
"November",
|
|
76
|
+
"December"
|
|
77
|
+
];
|
|
63
78
|
var DAYS = [
|
|
64
79
|
"Sunday",
|
|
65
80
|
"Monday",
|
|
@@ -98,19 +113,39 @@ function generateCalendarDates(year, month, events = [], weekStartsOn = 0) {
|
|
|
98
113
|
const firstDay = new Date(year, month, 1);
|
|
99
114
|
const lastDay = new Date(year, month + 1, 0);
|
|
100
115
|
const daysInMonth = lastDay.getDate();
|
|
116
|
+
const prevMonthLastDay = new Date(year, month, 0).getDate();
|
|
101
117
|
let firstDayOfWeek = firstDay.getDay();
|
|
102
118
|
if (weekStartsOn === 1) {
|
|
103
119
|
firstDayOfWeek = firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1;
|
|
104
120
|
}
|
|
105
121
|
const dates = [];
|
|
106
122
|
let day = 1;
|
|
123
|
+
let nextMonthDay = 1;
|
|
107
124
|
for (let week = 0; week < 6; week++) {
|
|
108
125
|
const weekDates = [];
|
|
109
126
|
for (let dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++) {
|
|
110
127
|
if (week === 0 && dayOfWeek < firstDayOfWeek) {
|
|
111
|
-
|
|
128
|
+
const prevDay = prevMonthLastDay - firstDayOfWeek + dayOfWeek + 1;
|
|
129
|
+
const prevDate = new Date(year, month - 1, prevDay);
|
|
130
|
+
const dateEvents = getEventsForDate(events, prevDate);
|
|
131
|
+
weekDates.push({
|
|
132
|
+
date: prevDate,
|
|
133
|
+
isCurrentMonth: false,
|
|
134
|
+
isToday: isToday(prevDate),
|
|
135
|
+
hasEvents: dateEvents.length > 0,
|
|
136
|
+
events: dateEvents
|
|
137
|
+
});
|
|
112
138
|
} else if (day > daysInMonth) {
|
|
113
|
-
|
|
139
|
+
const nextDate = new Date(year, month + 1, nextMonthDay);
|
|
140
|
+
const dateEvents = getEventsForDate(events, nextDate);
|
|
141
|
+
weekDates.push({
|
|
142
|
+
date: nextDate,
|
|
143
|
+
isCurrentMonth: false,
|
|
144
|
+
isToday: isToday(nextDate),
|
|
145
|
+
hasEvents: dateEvents.length > 0,
|
|
146
|
+
events: dateEvents
|
|
147
|
+
});
|
|
148
|
+
nextMonthDay++;
|
|
114
149
|
} else {
|
|
115
150
|
const currentDate = new Date(year, month, day);
|
|
116
151
|
const dateEvents = getEventsForDate(events, currentDate);
|
|
@@ -125,9 +160,6 @@ function generateCalendarDates(year, month, events = [], weekStartsOn = 0) {
|
|
|
125
160
|
}
|
|
126
161
|
}
|
|
127
162
|
dates.push(weekDates);
|
|
128
|
-
if (day > daysInMonth && weekDates.every((date) => date === null)) {
|
|
129
|
-
break;
|
|
130
|
-
}
|
|
131
163
|
}
|
|
132
164
|
return dates;
|
|
133
165
|
}
|
|
@@ -142,8 +174,10 @@ function getPopupPositionClass(selectedDayIndex) {
|
|
|
142
174
|
}
|
|
143
175
|
}
|
|
144
176
|
function getCellClasses(calendarDate) {
|
|
145
|
-
if (!calendarDate) return [];
|
|
146
177
|
const classes = [];
|
|
178
|
+
if (!calendarDate.isCurrentMonth) {
|
|
179
|
+
classes.push("other-month");
|
|
180
|
+
}
|
|
147
181
|
if (calendarDate.isToday) {
|
|
148
182
|
classes.push("schedule--current--exam");
|
|
149
183
|
}
|
|
@@ -156,7 +190,7 @@ function formatDateForDisplay(date) {
|
|
|
156
190
|
return `${DAYS[date.getDay()]} ${date.getDate()}`;
|
|
157
191
|
}
|
|
158
192
|
function getMonthYearText(year, month) {
|
|
159
|
-
return `${
|
|
193
|
+
return `${MONTHS_FULL[month]} ${year}`;
|
|
160
194
|
}
|
|
161
195
|
function formatTimeRange(event) {
|
|
162
196
|
if (event.allDay || !event.startTime && !event.endTime) {
|
|
@@ -283,6 +317,8 @@ var CalendarEngine = class {
|
|
|
283
317
|
next: this.next.bind(this),
|
|
284
318
|
previous: this.previous.bind(this),
|
|
285
319
|
jump: this.jump.bind(this),
|
|
320
|
+
goToToday: this.goToToday.bind(this),
|
|
321
|
+
isCurrentMonth: this.isCurrentMonth.bind(this),
|
|
286
322
|
selectDate: this.selectDate.bind(this),
|
|
287
323
|
updateTasks: this.updateTasks.bind(this)
|
|
288
324
|
};
|
|
@@ -328,6 +364,25 @@ var CalendarEngine = class {
|
|
|
328
364
|
this.updateTasks();
|
|
329
365
|
this.notify();
|
|
330
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Navigate to current month (today)
|
|
369
|
+
*/
|
|
370
|
+
goToToday() {
|
|
371
|
+
const today = /* @__PURE__ */ new Date();
|
|
372
|
+
this.state.currentYear = today.getFullYear();
|
|
373
|
+
this.state.currentMonth = today.getMonth();
|
|
374
|
+
this.state.selectedDate = null;
|
|
375
|
+
this.state.selectedDayIndex = null;
|
|
376
|
+
this.updateTasks();
|
|
377
|
+
this.notify();
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Check if currently viewing today's month
|
|
381
|
+
*/
|
|
382
|
+
isCurrentMonth() {
|
|
383
|
+
const today = /* @__PURE__ */ new Date();
|
|
384
|
+
return this.state.currentYear === today.getFullYear() && this.state.currentMonth === today.getMonth();
|
|
385
|
+
}
|
|
331
386
|
/**
|
|
332
387
|
* Select a specific date
|
|
333
388
|
*/
|
|
@@ -428,6 +483,7 @@ var CalendarEngine = class {
|
|
|
428
483
|
DAYS,
|
|
429
484
|
DEFAULT_CATEGORY_COLORS,
|
|
430
485
|
MONTHS,
|
|
486
|
+
MONTHS_FULL,
|
|
431
487
|
formatAttendees,
|
|
432
488
|
formatDateForDisplay,
|
|
433
489
|
formatTimeRange,
|