Skip to content

Commit

Permalink
Add shuffle and templateLock to the pattern block
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 committed Jan 31, 2023
1 parent 7381ea5 commit fbf75eb
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 12 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 @@ -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

Expand Down
4 changes: 4 additions & 0 deletions packages/block-library/src/pattern/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
"attributes": {
"slug": {
"type": "string"
},
"templateLock": {
"type": [ "string", "boolean" ],
"enum": [ "all", "insert", "contentOnly", false ]
}
}
}
79 changes: 68 additions & 11 deletions packages/block-library/src/pattern/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand All @@ -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,
Expand All @@ -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 <div { ...props } />;
setAttributes( { slug: nextPattern.name } );
}

return (
<>
<div { ...( canShuffle ? innerBlockProps : blockProps ) } />
{ canShuffle && (
<BlockControls group="other">
<ToolbarButton onClick={ shuffle }>
{ __( 'Shuffle' ) }
</ToolbarButton>
</BlockControls>
) }
</>
);
};

export default PatternEdit;

0 comments on commit fbf75eb

Please sign in to comment.