@getmicdrop/venue-calendar 4.0.11 → 4.0.12

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