From fbf75ebc0b638162078da602bf1daf2cd6256990 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Thu, 19 Jan 2023 15:11:40 +0800 Subject: [PATCH 1/2] Add shuffle and templateLock to the pattern block --- docs/reference-guides/core-blocks.md | 2 +- packages/block-library/src/pattern/block.json | 4 + packages/block-library/src/pattern/edit.js | 79 ++++++++++++++++--- 3 files changed, 73 insertions(+), 12 deletions(-) diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index 60147a5bac7fd..8ae0ede80e91c 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -456,7 +456,7 @@ Show a block pattern. ([Source](https://github.com/WordPress/gutenberg/tree/trun - **Name:** core/pattern - **Category:** theme - **Supports:** ~~html~~, ~~inserter~~ -- **Attributes:** slug +- **Attributes:** slug, templateLock ## Post Author diff --git a/packages/block-library/src/pattern/block.json b/packages/block-library/src/pattern/block.json index da023142403c8..266e0f81afa47 100644 --- a/packages/block-library/src/pattern/block.json +++ b/packages/block-library/src/pattern/block.json @@ -13,6 +13,10 @@ "attributes": { "slug": { "type": "string" + }, + "templateLock": { + "type": [ "string", "boolean" ], + "enum": [ "all", "insert", "contentOnly", false ] } } } diff --git a/packages/block-library/src/pattern/edit.js b/packages/block-library/src/pattern/edit.js index be0b778eb4ae1..a4798a91d0adf 100644 --- a/packages/block-library/src/pattern/edit.js +++ b/packages/block-library/src/pattern/edit.js @@ -6,16 +6,43 @@ import { useEffect } from '@wordpress/element'; import { store as blockEditorStore, useBlockProps, + useInnerBlocksProps, + BlockControls, } from '@wordpress/block-editor'; +import { ToolbarButton } from '@wordpress/components'; +import { __ } from '@wordpress/i18n'; -const PatternEdit = ( { attributes, clientId } ) => { - const selectedPattern = useSelect( - ( select ) => - select( blockEditorStore ).__experimentalGetParsedPattern( - attributes.slug - ), - [ attributes.slug ] - ); +const PatternEdit = ( { attributes, clientId, setAttributes } ) => { + const { selectedPattern, isContentLocked, patternsInSameCategories } = + useSelect( + ( select ) => { + const { + __experimentalGetParsedPattern: getParsedPattern, + __unstableGetContentLockingParent: getContentLockingParent, + __experimentalGetAllowedPatterns: getAllowedPatterns, + } = select( blockEditorStore ); + const _selectedPattern = getParsedPattern( attributes.slug ); + return { + selectedPattern: _selectedPattern, + isContentLocked: + ! getContentLockingParent( clientId ) && + attributes.templateLock === 'contentOnly', + patternsInSameCategories: getAllowedPatterns().filter( + ( pattern ) => + pattern.name !== _selectedPattern.name && + pattern.categories?.length > 0 && + pattern.categories?.some( + ( category ) => + _selectedPattern.categories?.length > 0 && + _selectedPattern.categories?.includes( + category + ) + ) + ), + }; + }, + [ attributes.slug, attributes.templateLock, clientId ] + ); const { replaceBlocks, __unstableMarkNextChangeAsNotPersistent } = useDispatch( blockEditorStore ); @@ -25,7 +52,7 @@ const PatternEdit = ( { attributes, clientId } ) => { // This change won't be saved. // It will continue to pull from the pattern file unless changes are made to its respective template part. useEffect( () => { - if ( selectedPattern?.blocks ) { + if ( ! isContentLocked && selectedPattern?.blocks ) { // We batch updates to block list settings to avoid triggering cascading renders // for each container block included in a tree and optimize initial render. // Since the above uses microtasks, we need to use a microtask here as well, @@ -38,9 +65,39 @@ const PatternEdit = ( { attributes, clientId } ) => { } }, [ clientId, selectedPattern?.blocks ] ); - const props = useBlockProps(); + const blockProps = useBlockProps(); + const innerBlockProps = useInnerBlocksProps( blockProps, { + templateLock: attributes.templateLock, + onInput: () => {}, + onChange: () => {}, + value: selectedPattern?.blocks ?? [], + } ); + + const canShuffle = isContentLocked && patternsInSameCategories.length > 0; + + function shuffle() { + const randomIndex = Math.floor( + // We explicitly want the randomness here for shuffling. + // eslint-disable-next-line no-restricted-syntax + Math.random() * patternsInSameCategories.length + ); + const nextPattern = patternsInSameCategories[ randomIndex ]; - return
; + setAttributes( { slug: nextPattern.name } ); + } + + return ( + <> +
+ { canShuffle && ( + + + { __( 'Shuffle' ) } + + + ) } + + ); }; export default PatternEdit; From d056cc685ee1bedbcfe5298d9617a6ae4aea8d46 Mon Sep 17 00:00:00 2001 From: Kai Hao Date: Thu, 2 Feb 2023 22:45:28 +0800 Subject: [PATCH 2/2] Replace blocks after editing --- packages/block-library/src/pattern/edit.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/block-library/src/pattern/edit.js b/packages/block-library/src/pattern/edit.js index a4798a91d0adf..bcf5c74097db9 100644 --- a/packages/block-library/src/pattern/edit.js +++ b/packages/block-library/src/pattern/edit.js @@ -69,7 +69,9 @@ const PatternEdit = ( { attributes, clientId, setAttributes } ) => { const innerBlockProps = useInnerBlocksProps( blockProps, { templateLock: attributes.templateLock, onInput: () => {}, - onChange: () => {}, + onChange: ( blocks ) => { + replaceBlocks( clientId, blocks ); + }, value: selectedPattern?.blocks ?? [], } );