diff options
Diffstat (limited to 'plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js')
-rw-r--r-- | plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js b/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js new file mode 100644 index 00000000..e4d77349 --- /dev/null +++ b/plugins/jetpack/extensions/blocks/tiled-gallery/gallery-image/edit.js @@ -0,0 +1,147 @@ +/** + * External Dependencies + */ +import classnames from 'classnames'; +import { __ } from '@wordpress/i18n'; +import { BACKSPACE, DELETE } from '@wordpress/keycodes'; +import { Component, createRef, Fragment } from '@wordpress/element'; +import { IconButton, Spinner } from '@wordpress/components'; +import { isBlobURL } from '@wordpress/blob'; +import { withSelect } from '@wordpress/data'; + +class GalleryImageEdit extends Component { + img = createRef(); + + onImageClick = () => { + if ( ! this.props.isSelected ) { + this.props.onSelect(); + } + }; + + onImageKeyDown = event => { + if ( + this.img.current === document.activeElement && + this.props.isSelected && + [ BACKSPACE, DELETE ].includes( event.keyCode ) + ) { + this.props.onRemove(); + } + }; + + componentDidUpdate() { + const { alt, height, image, link, url, width } = this.props; + + if ( image ) { + const nextAtts = {}; + + if ( ! alt && image.alt_text ) { + nextAtts.alt = image.alt_text; + } + if ( ! height && image.media_details && image.media_details.height ) { + nextAtts.height = +image.media_details.height; + } + if ( ! link && image.link ) { + nextAtts.link = image.link; + } + if ( ! url && image.source_url ) { + nextAtts.url = image.source_url; + } + if ( ! width && image.media_details && image.media_details.width ) { + nextAtts.width = +image.media_details.width; + } + + if ( Object.keys( nextAtts ).length ) { + this.props.setAttributes( nextAtts ); + } + } + } + + render() { + const { + 'aria-label': ariaLabel, + alt, + height, + id, + imageFilter, + isSelected, + link, + linkTo, + onRemove, + origUrl, + url, + width, + } = this.props; + + let href; + + switch ( linkTo ) { + case 'media': + href = url; + break; + case 'attachment': + href = link; + break; + } + + const isTransient = isBlobURL( origUrl ); + + const img = ( + // Disable reason: Image itself is not meant to be interactive, but should + // direct image selection and unfocus caption fields. + /* eslint-disable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex */ + <Fragment> + <img + alt={ alt } + aria-label={ ariaLabel } + data-height={ height } + data-id={ id } + data-link={ link } + data-url={ origUrl } + data-width={ width } + onClick={ this.onImageClick } + onKeyDown={ this.onImageKeyDown } + ref={ this.img } + src={ isTransient ? undefined : url } + tabIndex="0" + style={ isTransient ? { backgroundImage: `url(${ url })` } : undefined } + /> + { isTransient && <Spinner /> } + </Fragment> + /* eslint-enable jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-noninteractive-tabindex */ + ); + + // Disable reason: Each block can be selected by clicking on it and we should keep the same saved markup + return ( + <figure + className={ classnames( 'tiled-gallery__item', { + 'is-selected': isSelected, + 'is-transient': isTransient, + [ `filter__${ imageFilter }` ]: !! imageFilter, + } ) } + > + { isSelected && ( + <div className="tiled-gallery__item__inline-menu"> + <IconButton + icon="no-alt" + onClick={ onRemove } + className="tiled-gallery__item__remove" + label={ __( 'Remove Image', 'jetpack' ) } + /> + </div> + ) } + { /* Keep the <a> HTML structure, but ensure there is no navigation from edit */ + /* eslint-disable-next-line jsx-a11y/anchor-is-valid */ } + { href ? <a>{ img }</a> : img } + </figure> + ); + } +} + +export default withSelect( ( select, ownProps ) => { + const { getMedia } = select( 'core' ); + const { id } = ownProps; + + return { + image: id ? getMedia( id ) : null, + }; +} )( GalleryImageEdit ); |