simple-calendar-js 2.0.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,665 +1,424 @@
1
- # Simple Calendar JS
1
+ # SimpleCalendarJs
2
2
 
3
- A pure JavaScript calendar component with no dependencies. Features responsive design, multiple view modes, and customizable styling.
3
+ A lightweight, zero-dependency JavaScript calendar component with internationalization support and framework wrappers for React, Vue, and Angular.
4
+
5
+ ![Version](https://img.shields.io/badge/version-3.0.0-blue.svg)
6
+ ![License](https://img.shields.io/badge/license-See%20LICENSE-green.svg)
4
7
 
5
8
  ## Features
6
9
 
7
- - **Pure JavaScript** - No jQuery or other dependencies
8
- - **Three View Modes** - Month, Week, and Day views
9
- - **Responsive Design** - Works on desktop, tablet, and mobile
10
- - **Time-based Views** - Week and day views with customizable time slots
11
- - **Fullday Mode** - Toggle between time-based and fullday event display
12
- - **Multi-day Events** - Seamless event display across multiple days
13
- - **Smart Event Fetching** - Callback-based event loading with intelligent caching
14
- - **Event Callbacks** - Day click, event click, and state change handlers
15
- - **Grid Border Control** - Customizable grid borders (both, vertical, horizontal, none)
16
- - **Internationalization** - Full localization support for weekdays, months, and UI labels
17
- - **Month/Year Dropdowns** - Quick navigation with clickable month and year selectors
18
- - **Color Customization** - Comprehensive theming system with light/dark mode support
19
- - **Theme Integration** - Built-in dark theme with automatic color adaptation
20
- - **Enhanced Navigation** - Transparent navigation buttons with theme-aware hover effects
21
- - **Always-Visible Time Lines** - Hour and half-hour lines remain visible regardless of grid settings
22
- - **CSS Prefix** - All classes prefixed with 'sc-' to avoid conflicts
23
- - **Template Strings** - Clean HTML generation using template literals
24
- - **Event Support** - Add, remove, and display events
25
- - **Keyboard Navigation** - Arrow keys, T (today), M/W/D (views)
10
+ - **Zero Dependencies** - Pure vanilla JavaScript, no external libraries
11
+ - **Three View Modes** - Month, week, and day views with smooth transitions
12
+ - **Full Internationalization** - Built on Intl.DateTimeFormat API for native locale support
13
+ - **Framework Wrappers** - Official React, Vue 3, and Angular components included
14
+ - **Module System Support** - Works as UMD (CommonJS, AMD, ES modules, or browser global)
15
+ - **Dark Mode Ready** - Automatic dark theme detection and support
16
+ - **Async Event Loading** - Fetch events dynamically with `async/await` support
17
+ - **Responsive Design** - Adapts to any screen size
18
+ - **Customizable Styling** - CSS custom properties for easy theming
19
+ - **Accessible** - Semantic HTML with proper ARIA attributes
20
+ - **Small Bundle Size** - ~22KB minified JS, ~14KB minified CSS
21
+
22
+ ## Installation
23
+
24
+ ### NPM
25
+
26
+ ```bash
27
+ npm install simple-calendar-js
28
+ ```
29
+
30
+ ### CDN
31
+
32
+ ```html
33
+ <link rel="stylesheet" href="https://unpkg.com/simple-calendar-js/dist/simple-calendar-js.min.css">
34
+ <script src="https://unpkg.com/simple-calendar-js/dist/simple-calendar-js.min.js"></script>
35
+ ```
36
+
37
+ ### Manual Download
38
+
39
+ Download the files from the [dist/](dist/) folder and include them in your project.
26
40
 
27
41
  ## Quick Start
28
42
 
43
+ ### Vanilla JavaScript
44
+
29
45
  ```html
30
46
  <!DOCTYPE html>
31
47
  <html>
32
48
  <head>
33
- <link rel="stylesheet" href="css/simple-calendar-js.css">
49
+ <link rel="stylesheet" href="simple-calendar-js.css">
34
50
  </head>
35
51
  <body>
36
- <div id="calendar"></div>
37
-
38
- <script src="js/simple-calendar-js.js"></script>
39
- <script>
40
- const calendar = new SimpleCalendarJs('#calendar', {
41
- view: 'month',
42
- date: new Date(),
43
- fulldayMode: false,
44
- events: []
45
- });
46
- </script>
52
+ <div id="calendar"></div>
53
+
54
+ <script src="simple-calendar-js.js"></script>
55
+ <script>
56
+ const calendar = new SimpleCalendarJs('#calendar', {
57
+ defaultView: 'month',
58
+ locale: 'en-US',
59
+ fetchEvents: async (startDate, endDate) => {
60
+ // Fetch events from your API
61
+ const response = await fetch(`/api/events?start=${startDate}&end=${endDate}`);
62
+ return await response.json();
63
+ },
64
+ onEventClick: (event, mouseEvent) => {
65
+ console.log('Event clicked:', event);
66
+ }
67
+ });
68
+ </script>
47
69
  </body>
48
70
  </html>
49
71
  ```
50
72
 
51
- ## Configuration Options
73
+ ### React
74
+
75
+ ```jsx
76
+ import SimpleCalendarJsReact from 'simple-calendar-js/frameworks/simple-calendar-js-react.jsx';
77
+ import 'simple-calendar-js/dist/simple-calendar-js.min.css';
78
+
79
+ function MyCalendar() {
80
+ const fetchEvents = async (startDate, endDate) => {
81
+ const res = await fetch(`/api/events?start=${startDate}&end=${endDate}`);
82
+ return await res.json();
83
+ };
84
+
85
+ return (
86
+ <SimpleCalendarJsReact
87
+ defaultView="month"
88
+ locale="en-US"
89
+ fetchEvents={fetchEvents}
90
+ onEventClick={(event) => console.log(event)}
91
+ style={{ height: '600px' }}
92
+ />
93
+ );
94
+ }
95
+ ```
52
96
 
53
- ```javascript
54
- const calendar = new SimpleCalendarJs('#calendar', {
55
- // View Configuration
56
- view: 'month', // 'month', 'week', or 'day'
57
- date: new Date(), // Initial date to display
58
- fulldayMode: false, // Show fullday events only
59
-
60
- // Time Configuration (for week/day views)
61
- startHour: 6, // Start time for week/day view (0-23)
62
- endHour: 22, // End time for week/day view (0-23)
63
- timeSlotMinutes: 30, // Time slot intervals (currently supports 30)
64
-
65
- // Visual Configuration
66
- gridBorders: 'both', // 'both', 'vertical', 'horizontal', 'none'
67
- eventBorders: false, // true/false - whether events should have borders
68
- eventBorderColor: '#6c757d', // Color for event borders (when eventBorders: true)
69
- defaultEventColor: '#4c6f94', // Default color for events without custom colors
70
-
71
- // UI Element Visibility
72
- showMonthButton: true, // true/false - show month view button
73
- showWeekButton: true, // true/false - show week view button
74
- showDayButton: true, // true/false - show day view button
75
- showNavigation: true, // true/false - show navigation buttons (prev/next)
76
-
77
- // Localization Options
78
- weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
79
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
80
- showWeekdayChars: null, // null = full weekday names, number = show first N characters
81
- labels: { // UI labels for buttons and text
82
- month: 'Month',
83
- week: 'Week',
84
- day: 'Day',
85
- events: 'events', // Badge text (plural)
86
- event: 'event', // Badge text (singular)
87
- before: 'Before', // Time slot label for early times
88
- after: 'After' // Time slot label for late times
89
- },
90
-
91
- // Color Customization
92
- colors: {
93
- // Light theme colors (defaults)
94
- background: '#ffffff',
95
- backgroundSecondary: '#f8f9fa',
96
- backgroundTertiary: '#ecf0f1',
97
- text: '#212529',
98
- textSecondary: '#6c757d',
99
- textMuted: '#adb5bd',
100
- border: '#e9ecef',
101
- borderLight: '#dee2e6',
102
- accent: '#4c6f94',
103
- accentHover: '#0056b3',
104
- todayBg: '#e3f2fd',
105
- todayText: '#dc3545',
106
- hoverBg: '#f8f9fa',
107
- // Dark theme colors (auto-applied when data-theme="dark")
108
- dark: {
109
- background: '#2d2d2d',
110
- backgroundSecondary: '#3a3a3a',
111
- backgroundTertiary: '#4a4a4a',
112
- text: '#ffffff',
113
- textSecondary: '#cccccc',
114
- textMuted: '#888888',
115
- border: '#444444',
116
- borderLight: '#555555',
117
- accent: '#4a90e2',
118
- accentHover: '#357abd',
119
- todayBg: '#1a2f4a',
120
- todayText: '#ff6b6b',
121
- hoverBg: '#2d2d2d'
122
- }
97
+ ### Vue 3
98
+
99
+ ```vue
100
+ <template>
101
+ <SimpleCalendarJsVue
102
+ :defaultView="'month'"
103
+ :locale="'en-US'"
104
+ :fetchEvents="fetchEvents"
105
+ @eventClick="handleEventClick"
106
+ :style="{ height: '600px' }"
107
+ />
108
+ </template>
109
+
110
+ <script>
111
+ import SimpleCalendarJsVue from 'simple-calendar-js/frameworks/simple-calendar-js-vue.js';
112
+ import 'simple-calendar-js/dist/simple-calendar-js.min.css';
113
+
114
+ export default {
115
+ components: { SimpleCalendarJsVue },
116
+ methods: {
117
+ async fetchEvents(startDate, endDate) {
118
+ const res = await fetch(`/api/events?start=${startDate}&end=${endDate}`);
119
+ return await res.json();
123
120
  },
124
-
125
- // Data Configuration
126
- events: [], // Array of event objects OR callback function
127
-
128
- // Event Handlers
129
- dayClick: null, // Function called when day is clicked
130
- eventClick: null, // Function called when event is clicked
131
- changeState: null // Function called when calendar state changes
132
- });
121
+ handleEventClick(event) {
122
+ console.log('Event clicked:', event);
123
+ }
124
+ }
125
+ }
126
+ </script>
133
127
  ```
134
128
 
135
- ## Localization
136
-
137
- SimpleCalendarJs supports full internationalization with customizable text and date formats:
129
+ ### Angular
130
+
131
+ ```typescript
132
+ import { Component } from '@angular/core';
133
+
134
+ @Component({
135
+ selector: 'app-calendar',
136
+ template: `
137
+ <simple-calendar-js
138
+ [defaultView]="'month'"
139
+ [locale]="'en-US'"
140
+ [fetchEvents]="fetchEvents"
141
+ (eventClick)="handleEventClick($event)"
142
+ [style.height.px]="600"
143
+ ></simple-calendar-js>
144
+ `
145
+ })
146
+ export class CalendarComponent {
147
+ async fetchEvents(startDate: Date, endDate: Date) {
148
+ const res = await fetch(`/api/events?start=${startDate}&end=${endDate}`);
149
+ return await res.json();
150
+ }
151
+
152
+ handleEventClick(event: any) {
153
+ console.log('Event clicked:', event);
154
+ }
155
+ }
156
+ ```
138
157
 
139
- ```javascript
140
- const calendar = new SimpleCalendarJs('#calendar', {
141
- // Portuguese example
142
- weekdays: ['Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado'],
143
- months: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
144
- showWeekdayChars: 3, // Show only first 3 characters: "Dom", "Seg", etc.
145
- labels: {
146
- month: 'Mês',
147
- week: 'Semana',
148
- day: 'Dia',
149
- events: 'eventos',
150
- event: 'evento',
151
- before: 'Antes das',
152
- after: 'Depois das'
153
- }
154
- });
158
+ ## Configuration Options
155
159
 
