diff --git a/packages/block-library/src/post-featured-image/style.scss b/packages/block-library/src/post-featured-image/style.scss index eaa2b5f413733..1deddff9a9fec 100644 --- a/packages/block-library/src/post-featured-image/style.scss +++ b/packages/block-library/src/post-featured-image/style.scss @@ -2,4 +2,8 @@ a { display: inline-block; } + img { + max-width: 100%; + height: auto; + } } diff --git a/packages/block-library/src/query-loop/block.json b/packages/block-library/src/query-loop/block.json index 963afbe71c630..5373403ea79a5 100644 --- a/packages/block-library/src/query-loop/block.json +++ b/packages/block-library/src/query-loop/block.json @@ -5,7 +5,8 @@ "usesContext": [ "queryId", "query", - "queryContext" + "queryContext", + "layout" ], "supports": { "reusable": false, diff --git a/packages/block-library/src/query-loop/edit.js b/packages/block-library/src/query-loop/edit.js index a87b8b33ca13d..a32ffd6741050 100644 --- a/packages/block-library/src/query-loop/edit.js +++ b/packages/block-library/src/query-loop/edit.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -38,6 +43,7 @@ export default function QueryLoopEdit( { sticky, } = {}, queryContext, + layout: { type: layoutType = 'flex', columns = 1 } = {}, }, } ) { const [ { page } ] = useQueryContext() || queryContext || [ {} ]; @@ -102,7 +108,13 @@ export default function QueryLoopEdit( { } ) ), [ posts ] ); - const blockProps = useBlockProps(); + const hasLayoutFlex = layoutType === 'flex' && columns > 1; + const blockProps = useBlockProps( { + className: classnames( { + 'is-flex-container': hasLayoutFlex, + [ `columns-${ columns }` ]: hasLayoutFlex, + } ), + } ); const innerBlocksProps = useInnerBlocksProps( {}, { template: TEMPLATE } ); if ( ! posts ) { @@ -114,7 +126,7 @@ export default function QueryLoopEdit( { } return ( -
+ ); } diff --git a/packages/block-library/src/query-loop/editor.scss b/packages/block-library/src/query-loop/editor.scss index 294eb615109be..39a614277d58d 100644 --- a/packages/block-library/src/query-loop/editor.scss +++ b/packages/block-library/src/query-loop/editor.scss @@ -1,3 +1,5 @@ -.editor-styles-wrapper .wp-block.wp-block-query-loop { +.wp-block.wp-block-query-loop { max-width: 100%; + padding-left: 0; + list-style: none; } diff --git a/packages/block-library/src/query-loop/index.php b/packages/block-library/src/query-loop/index.php index 5acc340bd66e2..d1aef57b1cb66 100644 --- a/packages/block-library/src/query-loop/index.php +++ b/packages/block-library/src/query-loop/index.php @@ -69,9 +69,18 @@ function render_block_core_query_loop( $attributes, $content, $block ) { $posts = get_posts( $query ); + $classnames = ''; + if ( isset( $block->context['layout'] ) && isset( $block->context['query'] ) ) { + if ( isset( $block->context['layout']['type'] ) && 'flex' === $block->context['layout']['type'] ) { + $classnames = "is-flex-container columns-{$block->context['layout']['columns']}"; + } + } + + $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => $classnames ) ); + $content = ''; foreach ( $posts as $post ) { - $content .= ( + $block_content = ( new WP_Block( $block->parsed_block, array( @@ -80,8 +89,13 @@ function render_block_core_query_loop( $attributes, $content, $block ) { ) ) )->render( array( 'dynamic' => false ) ); + $content .= "
  • {$block_content}
  • "; } - return $content; + return sprintf( + '', + $wrapper_attributes, + $content + ); } /** diff --git a/packages/block-library/src/query-loop/style.scss b/packages/block-library/src/query-loop/style.scss new file mode 100644 index 0000000000000..40413f4041a27 --- /dev/null +++ b/packages/block-library/src/query-loop/style.scss @@ -0,0 +1,32 @@ +.wp-block-query-loop { + max-width: 100%; + list-style: none; + padding: 0; + + li { + clear: both; + } + + &.is-flex-container { + flex-direction: row; + display: flex; + flex-wrap: wrap; + + li { + margin: 0 1.25em 1.25em 0; + width: 100%; + } + + @include break-small { + @for $i from 2 through 6 { + &.is-flex-container.columns-#{ $i } > li { + width: calc((100% / #{ $i }) - 1.25em + (1.25em / #{ $i })); + + &:nth-child( #{ $i }n ) { + margin-right: 0; + } + } + } + } + } +} diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index f01c6b66081e3..7477e03d6f848 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -22,11 +22,18 @@ "exclude": [], "sticky": "" } + }, + "layout": { + "type": "object", + "default": { + "type": "list" + } } }, "providesContext": { "queryId": "queryId", - "query": "query" + "query": "query", + "layout": "layout" }, "usesContext": [ "postId" diff --git a/packages/block-library/src/query/edit/index.js b/packages/block-library/src/query/edit/index.js index 40b9cc4ab755d..45be4c7f88537 100644 --- a/packages/block-library/src/query/edit/index.js +++ b/packages/block-library/src/query/edit/index.js @@ -21,10 +21,11 @@ import { DEFAULTS_POSTS_PER_PAGE } from '../constants'; const TEMPLATE = [ [ 'core/query-loop' ] ]; export function QueryContent( { - attributes: { queryId, query }, + attributes, context: { postId }, setAttributes, } ) { + const { queryId, query, layout } = attributes; const instanceId = useInstanceId( QueryContent ); const blockProps = useBlockProps(); const innerBlocksProps = useInnerBlocksProps( {}, { template: TEMPLATE } ); @@ -59,11 +60,21 @@ export function QueryContent( { }, [ queryId, instanceId ] ); const updateQuery = ( newQuery ) => setAttributes( { query: { ...query, ...newQuery } } ); + const updateLayout = ( newLayout ) => + setAttributes( { layout: { ...layout, ...newLayout } } ); return ( <> - + - +
    diff --git a/packages/block-library/src/query/edit/query-inspector-controls.js b/packages/block-library/src/query/edit/query-inspector-controls.js index a558884ca1f91..0be60543a6512 100644 --- a/packages/block-library/src/query/edit/query-inspector-controls.js +++ b/packages/block-library/src/query/edit/query-inspector-controls.js @@ -13,6 +13,8 @@ import { TextControl, FormTokenField, SelectControl, + RangeControl, + Notice, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { InspectorControls } from '@wordpress/block-editor'; @@ -31,7 +33,11 @@ const stickyOptions = [ { label: __( 'Only' ), value: 'only' }, ]; -export default function QueryInspectorControls( { query, setQuery } ) { +export default function QueryInspectorControls( { + attributes: { query, layout }, + setQuery, + setLayout, +} ) { const { order, orderBy, @@ -139,6 +145,26 @@ export default function QueryInspectorControls( { query, setQuery } ) { label={ __( 'Post Type' ) } onChange={ onPostTypeChange } /> + { layout?.type === 'flex' && ( + <> + + setLayout( { columns: value } ) + } + min={ 2 } + max={ Math.max( 6, layout.columns ) } + /> + { layout.columns > 6 && ( + + { __( + 'This column count exceeds the recommended amount and may cause visual breakage.' + ) } + + ) } + + ) } setQuery( { order: value } ) } diff --git a/packages/block-library/src/query/edit/query-toolbar.js b/packages/block-library/src/query/edit/query-toolbar.js index d4c5539df653f..dd079aa1a8110 100644 --- a/packages/block-library/src/query/edit/query-toolbar.js +++ b/packages/block-library/src/query/edit/query-toolbar.js @@ -10,66 +10,88 @@ import { __experimentalNumberControl as NumberControl, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { settings } from '@wordpress/icons'; +import { settings, list, grid } from '@wordpress/icons'; -export default function QueryToolbar( { query, setQuery } ) { +export default function QueryToolbar( { + attributes: { query, layout }, + setQuery, + setLayout, +} ) { + const layoutControls = [ + { + icon: list, + title: __( 'List view' ), + onClick: () => setLayout( { type: 'list' } ), + isActive: layout?.type === 'list', + }, + { + icon: grid, + title: __( 'Grid view' ), + onClick: () => + setLayout( { type: 'flex', columns: layout?.columns || 3 } ), + isActive: layout?.type === 'flex', + }, + ]; return ( - - ( - - ) } - renderContent={ () => ( - <> - - - setQuery( { perPage: +value ?? -1 } ) - } - step="1" - value={ query.perPage } - isDragEnabled={ false } - /> - - - - setQuery( { offset: +value } ) - } - step="1" - value={ query.offset } - isDragEnabled={ false } - /> - - - - setQuery( { pages: value ?? -1 } ) - } - /> - - - ) } - /> - + <> + + ( + + ) } + renderContent={ () => ( + <> + + + setQuery( { perPage: +value ?? -1 } ) + } + step="1" + value={ query.perPage } + isDragEnabled={ false } + /> + + + + setQuery( { offset: +value } ) + } + step="1" + value={ query.offset } + isDragEnabled={ false } + /> + + + + setQuery( { pages: value ?? -1 } ) + } + /> + + + ) } + /> + + + ); } diff --git a/packages/block-library/src/style.scss b/packages/block-library/src/style.scss index 899f51a4b688a..eeafa5502873c 100644 --- a/packages/block-library/src/style.scss +++ b/packages/block-library/src/style.scss @@ -26,6 +26,7 @@ @import "./paragraph/style.scss"; @import "./post-author/style.scss"; @import "./pullquote/style.scss"; +@import "./query-loop/style.scss"; @import "./quote/style.scss"; @import "./rss/style.scss"; @import "./search/style.scss"; diff --git a/packages/e2e-tests/fixtures/blocks/core__query.json b/packages/e2e-tests/fixtures/blocks/core__query.json index 3e90d6a3f9c0f..235fcefff51e2 100644 --- a/packages/e2e-tests/fixtures/blocks/core__query.json +++ b/packages/e2e-tests/fixtures/blocks/core__query.json @@ -17,6 +17,9 @@ "search": "", "exclude": [], "sticky": "" + }, + "layout": { + "type": "list" } }, "innerBlocks": [],