diff --git a/packages/block-library/src/audio/edit.js b/packages/block-library/src/audio/edit.js index d222b42ae6a64..19ef9d955baf2 100644 --- a/packages/block-library/src/audio/edit.js +++ b/packages/block-library/src/audio/edit.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -6,7 +11,10 @@ import { Disabled, IconButton, PanelBody, + Path, + Rect, SelectControl, + SVG, ToggleControl, Toolbar, withNotices, @@ -26,10 +34,6 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import icon from './icon'; - -/** - * Internal dependencies - */ import { createUpgradedEmbedBlock } from '../embed/util'; const ALLOWED_MEDIA_TYPES = [ 'audio' ]; @@ -103,7 +107,7 @@ class AudioEdit extends Component { const { setAttributes, isSelected, className, noticeOperations, noticeUI } = this.props; const { editing } = this.state; const switchToEditing = () => { - this.setState( { editing: true } ); + this.setState( { editing: ! this.state.editing } ); }; const onSelectAudio = ( media ) => { if ( ! media || ! media.url ) { @@ -118,22 +122,35 @@ class AudioEdit extends Component { setAttributes( { src: media.url, id: media.id } ); this.setState( { src: media.url, editing: false } ); }; + const editImageIcon = ( ); if ( editing ) { return ( - } - className={ className } - onSelect={ onSelectAudio } - onSelectURL={ this.onSelectURL } - accept="audio/*" - allowedTypes={ ALLOWED_MEDIA_TYPES } - value={ this.props.attributes } - notices={ noticeUI } - onError={ noticeOperations.createErrorNotice } - /> + + + { !! src && ( + + ) } + + } + className={ className } + onCancel={ !! src && switchToEditing } + onSelect={ onSelectAudio } + onSelectURL={ this.onSelectURL } + accept="audio/*" + allowedTypes={ ALLOWED_MEDIA_TYPES } + value={ this.props.attributes } + notices={ noticeUI } + onError={ noticeOperations.createErrorNotice } + /> + ); } - /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/onclick-has-role, jsx-a11y/click-events-have-key-events */ return ( @@ -143,7 +160,7 @@ class AudioEdit extends Component { className="components-icon-button components-toolbar__control" label={ __( 'Edit audio' ) } onClick={ switchToEditing } - icon="edit" + icon={ editImageIcon } /> diff --git a/packages/block-library/src/cover/edit.js b/packages/block-library/src/cover/edit.js index 9fadb5541082b..b031700d95786 100644 --- a/packages/block-library/src/cover/edit.js +++ b/packages/block-library/src/cover/edit.js @@ -12,7 +12,10 @@ import { FocalPointPicker, IconButton, PanelBody, + Path, RangeControl, + Rect, + SVG, ToggleControl, Toolbar, withNotices, @@ -24,7 +27,6 @@ import { InnerBlocks, InspectorControls, MediaPlaceholder, - MediaUpload, MediaUploadCheck, PanelColorSettings, withColors, @@ -42,6 +44,7 @@ import { backgroundImageStyles, dimRatioToClass, } from './shared'; +import { speak } from '@wordpress/a11y'; /** * Module Constants @@ -64,14 +67,27 @@ function retrieveFastAverageColor() { } class CoverEdit extends Component { - constructor() { + constructor( { attributes } ) { super( ...arguments ); this.state = { isDark: false, + isEditing: ! attributes.url, }; this.imageRef = createRef(); this.videoRef = createRef(); this.changeIsDarkIfRequired = this.changeIsDarkIfRequired.bind( this ); + this.toggleIsEditing = this.toggleIsEditing.bind( this ); + } + + toggleIsEditing() { + this.setState( { + isEditing: ! this.state.isEditing, + } ); + if ( this.state.isEditing ) { + speak( __( 'You are now viewing the image in the image block.' ) ); + } else { + speak( __( 'You are now editing the image in the image block.' ) ); + } } componentDidMount() { @@ -83,11 +99,11 @@ class CoverEdit extends Component { } render() { + const { isEditing } = this.state; const { attributes, setAttributes, className, - noticeOperations, noticeUI, overlayColor, setOverlayColor, @@ -97,9 +113,23 @@ class CoverEdit extends Component { dimRatio, focalPoint, hasParallax, - id, url, + id, } = attributes; + + const onSelectUrl = ( newURL ) => { + if ( newURL !== url ) { + this.props.setAttributes( { + url: newURL, + id: undefined, + } ); + } + + this.setState( { + isEditing: false, + } ); + }; + const onSelectMedia = ( media ) => { if ( ! media || ! media.url ) { setAttributes( { url: undefined, id: undefined } ); @@ -134,6 +164,10 @@ class CoverEdit extends Component { {} ), } ); + + this.setState( { + isEditing: false, + } ); }; const toggleParallax = () => { @@ -157,6 +191,7 @@ class CoverEdit extends Component { style.backgroundPosition = `${ focalPoint.x * 100 }% ${ focalPoint.y * 100 }%`; } + const editImageIcon = ( ); const controls = ( @@ -164,18 +199,12 @@ class CoverEdit extends Component { - ( - - ) } + @@ -225,25 +254,36 @@ class CoverEdit extends Component { ); - if ( ! url ) { - const placeholderIcon = ; - const label = __( 'Cover' ); + if ( isEditing || ! url ) { + const labels = { + title: __( 'Cover' ), + instructions: __( 'Drag an image or a video, upload a new one or select a file from your library.' ), + }; + + const mediaPreview = ( !! url && { ); return ( { controls } } className={ className } - labels={ { - title: label, - instructions: __( 'Drag an image or a video, upload a new one or select a file from your library.' ), - } } + labels={ labels } onSelect={ onSelectMedia } + onSelectURL={ onSelectUrl } + onDoubleClick={ this.toggleIsEditing } + onCancel={ !! url && this.toggleIsEditing } + notices={ noticeUI } + onError={ this.onUploadError } accept="image/*,video/*" allowedTypes={ ALLOWED_MEDIA_TYPES } - notices={ noticeUI } - onError={ noticeOperations.createErrorNotice } + value={ { id, url } } + mediaPreview={ backgroundType === IMAGE_BACKGROUND_TYPE && mediaPreview } /> ); diff --git a/packages/block-library/src/embed/edit.js b/packages/block-library/src/embed/edit.js index fcc305d9e8a7c..95481d044499b 100644 --- a/packages/block-library/src/embed/edit.js +++ b/packages/block-library/src/embed/edit.js @@ -129,7 +129,7 @@ export function getEmbedEditComponent( title, icon, responsive = true ) { } switchBackToURLInput() { - this.setState( { editingURL: true } ); + this.setState( { editingURL: ! this.state.editingURL } ); } getResponsiveHelp( checked ) { @@ -166,16 +166,32 @@ export function getEmbedEditComponent( title, icon, responsive = true ) { // No preview, or we can't embed the current URL, or we've clicked the edit button. if ( ! preview || cannotEmbed || editingURL ) { return ( - this.setState( { url: event.target.value } ) } - fallback={ () => fallback( url, this.props.onReplace ) } - tryAgain={ tryAgain } - /> + + + this.setState( { url: event.target.value } ) } + fallback={ () => fallback( url, this.props.onReplace ) } + tryAgain={ tryAgain } + switchBackToURLInput={ this.switchBackToURLInput } + editingURL={ this.state.editingURL } + url={ this.state.url } + /> + ); } @@ -183,6 +199,8 @@ export function getEmbedEditComponent( title, icon, responsive = true ) { { const { blockSupportsResponsive, - showEditButton, themeSupportsResponsive, allowResponsive, getResponsiveHelp, toggleResponsive, switchBackToURLInput, + editingURL, + url, } = props; + const editImageIcon = ( ); return ( - - { showEditButton && ( - - ) } - + { !! url && ( + + ) } { themeSupportsResponsive && blockSupportsResponsive && ( diff --git a/packages/block-library/src/embed/embed-placeholder.js b/packages/block-library/src/embed/embed-placeholder.js index b532d7b1a84a7..644a4b6cb7b07 100644 --- a/packages/block-library/src/embed/embed-placeholder.js +++ b/packages/block-library/src/embed/embed-placeholder.js @@ -4,31 +4,44 @@ import { __, _x } from '@wordpress/i18n'; import { Button, Placeholder } from '@wordpress/components'; import { BlockIcon } from '@wordpress/block-editor'; +import { Fragment } from '@wordpress/element'; const EmbedPlaceholder = ( props ) => { - const { icon, label, value, onSubmit, onChange, cannotEmbed, fallback, tryAgain } = props; + const { icon, label, value, onSubmit, onChange, switchBackToURLInput, cannotEmbed, fallback, tryAgain } = props; return ( } label={ label } className="wp-block-embed"> -
- - - { cannotEmbed && -

- { __( 'Sorry, this content could not be embedded.' ) }
- -

- } -
+ +
+ + + { cannotEmbed && +

+ { __( 'Sorry, this content could not be embedded.' ) }
+ +

+ } +
+ { value &&
+ +
} +
); }; diff --git a/packages/block-library/src/file/edit.js b/packages/block-library/src/file/edit.js index 3ce7211eceb85..095d5d19c4ef1 100644 --- a/packages/block-library/src/file/edit.js +++ b/packages/block-library/src/file/edit.js @@ -14,6 +14,9 @@ import { import { ClipboardButton, IconButton, + Path, + Rect, + SVG, Toolbar, withNotices, } from '@wordpress/components'; @@ -22,8 +25,6 @@ import { withSelect } from '@wordpress/data'; import { BlockControls, BlockIcon, - MediaUpload, - MediaUploadCheck, MediaPlaceholder, RichText, } from '@wordpress/block-editor'; @@ -36,12 +37,15 @@ import { __ } from '@wordpress/i18n'; */ import icon from './icon'; import FileBlockInspector from './inspector'; +import { speak } from '@wordpress/a11y'; class FileEdit extends Component { - constructor() { + constructor( { attributes } ) { super( ...arguments ); this.onSelectFile = this.onSelectFile.bind( this ); + this.onSelectURL = this.onSelectURL.bind( this ); + this.toggleIsEditing = this.toggleIsEditing.bind( this ); this.confirmCopyURL = this.confirmCopyURL.bind( this ); this.resetCopyConfirmation = this.resetCopyConfirmation.bind( this ); this.changeLinkDestinationOption = this.changeLinkDestinationOption.bind( this ); @@ -51,6 +55,7 @@ class FileEdit extends Component { this.state = { hasError: false, showCopyConfirmation: false, + isEditing: ! attributes.href, }; } @@ -92,6 +97,33 @@ class FileEdit extends Component { id: media.id, } ); } + this.toggleIsEditing(); + } + + onSelectURL( newURL ) { + const { href } = this.props.attributes; + + if ( newURL !== href ) { + this.props.setAttributes( { + href: newURL, + id: undefined, + } ); + } + + this.setState( { + isEditing: false, + } ); + } + + toggleIsEditing() { + this.setState( { + isEditing: ! this.state.isEditing, + } ); + if ( this.state.isEditing ) { + speak( __( 'You are now viewing the image in the image block.' ) ); + } else { + speak( __( 'You are now editing the image in the image block.' ) ); + } } confirmCopyURL() { @@ -134,33 +166,58 @@ class FileEdit extends Component { textLinkTarget, showDownloadButton, downloadButtonText, - id, } = attributes; - const { hasError, showCopyConfirmation } = this.state; + const { hasError, showCopyConfirmation, isEditing } = this.state; const attachmentPage = media && media.link; + const editImageIcon = ( ); - if ( ! href || hasError ) { + if ( ! href || isEditing || hasError ) { return ( - } - labels={ { - title: __( 'File' ), - instructions: __( 'Drag a file, upload a new one or select a file from your library.' ), - } } - onSelect={ this.onSelectFile } - notices={ noticeUI } - onError={ noticeOperations.createErrorNotice } - accept="*" - /> + + + + { !! href && ( ) } + + + } + labels={ { + title: __( 'File' ), + instructions: __( 'Drag a file, upload a new one or select a file from your library.' ), + } } + onSelect={ this.onSelectFile } + onSelectURL={ this.onSelectURL } + onCancel={ !! href && this.toggleIsEditing } + notices={ noticeUI } + onError={ noticeOperations.createErrorNotice } + accept="*" + /> + ); } const classes = classnames( className, { 'is-transient': isBlobURL( href ), } ); - return ( + + + + + - - - - ( - - ) } - /> - - -
); @@ -208,6 +259,7 @@ class MediaTextEdit extends Component { /> ) } ); + const editImageIcon = ( ); return ( @@ -222,6 +274,15 @@ class MediaTextEdit extends Component { + + { mediaUrl && } + - - ( - - ) } - /> - - - ); - } - renderImage() { const { mediaAlt, mediaUrl, className, imageFill, focalPoint } = this.props; const backgroundStyles = imageFill ? imageFillStyles( mediaUrl, focalPoint ) : {}; return ( - { this.renderToolbarEditButton() }
{
@@ -71,7 +47,6 @@ class MediaContainer extends Component { const { mediaUrl, className } = this.props; return ( - { this.renderToolbarEditButton() }
@@ -80,60 +55,85 @@ class MediaContainer extends Component { } renderPlaceholder() { - const { onSelectMedia, className } = this.props; + const { + mediaUrl, + mediaId, + mediaType, + toggleIsEditing, + onSelectMedia, + onSelectUrl, + className, + } = this.props; + + const labels = { + title: ! mediaUrl ? __( 'Media' ) : __( 'Edit media' ), + }; + + const mediaPreview = ( !! mediaUrl && { ); + return ( + } - labels={ { - title: __( 'Media area' ), - } } className={ className } + labels={ labels } onSelect={ onSelectMedia } + onSelectURL={ onSelectUrl } + onDoubleClick={ toggleIsEditing } + onCancel={ !! mediaUrl && toggleIsEditing } + onError={ this.onUploadError } accept="image/*,video/*" allowedTypes={ ALLOWED_MEDIA_TYPES } + value={ { mediaId, mediaUrl } } + mediaPreview={ mediaType === 'image' && mediaPreview } /> ); } render() { - const { mediaPosition, mediaUrl, mediaType, mediaWidth, commitWidthChange, onWidthChange } = this.props; - if ( mediaType && mediaUrl ) { - const onResize = ( event, direction, elt ) => { - onWidthChange( parseInt( elt.style.width ) ); - }; - const onResizeStop = ( event, direction, elt ) => { - commitWidthChange( parseInt( elt.style.width ) ); - }; - const enablePositions = { - right: mediaPosition === 'left', - left: mediaPosition === 'right', - }; + const { isEditing, mediaPosition, mediaType, mediaWidth, commitWidthChange, onWidthChange } = this.props; + if ( isEditing ) { + return this.renderPlaceholder(); + } + const onResize = ( event, direction, elt ) => { + onWidthChange( parseInt( elt.style.width ) ); + }; + const onResizeStop = ( event, direction, elt ) => { + commitWidthChange( parseInt( elt.style.width ) ); + }; + const enablePositions = { + right: mediaPosition === 'left', + left: mediaPosition === 'right', + }; - let mediaElement = null; - switch ( mediaType ) { - case 'image': - mediaElement = this.renderImage(); - break; - case 'video': - mediaElement = this.renderVideo(); - break; - } - return ( - - { mediaElement } - - ); + let mediaElement = null; + switch ( mediaType ) { + case 'image': + mediaElement = this.renderImage(); + break; + case 'video': + mediaElement = this.renderVideo(); + break; } - return this.renderPlaceholder(); + return ( + + { mediaElement } + + ); } } diff --git a/packages/block-library/src/video/edit.js b/packages/block-library/src/video/edit.js index 35532afe073cc..a38de03ca1721 100644 --- a/packages/block-library/src/video/edit.js +++ b/packages/block-library/src/video/edit.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -8,7 +13,10 @@ import { Disabled, IconButton, PanelBody, + Path, + Rect, SelectControl, + SVG, ToggleControl, Toolbar, withNotices, @@ -148,7 +156,7 @@ class VideoEdit extends Component { } = this.props; const { editing } = this.state; const switchToEditing = () => { - this.setState( { editing: true } ); + this.setState( { editing: ! this.state.editing } ); }; const onSelectVideo = ( media ) => { if ( ! media || ! media.url ) { @@ -164,19 +172,35 @@ class VideoEdit extends Component { this.setState( { src: media.url, editing: false } ); }; + const editImageIcon = ( ); + if ( editing ) { return ( - } - className={ className } - onSelect={ onSelectVideo } - onSelectURL={ this.onSelectURL } - accept="video/*" - allowedTypes={ ALLOWED_MEDIA_TYPES } - value={ this.props.attributes } - notices={ noticeUI } - onError={ noticeOperations.createErrorNotice } - /> + + + { !! src && ( + + ) } + + } + className={ className } + onSelect={ onSelectVideo } + onSelectURL={ this.onSelectURL } + onCancel={ !! src && switchToEditing } + accept="video/*" + allowedTypes={ ALLOWED_MEDIA_TYPES } + value={ this.props.attributes } + notices={ noticeUI } + onError={ noticeOperations.createErrorNotice } + /> + ); } const videoPosterDescription = `video-block__poster-image-description-${ instanceId }`; @@ -190,7 +214,7 @@ class VideoEdit extends Component { className="components-icon-button components-toolbar__control" label={ __( 'Edit video' ) } onClick={ switchToEditing } - icon="edit" + icon={ editImageIcon } />
diff --git a/packages/components/src/placeholder/style.scss b/packages/components/src/placeholder/style.scss index 63938e69498e9..839c047bbc838 100644 --- a/packages/components/src/placeholder/style.scss +++ b/packages/components/src/placeholder/style.scss @@ -30,6 +30,7 @@ justify-content: center; font-weight: 600; margin-bottom: 1em; + margin-top: 1em; .dashicon, .block-editor-block-icon {