Skip to content

Commit

Permalink
Template part - add patterns placeholder selection. (#31155)
Browse files Browse the repository at this point in the history
* component renders in expected states, shows expected patterns

* onBlockPatternSelect override in pattern setup

* use onBlockPatternSelect function to make 'choose' pattern work properly

* use filterPatternsFn

* refactor to separate components/files

* remove unnecessary added newlines

* update example patterns to now show for general case

* Revert "update example patterns to now show for general case"

This reverts commit 5dabb7b89987fe36a15058dea37e0e33bb0f7fe1.

* move this to placeholder step and pre-creation

* remove unnecessary blockName prop

* use enum for pattern steps

* lowercase enum props and set values as integers

* remove example patterns

Co-authored-by: ntsekouras <ntsekouras@outlook.com>
  • Loading branch information
Addison-Stavlo and ntsekouras authored Apr 28, 2021
1 parent d2da787 commit b8589ef
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ const BlockPatternSetup = ( {
blockName,
filterPatternsFn,
startBlankComponent,
onBlockPatternSelect,
} ) => {
const [ viewMode, setViewMode ] = useState( VIEWMODES.carousel );
const [ activeSlide, setActiveSlide ] = useState( 0 );
Expand All @@ -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 (
<div
className={ `block-editor-block-pattern-setup view-mode-${ viewMode }` }
Expand All @@ -165,7 +168,7 @@ const BlockPatternSetup = ( {
setActiveSlide( ( active ) => active - 1 );
} }
onBlockPatternSelect={ () => {
onBlockPatternSelect( patterns[ activeSlide ].blocks );
onPatternSelectCallback( patterns[ activeSlide ].blocks );
} }
onStartBlank={ () => {
setShowBlank( true );
Expand All @@ -175,7 +178,7 @@ const BlockPatternSetup = ( {
viewMode={ viewMode }
activeSlide={ activeSlide }
patterns={ patterns }
onBlockPatternSelect={ onBlockPatternSelect }
onBlockPatternSelect={ onPatternSelectCallback }
/>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions packages/block-library/src/template-part/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -130,8 +130,8 @@ export default function TemplatePartEdit( {
<TagName { ...blockProps }>
<TemplatePartPlaceholder
area={ attributes.area }
clientId={ clientId }
setAttributes={ setAttributes }
innerBlocks={ innerBlocks }
/>
</TagName>
) }
Expand Down
143 changes: 85 additions & 58 deletions packages/block-library/src/template-part/edit/placeholder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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 (
<Placeholder
icon={ blockDefault }
label={ __( 'Template Part' ) }
instructions={ __(
'Create a new template part or pick an existing one from the list.'
) }
>
<Dropdown
contentClassName="wp-block-template-part__placeholder-preview-dropdown-content"
position="bottom right left"
renderToggle={ ( { isOpen, onToggle } ) => (
<>
<Button
isPrimary
onClick={ onToggle }
aria-expanded={ isOpen }
>
{ __( 'Choose existing' ) }
</Button>
<Button isTertiary onClick={ onCreate }>
{ __( 'New template part' ) }
</Button>
</>
) }
renderContent={ ( { onClose } ) => (
<TemplatePartSelection
setAttributes={ setAttributes }
onClose={ onClose }
<>
{ step === PLACEHOLDER_STEPS.initial && (
<Placeholder
icon={ blockDefault }
label={ __( 'Template Part' ) }
instructions={ __(
'Create a new template part or pick an existing one from the list.'
) }
>
<Dropdown
contentClassName="wp-block-template-part__placeholder-preview-dropdown-content"
position="bottom right left"
renderToggle={ ( { isOpen, onToggle } ) => (
<>
<Button
isPrimary
onClick={ onToggle }
aria-expanded={ isOpen }
>
{ __( 'Choose existing' ) }
</Button>
<Button
isTertiary
onClick={ () =>
setStep( PLACEHOLDER_STEPS.patterns )
}
>
{ __( 'New template part' ) }
</Button>
</>
) }
renderContent={ ( { onClose } ) => (
<TemplatePartSelection
setAttributes={ setAttributes }
onClose={ onClose }
/>
) }
/>
) }
/>
</Placeholder>
</Placeholder>
) }
{ step === PLACEHOLDER_STEPS.patterns && (
<PatternsSetup
area={ area }
onCreate={ onCreate }
clientId={ clientId }
/>
) }
</>
);
}
Original file line number Diff line number Diff line change
@@ -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 (
<BlockPatternSetup
clientId={ clientId }
startBlankComponent={
<StartBlankComponent onCreate={ onCreate } />
}
onBlockPatternSelect={ onCreate }
filterPatternsFn={ ( pattern ) =>
pattern?.blockTypes?.some?.(
( blockType ) => blockType === blockNameWithArea
)
}
/>
);
}

function StartBlankComponent( { onCreate } ) {
useEffect( () => {
onCreate();
}, [] );
return null;
}

0 comments on commit b8589ef

Please sign in to comment.