156
- // French example
157
- const frenchCalendar = new SimpleCalendarJs('#calendar', {
158
- weekdays: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
159
- months: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
160
- showWeekdayChars: 2, // Show first 2 characters: "Di", "Lu", etc.
161
- labels: {
162
- month: 'Mois',
163
- week: 'Semaine',
164
- day: 'Jour',
165
- events: 'événements',
166
- event: 'événement',
167
- before: 'Avant',
168
- after: 'Après'
169
- }
170
- });
160
+ | Option | Type | Default | Description |
161
+ |--------|------|---------|-------------|
162
+ | `defaultView` | string | `'month'` | Initial view: `'month'`, `'week'`, or `'day'` |
163
+ | `defaultDate` | Date | `new Date()` | Initial date to display |
164
+ | `weekStartsOn` | number | `0` | First day of week: `0` (Sunday) or `1` (Monday) |
165
+ | `locale` | string | `'default'` | Locale code for Intl API (e.g., `'en-US'`, `'fr-FR'`, `'ja-JP'`) |
166
+ | `use24Hour` | boolean | `false` | Use 24-hour time format |
167
+ | `showTimeInItems` | boolean | `true` | Show time in event items |
168
+ | `showGridLines` | boolean | `true` | Show calendar grid lines |
169
+ | `showToolbar` | boolean | `true` | Show the toolbar |
170
+ | `showTodayButton` | boolean | `true` | Show "Today" button |
171
+ | `showNavigation` | boolean | `true` | Show prev/next navigation arrows |
172
+ | `showTitle` | boolean | `true` | Show month/year title |
173
+ | `showYearPicker` | boolean | `true` | Enable year picker dropdown (month view) |
174
+ | `showViewSwitcher` | boolean | `true` | Show view switcher buttons |
175
+ | `enabledViews` | string[] | `['month', 'week', 'day']` | Available view modes |
176
+ | `primaryColor` | string | `'#4f46e5'` | Primary theme color (hex) |
177
+ | `fetchEvents` | function | `null` | Async function to fetch events: `async (start, end) => Event[]` |
178
+ | `onEventClick` | function | `null` | Callback when event is clicked: `(event, mouseEvent) => void` |
179
+ | `onSlotClick` | function | `null` | Callback when time slot is clicked: `(date, mouseEvent) => void` |
180
+ | `onViewChange` | function | `null` | Callback when view changes: `(view) => void` |
181
+ | `onNavigate` | function | `null` | Callback when date range changes: `(startDate, endDate) => void` |
182
+
183
+ ## Event Object Format
184
+
185
+ Events returned by `fetchEvents` should follow this structure:
186
+
187
+ ```typescript
188
+ interface CalendarEvent {
189
+ id: string | number; // Unique identifier
190
+ title: string; // Event title
191
+ start: Date; // Start date/time
192
+ end?: Date; // End date/time (optional, defaults to start)
193
+ allDay?: boolean; // All-day event flag (optional)
194
+ color?: string; // Custom color (hex, optional)
195
+ [key: string]: any; // Any additional custom properties
196
+ }
171
197
  ```
