forked from
smokesignal.events/smokesignal
The smokesignal.events web application
1/**
2 * Cropper Feature - Lazy Loading
3 *
4 * Provides lazy loading for Cropper.js, used for image cropping
5 * in the event creation form.
6 */
7
8import type Cropper from 'cropperjs'
9
10// Track loading state to avoid duplicate loads
11let loadPromise: Promise<typeof Cropper> | null = null
12
13/**
14 * Lazy load Cropper.js and its CSS.
15 * Returns the Cropper constructor.
16 */
17export async function loadCropper(): Promise<typeof Cropper> {
18 if (loadPromise) {
19 return loadPromise
20 }
21
22 loadPromise = (async () => {
23 // Import Cropper.js and its CSS
24 const [CropperModule] = await Promise.all([
25 import('cropperjs'),
26 import('cropperjs/dist/cropper.css'),
27 ])
28
29 const CropperClass = CropperModule.default
30
31 // Expose globally for inline scripts in templates
32 ;(window as Window & { Cropper?: typeof Cropper }).Cropper = CropperClass
33
34 return CropperClass
35 })()
36
37 return loadPromise
38}
39
40/**
41 * Initialize cropper on pages that need it.
42 * Detects the presence of cropper-related elements.
43 */
44export async function initCropper(): Promise<void> {
45 // Check if any cropper-related elements exist
46 const headerCanvas = document.getElementById('headerCanvas')
47 const thumbnailCanvas = document.getElementById('thumbnailCanvas')
48
49 if (!headerCanvas && !thumbnailCanvas) {
50 return
51 }
52
53 // Preload Cropper.js so it's available when user selects an image
54 await loadCropper()
55}
56
57// Export types for consumers
58export type { Cropper }