Skip to content

Commit

Permalink
Patterns: Add client side pagination to patterns list (#52538)
Browse files Browse the repository at this point in the history
Co-authored-by: Saxon Fletcher <saxonafletcher@gmail.com>
  • Loading branch information
glendaviesnz and SaxonF committed Jul 13, 2023
1 parent f1caa12 commit ea4261a
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 21 deletions.
117 changes: 101 additions & 16 deletions packages/edit-site/src/components/page-patterns/grid.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,115 @@
/**
* WordPress dependencies
*/
import { __experimentalText as Text } from '@wordpress/components';
import { useRef } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import {
__experimentalHStack as HStack,
__experimentalText as Text,
Button,
} from '@wordpress/components';
import { useRef, useState, useMemo } from '@wordpress/element';
import { __, _x, _n, sprintf } from '@wordpress/i18n';
import { useAsyncList } from '@wordpress/compose';

/**
* Internal dependencies
*/
import GridItem from './grid-item';

const PAGE_SIZE = 100;
const PAGE_SIZE = 20;

function Pagination( { currentPage, numPages, changePage, totalItems } ) {
return (
<HStack
expanded={ false }
spacing={ 3 }
className="edit-site-patterns__grid-pagination"
>
<Text variant="muted">
{
// translators: %s: Total number of patterns.
sprintf(
// translators: %s: Total number of patterns.
_n( '%s item', '%s items', totalItems ),
totalItems
)
}
</Text>
<HStack expanded={ false } spacing={ 1 }>
<Button
variant="tertiary"
onClick={ () => changePage( 1 ) }
disabled={ currentPage === 1 }
aria-label={ __( 'First page' ) }
>
«
</Button>
<Button
variant="tertiary"
onClick={ () => changePage( currentPage - 1 ) }
disabled={ currentPage === 1 }
aria-label={ __( 'Previous page' ) }
>
</Button>
</HStack>
<Text variant="muted">
{ sprintf(
// translators: %1$s: Current page number, %2$s: Total number of pages.
_x( '%1$s of %2$s', 'paging' ),
currentPage,
numPages
) }
</Text>
<HStack expanded={ false } spacing={ 1 }>
<Button
variant="tertiary"
onClick={ () => changePage( currentPage + 1 ) }
disabled={ currentPage === numPages }
aria-label={ __( 'Next page' ) }
>
</Button>
<Button
variant="tertiary"
onClick={ () => changePage( numPages ) }
disabled={ currentPage === numPages }
aria-label={ __( 'Last page' ) }
>
»
</Button>
</HStack>
</HStack>
);
}

export default function Grid( { categoryId, items, ...props } ) {
const [ currentPage, setCurrentPage ] = useState( 1 );
const gridRef = useRef();
const totalItems = items.length;
const pageIndex = currentPage - 1;

if ( ! items?.length ) {
const list = useMemo(
() =>
items.slice(
pageIndex * PAGE_SIZE,
pageIndex * PAGE_SIZE + PAGE_SIZE
),
[ pageIndex, items ]
);

const asyncList = useAsyncList( list, { step: 10 } );

if ( ! list?.length ) {
return null;
}

const list = items.slice( 0, PAGE_SIZE );
const restLength = items.length - PAGE_SIZE;
const numPages = Math.ceil( items.length / PAGE_SIZE );
const changePage = ( page ) => {
const scrollContainer = document.querySelector( '.edit-site-patterns' );
scrollContainer?.scrollTo( 0, 0 );

setCurrentPage( page );
};

return (
<>
Expand All @@ -30,22 +119,18 @@ export default function Grid( { categoryId, items, ...props } ) {
{ ...props }
ref={ gridRef }
>
{ list.map( ( item ) => (
{ asyncList.map( ( item ) => (
<GridItem
key={ item.name }
item={ item }
categoryId={ categoryId }
/>
) ) }
</ul>
{ restLength > 0 && (
<Text variant="muted" as="p" align="center">
{ sprintf(
/* translators: %d: number of patterns */
__( '+ %d more patterns discoverable by searching' ),
restLength
) }
</Text>
{ numPages > 1 && (
<Pagination
{ ...{ currentPage, numPages, changePage, totalItems } }
/>
) }
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { __, isRTL } from '@wordpress/i18n';
import { chevronLeft, chevronRight } from '@wordpress/icons';
import { privateApis as routerPrivateApis } from '@wordpress/router';
import { useViewportMatch, useAsyncList } from '@wordpress/compose';
import { useViewportMatch } from '@wordpress/compose';

/**
* Internal dependencies
Expand Down Expand Up @@ -70,7 +70,6 @@ export default function PatternsList( { categoryId, type } ) {
const hasPatterns = patterns.length;
const title = SYNC_FILTERS[ syncFilter ];
const description = SYNC_DESCRIPTIONS[ syncFilter ];
const shownPatterns = useAsyncList( patterns );

return (
<VStack spacing={ 6 }>
Expand Down Expand Up @@ -132,7 +131,7 @@ export default function PatternsList( { categoryId, type } ) {
</Flex>
{ syncFilter !== 'all' && (
<VStack className="edit-site-patterns__section-header">
<Heading as="h3" level={ 4 } id={ titleId }>
<Heading as="h3" level={ 5 } id={ titleId }>
{ title }
</Heading>
{ description ? (
Expand All @@ -145,7 +144,7 @@ export default function PatternsList( { categoryId, type } ) {
{ hasPatterns && (
<Grid
categoryId={ categoryId }
items={ shownPatterns }
items={ patterns }
aria-labelledby={ titleId }
aria-describedby={ descriptionId }
/>
Expand Down
22 changes: 21 additions & 1 deletion packages/edit-site/src/components/page-patterns/style.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.edit-site-patterns {
background: rgba(0, 0, 0, 0.15);
border: 1px solid $gray-800;
background: none;
margin: $header-height 0 0;
border-radius: 0;
.components-base-control {
width: 100%;
@include break-medium {
Expand Down Expand Up @@ -59,6 +61,23 @@
background: $gray-700;
color: $gray-100;
}

.edit-site-patterns__grid-pagination {
width: fit-content;
.components-button.is-tertiary {
width: $button-size-compact;
height: $button-size-compact;
color: $gray-100;
background-color: $gray-800;
&:disabled {
color: $gray-600;
background: none;
}
&:hover:not(:disabled) {
background-color: $gray-700;
}
}
}
}

.edit-site-patterns__section-header {
Expand All @@ -74,6 +93,7 @@
// Small top padding required to avoid cutting off the visible outline
// when hovering items.
padding-top: $border-width-focus-fallback;
margin-top: 0;
margin-bottom: $grid-unit-40;
@include break-large {
grid-template-columns: 1fr 1fr;
Expand Down

0 comments on commit ea4261a

Please sign in to comment.