Skip to content

Commit

Permalink
Update query block creation and replacement flows
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgefilipecosta committed Mar 31, 2022
1 parent 27b4e83 commit 8125f78
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 40 deletions.
140 changes: 113 additions & 27 deletions packages/block-library/src/query/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@
* WordPress dependencies
*/
import { useSelect, useDispatch } from '@wordpress/data';
import { cloneBlock } from '@wordpress/blocks';
import { store as blocksStore } from '@wordpress/blocks';
import { useInstanceId } from '@wordpress/compose';
import { useEffect } from '@wordpress/element';
import { useState, useEffect } from '@wordpress/element';
import {
BlockControls,
InspectorControls,
useBlockProps,
useSetting,
store as blockEditorStore,
useInnerBlocksProps,
__experimentalBlockPatternSetup as BlockPatternSetup,
__experimentalGetMatchingVariation as getMatchingVariation,
} from '@wordpress/block-editor';
import { SelectControl } from '@wordpress/components';
import {
Button,
SelectControl,
Placeholder,
Modal,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';

/**
Expand All @@ -24,10 +29,14 @@ import QueryToolbar from './query-toolbar';
import QueryInspectorControls from './inspector-controls';
import QueryPlaceholder from './query-placeholder';
import { DEFAULTS_POSTS_PER_PAGE } from '../constants';
import { getFirstQueryClientIdFromBlocks } from '../utils';
import PatternSelectionModal from './pattern-selection-modal';

const TEMPLATE = [ [ 'core/post-template' ] ];
export function QueryContent( { attributes, setAttributes } ) {
export function QueryContent( {
attributes,
setAttributes,
openPatternSelectionModal,
} ) {
const {
queryId,
query,
Expand Down Expand Up @@ -102,6 +111,7 @@ export function QueryContent( { attributes, setAttributes } ) {
attributes={ attributes }
setQuery={ updateQuery }
setDisplayLayout={ updateDisplayLayout }
openPatternSelectionModal={ openPatternSelectionModal }
/>
</BlockControls>
<InspectorControls __experimentalGroup="advanced">
Expand All @@ -124,43 +134,119 @@ export function QueryContent( { attributes, setAttributes } ) {
);
}

function QueryPatternSetup( props ) {
const { clientId, name: blockName } = props;
function QueryPatternSetup( {
attributes,
clientId,
name,
openPatternSelectionModal,
setAttributes,
} ) {
const [ isStartingBlank, setIsStartingBlank ] = useState( false );
const blockProps = useBlockProps();
const { replaceBlock, selectBlock } = useDispatch( blockEditorStore );
const onBlockPatternSelect = ( blocks ) => {
const clonedBlocks = blocks.map( ( block ) => cloneBlock( block ) );
const firstQueryClientId = getFirstQueryClientIdFromBlocks(
clonedBlocks

const { blockType, allVariations, hasPatterns } = useSelect(
( select ) => {
const { getBlockVariations, getBlockType } = select( blocksStore );
const {
getBlockRootClientId,
__experimentalGetPatternsByBlockTypes,
} = select( blockEditorStore );
const rootClientId = getBlockRootClientId( clientId );

return {
blockType: getBlockType( name ),
allVariations: getBlockVariations( name ),
hasPatterns: !! __experimentalGetPatternsByBlockTypes(
name,
rootClientId
).length,
};
},
[ name, clientId ]
);

const matchingVariation = getMatchingVariation( attributes, allVariations );
const icon = matchingVariation?.icon || blockType?.icon?.src;
const label = matchingVariation?.title || blockType?.title;
if ( isStartingBlank ) {
return (
<QueryPlaceholder
clientId={ clientId }
name={ name }
setAttributes={ setAttributes }
icon={ icon }
label={ label }
/>
);
replaceBlock( clientId, clonedBlocks );
if ( firstQueryClientId ) {
selectBlock( firstQueryClientId );
}
};
// `startBlankComponent` is what to render when clicking `Start blank`
// or if no matched patterns are found.
}
return (
<div { ...blockProps }>
<BlockPatternSetup
blockName={ blockName }
clientId={ clientId }
startBlankComponent={ <QueryPlaceholder { ...props } /> }
onBlockPatternSelect={ onBlockPatternSelect }
/>
<Placeholder
icon={ icon }
label={ label }
instructions={ __(
'Choose a pattern for the query loop or start blank.'
) }
>
{ !! hasPatterns && (
<Button
variant="primary"
onClick={ openPatternSelectionModal }
>
{ __( 'Choose' ) }
</Button>
) }

<Button
variant="secondary"
onClick={ () => {
setIsStartingBlank( true );
} }
>
{ __( 'Start blank' ) }
</Button>
</Placeholder>
</div>
);
}

const QueryEdit = ( props ) => {
const { clientId } = props;
const [
isPatternSelectionModalOpen,
setIsPatternSelectionModalOpen,
] = useState( false );
const hasInnerBlocks = useSelect(
( select ) =>
!! select( blockEditorStore ).getBlocks( clientId ).length,
[ clientId ]
);
const Component = hasInnerBlocks ? QueryContent : QueryPatternSetup;
return <Component { ...props } />;
return (
<>
<Component
{ ...props }
openPatternSelectionModal={ () =>
setIsPatternSelectionModalOpen( true )
}
/>
{ isPatternSelectionModalOpen && (
<Modal
className="block-editor-template-part__selection-modal"
title={ __( 'Choose a pattern' ) }
closeLabel={ __( 'Cancel' ) }
onRequestClose={ () =>
setIsPatternSelectionModalOpen( false )
}
>
<PatternSelectionModal
clientId={ clientId }
name={ props.name }
/>
</Modal>
) }
</>
);
};

export default QueryEdit;
58 changes: 58 additions & 0 deletions packages/block-library/src/query/edit/pattern-selection-modal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* WordPress dependencies
*/
import { cloneBlock } from '@wordpress/blocks';
import { useAsyncList } from '@wordpress/compose';
import {
__experimentalBlockPatternsList as BlockPatternsList,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { useSelect, useDispatch } from '@wordpress/data';

/**
* Internal dependencies
*/
import { getFirstQueryClientIdFromBlocks } from '../utils';

export default function PatternSelectionModal( { clientId, name } ) {
const { blockPatterns } = useSelect(
( select ) => {
const {
getBlockRootClientId,
__experimentalGetPatternsByBlockTypes,
} = select( blockEditorStore );
const rootClientId = getBlockRootClientId( clientId );

return {
blockPatterns: __experimentalGetPatternsByBlockTypes(
name,
rootClientId
),
};
},
[ clientId, name ]
);
const { replaceBlock, selectBlock } = useDispatch( blockEditorStore );

const onBlockPatternSelect = ( _pattern, blocks ) => {
const clonedBlocks = blocks.map( ( block ) => cloneBlock( block ) );
const firstQueryClientId = getFirstQueryClientIdFromBlocks(
clonedBlocks
);
replaceBlock( clientId, clonedBlocks );
if ( firstQueryClientId ) {
selectBlock( firstQueryClientId );
}
};
const shownBlockPatterns = useAsyncList( blockPatterns, { step: 6 } );

return (
<div className="block-library-query__pattern-selection-content">
<BlockPatternsList
blockPatterns={ blockPatterns }
shownPatterns={ shownBlockPatterns }
onClickPattern={ onBlockPatternSelect }
/>
</div>
);
}
16 changes: 3 additions & 13 deletions packages/block-library/src/query/edit/query-placeholder.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,15 @@ import { useSelect, useDispatch } from '@wordpress/data';
import {
useBlockProps,
__experimentalBlockVariationPicker,
__experimentalGetMatchingVariation as getMatchingVariation,
store as blockEditorStore,
} from '@wordpress/block-editor';
import {
createBlocksFromInnerBlocksTemplate,
store as blocksStore,
} from '@wordpress/blocks';

const QueryPlaceholder = ( { clientId, name, attributes, setAttributes } ) => {
const {
blockType,
defaultVariation,
scopeVariations,
allVariations,
} = useSelect(
function QueryPlaceholder( { clientId, name, setAttributes, icon, label } ) {
const { defaultVariation, scopeVariations } = useSelect(
( select ) => {
const {
getBlockVariations,
Expand All @@ -31,16 +25,12 @@ const QueryPlaceholder = ( { clientId, name, attributes, setAttributes } ) => {
blockType: getBlockType( name ),
defaultVariation: getDefaultBlockVariation( name, 'block' ),
scopeVariations: getBlockVariations( name, 'block' ),
allVariations: getBlockVariations( name ),
};
},
[ name ]
);
const { replaceInnerBlocks } = useDispatch( blockEditorStore );
const blockProps = useBlockProps();
const matchingVariation = getMatchingVariation( attributes, allVariations );
const icon = matchingVariation?.icon || blockType?.icon?.src;
const label = matchingVariation?.title || blockType?.title;
return (
<div { ...blockProps }>
<__experimentalBlockVariationPicker
Expand All @@ -64,6 +54,6 @@ const QueryPlaceholder = ( { clientId, name, attributes, setAttributes } ) => {
/>
</div>
);
};
}

export default QueryPlaceholder;
6 changes: 6 additions & 0 deletions packages/block-library/src/query/edit/query-toolbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default function QueryToolbar( {
attributes: { query, displayLayout },
setQuery,
setDisplayLayout,
openPatternSelectionModal,
} ) {
const maxPageInputId = useInstanceId(
QueryToolbar,
Expand Down Expand Up @@ -128,6 +129,11 @@ export default function QueryToolbar( {
/>
</ToolbarGroup>
) }
<ToolbarGroup className="wp-block-template-part__block-control-group">
<ToolbarButton onClick={ openPatternSelectionModal }>
{ __( 'Replace' ) }
</ToolbarButton>
</ToolbarGroup>
<ToolbarGroup controls={ displayLayoutControls } />
</>
);
Expand Down
13 changes: 13 additions & 0 deletions packages/block-library/src/query/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,16 @@
.wp-block-query__create-new-link {
padding: 0 $grid-unit-20 $grid-unit-20 56px;
}

.block-library-query__pattern-selection-content .block-editor-block-patterns-list {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: $grid-unit-10;

.block-editor-block-patterns-list__list-item {
margin-bottom: 0;
.block-editor-block-preview__container {
max-height: 250px;
}
}
}

0 comments on commit 8125f78

Please sign in to comment.