diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md
index 2d6a5627a52a44..990148cbc855f3 100644
--- a/packages/block-editor/README.md
+++ b/packages/block-editor/README.md
@@ -867,13 +867,14 @@ function MyBlock( { attributes, setAttributes } ) {
}
```
-`mode` can be one of three options:
+`mode` can be one of four options:
- `'disabled'`: Prevents editing the block entirely, i.e. it cannot be
selected.
- `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the
toolbar, the block movers, block settings.
- `'default'`: Allows editing the block as normal.
+- `'syncedPattern'`: Restricts editing of synced pattern blocks to only child blocks that have attribute connections set.
The mode is inherited by all of the block's inner blocks, unless they have
their own mode.
diff --git a/packages/block-editor/src/components/block-editing-mode/index.js b/packages/block-editor/src/components/block-editing-mode/index.js
index 5d916d9816e606..5a40604d0eaa5a 100644
--- a/packages/block-editor/src/components/block-editing-mode/index.js
+++ b/packages/block-editor/src/components/block-editing-mode/index.js
@@ -11,7 +11,7 @@ import { store as blockEditorStore } from '../../store';
import { BlockListBlockContext } from '../block-list/block-list-block-context';
/**
- * @typedef {'disabled'|'contentOnly'|'default'} BlockEditingMode
+ * @typedef {'disabled'|'contentOnly'|'default'|'syncedPattern'} BlockEditingMode
*/
/**
@@ -26,13 +26,14 @@ import { BlockListBlockContext } from '../block-list/block-list-block-context';
* }
* ```
*
- * `mode` can be one of three options:
+ * `mode` can be one of four options:
*
* - `'disabled'`: Prevents editing the block entirely, i.e. it cannot be
* selected.
* - `'contentOnly'`: Hides all non-content UI, e.g. auxiliary controls in the
* toolbar, the block movers, block settings.
* - `'default'`: Allows editing the block as normal.
+ * - `'syncedPattern'`: Restricts editing of synced pattern blocks to only child blocks that have attribute connections set.
*
* The mode is inherited by all of the block's inner blocks, unless they have
* their own mode.
diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js
index a95075c6f9b42c..7e2246fff21cd5 100644
--- a/packages/block-editor/src/components/block-list/block.js
+++ b/packages/block-editor/src/components/block-list/block.js
@@ -113,6 +113,8 @@ function BlockListBlock( {
);
const { removeBlock } = useDispatch( blockEditorStore );
const onRemove = useCallback( () => removeBlock( clientId ), [ clientId ] );
+ const isSyncedPatternChild =
+ name !== 'core/block' && blockEditingMode === 'syncedPattern';
const parentLayout = useLayout() || {};
@@ -142,7 +144,7 @@ function BlockListBlock( {
const blockType = getBlockType( name );
- if ( blockEditingMode === 'disabled' ) {
+ if ( blockEditingMode === 'disabled' || isSyncedPatternChild ) {
wrapperProps = {
...wrapperProps,
tabIndex: -1,
@@ -216,7 +218,8 @@ function BlockListBlock( {
clientId,
className: classnames(
{
- 'is-editing-disabled': blockEditingMode === 'disabled',
+ 'is-editing-disabled':
+ blockEditingMode === 'disabled' || isSyncedPatternChild,
'is-content-locked-temporarily-editing-as-blocks':
isTemporarilyEditingAsBlocks,
},
diff --git a/packages/block-editor/src/components/block-list/use-in-between-inserter.js b/packages/block-editor/src/components/block-list/use-in-between-inserter.js
index a60453716ff29c..3effeb6d6b1aac 100644
--- a/packages/block-editor/src/components/block-list/use-in-between-inserter.js
+++ b/packages/block-editor/src/components/block-list/use-in-between-inserter.js
@@ -75,7 +75,8 @@ export function useInBetweenInserter() {
if (
getTemplateLock( rootClientId ) ||
- getBlockEditingMode( rootClientId ) === 'disabled'
+ getBlockEditingMode( rootClientId ) === 'disabled' ||
+ getBlockEditingMode( rootClientId ) === 'syncedPattern'
) {
return;
}
diff --git a/packages/block-editor/src/components/block-lock/modal.js b/packages/block-editor/src/components/block-lock/modal.js
index cfafa6c031bbd1..c08159faa05fd6 100644
--- a/packages/block-editor/src/components/block-lock/modal.js
+++ b/packages/block-editor/src/components/block-lock/modal.js
@@ -25,7 +25,7 @@ import useBlockDisplayInformation from '../use-block-display-information';
import { store as blockEditorStore } from '../../store';
// Entity based blocks which allow edit locking
-const ALLOWS_EDIT_LOCKING = [ 'core/block', 'core/navigation' ];
+const ALLOWS_EDIT_LOCKING = [ 'core/navigation' ];
function getTemplateLockValue( lock ) {
// Prevents all operations.
diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js
index 963cd8a475328a..239b677fa04ad6 100644
--- a/packages/block-editor/src/components/block-toolbar/index.js
+++ b/packages/block-editor/src/components/block-toolbar/index.js
@@ -91,6 +91,7 @@ const BlockToolbar = ( { hideDragHandle } ) => {
const isSynced =
isReusableBlock( blockType ) || isTemplatePart( blockType );
+ const isSyncedPattern = isReusableBlock( blockType );
const classes = classnames( 'block-editor-block-toolbar', {
'is-synced': isSynced,
} );
@@ -101,7 +102,8 @@ const BlockToolbar = ( { hideDragHandle } ) => {
isLargeViewport &&
blockEditingMode === 'default' &&