172
198
 
173
- ### Weekday Display Options
174
- - **`showWeekdayChars: null`** - Show full weekday names (default)
175
- - **`showWeekdayChars: 3`** - Show first 3 characters ("Sun", "Mon", etc.)
176
- - **`showWeekdayChars: 1`** - Show single character ("S", "M", etc.)
199
+ ### Example Events
177
200
 
178
- ## Month/Year Navigation
201
+ ```javascript
202
+ const events = [
203
+ {
204
+ id: 1,
205
+ title: 'Team Meeting',
206
+ start: new Date('2024-03-15T10:00:00'),
207
+ end: new Date('2024-03-15T11:00:00'),
208
+ color: '#3b82f6'
209
+ },
210
+ {
211
+ id: 2,
212
+ title: 'Conference',
213
+ start: new Date('2024-03-20T00:00:00'),
214
+ end: new Date('2024-03-22T23:59:59'),
215
+ allDay: true,
216
+ color: '#10b981'
217
+ }
218
+ ];
219
+ ```
179
220
 
180
- In month view, clicking on the month or year title opens dropdown menus for quick navigation:
221
+ ## API Methods
181
222
 
182
- ### Features
183
- - **Month Dropdown** - Click month title to select any month
184
- - **Year Dropdown** - Click year title to select from a range of years
185
- - **Keyboard Support** - Navigate with arrow keys and Enter
186
- - **Auto-scroll** - Current month/year automatically scrolls into view
187
- - **Compact Design** - Minimal dropdown styling that adapts to themes
223
+ ```javascript
224
+ // Switch view
225
+ calendar.setView('week');
188
226
 
189
- ### Styling
190
- The dropdowns automatically inherit the calendar's theme and can be customized via CSS:
227
+ // Navigate forward/backward
228
+ calendar.navigate(1); // Next period
229
+ calendar.navigate(-1); // Previous period
191
230
 
192
- ```css
193
- .sc-month-dropdown, .sc-year-dropdown {
194
- /* Customize dropdown appearance */
195
- max-height: 200px;
196
- background: var(--sc-bg-secondary);
197
- border: 1px solid var(--sc-border-color);
198
- }
231
+ // Jump to specific date
232
+ calendar.goToDate(new Date('2024-12-25'));
199
233
 
