diff --git a/packages/block-editor/src/components/tool-selector/index.js b/packages/block-editor/src/components/tool-selector/index.js index 14f2427a4eaad..77080f5a3b563 100644 --- a/packages/block-editor/src/components/tool-selector/index.js +++ b/packages/block-editor/src/components/tool-selector/index.js @@ -12,17 +12,8 @@ import { import { __ } from '@wordpress/i18n'; import { useSelect, useDispatch } from '@wordpress/data'; import { forwardRef } from '@wordpress/element'; +import { edit as editIcon } from '@wordpress/icons'; -const editIcon = ( - - - -); const selectIcon = ( ! id && isBlobURL( url ); class GalleryImage extends Component { constructor() { @@ -27,6 +40,11 @@ class GalleryImage extends Component { this.onSelectCaption = this.onSelectCaption.bind( this ); this.onRemoveImage = this.onRemoveImage.bind( this ); this.bindContainer = this.bindContainer.bind( this ); + this.onEdit = this.onEdit.bind( this ); + this.onSelectImageFromLibrary = this.onSelectImageFromLibrary.bind( + this + ); + this.onSelectCustomURL = this.onSelectCustomURL.bind( this ); // The onDeselect prop is used to signal that the GalleryImage component // has lost focus. We want to call it when focus has been lost @@ -39,10 +57,11 @@ class GalleryImage extends Component { // // onBlur / onFocus events are quick operations (<5ms apart in my testing), // so 50ms accounts for 10x lagging while feels responsive to the user. - this.debouncedOnDeselect = debounce( this.props.onDeselect, 50 ); + this.debouncedOnDeselect = debounce( this.onDeselect.bind( this ), 50 ); this.state = { captionSelected: false, + isEditing: false, }; } @@ -86,6 +105,12 @@ class GalleryImage extends Component { } } + onEdit() { + this.setState( { + isEditing: true, + } ); + } + componentDidUpdate( prevProps ) { const { isSelected, @@ -114,6 +139,11 @@ class GalleryImage extends Component { } } + onDeselect() { + this.setState( { isEditing: false } ); + this.props.onDeselect(); + } + /** * Note that, unlike the DOM, all React events bubble, * so this will be called after the onBlur event of any figure's children. @@ -130,6 +160,47 @@ class GalleryImage extends Component { this.debouncedOnDeselect.cancel(); } + onSelectImageFromLibrary( media ) { + const { setAttributes, id, url, alt, caption, sizeSlug } = this.props; + if ( ! media || ! media.url ) { + return; + } + + let mediaAttributes = pickRelevantMediaFiles( media, sizeSlug ); + + // If the current image is temporary but an alt text was meanwhile + // written by the user, make sure the text is not overwritten. + if ( isTemporaryImage( id, url ) ) { + if ( alt ) { + mediaAttributes = omit( mediaAttributes, [ 'alt' ] ); + } + } + + // If a caption text was meanwhile written by the user, + // make sure the text is not overwritten by empty captions. + if ( caption && ! get( mediaAttributes, [ 'caption' ] ) ) { + mediaAttributes = omit( mediaAttributes, [ 'caption' ] ); + } + + setAttributes( mediaAttributes ); + this.setState( { + isEditing: false, + } ); + } + + onSelectCustomURL( newURL ) { + const { setAttributes, url } = this.props; + if ( newURL !== url ) { + setAttributes( { + url: newURL, + id: undefined, + } ); + this.setState( { + isEditing: false, + } ); + } + } + render() { const { url, @@ -147,6 +218,7 @@ class GalleryImage extends Component { setAttributes, 'aria-label': ariaLabel, } = this.props; + const { isEditing } = this.state; let href; @@ -191,12 +263,22 @@ class GalleryImage extends Component { onBlur={ this.onBlur } onFocus={ this.onFocus } > - { href ? { img } : img } -
+ { ! isEditing && ( href ? { img } : img ) } + { isEditing && ( + + ) } +
-
+ + +
- { ( isSelected || caption ) && ( + + { ! isEditing && ( isSelected || caption ) && ( { } caption={ img.caption } aria-label={ ariaLabel } + sizeSlug={ attributes.sizeSlug } /> ); diff --git a/packages/edit-post/src/components/visual-editor/style.scss b/packages/edit-post/src/components/visual-editor/style.scss index ceff380d22aee..a9a261a417eb8 100644 --- a/packages/edit-post/src/components/visual-editor/style.scss +++ b/packages/edit-post/src/components/visual-editor/style.scss @@ -12,7 +12,8 @@ font-size: $default-font-size; padding: 6px 12px; - &.is-tertiary { + &.is-tertiary, + &.has-icon { padding: 6px; } } diff --git a/packages/edit-site/src/components/block-editor/style.scss b/packages/edit-site/src/components/block-editor/style.scss index 38b2c0ad022c8..1b273ae401f32 100644 --- a/packages/edit-site/src/components/block-editor/style.scss +++ b/packages/edit-site/src/components/block-editor/style.scss @@ -20,7 +20,8 @@ font-size: $default-font-size; padding: 6px 12px; - &.is-tertiary { + &.is-tertiary, + &.has-icon { padding: 6px; } } diff --git a/packages/icons/src/index.js b/packages/icons/src/index.js index 754ff493cbcc2..c00ec9067445e 100644 --- a/packages/icons/src/index.js +++ b/packages/icons/src/index.js @@ -48,6 +48,7 @@ export { default as currencyDollar } from './library/currency-dollar'; export { default as currencyEuro } from './library/currency-euro'; export { default as currencyPound } from './library/currency-pound'; export { default as desktop } from './library/desktop'; +export { default as edit } from './library/edit'; export { default as external } from './library/external'; export { default as file } from './library/file'; export { default as flipHorizontal } from './library/flip-horizontal'; diff --git a/packages/icons/src/library/edit.js b/packages/icons/src/library/edit.js new file mode 100644 index 0000000000000..255de560c2b1d --- /dev/null +++ b/packages/icons/src/library/edit.js @@ -0,0 +1,12 @@ +/** + * WordPress dependencies + */ +import { SVG, Path } from '@wordpress/primitives'; + +const edit = ( + + + +); + +export default edit;