diff --git a/packages/block-editor/src/components/block-pattern-setup/index.js b/packages/block-editor/src/components/block-pattern-setup/index.js index 26c5533be8c840..2fa25326a5c9c9 100644 --- a/packages/block-editor/src/components/block-pattern-setup/index.js +++ b/packages/block-editor/src/components/block-pattern-setup/index.js @@ -134,6 +134,7 @@ const BlockPatternSetup = ( { blockName, filterPatternsFn, startBlankComponent, + onBlockPatternSelect, } ) => { const [ viewMode, setViewMode ] = useState( VIEWMODES.carousel ); const [ activeSlide, setActiveSlide ] = useState( 0 ); @@ -145,10 +146,12 @@ const BlockPatternSetup = ( { return startBlankComponent; } - const onBlockPatternSelect = ( blocks ) => { + const onBlockPatternSelectDefault = ( blocks ) => { const clonedBlocks = blocks.map( ( block ) => cloneBlock( block ) ); replaceBlock( clientId, clonedBlocks ); }; + const onPatternSelectCallback = + onBlockPatternSelect || onBlockPatternSelectDefault; return (
active - 1 ); } } onBlockPatternSelect={ () => { - onBlockPatternSelect( patterns[ activeSlide ].blocks ); + onPatternSelectCallback( patterns[ activeSlide ].blocks ); } } onStartBlank={ () => { setShowBlank( true ); @@ -175,7 +178,7 @@ const BlockPatternSetup = ( { viewMode={ viewMode } activeSlide={ activeSlide } patterns={ patterns } - onBlockPatternSelect={ onBlockPatternSelect } + onBlockPatternSelect={ onPatternSelectCallback } />
); diff --git a/packages/block-library/src/template-part/edit/index.js b/packages/block-library/src/template-part/edit/index.js index eb7ac5af85a70d..6359a206803c55 100644 --- a/packages/block-library/src/template-part/edit/index.js +++ b/packages/block-library/src/template-part/edit/index.js @@ -22,10 +22,10 @@ import { store as editorStore } from '@wordpress/editor'; /** * Internal dependencies */ -import TemplatePartInnerBlocks from './inner-blocks'; import TemplatePartPlaceholder from './placeholder'; import TemplatePartSelection from './selection'; import { TemplatePartAdvancedControls } from './advanced-controls'; +import TemplatePartInnerBlocks from './inner-blocks'; export default function TemplatePartEdit( { attributes, @@ -130,8 +130,8 @@ export default function TemplatePartEdit( { ) } diff --git a/packages/block-library/src/template-part/edit/placeholder/index.js b/packages/block-library/src/template-part/edit/placeholder/index.js index 4a8462b278b9c7..d4233d68991611 100644 --- a/packages/block-library/src/template-part/edit/placeholder/index.js +++ b/packages/block-library/src/template-part/edit/placeholder/index.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { __ } from '@wordpress/i18n'; -import { useCallback } from '@wordpress/element'; +import { useCallback, useState } from '@wordpress/element'; import { useDispatch } from '@wordpress/data'; import { Placeholder, Dropdown, Button } from '@wordpress/components'; import { blockDefault } from '@wordpress/icons'; @@ -13,71 +13,98 @@ import { store as coreStore } from '@wordpress/core-data'; * Internal dependencies */ import TemplatePartSelection from '../selection'; +import PatternsSetup from './patterns-setup'; + +const PLACEHOLDER_STEPS = { + initial: 1, + patterns: 2, +}; export default function TemplatePartPlaceholder( { area, + clientId, setAttributes, - innerBlocks, } ) { const { saveEntityRecord } = useDispatch( coreStore ); - const onCreate = useCallback( async () => { - const title = __( 'Untitled Template Part' ); - // If we have `area` set from block attributes, means an exposed - // block variation was inserted. So add this prop to the template - // part entity on creation. Afterwards remove `area` value from - // block attributes. - const record = { - title, - slug: 'template-part', - content: serialize( innerBlocks ), - // `area` is filterable on the server and defaults to `UNCATEGORIZED` - // if provided value is not allowed. - area, - }; - const templatePart = await saveEntityRecord( - 'postType', - 'wp_template_part', - record - ); - setAttributes( { - slug: templatePart.slug, - theme: templatePart.theme, - area: undefined, - } ); - }, [ setAttributes, area ] ); + const [ step, setStep ] = useState( PLACEHOLDER_STEPS.initial ); + + const onCreate = useCallback( + async ( startingBlocks = [] ) => { + const title = __( 'Untitled Template Part' ); + // If we have `area` set from block attributes, means an exposed + // block variation was inserted. So add this prop to the template + // part entity on creation. Afterwards remove `area` value from + // block attributes. + const record = { + title, + slug: 'template-part', + content: serialize( startingBlocks ), + // `area` is filterable on the server and defaults to `UNCATEGORIZED` + // if provided value is not allowed. + area, + }; + const templatePart = await saveEntityRecord( + 'postType', + 'wp_template_part', + record + ); + setAttributes( { + slug: templatePart.slug, + theme: templatePart.theme, + area: undefined, + } ); + }, + [ setAttributes, area ] + ); return ( - - ( - <> - - - - ) } - renderContent={ ( { onClose } ) => ( - + { step === PLACEHOLDER_STEPS.initial && ( + + ( + <> + + + + ) } + renderContent={ ( { onClose } ) => ( + + ) } /> - ) } - /> - + + ) } + { step === PLACEHOLDER_STEPS.patterns && ( + + ) } + ); } diff --git a/packages/block-library/src/template-part/edit/placeholder/patterns-setup.js b/packages/block-library/src/template-part/edit/placeholder/patterns-setup.js new file mode 100644 index 00000000000000..6add051c040408 --- /dev/null +++ b/packages/block-library/src/template-part/edit/placeholder/patterns-setup.js @@ -0,0 +1,33 @@ +/** + * WordPress dependencies + */ +import { __experimentalBlockPatternSetup as BlockPatternSetup } from '@wordpress/block-editor'; +import { useEffect } from '@wordpress/element'; + +export default function PatternsSetup( { area, clientId, onCreate } ) { + const blockNameWithArea = area + ? `core/template-part/${ area }` + : 'core/template-part'; + + return ( + + } + onBlockPatternSelect={ onCreate } + filterPatternsFn={ ( pattern ) => + pattern?.blockTypes?.some?.( + ( blockType ) => blockType === blockNameWithArea + ) + } + /> + ); +} + +function StartBlankComponent( { onCreate } ) { + useEffect( () => { + onCreate(); + }, [] ); + return null; +}