200
- .sc-month-option:hover, .sc-year-option:hover {
201
- background: var(--sc-hover-bg);
202
- color: var(--sc-accent-color);
203
- }
234
+ // Jump to today
235
+ calendar.goToToday();
236
+
237
+ // Cleanup (important for SPAs)
238
+ calendar.destroy();
204
239
  ```
205
240
 
206
- ## Color Customization
241
+ ## Internationalization
207
242
 
208
- SimpleCalendarJs provides a comprehensive color system that supports partial customization and automatic theme switching:
243
+ SimpleCalendarJs uses the native Intl.DateTimeFormat API for full locale support. Simply pass a valid locale code:
209
244
 
210
- ### Basic Color Override
211
245
  ```javascript
246
+ // French
212
247
  const calendar = new SimpleCalendarJs('#calendar', {
213
- colors: {
214
- background: '#f0f8ff', // Only override background
215
- accent: '#ff6b6b' // Only override accent color
216
- // All other colors use defaults
217
- }
248
+ locale: 'fr-FR',
249
+ weekStartsOn: 1 // Monday
218
250
  });
219
- ```
220
251
 
221
- ### Full Theme Customization
222
- ```javascript
252
+ // Japanese
223
253
  const calendar = new SimpleCalendarJs('#calendar', {
224
- colors: {
225
- // Light theme colors
226
- background: '#ffffff',
227
- backgroundSecondary: '#f8f9fa',
228
- backgroundTertiary: '#ecf0f1',
229
- text: '#212529',
230
- textSecondary: '#6c757d',
231
- textMuted: '#adb5bd',
232
- border: '#e9ecef',
233
- borderLight: '#dee2e6',
234
- accent: '#4c6f94',
235
- accentHover: '#0056b3',
236
- todayBg: '#e3f2fd',
237
- todayText: '#dc3545',
238
- hoverBg: '#f8f9fa',
239
-
240
- // Dark theme colors (optional)
241
- dark: {
242
- background: '#1a1a1a',
243
- backgroundSecondary: '#2d2d2d',
244
- backgroundTertiary: '#3a3a3a',
245
- text: '#ffffff',
246
- textSecondary: '#cccccc',
247
- textMuted: '#888888',
248
- border: '#444444',
249
- borderLight: '#555555',
250
- accent: '#4a90e2',
251
- accentHover: '#357abd',
252
- todayBg: '#1a2f4a',
253
- todayText: '#ff6b6b',
254
- hoverBg: '#2d2d2d'
255
- }
256
- }
254
+ locale: 'ja-JP'
255
+ });
256
+
257
+ // Arabic (RTL support automatic)
258
+ const calendar = new SimpleCalendarJs('#calendar', {
259
+ locale: 'ar-SA'
257
260
  });
258
261
  ```
259
262
 
260
- ### Transparent Values
261
- Any color property can be set to `'transparent'` for seamless integration:
263
+ Supported locales include: `en-US`, `en-GB`, `fr-FR`, `de-DE`, `es-ES`, `it-IT`, `pt-PT`, `pt-BR`, `ja-JP`, `zh-CN`, `ko-KR`, `ar-SA`, `ru-RU`, `tr-TR`, and [many more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat#locales).
262
264
 
263
- ```javascript
264
- colors: {
265
- background: 'transparent', // Calendar blends with page background
266
- border: 'transparent', // Remove all borders
267
- hoverBg: 'transparent' // Disable hover backgrounds
268
- }
269
- ```
265
+ ## Dark Mode
270
266
 
271
- ### Color Properties Reference
272
-
273
- | Property | Description | Default (Light) | Default (Dark) |
274
- |----------|-------------|-----------------|----------------|
275
- | `background` | Main calendar background | `#ffffff` | `#2d2d2d` |
276
- | `backgroundSecondary` | Secondary backgrounds | `#f8f9fa` | `#3a3a3a` |
277
- | `backgroundTertiary` | Controls and headers | `#ecf0f1` | `#4a4a4a` |
278
- | `text` | Primary text color | `#212529` | `#ffffff` |
279
- | `textSecondary` | Secondary text | `#6c757d` | `#cccccc` |
280
- | `textMuted` | Muted/disabled text | `#adb5bd` | `#888888` |
281
- | `border` | Grid and element borders | `#e9ecef` | `#444444` |
282
- | `borderLight` | Light accent borders | `#dee2e6` | `#555555` |
283
- | `accent` | Active states and highlights | `#4c6f94` | `#4a90e2` |
284
- | `accentHover` | Hover states | `#0056b3` | `#357abd` |
285
- | `todayBg` | Today's date background | `#e3f2fd` | `#1a2f4a` |
286
- | `todayText` | Today's date text | `#dc3545` | `#ff6b6b` |
287
- | `hoverBg` | Hover backgrounds | `#f8f9fa` | `#2d2d2d` |
288
-
289
- ### Theme Integration
290
- The calendar automatically detects `data-theme="dark"` on parent elements and applies dark colors accordingly. Perfect for integration with existing website theme systems.
291
-
292
- ## Event Format
267
+ Dark mode is automatically detected from the user's system preferences. You can also manually toggle it:
293
268
 
