diff --git a/docs/reference-guides/core-blocks.md b/docs/reference-guides/core-blocks.md index c68bb419467f3..0eed9facfe97a 100644 --- a/docs/reference-guides/core-blocks.md +++ b/docs/reference-guides/core-blocks.md @@ -704,7 +704,7 @@ An advanced block that allows displaying post types based on different query par - **Name:** core/query - **Category:** theme - **Supports:** align (full, wide), layout, ~~html~~ -- **Attributes:** enhancedPagination, namespace, query, queryId, tagName +- **Attributes:** enhancedPagination, infiniteScroll, namespace, query, queryId, tagName ## No results diff --git a/packages/block-library/src/post-template/index.php b/packages/block-library/src/post-template/index.php index 2c7502ca3b665..a5e4eee68bc49 100644 --- a/packages/block-library/src/post-template/index.php +++ b/packages/block-library/src/post-template/index.php @@ -135,9 +135,10 @@ function render_block_core_post_template( $attributes, $content, $block ) { wp_reset_postdata(); return sprintf( - '', + '', $wrapper_attributes, - $content + $content, + $page_key . '-' . ( $use_global_query ? $query->query_vars['paged'] : $page ) ); } diff --git a/packages/block-library/src/query-pagination-next/block.json b/packages/block-library/src/query-pagination-next/block.json index 95b1169dc992f..d1599301d4987 100644 --- a/packages/block-library/src/query-pagination-next/block.json +++ b/packages/block-library/src/query-pagination-next/block.json @@ -17,7 +17,8 @@ "query", "paginationArrow", "showLabel", - "enhancedPagination" + "enhancedPagination", + "query/infiniteScroll" ], "supports": { "reusable": false, diff --git a/packages/block-library/src/query-pagination-next/edit.js b/packages/block-library/src/query-pagination-next/edit.js index ce76889f37c75..4db7dacd12451 100644 --- a/packages/block-library/src/query-pagination-next/edit.js +++ b/packages/block-library/src/query-pagination-next/edit.js @@ -13,7 +13,11 @@ const arrowMap = { export default function QueryPaginationNextEdit( { attributes: { label }, setAttributes, - context: { paginationArrow, showLabel }, + context: { + 'query/infiniteScroll': hasInfiniteScroll, + paginationArrow, + showLabel, + }, } ) { const displayArrow = arrowMap[ paginationArrow ]; return ( @@ -22,7 +26,8 @@ export default function QueryPaginationNextEdit( { onClick={ ( event ) => event.preventDefault() } { ...useBlockProps() } > - { showLabel && ( + { hasInfiniteScroll && __( 'Load more link' ) } + { ! hasInfiniteScroll && showLabel && ( ) } - { displayArrow && ( + { ! hasInfiniteScroll && displayArrow && ( <span className={ `wp-block-query-pagination-next-arrow is-arrow-${ paginationArrow }` } aria-hidden={ true } diff --git a/packages/block-library/src/query-pagination-next/index.php b/packages/block-library/src/query-pagination-next/index.php index ca134f62192f9..155ba64224fd3 100644 --- a/packages/block-library/src/query-pagination-next/index.php +++ b/packages/block-library/src/query-pagination-next/index.php @@ -17,22 +17,29 @@ function render_block_core_query_pagination_next( $attributes, $content, $block ) { $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; $enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination']; + $infinite_scroll = ! empty( $block->context['query/infiniteScroll'] ); $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; $max_page = isset( $block->context['query']['pages'] ) ? (int) $block->context['query']['pages'] : 0; $wrapper_attributes = get_block_wrapper_attributes(); - $show_label = isset( $block->context['showLabel'] ) ? (bool) $block->context['showLabel'] : true; - $default_label = __( 'Next Page' ); - $label_text = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? esc_html( $attributes['label'] ) : $default_label; - $label = $show_label ? $label_text : ''; - $pagination_arrow = get_query_pagination_arrow( $block, true ); - if ( ! $label ) { - $wrapper_attributes .= ' aria-label="' . $label_text . '"'; - } - if ( $pagination_arrow ) { - $label .= $pagination_arrow; + if ( $infinite_scroll ) { + $label = __( 'Load more' ); + } else { + $show_label = isset( $block->context['showLabel'] ) ? (bool) $block->context['showLabel'] : true; + $default_label = __( 'Next Page' ); + $label_text = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? esc_html( $attributes['label'] ) : $default_label; + $label = $show_label ? $label_text : ''; + $pagination_arrow = get_query_pagination_arrow( $block, true ); + + if ( ! $label ) { + $wrapper_attributes .= ' aria-label="' . $label_text . '"'; + } + if ( $pagination_arrow ) { + $label .= $pagination_arrow; + } } + $content = ''; // Check if the pagination is for Query that inherits the global context. diff --git a/packages/block-library/src/query-pagination-numbers/block.json b/packages/block-library/src/query-pagination-numbers/block.json index f05e269d2ece2..7e137f3a05e47 100644 --- a/packages/block-library/src/query-pagination-numbers/block.json +++ b/packages/block-library/src/query-pagination-numbers/block.json @@ -13,7 +13,12 @@ "default": 2 } }, - "usesContext": [ "queryId", "query", "enhancedPagination" ], + "usesContext": [ + "queryId", + "query", + "enhancedPagination", + "query/infiniteScroll" + ], "supports": { "reusable": false, "html": false, diff --git a/packages/block-library/src/query-pagination-numbers/edit.js b/packages/block-library/src/query-pagination-numbers/edit.js index eb83204b2cca2..c63b5b5af47a6 100644 --- a/packages/block-library/src/query-pagination-numbers/edit.js +++ b/packages/block-library/src/query-pagination-numbers/edit.js @@ -41,8 +41,16 @@ const previewPaginationNumbers = ( midSize ) => { export default function QueryPaginationNumbersEdit( { attributes, setAttributes, + context, } ) { + const blockProps = useBlockProps(); + + if ( context[ 'query/infiniteScroll' ] ) { + return null; + } + const { midSize } = attributes; + const paginationNumbers = previewPaginationNumbers( parseInt( midSize, 10 ) ); @@ -67,7 +75,7 @@ export default function QueryPaginationNumbersEdit( { /> </PanelBody> </InspectorControls> - <div { ...useBlockProps() }>{ paginationNumbers }</div> + <div { ...blockProps }>{ paginationNumbers }</div> </> ); } diff --git a/packages/block-library/src/query-pagination-numbers/index.php b/packages/block-library/src/query-pagination-numbers/index.php index 2f9370751f6d2..a617623da76c6 100644 --- a/packages/block-library/src/query-pagination-numbers/index.php +++ b/packages/block-library/src/query-pagination-numbers/index.php @@ -15,6 +15,10 @@ * @return string Returns the pagination numbers for the Query. */ function render_block_core_query_pagination_numbers( $attributes, $content, $block ) { + if ( ! empty( $block->context['query/infiniteScroll'] ) ) { + return ''; + } + $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; $enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination']; $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; diff --git a/packages/block-library/src/query-pagination-previous/block.json b/packages/block-library/src/query-pagination-previous/block.json index fbaac543c1da3..ad07902beb040 100644 --- a/packages/block-library/src/query-pagination-previous/block.json +++ b/packages/block-library/src/query-pagination-previous/block.json @@ -17,7 +17,8 @@ "query", "paginationArrow", "showLabel", - "enhancedPagination" + "enhancedPagination", + "query/infiniteScroll" ], "supports": { "reusable": false, diff --git a/packages/block-library/src/query-pagination-previous/edit.js b/packages/block-library/src/query-pagination-previous/edit.js index 3d8b3cfbbef72..7a52285f0838a 100644 --- a/packages/block-library/src/query-pagination-previous/edit.js +++ b/packages/block-library/src/query-pagination-previous/edit.js @@ -13,14 +13,24 @@ const arrowMap = { export default function QueryPaginationPreviousEdit( { attributes: { label }, setAttributes, - context: { paginationArrow, showLabel }, + context: { + 'query/infiniteScroll': hasInfiniteScroll, + paginationArrow, + showLabel, + }, } ) { + const blockProps = useBlockProps(); + + if ( hasInfiniteScroll ) { + return null; + } + const displayArrow = arrowMap[ paginationArrow ]; return ( <a href="#pagination-previous-pseudo-link" onClick={ ( event ) => event.preventDefault() } - { ...useBlockProps() } + { ...blockProps } > { displayArrow && ( <span diff --git a/packages/block-library/src/query-pagination-previous/index.php b/packages/block-library/src/query-pagination-previous/index.php index b49130a44d8dd..d11892901eb25 100644 --- a/packages/block-library/src/query-pagination-previous/index.php +++ b/packages/block-library/src/query-pagination-previous/index.php @@ -15,6 +15,10 @@ * @return string Returns the previous posts link for the query. */ function render_block_core_query_pagination_previous( $attributes, $content, $block ) { + if ( ! empty( $block->context['query/infiniteScroll'] ) ) { + return ''; + } + $page_key = isset( $block->context['queryId'] ) ? 'query-' . $block->context['queryId'] . '-page' : 'query-page'; $enhanced_pagination = isset( $block->context['enhancedPagination'] ) && $block->context['enhancedPagination']; $page = empty( $_GET[ $page_key ] ) ? 1 : (int) $_GET[ $page_key ]; diff --git a/packages/block-library/src/query/block.json b/packages/block-library/src/query/block.json index d30eccf376579..58536e04e6c4f 100644 --- a/packages/block-library/src/query/block.json +++ b/packages/block-library/src/query/block.json @@ -38,13 +38,18 @@ "enhancedPagination": { "type": "boolean", "default": false + }, + "infiniteScroll": { + "type": "boolean", + "default": false } }, "providesContext": { "queryId": "queryId", "query": "query", "displayLayout": "displayLayout", - "enhancedPagination": "enhancedPagination" + "enhancedPagination": "enhancedPagination", + "query/infiniteScroll": "infiniteScroll" }, "supports": { "align": [ "wide", "full" ], diff --git a/packages/block-library/src/query/edit/inspector-controls/enhanced-pagination-control.js b/packages/block-library/src/query/edit/inspector-controls/enhanced-pagination-control.js index de889c0715c07..9f56e4be5b56f 100644 --- a/packages/block-library/src/query/edit/inspector-controls/enhanced-pagination-control.js +++ b/packages/block-library/src/query/edit/inspector-controls/enhanced-pagination-control.js @@ -11,6 +11,7 @@ import { useUnsupportedBlocks } from '../../utils'; export default function EnhancedPaginationControl( { enhancedPagination, + infiniteScroll, setAttributes, clientId, } ) { @@ -40,6 +41,18 @@ export default function EnhancedPaginationControl( { } ); } } /> + { enhancedPagination && ( + <ToggleControl + label={ __( 'Infinite scroll' ) } + checked={ infiniteScroll } + disabled={ hasUnsupportedBlocks } + onChange={ ( value ) => { + setAttributes( { + infiniteScroll: value, + } ); + } } + /> + ) } </> ); } diff --git a/packages/block-library/src/query/edit/inspector-controls/index.js b/packages/block-library/src/query/edit/inspector-controls/index.js index d276bdec98ed6..165f94146ca69 100644 --- a/packages/block-library/src/query/edit/inspector-controls/index.js +++ b/packages/block-library/src/query/edit/inspector-controls/index.js @@ -43,7 +43,8 @@ const { BlockInfo } = unlock( blockEditorPrivateApis ); export default function QueryInspectorControls( props ) { const { attributes, setQuery, setDisplayLayout, setAttributes, clientId } = props; - const { query, displayLayout, enhancedPagination } = attributes; + const { query, displayLayout, enhancedPagination, infiniteScroll } = + attributes; const { order, orderBy, @@ -206,6 +207,7 @@ export default function QueryInspectorControls( props ) { ) } <EnhancedPaginationControl enhancedPagination={ enhancedPagination } + infiniteScroll={ infiniteScroll } setAttributes={ setAttributes } clientId={ clientId } /> diff --git a/packages/block-library/src/query/view.js b/packages/block-library/src/query/view.js index ccf7081004767..40b86720fee2e 100644 --- a/packages/block-library/src/query/view.js +++ b/packages/block-library/src/query/view.js @@ -68,8 +68,8 @@ store( 'core/query', { ctx.url = ref.href; // Focus the first anchor of the Query block. - const firstAnchor = `[data-wp-navigation-id=${ id }] .wp-block-post-template a[href]`; - document.querySelector( firstAnchor )?.focus(); + // const firstAnchor = `[data-wp-navigation-id=${ id }] .wp-block-post-template a[href]`; + // document.querySelector( firstAnchor )?.focus(); } }, *prefetch() { diff --git a/packages/interactivity/src/directives.js b/packages/interactivity/src/directives.js index 0793dc0cc5d5b..27e60159360ef 100644 --- a/packages/interactivity/src/directives.js +++ b/packages/interactivity/src/directives.js @@ -390,4 +390,25 @@ export default () => { ), { priority: 4 } ); + + const InfiniteScroll = ( { + elementType: Type, + pageId, + children, + ...props + } ) => { + const { current: pages } = useRef( new Map() ); + if ( ! pages.has( pageId ) ) pages.set( pageId, children ); + return <Type { ...props }>{ [ ...pages.values() ] }</Type>; + }; + + directive( + 'infinite-scroll', + ( { directives: { 'infinite-scroll': isr }, element } ) => { + const { value } = isr.find( ( e ) => e.suffix === 'default' ); + element.props.elementType = element.type; + element.props.pageId = value; + element.type = InfiniteScroll; + } + ); };