@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.
- package/CHANGELOG.md +2 -0
- package/build/components/media-edit/index.cjs +124 -36
- package/build/components/media-edit/index.cjs.map +3 -3
- package/build/types.cjs.map +1 -1
- package/build-module/components/media-edit/index.mjs +139 -38
- package/build-module/components/media-edit/index.mjs.map +2 -2
- package/build-style/style-rtl.css +4 -20
- package/build-style/style.css +4 -20
- package/build-types/components/media-edit/index.d.ts +1 -1
- package/build-types/components/media-edit/index.d.ts.map +1 -1
- package/build-types/types.d.ts +1 -1
- package/build-types/types.d.ts.map +1 -1
- package/package.json +26 -26
- package/src/components/media-edit/index.tsx +168 -58
- package/src/fields/featured-image/style.scss +9 -28
- package/src/types.ts +1 -1
|
@@ -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": ";AAGA,OAAO,UAAU;AAKjB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAsB;AAAA,EACtB,0BAA0B;AAAA,EAC1B,wBAAwB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,WAAW,wBAAwB;AAC5C,SAAS,SAAS,iBAAkC;AACpD,SAAS,WAAW,mBAAmB;AACvC,
|
|
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
|
-
.
|
|
401
|
-
.
|
|
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
|
-
|
|
412
|
-
.
|
|
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;
|
package/build-style/style.css
CHANGED
|
@@ -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
|
-
.
|
|
401
|
-
.
|
|
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
|
-
|
|
412
|
-
.
|
|
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":"
|
|
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"}
|
package/build-types/types.d.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
51
|
-
"@wordpress/base-styles": "^6.
|
|
52
|
-
"@wordpress/blob": "^4.
|
|
53
|
-
"@wordpress/block-editor": "^15.
|
|
54
|
-
"@wordpress/blocks": "^15.
|
|
55
|
-
"@wordpress/components": "^32.
|
|
56
|
-
"@wordpress/compose": "^7.
|
|
57
|
-
"@wordpress/core-data": "^7.
|
|
58
|
-
"@wordpress/data": "^10.
|
|
59
|
-
"@wordpress/dataviews": "^11.
|
|
60
|
-
"@wordpress/date": "^5.
|
|
61
|
-
"@wordpress/element": "^6.
|
|
62
|
-
"@wordpress/hooks": "^4.
|
|
63
|
-
"@wordpress/html-entities": "^4.
|
|
64
|
-
"@wordpress/i18n": "^6.
|
|
65
|
-
"@wordpress/icons": "^11.
|
|
66
|
-
"@wordpress/media-utils": "^5.
|
|
67
|
-
"@wordpress/notices": "^5.
|
|
68
|
-
"@wordpress/patterns": "^2.
|
|
69
|
-
"@wordpress/primitives": "^4.
|
|
70
|
-
"@wordpress/private-apis": "^1.
|
|
71
|
-
"@wordpress/router": "^1.
|
|
72
|
-
"@wordpress/url": "^4.
|
|
73
|
-
"@wordpress/warning": "^3.
|
|
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": "
|
|
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 {
|
|
24
|
+
import {
|
|
25
|
+
useCallback,
|
|
26
|
+
useEffect,
|
|
27
|
+
useMemo,
|
|
28
|
+
useRef,
|
|
29
|
+
useState,
|
|
30
|
+
} from '@wordpress/element';
|
|
25
31
|
import { __ } from '@wordpress/i18n';
|
|
26
|
-
import {
|
|
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 = (
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
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
|
-
<
|
|
565
|
-
<
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
{
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
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
|
}
|