@wordpress/fields 0.30.0 → 0.31.0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/components/media-edit/index.tsx"],
4
- "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tDropZone,\n\tIcon,\n\tSpinner,\n\t__experimentalText as Text,\n\t__experimentalTruncate as Truncate,\n\t__experimentalVStack as VStack,\n\tBaseControl,\n\tTooltip,\n\tVisuallyHidden,\n} from '@wordpress/components';\nimport { isBlobURL, getBlobTypeByURL } from '@wordpress/blob';\nimport { store as coreStore, type Attachment } from '@wordpress/core-data';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useCallback, useMemo, useState } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport { archive, audio, video, file, closeSmall } from '@wordpress/icons';\nimport {\n\tMediaUpload,\n\tuploadMedia,\n\tprivateApis as mediaUtilsPrivateApis,\n} from '@wordpress/media-utils';\nimport { store as noticesStore } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport type { MediaEditProps } from '../../types';\n\nconst { MediaUploadModal } = unlock( mediaUtilsPrivateApis );\n\ntype BlobItem = {\n\tid: string;\n\tsource_url: string;\n\tmime_type: string | undefined;\n\talt_text?: string;\n};\n\n/**\n * Conditional Media component that uses MediaUploadModal when experiment is enabled,\n * otherwise falls back to media-utils MediaUpload.\n *\n * @param root0 Component props.\n * @param root0.render Render prop function that receives { open } object.\n * @param root0.multiple Whether to allow multiple media selections.\n * @return The component.\n */\nfunction ConditionalMediaUpload( { render, multiple, ...props }: any ) {\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tif ( ( window as any ).__experimentalDataViewsMediaModal ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ render && render( { open: () => setIsModalOpen( true ) } ) }\n\t\t\t\t{ isModalOpen && (\n\t\t\t\t\t<MediaUploadModal\n\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\tisOpen={ isModalOpen }\n\t\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onClose?.();\n\t\t\t\t\t\t} }\n\t\t\t\t\t\tonSelect={ ( media: any ) => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onSelect?.( media );\n\t\t\t\t\t\t} }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n\t// Fallback to media-utils MediaUpload when experiment is disabled.\n\treturn (\n\t\t<MediaUpload\n\t\t\t{ ...props }\n\t\t\trender={ render }\n\t\t\tmultiple={ multiple ? 'add' : undefined }\n\t\t/>\n\t);\n}\n\nfunction MediaPickerButton( {\n\topen,\n\tchildren,\n\tlabel,\n\tshowTooltip = false,\n\tonFilesDrop,\n\tattachment,\n\tisUploading = false,\n}: {\n\topen: () => void;\n\tchildren: React.ReactNode;\n\tlabel: string;\n\tshowTooltip?: boolean;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tattachment?: MediaEditAttachment;\n\tisUploading?: boolean;\n} ) {\n\tconst isBlob = attachment && isBlobURL( attachment.source_url );\n\tconst mediaPickerButton = (\n\t\t<div\n\t\t\tclassName=\"fields__media-edit-picker-button\"\n\t\t\trole=\"button\"\n\t\t\ttabIndex={ 0 }\n\t\t\tonClick={ () => {\n\t\t\t\tif ( ! isUploading ) {\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\tonKeyDown={ ( event ) => {\n\t\t\t\tif ( isUploading ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( event.key === 'Enter' || event.key === ' ' ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\taria-label={ label }\n\t\t\taria-disabled={ isUploading }\n\t\t>\n\t\t\t{ children }\n\t\t\t{ isBlob && (\n\t\t\t\t<span className=\"fields__media-edit-picker-button-spinner\">\n\t\t\t\t\t<Spinner />\n\t\t\t\t</span>\n\t\t\t) }\n\t\t\t{ ! isUploading && (\n\t\t\t\t<DropZone\n\t\t\t\t\tonFilesDrop={ ( files ) =>\n\t\t\t\t\t\tonFilesDrop( files, attachment?.id as number )\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n\tif ( ! showTooltip ) {\n\t\treturn mediaPickerButton;\n\t}\n\treturn <Tooltip text={ label }>{ mediaPickerButton }</Tooltip>;\n}\n\nconst archiveMimeTypes = [\n\t'application/zip',\n\t'application/x-zip-compressed',\n\t'application/x-rar-compressed',\n\t'application/x-7z-compressed',\n\t'application/x-tar',\n\t'application/x-gzip',\n];\n\nfunction MediaTitle( { attachment }: { attachment: Attachment< 'view' > } ) {\n\treturn (\n\t\t<Truncate className=\"fields__media-edit-filename\">\n\t\t\t{ attachment.title.rendered }\n\t\t</Truncate>\n\t);\n}\n\nfunction MediaEditPlaceholder( props: {\n\topen: () => void;\n\tlabel: string;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tisUploading: boolean;\n} ) {\n\treturn (\n\t\t<MediaPickerButton { ...props }>\n\t\t\t<span className=\"fields__media-edit-placeholder\">\n\t\t\t\t{ props.label }\n\t\t\t</span>\n\t\t</MediaPickerButton>\n\t);\n}\n\nfunction MediaPreview( { attachment }: { attachment: MediaEditAttachment } ) {\n\tconst url = attachment.source_url;\n\tconst mimeType = attachment.mime_type || '';\n\tif ( mimeType.startsWith( 'image' ) ) {\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"fields__media-edit-thumbnail\"\n\t\t\t\talt={ attachment.alt_text || '' }\n\t\t\t\tsrc={ url }\n\t\t\t/>\n\t\t);\n\t} else if ( mimeType.startsWith( 'audio' ) ) {\n\t\treturn <Icon icon={ audio } />;\n\t} else if ( mimeType.startsWith( 'video' ) ) {\n\t\treturn <Icon icon={ video } />;\n\t} else if ( archiveMimeTypes.includes( mimeType ) ) {\n\t\treturn <Icon icon={ archive } />;\n\t}\n\treturn <Icon icon={ file } />;\n}\n\ntype MediaEditAttachment = Attachment< 'view' > | BlobItem;\ninterface MediaEditAttachmentsProps {\n\tallItems: Array< MediaEditAttachment > | null;\n\taddButtonLabel: string;\n\tmultiple?: boolean;\n\tremoveItem: ( itemId: number ) => void;\n\topen: () => void;\n\tonFilesDrop: ( files: File[], attachmentId?: number ) => void;\n\tisUploading: boolean;\n}\n\nfunction ExpandedMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<div\n\t\t\tclassName={ clsx( 'fields__media-edit-expanded', {\n\t\t\t\t'is-multiple': multiple,\n\t\t\t\t'is-single': ! multiple,\n\t\t\t\t'is-empty': ! allItems?.length,\n\t\t\t} ) }\n\t\t>\n\t\t\t{ allItems?.map( ( attachment ) => {\n\t\t\t\tconst hasPreviewImage =\n\t\t\t\t\tattachment.mime_type?.startsWith( 'image' );\n\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\tclassName={ clsx( 'fields__media-edit-expanded-item', {\n\t\t\t\t\t\t\t'has-preview-image': hasPreviewImage,\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-preview\">\n\t\t\t\t\t\t\t\t<VStack\n\t\t\t\t\t\t\t\t\tspacing={ 0 }\n\t\t\t\t\t\t\t\t\talignment=\"center\"\n\t\t\t\t\t\t\t\t\tjustify=\"center\"\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-preview-stack\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ ( ! isBlob || hasPreviewImage ) && (\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t{ ! isBlob &&\n\t\t\t\t\t\t\t\t\t\t( ! hasPreviewImage ? (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-remove\"\n\t\t\t\t\t\t\t\t\ticon={ closeSmall }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id as number );\n\t\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n\nfunction CompactMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<>\n\t\t\t{ !! allItems?.length && (\n\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t{ allItems.map( ( attachment ) => {\n\t\t\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-compact\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-remove\"\n\t\t\t\t\t\t\t\t\ttext={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\ttypeof attachment.id === 'number'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</VStack>\n\t\t\t) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\n/**\n * A media edit control component that provides a media picker UI with upload functionality\n * for selecting WordPress media attachments. Supports both the traditional WordPress media\n * library and the experimental DataViews media modal.\n *\n * This component is intended to be used as the `Edit` property of a field definition when\n * registering fields with `registerEntityField` from `@wordpress/editor`.\n *\n * @template Item - The type of the item being edited.\n *\n * @param {MediaEditProps<Item>} props - The component props.\n * @param {Item} props.data - The item being edited.\n * @param {Object} props.field - The field configuration with getValue and setValue methods.\n * @param {Function} props.onChange - Callback function when the media selection changes.\n * @param {string[]} [props.allowedTypes] - Array of allowed media types. Default `['image']`.\n * @param {boolean} [props.multiple] - Whether to allow multiple media selections. Default `false`.\n * @param {boolean} [props.hideLabelFromVision] - Whether the label should be hidden from vision.\n * @param {boolean} [props.isExpanded] - Whether to render in an expanded form. Default `false`.\n *\n * @return {JSX.Element} The media edit control component.\n *\n * @example\n * ```tsx\n * import { MediaEdit } from '@wordpress/fields';\n * import type { DataFormControlProps } from '@wordpress/dataviews';\n *\n * const featuredImageField = {\n * id: 'featured_media',\n * type: 'media',\n * label: 'Featured Image',\n * Edit: (props: DataFormControlProps<MyPostType>) => (\n * <MediaEdit\n * {...props}\n * allowedTypes={['image']}\n * />\n * ),\n * };\n * ```\n */\nexport default function MediaEdit< Item >( {\n\tdata,\n\tfield,\n\tonChange,\n\thideLabelFromVision,\n\tallowedTypes = [ 'image' ],\n\tmultiple,\n\tisExpanded,\n}: MediaEditProps< Item > ) {\n\tconst value = field.getValue( { item: data } );\n\tconst attachments = useSelect(\n\t\t( select ) => {\n\t\t\tif ( ! value ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst normalizedValue = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst { getEntityRecords } = select( coreStore );\n\t\t\treturn getEntityRecords( 'postType', 'attachment', {\n\t\t\t\tinclude: normalizedValue,\n\t\t\t} ) as Attachment< 'view' >[] | null;\n\t\t},\n\t\t[ value ]\n\t);\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\t// Support one upload action at a time for now.\n\tconst [ replacementId, setReplacementId ] = useState< number >();\n\tconst [ blobs, setBlobs ] = useState< string[] >( [] );\n\tconst onChangeControl = useCallback(\n\t\t( newValue: number | number[] | undefined ) =>\n\t\t\tonChange( field.setValue( { item: data, value: newValue } ) ),\n\t\t[ data, field, onChange ]\n\t);\n\tconst removeItem = ( itemId: number ) => {\n\t\tconst currentIds = Array.isArray( value ) ? value : [ value ];\n\t\tconst newIds = currentIds.filter( ( id ) => id !== itemId );\n\t\tonChangeControl( newIds.length ? newIds : undefined );\n\t};\n\tconst onFilesDrop = useCallback(\n\t\t( files: File[], _replacementId?: number ) => {\n\t\t\tuploadMedia( {\n\t\t\t\tallowedTypes: allowedTypes?.length ? allowedTypes : undefined,\n\t\t\t\tfilesList: files,\n\t\t\t\tonFileChange( uploadedMedia: any[] ) {\n\t\t\t\t\tsetReplacementId( _replacementId );\n\t\t\t\t\tconst { blobItems, uploadedItems } = uploadedMedia.reduce(\n\t\t\t\t\t\t( accumulator, item ) => {\n\t\t\t\t\t\t\tif ( isBlobURL( item.url ) ) {\n\t\t\t\t\t\t\t\taccumulator.blobItems.push( item.url );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\taccumulator.uploadedItems.push( item.id );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn accumulator;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblobItems: [] as string[],\n\t\t\t\t\t\t\tuploadedItems: [] as number[],\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\tsetBlobs( blobItems );\n\t\t\t\t\t// If all uploads are complete reset the replacementId.\n\t\t\t\t\tif ( uploadedItems.length === uploadedMedia.length ) {\n\t\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! uploadedItems.length ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! multiple ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems[ 0 ] );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! value ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst normalizedValue = Array.isArray( value )\n\t\t\t\t\t\t? value\n\t\t\t\t\t\t: [ value ];\n\t\t\t\t\tconst newIds = [\n\t\t\t\t\t\t...( _replacementId\n\t\t\t\t\t\t\t? normalizedValue.filter(\n\t\t\t\t\t\t\t\t\t( id: any ) => id !== _replacementId\n\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t: normalizedValue ),\n\t\t\t\t\t\t...uploadedItems,\n\t\t\t\t\t];\n\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t},\n\t\t\t\tonError( error: Error ) {\n\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\tsetBlobs( [] );\n\t\t\t\t\tcreateErrorNotice( error.message, { type: 'snackbar' } );\n\t\t\t\t},\n\t\t\t\tmultiple: !! multiple,\n\t\t\t} );\n\t\t},\n\t\t[ allowedTypes, value, multiple, createErrorNotice, onChangeControl ]\n\t);\n\tconst addButtonLabel =\n\t\tfield.placeholder ||\n\t\t( multiple ? __( 'Choose files' ) : __( 'Choose file' ) );\n\t// Merge real attachments with any existing blob items that are being uploaded.\n\tconst allItems: Array< MediaEditAttachment > | null = useMemo( () => {\n\t\tif ( ! blobs.length ) {\n\t\t\treturn attachments;\n\t\t}\n\t\tconst items: Array< MediaEditAttachment > = [\n\t\t\t...( attachments || [] ),\n\t\t];\n\t\tconst blobItems = blobs.map( ( url ) => ( {\n\t\t\tid: url,\n\t\t\tsource_url: url,\n\t\t\tmime_type: getBlobTypeByURL( url ),\n\t\t} ) );\n\t\tconst replacementIndex = items.findIndex(\n\t\t\t( a ) => a.id === replacementId\n\t\t);\n\t\t// Place blobs at the replacement index, when files\n\t\t// dropped in existing media item.\n\t\tif ( replacementIndex !== -1 ) {\n\t\t\treturn [\n\t\t\t\t...items.slice( 0, replacementIndex ),\n\t\t\t\t...blobItems,\n\t\t\t\t...items.slice( replacementIndex + 1 ),\n\t\t\t];\n\t\t}\n\t\titems.push( ...blobItems );\n\t\treturn items;\n\t}, [ attachments, replacementId, blobs ] );\n\treturn (\n\t\t<fieldset className=\"fields__media-edit\" data-field-id={ field.id }>\n\t\t\t<ConditionalMediaUpload\n\t\t\t\tonSelect={ ( selectedMedia: any ) => {\n\t\t\t\t\tif ( multiple ) {\n\t\t\t\t\t\tconst newIds = Array.isArray( selectedMedia )\n\t\t\t\t\t\t\t? selectedMedia.map( ( m: any ) => m.id )\n\t\t\t\t\t\t\t: [ selectedMedia.id ];\n\t\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tonChangeControl( selectedMedia.id );\n\t\t\t\t\t}\n\t\t\t\t} }\n\t\t\t\tallowedTypes={ allowedTypes }\n\t\t\t\tvalue={ value }\n\t\t\t\tmultiple={ multiple }\n\t\t\t\ttitle={ field.label }\n\t\t\t\trender={ ( { open }: any ) => {\n\t\t\t\t\tconst AttachmentsComponent = isExpanded\n\t\t\t\t\t\t? ExpandedMediaEditAttachments\n\t\t\t\t\t\t: CompactMediaEditAttachments;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t\t\t{ field.label &&\n\t\t\t\t\t\t\t\t( hideLabelFromVision ? (\n\t\t\t\t\t\t\t\t\t<VisuallyHidden as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t</VisuallyHidden>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<BaseControl.VisualLabel as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t</BaseControl.VisualLabel>\n\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t<AttachmentsComponent\n\t\t\t\t\t\t\t\tallItems={ allItems }\n\t\t\t\t\t\t\t\taddButtonLabel={ addButtonLabel }\n\t\t\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\t\t\tremoveItem={ removeItem }\n\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\tisUploading={ !! blobs.length }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{ field.description && (\n\t\t\t\t\t\t\t\t<Text variant=\"muted\">\n\t\t\t\t\t\t\t\t\t{ field.description }\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t</VStack>\n\t\t\t\t\t);\n\t\t\t\t} }\n\t\t\t/>\n\t\t</fieldset>\n\t);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * External dependencies\n */\nimport clsx from 'clsx';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tButton,\n\tDropZone,\n\tIcon,\n\tSpinner,\n\t__experimentalText as Text,\n\t__experimentalTruncate as Truncate,\n\t__experimentalVStack as VStack,\n\tBaseControl,\n\tTooltip,\n\tVisuallyHidden,\n} from '@wordpress/components';\nimport { isBlobURL, getBlobTypeByURL } from '@wordpress/blob';\nimport { store as coreStore, type Attachment } from '@wordpress/core-data';\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport {\n\tuseCallback,\n\tuseEffect,\n\tuseMemo,\n\tuseRef,\n\tuseState,\n} from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tarchive,\n\taudio,\n\tvideo,\n\tfile,\n\tcloseSmall,\n\terror as errorIcon,\n} from '@wordpress/icons';\nimport {\n\tMediaUpload,\n\tuploadMedia,\n\tprivateApis as mediaUtilsPrivateApis,\n} from '@wordpress/media-utils';\nimport { store as noticesStore } from '@wordpress/notices';\n\n/**\n * Internal dependencies\n */\nimport { unlock } from '../../lock-unlock';\nimport type { MediaEditProps } from '../../types';\n\nconst { MediaUploadModal } = unlock( mediaUtilsPrivateApis );\n\ntype BlobItem = {\n\tid: string;\n\tsource_url: string;\n\tmime_type: string | undefined;\n\talt_text?: string;\n};\n\n/**\n * Conditional Media component that uses MediaUploadModal when experiment is enabled,\n * otherwise falls back to media-utils MediaUpload.\n *\n * @param root0 Component props.\n * @param root0.render Render prop function that receives { open } object.\n * @param root0.multiple Whether to allow multiple media selections.\n * @return The component.\n */\nfunction ConditionalMediaUpload( { render, multiple, ...props }: any ) {\n\tconst [ isModalOpen, setIsModalOpen ] = useState( false );\n\tif ( ( window as any ).__experimentalDataViewsMediaModal ) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t{ render && render( { open: () => setIsModalOpen( true ) } ) }\n\t\t\t\t{ isModalOpen && (\n\t\t\t\t\t<MediaUploadModal\n\t\t\t\t\t\t{ ...props }\n\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\tisOpen={ isModalOpen }\n\t\t\t\t\t\tonClose={ () => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onClose?.();\n\t\t\t\t\t\t} }\n\t\t\t\t\t\tonSelect={ ( media: any ) => {\n\t\t\t\t\t\t\tsetIsModalOpen( false );\n\t\t\t\t\t\t\tprops.onSelect?.( media );\n\t\t\t\t\t\t} }\n\t\t\t\t\t/>\n\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n\t// Fallback to media-utils MediaUpload when experiment is disabled.\n\treturn (\n\t\t<MediaUpload\n\t\t\t{ ...props }\n\t\t\trender={ render }\n\t\t\tmultiple={ multiple ? 'add' : undefined }\n\t\t/>\n\t);\n}\n\nfunction MediaPickerButton( {\n\topen,\n\tchildren,\n\tlabel,\n\tshowTooltip = false,\n\tonFilesDrop,\n\tattachment,\n\tisUploading = false,\n}: {\n\topen: () => void;\n\tchildren: React.ReactNode;\n\tlabel: string;\n\tshowTooltip?: boolean;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tattachment?: MediaEditAttachment;\n\tisUploading?: boolean;\n} ) {\n\tconst isBlob = attachment && isBlobURL( attachment.source_url );\n\tconst mediaPickerButton = (\n\t\t<div\n\t\t\tclassName=\"fields__media-edit-picker-button\"\n\t\t\trole=\"button\"\n\t\t\ttabIndex={ 0 }\n\t\t\tonClick={ () => {\n\t\t\t\tif ( ! isUploading ) {\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\tonKeyDown={ ( event ) => {\n\t\t\t\tif ( isUploading ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( event.key === 'Enter' || event.key === ' ' ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\topen();\n\t\t\t\t}\n\t\t\t} }\n\t\t\taria-label={ label }\n\t\t\taria-disabled={ isUploading }\n\t\t>\n\t\t\t{ children }\n\t\t\t{ isBlob && (\n\t\t\t\t<span className=\"fields__media-edit-picker-button-spinner\">\n\t\t\t\t\t<Spinner />\n\t\t\t\t</span>\n\t\t\t) }\n\t\t\t{ ! isUploading && (\n\t\t\t\t<DropZone\n\t\t\t\t\tonFilesDrop={ ( files ) =>\n\t\t\t\t\t\tonFilesDrop( files, attachment?.id as number )\n\t\t\t\t\t}\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n\tif ( ! showTooltip ) {\n\t\treturn mediaPickerButton;\n\t}\n\treturn <Tooltip text={ label }>{ mediaPickerButton }</Tooltip>;\n}\n\nconst archiveMimeTypes = [\n\t'application/zip',\n\t'application/x-zip-compressed',\n\t'application/x-rar-compressed',\n\t'application/x-7z-compressed',\n\t'application/x-tar',\n\t'application/x-gzip',\n];\n\nfunction MediaTitle( { attachment }: { attachment: Attachment< 'view' > } ) {\n\treturn (\n\t\t<Truncate className=\"fields__media-edit-filename\">\n\t\t\t{ attachment.title.rendered }\n\t\t</Truncate>\n\t);\n}\n\nfunction MediaEditPlaceholder( props: {\n\topen: () => void;\n\tlabel: string;\n\tonFilesDrop: MediaEditAttachmentsProps[ 'onFilesDrop' ];\n\tisUploading: boolean;\n} ) {\n\treturn (\n\t\t<MediaPickerButton { ...props }>\n\t\t\t<span className=\"fields__media-edit-placeholder\">\n\t\t\t\t{ props.label }\n\t\t\t</span>\n\t\t</MediaPickerButton>\n\t);\n}\n\nfunction MediaPreview( { attachment }: { attachment: MediaEditAttachment } ) {\n\tconst url = attachment.source_url;\n\tconst mimeType = attachment.mime_type || '';\n\tif ( mimeType.startsWith( 'image' ) ) {\n\t\treturn (\n\t\t\t<img\n\t\t\t\tclassName=\"fields__media-edit-thumbnail\"\n\t\t\t\talt={ attachment.alt_text || '' }\n\t\t\t\tsrc={ url }\n\t\t\t/>\n\t\t);\n\t} else if ( mimeType.startsWith( 'audio' ) ) {\n\t\treturn <Icon icon={ audio } />;\n\t} else if ( mimeType.startsWith( 'video' ) ) {\n\t\treturn <Icon icon={ video } />;\n\t} else if ( archiveMimeTypes.includes( mimeType ) ) {\n\t\treturn <Icon icon={ archive } />;\n\t}\n\treturn <Icon icon={ file } />;\n}\n\ntype MediaEditAttachment = Attachment< 'view' > | BlobItem;\ninterface MediaEditAttachmentsProps {\n\tallItems: Array< MediaEditAttachment > | null;\n\taddButtonLabel: string;\n\tmultiple?: boolean;\n\tremoveItem: ( itemId: number ) => void;\n\topen: () => void;\n\tonFilesDrop: ( files: File[], attachmentId?: number ) => void;\n\tisUploading: boolean;\n}\n\nfunction ExpandedMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<div\n\t\t\tclassName={ clsx( 'fields__media-edit-expanded', {\n\t\t\t\t'is-multiple': multiple,\n\t\t\t\t'is-single': ! multiple,\n\t\t\t\t'is-empty': ! allItems?.length,\n\t\t\t} ) }\n\t\t>\n\t\t\t{ allItems?.map( ( attachment ) => {\n\t\t\t\tconst hasPreviewImage =\n\t\t\t\t\tattachment.mime_type?.startsWith( 'image' );\n\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\treturn (\n\t\t\t\t\t<div\n\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\tclassName={ clsx( 'fields__media-edit-expanded-item', {\n\t\t\t\t\t\t\t'has-preview-image': hasPreviewImage,\n\t\t\t\t\t\t} ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-preview\">\n\t\t\t\t\t\t\t\t<VStack\n\t\t\t\t\t\t\t\t\tspacing={ 0 }\n\t\t\t\t\t\t\t\t\talignment=\"center\"\n\t\t\t\t\t\t\t\t\tjustify=\"center\"\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-preview-stack\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{ ( ! isBlob || hasPreviewImage ) && (\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t{ ! isBlob &&\n\t\t\t\t\t\t\t\t\t\t( ! hasPreviewImage ? (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-title\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t<div className=\"fields__media-edit-expanded-overlay\">\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-expanded-remove\"\n\t\t\t\t\t\t\t\t\ticon={ closeSmall }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tsize=\"small\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id as number );\n\t\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</div>\n\t\t\t\t);\n\t\t\t} ) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n\nfunction CompactMediaEditAttachments( {\n\tallItems,\n\taddButtonLabel,\n\tmultiple,\n\tremoveItem,\n\topen,\n\tonFilesDrop,\n\tisUploading,\n}: MediaEditAttachmentsProps ) {\n\treturn (\n\t\t<>\n\t\t\t{ !! allItems?.length && (\n\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t{ allItems.map( ( attachment ) => {\n\t\t\t\t\t\tconst isBlob = isBlobURL( attachment.source_url );\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tkey={ attachment.id }\n\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-compact\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<MediaPickerButton\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tlabel={ __( 'Replace' ) }\n\t\t\t\t\t\t\t\t\tshowTooltip\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t<MediaPreview\n\t\t\t\t\t\t\t\t\t\t\tattachment={ attachment }\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t{ ! isBlob && (\n\t\t\t\t\t\t\t\t\t\t\t<MediaTitle\n\t\t\t\t\t\t\t\t\t\t\t\tattachment={\n\t\t\t\t\t\t\t\t\t\t\t\t\tattachment as Attachment< 'view' >\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t\t\t</>\n\t\t\t\t\t\t\t\t</MediaPickerButton>\n\t\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\t\t__next40pxDefaultSize\n\t\t\t\t\t\t\t\t\tclassName=\"fields__media-edit-remove\"\n\t\t\t\t\t\t\t\t\ttext={ __( 'Remove' ) }\n\t\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t\t\tdisabled={ isUploading }\n\t\t\t\t\t\t\t\t\taccessibleWhenDisabled\n\t\t\t\t\t\t\t\t\tonClick={ (\n\t\t\t\t\t\t\t\t\t\tevent: React.MouseEvent< HTMLButtonElement >\n\t\t\t\t\t\t\t\t\t) => {\n\t\t\t\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\ttypeof attachment.id === 'number'\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tremoveItem( attachment.id );\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t);\n\t\t\t\t\t} ) }\n\t\t\t\t</VStack>\n\t\t\t) }\n\t\t\t{ ( multiple || ! allItems?.length ) && (\n\t\t\t\t<MediaEditPlaceholder\n\t\t\t\t\topen={ open }\n\t\t\t\t\tlabel={ addButtonLabel }\n\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\tisUploading={ isUploading }\n\t\t\t\t/>\n\t\t\t) }\n\t\t</>\n\t);\n}\n\n/**\n * A media edit control component that provides a media picker UI with upload functionality\n * for selecting WordPress media attachments. Supports both the traditional WordPress media\n * library and the experimental DataViews media modal.\n *\n * This component is intended to be used as the `Edit` property of a field definition when\n * registering fields with `registerEntityField` from `@wordpress/editor`.\n *\n * @template Item - The type of the item being edited.\n *\n * @param {MediaEditProps<Item>} props - The component props.\n * @param {Item} props.data - The item being edited.\n * @param {Object} props.field - The field configuration with getValue and setValue methods.\n * @param {Function} props.onChange - Callback function when the media selection changes.\n * @param {string[]} [props.allowedTypes] - Array of allowed media types. Default `['image']`.\n * @param {boolean} [props.multiple] - Whether to allow multiple media selections. Default `false`.\n * @param {boolean} [props.hideLabelFromVision] - Whether the label should be hidden from vision.\n * @param {boolean} [props.isExpanded] - Whether to render in an expanded form. Default `false`.\n *\n * @return {JSX.Element} The media edit control component.\n *\n * @example\n * ```tsx\n * import { MediaEdit } from '@wordpress/fields';\n * import type { DataFormControlProps } from '@wordpress/dataviews';\n *\n * const featuredImageField = {\n * id: 'featured_media',\n * type: 'media',\n * label: 'Featured Image',\n * Edit: (props: DataFormControlProps<MyPostType>) => (\n * <MediaEdit\n * {...props}\n * allowedTypes={['image']}\n * />\n * ),\n * };\n * ```\n */\nexport default function MediaEdit< Item >( {\n\tdata,\n\tfield,\n\tonChange,\n\thideLabelFromVision,\n\tallowedTypes = [ 'image' ],\n\tmultiple,\n\tisExpanded,\n\tvalidity,\n}: MediaEditProps< Item > ) {\n\tconst value = field.getValue( { item: data } );\n\tconst [ isTouched, setIsTouched ] = useState( false );\n\tconst validityTargetRef = useRef< HTMLInputElement >( null );\n\tconst [ customValidity, setCustomValidity ] = useState<\n\t\t| { type: 'valid' | 'validating' | 'invalid'; message?: string }\n\t\t| undefined\n\t>( undefined );\n\t// Listen for invalid event (e.g., form submission, reportValidity())\n\t// to show validation messages even before blur.\n\tuseEffect( () => {\n\t\tconst validityTarget = validityTargetRef.current;\n\t\tconst handler = () => {\n\t\t\tsetIsTouched( true );\n\t\t};\n\t\tvalidityTarget?.addEventListener( 'invalid', handler );\n\t\treturn () => validityTarget?.removeEventListener( 'invalid', handler );\n\t}, [] );\n\tconst attachments = useSelect(\n\t\t( select ) => {\n\t\t\tif ( ! value ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tconst normalizedValue = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst { getEntityRecords } = select( coreStore );\n\t\t\treturn getEntityRecords( 'postType', 'attachment', {\n\t\t\t\tinclude: normalizedValue,\n\t\t\t} ) as Attachment< 'view' >[] | null;\n\t\t},\n\t\t[ value ]\n\t);\n\tconst { createErrorNotice } = useDispatch( noticesStore );\n\t// Support one upload action at a time for now.\n\tconst [ replacementId, setReplacementId ] = useState< number >();\n\tconst [ blobs, setBlobs ] = useState< string[] >( [] );\n\tconst onChangeControl = useCallback(\n\t\t( newValue: number | number[] | undefined ) =>\n\t\t\tonChange( field.setValue( { item: data, value: newValue } ) ),\n\t\t[ data, field, onChange ]\n\t);\n\tconst removeItem = useCallback(\n\t\t( itemId: number ) => {\n\t\t\tconst currentIds = Array.isArray( value ) ? value : [ value ];\n\t\t\tconst newIds = currentIds.filter( ( id ) => id !== itemId );\n\t\t\t// Mark as touched to immediately show any validation error.\n\t\t\tsetIsTouched( true );\n\t\t\tonChangeControl( newIds.length ? newIds : undefined );\n\t\t},\n\t\t[ value, onChangeControl ]\n\t);\n\tconst onFilesDrop = useCallback(\n\t\t( files: File[], _replacementId?: number ) => {\n\t\t\tuploadMedia( {\n\t\t\t\tallowedTypes: allowedTypes?.length ? allowedTypes : undefined,\n\t\t\t\tfilesList: files,\n\t\t\t\tonFileChange( uploadedMedia: any[] ) {\n\t\t\t\t\tsetReplacementId( _replacementId );\n\t\t\t\t\tconst { blobItems, uploadedItems } = uploadedMedia.reduce(\n\t\t\t\t\t\t( accumulator, item ) => {\n\t\t\t\t\t\t\tif ( isBlobURL( item.url ) ) {\n\t\t\t\t\t\t\t\taccumulator.blobItems.push( item.url );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\taccumulator.uploadedItems.push( item.id );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn accumulator;\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tblobItems: [] as string[],\n\t\t\t\t\t\t\tuploadedItems: [] as number[],\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t\tsetBlobs( blobItems );\n\t\t\t\t\t// If all uploads are complete reset the replacementId.\n\t\t\t\t\tif ( uploadedItems.length === uploadedMedia.length ) {\n\t\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! uploadedItems.length ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! multiple ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems[ 0 ] );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif ( ! value ) {\n\t\t\t\t\t\tonChangeControl( uploadedItems );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst normalizedValue = Array.isArray( value )\n\t\t\t\t\t\t? value\n\t\t\t\t\t\t: [ value ];\n\t\t\t\t\tconst newIds = [\n\t\t\t\t\t\t...( _replacementId\n\t\t\t\t\t\t\t? normalizedValue.filter(\n\t\t\t\t\t\t\t\t\t( id: any ) => id !== _replacementId\n\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t: normalizedValue ),\n\t\t\t\t\t\t...uploadedItems,\n\t\t\t\t\t];\n\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t},\n\t\t\t\tonError( error: Error ) {\n\t\t\t\t\tsetReplacementId( undefined );\n\t\t\t\t\tsetBlobs( [] );\n\t\t\t\t\tcreateErrorNotice( error.message, { type: 'snackbar' } );\n\t\t\t\t},\n\t\t\t\tmultiple: !! multiple,\n\t\t\t} );\n\t\t},\n\t\t[ allowedTypes, value, multiple, createErrorNotice, onChangeControl ]\n\t);\n\tconst addButtonLabel =\n\t\tfield.placeholder ||\n\t\t( multiple ? __( 'Choose files' ) : __( 'Choose file' ) );\n\t// Merge real attachments with any existing blob items that are being uploaded.\n\tconst allItems: Array< MediaEditAttachment > | null = useMemo( () => {\n\t\tif ( ! blobs.length ) {\n\t\t\treturn attachments;\n\t\t}\n\t\tconst items: Array< MediaEditAttachment > = [\n\t\t\t...( attachments || [] ),\n\t\t];\n\t\tconst blobItems = blobs.map( ( url ) => ( {\n\t\t\tid: url,\n\t\t\tsource_url: url,\n\t\t\tmime_type: getBlobTypeByURL( url ),\n\t\t} ) );\n\t\tconst replacementIndex = items.findIndex(\n\t\t\t( a ) => a.id === replacementId\n\t\t);\n\t\t// Place blobs at the replacement index, when files\n\t\t// dropped in existing media item.\n\t\tif ( replacementIndex !== -1 ) {\n\t\t\treturn [\n\t\t\t\t...items.slice( 0, replacementIndex ),\n\t\t\t\t...blobItems,\n\t\t\t\t...items.slice( replacementIndex + 1 ),\n\t\t\t];\n\t\t}\n\t\titems.push( ...blobItems );\n\t\treturn items;\n\t}, [ attachments, replacementId, blobs ] );\n\tuseEffect( () => {\n\t\tif ( ! isTouched ) {\n\t\t\treturn;\n\t\t}\n\t\tconst input = validityTargetRef.current;\n\t\tif ( ! input ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( validity ) {\n\t\t\tconst customValidityResult = validity?.custom;\n\t\t\tsetCustomValidity( customValidityResult );\n\n\t\t\t// Set custom validity on hidden input for HTML5 form validation.\n\t\t\tif ( customValidityResult?.type === 'invalid' ) {\n\t\t\t\tinput.setCustomValidity(\n\t\t\t\t\tcustomValidityResult.message || __( 'Invalid' )\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tinput.setCustomValidity( '' ); // Clear validity\n\t\t\t}\n\t\t} else {\n\t\t\t// Clear any previous validation.\n\t\t\tinput.setCustomValidity( '' );\n\t\t\tsetCustomValidity( undefined );\n\t\t}\n\t}, [ isTouched, field.isValid, validity ] );\n\tconst onBlur = useCallback(\n\t\t( event: React.FocusEvent< HTMLElement > ) => {\n\t\t\tif ( isTouched ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\t! event.relatedTarget ||\n\t\t\t\t! event.currentTarget.contains( event.relatedTarget )\n\t\t\t) {\n\t\t\t\tsetIsTouched( true );\n\t\t\t}\n\t\t},\n\t\t[ isTouched ]\n\t);\n\treturn (\n\t\t<div onBlur={ onBlur }>\n\t\t\t<fieldset className=\"fields__media-edit\" data-field-id={ field.id }>\n\t\t\t\t<ConditionalMediaUpload\n\t\t\t\t\tonSelect={ ( selectedMedia: any ) => {\n\t\t\t\t\t\tif ( multiple ) {\n\t\t\t\t\t\t\tconst newIds = Array.isArray( selectedMedia )\n\t\t\t\t\t\t\t\t? selectedMedia.map( ( m: any ) => m.id )\n\t\t\t\t\t\t\t\t: [ selectedMedia.id ];\n\t\t\t\t\t\t\tonChangeControl( newIds );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tonChangeControl( selectedMedia.id );\n\t\t\t\t\t\t}\n\t\t\t\t\t} }\n\t\t\t\t\tallowedTypes={ allowedTypes }\n\t\t\t\t\tvalue={ value }\n\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\ttitle={ field.label }\n\t\t\t\t\trender={ ( { open }: any ) => {\n\t\t\t\t\t\tconst AttachmentsComponent = isExpanded\n\t\t\t\t\t\t\t? ExpandedMediaEditAttachments\n\t\t\t\t\t\t\t: CompactMediaEditAttachments;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<VStack spacing={ 2 }>\n\t\t\t\t\t\t\t\t{ field.label &&\n\t\t\t\t\t\t\t\t\t( hideLabelFromVision ? (\n\t\t\t\t\t\t\t\t\t\t<VisuallyHidden as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t\t</VisuallyHidden>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<BaseControl.VisualLabel as=\"legend\">\n\t\t\t\t\t\t\t\t\t\t\t{ field.label }\n\t\t\t\t\t\t\t\t\t\t</BaseControl.VisualLabel>\n\t\t\t\t\t\t\t\t\t) ) }\n\t\t\t\t\t\t\t\t<AttachmentsComponent\n\t\t\t\t\t\t\t\t\tallItems={ allItems }\n\t\t\t\t\t\t\t\t\taddButtonLabel={ addButtonLabel }\n\t\t\t\t\t\t\t\t\tmultiple={ multiple }\n\t\t\t\t\t\t\t\t\tremoveItem={ removeItem }\n\t\t\t\t\t\t\t\t\topen={ open }\n\t\t\t\t\t\t\t\t\tonFilesDrop={ onFilesDrop }\n\t\t\t\t\t\t\t\t\tisUploading={ !! blobs.length }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t{ field.description && (\n\t\t\t\t\t\t\t\t\t<Text variant=\"muted\">\n\t\t\t\t\t\t\t\t\t\t{ field.description }\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\t</VStack>\n\t\t\t\t\t\t);\n\t\t\t\t\t} }\n\t\t\t\t/>\n\t\t\t</fieldset>\n\t\t\t{ /* Visually hidden text input for validation. */ }\n\t\t\t<VisuallyHidden>\n\t\t\t\t<input\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t\tref={ validityTargetRef }\n\t\t\t\t\tvalue={ value ?? '' }\n\t\t\t\t\ttabIndex={ -1 }\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tonChange={ () => {} }\n\t\t\t\t/>\n\t\t\t</VisuallyHidden>\n\t\t\t{ customValidity && (\n\t\t\t\t<div aria-live=\"polite\">\n\t\t\t\t\t<p\n\t\t\t\t\t\tclassName={ clsx(\n\t\t\t\t\t\t\t'components-validated-control__indicator',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'is-invalid': customValidity.type === 'invalid',\n\t\t\t\t\t\t\t\t'is-valid': customValidity.type === 'valid',\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon\n\t\t\t\t\t\t\tclassName=\"components-validated-control__indicator-icon\"\n\t\t\t\t\t\t\ticon={ errorIcon }\n\t\t\t\t\t\t\tsize={ 16 }\n\t\t\t\t\t\t\tfill=\"currentColor\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ customValidity.message }\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\t\t\t) }\n\t\t</div>\n\t);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -397,35 +397,19 @@ fieldset.fields__media-edit .fields__media-edit-expanded:not(.is-empty) .fields_
397
397
  font-weight: 600;
