diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md
index 23e48402fb1cbd..3c0d6eca4901f6 100644
--- a/docs/designers-developers/developers/data/data-core-block-editor.md
+++ b/docs/designers-developers/developers/data/data-core-block-editor.md
@@ -733,6 +733,18 @@ _Returns_
- `boolean`: Whether an ancestor of the block is in multi-selection set.
+# **isAutoFocusEnabled**
+
+Returns whether the automatic focus is enabled.
+
+_Parameters_
+
+- _state_ `Object`: Editor state.
+
+_Returns_
+
+- `boolean`: Is automatic focus enabled.
+
# **isBlockHighlighted**
Returns true if the current highlighted block matches the block clientId.
@@ -1255,6 +1267,14 @@ _Parameters_
- _clientId_ `string`: Block client ID.
+# **setAutoFocusEnabled**
+
+Generators that triggers an action used to enable or disable the automatic focus.
+
+_Parameters_
+
+- _isAutoFocusEnabled_ `boolean`: Enable/Disable navigation mode.
+
# **setHasControlledInnerBlocks**
Returns an action object that sets whether the block has controlled innerblocks.
diff --git a/packages/block-editor/src/components/block-list/block-wrapper.js b/packages/block-editor/src/components/block-list/block-wrapper.js
index ec638ee132128d..2fcc4e9b0f43e9 100644
--- a/packages/block-editor/src/components/block-list/block-wrapper.js
+++ b/packages/block-editor/src/components/block-list/block-wrapper.js
@@ -30,6 +30,7 @@ const BlockComponent = forwardRef(
const {
clientId,
rootClientId,
+ isAutoFocusEnabled,
isSelected,
isFirstMultiSelected,
isLastMultiSelected,
@@ -124,10 +125,20 @@ const BlockComponent = forwardRef(
};
useEffect( () => {
- if ( ! isMultiSelecting && ! isNavigationMode && isSelected ) {
+ if (
+ ! isMultiSelecting &&
+ ! isNavigationMode &&
+ isSelected &&
+ isAutoFocusEnabled
+ ) {
focusTabbable();
}
- }, [ isSelected, isMultiSelecting, isNavigationMode ] );
+ }, [
+ isSelected,
+ isMultiSelecting,
+ isNavigationMode,
+ isAutoFocusEnabled,
+ ] );
// Block Reordering animation
const animationStyle = useMovingAnimation(
diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js
index 6e8cb32daff44e..ae806c65db625a 100644
--- a/packages/block-editor/src/components/block-list/block.js
+++ b/packages/block-editor/src/components/block-list/block.js
@@ -64,6 +64,7 @@ function BlockListBlock( {
toggleSelection,
index,
enableAnimation,
+ isAutoFocusEnabled,
isNavigationMode,
isMultiSelecting,
} ) {
@@ -159,6 +160,7 @@ function BlockListBlock( {
const value = {
clientId,
rootClientId,
+ isAutoFocusEnabled,
isSelected,
isFirstMultiSelected,
isLastMultiSelected,
@@ -218,6 +220,7 @@ const applyWithSelect = withSelect(
const {
isBlockSelected,
isAncestorMultiSelected,
+ isAutoFocusEnabled,
isBlockMultiSelected,
isFirstMultiSelectedBlock,
getLastMultiSelectedBlockClientId,
@@ -251,6 +254,7 @@ const applyWithSelect = withSelect(
// Do not add new properties here, use `useSelect` instead to avoid
// leaking new props to the public API (editor.BlockListBlock filter).
return {
+ isAutoFocusEnabled: isAutoFocusEnabled(),
isMultiSelected: isBlockMultiSelected( clientId ),
isPartOfMultiSelection:
isBlockMultiSelected( clientId ) ||
diff --git a/packages/block-editor/src/components/block-navigation/block-contents.js b/packages/block-editor/src/components/block-navigation/block-contents.js
index f7d46f53af80db..5619370929b9aa 100644
--- a/packages/block-editor/src/components/block-navigation/block-contents.js
+++ b/packages/block-editor/src/components/block-navigation/block-contents.js
@@ -21,7 +21,6 @@ const BlockNavigationBlockContents = forwardRef(
return withBlockNavigationSlots ? (
) : (
);
}
diff --git a/packages/block-editor/src/components/block-navigation/block.js b/packages/block-editor/src/components/block-navigation/block.js
index 50b8ad407c6b4a..833e6460ff21fe 100644
--- a/packages/block-editor/src/components/block-navigation/block.js
+++ b/packages/block-editor/src/components/block-navigation/block.js
@@ -8,7 +8,8 @@ import classnames from 'classnames';
*/
import { __experimentalTreeGridCell as TreeGridCell } from '@wordpress/components';
import { moreVertical } from '@wordpress/icons';
-import { useState } from '@wordpress/element';
+import { useState, useEffect, useRef } from '@wordpress/element';
+import { useSelect } from '@wordpress/data';
/**
* Internal dependencies
@@ -34,6 +35,7 @@ export default function BlockNavigationBlock( {
terminatedLevels,
path,
} ) {
+ const ref = useRef();
const [ isHovered, setIsHovered ] = useState( false );
const [ isFocused, setIsFocused ] = useState( false );
const { clientId } = block;
@@ -51,11 +53,34 @@ export default function BlockNavigationBlock( {
__experimentalWithEllipsisMenu: withEllipsisMenu,
__experimentalWithEllipsisMenuMinLevel: ellipsisMenuMinLevel,
} = useBlockNavigationContext();
+
const ellipsisMenuClassName = classnames(
'block-editor-block-navigation-block__menu-cell',
{ 'is-visible': hasVisibleMovers }
);
+ const { isEditorAutoFocusEnabled } = useSelect( ( select ) => ( {
+ isEditorAutoFocusEnabled: select(
+ 'core/block-editor'
+ ).isAutoFocusEnabled(),
+ } ) );
+ useEffect( () => {
+ let timeout;
+ if ( ! isEditorAutoFocusEnabled && isSelected ) {
+ // Give slots time to settle down
+ timeout = setTimeout( function() {
+ // Select the new block
+ onClick();
+
+ // Move focus to the new block
+ if ( ref.current ) {
+ ref.current.focus();
+ }
+ } );
+ }
+ return () => clearTimeout( timeout );
+ }, [ isEditorAutoFocusEnabled, isSelected ] );
+
return (
) }
diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js
index 5aef9e4ce2dd6c..93fef4169f11ec 100644
--- a/packages/block-editor/src/store/actions.js
+++ b/packages/block-editor/src/store/actions.js
@@ -883,6 +883,18 @@ export function* setNavigationMode( isNavigationMode = true ) {
}
}
+/**
+ * Generators that triggers an action used to enable or disable the automatic focus.
+ *
+ * @param {boolean} isAutoFocusEnabled Enable/Disable navigation mode.
+ */
+export function* setAutoFocusEnabled( isAutoFocusEnabled = true ) {
+ yield {
+ type: 'SET_AUTO_FOCUS_ENABLED',
+ isAutoFocusEnabled,
+ };
+}
+
/**
* Generator that triggers an action used to duplicate a list of blocks.
*
diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js
index 223fe269508841..759608409ccf3f 100644
--- a/packages/block-editor/src/store/reducer.js
+++ b/packages/block-editor/src/store/reducer.js
@@ -1519,6 +1519,22 @@ export function isNavigationMode( state = false, action ) {
return state;
}
+/**
+ * Reducer returning whether the automatic focus should be enabled or not.
+ *
+ * @param {boolean} state Current state.
+ * @param {Object} action Dispatched action.
+ *
+ * @return {string} Updated state.
+ */
+export function isAutoFocusEnabled( state = true, action ) {
+ if ( action.type === 'SET_AUTO_FOCUS_ENABLED' ) {
+ return action.isAutoFocusEnabled;
+ }
+
+ return state;
+}
+
/**
* Reducer return an updated state representing the most recent block attribute
* update. The state is structured as an object where the keys represent the
@@ -1621,6 +1637,7 @@ export default combineReducers( {
preferences,
lastBlockAttributesChange,
isNavigationMode,
+ isAutoFocusEnabled,
automaticChangeStatus,
highlightedBlock,
} );
diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js
index 183210fc14c79f..adc84d8797bb81 100644
--- a/packages/block-editor/src/store/selectors.js
+++ b/packages/block-editor/src/store/selectors.js
@@ -1627,6 +1627,17 @@ export function isNavigationMode( state ) {
return state.isNavigationMode;
}
+/**
+ * Returns whether the automatic focus is enabled.
+ *
+ * @param {Object} state Editor state.
+ *
+ * @return {boolean} Is automatic focus enabled.
+ */
+export function isAutoFocusEnabled( state ) {
+ return state.isAutoFocusEnabled;
+}
+
/**
* Returns true if the last change was an automatic change, false otherwise.
*
diff --git a/packages/components/src/panel/index.js b/packages/components/src/panel/index.js
index 96e9daf8e647b3..d6e85fd43bea08 100644
--- a/packages/components/src/panel/index.js
+++ b/packages/components/src/panel/index.js
@@ -8,10 +8,10 @@ import classnames from 'classnames';
*/
import PanelHeader from './header';
-function Panel( { header, className, children } ) {
+function Panel( { header, className, children, ...props } ) {
const classNames = classnames( className, 'components-panel' );
return (
-
+
{ header &&
}
{ children }
diff --git a/packages/edit-navigation/src/components/menu-editor/block-editor-panel.js b/packages/edit-navigation/src/components/menu-editor/block-editor-panel.js
index 1706bff5ed20d1..209b763f8b18b3 100644
--- a/packages/edit-navigation/src/components/menu-editor/block-editor-panel.js
+++ b/packages/edit-navigation/src/components/menu-editor/block-editor-panel.js
@@ -26,6 +26,7 @@ export default function BlockEditorPanel( {
onDeleteMenu,
menuId,
saveBlocks,
+ ...props
} ) {
const { isNavigationModeActive, hasSelectedBlock } = useSelect(
( select ) => {
@@ -48,7 +49,10 @@ export default function BlockEditorPanel( {
);
return (
-
+