diff --git a/packages/block-editor/src/components/block-controls/slot.js b/packages/block-editor/src/components/block-controls/slot.js
index fb2ace0ba17a10..ad800b49ab40db 100644
--- a/packages/block-editor/src/components/block-controls/slot.js
+++ b/packages/block-editor/src/components/block-controls/slot.js
@@ -42,7 +42,7 @@ export default function BlockControlsSlot( { group = 'default', ...props } ) {
return null;
}
- const slot = ;
+ const slot = ;
if ( group === 'default' ) {
return slot;
diff --git a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js
index f27d8bb25e5a87..28126e745f90c4 100644
--- a/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js
+++ b/packages/block-editor/src/components/block-tools/block-contextual-toolbar.js
@@ -9,6 +9,7 @@ import classnames from 'classnames';
import { __ } from '@wordpress/i18n';
import { hasBlockSupport, store as blocksStore } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
+import { ESCAPE } from '@wordpress/keycodes';
/**
* Internal dependencies
@@ -19,40 +20,47 @@ import { store as blockEditorStore } from '../../store';
import { useHasAnyBlockControls } from '../block-controls/use-has-block-controls';
function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) {
- const { blockType, blockEditingMode, hasParents, showParentSelector } =
- useSelect( ( select ) => {
- const {
- getBlockName,
- getBlockParents,
- getSelectedBlockClientIds,
- getBlockEditingMode,
- } = select( blockEditorStore );
- const { getBlockType } = select( blocksStore );
- const selectedBlockClientIds = getSelectedBlockClientIds();
- const _selectedBlockClientId = selectedBlockClientIds[ 0 ];
- const parents = getBlockParents( _selectedBlockClientId );
- const firstParentClientId = parents[ parents.length - 1 ];
- const parentBlockName = getBlockName( firstParentClientId );
- const parentBlockType = getBlockType( parentBlockName );
+ const {
+ blockType,
+ blockEditingMode,
+ lastFocus,
+ hasParents,
+ showParentSelector,
+ } = useSelect( ( select ) => {
+ const {
+ getBlockName,
+ getBlockParents,
+ getLastFocus,
+ getSelectedBlockClientIds,
+ getBlockEditingMode,
+ } = select( blockEditorStore );
+ const { getBlockType } = select( blocksStore );
+ const selectedBlockClientIds = getSelectedBlockClientIds();
+ const _selectedBlockClientId = selectedBlockClientIds[ 0 ];
+ const parents = getBlockParents( _selectedBlockClientId );
+ const firstParentClientId = parents[ parents.length - 1 ];
+ const parentBlockName = getBlockName( firstParentClientId );
+ const parentBlockType = getBlockType( parentBlockName );
- return {
- blockType:
- _selectedBlockClientId &&
- getBlockType( getBlockName( _selectedBlockClientId ) ),
- blockEditingMode: getBlockEditingMode( _selectedBlockClientId ),
- hasParents: parents.length,
- showParentSelector:
- parentBlockType &&
- getBlockEditingMode( firstParentClientId ) === 'default' &&
- hasBlockSupport(
- parentBlockType,
- '__experimentalParentSelector',
- true
- ) &&
- selectedBlockClientIds.length <= 1 &&
- getBlockEditingMode( _selectedBlockClientId ) === 'default',
- };
- }, [] );
+ return {
+ blockType:
+ _selectedBlockClientId &&
+ getBlockType( getBlockName( _selectedBlockClientId ) ),
+ blockEditingMode: getBlockEditingMode( _selectedBlockClientId ),
+ lastFocus: getLastFocus(),
+ hasParents: parents.length,
+ showParentSelector:
+ parentBlockType &&
+ getBlockEditingMode( firstParentClientId ) === 'default' &&
+ hasBlockSupport(
+ parentBlockType,
+ '__experimentalParentSelector',
+ true
+ ) &&
+ selectedBlockClientIds.length <= 1 &&
+ getBlockEditingMode( _selectedBlockClientId ) === 'default',
+ };
+ }, [] );
const isToolbarEnabled =
! blockType ||
@@ -78,6 +86,12 @@ function BlockContextualToolbar( { focusOnMount, isFixed, ...props } ) {
/* translators: accessibility text for the block toolbar */
aria-label={ __( 'Block tools' ) }
variant={ isFixed ? 'unstyled' : undefined }
+ onChildrenKeyDown={ ( event ) => {
+ if ( event.keyCode === ESCAPE && lastFocus?.current ) {
+ event.preventDefault();
+ lastFocus.current.focus();
+ }
+ } }
{ ...props }
>
diff --git a/packages/block-editor/src/components/navigable-toolbar/index.js b/packages/block-editor/src/components/navigable-toolbar/index.js
index d26476a866b7aa..f5826e2797bc06 100644
--- a/packages/block-editor/src/components/navigable-toolbar/index.js
+++ b/packages/block-editor/src/components/navigable-toolbar/index.js
@@ -200,6 +200,7 @@ function NavigableToolbar( {
shouldUseKeyboardFocusShortcut = true,
__experimentalInitialIndex: initialIndex,
__experimentalOnIndexChange: onIndexChange,
+ onChildrenKeyDown,
...props
} ) {
const ref = useRef();
@@ -214,6 +215,35 @@ function NavigableToolbar( {
shouldUseKeyboardFocusShortcut
);
+ useEffect( () => {
+ const navigableToolbarRef = ref.current;
+ const toolbarButtons = navigableToolbarRef.querySelectorAll(
+ '[data-toolbar-item="true"]'
+ );
+
+ if ( onChildrenKeyDown ) {
+ const handleChildrenKeyDown = ( event ) => {
+ onChildrenKeyDown( event );
+ };
+
+ toolbarButtons.forEach( ( toolbarButton ) => {
+ toolbarButton.addEventListener(
+ 'keydown',
+ handleChildrenKeyDown
+ );
+ } );
+
+ return () => {
+ toolbarButtons.forEach( ( toolbarButton ) => {
+ toolbarButton.removeEventListener(
+ 'keydown',
+ handleChildrenKeyDown
+ );
+ } );
+ };
+ }
+ }, [ onChildrenKeyDown, children ] );
+
if ( isAccessibleToolbar ) {
return (