/** * WordPress Media Library Integration * * Provides a clean interface to WordPress's native media modal. * Respects WordPress conventions and user familiarity. */ declare global { interface Window { wp: { media: (options: any) => { on: (event: string, callback: (...args: any[]) => void) => void; open: () => void; state: () => { get: (key: string) => { first: () => { toJSON: () => { url: string; id: number; title: string; filename: string; alt: string; width: number; height: number; }; }; }; }; }; }; } } export interface WPMediaFile { url: string; id: number; title: string; filename: string; alt?: string; width?: number; height?: number; } export interface WPMediaOptions { title?: string; button?: { text: string; }; multiple?: boolean; library?: { type?: string | string[]; }; } /** * Open WordPress Media Modal * * @param options - Configuration for the media modal * @param onSelect - Callback when media is selected * @returns Promise that resolves when modal is closed */ export function openWPMedia( options: WPMediaOptions = {}, onSelect: (file: WPMediaFile) => void ): void { // Check if WordPress media is available if (typeof window.wp === 'undefined' || typeof window.wp.media === 'undefined') { console.error('WordPress media library is not available'); alert('WordPress media library is not loaded. Please refresh the page.'); return; } // Default options const defaultOptions: WPMediaOptions = { title: 'Select or Upload Media', button: { text: 'Use this media', }, multiple: false, }; // Merge options const modalOptions = { ...defaultOptions, ...options }; // Create media frame const frame = window.wp.media(modalOptions); // Handle selection frame.on('select', () => { const attachment = frame.state().get('selection').first().toJSON(); const file: WPMediaFile = { url: attachment.url, id: attachment.id, title: attachment.title || attachment.filename, filename: attachment.filename, alt: attachment.alt || '', width: attachment.width, height: attachment.height, }; onSelect(file); }); // Open modal frame.open(); } /** * Open WordPress Media Modal for Images Only */ export function openWPMediaImage(onSelect: (file: WPMediaFile) => void): void { openWPMedia( { title: 'Select or Upload Image', button: { text: 'Use this image', }, library: { type: 'image', }, }, onSelect ); } /** * Open WordPress Media Modal for Logo/Icon */ export function openWPMediaLogo(onSelect: (file: WPMediaFile) => void): void { openWPMedia( { title: 'Select or Upload Logo', button: { text: 'Use this logo', }, library: { type: ['image/png', 'image/jpeg', 'image/svg+xml', 'image/webp'], }, }, onSelect ); } /** * Open WordPress Media Modal for Favicon */ export function openWPMediaFavicon(onSelect: (file: WPMediaFile) => void): void { openWPMedia( { title: 'Select or Upload Favicon', button: { text: 'Use this favicon', }, library: { type: ['image/png', 'image/x-icon', 'image/vnd.microsoft.icon'], }, }, onSelect ); }