Skip to content

Commit

Permalink
Synchronise inner block attribute updates to the parent pattern block
Browse files Browse the repository at this point in the history
- Use a BlockEdit filter to optionally wrap the setAttributes function when a partially synced pattern block exits
- Merge inner block attributes updates into a pattern block `content` attribute
- Batch the updates into one action`
  • Loading branch information
talldan committed May 16, 2023
1 parent b0d2da0 commit 2bded3a
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 3 deletions.
2 changes: 1 addition & 1 deletion docs/reference-guides/core-blocks.md
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ Show a block pattern. ([Source](https://github.com/WordPress/gutenberg/tree/trun
- **Name:** core/pattern
- **Category:** theme
- **Supports:** ~~html~~, ~~inserter~~
- **Attributes:** slug, syncStatus
- **Attributes:** content, slug, syncStatus

## Post Author

Expand Down
3 changes: 3 additions & 0 deletions packages/block-library/src/pattern/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
"syncStatus": {
"type": [ "string", "boolean" ],
"enum": [ "full", "partial" ]
},
"content": {
"type": "object"
}
}
}
99 changes: 97 additions & 2 deletions packages/block-library/src/pattern/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
* WordPress dependencies
*/
import { cloneBlock } from '@wordpress/blocks';
import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';
import { createHigherOrderComponent } from '@wordpress/compose';
import { useSelect, useDispatch, useRegistry } from '@wordpress/data';
import { useEffect, useCallback } from '@wordpress/element';
import {
store as blockEditorStore,
useBlockProps,
useInnerBlocksProps,
} from '@wordpress/block-editor';
import { addFilter } from '@wordpress/hooks';

const EMPTY_OBJECT = {};

const PatternEdit = ( { attributes, clientId } ) => {
const { slug, syncStatus } = attributes;
Expand Down Expand Up @@ -81,3 +85,94 @@ const PatternEdit = ( { attributes, clientId } ) => {
};

export default PatternEdit;

/**
* Override the default edit UI to include layout controls
*
* @param {Function} BlockEdit Original component.
*
* @return {Function} Wrapped component.
*/
export const withChildContentAttributes = createHigherOrderComponent(
( BlockEdit ) => ( props ) => {
const { name: blockName, clientId, setAttributes } = props;

const registry = useRegistry();

const { patternClientId, patternSyncStatus, patternContent } =
useSelect(
( select ) => {
const { getBlockParentsByBlockName, getBlockAttributes } =
select( blockEditorStore );

const patternBlockParents = getBlockParentsByBlockName(
clientId,
'core/pattern'
);

const parentPatternClientId = patternBlockParents?.[ 0 ];

if ( ! parentPatternClientId ) {
return EMPTY_OBJECT;
}

const { syncStatus, content } = getBlockAttributes(
parentPatternClientId
);

return {
patternClientId: parentPatternClientId,
patternSyncStatus: syncStatus,
patternContent: content,
};
},
[ clientId ]
);

const { updateBlockAttributes } = useDispatch( blockEditorStore );

if ( patternSyncStatus !== 'partial' ) {
return <BlockEdit { ...props } />;
}

const setContentAttributes = useCallback(
( newAttributes ) => {
registry.batch( () => {
// Sync any attribute updates to a partially synced pattern parent.
// todo
// - Only set `role: 'content' attributes.
// - Handle multiple blocks of the same type.
updateBlockAttributes( patternClientId, {
content: {
...patternContent,
[ blockName ]: {
...patternContent?.[ blockName ],
...newAttributes,
},
},
} );
setAttributes( newAttributes );
} );
},
[
blockName,
patternClientId,
patternContent,
registry,
setAttributes,
updateBlockAttributes,
]
);

return (
<BlockEdit { ...props } setAttributes={ setContentAttributes } />
);
},
'withInspectorControls'
);

addFilter(
'editor.BlockEdit',
'core/block-library/pattern/with-child-content-attributes',
withChildContentAttributes
);

0 comments on commit 2bded3a

Please sign in to comment.