398
398
  }
399
399
 
400
- .dataviews-view-grid__media .fields-controls__featured-image-image,
401
- .dataviews-view-grid__media .fields-controls__featured-image-placeholder,
402
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-image,
403
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder,
404
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-image,
405
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-placeholder {
400
+ .fields-controls__featured-image-image,
401
+ .fields-controls__featured-image-placeholder {
406
402
  width: 100%;
407
403
  height: 100%;
408
404
  display: block;
409
405
  border-radius: 4px;
410
406
  }
411
- .dataviews-view-grid__media .fields-controls__featured-image-placeholder,
412
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder,
413
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-placeholder {
407
+
408
+ .fields-controls__featured-image-placeholder {
414
409
  box-shadow: none;
415
410
  background: #f0f0f0;
416
411
  }
417
412
 
418
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-image,
419
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder {
420
- width: 32px;
421
- height: 32px;
422
- }
423
-
424
- .dataforms-layouts-panel__field-control .fields-controls__featured-image-image {
425
- width: 16px;
426
- height: 16px;
427
- }
428
-
429
413
  .fields-controls__parent {
430
414
  border: 0;
431
415
  padding: 0;
@@ -397,35 +397,19 @@ fieldset.fields__media-edit .fields__media-edit-expanded:not(.is-empty) .fields_
397
397
  font-weight: 600;
398
398
  }
399
399
 
400
- .dataviews-view-grid__media .fields-controls__featured-image-image,
401
- .dataviews-view-grid__media .fields-controls__featured-image-placeholder,
402
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-image,
403
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder,
404
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-image,
405
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-placeholder {
400
+ .fields-controls__featured-image-image,
401
+ .fields-controls__featured-image-placeholder {
406
402
  width: 100%;
407
403
  height: 100%;
408
404
  display: block;
409
405
  border-radius: 4px;
410
406
  }
411
- .dataviews-view-grid__media .fields-controls__featured-image-placeholder,
412
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder,
413
- .dataviews-view-list__media-wrapper .fields-controls__featured-image-placeholder {
407
+
408
+ .fields-controls__featured-image-placeholder {
414
409
  box-shadow: none;
415
410
  background: #f0f0f0;
416
411
  }
417
412
 
418
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-image,
419
- .dataviews-view-table__cell-content-wrapper.dataviews-column-primary__media .fields-controls__featured-image-placeholder {
420
- width: 32px;
421
- height: 32px;
422
- }
423
-
424
- .dataforms-layouts-panel__field-control .fields-controls__featured-image-image {
425
- width: 16px;
426
- height: 16px;
427
- }
428
-
429
413
  .fields-controls__parent {
430
414
  border: 0;
431
415
  padding: 0;
@@ -38,5 +38,5 @@ import type { MediaEditProps } from '../../types';
38
38
  * };
39
39
  * ```
40
40
  */
41
- export default function MediaEdit<Item>({ data, field, onChange, hideLabelFromVision, allowedTypes, multiple, isExpanded, }: MediaEditProps<Item>): import("react").JSX.Element;
41
+ export default function MediaEdit<Item>({ data, field, onChange, hideLabelFromVision, allowedTypes, multiple, isExpanded, validity, }: MediaEditProps<Item>): import("react").JSX.Element;
42
42
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/media-edit/index.tsx"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAsWlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAE,IAAI,EAAI,EAC1C,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,mBAAmB,EACnB,YAA0B,EAC1B,QAAQ,EACR,UAAU,GACV,EAAE,cAAc,CAAE,IAAI,CAAE,+BA6KxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/media-edit/index.tsx"],"names":[],"mappings":"AAkDA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAsWlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAE,IAAI,EAAI,EAC1C,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,mBAAmB,EACnB,YAA0B,EAC1B,QAAQ,EACR,UAAU,EACV,QAAQ,GACR,EAAE,cAAc,CAAE,IAAI,CAAE,+BA6QxB"}
@@ -138,7 +138,7 @@ export type CoreDataError = {
138
138
  message?: string;
139
139
  code?: string;
140
140
  };
141
- export interface MediaEditProps<Item> extends Pick<DataFormControlProps<Item>, 'data' | 'field' | 'onChange' | 'hideLabelFromVision'> {
141
+ export interface MediaEditProps<Item> extends Pick<DataFormControlProps<Item>, 'data' | 'field' | 'onChange' | 'hideLabelFromVision' | 'validity'> {
142
142
  /**
143
143
  * Array of allowed media types (e.g., ['image', 'video']).
144
144
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/fields",
3
- "version": "0.30.0",
3
+ "version": "0.31.0",
4
4
  "description": "DataViews is a component that provides an API to render datasets using different types of layouts (table, grid, list, etc.).",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -47,30 +47,30 @@
47
47
  "src/**/*.scss"
48
48
  ],
49
49
  "dependencies": {
50
- "@wordpress/api-fetch": "^7.38.0",
51
- "@wordpress/base-styles": "^6.14.0",
52
- "@wordpress/blob": "^4.38.0",
53
- "@wordpress/block-editor": "^15.11.0",
54
- "@wordpress/blocks": "^15.11.0",
55
- "@wordpress/components": "^32.0.0",
56
- "@wordpress/compose": "^7.38.0",
57
- "@wordpress/core-data": "^7.38.0",
58
- "@wordpress/data": "^10.38.0",
59
- "@wordpress/dataviews": "^11.2.0",
60
- "@wordpress/date": "^5.38.0",
61
- "@wordpress/element": "^6.38.0",
62
- "@wordpress/hooks": "^4.38.0",
63
- "@wordpress/html-entities": "^4.38.0",
64
- "@wordpress/i18n": "^6.11.0",
65
- "@wordpress/icons": "^11.5.0",
66
- "@wordpress/media-utils": "^5.38.0",
67
- "@wordpress/notices": "^5.38.0",
68
- "@wordpress/patterns": "^2.38.0",
69
- "@wordpress/primitives": "^4.38.0",
70
- "@wordpress/private-apis": "^1.38.0",
71
- "@wordpress/router": "^1.38.0",
72
- "@wordpress/url": "^4.38.0",
73
- "@wordpress/warning": "^3.38.0",
50
+ "@wordpress/api-fetch": "^7.39.0",
51
+ "@wordpress/base-styles": "^6.15.0",
52
+ "@wordpress/blob": "^4.39.0",
53
+ "@wordpress/block-editor": "^15.12.0",
54
+ "@wordpress/blocks": "^15.12.0",
55
+ "@wordpress/components": "^32.1.0",
56
+ "@wordpress/compose": "^7.39.0",
57
+ "@wordpress/core-data": "^7.39.0",
58
+ "@wordpress/data": "^10.39.0",
59
+ "@wordpress/dataviews": "^11.3.0",
60
+ "@wordpress/date": "^5.39.0",
61
+ "@wordpress/element": "^6.39.0",
62
+ "@wordpress/hooks": "^4.39.0",
63
+ "@wordpress/html-entities": "^4.39.0",
64
+ "@wordpress/i18n": "^6.12.0",
65
+ "@wordpress/icons": "^11.6.0",
66
+ "@wordpress/media-utils": "^5.39.0",
67
+ "@wordpress/notices": "^5.39.0",
68
+ "@wordpress/patterns": "^2.39.0",
69
+ "@wordpress/primitives": "^4.39.0",
70
+ "@wordpress/private-apis": "^1.39.0",
71
+ "@wordpress/router": "^1.39.0",
72
+ "@wordpress/url": "^4.39.0",
73
+ "@wordpress/warning": "^3.39.0",
74
74
  "change-case": "4.1.2",
75
75
  "client-zip": "^2.4.5",
76
76
  "clsx": "2.1.1",
@@ -82,5 +82,5 @@
82
82
  "publishConfig": {
83
83
  "access": "public"
84
84
  },
85
- "gitHead": "50c4c0f51e4797c217946ce42adfaa5eb026f33f"
85
+ "gitHead": "eee1cfb1472f11183e40fb77465a5f13145df7ad"
86
86
  }
@@ -21,9 +21,22 @@ import {
21
21
  import { isBlobURL, getBlobTypeByURL } from '@wordpress/blob';
22
22
  import { store as coreStore, type Attachment } from '@wordpress/core-data';
23
23
  import { useSelect, useDispatch } from '@wordpress/data';
24
- import { useCallback, useMemo, useState } from '@wordpress/element';
24
+ import {
25
+ useCallback,
26
+ useEffect,
27
+ useMemo,
28
+ useRef,
29
+ useState,
30
+ } from '@wordpress/element';
25
31
  import { __ } from '@wordpress/i18n';
26
- import { archive, audio, video, file, closeSmall } from '@wordpress/icons';
32
+ import {
33
+ archive,
34
+ audio,
35
+ video,
36
+ file,
37
+ closeSmall,
38
+ error as errorIcon,
39
+ } from '@wordpress/icons';
27
40
  import {
28
41
  MediaUpload,
29
42
  uploadMedia,
@@ -440,8 +453,25 @@ export default function MediaEdit< Item >( {
440
453
  allowedTypes = [ 'image' ],
441
454
  multiple,
442
455
  isExpanded,
456
+ validity,
443
457
  }: MediaEditProps< Item > ) {
444
458
  const value = field.getValue( { item: data } );
459
+ const [ isTouched, setIsTouched ] = useState( false );
460
+ const validityTargetRef = useRef< HTMLInputElement >( null );
461
+ const [ customValidity, setCustomValidity ] = useState<
462
+ | { type: 'valid' | 'validating' | 'invalid'; message?: string }
463
+ | undefined
464
+ >( undefined );
465
+ // Listen for invalid event (e.g., form submission, reportValidity())
466
+ // to show validation messages even before blur.
467
+ useEffect( () => {
468
+ const validityTarget = validityTargetRef.current;
469
+ const handler = () => {
470
+ setIsTouched( true );
471
+ };
472
+ validityTarget?.addEventListener( 'invalid', handler );
473
+ return () => validityTarget?.removeEventListener( 'invalid', handler );
474
+ }, [] );
445
475
  const attachments = useSelect(
446
476
  ( select ) => {
447
477
  if ( ! value ) {
@@ -464,11 +494,16 @@ export default function MediaEdit< Item >( {
464
494
  onChange( field.setValue( { item: data, value: newValue } ) ),
465
495
  [ data, field, onChange ]
466
496
  );
467
- const removeItem = ( itemId: number ) => {
468
- const currentIds = Array.isArray( value ) ? value : [ value ];
469
- const newIds = currentIds.filter( ( id ) => id !== itemId );
470
- onChangeControl( newIds.length ? newIds : undefined );
471
- };
497
+ const removeItem = useCallback(
498
+ ( itemId: number ) => {
499
+ const currentIds = Array.isArray( value ) ? value : [ value ];
500
+ const newIds = currentIds.filter( ( id ) => id !== itemId );
501
+ // Mark as touched to immediately show any validation error.
502
+ setIsTouched( true );
503
+ onChangeControl( newIds.length ? newIds : undefined );
504
+ },
505
+ [ value, onChangeControl ]
506
+ );
472
507
  const onFilesDrop = useCallback(
473
508
  ( files: File[], _replacementId?: number ) => {
474
509
  uploadMedia( {
@@ -560,57 +595,132 @@ export default function MediaEdit< Item >( {
560
595
  items.push( ...blobItems );
561
596
  return items;
562
597
  }, [ attachments, replacementId, blobs ] );
598
+ useEffect( () => {
599
+ if ( ! isTouched ) {
600
+ return;
601
+ }
602
+ const input = validityTargetRef.current;
603
+ if ( ! input ) {
604
+ return;
605
+ }
606
+
607
+ if ( validity ) {
608
+ const customValidityResult = validity?.custom;
609
+ setCustomValidity( customValidityResult );
610
+
611
+ // Set custom validity on hidden input for HTML5 form validation.
612
+ if ( customValidityResult?.type === 'invalid' ) {
613
+ input.setCustomValidity(
614
+ customValidityResult.message || __( 'Invalid' )
615
+ );
616
+ } else {
617
+ input.setCustomValidity( '' ); // Clear validity
618
+ }
619
+ } else {
620
+ // Clear any previous validation.
621
+ input.setCustomValidity( '' );
622
+ setCustomValidity( undefined );
623
+ }
624
+ }, [ isTouched, field.isValid, validity ] );
625
+ const onBlur = useCallback(
626
+ ( event: React.FocusEvent< HTMLElement > ) => {
627
+ if ( isTouched ) {
628
+ return;
629
+ }
630
+ if (
631
+ ! event.relatedTarget ||
632
+ ! event.currentTarget.contains( event.relatedTarget )
633
+ ) {
634
+ setIsTouched( true );
635
+ }
636
+ },
637
+ [ isTouched ]
638
+ );
563
639
  return (
564
- <fieldset className="fields__media-edit" data-field-id={ field.id }>
565
- <ConditionalMediaUpload
566
- onSelect={ ( selectedMedia: any ) => {
567
- if ( multiple ) {
568
- const newIds = Array.isArray( selectedMedia )
569
- ? selectedMedia.map( ( m: any ) => m.id )
570
- : [ selectedMedia.id ];
571
- onChangeControl( newIds );
572
- } else {
573
- onChangeControl( selectedMedia.id );
574
- }
575
- } }
576
- allowedTypes={ allowedTypes }
577
- value={ value }
578
- multiple={ multiple }
579
- title={ field.label }
580
- render={ ( { open }: any ) => {
581
- const AttachmentsComponent = isExpanded
582
- ? ExpandedMediaEditAttachments
583
- : CompactMediaEditAttachments;
584
- return (
585
- <VStack spacing={ 2 }>
586
- { field.label &&
587
- ( hideLabelFromVision ? (
588
- <VisuallyHidden as="legend">
589
- { field.label }
590
- </VisuallyHidden>
591
- ) : (
592
- <BaseControl.VisualLabel as="legend">
593
- { field.label }
594
- </BaseControl.VisualLabel>
595
- ) ) }
596
- <AttachmentsComponent
597
- allItems={ allItems }
598
- addButtonLabel={ addButtonLabel }
599
- multiple={ multiple }
600
- removeItem={ removeItem }
601
- open={ open }
602
- onFilesDrop={ onFilesDrop }
603
- isUploading={ !! blobs.length }
604
- />
605
- { field.description && (
606
- <Text variant="muted">
607
- { field.description }
608
- </Text>
609
- ) }
610
- </VStack>
611
- );
612
- } }
613
- />
614
- </fieldset>
640
+ <div onBlur={ onBlur }>
641
+ <fieldset className="fields__media-edit" data-field-id={ field.id }>
642
+ <ConditionalMediaUpload
643
+ onSelect={ ( selectedMedia: any ) => {
644
+ if ( multiple ) {
645
+ const newIds = Array.isArray( selectedMedia )
646
+ ? selectedMedia.map( ( m: any ) => m.id )
647
+ : [ selectedMedia.id ];
648
+ onChangeControl( newIds );
649
+ } else {
650
+ onChangeControl( selectedMedia.id );
651
+ }
652
+ } }
653
+ allowedTypes={ allowedTypes }
654
+ value={ value }
655
+ multiple={ multiple }
656
+ title={ field.label }
657
+ render={ ( { open }: any ) => {
658
+ const AttachmentsComponent = isExpanded
659
+ ? ExpandedMediaEditAttachments
660
+ : CompactMediaEditAttachments;
661
+ return (
662
+ <VStack spacing={ 2 }>
663
+ { field.label &&
664
+ ( hideLabelFromVision ? (
665
+ <VisuallyHidden as="legend">
666
+ { field.label }
667
+ </VisuallyHidden>
668
+ ) : (
669
+ <BaseControl.VisualLabel as="legend">
670
+ { field.label }
671
+ </BaseControl.VisualLabel>
672
+ ) ) }
673
+ <AttachmentsComponent
674
+ allItems={ allItems }
675
+ addButtonLabel={ addButtonLabel }
676
+ multiple={ multiple }
677
+ removeItem={ removeItem }
678
+ open={ open }
679
+ onFilesDrop={ onFilesDrop }
680
+ isUploading={ !! blobs.length }
681
+ />
682
+ { field.description && (
683
+ <Text variant="muted">
684
+ { field.description }
685
+ </Text>
686
+ ) }
687
+ </VStack>
688
+ );
689
+ } }
690
+ />
691
+ </fieldset>
692
+ { /* Visually hidden text input for validation. */ }
693
+ <VisuallyHidden>
694
+ <input
695
+ type="text"
696
+ ref={ validityTargetRef }
697
+ value={ value ?? '' }
698
+ tabIndex={ -1 }
699
+ aria-hidden="true"
700
+ onChange={ () => {} }
701
+ />
702
+ </VisuallyHidden>
703
+ { customValidity && (
704
+ <div aria-live="polite">
705
+ <p
706
+ className={ clsx(
707
+ 'components-validated-control__indicator',
708
+ {
709
+ 'is-invalid': customValidity.type === 'invalid',
710
+ 'is-valid': customValidity.type === 'valid',
711
+ }
712
+ ) }
713
+ >
714
+ <Icon
715
+ className="components-validated-control__indicator-icon"
716
+ icon={ errorIcon }
717
+ size={ 16 }
718
+ fill="currentColor"
719
+ />
720
+ { customValidity.message }
721
+ </p>
722
+ </div>
723
+ ) }
724
+ </div>
615
725
  );
616
726
  }