diff --git a/packages/block-editor/src/components/block-patterns-list/index.js b/packages/block-editor/src/components/block-patterns-list/index.js index 56b39b0171ba16..daea191920efc6 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -18,7 +18,6 @@ import { Icon, symbolFilled } from '@wordpress/icons'; */ import BlockPreview from '../block-preview'; import InserterDraggableBlocks from '../inserter-draggable-blocks'; -import BlockPatternsSyncFilter from '../block-patterns-sync-filter'; const WithToolTip = ( { showTooltip, title, children } ) => { if ( showTooltip ) { @@ -141,10 +140,8 @@ function BlockPatternList( { orientation, label = __( 'Block Patterns' ), showTitlesAsTooltip, - category, } ) { const composite = useCompositeState( { orientation } ); - const [ syncFilter, setSyncFilter ] = useState( 'all' ); return ( - { category === 'custom' && ( - - ) } { blockPatterns.map( ( pattern ) => { const isShown = shownPatterns.includes( pattern ); return isShown ? ( diff --git a/packages/block-editor/src/components/block-patterns-paging/index.js b/packages/block-editor/src/components/block-patterns-paging/index.js index 7b09ed8b9f0a6b..4b57e9b500b8b3 100644 --- a/packages/block-editor/src/components/block-patterns-paging/index.js +++ b/packages/block-editor/src/components/block-patterns-paging/index.js @@ -2,6 +2,7 @@ * WordPress dependencies */ import { + __experimentalVStack as VStack, __experimentalHStack as HStack, __experimentalText as Text, Button, @@ -15,12 +16,7 @@ export default function Pagination( { totalItems, } ) { return ( - + { // translators: %s: Total number of patterns. @@ -31,50 +27,57 @@ export default function Pagination( { ) } - - - + + + + + + + { sprintf( + // translators: %1$s: Current page number, %2$s: Total number of pages. + _x( '%1$s of %2$s', 'paging' ), + currentPage, + numPages + ) } + + + + + - - { sprintf( - // translators: %1$s: Current page number, %2$s: Total number of pages. - _x( '%1$s of %2$s', 'paging' ), - currentPage, - numPages - ) } - - - - - - + ); } diff --git a/packages/block-editor/src/components/block-patterns-sync-filter/index.js b/packages/block-editor/src/components/block-patterns-sync-filter/index.js deleted file mode 100644 index dfb08c0bb9fa51..00000000000000 --- a/packages/block-editor/src/components/block-patterns-sync-filter/index.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * WordPress dependencies - */ -import { - __experimentalToggleGroupControl as ToggleGroupControl, - __experimentalToggleGroupControlOption as ToggleGroupControlOption, -} from '@wordpress/components'; - -import { __ } from '@wordpress/i18n'; - -const SYNC_TYPES = { - full: 'fully', - unsynced: 'unsynced', -}; -const SYNC_FILTERS = { - all: __( 'All' ), - [ SYNC_TYPES.full ]: __( 'Synced' ), - [ SYNC_TYPES.unsynced ]: __( 'Standard' ), -}; - -export default function BlockPatternsSyncFilter( { - setSyncFilter, - syncFilter, -} ) { - return ( - setSyncFilter( value ) } - __nextHasNoMarginBottom - > - { Object.entries( SYNC_FILTERS ).map( ( [ key, optionLabel ] ) => ( - - ) ) } - - ); -} diff --git a/packages/block-editor/src/components/block-patterns-sync-filter/style.scss b/packages/block-editor/src/components/block-patterns-sync-filter/style.scss deleted file mode 100644 index 41044dff03277a..00000000000000 --- a/packages/block-editor/src/components/block-patterns-sync-filter/style.scss +++ /dev/null @@ -1,3 +0,0 @@ -.block-editor-patterns__sync-status-filter { - margin-bottom: $grid-unit-10; -} diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/patterns-list.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/patterns-list.js index 37d17af8c12cba..5223b8e270a76f 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/patterns-list.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/patterns-list.js @@ -1,9 +1,9 @@ /** * WordPress dependencies */ -import { useMemo, useEffect, useState } from '@wordpress/element'; +import { useMemo, useEffect } from '@wordpress/element'; import { _n, sprintf } from '@wordpress/i18n'; -import { useDebounce, useAsyncList } from '@wordpress/compose'; +import { useDebounce } from '@wordpress/compose'; import { __experimentalHeading as Heading } from '@wordpress/components'; import { speak } from '@wordpress/a11y'; @@ -16,10 +16,8 @@ import useInsertionPoint from '../hooks/use-insertion-point'; import usePatternsState from '../hooks/use-patterns-state'; import InserterListbox from '../../inserter-listbox'; import { searchItems } from '../search-items'; -import BlockPatternsSyncFilter from '../../block-patterns-sync-filter'; import BlockPatternsPaging from '../../block-patterns-paging'; - -const INITIAL_INSERTER_RESULTS = 2; +import usePatternsPaging from '../hooks/use-patterns-paging'; function PatternsListHeader( { filterValue, filteredBlockPatternsLength } ) { if ( ! filterValue ) { @@ -46,7 +44,6 @@ function PatternsListHeader( { filterValue, filteredBlockPatternsLength } ) { } function PatternList( { filterValue, selectedCategory, patternCategories } ) { - const [ syncFilter, setSyncFilter ] = useState( 'all' ); const debouncedSpeak = useDebounce( speak, 500 ); const [ destinationRootClientId, onInsertBlocks ] = useInsertionPoint( { shouldFocusBlock: true, @@ -100,9 +97,16 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { debouncedSpeak( resultsFoundMessage ); }, [ filterValue, debouncedSpeak, filteredBlockPatterns.length ] ); - const currentShownPatterns = useAsyncList( filteredBlockPatterns, { - step: INITIAL_INSERTER_RESULTS, - } ); + const { + totalItems, + categoryPatternsList, + numPages, + changePage, + currentPage, + } = usePatternsPaging( + filteredBlockPatterns, + '.components-modal__content.is-scrollable' + ); const hasItems = !! filteredBlockPatterns?.length; return ( @@ -115,26 +119,22 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { ) } { ! hasItems && } - { selectedCategory === 'custom' && ( - - ) } { hasItems && ( ) } - {} } - totalItems={ 40 } - /> + { numPages > 1 && ( + + ) } ); diff --git a/packages/block-editor/src/components/inserter/block-patterns-tab.js b/packages/block-editor/src/components/inserter/block-patterns-tab.js index 5c573e7ea950f8..56c480696b9399 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -9,7 +9,7 @@ import { useEffect, } from '@wordpress/element'; import { _x, __, isRTL } from '@wordpress/i18n'; -import { useAsyncList, useViewportMatch } from '@wordpress/compose'; +import { useViewportMatch } from '@wordpress/compose'; import { __experimentalItemGroup as ItemGroup, __experimentalItem as Item, @@ -28,6 +28,7 @@ import BlockPatternList from '../block-patterns-list'; import PatternsExplorerModal from './block-patterns-explorer/explorer'; import MobileTabNavigation from './mobile-tab-navigation'; import BlockPatternsPaging from '../block-patterns-paging'; +import usePatternsPaging from './hooks/use-patterns-paging'; const noop = () => {}; @@ -169,11 +170,21 @@ export function BlockPatternsCategoryPanel( { [ allPatterns, availableCategories, category.name ] ); - const categoryPatternsList = useAsyncList( currentCategoryPatterns ); - // Hide block pattern preview on unmount. + // eslint-disable-next-line react-hooks/exhaustive-deps useEffect( () => () => onHover( null ), [] ); + const { + totalItems, + categoryPatternsList, + numPages, + changePage, + currentPage, + } = usePatternsPaging( + currentCategoryPatterns, + '.block-editor-inserter__patterns-category-dialog' + ); + if ( ! currentCategoryPatterns.length ) { return null; } @@ -195,12 +206,14 @@ export function BlockPatternsCategoryPanel( { isDraggable showTitlesAsTooltip={ showTitlesAsTooltip } /> - {} } - totalItems={ 40 } - /> + { numPages > 1 && ( + + ) } ); } diff --git a/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js b/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js new file mode 100644 index 00000000000000..b0c7db9da8cb29 --- /dev/null +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js @@ -0,0 +1,49 @@ +/** + * WordPress dependencies + */ +import { useMemo, useState } from '@wordpress/element'; + +import { useAsyncList } from '@wordpress/compose'; + +const PAGE_SIZE = 20; +const INITIAL_INSERTER_RESULTS = 2; + +/** + * Supplies values needed to page the patterns list client side. + * + * @param {Array} currentCategoryPatterns An array of the current categories to display. + * @param {string} scrollContainerClass Class of container to scroll when moving between pages. + * + * @return {Object} Returns the relevant paging values. (totalItems, categoryPatternsList, numPages, changePage, currentPage) + */ +export default function usePatternsPaging( + currentCategoryPatterns, + scrollContainerClass +) { + const [ currentPage, setCurrentPage ] = useState( 1 ); + const totalItems = currentCategoryPatterns.length; + const pageIndex = currentPage - 1; + const list = useMemo( () => { + return currentCategoryPatterns.slice( + pageIndex * PAGE_SIZE, + pageIndex * PAGE_SIZE + PAGE_SIZE + ); + }, [ pageIndex, currentCategoryPatterns ] ); + const categoryPatternsList = useAsyncList( list, { + step: INITIAL_INSERTER_RESULTS, + } ); + const numPages = Math.ceil( currentCategoryPatterns.length / PAGE_SIZE ); + const changePage = ( page ) => { + const scrollContainer = document.querySelector( scrollContainerClass ); + scrollContainer?.scrollTo( 0, 0 ); + + setCurrentPage( page ); + }; + return { + totalItems, + categoryPatternsList, + numPages, + changePage, + currentPage, + }; +}