@getmicdrop/venue-calendar 3.3.5 → 3.3.7
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 +661 -661
- package/dist/VenueCalendar-2gCRs3C_.js.map +1 -1
- package/dist/api/api.cjs.map +1 -1
- package/dist/api/api.mjs.map +1 -1
- package/dist/api/types.d.ts +289 -289
- package/dist/types/index.d.ts +395 -395
- package/dist/venue-calendar.iife.js.map +1 -1
- package/dist/venue-calendar.umd.js.map +1 -1
- package/package.json +96 -96
- package/src/lib/theme.js +209 -209
package/README.md
CHANGED
|
@@ -1,661 +1,661 @@
|
|
|
1
|
-
# @getmicdrop/venue-calendar
|
|
2
|
-
|
|
3
|
-
A beautiful, customizable calendar component built with Svelte for displaying comedy events. Perfect for comedy clubs, venues, and event organizers who want to showcase their upcoming shows.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
✨ **Three View Modes**: List, Gallery, and Calendar views
|
|
8
|
-
🎨 **Beautiful UI**: Modern, responsive design built with Tailwind CSS
|
|
9
|
-
📱 **Mobile-Friendly**: Swipe gestures, touch-optimized, responsive design
|
|
10
|
-
🔌 **Easy Integration**: Works with React, Vue, vanilla JS, and more
|
|
11
|
-
🌐 **CDN Ready**: Use directly in HTML via JSDelivr
|
|
12
|
-
⚡ **Auto-Mount**: Automatically finds and mounts to designated containers
|
|
13
|
-
🎯 **Customizable**: Configure views, navigation, and more
|
|
14
|
-
🌙 **Dark Mode**: Built-in light, dark, and high-contrast themes
|
|
15
|
-
♿ **Accessible**: ARIA labels, keyboard navigation, screen reader support
|
|
16
|
-
🎫 **Event Status**: Visual badges for "On Sale", "Selling Fast", "Sold Out"
|
|
17
|
-
|
|
18
|
-
## Installation
|
|
19
|
-
|
|
20
|
-
### NPM/Yarn
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm install @getmicdrop/venue-calendar
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
or
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
yarn add @getmicdrop/venue-calendar
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### CDN (JSDelivr)
|
|
33
|
-
|
|
34
|
-
```html
|
|
35
|
-
<!-- Latest version -->
|
|
36
|
-
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.iife.js"></script>
|
|
37
|
-
|
|
38
|
-
<!-- Specific version (recommended for production) -->
|
|
39
|
-
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar@1.3.0/dist/venue-calendar.iife.js"></script>
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Quick Start
|
|
43
|
-
|
|
44
|
-
### Method 1: Auto-Mount (Easiest)
|
|
45
|
-
|
|
46
|
-
Simply add a div with the class `micdrop-calendar-container` and the calendar will automatically mount:
|
|
47
|
-
|
|
48
|
-
```html
|
|
49
|
-
<!DOCTYPE html>
|
|
50
|
-
<html>
|
|
51
|
-
<head>
|
|
52
|
-
<title>My Comedy Club</title>
|
|
53
|
-
</head>
|
|
54
|
-
<body>
|
|
55
|
-
<!-- Calendar will auto-mount here -->
|
|
56
|
-
<div class="micdrop-calendar-container"
|
|
57
|
-
data-venue-id="your-venue-id"
|
|
58
|
-
data-view="calendar"
|
|
59
|
-
data-show-view-options="true"
|
|
60
|
-
data-show-month-switcher="true">
|
|
61
|
-
</div>
|
|
62
|
-
|
|
63
|
-
<!-- Load the script -->
|
|
64
|
-
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.iife.js"></script>
|
|
65
|
-
</body>
|
|
66
|
-
</html>
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Method 2: Web Component
|
|
70
|
-
|
|
71
|
-
Use the custom `<micdrop-calendar>` element:
|
|
72
|
-
|
|
73
|
-
```html
|
|
74
|
-
<!DOCTYPE html>
|
|
75
|
-
<html>
|
|
76
|
-
<head>
|
|
77
|
-
<title>My Comedy Club</title>
|
|
78
|
-
</head>
|
|
79
|
-
<body>
|
|
80
|
-
<!-- Web Component -->
|
|
81
|
-
<micdrop-calendar
|
|
82
|
-
venue-id="your-venue-id"
|
|
83
|
-
view="calendar"
|
|
84
|
-
show-view-options="true"
|
|
85
|
-
show-month-switcher="true">
|
|
86
|
-
</micdrop-calendar>
|
|
87
|
-
|
|
88
|
-
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.iife.js"></script>
|
|
89
|
-
</body>
|
|
90
|
-
</html>
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
### Method 3: JavaScript API
|
|
94
|
-
|
|
95
|
-
For more control, use the JavaScript API:
|
|
96
|
-
|
|
97
|
-
```html
|
|
98
|
-
<!DOCTYPE html>
|
|
99
|
-
<html>
|
|
100
|
-
<head>
|
|
101
|
-
<title>My Comedy Club</title>
|
|
102
|
-
</head>
|
|
103
|
-
<body>
|
|
104
|
-
<div id="my-calendar"></div>
|
|
105
|
-
|
|
106
|
-
<script type="module">
|
|
107
|
-
import { initVenueCalendar } from 'https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.es.js';
|
|
108
|
-
|
|
109
|
-
initVenueCalendar({
|
|
110
|
-
target: '#my-calendar',
|
|
111
|
-
venueId: 'your-venue-id',
|
|
112
|
-
view: 'calendar',
|
|
113
|
-
events: [],
|
|
114
|
-
showViewOptions: true,
|
|
115
|
-
showMonthSwitcher: true,
|
|
116
|
-
});
|
|
117
|
-
</script>
|
|
118
|
-
</body>
|
|
119
|
-
</html>
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## Framework Integration
|
|
123
|
-
|
|
124
|
-
### React
|
|
125
|
-
|
|
126
|
-
```jsx
|
|
127
|
-
import React, { useEffect, useRef } from 'react';
|
|
128
|
-
import { initVenueCalendar } from '@getmicdrop/venue-calendar';
|
|
129
|
-
|
|
130
|
-
function VenueCalendarComponent({ venueId, view = 'calendar' }) {
|
|
131
|
-
const calendarRef = useRef(null);
|
|
132
|
-
const instanceRef = useRef(null);
|
|
133
|
-
|
|
134
|
-
useEffect(() => {
|
|
135
|
-
if (calendarRef.current) {
|
|
136
|
-
// Initialize calendar
|
|
137
|
-
instanceRef.current = initVenueCalendar({
|
|
138
|
-
target: calendarRef.current,
|
|
139
|
-
venueId,
|
|
140
|
-
view,
|
|
141
|
-
events: [],
|
|
142
|
-
showViewOptions: true,
|
|
143
|
-
showMonthSwitcher: true,
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Cleanup on unmount
|
|
148
|
-
return () => {
|
|
149
|
-
if (instanceRef.current && instanceRef.current.$destroy) {
|
|
150
|
-
instanceRef.current.$destroy();
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
}, [venueId, view]);
|
|
154
|
-
|
|
155
|
-
return <div ref={calendarRef}></div>;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export default VenueCalendarComponent;
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**Usage in React App:**
|
|
162
|
-
|
|
163
|
-
```jsx
|
|
164
|
-
import React, { useState } from "react";
|
|
165
|
-
import VenueCalendarComponent from "./VenueCalendarComponent";
|
|
166
|
-
|
|
167
|
-
function App() {
|
|
168
|
-
const [venueId, setVenueId] = useState("comedy-club-123");
|
|
169
|
-
const [view, setView] = useState("calendar");
|
|
170
|
-
|
|
171
|
-
return (
|
|
172
|
-
<div style={{ padding: "20px" }}>
|
|
173
|
-
<h1>Event Viewer</h1>
|
|
174
|
-
|
|
175
|
-
<div style={{ marginBottom: "20px" }}>
|
|
176
|
-
<label>Venue ID:</label>
|
|
177
|
-
<input
|
|
178
|
-
type="text"
|
|
179
|
-
value={venueId}
|
|
180
|
-
onChange={(e) => setVenueId(e.target.value)}
|
|
181
|
-
/>
|
|
182
|
-
</div>
|
|
183
|
-
|
|
184
|
-
<div style={{ marginBottom: "20px" }}>
|
|
185
|
-
<label>Select View:</label>
|
|
186
|
-
<label>
|
|
187
|
-
<input
|
|
188
|
-
type="radio"
|
|
189
|
-
value="list"
|
|
190
|
-
checked={view === "list"}
|
|
191
|
-
onChange={(e) => setView(e.target.value)}
|
|
192
|
-
/>
|
|
193
|
-
List
|
|
194
|
-
</label>
|
|
195
|
-
<label>
|
|
196
|
-
<input
|
|
197
|
-
type="radio"
|
|
198
|
-
value="gallery"
|
|
199
|
-
checked={view === "gallery"}
|
|
200
|
-
onChange={(e) => setView(e.target.value)}
|
|
201
|
-
/>
|
|
202
|
-
Gallery
|
|
203
|
-
</label>
|
|
204
|
-
<label>
|
|
205
|
-
<input
|
|
206
|
-
type="radio"
|
|
207
|
-
value="calendar"
|
|
208
|
-
checked={view === "calendar"}
|
|
209
|
-
onChange={(e) => setView(e.target.value)}
|
|
210
|
-
/>
|
|
211
|
-
Calendar
|
|
212
|
-
</label>
|
|
213
|
-
</div>
|
|
214
|
-
|
|
215
|
-
<VenueCalendarComponent venueId={venueId} view={view} />
|
|
216
|
-
</div>
|
|
217
|
-
);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
export default App;
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
### Vue 3
|
|
224
|
-
|
|
225
|
-
```vue
|
|
226
|
-
<template>
|
|
227
|
-
<div ref="calendarContainer"></div>
|
|
228
|
-
</template>
|
|
229
|
-
|
|
230
|
-
<script setup>
|
|
231
|
-
import { ref, onMounted, onUnmounted, watch } from 'vue';
|
|
232
|
-
import { initVenueCalendar } from '@getmicdrop/venue-calendar';
|
|
233
|
-
|
|
234
|
-
const props = defineProps({
|
|
235
|
-
venueId: String,
|
|
236
|
-
view: {
|
|
237
|
-
type: String,
|
|
238
|
-
default: 'calendar'
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
const calendarContainer = ref(null);
|
|
243
|
-
let calendarInstance = null;
|
|
244
|
-
|
|
245
|
-
onMounted(() => {
|
|
246
|
-
calendarInstance = initVenueCalendar({
|
|
247
|
-
target: calendarContainer.value,
|
|
248
|
-
venueId: props.venueId,
|
|
249
|
-
view: props.view,
|
|
250
|
-
events: [],
|
|
251
|
-
showViewOptions: true,
|
|
252
|
-
showMonthSwitcher: true,
|
|
253
|
-
});
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
onUnmounted(() => {
|
|
257
|
-
if (calendarInstance && calendarInstance.$destroy) {
|
|
258
|
-
calendarInstance.$destroy();
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
watch(() => props.venueId, (newId) => {
|
|
263
|
-
if (calendarInstance) {
|
|
264
|
-
calendarInstance.$destroy();
|
|
265
|
-
calendarInstance = initVenueCalendar({
|
|
266
|
-
target: calendarContainer.value,
|
|
267
|
-
venueId: newId,
|
|
268
|
-
view: props.view,
|
|
269
|
-
events: [],
|
|
270
|
-
showViewOptions: true,
|
|
271
|
-
showMonthSwitcher: true,
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
});
|
|
275
|
-
</script>
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
### Svelte
|
|
279
|
-
|
|
280
|
-
```svelte
|
|
281
|
-
<script>
|
|
282
|
-
import { VenueCalendar } from '@getmicdrop/venue-calendar';
|
|
283
|
-
import { Calendar, Grid, List } from 'carbon-icons-svelte';
|
|
284
|
-
import { writable } from 'svelte/store';
|
|
285
|
-
|
|
286
|
-
let venueId = 'your-venue-id';
|
|
287
|
-
let currentMonth = writable(new Date().getUTCMonth());
|
|
288
|
-
let currentYear = writable(new Date().getUTCFullYear());
|
|
289
|
-
|
|
290
|
-
function handleNext() {
|
|
291
|
-
currentMonth.update(m => m + 1);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
function handlePrev() {
|
|
295
|
-
currentMonth.update(m => m - 1);
|
|
296
|
-
}
|
|
297
|
-
</script>
|
|
298
|
-
|
|
299
|
-
<VenueCalendar
|
|
300
|
-
showViewOptions={[
|
|
301
|
-
{ id: 0, text: "List view", icon: List },
|
|
302
|
-
{ id: 1, text: "Gallery view", icon: Grid },
|
|
303
|
-
{ id: 2, text: "Calendar view", icon: Calendar }
|
|
304
|
-
]}
|
|
305
|
-
showMonthSwitcher={true}
|
|
306
|
-
events={[]}
|
|
307
|
-
{currentMonth}
|
|
308
|
-
{currentYear}
|
|
309
|
-
handleNext={handleNext}
|
|
310
|
-
handlePrev={handlePrev}
|
|
311
|
-
on:eventClick={(e) => console.log('Event clicked:', e.detail)}
|
|
312
|
-
/>
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Angular
|
|
316
|
-
|
|
317
|
-
```typescript
|
|
318
|
-
import { Component, OnInit, OnDestroy, ElementRef, ViewChild } from '@angular/core';
|
|
319
|
-
import { initVenueCalendar } from '@getmicdrop/venue-calendar';
|
|
320
|
-
|
|
321
|
-
@Component({
|
|
322
|
-
selector: 'app-venue-calendar',
|
|
323
|
-
template: '<div #calendarContainer></div>',
|
|
324
|
-
})
|
|
325
|
-
export class VenueCalendarComponent implements OnInit, OnDestroy {
|
|
326
|
-
@ViewChild('calendarContainer', { static: true }) calendarContainer!: ElementRef;
|
|
327
|
-
private calendarInstance: any;
|
|
328
|
-
|
|
329
|
-
ngOnInit() {
|
|
330
|
-
this.calendarInstance = initVenueCalendar({
|
|
331
|
-
target: this.calendarContainer.nativeElement,
|
|
332
|
-
venueId: 'your-venue-id',
|
|
333
|
-
view: 'calendar',
|
|
334
|
-
events: [],
|
|
335
|
-
showViewOptions: true,
|
|
336
|
-
showMonthSwitcher: true,
|
|
337
|
-
});
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
ngOnDestroy() {
|
|
341
|
-
if (this.calendarInstance && this.calendarInstance.$destroy) {
|
|
342
|
-
this.calendarInstance.$destroy();
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
}
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
## Configuration Options
|
|
349
|
-
|
|
350
|
-
### Data Attributes (for auto-mount)
|
|
351
|
-
|
|
352
|
-
| Attribute | Type | Default | Description |
|
|
353
|
-
|-----------|------|---------|-------------|
|
|
354
|
-
| `data-venue-id` | string | `''` | The venue ID to fetch events for |
|
|
355
|
-
| `data-view` | string | `'calendar'` | Initial view: `'list'`, `'gallery'`, or `'calendar'` |
|
|
356
|
-
| `data-show-view-options` | boolean | `true` | Show view switcher buttons |
|
|
357
|
-
| `data-show-month-switcher` | boolean | `true` | Show month navigation controls |
|
|
358
|
-
|
|
359
|
-
### JavaScript API Options
|
|
360
|
-
|
|
361
|
-
```javascript
|
|
362
|
-
initVenueCalendar({
|
|
363
|
-
target: '.my-calendar', // CSS selector or HTMLElement (required)
|
|
364
|
-
venueId: 'venue-123', // Venue ID (optional)
|
|
365
|
-
view: 'calendar', // 'list', 'gallery', or 'calendar' (default: 'calendar')
|
|
366
|
-
events: [], // Array of event objects (default: [])
|
|
367
|
-
showViewOptions: true, // Show view switcher (default: true)
|
|
368
|
-
showMonthSwitcher: true, // Show month navigation (default: true)
|
|
369
|
-
});
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
### Event Object Structure
|
|
373
|
-
|
|
374
|
-
```javascript
|
|
375
|
-
{
|
|
376
|
-
id: 'event-123',
|
|
377
|
-
name: 'Comedy Night',
|
|
378
|
-
date: '2024-10-25T20:00:00Z',
|
|
379
|
-
image: 'https://example.com/image.jpg',
|
|
380
|
-
status: 'On Sale',
|
|
381
|
-
timeline: '8:00 PM - 10:00 PM',
|
|
382
|
-
// ... other fields
|
|
383
|
-
}
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
## Views
|
|
387
|
-
|
|
388
|
-
### Calendar View
|
|
389
|
-
The default view showing events in a monthly calendar grid. Perfect for venues with regular shows.
|
|
390
|
-
|
|
391
|
-
### List View
|
|
392
|
-
A vertical list layout showing all upcoming events with details. Great for mobile experiences.
|
|
393
|
-
|
|
394
|
-
### Gallery View
|
|
395
|
-
A grid layout displaying event posters in a gallery format. Ideal for showcasing event imagery.
|
|
396
|
-
|
|
397
|
-
## WordPress Integration
|
|
398
|
-
|
|
399
|
-
For WordPress sites, you can add this to your page/post HTML:
|
|
400
|
-
|
|
401
|
-
```html
|
|
402
|
-
<div class="micdrop-calendar-container"
|
|
403
|
-
data-venue-id="your-venue-id"
|
|
404
|
-
data-view="calendar">
|
|
405
|
-
</div>
|
|
406
|
-
|
|
407
|
-
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.iife.js"></script>
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
Or add the script to your theme's footer and use the div anywhere in your content.
|
|
411
|
-
|
|
412
|
-
## Styling
|
|
413
|
-
|
|
414
|
-
The calendar comes with built-in styles using Tailwind CSS. If you need to customize the appearance, you can override the CSS classes or add your own styles.
|
|
415
|
-
|
|
416
|
-
```css
|
|
417
|
-
/* Example: Custom styling */
|
|
418
|
-
.micdrop-calendar-container {
|
|
419
|
-
max-width: 1200px;
|
|
420
|
-
margin: 0 auto;
|
|
421
|
-
padding: 20px;
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
## Theming
|
|
426
|
-
|
|
427
|
-
The calendar supports comprehensive theming via CSS custom properties and JavaScript utilities.
|
|
428
|
-
|
|
429
|
-
### Using CSS Custom Properties
|
|
430
|
-
|
|
431
|
-
Override the default theme by setting CSS custom properties:
|
|
432
|
-
|
|
433
|
-
```css
|
|
434
|
-
/* Custom brand colors */
|
|
435
|
-
.micdrop-calendar-container {
|
|
436
|
-
--Brand-Primary: 270 76% 60%; /* Purple */
|
|
437
|
-
--Text-Primary: 0 0% 10%;
|
|
438
|
-
--BG-Primary: 0 0% 100%;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/* Dark mode */
|
|
442
|
-
.dark .micdrop-calendar-container,
|
|
443
|
-
[data-theme="dark"] .micdrop-calendar-container {
|
|
444
|
-
--Brand-Primary: 270 76% 70%;
|
|
445
|
-
--Text-Primary: 0 0% 95%;
|
|
446
|
-
--BG-Primary: 0 0% 10%;
|
|
447
|
-
}
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
### Available CSS Variables
|
|
451
|
-
|
|
452
|
-
| Variable | Description | Default (Light) |
|
|
453
|
-
|----------|-------------|-----------------|
|
|
454
|
-
| `--Brand-Primary` | Primary brand color | `217 91% 60%` (Blue) |
|
|
455
|
-
| `--Text-Primary` | Main text color | `0 0% 0%` |
|
|
456
|
-
| `--Text-Secondary` | Secondary text | `0 0% 40%` |
|
|
457
|
-
| `--BG-Primary` | Main background | `0 0% 100%` |
|
|
458
|
-
| `--BG-Secondary` | Secondary background | `0 0% 98%` |
|
|
459
|
-
| `--Stroke-Primary` | Border colors | `0 0% 80%` |
|
|
460
|
-
| `--Status-OnSale` | "On Sale" badge | `217 91% 60%` |
|
|
461
|
-
| `--Status-SellingFast` | "Selling Fast" badge | `38 92% 50%` |
|
|
462
|
-
| `--Status-SoldOut` | "Sold Out" badge | `0 84% 60%` |
|
|
463
|
-
| `--Today-BG` | Today's date background | `217 91% 97%` |
|
|
464
|
-
| `--Focus-Ring` | Keyboard focus ring | `217 91% 60%` |
|
|
465
|
-
|
|
466
|
-
### Using JavaScript Theme Utilities
|
|
467
|
-
|
|
468
|
-
```javascript
|
|
469
|
-
import { applyTheme, themes, generateThemeCSS } from '@getmicdrop/venue-calendar';
|
|
470
|
-
|
|
471
|
-
// Apply a preset theme
|
|
472
|
-
applyTheme(themes.dark);
|
|
473
|
-
|
|
474
|
-
// Apply to a specific container
|
|
475
|
-
const container = document.querySelector('.micdrop-calendar-container');
|
|
476
|
-
applyTheme(themes.dark, container);
|
|
477
|
-
|
|
478
|
-
// Create a custom theme
|
|
479
|
-
const myTheme = {
|
|
480
|
-
brandPrimary: '270 76% 60%', // Purple
|
|
481
|
-
textPrimary: '0 0% 10%',
|
|
482
|
-
bgPrimary: '0 0% 100%',
|
|
483
|
-
statusOnSale: '142 71% 45%', // Green for on sale
|
|
484
|
-
};
|
|
485
|
-
applyTheme(myTheme);
|
|
486
|
-
|
|
487
|
-
// Generate CSS string for embedding
|
|
488
|
-
const cssString = generateThemeCSS(myTheme);
|
|
489
|
-
console.log(cssString);
|
|
490
|
-
// Output: :root { --Brand-Primary: 270 76% 60%; ... }
|
|
491
|
-
```
|
|
492
|
-
|
|
493
|
-
### Preset Themes
|
|
494
|
-
|
|
495
|
-
Three themes are included out of the box:
|
|
496
|
-
|
|
497
|
-
```javascript
|
|
498
|
-
import { themes } from '@getmicdrop/venue-calendar';
|
|
499
|
-
|
|
500
|
-
// Light theme (default)
|
|
501
|
-
applyTheme(themes.light);
|
|
502
|
-
|
|
503
|
-
// Dark theme
|
|
504
|
-
applyTheme(themes.dark);
|
|
505
|
-
|
|
506
|
-
// High contrast (accessibility)
|
|
507
|
-
applyTheme(themes.highContrast);
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
### Automatic Dark Mode
|
|
511
|
-
|
|
512
|
-
The calendar automatically respects the user's system preference:
|
|
513
|
-
|
|
514
|
-
```css
|
|
515
|
-
/* Automatically applied when user prefers dark mode */
|
|
516
|
-
@media (prefers-color-scheme: dark) {
|
|
517
|
-
/* Dark theme variables are applied */
|
|
518
|
-
}
|
|
519
|
-
```
|
|
520
|
-
|
|
521
|
-
You can also manually toggle dark mode:
|
|
522
|
-
|
|
523
|
-
```html
|
|
524
|
-
<!-- Add 'dark' class to enable dark theme -->
|
|
525
|
-
<div class="dark">
|
|
526
|
-
<div class="micdrop-calendar-container" data-venue-id="123"></div>
|
|
527
|
-
</div>
|
|
528
|
-
|
|
529
|
-
<!-- Or use data-theme attribute -->
|
|
530
|
-
<div data-theme="dark">
|
|
531
|
-
<div class="micdrop-calendar-container" data-venue-id="123"></div>
|
|
532
|
-
</div>
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
## Browser Support
|
|
536
|
-
|
|
537
|
-
- Chrome (latest)
|
|
538
|
-
- Firefox (latest)
|
|
539
|
-
- Safari (latest)
|
|
540
|
-
- Edge (latest)
|
|
541
|
-
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
542
|
-
|
|
543
|
-
## Development
|
|
544
|
-
|
|
545
|
-
### Building the Package
|
|
546
|
-
|
|
547
|
-
```bash
|
|
548
|
-
# Install dependencies
|
|
549
|
-
npm install
|
|
550
|
-
|
|
551
|
-
# Build the library
|
|
552
|
-
npm run build:lib
|
|
553
|
-
|
|
554
|
-
# Development mode (SvelteKit app)
|
|
555
|
-
npm run dev
|
|
556
|
-
|
|
557
|
-
# Preview production build
|
|
558
|
-
npm run preview
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
### Project Structure
|
|
562
|
-
|
|
563
|
-
```
|
|
564
|
-
venue-calendar/
|
|
565
|
-
├── src/
|
|
566
|
-
│ ├── components/ # Svelte components
|
|
567
|
-
│ │ ├── Calendar/
|
|
568
|
-
│ │ ├── CalendarContainer/
|
|
569
|
-
│ │ └── Button/
|
|
570
|
-
│ ├── lib/ # Library entry points
|
|
571
|
-
│ │ ├── VenueCalendar.js
|
|
572
|
-
│ │ └── web-component.js
|
|
573
|
-
│ └── routes/ # SvelteKit routes (for dev)
|
|
574
|
-
├── dist/ # Built package (generated)
|
|
575
|
-
├── package.json
|
|
576
|
-
├── vite.config.lib.js # Library build config
|
|
577
|
-
└── README.md
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
## API Reference
|
|
581
|
-
|
|
582
|
-
### `initVenueCalendar(options)`
|
|
583
|
-
|
|
584
|
-
Initialize a calendar instance.
|
|
585
|
-
|
|
586
|
-
**Parameters:**
|
|
587
|
-
- `options` (Object): Configuration options
|
|
588
|
-
|
|
589
|
-
**Returns:** Svelte component instance
|
|
590
|
-
|
|
591
|
-
**Example:**
|
|
592
|
-
```javascript
|
|
593
|
-
const calendar = initVenueCalendar({
|
|
594
|
-
target: '#calendar',
|
|
595
|
-
venueId: 'venue-123',
|
|
596
|
-
view: 'calendar',
|
|
597
|
-
});
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
### `autoMount()`
|
|
601
|
-
|
|
602
|
-
Automatically mount calendars to all elements with class `micdrop-calendar-container`.
|
|
603
|
-
|
|
604
|
-
**Example:**
|
|
605
|
-
```javascript
|
|
606
|
-
import { autoMount } from '@getmicdrop/venue-calendar';
|
|
607
|
-
autoMount();
|
|
608
|
-
```
|
|
609
|
-
|
|
610
|
-
### Component Events
|
|
611
|
-
|
|
612
|
-
The calendar component emits events that you can listen to:
|
|
613
|
-
|
|
614
|
-
```javascript
|
|
615
|
-
const calendar = initVenueCalendar({
|
|
616
|
-
target: '#calendar',
|
|
617
|
-
// ... other options
|
|
618
|
-
});
|
|
619
|
-
|
|
620
|
-
// Listen to component events (if using Svelte component directly)
|
|
621
|
-
calendar.$on('eventClick', (event) => {
|
|
622
|
-
console.log('Event clicked:', event.detail);
|
|
623
|
-
});
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
## Troubleshooting
|
|
627
|
-
|
|
628
|
-
### Calendar not appearing
|
|
629
|
-
|
|
630
|
-
1. **Check the script is loaded**: Open browser console and verify no errors
|
|
631
|
-
2. **Verify container exists**: Make sure the target element exists in the DOM
|
|
632
|
-
3. **Check data attributes**: Ensure attributes are correctly formatted with `data-` prefix
|
|
633
|
-
|
|
634
|
-
### Styles not applying
|
|
635
|
-
|
|
636
|
-
1. **CSS not loaded**: The styles are bundled in the JS file and auto-injected
|
|
637
|
-
2. **CSS conflicts**: Check if other styles are overriding the calendar styles
|
|
638
|
-
3. **CDN issues**: Try using a specific version instead of `@latest`
|
|
639
|
-
|
|
640
|
-
### Events not showing
|
|
641
|
-
|
|
642
|
-
1. **Check event data format**: Ensure events match the expected structure
|
|
643
|
-
2. **Date format**: Use ISO 8601 format for dates (`YYYY-MM-DDTHH:mm:ssZ`)
|
|
644
|
-
3. **Venue ID**: Verify the venue ID is correct
|
|
645
|
-
|
|
646
|
-
## Contributing
|
|
647
|
-
|
|
648
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
649
|
-
|
|
650
|
-
## License
|
|
651
|
-
|
|
652
|
-
MIT © MicDrop
|
|
653
|
-
|
|
654
|
-
## Support
|
|
655
|
-
|
|
656
|
-
For issues, questions, or feature requests, please visit:
|
|
657
|
-
https://github.com/get-micdrop/venue-calendar/issues
|
|
658
|
-
|
|
659
|
-
---
|
|
660
|
-
|
|
661
|
-
Made with ❤️ by the MicDrop team
|
|
1
|
+
# @getmicdrop/venue-calendar
|
|
2
|
+
|
|
3
|
+
A beautiful, customizable calendar component built with Svelte for displaying comedy events. Perfect for comedy clubs, venues, and event organizers who want to showcase their upcoming shows.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
✨ **Three View Modes**: List, Gallery, and Calendar views
|
|
8
|
+
🎨 **Beautiful UI**: Modern, responsive design built with Tailwind CSS
|
|
9
|
+
📱 **Mobile-Friendly**: Swipe gestures, touch-optimized, responsive design
|
|
10
|
+
🔌 **Easy Integration**: Works with React, Vue, vanilla JS, and more
|
|
11
|
+
🌐 **CDN Ready**: Use directly in HTML via JSDelivr
|
|
12
|
+
⚡ **Auto-Mount**: Automatically finds and mounts to designated containers
|
|
13
|
+
🎯 **Customizable**: Configure views, navigation, and more
|
|
14
|
+
🌙 **Dark Mode**: Built-in light, dark, and high-contrast themes
|
|
15
|
+
♿ **Accessible**: ARIA labels, keyboard navigation, screen reader support
|
|
16
|
+
🎫 **Event Status**: Visual badges for "On Sale", "Selling Fast", "Sold Out"
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
### NPM/Yarn
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm install @getmicdrop/venue-calendar
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
or
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
yarn add @getmicdrop/venue-calendar
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### CDN (JSDelivr)
|
|
33
|
+
|
|
34
|
+
```html
|
|
35
|
+
<!-- Latest version -->
|
|
36
|
+
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.iife.js"></script>
|
|
37
|
+
|
|
38
|
+
<!-- Specific version (recommended for production) -->
|
|
39
|
+
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar@1.3.0/dist/venue-calendar.iife.js"></script>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
### Method 1: Auto-Mount (Easiest)
|
|
45
|
+
|
|
46
|
+
Simply add a div with the class `micdrop-calendar-container` and the calendar will automatically mount:
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<!DOCTYPE html>
|
|
50
|
+
<html>
|
|
51
|
+
<head>
|
|
52
|
+
<title>My Comedy Club</title>
|
|
53
|
+
</head>
|
|
54
|
+
<body>
|
|
55
|
+
<!-- Calendar will auto-mount here -->
|
|
56
|
+
<div class="micdrop-calendar-container"
|
|
57
|
+
data-venue-id="your-venue-id"
|
|
58
|
+
data-view="calendar"
|
|
59
|
+
data-show-view-options="true"
|
|
60
|
+
data-show-month-switcher="true">
|
|
61
|
+
</div>
|
|
62
|
+
|
|
63
|
+
<!-- Load the script -->
|
|
64
|
+
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.iife.js"></script>
|
|
65
|
+
</body>
|
|
66
|
+
</html>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Method 2: Web Component
|
|
70
|
+
|
|
71
|
+
Use the custom `<micdrop-calendar>` element:
|
|
72
|
+
|
|
73
|
+
```html
|
|
74
|
+
<!DOCTYPE html>
|
|
75
|
+
<html>
|
|
76
|
+
<head>
|
|
77
|
+
<title>My Comedy Club</title>
|
|
78
|
+
</head>
|
|
79
|
+
<body>
|
|
80
|
+
<!-- Web Component -->
|
|
81
|
+
<micdrop-calendar
|
|
82
|
+
venue-id="your-venue-id"
|
|
83
|
+
view="calendar"
|
|
84
|
+
show-view-options="true"
|
|
85
|
+
show-month-switcher="true">
|
|
86
|
+
</micdrop-calendar>
|
|
87
|
+
|
|
88
|
+
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.iife.js"></script>
|
|
89
|
+
</body>
|
|
90
|
+
</html>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Method 3: JavaScript API
|
|
94
|
+
|
|
95
|
+
For more control, use the JavaScript API:
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<!DOCTYPE html>
|
|
99
|
+
<html>
|
|
100
|
+
<head>
|
|
101
|
+
<title>My Comedy Club</title>
|
|
102
|
+
</head>
|
|
103
|
+
<body>
|
|
104
|
+
<div id="my-calendar"></div>
|
|
105
|
+
|
|
106
|
+
<script type="module">
|
|
107
|
+
import { initVenueCalendar } from 'https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.es.js';
|
|
108
|
+
|
|
109
|
+
initVenueCalendar({
|
|
110
|
+
target: '#my-calendar',
|
|
111
|
+
venueId: 'your-venue-id',
|
|
112
|
+
view: 'calendar',
|
|
113
|
+
events: [],
|
|
114
|
+
showViewOptions: true,
|
|
115
|
+
showMonthSwitcher: true,
|
|
116
|
+
});
|
|
117
|
+
</script>
|
|
118
|
+
</body>
|
|
119
|
+
</html>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Framework Integration
|
|
123
|
+
|
|
124
|
+
### React
|
|
125
|
+
|
|
126
|
+
```jsx
|
|
127
|
+
import React, { useEffect, useRef } from 'react';
|
|
128
|
+
import { initVenueCalendar } from '@getmicdrop/venue-calendar';
|
|
129
|
+
|
|
130
|
+
function VenueCalendarComponent({ venueId, view = 'calendar' }) {
|
|
131
|
+
const calendarRef = useRef(null);
|
|
132
|
+
const instanceRef = useRef(null);
|
|
133
|
+
|
|
134
|
+
useEffect(() => {
|
|
135
|
+
if (calendarRef.current) {
|
|
136
|
+
// Initialize calendar
|
|
137
|
+
instanceRef.current = initVenueCalendar({
|
|
138
|
+
target: calendarRef.current,
|
|
139
|
+
venueId,
|
|
140
|
+
view,
|
|
141
|
+
events: [],
|
|
142
|
+
showViewOptions: true,
|
|
143
|
+
showMonthSwitcher: true,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Cleanup on unmount
|
|
148
|
+
return () => {
|
|
149
|
+
if (instanceRef.current && instanceRef.current.$destroy) {
|
|
150
|
+
instanceRef.current.$destroy();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}, [venueId, view]);
|
|
154
|
+
|
|
155
|
+
return <div ref={calendarRef}></div>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export default VenueCalendarComponent;
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**Usage in React App:**
|
|
162
|
+
|
|
163
|
+
```jsx
|
|
164
|
+
import React, { useState } from "react";
|
|
165
|
+
import VenueCalendarComponent from "./VenueCalendarComponent";
|
|
166
|
+
|
|
167
|
+
function App() {
|
|
168
|
+
const [venueId, setVenueId] = useState("comedy-club-123");
|
|
169
|
+
const [view, setView] = useState("calendar");
|
|
170
|
+
|
|
171
|
+
return (
|
|
172
|
+
<div style={{ padding: "20px" }}>
|
|
173
|
+
<h1>Event Viewer</h1>
|
|
174
|
+
|
|
175
|
+
<div style={{ marginBottom: "20px" }}>
|
|
176
|
+
<label>Venue ID:</label>
|
|
177
|
+
<input
|
|
178
|
+
type="text"
|
|
179
|
+
value={venueId}
|
|
180
|
+
onChange={(e) => setVenueId(e.target.value)}
|
|
181
|
+
/>
|
|
182
|
+
</div>
|
|
183
|
+
|
|
184
|
+
<div style={{ marginBottom: "20px" }}>
|
|
185
|
+
<label>Select View:</label>
|
|
186
|
+
<label>
|
|
187
|
+
<input
|
|
188
|
+
type="radio"
|
|
189
|
+
value="list"
|
|
190
|
+
checked={view === "list"}
|
|
191
|
+
onChange={(e) => setView(e.target.value)}
|
|
192
|
+
/>
|
|
193
|
+
List
|
|
194
|
+
</label>
|
|
195
|
+
<label>
|
|
196
|
+
<input
|
|
197
|
+
type="radio"
|
|
198
|
+
value="gallery"
|
|
199
|
+
checked={view === "gallery"}
|
|
200
|
+
onChange={(e) => setView(e.target.value)}
|
|
201
|
+
/>
|
|
202
|
+
Gallery
|
|
203
|
+
</label>
|
|
204
|
+
<label>
|
|
205
|
+
<input
|
|
206
|
+
type="radio"
|
|
207
|
+
value="calendar"
|
|
208
|
+
checked={view === "calendar"}
|
|
209
|
+
onChange={(e) => setView(e.target.value)}
|
|
210
|
+
/>
|
|
211
|
+
Calendar
|
|
212
|
+
</label>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<VenueCalendarComponent venueId={venueId} view={view} />
|
|
216
|
+
</div>
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export default App;
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Vue 3
|
|
224
|
+
|
|
225
|
+
```vue
|
|
226
|
+
<template>
|
|
227
|
+
<div ref="calendarContainer"></div>
|
|
228
|
+
</template>
|
|
229
|
+
|
|
230
|
+
<script setup>
|
|
231
|
+
import { ref, onMounted, onUnmounted, watch } from 'vue';
|
|
232
|
+
import { initVenueCalendar } from '@getmicdrop/venue-calendar';
|
|
233
|
+
|
|
234
|
+
const props = defineProps({
|
|
235
|
+
venueId: String,
|
|
236
|
+
view: {
|
|
237
|
+
type: String,
|
|
238
|
+
default: 'calendar'
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const calendarContainer = ref(null);
|
|
243
|
+
let calendarInstance = null;
|
|
244
|
+
|
|
245
|
+
onMounted(() => {
|
|
246
|
+
calendarInstance = initVenueCalendar({
|
|
247
|
+
target: calendarContainer.value,
|
|
248
|
+
venueId: props.venueId,
|
|
249
|
+
view: props.view,
|
|
250
|
+
events: [],
|
|
251
|
+
showViewOptions: true,
|
|
252
|
+
showMonthSwitcher: true,
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
onUnmounted(() => {
|
|
257
|
+
if (calendarInstance && calendarInstance.$destroy) {
|
|
258
|
+
calendarInstance.$destroy();
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
watch(() => props.venueId, (newId) => {
|
|
263
|
+
if (calendarInstance) {
|
|
264
|
+
calendarInstance.$destroy();
|
|
265
|
+
calendarInstance = initVenueCalendar({
|
|
266
|
+
target: calendarContainer.value,
|
|
267
|
+
venueId: newId,
|
|
268
|
+
view: props.view,
|
|
269
|
+
events: [],
|
|
270
|
+
showViewOptions: true,
|
|
271
|
+
showMonthSwitcher: true,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
</script>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Svelte
|
|
279
|
+
|
|
280
|
+
```svelte
|
|
281
|
+
<script>
|
|
282
|
+
import { VenueCalendar } from '@getmicdrop/venue-calendar';
|
|
283
|
+
import { Calendar, Grid, List } from 'carbon-icons-svelte';
|
|
284
|
+
import { writable } from 'svelte/store';
|
|
285
|
+
|
|
286
|
+
let venueId = 'your-venue-id';
|
|
287
|
+
let currentMonth = writable(new Date().getUTCMonth());
|
|
288
|
+
let currentYear = writable(new Date().getUTCFullYear());
|
|
289
|
+
|
|
290
|
+
function handleNext() {
|
|
291
|
+
currentMonth.update(m => m + 1);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function handlePrev() {
|
|
295
|
+
currentMonth.update(m => m - 1);
|
|
296
|
+
}
|
|
297
|
+
</script>
|
|
298
|
+
|
|
299
|
+
<VenueCalendar
|
|
300
|
+
showViewOptions={[
|
|
301
|
+
{ id: 0, text: "List view", icon: List },
|
|
302
|
+
{ id: 1, text: "Gallery view", icon: Grid },
|
|
303
|
+
{ id: 2, text: "Calendar view", icon: Calendar }
|
|
304
|
+
]}
|
|
305
|
+
showMonthSwitcher={true}
|
|
306
|
+
events={[]}
|
|
307
|
+
{currentMonth}
|
|
308
|
+
{currentYear}
|
|
309
|
+
handleNext={handleNext}
|
|
310
|
+
handlePrev={handlePrev}
|
|
311
|
+
on:eventClick={(e) => console.log('Event clicked:', e.detail)}
|
|
312
|
+
/>
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Angular
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import { Component, OnInit, OnDestroy, ElementRef, ViewChild } from '@angular/core';
|
|
319
|
+
import { initVenueCalendar } from '@getmicdrop/venue-calendar';
|
|
320
|
+
|
|
321
|
+
@Component({
|
|
322
|
+
selector: 'app-venue-calendar',
|
|
323
|
+
template: '<div #calendarContainer></div>',
|
|
324
|
+
})
|
|
325
|
+
export class VenueCalendarComponent implements OnInit, OnDestroy {
|
|
326
|
+
@ViewChild('calendarContainer', { static: true }) calendarContainer!: ElementRef;
|
|
327
|
+
private calendarInstance: any;
|
|
328
|
+
|
|
329
|
+
ngOnInit() {
|
|
330
|
+
this.calendarInstance = initVenueCalendar({
|
|
331
|
+
target: this.calendarContainer.nativeElement,
|
|
332
|
+
venueId: 'your-venue-id',
|
|
333
|
+
view: 'calendar',
|
|
334
|
+
events: [],
|
|
335
|
+
showViewOptions: true,
|
|
336
|
+
showMonthSwitcher: true,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
ngOnDestroy() {
|
|
341
|
+
if (this.calendarInstance && this.calendarInstance.$destroy) {
|
|
342
|
+
this.calendarInstance.$destroy();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Configuration Options
|
|
349
|
+
|
|
350
|
+
### Data Attributes (for auto-mount)
|
|
351
|
+
|
|
352
|
+
| Attribute | Type | Default | Description |
|
|
353
|
+
|-----------|------|---------|-------------|
|
|
354
|
+
| `data-venue-id` | string | `''` | The venue ID to fetch events for |
|
|
355
|
+
| `data-view` | string | `'calendar'` | Initial view: `'list'`, `'gallery'`, or `'calendar'` |
|
|
356
|
+
| `data-show-view-options` | boolean | `true` | Show view switcher buttons |
|
|
357
|
+
| `data-show-month-switcher` | boolean | `true` | Show month navigation controls |
|
|
358
|
+
|
|
359
|
+
### JavaScript API Options
|
|
360
|
+
|
|
361
|
+
```javascript
|
|
362
|
+
initVenueCalendar({
|
|
363
|
+
target: '.my-calendar', // CSS selector or HTMLElement (required)
|
|
364
|
+
venueId: 'venue-123', // Venue ID (optional)
|
|
365
|
+
view: 'calendar', // 'list', 'gallery', or 'calendar' (default: 'calendar')
|
|
366
|
+
events: [], // Array of event objects (default: [])
|
|
367
|
+
showViewOptions: true, // Show view switcher (default: true)
|
|
368
|
+
showMonthSwitcher: true, // Show month navigation (default: true)
|
|
369
|
+
});
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Event Object Structure
|
|
373
|
+
|
|
374
|
+
```javascript
|
|
375
|
+
{
|
|
376
|
+
id: 'event-123',
|
|
377
|
+
name: 'Comedy Night',
|
|
378
|
+
date: '2024-10-25T20:00:00Z',
|
|
379
|
+
image: 'https://example.com/image.jpg',
|
|
380
|
+
status: 'On Sale',
|
|
381
|
+
timeline: '8:00 PM - 10:00 PM',
|
|
382
|
+
// ... other fields
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## Views
|
|
387
|
+
|
|
388
|
+
### Calendar View
|
|
389
|
+
The default view showing events in a monthly calendar grid. Perfect for venues with regular shows.
|
|
390
|
+
|
|
391
|
+
### List View
|
|
392
|
+
A vertical list layout showing all upcoming events with details. Great for mobile experiences.
|
|
393
|
+
|
|
394
|
+
### Gallery View
|
|
395
|
+
A grid layout displaying event posters in a gallery format. Ideal for showcasing event imagery.
|
|
396
|
+
|
|
397
|
+
## WordPress Integration
|
|
398
|
+
|
|
399
|
+
For WordPress sites, you can add this to your page/post HTML:
|
|
400
|
+
|
|
401
|
+
```html
|
|
402
|
+
<div class="micdrop-calendar-container"
|
|
403
|
+
data-venue-id="your-venue-id"
|
|
404
|
+
data-view="calendar">
|
|
405
|
+
</div>
|
|
406
|
+
|
|
407
|
+
<script src="https://cdn.jsdelivr.net/npm/@getmicdrop/venue-calendar/dist/venue-calendar.iife.js"></script>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
Or add the script to your theme's footer and use the div anywhere in your content.
|
|
411
|
+
|
|
412
|
+
## Styling
|
|
413
|
+
|
|
414
|
+
The calendar comes with built-in styles using Tailwind CSS. If you need to customize the appearance, you can override the CSS classes or add your own styles.
|
|
415
|
+
|
|
416
|
+
```css
|
|
417
|
+
/* Example: Custom styling */
|
|
418
|
+
.micdrop-calendar-container {
|
|
419
|
+
max-width: 1200px;
|
|
420
|
+
margin: 0 auto;
|
|
421
|
+
padding: 20px;
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
## Theming
|
|
426
|
+
|
|
427
|
+
The calendar supports comprehensive theming via CSS custom properties and JavaScript utilities.
|
|
428
|
+
|
|
429
|
+
### Using CSS Custom Properties
|
|
430
|
+
|
|
431
|
+
Override the default theme by setting CSS custom properties:
|
|
432
|
+
|
|
433
|
+
```css
|
|
434
|
+
/* Custom brand colors */
|
|
435
|
+
.micdrop-calendar-container {
|
|
436
|
+
--Brand-Primary: 270 76% 60%; /* Purple */
|
|
437
|
+
--Text-Primary: 0 0% 10%;
|
|
438
|
+
--BG-Primary: 0 0% 100%;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/* Dark mode */
|
|
442
|
+
.dark .micdrop-calendar-container,
|
|
443
|
+
[data-theme="dark"] .micdrop-calendar-container {
|
|
444
|
+
--Brand-Primary: 270 76% 70%;
|
|
445
|
+
--Text-Primary: 0 0% 95%;
|
|
446
|
+
--BG-Primary: 0 0% 10%;
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
### Available CSS Variables
|
|
451
|
+
|
|
452
|
+
| Variable | Description | Default (Light) |
|
|
453
|
+
|----------|-------------|-----------------|
|
|
454
|
+
| `--Brand-Primary` | Primary brand color | `217 91% 60%` (Blue) |
|
|
455
|
+
| `--Text-Primary` | Main text color | `0 0% 0%` |
|
|
456
|
+
| `--Text-Secondary` | Secondary text | `0 0% 40%` |
|
|
457
|
+
| `--BG-Primary` | Main background | `0 0% 100%` |
|
|
458
|
+
| `--BG-Secondary` | Secondary background | `0 0% 98%` |
|
|
459
|
+
| `--Stroke-Primary` | Border colors | `0 0% 80%` |
|
|
460
|
+
| `--Status-OnSale` | "On Sale" badge | `217 91% 60%` |
|
|
461
|
+
| `--Status-SellingFast` | "Selling Fast" badge | `38 92% 50%` |
|
|
462
|
+
| `--Status-SoldOut` | "Sold Out" badge | `0 84% 60%` |
|
|
463
|
+
| `--Today-BG` | Today's date background | `217 91% 97%` |
|
|
464
|
+
| `--Focus-Ring` | Keyboard focus ring | `217 91% 60%` |
|
|
465
|
+
|
|
466
|
+
### Using JavaScript Theme Utilities
|
|
467
|
+
|
|
468
|
+
```javascript
|
|
469
|
+
import { applyTheme, themes, generateThemeCSS } from '@getmicdrop/venue-calendar';
|
|
470
|
+
|
|
471
|
+
// Apply a preset theme
|
|
472
|
+
applyTheme(themes.dark);
|
|
473
|
+
|
|
474
|
+
// Apply to a specific container
|
|
475
|
+
const container = document.querySelector('.micdrop-calendar-container');
|
|
476
|
+
applyTheme(themes.dark, container);
|
|
477
|
+
|
|
478
|
+
// Create a custom theme
|
|
479
|
+
const myTheme = {
|
|
480
|
+
brandPrimary: '270 76% 60%', // Purple
|
|
481
|
+
textPrimary: '0 0% 10%',
|
|
482
|
+
bgPrimary: '0 0% 100%',
|
|
483
|
+
statusOnSale: '142 71% 45%', // Green for on sale
|
|
484
|
+
};
|
|
485
|
+
applyTheme(myTheme);
|
|
486
|
+
|
|
487
|
+
// Generate CSS string for embedding
|
|
488
|
+
const cssString = generateThemeCSS(myTheme);
|
|
489
|
+
console.log(cssString);
|
|
490
|
+
// Output: :root { --Brand-Primary: 270 76% 60%; ... }
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Preset Themes
|
|
494
|
+
|
|
495
|
+
Three themes are included out of the box:
|
|
496
|
+
|
|
497
|
+
```javascript
|
|
498
|
+
import { themes } from '@getmicdrop/venue-calendar';
|
|
499
|
+
|
|
500
|
+
// Light theme (default)
|
|
501
|
+
applyTheme(themes.light);
|
|
502
|
+
|
|
503
|
+
// Dark theme
|
|
504
|
+
applyTheme(themes.dark);
|
|
505
|
+
|
|
506
|
+
// High contrast (accessibility)
|
|
507
|
+
applyTheme(themes.highContrast);
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### Automatic Dark Mode
|
|
511
|
+
|
|
512
|
+
The calendar automatically respects the user's system preference:
|
|
513
|
+
|
|
514
|
+
```css
|
|
515
|
+
/* Automatically applied when user prefers dark mode */
|
|
516
|
+
@media (prefers-color-scheme: dark) {
|
|
517
|
+
/* Dark theme variables are applied */
|
|
518
|
+
}
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
You can also manually toggle dark mode:
|
|
522
|
+
|
|
523
|
+
```html
|
|
524
|
+
<!-- Add 'dark' class to enable dark theme -->
|
|
525
|
+
<div class="dark">
|
|
526
|
+
<div class="micdrop-calendar-container" data-venue-id="123"></div>
|
|
527
|
+
</div>
|
|
528
|
+
|
|
529
|
+
<!-- Or use data-theme attribute -->
|
|
530
|
+
<div data-theme="dark">
|
|
531
|
+
<div class="micdrop-calendar-container" data-venue-id="123"></div>
|
|
532
|
+
</div>
|
|
533
|
+
```
|
|
534
|
+
|
|
535
|
+
## Browser Support
|
|
536
|
+
|
|
537
|
+
- Chrome (latest)
|
|
538
|
+
- Firefox (latest)
|
|
539
|
+
- Safari (latest)
|
|
540
|
+
- Edge (latest)
|
|
541
|
+
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
542
|
+
|
|
543
|
+
## Development
|
|
544
|
+
|
|
545
|
+
### Building the Package
|
|
546
|
+
|
|
547
|
+
```bash
|
|
548
|
+
# Install dependencies
|
|
549
|
+
npm install
|
|
550
|
+
|
|
551
|
+
# Build the library
|
|
552
|
+
npm run build:lib
|
|
553
|
+
|
|
554
|
+
# Development mode (SvelteKit app)
|
|
555
|
+
npm run dev
|
|
556
|
+
|
|
557
|
+
# Preview production build
|
|
558
|
+
npm run preview
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Project Structure
|
|
562
|
+
|
|
563
|
+
```
|
|
564
|
+
venue-calendar/
|
|
565
|
+
├── src/
|
|
566
|
+
│ ├── components/ # Svelte components
|
|
567
|
+
│ │ ├── Calendar/
|
|
568
|
+
│ │ ├── CalendarContainer/
|
|
569
|
+
│ │ └── Button/
|
|
570
|
+
│ ├── lib/ # Library entry points
|
|
571
|
+
│ │ ├── VenueCalendar.js
|
|
572
|
+
│ │ └── web-component.js
|
|
573
|
+
│ └── routes/ # SvelteKit routes (for dev)
|
|
574
|
+
├── dist/ # Built package (generated)
|
|
575
|
+
├── package.json
|
|
576
|
+
├── vite.config.lib.js # Library build config
|
|
577
|
+
└── README.md
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
## API Reference
|
|
581
|
+
|
|
582
|
+
### `initVenueCalendar(options)`
|
|
583
|
+
|
|
584
|
+
Initialize a calendar instance.
|
|
585
|
+
|
|
586
|
+
**Parameters:**
|
|
587
|
+
- `options` (Object): Configuration options
|
|
588
|
+
|
|
589
|
+
**Returns:** Svelte component instance
|
|
590
|
+
|
|
591
|
+
**Example:**
|
|
592
|
+
```javascript
|
|
593
|
+
const calendar = initVenueCalendar({
|
|
594
|
+
target: '#calendar',
|
|
595
|
+
venueId: 'venue-123',
|
|
596
|
+
view: 'calendar',
|
|
597
|
+
});
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### `autoMount()`
|
|
601
|
+
|
|
602
|
+
Automatically mount calendars to all elements with class `micdrop-calendar-container`.
|
|
603
|
+
|
|
604
|
+
**Example:**
|
|
605
|
+
```javascript
|
|
606
|
+
import { autoMount } from '@getmicdrop/venue-calendar';
|
|
607
|
+
autoMount();
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
### Component Events
|
|
611
|
+
|
|
612
|
+
The calendar component emits events that you can listen to:
|
|
613
|
+
|
|
614
|
+
```javascript
|
|
615
|
+
const calendar = initVenueCalendar({
|
|
616
|
+
target: '#calendar',
|
|
617
|
+
// ... other options
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
// Listen to component events (if using Svelte component directly)
|
|
621
|
+
calendar.$on('eventClick', (event) => {
|
|
622
|
+
console.log('Event clicked:', event.detail);
|
|
623
|
+
});
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
## Troubleshooting
|
|
627
|
+
|
|
628
|
+
### Calendar not appearing
|
|
629
|
+
|
|
630
|
+
1. **Check the script is loaded**: Open browser console and verify no errors
|
|
631
|
+
2. **Verify container exists**: Make sure the target element exists in the DOM
|
|
632
|
+
3. **Check data attributes**: Ensure attributes are correctly formatted with `data-` prefix
|
|
633
|
+
|
|
634
|
+
### Styles not applying
|
|
635
|
+
|
|
636
|
+
1. **CSS not loaded**: The styles are bundled in the JS file and auto-injected
|
|
637
|
+
2. **CSS conflicts**: Check if other styles are overriding the calendar styles
|
|
638
|
+
3. **CDN issues**: Try using a specific version instead of `@latest`
|
|
639
|
+
|
|
640
|
+
### Events not showing
|
|
641
|
+
|
|
642
|
+
1. **Check event data format**: Ensure events match the expected structure
|
|
643
|
+
2. **Date format**: Use ISO 8601 format for dates (`YYYY-MM-DDTHH:mm:ssZ`)
|
|
644
|
+
3. **Venue ID**: Verify the venue ID is correct
|
|
645
|
+
|
|
646
|
+
## Contributing
|
|
647
|
+
|
|
648
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
649
|
+
|
|
650
|
+
## License
|
|
651
|
+
|
|
652
|
+
MIT © MicDrop
|
|
653
|
+
|
|
654
|
+
## Support
|
|
655
|
+
|
|
656
|
+
For issues, questions, or feature requests, please visit:
|
|
657
|
+
https://github.com/get-micdrop/venue-calendar/issues
|
|
658
|
+
|
|
659
|
+
---
|
|
660
|
+
|
|
661
|
+
Made with ❤️ by the MicDrop team
|