Skip to content

Commit

Permalink
[Block Library - Query Pagination Next/Previous]: Add an arrow attrib…
Browse files Browse the repository at this point in the history
…ute and sync next/previous block's arrow (#33656)

* Query Pagination Next: Add an arrow attribute

* change to a segmented control

* update comment

* Use CSS for RTL

* formatting change

* add arrow inside the link

* sync next+previous icons

* handle rtl for used arrows

* update fixtures + polish

* add small margin

* update unit and control's label

* use block context and handle the arrow in `QueryPagination` block

* fix arrow css class

* remove unneeded provider

* fix fixtures

Co-authored-by: ntsekouras <[email protected]>
  • Loading branch information
scruffian and ntsekouras authored Sep 7, 2021
1 parent 491eb8a commit 7dc480d
Show file tree
Hide file tree
Showing 12 changed files with 228 additions and 23 deletions.
36 changes: 36 additions & 0 deletions lib/compat/wordpress-5.8/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,39 @@ function gutenberg_register_legacy_query_loop_block() {

add_action( 'init', 'gutenberg_register_legacy_query_loop_block' );
}

if ( ! function_exists( 'get_query_pagination_arrow' ) ) {
/**
* Helper function that returns the proper pagination arrow html for
* `QueryPaginationNext` and `QueryPaginationPrevious` blocks based
* on the provided `paginationArrow` from `QueryPagination` context.
*
* It's used in QueryPaginationNext and QueryPaginationPrevious blocks.
*
* @param WP_Block $block Block instance.
* @param boolean $is_next Flag for hanlding `next/previous` blocks.
*
* @return string|null Returns the constructed WP_Query arguments.
*/
function get_query_pagination_arrow( $block, $is_next ) {
$arrow_map = array(
'none' => '',
'arrow' => array(
'next' => '',
'previous' => '',
),
'chevron' => array(
'next' => '»',
'previous' => '«',
),
);
if ( ! empty( $block->context['paginationArrow'] ) && array_key_exists( $block->context['paginationArrow'], $arrow_map ) && ! empty( $arrow_map[ $block->context['paginationArrow'] ] ) ) {
$pagination_type = $is_next ? 'next' : 'previous';
$arrow_attribute = $block->context['paginationArrow'];
$arrow = $arrow_map[ $block->context['paginationArrow'] ][ $pagination_type ];
$arrow_classes = "wp-block-query-pagination-$pagination_type-arrow is-arrow-$arrow_attribute";
return "<span class='$arrow_classes'>$arrow</span>";
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"type": "string"
}
},
"usesContext": [ "queryId", "query" ],
"usesContext": [ "queryId", "query", "paginationArrow" ],
"supports": {
"reusable": false,
"html": false,
Expand Down
38 changes: 30 additions & 8 deletions packages/block-library/src/query-pagination-next/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,41 @@
import { __ } from '@wordpress/i18n';
import { useBlockProps, PlainText } from '@wordpress/block-editor';

const arrowMap = {
none: '',
arrow: '→',
chevron: '»',
};

export default function QueryPaginationNextEdit( {
attributes: { label },
setAttributes,
context: { paginationArrow },
} ) {
const displayArrow = arrowMap[ paginationArrow ];
return (
<PlainText
__experimentalVersion={ 2 }
tagName="a"
aria-label={ __( 'Next page link' ) }
placeholder={ __( 'Next Page' ) }
value={ label }
onChange={ ( newLabel ) => setAttributes( { label: newLabel } ) }
<a
href="#pagination-next-pseudo-link"
onClick={ ( event ) => event.preventDefault() }
{ ...useBlockProps() }
/>
>
<PlainText
__experimentalVersion={ 2 }
tagName="span"
aria-label={ __( 'Next page link' ) }
placeholder={ __( 'Next Page' ) }
value={ label }
onChange={ ( newLabel ) =>
setAttributes( { label: newLabel } )
}
/>
{ displayArrow && (
<span
className={ `wp-block-query-pagination-next-arrow is-arrow-${ paginationArrow }` }
>
{ displayArrow }
</span>
) }
</a>
);
}
6 changes: 5 additions & 1 deletion packages/block-library/src/query-pagination-next/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ function render_block_core_query_pagination_next( $attributes, $content, $block
$wrapper_attributes = get_block_wrapper_attributes();
$default_label = __( 'Next Page' );
$label = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
$content = '';
$pagination_arrow = get_query_pagination_arrow( $block, true );
if ( $pagination_arrow ) {
$label .= $pagination_arrow;
}
$content = '';

// Check if the pagination is for Query that inherits the global context.
if ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"type": "string"
}
},
"usesContext": [ "queryId", "query" ],
"usesContext": [ "queryId", "query", "paginationArrow" ],
"supports": {
"reusable": false,
"html": false,
Expand Down
38 changes: 30 additions & 8 deletions packages/block-library/src/query-pagination-previous/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,41 @@
import { __ } from '@wordpress/i18n';
import { useBlockProps, PlainText } from '@wordpress/block-editor';

const arrowMap = {
none: '',
arrow: '←',
chevron: '«',
};

export default function QueryPaginationPreviousEdit( {
attributes: { label },
setAttributes,
context: { paginationArrow },
} ) {
const displayArrow = arrowMap[ paginationArrow ];
return (
<PlainText
__experimentalVersion={ 2 }
tagName="a"
aria-label={ __( 'Previous page link' ) }
placeholder={ __( 'Previous Page' ) }
value={ label }
onChange={ ( newLabel ) => setAttributes( { label: newLabel } ) }
<a
href="#pagination-previous-pseudo-link"
onClick={ ( event ) => event.preventDefault() }
{ ...useBlockProps() }
/>
>
{ displayArrow && (
<span
className={ `wp-block-query-pagination-previous-arrow is-arrow-${ paginationArrow }` }
>
{ displayArrow }
</span>
) }
<PlainText
__experimentalVersion={ 2 }
tagName="span"
aria-label={ __( 'Previous page link' ) }
placeholder={ __( 'Previous Page' ) }
value={ label }
onChange={ ( newLabel ) =>
setAttributes( { label: newLabel } )
}
/>
</a>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ function render_block_core_query_pagination_previous( $attributes, $content, $bl
$wrapper_attributes = get_block_wrapper_attributes();
$default_label = __( 'Previous Page' );
$label = isset( $attributes['label'] ) && ! empty( $attributes['label'] ) ? $attributes['label'] : $default_label;
$content = '';
$pagination_arrow = get_query_pagination_arrow( $block, false );
if ( $pagination_arrow ) {
$label = $pagination_arrow . $label;
}
$content = '';
// Check if the pagination is for Query that inherits the global context
// and handle appropriately.
if ( isset( $block->context['query']['inherit'] ) && $block->context['query']['inherit'] ) {
Expand Down
9 changes: 9 additions & 0 deletions packages/block-library/src/query-pagination/block.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@
"parent": [ "core/query" ],
"description": "Displays a paginated navigation to next/previous set of posts, when applicable.",
"textdomain": "default",
"attributes": {
"paginationArrow": {
"type": "string",
"default": "none"
}
},
"usesContext": [ "queryId", "query" ],
"providesContext": {
"paginationArrow": "paginationArrow"
},
"supports": {
"align": true,
"reusable": false,
Expand Down
48 changes: 46 additions & 2 deletions packages/block-library/src/query-pagination/edit.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
/**
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import {
InspectorControls,
useBlockProps,
__experimentalUseInnerBlocksProps as useInnerBlocksProps,
store as blockEditorStore,
} from '@wordpress/block-editor';
import { useSelect } from '@wordpress/data';
import { PanelBody } from '@wordpress/components';

/**
* Internal dependencies
*/
import { QueryPaginationArrowControls } from './query-pagination-arrow-controls';

const TEMPLATE = [
[ 'core/query-pagination-previous' ],
[ 'core/query-pagination-numbers' ],
[ 'core/query-pagination-next' ],
];

export default function QueryPaginationEdit() {
export default function QueryPaginationEdit( {
attributes: { paginationArrow },
setAttributes,
clientId,
} ) {
const hasNextPreviousBlocks = useSelect( ( select ) => {
const { getBlocks } = select( blockEditorStore );
const innerBlocks = getBlocks( clientId );
/**
* Show the `paginationArrow` control only if a
* `QueryPaginationNext/Previous` block exists.
*/
return innerBlocks?.find( ( innerBlock ) => {
return [
'core/query-pagination-next',
'core/query-pagination-previous',
].includes( innerBlock.name );
} );
}, [] );
const blockProps = useBlockProps();
const innerBlocksProps = useInnerBlocksProps( blockProps, {
template: TEMPLATE,
Expand All @@ -23,5 +51,21 @@ export default function QueryPaginationEdit() {
],
orientation: 'horizontal',
} );
return <div { ...innerBlocksProps } />;
return (
<>
{ hasNextPreviousBlocks && (
<InspectorControls>
<PanelBody title={ __( 'Settings' ) }>
<QueryPaginationArrowControls
value={ paginationArrow }
onChange={ ( value ) => {
setAttributes( { paginationArrow: value } );
} }
/>
</PanelBody>
</InspectorControls>
) }
<div { ...innerBlocksProps } />
</>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* WordPress dependencies
*/
import { __, _x } from '@wordpress/i18n';
import {
__experimentalToggleGroupControl as ToggleGroupControl,
__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';

export function QueryPaginationArrowControls( { value, onChange } ) {
return (
<ToggleGroupControl
label={ __( 'Arrow' ) }
value={ value }
onChange={ onChange }
help={ __(
'A decorative arrow appended to the next and previous page link.'
) }
isBlock
>
<ToggleGroupControlOption
value="none"
label={ _x(
'None',
'Arrow option for Query Pagination Next/Previous blocks'
) }
/>
<ToggleGroupControlOption
value="arrow"
label={ _x(
'Arrow',
'Arrow option for Query Pagination Next/Previous blocks'
) }
/>
<ToggleGroupControlOption
value="chevron"
label={ _x(
'Chevron',
'Arrow option for Query Pagination Next/Previous blocks'
) }
/>
</ToggleGroupControl>
);
}
18 changes: 18 additions & 0 deletions packages/block-library/src/query-pagination/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,22 @@ $pagination-margin: 0.5em;
margin-right: 0;
}
}
.wp-block-query-pagination-previous-arrow {
margin-right: 1ch;
display: inline-block; // Needed so that the transform works.
// chevron(`»`) symbol doesn't need the mirroring by us.
&:not(.is-arrow-chevron) {
// Flip for RTL.
transform: scaleX(1) #{"/*rtl:scaleX(-1);*/"}; // This points the arrow right for LTR and left for RTL.
}
}
.wp-block-query-pagination-next-arrow {
margin-left: 1ch;
display: inline-block; // Needed so that the transform works.
// chevron(`»`) symbol doesn't need the mirroring by us.
&:not(.is-arrow-chevron) {
// Flip for RTL.
transform: scaleX(1) #{"/*rtl:scaleX(-1);*/"}; // This points the arrow right for LTR and left for RTL.
}
}
}
4 changes: 3 additions & 1 deletion test/integration/fixtures/blocks/core__query-pagination.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"clientId": "_clientId_0",
"name": "core/query-pagination",
"isValid": true,
"attributes": {},
"attributes": {
"paginationArrow": "none"
},
"innerBlocks": [],
"originalContent": "<div class=\"wp-block-query-pagination\"></div>"
}
Expand Down

0 comments on commit 7dc480d

Please sign in to comment.