diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js
index 3dcf548bd117a3..9bca24a54ff0dc 100644
--- a/packages/block-library/src/template-part/edit/index.js
+++ b/packages/block-library/src/template-part/edit/index.js
@@ -15,8 +15,15 @@ import {
store as blockEditorStore,
__experimentalRecursionProvider as RecursionProvider,
__experimentalUseHasRecursion as useHasRecursion,
+ BlockControls,
} from '@wordpress/block-editor';
-import { Spinner, Modal, MenuItem } from '@wordpress/components';
+import {
+ Spinner,
+ Modal,
+ MenuItem,
+ ToolbarButton,
+ Tooltip,
+} from '@wordpress/components';
import { __, sprintf } from '@wordpress/i18n';
import { store as coreStore } from '@wordpress/core-data';
import { useState, createInterpolateElement } from '@wordpress/element';
@@ -33,6 +40,7 @@ import {
useAlternativeBlockPatterns,
useAlternativeTemplateParts,
useTemplatePartArea,
+ useShuffleTemplatePart,
} from './utils/hooks';
export default function TemplatePartEdit( {
@@ -92,6 +100,12 @@ export default function TemplatePartEdit( {
const isPlaceholder = ! slug;
const isEntityAvailable = ! isPlaceholder && ! isMissing && isResolved;
const TagName = tagName || areaObject.tagName;
+ const shuffleTemplatePart = useShuffleTemplatePart(
+ area,
+ clientId,
+ templatePartId,
+ setAttributes
+ );
// The `isSelected` check ensures the `BlockSettingsMenuControls` fill
// doesn't render multiple times. The block controls has similar internal check.
@@ -157,27 +171,39 @@ export default function TemplatePartEdit( {
) }
{ canReplace && (
-
- { () => (
-
- ) }
-
+
+ { __( 'Shuffle' ) }
+
+
+
+ >
) }
{ isEntityAvailable && (
{
+ const serializedPatternBlocks = serialize( pattern.blocks );
+ return (
+ pattern.name !== currentPatternRef.current &&
+ templateParts.every(
+ ( templatePart ) =>
+ templatePart.content.raw !== serializedPatternBlocks
+ )
+ );
+ } ),
+ ];
+ // We explicitly want the randomness here.
+ // eslint-disable-next-line no-restricted-syntax
+ const randomIndex = Math.floor( Math.random() * list.length );
+ const randomItem = list[ randomIndex ];
+
+ if ( randomIndex < templateParts.length ) {
+ const templatePart = randomItem;
+ setAttributes( {
+ slug: templatePart.slug,
+ theme: templatePart.theme,
+ area: undefined,
+ } );
+ } else {
+ const pattern = randomItem;
+ currentPatternRef.current = pattern.name;
+
+ replaceInnerBlocks( clientId, pattern.blocks );
+ }
+ };
+}