/** * Media Picker Component * * WordPress media library integration for selecting images * * @package ThinkRank * @since 1.0.0 */ import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { Button, Flex, FlexItem, __experimentalSpacer as Spacer } from '@wordpress/components'; /** * Media Picker Component */ const MediaPicker = ({ value, onChange, label, help, allowedTypes = ['image'], multiple = false, disabled = false }) => { const [isOpen, setIsOpen] = useState(false); /** * Open WordPress media library */ const openMediaLibrary = () => { if (disabled) return; // Check if wp.media is available if (typeof wp === 'undefined' || typeof wp.media === 'undefined') { console.error('WordPress media library not available'); return; } // Create media frame const frame = wp.media({ title: label || __('Select Media', 'thinkrank'), button: { text: __('Use this media', 'thinkrank') }, multiple: multiple, library: { type: allowedTypes } }); // Handle media selection frame.on('select', () => { const selection = frame.state().get('selection'); if (multiple) { const attachments = selection.map(attachment => { const data = attachment.toJSON(); return { id: data.id, url: data.url, alt: data.alt || '', title: data.title || '', filename: data.filename || '', mime: data.mime || '', width: data.width || 0, height: data.height || 0 }; }); onChange(attachments); } else { const attachment = selection.first().toJSON(); const mediaData = { id: attachment.id, url: attachment.url, alt: attachment.alt || '', title: attachment.title || '', filename: attachment.filename || '', mime: attachment.mime || '', width: attachment.width || 0, height: attachment.height || 0 }; onChange(mediaData.url); } }); // Open the frame frame.open(); }; /** * Remove selected media */ const removeMedia = () => { onChange(multiple ? [] : ''); }; /** * Get media preview */ const getMediaPreview = () => { if (!value) return null; if (multiple && Array.isArray(value)) { return value.map((item, index) => (
{item.alt
)); } // Single media item const mediaUrl = typeof value === 'object' ? value.url : value; if (mediaUrl) { return (
); } return null; }; const hasMedia = multiple ? (Array.isArray(value) && value.length > 0) : !!value; return (
{label && ( )} {hasMedia && (
{getMediaPreview()}
)} {hasMedia && ( )}
{help && (

{help}

)}
); }; export default MediaPicker;