@getmicdrop/venue-calendar 3.8.4 → 4.0.3

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 (92) hide show
  1. package/README.md +700 -661
  2. package/dist/AirbnbSplitMain-BfddFqOQ.js +2201 -0
  3. package/dist/AirbnbSplitMain-BfddFqOQ.js.map +1 -0
  4. package/dist/{CarouselView.legacy-G433jD--.js → CarouselView.legacy-BKXwmB2P.js} +11 -10
  5. package/dist/CarouselView.legacy-BKXwmB2P.js.map +1 -0
  6. package/dist/CartView-iIEjDwFN.js +1667 -0
  7. package/dist/CartView-iIEjDwFN.js.map +1 -0
  8. package/dist/Checkout-Cu0D8mFn.js +743 -0
  9. package/dist/Checkout-Cu0D8mFn.js.map +1 -0
  10. package/dist/{Checkout.legacy-HODJd0ax.js → Checkout.legacy-C6V9HmUZ.js} +374 -359
  11. package/dist/Checkout.legacy-C6V9HmUZ.js.map +1 -0
  12. package/dist/CheckoutMain-B17znLe0.js +1403 -0
  13. package/dist/CheckoutMain-B17znLe0.js.map +1 -0
  14. package/dist/CheckoutTimer-BsI1r6lY.js +34 -0
  15. package/dist/CheckoutTimer-BsI1r6lY.js.map +1 -0
  16. package/dist/CollectionView-CQgKWQHT.js +142 -0
  17. package/dist/CollectionView-CQgKWQHT.js.map +1 -0
  18. package/dist/{CollectionView.legacy-CmNcGUzq.js → CollectionView.legacy-B8SDspBL.js} +25 -24
  19. package/dist/CollectionView.legacy-B8SDspBL.js.map +1 -0
  20. package/dist/EventDetailsView-XXl8aQJ9.js +1187 -0
  21. package/dist/EventDetailsView-XXl8aQJ9.js.map +1 -0
  22. package/dist/{FeaturedView.legacy-9h2qZMOt.js → FeaturedView.legacy-Dse2jnrt.js} +15 -15
  23. package/dist/FeaturedView.legacy-Dse2jnrt.js.map +1 -0
  24. package/dist/GalleryCard-CDaYD8XI.js +92 -0
  25. package/dist/GalleryCard-CDaYD8XI.js.map +1 -0
  26. package/dist/{GalleryView.legacy-DiA_IVST.js → GalleryView.legacy-U_ripo22.js} +18 -17
  27. package/dist/GalleryView.legacy-U_ripo22.js.map +1 -0
  28. package/dist/{GroupedListView.legacy-Bo-kep9X.js → GroupedListView.legacy-BrickaeB.js} +25 -25
  29. package/dist/GroupedListView.legacy-BrickaeB.js.map +1 -0
  30. package/dist/Heading-AFd3o0xt.js +44 -0
  31. package/dist/Heading-AFd3o0xt.js.map +1 -0
  32. package/dist/OrderSummarySkeleton-dDKUH741.js +16 -0
  33. package/dist/OrderSummarySkeleton-dDKUH741.js.map +1 -0
  34. package/dist/SeriesPage-CNoI4R4M.js +56 -0
  35. package/dist/SeriesPage-CNoI4R4M.js.map +1 -0
  36. package/dist/SeriesPage.legacy-Cugebbf0.js +195 -0
  37. package/dist/SeriesPage.legacy-Cugebbf0.js.map +1 -0
  38. package/dist/Success-BQAu7uZn.js +715 -0
  39. package/dist/Success-BQAu7uZn.js.map +1 -0
  40. package/dist/Success.legacy-DSmTsdB_.js +195 -0
  41. package/dist/Success.legacy-DSmTsdB_.js.map +1 -0
  42. package/dist/Text-CXR2fhx6.js +54 -0
  43. package/dist/Text-CXR2fhx6.js.map +1 -0
  44. package/dist/{VenueCalendar-DkyugLs1.js → VenueCalendar-DzTrcN8J.js} +11242 -21624
  45. package/dist/VenueCalendar-DzTrcN8J.js.map +1 -0
  46. package/dist/ViewTicketsEmbed-DOTq6kSz.js +2038 -0
  47. package/dist/ViewTicketsEmbed-DOTq6kSz.js.map +1 -0
  48. package/dist/__SKIP_NAVIGATION__-CJ96TTPE.js +7 -0
  49. package/dist/__SKIP_NAVIGATION__-CJ96TTPE.js.map +1 -0
  50. package/dist/api/api.cjs +1 -1
  51. package/dist/api/api.cjs.map +1 -1
  52. package/dist/api/api.mjs +511 -279
  53. package/dist/api/api.mjs.map +1 -1
  54. package/dist/api/client.d.ts +3 -33
  55. package/dist/api/cta.d.ts +38 -0
  56. package/dist/api/events.d.ts +3 -1
  57. package/dist/api/gift-cards.d.ts +88 -0
  58. package/dist/api/index.d.ts +6 -0
  59. package/dist/api/types.d.ts +353 -349
  60. package/dist/api/waitlist.d.ts +23 -0
  61. package/dist/colors-BZoMuXdh.js.map +1 -1
  62. package/dist/labels-BPzDu-3y.js +1351 -0
  63. package/dist/labels-BPzDu-3y.js.map +1 -0
  64. package/dist/seo/HostSeoController.d.ts +9 -1
  65. package/dist/seo/seo.cjs +1 -1
  66. package/dist/seo/seo.cjs.map +1 -1
  67. package/dist/seo/seo.mjs +53 -50
  68. package/dist/seo/seo.mjs.map +1 -1
  69. package/dist/seo/types.d.ts +137 -136
  70. package/dist/transform-CZI_M7Wk.js +218 -0
  71. package/dist/transform-CZI_M7Wk.js.map +1 -0
  72. package/dist/types/index.d.ts +387 -387
  73. package/dist/venue-calendar.css +1 -1
  74. package/dist/venue-calendar.es.js +36 -28
  75. package/dist/venue-calendar.es.js.map +1 -1
  76. package/dist/venue-calendar.iife.js +43 -43
  77. package/dist/venue-calendar.iife.js.map +1 -1
  78. package/dist/venue-calendar.umd.js +40 -40
  79. package/dist/venue-calendar.umd.js.map +1 -1
  80. package/package.json +44 -6
  81. package/src/lib/theme.js +13 -0
  82. package/dist/CarouselView.legacy-G433jD--.js.map +0 -1
  83. package/dist/Checkout.legacy-HODJd0ax.js.map +0 -1
  84. package/dist/CollectionView.legacy-CmNcGUzq.js.map +0 -1
  85. package/dist/FeaturedView.legacy-9h2qZMOt.js.map +0 -1
  86. package/dist/GalleryView.legacy-DiA_IVST.js.map +0 -1
  87. package/dist/GroupedListView.legacy-Bo-kep9X.js.map +0 -1
  88. package/dist/SeriesPage.legacy-BjDBPDcq.js +0 -190
  89. package/dist/SeriesPage.legacy-BjDBPDcq.js.map +0 -1
  90. package/dist/Success.legacy-D86LAPHq.js +0 -194
  91. package/dist/Success.legacy-D86LAPHq.js.map +0 -1
  92. package/dist/VenueCalendar-DkyugLs1.js.map +0 -1
package/README.md CHANGED
@@ -1,661 +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
- ```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
+ 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