294
269
  ```javascript
295
- // Single-day event with basic properties
296
- const singleEvent = {
297
- id: 1,
298
- title: 'Meeting',
299
- date: new Date('2023-12-25'),
300
- time: '10:00 AM' // Optional: for time-based views
301
- };
270
+ // Set data-theme attribute on <html> or <body>
271
+ document.documentElement.setAttribute('data-theme', 'dark');
302
272
 
303
- // Multi-day event with basic properties
304
- const multiDayEvent = {
305
- id: 2,
306
- title: 'Conference',
307
- startDate: new Date('2023-12-25'),
308
- endDate: new Date('2023-12-27'),
309
- time: '9:00 AM' // Optional: shown on start day
310
- };
311
-
312
- // Event with custom colors and styling
313
- const coloredEvent = {
314
- id: 3,
315
- title: 'Important Meeting',
316
- date: new Date('2023-12-25'),
317
- time: '2:00 PM',
318
- color: '#e74c3c', // Custom color (hex format)
319
- colorIsGradient: true // Apply gradient effect to color
320
- };
321
-
322
- // Event with solid custom color
323
- const solidColorEvent = {
324
- id: 4,
325
- title: 'Team Lunch',
326
- date: new Date('2023-12-26'),
327
- color: '#2ecc71', // Custom green color
328
- colorIsGradient: false // Use solid color (default behavior)
329
- };
330
-
331
- // Event with gradient using default color
332
- const defaultGradientEvent = {
333
- id: 5,
334
- title: 'Training Session',
335
- date: new Date('2023-12-27'),
336
- colorIsGradient: true // Use default color with gradient
337
- };
273
+ // Or add a CSS class
274
+ document.documentElement.classList.add('dark');
338
275
  ```
339
276
 
340
- ### Event Color Properties
341
-
342
- | Property | Type | Description |
343
- |----------|------|-------------|
344
- | `color` | string | Hex color code (e.g., '#e74c3c'). If not provided, uses `defaultEventColor` |
345
- | `colorIsGradient` | boolean | When `true`, creates a subtle gradient effect. When `false` or omitted, uses solid color |
346
-
347
- ### Color Logic
348
- 1. **`event.color` + `colorIsGradient: true`** → Custom color with gradient effect
349
- 2. **`event.color` + `colorIsGradient: false`** → Custom solid color
350
- 3. **`colorIsGradient: true` (no color)** → Default color with gradient effect
351
- 4. **No color properties** → Default solid color
277
+ For framework wrappers, use the `darkMode` prop:
352
278
 
