diff --git a/blocks/library/image/block.js b/blocks/library/image/block.js
index eb24f8fe1e351b..c92b98946195bb 100644
--- a/blocks/library/image/block.js
+++ b/blocks/library/image/block.js
@@ -6,6 +6,7 @@ import ResizableBox from 'react-resizable-box';
import {
startCase,
isEmpty,
+ isEqual,
map,
get,
flowRight,
@@ -15,8 +16,8 @@ import {
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
-import { Component } from '@wordpress/element';
-import { mediaUpload } from '@wordpress/utils';
+import { Component, findDOMNode } from '@wordpress/element';
+import { focus as focusutil, mediaUpload } from '@wordpress/utils';
import {
Placeholder,
Dashicon,
@@ -44,11 +45,47 @@ import ImageSize from './image-size';
class ImageBlock extends Component {
constructor() {
super( ...arguments );
+ this.bindNode = this.bindNode.bind( this );
+ this.isActive = this.isActive.bind( this );
+ this.updateFocus = this.updateFocus.bind( this );
this.updateAlt = this.updateAlt.bind( this );
this.updateAlignment = this.updateAlignment.bind( this );
this.onSelectImage = this.onSelectImage.bind( this );
this.onSetHref = this.onSetHref.bind( this );
this.updateImageURL = this.updateImageURL.bind( this );
+
+ this.nodes = {};
+ }
+
+ bindNode( name ) {
+ return ( node ) => this.nodes[ name ] = node;
+ }
+
+ isActive() {
+ const parent = this.nodes.placeholder || this.nodes.figure;
+ if ( parent ) {
+ const parentNode = findDOMNode( parent );
+ if ( parentNode.contains( document.activeElement ) ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ updateFocus() {
+ const { focus } = this.props;
+ const isActive = this.isActive();
+
+ if ( focus && ! isActive ) {
+ const parent = this.nodes.placeholder || this.nodes.figure;
+ if ( parent ) {
+ const tabbables = focusutil.tabbable.find( parent );
+ if ( tabbables.length > 0 ) {
+ const firstTabbable = tabbables[ 0 ];
+ setTimeout( () => firstTabbable.focus(), 0 );
+ }
+ }
+ }
}
onSelectImage( media ) {
@@ -78,6 +115,16 @@ class ImageBlock extends Component {
return get( this.props.image, [ 'data', 'media_details', 'sizes' ], {} );
}
+ componentDidUpdate( prevProps ) {
+ if ( ! isEqual( this.props.focus, prevProps.focus ) ) {
+ this.updateFocus();
+ }
+ }
+
+ componentDidMount() {
+ this.updateFocus();
+ }
+
render() {
const { attributes, setAttributes, focus, setFocus, className, settings } = this.props;
const { url, alt, caption, align, id, href, width, height } = attributes;
@@ -118,31 +165,32 @@ class ImageBlock extends Component {
if ( ! url ) {
return [
controls,
-