diff --git a/assets/stylesheets/_z-index.scss b/assets/stylesheets/_z-index.scss index b9cd8c4032e0a..bcb054a4ea41b 100644 --- a/assets/stylesheets/_z-index.scss +++ b/assets/stylesheets/_z-index.scss @@ -29,6 +29,8 @@ $z-layers: ( ".edit-post-header": 30, ".block-library-button__inline-link .editor-url-input__suggestions": 6, // URL suggestions for button block above sibling inserter ".block-library-image__resize-handlers": 1, // Resize handlers above sibling inserter + ".wp-block-cover.has-background-dim::before": 1, // Overlay area inside block cover need to be higher than the video background. + ".wp-block-cover__video-background": 0, // Video background inside cover block. // Side UI active buttons ".editor-block-mover__control": 1, diff --git a/packages/block-library/src/cover-image/editor.scss b/packages/block-library/src/cover/editor.scss similarity index 93% rename from packages/block-library/src/cover-image/editor.scss rename to packages/block-library/src/cover/editor.scss index bc55badc130be..e69a8080342b1 100644 --- a/packages/block-library/src/cover-image/editor.scss +++ b/packages/block-library/src/cover/editor.scss @@ -1,4 +1,5 @@ -.wp-block-cover-image { +.wp-block-cover-image, +.wp-block-cover { .editor-rich-text__tinymce[data-is-empty="true"]::before { position: inherit; } diff --git a/packages/block-library/src/cover-image/index.js b/packages/block-library/src/cover/index.js similarity index 61% rename from packages/block-library/src/cover-image/index.js rename to packages/block-library/src/cover/index.js index 2d06ec2112283..9d9ef6f0f1c5e 100644 --- a/packages/block-library/src/cover-image/index.js +++ b/packages/block-library/src/cover/index.js @@ -58,16 +58,22 @@ const blockAttributes = { customOverlayColor: { type: 'string', }, + backgroundType: { + type: 'string', + default: 'image', + }, }; -export const name = 'core/cover-image'; +export const name = 'core/cover'; -const ALLOWED_MEDIA_TYPES = [ 'image' ]; +const ALLOWED_MEDIA_TYPES = [ 'image', 'video' ]; +const IMAGE_BACKGROUND_TYPE = 'image'; +const VIDEO_BACKGROUND_TYPE = 'video'; export const settings = { - title: __( 'Cover Image' ), + title: __( 'Cover' ), - description: __( 'Add a full-width image, and layer text over it — great for headers.' ), + description: __( 'Add a full-width image or video, and layer text over it — great for headers.' ), icon: , @@ -81,14 +87,14 @@ export const settings = { type: 'block', blocks: [ 'core/heading' ], transform: ( { content } ) => ( - createBlock( 'core/cover-image', { title: content } ) + createBlock( 'core/cover', { title: content } ) ), }, { type: 'block', blocks: [ 'core/image' ], transform: ( { caption, url, align, id } ) => ( - createBlock( 'core/cover-image', { + createBlock( 'core/cover', { title: caption, url, align, @@ -96,6 +102,19 @@ export const settings = { } ) ), }, + { + type: 'block', + blocks: [ 'core/video' ], + transform: ( { caption, src, align, id } ) => ( + createBlock( 'core/cover', { + title: caption, + url: src, + align, + id, + backgroundType: VIDEO_BACKGROUND_TYPE, + } ) + ), + }, ], to: [ { @@ -108,6 +127,9 @@ export const settings = { { type: 'block', blocks: [ 'core/image' ], + isMatch: ( { backgroundType, url } ) => { + return ! url || backgroundType === IMAGE_BACKGROUND_TYPE; + }, transform: ( { title, url, align, id } ) => ( createBlock( 'core/image', { caption: title, @@ -117,6 +139,21 @@ export const settings = { } ) ), }, + { + type: 'block', + blocks: [ 'core/video' ], + isMatch: ( { backgroundType, url } ) => { + return ! url || backgroundType === VIDEO_BACKGROUND_TYPE; + }, + transform: ( { title, url, align, id } ) => ( + createBlock( 'core/video', { + caption: title, + src: url, + id, + align, + } ) + ), + }, ], }, @@ -132,21 +169,57 @@ export const settings = { withNotices, ] )( ( { attributes, setAttributes, isSelected, className, noticeOperations, noticeUI, overlayColor, setOverlayColor } ) => { - const { url, title, align, contentAlign, id, hasParallax, dimRatio } = attributes; + const { + align, + backgroundType, + contentAlign, + dimRatio, + hasParallax, + id, + title, + url, + } = attributes; const updateAlignment = ( nextAlign ) => setAttributes( { align: nextAlign } ); - const onSelectImage = ( media ) => { + const onSelectMedia = ( media ) => { if ( ! media || ! media.url ) { setAttributes( { url: undefined, id: undefined } ); return; } - setAttributes( { url: media.url, id: media.id } ); + let mediaType; + // for media selections originated from a file upload. + if ( media.media_type ) { + if ( media.media_type === IMAGE_BACKGROUND_TYPE ) { + mediaType = IMAGE_BACKGROUND_TYPE; + } else { + // only images and videos are accepted so if the media_type is not an image we can assume it is a video. + // Videos contain the media type of 'file' in the object returned from the rest api. + mediaType = VIDEO_BACKGROUND_TYPE; + } + } else { // for media selections originated from existing files in the media library. + if ( + media.type !== IMAGE_BACKGROUND_TYPE && + media.type !== VIDEO_BACKGROUND_TYPE + ) { + return; + } + mediaType = media.type; + } + setAttributes( { + url: media.url, + id: media.id, + backgroundType: mediaType, + } ); }; const toggleParallax = () => setAttributes( { hasParallax: ! hasParallax } ); const setDimRatio = ( ratio ) => setAttributes( { dimRatio: ratio } ); const setTitle = ( newTitle ) => setAttributes( { title: newTitle } ); const style = { - ...backgroundImageStyles( url ), + ...( + backgroundType === IMAGE_BACKGROUND_TYPE ? + backgroundImageStyles( url ) : + {} + ), backgroundColor: overlayColor.color, }; @@ -177,13 +250,13 @@ export const settings = { /> ( @@ -195,12 +268,14 @@ export const settings = { { !! url && ( - - + + { IMAGE_BACKGROUND_TYPE === backgroundType && ( + + ) } - ) : __( 'Cover Image' ); + ) : __( 'Cover' ); return ( @@ -245,10 +320,11 @@ export const settings = { className={ className } labels={ { title: label, - name: __( 'an image' ), + /* translators: Fragment of the sentence: "Drag %s, upload a new one or select a file from your library." */ + name: __( 'an image or a video' ), } } - onSelect={ onSelectImage } - accept="image/*" + onSelect={ onSelectMedia } + accept="image/*,video/*" allowedTypes={ ALLOWED_MEDIA_TYPES } notices={ noticeUI } onError={ noticeOperations.createErrorNotice } @@ -265,10 +341,19 @@ export const settings = { style={ style } className={ classes } > + { VIDEO_BACKGROUND_TYPE === backgroundType && ( +