353
- Text color (black or white) is automatically calculated for optimal contrast using WCAG guidelines.
279
+ ```jsx
280
+ // React
281
+ <SimpleCalendarJsReact darkMode={isDark} />
354
282
 
355
- ## Event Callbacks
283
+ // Vue
284
+ <SimpleCalendarJsVue :darkMode="isDark" />
356
285
 
357
- ```javascript
358
- const calendar = new SimpleCalendarJs('#calendar', {
359
- // Dynamic event loading
360
- events: function(dateRange) {
361
- // Called with {startDate, endDate} for visible range
362
- // Return array of events for this range
363
- return fetchEventsFromAPI(dateRange.startDate, dateRange.endDate);
364
- },
365
-
366
- // Day click handler
367
- dayClick: function(clickInfo, originalEvent) {
368
- // clickInfo: {date, time} - time only for time-based views
369
- console.log('Clicked on:', clickInfo.date, clickInfo.time);
370
- },
371
-
372
- // Event click handler
373
- eventClick: function(event, clickInfo, originalEvent) {
374
- // event: the clicked event object
375
- // clickInfo: {date, time} - date/time where event was clicked
376
- console.log('Clicked event:', event.title, 'at', clickInfo.time);
377
- },
378
-
379
- // State change handler
380
- changeState: function(state) {
381
- // state: {view, date, fulldayMode, startHour, endHour, timeSlotMinutes}
382
- console.log('Calendar state changed:', state);
383
- }
384
- });
286
+ // Angular
287
+ <simple-calendar-js [darkMode]="isDark"></simple-calendar-js>
385
288
  ```
386
289
 
387
- ## API Methods
290
+ ## Styling & Theming
388
291
 
389
- ```javascript
390
- // Navigation
391
- calendar.navigate('next'); // Navigate to next period
392
- calendar.navigate('prev'); // Navigate to previous period
393
- calendar.goToDate(new Date()); // Go to specific date
394
- calendar.goToToday(); // Go to today
395
-
396
- // View switching
397
- calendar.setView('month'); // 'month', 'week', 'day'
398
- calendar.setFulldayMode(true); // Toggle fullday mode
399
-
400
- // Event management
401
- calendar.addEvent(event); // Add single event
402
- calendar.removeEvent(eventId); // Remove event by ID
403
- calendar.setEvents(eventsArray); // Replace all events
404
- calendar.setEvents(callbackFunction); // Set dynamic event loading
405
-
406
- // Visual customization
407
- calendar.setGridBorders('none'); // 'both', 'vertical', 'horizontal', 'none'
408
- calendar.setEventBorders(true); // Enable/disable event borders
409
- calendar.setEventBorderColor('#ff0000'); // Set event border color
410
- calendar.setDefaultEventColor('#3498db'); // Set default event color
411
-
412
- // UI element visibility
413
- calendar.setShowMonthButton(true); // Show/hide month view button
414
- calendar.setShowWeekButton(true); // Show/hide week view button
415
- calendar.setShowDayButton(true); // Show/hide day view button
416
- calendar.setShowNavigation(true); // Show/hide navigation buttons
417
- calendar.setViewButtonsVisibility( // Set multiple button visibility at once
418
- true, // month button
419
- true, // week button
420
- false // day button
421
- );
422
- ```
292
+ Customize the calendar appearance using CSS custom properties:
423
293
 
424
- ## CSS Classes
425
-
426
- All CSS classes are prefixed with `sc-` to prevent conflicts:
427
-
428
- ### Main Structure
429
- - `.sc-calendar` - Main container
430
- - `.sc-header` - Calendar header
431
- - `.sc-content` - Content area
432
- - `.sc-view-container` - View-specific container
433
-
434
- ### Views
435
- - `.sc-month-view` - Month view container
436
- - `.sc-week-view` - Week view container
437
- - `.sc-day-view` - Day view container
438
- - `.sc-fullday` - Fullday mode modifier
439
-
440
- ### Grid & Days
441
- - `.sc-days-grid` - Grid container for days
442
- - `.sc-day` - Individual day cell
443
- - `.sc-day-number` - Day number text
444
- - `.sc-today` - Today's date styling
445
- - `.sc-other-month` - Days from other months
446
-
447
- ### Events
448
- - `.sc-event-month`, `.sc-event-week`, `.sc-event-day`, `.sc-event-time` - Event containers
449
- - `.sc-event-text` - Event text content
450
- - `.sc-event-single` - Single-day event
451
- - `.sc-event-start` - Multi-day event start
452
- - `.sc-event-middle` - Multi-day event middle
453
- - `.sc-event-end` - Multi-day event end
454
- - `.sc-event-placeholder` - Transparent placeholder for multi-day alignment
455
-
456
- ### Event Count (Month View - Non-Fullday)
457
- - `.sc-day-count-mode` - Day cell in count mode
458
- - `.sc-day-content` - Container for day number and event count
459
- - `.sc-event-count` - Event count badge with rounded corners
460
-
461
- ### Headers & Navigation
462
- - `.sc-nav` - Navigation buttons container
463
- - `.sc-title` - Month/date title
464
- - `.sc-title-month` - Clickable month title (in month view)
465
- - `.sc-title-year` - Clickable year title (in month view)
466
- - `.sc-view-switcher` - View mode buttons
467
- - `.sc-btn` - Button styling
468
-
469
- ### Dropdown Navigation
470
- - `.sc-month-dropdown` - Month selection dropdown
471
- - `.sc-year-dropdown` - Year selection dropdown
472
- - `.sc-month-option` - Individual month option
473
- - `.sc-year-option` - Individual year option
474
-
475
- ### Border Modifiers
476
- - `.sc-borders-both` - Show all grid borders
477
- - `.sc-borders-vertical` - Vertical grid borders only
478
- - `.sc-borders-horizontal` - Horizontal grid borders only
479
- - `.sc-borders-none` - No grid borders
480
- - `.sc-event-borders` - Enable event borders
481
- - `.sc-event-no-borders` - Disable event borders (default)
482
-
483
- ## CSS Custom Properties (Variables)
484
-
485
- The calendar uses CSS custom properties for comprehensive theming. These are automatically managed by the color customization system, but can also be overridden directly:
486
-
487
- ### Event Colors
488
294
  ```css
