From 8125f780ac8cfff79880040cecb4f76c94be7e1e Mon Sep 17 00:00:00 2001 From: Jorge Date: Tue, 22 Feb 2022 16:38:10 +0000 Subject: [PATCH] Update query block creation and replacement flows --- .../block-library/src/query/edit/index.js | 140 ++++++++++++++---- .../src/query/edit/pattern-selection-modal.js | 58 ++++++++ .../src/query/edit/query-placeholder.js | 16 +- .../src/query/edit/query-toolbar.js | 6 + packages/block-library/src/query/editor.scss | 13 ++ 5 files changed, 193 insertions(+), 40 deletions(-) create mode 100644 packages/block-library/src/query/edit/pattern-selection-modal.js diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index f31945a08f1d3..40f9d64df50a9 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -2,9 +2,9 @@ * 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, @@ -12,9 +12,14 @@ import { 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'; /** @@ -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, @@ -102,6 +111,7 @@ export function QueryContent( { attributes, setAttributes } ) { attributes={ attributes } setQuery={ updateQuery } setDisplayLayout={ updateDisplayLayout } + openPatternSelectionModal={ openPatternSelectionModal } /> @@ -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 ( + ); - replaceBlock( clientId, clonedBlocks ); - if ( firstQueryClientId ) { - selectBlock( firstQueryClientId ); - } - }; - // `startBlankComponent` is what to render when clicking `Start blank` - // or if no matched patterns are found. + } return (
- } - onBlockPatternSelect={ onBlockPatternSelect } - /> + + { !! hasPatterns && ( + + ) } + + +
); } 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 ; + return ( + <> + + setIsPatternSelectionModalOpen( true ) + } + /> + { isPatternSelectionModalOpen && ( + + setIsPatternSelectionModalOpen( false ) + } + > + + + ) } + + ); }; export default QueryEdit; diff --git a/packages/block-library/src/query/edit/pattern-selection-modal.js b/packages/block-library/src/query/edit/pattern-selection-modal.js new file mode 100644 index 0000000000000..fb6cc5786687b --- /dev/null +++ b/packages/block-library/src/query/edit/pattern-selection-modal.js @@ -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 ( +
+ +
+ ); +} diff --git a/packages/block-library/src/query/edit/query-placeholder.js b/packages/block-library/src/query/edit/query-placeholder.js index 51b31d59e11c6..07151aff4823b 100644 --- a/packages/block-library/src/query/edit/query-placeholder.js +++ b/packages/block-library/src/query/edit/query-placeholder.js @@ -5,7 +5,6 @@ import { useSelect, useDispatch } from '@wordpress/data'; import { useBlockProps, __experimentalBlockVariationPicker, - __experimentalGetMatchingVariation as getMatchingVariation, store as blockEditorStore, } from '@wordpress/block-editor'; import { @@ -13,13 +12,8 @@ import { 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, @@ -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 (
<__experimentalBlockVariationPicker @@ -64,6 +54,6 @@ const QueryPlaceholder = ( { clientId, name, attributes, setAttributes } ) => { />
); -}; +} export default QueryPlaceholder; diff --git a/packages/block-library/src/query/edit/query-toolbar.js b/packages/block-library/src/query/edit/query-toolbar.js index 92db79c7dad7b..c9e02a5d2a3ac 100644 --- a/packages/block-library/src/query/edit/query-toolbar.js +++ b/packages/block-library/src/query/edit/query-toolbar.js @@ -16,6 +16,7 @@ export default function QueryToolbar( { attributes: { query, displayLayout }, setQuery, setDisplayLayout, + openPatternSelectionModal, } ) { const maxPageInputId = useInstanceId( QueryToolbar, @@ -128,6 +129,11 @@ export default function QueryToolbar( { /> ) } + + + { __( 'Replace' ) } + + ); diff --git a/packages/block-library/src/query/editor.scss b/packages/block-library/src/query/editor.scss index 27d4ce00c4939..3b3ed11676ac3 100644 --- a/packages/block-library/src/query/editor.scss +++ b/packages/block-library/src/query/editor.scss @@ -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; + } + } +}