489
- .sc-calendar {
490
- --sc-event-color: #4c6f94; /* Default event background color */
491
- --sc-event-border-color: #6c757d; /* Event border color */
295
+ .uc-calendar {
296
+ /* Primary color */
297
+ --cal-primary: #4f46e5;
298
+ --cal-primary-dark: #4338ca;
299
+ --cal-primary-light: #eef2ff;
300
+
301
+ /* Background colors */
302
+ --cal-bg: #ffffff;
303
+ --cal-bg-secondary: #f9fafb;
304
+
305
+ /* Text colors */
306
+ --cal-text: #111827;
307
+ --cal-text-subtle: #6b7280;
308
+
309
+ /* Borders */
310
+ --cal-border: #e5e7eb;
311
+
312
+ /* Today indicator */
313
+ --cal-today-bg: #eef2ff;
314
+ --cal-today-text: var(--cal-primary);
315
+
316
+ /* Events */
317
+ --cal-event-bg: var(--cal-primary);
318
+ --cal-event-text: #ffffff;
319
+
320
+ /* Sizing */
321
+ --cal-font-size: 13px;
322
+ --cal-hour-height: 60px;
492
323
  }
493
324
  ```
494
325
 
495
- ### Theme Colors (Auto-managed)
496
- ```css
497
- .sc-calendar {
498
- /* Main backgrounds */
499
- --sc-bg-primary: #ffffff;
500
- --sc-bg-secondary: #f8f9fa;
501
- --sc-bg-tertiary: #ecf0f1;
502
-
503
- /* Text colors */
504
- --sc-text-primary: #212529;
505
- --sc-text-secondary: #6c757d;
506
- --sc-text-muted: #adb5bd;
507
-
508
- /* Borders */
509
- --sc-border-color: #e9ecef;
510
- --sc-border-light: #dee2e6;
511
-
512
- /* Interactive elements */
513
- --sc-accent-color: #4c6f94;
514
- --sc-accent-hover: #0056b3;
515
- --sc-today-bg: #e3f2fd;
516
- --sc-today-text: #dc3545;
517
- --sc-hover-bg: #f8f9fa;
518
- }
519
-
520
- /* Dark theme variables (auto-applied with data-theme="dark") */
521
- [data-theme="dark"] .sc-calendar {
522
- --sc-bg-primary: #2d2d2d;
523
- --sc-bg-secondary: #3a3a3a;
524
- --sc-bg-tertiary: #4a4a4a;
525
- --sc-text-primary: #ffffff;
526
- --sc-text-secondary: #cccccc;
527
- --sc-text-muted: #888888;
528
- --sc-border-color: #444444;
529
- --sc-border-light: #555555;
530
- --sc-accent-color: #4a90e2;
531
- --sc-accent-hover: #357abd;
532
- --sc-today-bg: #1a2f4a;
533
- --sc-today-text: #ff6b6b;
534
- --sc-hover-bg: #2d2d2d;
326
+ All styles are scoped under `.uc-calendar` to prevent conflicts with your existing CSS.
327
+
328
+ ## Framework Wrapper APIs
329
+
330
+ ### React
331
+
332
+ ```jsx
333
+ import { useRef } from 'react';
334
+ import SimpleCalendarJsReact from 'simple-calendar-js/frameworks/simple-calendar-js-react.jsx';
335
+
336
+ function MyComponent() {
337
+ const calendarRef = useRef();
338
+
339
+ const handleSomeAction = () => {
340
+ // Access imperative methods
341
+ calendarRef.current.goToToday();
342
+ calendarRef.current.setView('week');
343
+ calendarRef.current.navigate(1);
344
+ calendarRef.current.goToDate(new Date('2024-12-25'));
345
+ };
346
+
347
+ return (
348
+ <SimpleCalendarJsReact
349
+ ref={calendarRef}
350
+ defaultView="month"
351
+ fetchEvents={fetchEvents}
352
+ onEventClick={(event) => console.log(event)}
353
+ onSlotClick={(date) => console.log('Clicked:', date)}
354
+ onViewChange={(view) => console.log('View:', view)}
355
+ onNavigate={(start, end) => console.log('Range:', start, end)}
356
+ />
357
+ );
535
358
  }
536
359
  ```
537
360
 
538
- ### Manual Override Example
539
- ```css
540
- /* Custom theme using CSS variables */
541
- .sc-calendar {
542
- --sc-bg-primary: #f0f8ff;
543
- --sc-accent-color: #ff6b6b;
544
- --sc-today-bg: #ffe4e1;
545
- }
546
-
547
- /* Dark theme integration */
548
- [data-theme="dark"] .sc-calendar {
549
- --sc-bg-primary: #1e1e1e;
550
- --sc-accent-color: #ff8a80;
361
+ ### Vue 3
362
+
363
+ ```vue
364
+ <template>
365
+ <SimpleCalendarJsVue
366
+ ref="calendar"
367
+ :defaultView="'month'"
368
+ :fetchEvents="fetchEvents"
369
+ @eventClick="handleEventClick"
370
+ @slotClick="handleSlotClick"
371
+ @viewChange="handleViewChange"
372
+ @navigate="handleNavigate"
373
+ />
374
+ </template>
375
+
376
+ <script>
377
+ export default {
378
+ methods: {
379
+ someAction() {
380
+ // Access imperative methods
381
+ this.$refs.calendar.goToToday();
382
+ this.$refs.calendar.setView('week');
383
+ this.$refs.calendar.navigate(1);
384
+ this.$refs.calendar.goToDate(new Date('2024-12-25'));
385
+ }
386
+ }
551
387
  }
388
+ </script>
552
389
  ```
553
390
 
554
- ## Event Count Badges
555
-
556
- In month view with `fulldayMode: false`, event counts are displayed as styled badges with theme-aware coloring:
557
-
558
- - **Regular days**: Uses default event color with reduced opacity for background
559
- - **Today**: Full default event color background with white text
560
- - **Other month days**: Muted background with secondary text color
561
- - **Theme adaptive**: Automatically adjusts colors for light/dark themes
562
- - **Responsive**: Automatically adjusts size on mobile devices
563
- - **Rounded corners**: Modern badge appearance with `border-radius: 10px`
564
-
565
- ### Badge Color Logic
566
- - Background uses `color-mix()` function to blend event color with theme background
567
- - Text color adapts to theme (darker in light mode, lighter in dark mode)
568
- - Today's badge uses full event color saturation for emphasis
569
- - Seamlessly integrates with custom color schemes
570
-
571
- ## Enhanced Styling Features
572
-
573
- ### Navigation Button Styling
574
- - **Transparent Background**: Navigation arrows have transparent backgrounds in both themes
575
- - **Theme-Aware Hover**: Hover effects use the default event color for consistency
576
- - **Proper Contrast**: Arrow colors automatically adjust for light/dark themes
577
-
578
- ### View Button Styling
579
- - **Active State**: Uses default event color when view button is active
580
- - **Inactive State**: Transparent background with theme-appropriate text color
581
- - **Consistent Theming**: Seamlessly adapts to color customization
582
-
583
- ### Time Lines Enhancement
584
- - **Always Visible**: Hour and half-hour lines remain visible regardless of grid border settings
585
- - **Proper Hierarchy**: Uses `!important` declarations to ensure visibility
586
- - **Theme Integration**: Line colors adapt to current theme automatically
587
-
588
- ### Today Highlighting
589
- - **Enhanced Contrast**: Today's background is darker in dark mode for better visibility
590
- - **Cross-View Consistency**: Today highlighting works consistently across month, week, and day views
591
- - **Customizable Colors**: Today colors can be overridden via color customization system
592
-
593
- ### Page Integration
594
- - **Scrollable Layout**: Calendar no longer uses fixed positioning, allowing page scrolling
595
- - **Flexible Container**: Adapts to parent container constraints
596
- - **Better Integration**: Easier to embed in existing page layouts
597
-
598
- ## Keyboard Shortcuts
599
-
600
- - **Arrow Left/Right** - Navigate to previous/next period
601
- - **T** - Go to today
602
- - **M** - Switch to month view
603
- - **W** - Switch to week view
604
- - **D** - Switch to day view
605
-
606
- ## Time Format
607
-
608
- Time strings should be in 12-hour format with AM/PM:
609
- ```javascript
610
- '9:00 AM' // Valid
611
- '2:30 PM' // Valid
612
- '09:00' // Invalid
613
- '14:30' // Invalid
614
- ```
615
-
616
- ## Multi-day Events
617
-
618
- Multi-day events are automatically detected when `startDate` and `endDate` differ:
619
- - **Start day**: Shows event title and colored bar
620
- - **Middle days**: Shows only colored bar (seamless connection)
621
- - **End day**: Shows only colored bar
622
-
623
- Events spanning across weeks will continue seamlessly in the next row.
624
-
625
- ## Smart Event Caching
626
-
627
- When using callback-based event loading, the calendar implements intelligent caching:
628
- - Only fetches missing date ranges
629
- - Merges overlapping ranges automatically
630
- - Minimizes API calls when navigating
631
- - Clears cache when `setEvents()` is called
632
-
633
- ## Color & Accessibility
634
-
635
- The calendar automatically ensures good color contrast for accessibility:
636
-
637
- ### WCAG Compliance
638
- - Text color (black or white) is automatically calculated for optimal contrast
639
- - Uses WCAG relative luminance algorithm to determine text color
640
- - Ensures contrast ratios meet accessibility standards
641
-
642
- ### Gradient Algorithm
643
- When `colorIsGradient: true` is used:
644
- 1. Base color is used as the bottom of the gradient
645
- 2. Top color is calculated by adding 20 to each RGB component (capped at 255)
646
- 3. Creates a subtle top-to-bottom linear gradient effect
647
- 4. Text color is calculated based on the base color luminance
648
-
649
- ### Color Processing
650
- ```javascript
651
- // Examples of color processing
652
- const redEvent = {
653
- color: '#e74c3c', // Red base color
654
- colorIsGradient: true // Creates gradient from #ff6659 to #e74c3c
655
- };
656
- // Text color: white (due to dark base color)
657
-
658
- const yellowEvent = {
659
- color: '#f1c40f', // Yellow base color
660
- colorIsGradient: true // Creates gradient from #fff323 to #f1c40f
661
- };
662
- // Text color: black (due to light base color)
391
+ ### Angular
392
+
393
+ ```typescript
394
+ import { Component, ViewChild } from '@angular/core';
395
+ import { SimpleCalendarJsComponent } from 'simple-calendar-js/frameworks/simple-calendar-js-angular.component';
396
+
397
+ @Component({
398
+ selector: 'app-root',
399
+ template: `
400
+ <simple-calendar-js
401
+ #calendar
402
+ [defaultView]="'month'"
403
+ [fetchEvents]="fetchEvents"
404
+ (eventClick)="handleEventClick($event)"
405
+ (slotClick)="handleSlotClick($event)"
406
+ (viewChange)="handleViewChange($event)"
407
+ (navigate)="handleNavigate($event)"
408
+ ></simple-calendar-js>
409
+ `
410
+ })
411
+ export class AppComponent {
412
+ @ViewChild('calendar') calendar!: SimpleCalendarJsComponent;
413
+
414
+ someAction() {
415
+ // Access imperative methods
416
+ this.calendar.goToToday();
417
+ this.calendar.setView('week');
418
+ this.calendar.navigate(1);
419
+ this.calendar.goToDate(new Date('2024-12-25'));
420
+ }
421
+ }
663
422
  ```
664
423
 
665
424
  ## Browser Support
@@ -669,25 +428,18 @@ const yellowEvent = {
669
428
  - Safari 12+
670
429
  - Edge 79+
671
430
 
672
- ## File Structure
673
-
674
- ```
675
- simple-calendar-js/
676
- ├── css/
677
- │ └── simple-calendar-js.css # Main stylesheet
678
- ├── js/
679
- │ └── simple-calendar-js.js # Main JavaScript file
680
- ├── index.html # Demo page
681
- ├── README.md # This file
682
- └── package.json # Package configuration
683
- ```
684
-
685
431
  ## License
686
432
 
687
- **Personal and Non-Commercial Use License**
433
+ This project is available for personal, educational, and non-commercial use.
434
+
435
+ **Commercial use requires a separate license.** See [LICENSE](LICENSE) file for full terms.
688
436
 
689
- This project is free for personal, educational, and non-commercial use.
437
+ For commercial licensing inquiries: simplecalendarjs@gmail.com
690
438
 
691
- **Commercial use requires a separate license.** See [LICENSE](LICENSE) file for details.
439
+ ## Links
692
440
 
693
- For commercial licensing: simplecalendarjs@gmail.com
441
+ - **Documentation**: [docs.html](docs.html)
442
+ - **Demo**: [index.html](index.html)
443
+ - **Repository**: [github.com/pclslopes/SimpleCalendarJs](https://github.com/pclslopes/SimpleCalendarJs)
444
+ - **NPM**: [npmjs.com/package/simple-calendar-js](https://www.npmjs.com/package/simple-calendar-js)
445
+ - **Website**: [simplecalendarjs.com](https://www.simplecalendarjs.com)