From fc921a7bafcbd7dc0a6e1f3f4e807c3131ada3c0 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 4 Sep 2023 11:09:34 +1200 Subject: [PATCH 01/61] merge synced patterns into patterns tab and add paging --- .../components/block-patterns-list/index.js | 16 ++++ .../components/block-patterns-list/style.scss | 7 +- .../components/block-patterns-paging/index.js | 83 ++++++++++++++++++ .../block-patterns-paging/style.scss | 19 +++++ .../block-patterns-explorer/patterns-list.js | 29 +++++-- .../components/inserter/block-patterns-tab.js | 25 +++++- .../inserter/hooks/use-patterns-paging.js | 49 +++++++++++ .../inserter/hooks/use-patterns-state.js | 8 +- .../src/components/inserter/menu.js | 16 +--- .../inserter/reusable-blocks-tab.js | 84 ------------------- .../src/components/inserter/tabs.js | 14 +--- .../inserter/test/reusable-blocks-tab.js | 73 ---------------- packages/block-editor/src/store/selectors.js | 41 ++++----- packages/block-editor/src/style.scss | 1 + 14 files changed, 245 insertions(+), 220 deletions(-) create mode 100644 packages/block-editor/src/components/block-patterns-paging/index.js create mode 100644 packages/block-editor/src/components/block-patterns-paging/style.scss create mode 100644 packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js delete mode 100644 packages/block-editor/src/components/inserter/reusable-blocks-tab.js delete mode 100644 packages/block-editor/src/components/inserter/test/reusable-blocks-tab.js 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 ec2aad3da2b7a4..daea191920efc6 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -11,6 +11,7 @@ import { } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; +import { Icon, symbolFilled } from '@wordpress/icons'; /** * Internal dependencies @@ -101,6 +102,21 @@ function BlockPattern( { { pattern.description } ) } + { pattern.id && ! pattern.syncStatus && ( + + + + + + ) } diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index ab80fc71d36dfe..fbc1fddbbd1cae 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -40,9 +40,14 @@ @include button-style-outset__focus(var(--wp-admin-theme-color)); } - &:hover .block-editor-block-patterns-list__item-title, &:focus .block-editor-block-patterns-list__item-title { color: var(--wp-admin-theme-color); } + + .block-editor-patterns__pattern-icon { + fill: #fff; + background: var(--wp-block-synced-color); + border-radius: 4px; + } } diff --git a/packages/block-editor/src/components/block-patterns-paging/index.js b/packages/block-editor/src/components/block-patterns-paging/index.js new file mode 100644 index 00000000000000..4b57e9b500b8b3 --- /dev/null +++ b/packages/block-editor/src/components/block-patterns-paging/index.js @@ -0,0 +1,83 @@ +/** + * WordPress dependencies + */ +import { + __experimentalVStack as VStack, + __experimentalHStack as HStack, + __experimentalText as Text, + Button, +} from '@wordpress/components'; +import { __, _x, _n, sprintf } from '@wordpress/i18n'; + +export default function Pagination( { + currentPage, + numPages, + changePage, + totalItems, +} ) { + return ( + + + { + // translators: %s: Total number of patterns. + sprintf( + // translators: %s: Total number of patterns. + _n( '%s item', '%s items', totalItems ), + totalItems + ) + } + + + + + + + + { 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-paging/style.scss b/packages/block-editor/src/components/block-patterns-paging/style.scss new file mode 100644 index 00000000000000..321f251597e1ec --- /dev/null +++ b/packages/block-editor/src/components/block-patterns-paging/style.scss @@ -0,0 +1,19 @@ +.block-editor-patterns__grid-pagination { + border-top: 1px solid $gray-800; + padding: $grid-unit-05; + + .components-button.is-tertiary { + width: $button-size-compact; + height: $button-size-compact; + justify-content: center; + + &:disabled { + color: $gray-600; + background: none; + } + + &:hover:not(:disabled) { + background-color: $gray-700; + } + } +} 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 e81badb97af5c5..2948156c251c80 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 @@ -3,7 +3,7 @@ */ 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,8 +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'; - -const INITIAL_INSERTER_RESULTS = 2; +import BlockPatternsPaging from '../../block-patterns-paging'; +import usePatternsPaging from '../hooks/use-patterns-paging'; function PatternsListHeader( { filterValue, filteredBlockPatternsLength } ) { if ( ! filterValue ) { @@ -97,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 ( @@ -114,12 +121,20 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { { ! hasItems && } { hasItems && ( ) } + { 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 955b6019931ad4..307e1b533c42f6 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, @@ -27,6 +27,8 @@ import usePatternsState from './hooks/use-patterns-state'; 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 = () => {}; @@ -168,7 +170,16 @@ export function BlockPatternsCategoryPanel( { [ allPatterns, availableCategories, category.name ] ); - const categoryPatternsList = useAsyncList( currentCategoryPatterns ); + const { + totalItems, + categoryPatternsList, + numPages, + changePage, + currentPage, + } = usePatternsPaging( + currentCategoryPatterns, + '.block-editor-inserter__patterns-category-dialog' + ); // Hide block pattern preview on unmount. useEffect( () => () => onHover( null ), [] ); @@ -190,10 +201,18 @@ export function BlockPatternsCategoryPanel( { onHover={ onHover } label={ category.label } orientation="vertical" - category={ category.label } + category={ category.name } isDraggable showTitlesAsTooltip={ showTitlesAsTooltip } /> + { 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, + }; +} diff --git a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js index b8bb18d48970a3..d26dea231eabbb 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js @@ -2,7 +2,7 @@ * WordPress dependencies */ import { useCallback, useMemo } from '@wordpress/element'; -import { cloneBlock } from '@wordpress/blocks'; +import { cloneBlock, createBlock } from '@wordpress/blocks'; import { useDispatch, useSelect } from '@wordpress/data'; import { __, sprintf } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; @@ -57,8 +57,12 @@ const usePatternsState = ( onInsert, rootClientId ) => { const { createSuccessNotice } = useDispatch( noticesStore ); const onClickPattern = useCallback( ( pattern, blocks ) => { + const patternBlocks = + pattern.syncStatus !== 'unsynced' + ? [ createBlock( 'core/block', { ref: pattern.id } ) ] + : blocks; onInsert( - ( blocks ?? [] ).map( ( block ) => cloneBlock( block ) ), + ( patternBlocks ?? [] ).map( ( block ) => cloneBlock( block ) ), pattern.name ); createSuccessNotice( diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js index c2257cf237669e..8978da4ccb9aa1 100644 --- a/packages/block-editor/src/components/inserter/menu.js +++ b/packages/block-editor/src/components/inserter/menu.js @@ -27,7 +27,6 @@ import BlockTypesTab from './block-types-tab'; import BlockPatternsTabs, { BlockPatternsCategoryDialog, } from './block-patterns-tab'; -import ReusableBlocksTab from './reusable-blocks-tab'; import { MediaTab, MediaCategoryDialog, useMediaCategories } from './media-tab'; import InserterSearchResults from './search-results'; import useDebouncedInput from './hooks/use-debounced-input'; @@ -174,17 +173,6 @@ function InserterMenu( ] ); - const reusableBlocksTab = useMemo( - () => ( - - ), - [ destinationRootClientId, onInsert, onHover ] - ); - const mediaTab = useMemo( () => ( { - return items.filter( - ( { category, syncStatus } ) => - category === 'reusable' && syncStatus !== 'unsynced' - ); - }, [ items ] ); - - if ( filteredItems.length === 0 ) { - return ; - } - - return ( - - - - ); -} - -// The unwrapped component is only exported for use by unit tests. -/** - * List of reusable blocks shown in the "Reusable" tab of the inserter. - * - * @param {Object} props Component props. - * @param {?string} props.rootClientId Client id of block to insert into. - * @param {Function} props.onInsert Callback to run when item is inserted. - * @param {Function} props.onHover Callback to run when item is hovered. - * - * @return {WPComponent} The component. - */ -export function ReusableBlocksTab( { rootClientId, onInsert, onHover } ) { - return ( - <> -
- -
- -
- -
- - ); -} - -export default ReusableBlocksTab; diff --git a/packages/block-editor/src/components/inserter/tabs.js b/packages/block-editor/src/components/inserter/tabs.js index 1ff8b529707a4b..a75e0029ef4900 100644 --- a/packages/block-editor/src/components/inserter/tabs.js +++ b/packages/block-editor/src/components/inserter/tabs.js @@ -1,7 +1,6 @@ /** * WordPress dependencies */ -import { symbol as reusableBlockIcon } from '@wordpress/icons'; import { useMemo } from '@wordpress/element'; import { TabPanel } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; @@ -16,12 +15,7 @@ const patternsTab = { /* translators: Theme and Directory Patterns tab title in the block inserter. */ title: __( 'Patterns' ), }; -const reusableBlocksTab = { - name: 'reusable', - /* translators: Locally created Patterns tab title in the block inserter. */ - title: __( 'Synced patterns' ), - icon: reusableBlockIcon, -}; + const mediaTab = { name: 'media', /* translators: Media tab title in the block inserter. */ @@ -31,7 +25,6 @@ const mediaTab = { function InserterTabs( { children, showPatterns = false, - showReusableBlocks = false, showMedia = false, onSelect, prioritizePatterns, @@ -48,11 +41,8 @@ function InserterTabs( { if ( showMedia ) { tempTabs.push( mediaTab ); } - if ( showReusableBlocks ) { - tempTabs.push( reusableBlocksTab ); - } return tempTabs; - }, [ prioritizePatterns, showPatterns, showReusableBlocks, showMedia ] ); + }, [ prioritizePatterns, showPatterns, showMedia ] ); return ( { - // This allows us to tweak the returned value on each test. - const mock = jest.fn(); - return mock; -} ); - -describe( 'InserterMenu', () => { - beforeAll( () => { - registerBlockType( 'core/block', { - save: () => {}, - title: 'reusable block', - edit: () => {}, - } ); - } ); - - afterAll( () => { - unregisterBlockType( 'core/block' ); - } ); - - beforeEach( () => { - useBlockTypesState.mockImplementation( () => [ - items, - categories, - collections, - ] ); - } ); - - it( 'should show nothing if there are no items', () => { - const noItems = []; - useBlockTypesState.mockImplementation( () => [ - noItems, - categories, - collections, - ] ); - - render( ); - - expect( screen.queryByRole( 'option' ) ).not.toBeInTheDocument(); - } ); - - it( 'should list reusable blocks', () => { - render( ); - - expect( - screen.getByRole( 'option', { name: 'My reusable block' } ) - ).toBeVisible(); - } ); - - it( 'should trim whitespace of search terms', () => { - render( ); - - expect( - screen.getByRole( 'option', { name: 'My reusable block' } ) - ).toBeVisible(); - } ); -} ); diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d8ef252973c49e..c0a51da3643cf6 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2290,28 +2290,23 @@ const checkAllowListRecursive = ( blocks, allowedBlockTypes ) => { return true; }; -function getUnsyncedPatterns( state ) { - const reusableBlocks = +function getUserPatterns( state ) { + const userPatterns = state?.settings?.__experimentalReusableBlocks ?? EMPTY_ARRAY; const { patternCategoriesMap: categories } = state?.settings?.__experimentalUserPatternCategories ?? {}; - return reusableBlocks - .filter( - ( reusableBlock ) => - reusableBlock.wp_pattern_sync_status === 'unsynced' - ) - .map( ( reusableBlock ) => { - return { - name: `core/block/${ reusableBlock.id }`, - title: reusableBlock.title.raw, - categories: reusableBlock.wp_pattern_category.map( ( catId ) => - categories && categories.get( catId ) - ? categories.get( catId ).slug - : catId - ), - content: reusableBlock.content.raw, - }; - } ); + return userPatterns.map( ( reusableBlock ) => { + return { + name: `core/block/${ reusableBlock.id }`, + title: reusableBlock.title.raw, + categories: reusableBlock.wp_pattern_category.map( ( catId ) => + categories && categories.get( catId ) + ? categories.get( catId ).slug + : catId + ), + content: reusableBlock.content.raw, + }; + } ); } export const __experimentalUserPatternCategories = createSelector( @@ -2324,9 +2319,9 @@ export const __experimentalUserPatternCategories = createSelector( export const __experimentalGetParsedPattern = createSelector( ( state, patternName ) => { const patterns = state.settings.__experimentalBlockPatterns; - const unsyncedPatterns = getUnsyncedPatterns( state ); + const userPatterns = getUserPatterns( state ); - const pattern = [ ...patterns, ...unsyncedPatterns ].find( + const pattern = [ ...patterns, ...userPatterns ].find( ( { name } ) => name === patternName ); if ( ! pattern ) { @@ -2349,11 +2344,11 @@ export const __experimentalGetParsedPattern = createSelector( const getAllAllowedPatterns = createSelector( ( state ) => { const patterns = state.settings.__experimentalBlockPatterns; - const unsyncedPatterns = getUnsyncedPatterns( state ); + const userPatterns = getUserPatterns( state ); const { allowedBlockTypes } = getSettings( state ); - const parsedPatterns = [ ...unsyncedPatterns, ...patterns ] + const parsedPatterns = [ ...userPatterns, ...patterns ] .filter( ( { inserter = true } ) => !! inserter ) .map( ( { name } ) => __experimentalGetParsedPattern( state, name ) diff --git a/packages/block-editor/src/style.scss b/packages/block-editor/src/style.scss index 5eafc0766ae220..48012d8f83a95d 100644 --- a/packages/block-editor/src/style.scss +++ b/packages/block-editor/src/style.scss @@ -12,6 +12,7 @@ @import "./components/block-navigation/style.scss"; @import "./components/block-parent-selector/style.scss"; @import "./components/block-patterns-list/style.scss"; +@import "./components/block-patterns-paging/style.scss"; @import "./components/block-popover/style.scss"; @import "./components/block-preview/style.scss"; @import "./components/block-settings-menu/style.scss"; From 8ca644b69ddbb4f5126fe6b64e3be2a97956d26f Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 29 Aug 2023 17:03:35 +1200 Subject: [PATCH 02/61] Add sync status back --- packages/block-editor/src/store/selectors.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index c0a51da3643cf6..1a19633a52c489 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2295,16 +2295,17 @@ function getUserPatterns( state ) { state?.settings?.__experimentalReusableBlocks ?? EMPTY_ARRAY; const { patternCategoriesMap: categories } = state?.settings?.__experimentalUserPatternCategories ?? {}; - return userPatterns.map( ( reusableBlock ) => { + return userPatterns.map( ( userPattern ) => { return { - name: `core/block/${ reusableBlock.id }`, - title: reusableBlock.title.raw, - categories: reusableBlock.wp_pattern_category.map( ( catId ) => + name: `core/block/${ userPattern.id }`, + title: userPattern.title.raw, + categories: userPattern.wp_pattern_category.map( ( catId ) => categories && categories.get( catId ) ? categories.get( catId ).slug : catId ), - content: reusableBlock.content.raw, + content: userPattern.content.raw, + syncStatus: userPattern.wp_pattern_sync_status, }; } ); } From 9be808401d8f614cf538064cd330345f8010e92e Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 29 Aug 2023 17:11:26 +1200 Subject: [PATCH 03/61] Add back pattern id --- packages/block-editor/src/store/selectors.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index 1a19633a52c489..fc6fb2d9f43357 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -2298,6 +2298,7 @@ function getUserPatterns( state ) { return userPatterns.map( ( userPattern ) => { return { name: `core/block/${ userPattern.id }`, + id: userPattern.id, title: userPattern.title.raw, categories: userPattern.wp_pattern_category.map( ( catId ) => categories && categories.get( catId ) From a098a7b956677b8f4e10021a24289083da20e061 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 30 Aug 2023 10:49:47 +1200 Subject: [PATCH 04/61] Add my patterns toggle --- .../block-patterns-explorer/patterns-list.js | 31 ++++++---- .../components/inserter/block-patterns-tab.js | 60 +++++++++++++++++-- .../inserter/hooks/use-patterns-paging.js | 11 ++-- .../inserter/hooks/use-patterns-state.js | 2 +- 4 files changed, 81 insertions(+), 23 deletions(-) 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 2948156c251c80..32b1e52619188c 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 @@ -18,6 +18,7 @@ import InserterListbox from '../../inserter-listbox'; import { searchItems } from '../search-items'; import BlockPatternsPaging from '../../block-patterns-paging'; import usePatternsPaging from '../hooks/use-patterns-paging'; +import { allPatternsCategory } from '../block-patterns-tab'; function PatternsListHeader( { filterValue, filteredBlockPatternsLength } ) { if ( ! filterValue ) { @@ -63,17 +64,20 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { const filteredBlockPatterns = useMemo( () => { if ( ! filterValue ) { - return allPatterns.filter( ( pattern ) => - selectedCategory === 'uncategorized' + return allPatterns.filter( ( pattern ) => { + if ( selectedCategory === allPatternsCategory.name ) { + return true; + } + return selectedCategory === 'uncategorized' ? ! pattern.categories?.length || - pattern.categories.every( - ( category ) => - ! registeredPatternCategories.includes( - category - ) - ) - : pattern.categories?.includes( selectedCategory ) - ); + pattern.categories.every( + ( category ) => + ! registeredPatternCategories.includes( + category + ) + ) + : pattern.categories?.includes( selectedCategory ); + } ); } return searchItems( allPatterns, filterValue ); }, [ @@ -99,7 +103,8 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { const { totalItems, - categoryPatternsList, + categoryPatterns, + categoryPatternsAsyncList, numPages, changePage, currentPage, @@ -121,8 +126,8 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { { ! hasItems && } { hasItems && ( 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 307e1b533c42f6..3ab16aecaf46e0 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -16,6 +16,8 @@ import { __experimentalHStack as HStack, FlexBlock, Button, + __experimentalToggleGroupControl as ToggleGroupControl, + __experimentalToggleGroupControlOption as ToggleGroupControlOption, } from '@wordpress/components'; import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; import { focus } from '@wordpress/dom'; @@ -45,6 +47,20 @@ const patternCategoriesOrder = [ 'footer', ]; +export const allPatternsCategory = { + name: 'allPatterns', + label: __( 'All patterns' ), +}; +export const SYNC_TYPES = { + full: 'fully', + unsynced: 'unsynced', +}; +const SYNC_FILTERS = { + all: __( 'All' ), + [ SYNC_TYPES.full ]: __( 'My synced' ), + [ SYNC_TYPES.unsynced ]: __( 'My standard' ), +}; + function usePatternsCategories( rootClientId ) { const { patterns: allPatterns, allCategories } = usePatternsState( undefined, @@ -95,6 +111,12 @@ function usePatternsCategories( rootClientId ) { label: _x( 'Uncategorized' ), } ); } + if ( allPatterns.length > 0 ) { + categories.unshift( { + name: allPatternsCategory.name, + label: allPatternsCategory.label, + } ); + } return categories; }, [ allCategories, allPatterns, hasRegisteredCategory ] ); @@ -146,11 +168,18 @@ export function BlockPatternsCategoryPanel( { onInsert, rootClientId ); - + const [ syncFilter, setSyncFilter ] = useState( 'all' ); + const updateSyncFilter = ( value ) => { + //setCurrentPage( 1 ); + setSyncFilter( value ); + }; const availableCategories = usePatternsCategories( rootClientId ); const currentCategoryPatterns = useMemo( () => allPatterns.filter( ( pattern ) => { + if ( category.name === allPatternsCategory.name ) { + return true; + } if ( category.name !== 'uncategorized' ) { return pattern.categories?.includes( category.name ); } @@ -172,7 +201,8 @@ export function BlockPatternsCategoryPanel( { const { totalItems, - categoryPatternsList, + categoryPatterns, + categoryPatternsAsyncList, numPages, changePage, currentPage, @@ -194,9 +224,31 @@ export function BlockPatternsCategoryPanel( { { category.label }

{ category.description }

+ { category.name === allPatternsCategory.name && ( + updateSyncFilter( value ) } + __nextHasNoMarginBottom + > + { Object.entries( SYNC_FILTERS ).map( + ( [ key, label ] ) => ( + + ) + ) } + + ) } { + const categoryPatterns = useMemo( () => { return currentCategoryPatterns.slice( pageIndex * PAGE_SIZE, pageIndex * PAGE_SIZE + PAGE_SIZE ); }, [ pageIndex, currentCategoryPatterns ] ); - const categoryPatternsList = useAsyncList( list, { + const categoryPatternsAsyncList = useAsyncList( categoryPatterns, { step: INITIAL_INSERTER_RESULTS, } ); const numPages = Math.ceil( currentCategoryPatterns.length / PAGE_SIZE ); @@ -41,7 +41,8 @@ export default function usePatternsPaging( }; return { totalItems, - categoryPatternsList, + categoryPatterns, + categoryPatternsAsyncList, numPages, changePage, currentPage, diff --git a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js index d26dea231eabbb..0c938b0474a9fa 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-state.js @@ -58,7 +58,7 @@ const usePatternsState = ( onInsert, rootClientId ) => { const onClickPattern = useCallback( ( pattern, blocks ) => { const patternBlocks = - pattern.syncStatus !== 'unsynced' + pattern.id && pattern.syncStatus !== 'unsynced' ? [ createBlock( 'core/block', { ref: pattern.id } ) ] : blocks; onInsert( From fda3f167f0da15cbc4e6482babfcf1799f1e1916 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 30 Aug 2023 11:03:35 +1200 Subject: [PATCH 05/61] Remove sync toggle for now --- .../components/inserter/block-patterns-tab.js | 38 ------------------- 1 file changed, 38 deletions(-) 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 3ab16aecaf46e0..8b15eab88e0f0a 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -16,8 +16,6 @@ import { __experimentalHStack as HStack, FlexBlock, Button, - __experimentalToggleGroupControl as ToggleGroupControl, - __experimentalToggleGroupControlOption as ToggleGroupControlOption, } from '@wordpress/components'; import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; import { focus } from '@wordpress/dom'; @@ -51,15 +49,6 @@ export const allPatternsCategory = { name: 'allPatterns', label: __( 'All patterns' ), }; -export const SYNC_TYPES = { - full: 'fully', - unsynced: 'unsynced', -}; -const SYNC_FILTERS = { - all: __( 'All' ), - [ SYNC_TYPES.full ]: __( 'My synced' ), - [ SYNC_TYPES.unsynced ]: __( 'My standard' ), -}; function usePatternsCategories( rootClientId ) { const { patterns: allPatterns, allCategories } = usePatternsState( @@ -168,11 +157,6 @@ export function BlockPatternsCategoryPanel( { onInsert, rootClientId ); - const [ syncFilter, setSyncFilter ] = useState( 'all' ); - const updateSyncFilter = ( value ) => { - //setCurrentPage( 1 ); - setSyncFilter( value ); - }; const availableCategories = usePatternsCategories( rootClientId ); const currentCategoryPatterns = useMemo( () => @@ -224,28 +208,6 @@ export function BlockPatternsCategoryPanel( { { category.label }

{ category.description }

- { category.name === allPatternsCategory.name && ( - updateSyncFilter( value ) } - __nextHasNoMarginBottom - > - { Object.entries( SYNC_FILTERS ).map( - ( [ key, label ] ) => ( - - ) - ) } - - ) } Date: Mon, 4 Sep 2023 11:57:52 +1200 Subject: [PATCH 06/61] Make sort order same as site editor --- .../components/inserter/block-patterns-tab.js | 24 ++----------------- 1 file changed, 2 insertions(+), 22 deletions(-) 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 8b15eab88e0f0a..ed4ec0c48f68ba 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -32,19 +32,6 @@ import usePatternsPaging from './hooks/use-patterns-paging'; const noop = () => {}; -// Preferred order of pattern categories. Any other categories should -// be at the bottom without any re-ordering. -const patternCategoriesOrder = [ - 'featured', - 'posts', - 'text', - 'gallery', - 'call-to-action', - 'banner', - 'header', - 'footer', -]; - export const allPatternsCategory = { name: 'allPatterns', label: __( 'All patterns' ), @@ -77,15 +64,7 @@ function usePatternsCategories( rootClientId ) { pattern.categories?.includes( category.name ) ) ) - .sort( ( { label: aLabel }, { label: bLabel } ) => { - // Sort categories according to `patternCategoriesOrder`. - let aIndex = patternCategoriesOrder.indexOf( aLabel ); - let bIndex = patternCategoriesOrder.indexOf( bLabel ); - // All other categories should come after that. - if ( aIndex < 0 ) aIndex = patternCategoriesOrder.length; - if ( bIndex < 0 ) bIndex = patternCategoriesOrder.length; - return aIndex - bIndex; - } ); + .sort( ( a, b ) => a.label.localeCompare( b.label ) ); if ( allPatterns.some( @@ -192,6 +171,7 @@ export function BlockPatternsCategoryPanel( { currentPage, } = usePatternsPaging( currentCategoryPatterns, + category, '.block-editor-inserter__patterns-category-dialog' ); From f99c31d611292f3385a2d6cafeed10ed9bfdb907 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 4 Sep 2023 11:58:27 +1200 Subject: [PATCH 07/61] Fix bug with paging --- .../inserter/block-patterns-explorer/patterns-list.js | 1 + .../src/components/inserter/hooks/use-patterns-paging.js | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) 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 32b1e52619188c..7bb2cc44ace3c7 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 @@ -110,6 +110,7 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { currentPage, } = usePatternsPaging( filteredBlockPatterns, + selectedCategory, '.components-modal__content.is-scrollable' ); 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 index d9264696526773..9120240212b1a9 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js @@ -3,7 +3,7 @@ */ import { useMemo, useState } from '@wordpress/element'; -import { useAsyncList } from '@wordpress/compose'; +import { useAsyncList, usePrevious } from '@wordpress/compose'; const PAGE_SIZE = 20; const INITIAL_INSERTER_RESULTS = 5; @@ -12,15 +12,21 @@ const INITIAL_INSERTER_RESULTS = 5; * Supplies values needed to page the patterns list client side. * * @param {Array} currentCategoryPatterns An array of the current patterns to display. + * @param {string} currentCategory The currently selected category. * @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, + currentCategory, scrollContainerClass ) { const [ currentPage, setCurrentPage ] = useState( 1 ); + const previousCategory = usePrevious( currentCategory ); + if ( previousCategory !== currentCategory && currentPage !== 1 ) { + setCurrentPage( 1 ); + } const totalItems = currentCategoryPatterns.length; const pageIndex = currentPage - 1; const categoryPatterns = useMemo( () => { From 516341c7cd12cbf97cf47ba0c01b80d734d6421b Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 4 Sep 2023 14:14:32 +1200 Subject: [PATCH 08/61] Reset to page one if search filter changes --- .../inserter/block-patterns-explorer/patterns-list.js | 3 ++- .../components/inserter/hooks/use-patterns-paging.js | 11 +++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) 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 7bb2cc44ace3c7..f9418fed4dfe1f 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 @@ -111,7 +111,8 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { } = usePatternsPaging( filteredBlockPatterns, selectedCategory, - '.components-modal__content.is-scrollable' + '.components-modal__content.is-scrollable', + filterValue ); const hasItems = !! filteredBlockPatterns?.length; 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 index 9120240212b1a9..5e83a86cb6eea8 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js @@ -14,17 +14,24 @@ const INITIAL_INSERTER_RESULTS = 5; * @param {Array} currentCategoryPatterns An array of the current patterns to display. * @param {string} currentCategory The currently selected category. * @param {string} scrollContainerClass Class of container to scroll when moving between pages. + * @param {string} currentFilter The currently search filter. * * @return {Object} Returns the relevant paging values. (totalItems, categoryPatternsList, numPages, changePage, currentPage) */ export default function usePatternsPaging( currentCategoryPatterns, currentCategory, - scrollContainerClass + scrollContainerClass, + currentFilter = '' ) { const [ currentPage, setCurrentPage ] = useState( 1 ); const previousCategory = usePrevious( currentCategory ); - if ( previousCategory !== currentCategory && currentPage !== 1 ) { + const previousFilter = usePrevious( currentFilter ); + if ( + ( previousCategory !== currentCategory || + previousFilter !== currentFilter ) && + currentPage !== 1 + ) { setCurrentPage( 1 ); } const totalItems = currentCategoryPatterns.length; From d4705b7fb4129b11d71169ab2b300628083701a5 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 5 Sep 2023 11:35:21 +1200 Subject: [PATCH 09/61] Update e2e tests --- packages/e2e-test-utils/README.md | 8 ----- packages/e2e-test-utils/src/index.js | 1 - packages/e2e-test-utils/src/inserter.js | 11 ------- ...-blocks.test.js => pattern-blocks.test.js} | 30 +++++++++---------- 4 files changed, 15 insertions(+), 35 deletions(-) rename packages/e2e-tests/specs/editor/various/{reusable-blocks.test.js => pattern-blocks.test.js} (94%) diff --git a/packages/e2e-test-utils/README.md b/packages/e2e-test-utils/README.md index 93d46d3f820daf..bce7c84d73716d 100644 --- a/packages/e2e-test-utils/README.md +++ b/packages/e2e-test-utils/README.md @@ -472,14 +472,6 @@ _Parameters_ - _searchTerm_ `string`: The term by which to find the pattern to insert. -### insertReusableBlock - -Inserts a reusable block matching a given search term via the global inserter. - -_Parameters_ - -- _searchTerm_ `string`: The term by which to find the reusable block to insert. - ### installPlugin Installs a plugin from the WP.org repository. diff --git a/packages/e2e-test-utils/src/index.js b/packages/e2e-test-utils/src/index.js index 22cb9b9fa81859..e2db1884a27387 100644 --- a/packages/e2e-test-utils/src/index.js +++ b/packages/e2e-test-utils/src/index.js @@ -51,7 +51,6 @@ export { searchForBlockDirectoryBlock, insertBlock, insertPattern, - insertReusableBlock, insertBlockDirectoryBlock, } from './inserter'; export { installPlugin } from './install-plugin'; diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index cdd1c534d928db..68f2ffaff49ac2 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -339,17 +339,6 @@ export async function insertPattern( searchTerm ) { await insertFromGlobalInserter( 'Patterns', searchTerm ); } -/** - * Inserts a reusable block matching a given search term via the global - * inserter. - * - * @param {string} searchTerm The term by which to find the reusable block to - * insert. - */ -export async function insertReusableBlock( searchTerm ) { - await insertFromGlobalInserter( 'Synced patterns', searchTerm ); -} - /** * Inserts a Block Directory block matching a given search term via the global * inserter. diff --git a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/pattern-blocks.test.js similarity index 94% rename from packages/e2e-tests/specs/editor/various/reusable-blocks.test.js rename to packages/e2e-tests/specs/editor/various/pattern-blocks.test.js index a647b61c2b4d3f..72f11f2c95e7a4 100644 --- a/packages/e2e-tests/specs/editor/various/reusable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/pattern-blocks.test.js @@ -4,7 +4,7 @@ import { clickMenuItem, insertBlock, - insertReusableBlock, + insertPattern, createNewPost, clickBlockToolbarButton, pressKeyWithModifier, @@ -19,9 +19,9 @@ import { canvas, } from '@wordpress/e2e-test-utils'; -const reusableBlockNameInputSelector = +const patternBlockNameInputSelector = '.patterns-menu-items__convert-modal .components-text-control__input'; -const reusableBlockInspectorNameInputSelector = +const patternBlockInspectorNameInputSelector = '.block-editor-block-inspector .components-text-control__input'; const syncToggleSelectorChecked = '.patterns-menu-items__convert-modal .components-form-toggle.is-checked'; @@ -60,7 +60,7 @@ const clearAllBlocks = async () => { } ); }; -describe( 'Reusable blocks', () => { +describe( 'Pattern blocks', () => { afterAll( async () => { await trashAllPosts( 'wp_block' ); } ); @@ -74,12 +74,12 @@ describe( 'Reusable blocks', () => { await clearAllBlocks(); // Insert the reusable block we created above. - await insertReusableBlock( 'Greeting block' ); + await insertPattern( 'Greeting block' ); // Change the block's title. await openDocumentSettingsSidebar(); const nameInput = await page.waitForSelector( - reusableBlockInspectorNameInputSelector + patternBlockInspectorNameInputSelector ); await nameInput.click(); await pressKeyWithModifier( 'primary', 'a' ); @@ -108,7 +108,7 @@ describe( 'Reusable blocks', () => { await clearAllBlocks(); // Insert the reusable block we edited above. - await insertReusableBlock( 'Surprised greeting block' ); + await insertPattern( 'Surprised greeting block' ); // Convert block to a regular block. await clickBlockToolbarButton( 'Options' ); @@ -170,12 +170,12 @@ describe( 'Reusable blocks', () => { await createNewPost(); // Step 3. Insert the block created in Step 1. - await insertReusableBlock( 'Awesome block' ); + await insertPattern( 'Awesome block' ); // Check the title. await openDocumentSettingsSidebar(); const title = await page.$eval( - reusableBlockInspectorNameInputSelector, + patternBlockInspectorNameInputSelector, ( element ) => element.value ); expect( title ).toBe( 'Awesome block' ); @@ -200,7 +200,7 @@ describe( 'Reusable blocks', () => { // Set title. const nameInput = await page.waitForSelector( - reusableBlockNameInputSelector + patternBlockNameInputSelector ); await nameInput.click(); await page.keyboard.type( 'Multi-selection reusable block' ); @@ -215,7 +215,7 @@ describe( 'Reusable blocks', () => { await clearAllBlocks(); // Insert the reusable block we edited above. - await insertReusableBlock( 'Multi-selection reusable block' ); + await insertPattern( 'Multi-selection reusable block' ); // Convert block to a regular block. await clickBlockToolbarButton( 'Options' ); @@ -231,7 +231,7 @@ describe( 'Reusable blocks', () => { 'Random reusable block' ); await clearAllBlocks(); - await insertReusableBlock( 'Random reusable block' ); + await insertPattern( 'Random reusable block' ); await visitAdminPage( 'edit.php', [ 'post_type=wp_block' ] ); @@ -298,8 +298,8 @@ describe( 'Reusable blocks', () => { 'Duplicated reusable block' ); await clearAllBlocks(); - await insertReusableBlock( 'Duplicated reusable block' ); - await insertReusableBlock( 'Duplicated reusable block' ); + await insertPattern( 'Duplicated reusable block' ); + await insertPattern( 'Duplicated reusable block' ); await saveDraft(); await page.reload(); await page.waitForSelector( 'iframe[name="editor-canvas"]' ); @@ -384,7 +384,7 @@ describe( 'Reusable blocks', () => { await clickBlockToolbarButton( 'Options' ); await clickMenuItem( 'Create pattern' ); const nameInput = await page.waitForSelector( - reusableBlockNameInputSelector + patternBlockNameInputSelector ); await nameInput.click(); await page.keyboard.type( 'Block with styles' ); From 39f33b243a41096084f7c4c61b68ad45eb37bdb4 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 5 Sep 2023 12:03:35 +1200 Subject: [PATCH 10/61] rename snapshot file --- .../{reusable-blocks.test.js.snap => pattern-blocks.test.js.snap} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/e2e-tests/specs/editor/various/__snapshots__/{reusable-blocks.test.js.snap => pattern-blocks.test.js.snap} (100%) diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/pattern-blocks.test.js.snap similarity index 100% rename from packages/e2e-tests/specs/editor/various/__snapshots__/reusable-blocks.test.js.snap rename to packages/e2e-tests/specs/editor/various/__snapshots__/pattern-blocks.test.js.snap From 4aa062339ca01a5b3c2cde5f74b540c374ee182b Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 7 Sep 2023 10:49:20 +1200 Subject: [PATCH 11/61] Add pattern type filters to insert patterns tab --- .../components/inserter/block-patterns-tab.js | 79 ++++++++++++++++--- .../src/components/inserter/menu.js | 5 +- 2 files changed, 72 insertions(+), 12 deletions(-) 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 ed4ec0c48f68ba..f5b0a1b2a8dcc1 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -16,6 +16,7 @@ import { __experimentalHStack as HStack, FlexBlock, Button, + SelectControl, } from '@wordpress/components'; import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; import { focus } from '@wordpress/dom'; @@ -34,15 +35,36 @@ const noop = () => {}; export const allPatternsCategory = { name: 'allPatterns', - label: __( 'All patterns' ), + label: __( 'All' ), }; - -function usePatternsCategories( rootClientId ) { +const PATTERN_TYPES = { + synced: 'synced', + unsynced: 'unsynced', + theme: 'theme', +}; +const SYNC_FILTERS = [ + { value: 'all', label: __( 'Unfiltered' ) }, + { value: PATTERN_TYPES.theme, label: __( 'Theme patterns' ) }, + { value: PATTERN_TYPES.synced, label: __( 'My synced patterns' ) }, + { value: PATTERN_TYPES.unsynced, label: __( 'My standard patterns' ) }, +]; +function usePatternsCategories( rootClientId, filter = 'all' ) { const { patterns: allPatterns, allCategories } = usePatternsState( undefined, rootClientId ); - + const filteredPatterns = + filter === 'all' + ? allPatterns + : allPatterns.filter( + ( pattern ) => + ( filter === PATTERN_TYPES.unsynced && + pattern.syncStatus === filter ) || + ( filter === PATTERN_TYPES.synced && + pattern.syncStatus === '' ) || + ( filter === PATTERN_TYPES.theme && + ! pattern.name.startsWith( 'core/block' ) ) + ); const hasRegisteredCategory = useCallback( ( pattern ) => { if ( ! pattern.categories || ! pattern.categories.length ) { @@ -60,14 +82,14 @@ function usePatternsCategories( rootClientId ) { const populatedCategories = useMemo( () => { const categories = allCategories .filter( ( category ) => - allPatterns.some( ( pattern ) => + filteredPatterns.some( ( pattern ) => pattern.categories?.includes( category.name ) ) ) .sort( ( a, b ) => a.label.localeCompare( b.label ) ); if ( - allPatterns.some( + filteredPatterns.some( ( pattern ) => ! hasRegisteredCategory( pattern ) ) && ! categories.find( @@ -79,7 +101,7 @@ function usePatternsCategories( rootClientId ) { label: _x( 'Uncategorized' ), } ); } - if ( allPatterns.length > 0 ) { + if ( filteredPatterns.length > 0 ) { categories.unshift( { name: allPatternsCategory.name, label: allPatternsCategory.label, @@ -87,7 +109,7 @@ function usePatternsCategories( rootClientId ) { } return categories; - }, [ allCategories, allPatterns, hasRegisteredCategory ] ); + }, [ allCategories, filteredPatterns, hasRegisteredCategory ] ); return populatedCategories; } @@ -98,6 +120,7 @@ export function BlockPatternsCategoryDialog( { onHover, category, showTitlesAsTooltip, + patternFilter, } ) { const container = useRef(); @@ -120,6 +143,7 @@ export function BlockPatternsCategoryDialog( { onHover={ onHover } category={ category } showTitlesAsTooltip={ showTitlesAsTooltip } + patternFilter={ patternFilter } /> ); @@ -131,6 +155,7 @@ export function BlockPatternsCategoryPanel( { onHover = noop, category, showTitlesAsTooltip, + patternFilter, } ) { const { patterns: allPatterns, onClickPattern } = usePatternsState( onInsert, @@ -140,6 +165,24 @@ export function BlockPatternsCategoryPanel( { const currentCategoryPatterns = useMemo( () => allPatterns.filter( ( pattern ) => { + if ( + patternFilter === PATTERN_TYPES.theme && + pattern.name.startsWith( 'core/block' ) + ) { + return false; + } + if ( + patternFilter === PATTERN_TYPES.synced && + pattern.syncStatus !== '' + ) { + return false; + } + if ( + patternFilter === PATTERN_TYPES.unsynced && + pattern.syncStatus !== PATTERN_TYPES.unsynced + ) { + return false; + } if ( category.name === allPatternsCategory.name ) { return true; } @@ -159,7 +202,7 @@ export function BlockPatternsCategoryPanel( { return availablePatternCategories.length === 0; } ), - [ allPatterns, availableCategories, category.name ] + [ allPatterns, availableCategories, category.name, patternFilter ] ); const { @@ -218,7 +261,8 @@ function BlockPatternsTabs( { rootClientId, } ) { const [ showPatternsExplorer, setShowPatternsExplorer ] = useState( false ); - const categories = usePatternsCategories( rootClientId ); + const [ patternFilter, setPatternFilter ] = useState( 'all' ); + const categories = usePatternsCategories( rootClientId, patternFilter ); const initialCategory = selectedCategory || categories[ 0 ]; const isMobile = useViewportMatch( 'medium', '<' ); return ( @@ -230,12 +274,25 @@ function BlockPatternsTabs( { role="list" className="block-editor-inserter__block-patterns-tabs" > + { + setPatternFilter( value ); + onSelectCategory( selectedCategory, value ); + } } + /> { categories.map( ( category ) => ( - onSelectCategory( category ) + onSelectCategory( + category, + patternFilter + ) } className={ category === selectedCategory diff --git a/packages/block-editor/src/components/inserter/menu.js b/packages/block-editor/src/components/inserter/menu.js index 8978da4ccb9aa1..5e0aeec08681f1 100644 --- a/packages/block-editor/src/components/inserter/menu.js +++ b/packages/block-editor/src/components/inserter/menu.js @@ -54,6 +54,7 @@ function InserterMenu( const [ hoveredItem, setHoveredItem ] = useState( null ); const [ selectedPatternCategory, setSelectedPatternCategory ] = useState( null ); + const [ patternFilter, setPatternFilter ] = useState( 'all' ); const [ selectedMediaCategory, setSelectedMediaCategory ] = useState( null ); const [ selectedTab, setSelectedTab ] = useState( null ); @@ -120,8 +121,9 @@ function InserterMenu( ); const onClickPatternCategory = useCallback( - ( patternCategory ) => { + ( patternCategory, filter ) => { setSelectedPatternCategory( patternCategory ); + setPatternFilter( filter ); }, [ setSelectedPatternCategory ] ); @@ -291,6 +293,7 @@ function InserterMenu( onInsert={ onInsertPattern } onHover={ onHoverPattern } category={ selectedPatternCategory } + patternFilter={ patternFilter } showTitlesAsTooltip /> ) } From 81165ec6eef520dc33b536e75f12f2905b49c909 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 7 Sep 2023 11:51:16 +1200 Subject: [PATCH 12/61] Add screen reader announcement to indicate number of categories when pattern filter changes --- .../src/components/inserter/block-patterns-tab.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) 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 f5b0a1b2a8dcc1..272e2021be5087 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -8,7 +8,7 @@ import { useRef, useEffect, } from '@wordpress/element'; -import { _x, __, isRTL } from '@wordpress/i18n'; +import { _x, __, _n, isRTL, sprintf } from '@wordpress/i18n'; import { useViewportMatch } from '@wordpress/compose'; import { __experimentalItemGroup as ItemGroup, @@ -20,6 +20,7 @@ import { } from '@wordpress/components'; import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; import { focus } from '@wordpress/dom'; +import { speak } from '@wordpress/a11y'; /** * Internal dependencies @@ -110,7 +111,17 @@ function usePatternsCategories( rootClientId, filter = 'all' ) { return categories; }, [ allCategories, filteredPatterns, hasRegisteredCategory ] ); - + speak( + sprintf( + /* translators: %d: number of categories . */ + _n( + '%d category button displayed.', + '%d category buttons displayed.', + populatedCategories.length + ), + populatedCategories.length + ) + ); return populatedCategories; } From 476ef8f832f1ae1974cabe9cafb29e7808e567a8 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 7 Sep 2023 11:56:09 +1200 Subject: [PATCH 13/61] Add aria label to filter select --- .../block-editor/src/components/inserter/block-patterns-tab.js | 1 + 1 file changed, 1 insertion(+) 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 272e2021be5087..54446b282b93eb 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -294,6 +294,7 @@ function BlockPatternsTabs( { setPatternFilter( value ); onSelectCategory( selectedCategory, value ); } } + aria-label={ __( 'Filter patterns by type' ) } /> { categories.map( ( category ) => ( Date: Thu, 7 Sep 2023 13:26:44 +1200 Subject: [PATCH 14/61] Add filtering to patterns explorer --- .../block-patterns-explorer/explorer.js | 15 +++++++-- .../block-patterns-explorer/patterns-list.js | 31 +++++++++++++++++-- .../block-patterns-explorer/sidebar.js | 23 ++++++++++---- .../inserter/block-patterns-filter.js | 31 +++++++++++++++++++ .../components/inserter/block-patterns-tab.js | 29 ++++++----------- 5 files changed, 99 insertions(+), 30 deletions(-) create mode 100644 packages/block-editor/src/components/inserter/block-patterns-filter.js diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js index 914177941821f3..be4756dcc8ed1f 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js @@ -10,22 +10,33 @@ import { __ } from '@wordpress/i18n'; */ import PatternExplorerSidebar from './sidebar'; import PatternList from './patterns-list'; +import { SYNC_FILTERS } from '../block-patterns-filter'; +import { usePatternsCategories } from '../block-patterns-tab'; -function PatternsExplorer( { initialCategory, patternCategories } ) { - const [ filterValue, setFilterValue ] = useState( '' ); +function PatternsExplorer( { initialCategory, rootClientId } ) { + const [ searchValue, setSearchValue ] = useState( '' ); + const [ filterValue, setFilterValue ] = useState( SYNC_FILTERS.all ); const [ selectedCategory, setSelectedCategory ] = useState( initialCategory?.name ); + const patternCategories = usePatternsCategories( + rootClientId, + filterValue + ); + return (
{ - if ( ! filterValue ) { + if ( ! searchValue ) { return allPatterns.filter( ( pattern ) => { + if ( + filterValue === PATTERN_TYPES.theme && + pattern.name.startsWith( 'core/block' ) + ) { + return false; + } + if ( + filterValue === PATTERN_TYPES.synced && + pattern.syncStatus !== '' + ) { + return false; + } + if ( + filterValue === PATTERN_TYPES.unsynced && + pattern.syncStatus !== PATTERN_TYPES.unsynced + ) { + return false; + } if ( selectedCategory === allPatternsCategory.name ) { return true; } @@ -79,8 +103,9 @@ function PatternList( { filterValue, selectedCategory, patternCategories } ) { : pattern.categories?.includes( selectedCategory ); } ); } - return searchItems( allPatterns, filterValue ); + return searchItems( allPatterns, searchValue ); }, [ + searchValue, filterValue, allPatterns, selectedCategory, diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js index 71431342221228..964c0b3bffdb57 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js @@ -4,6 +4,11 @@ import { Button, SearchControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +/** + * Internal dependencies + */ +import { default as BlockPatternsFilter } from '../block-patterns-filter'; + function PatternCategoriesList( { selectedCategory, patternCategories, @@ -31,14 +36,14 @@ function PatternCategoriesList( { ); } -function PatternsExplorerSearch( { filterValue, setFilterValue } ) { +function PatternsExplorerSearch( { searchValue, setSearchValue } ) { const baseClassName = 'block-editor-block-patterns-explorer__search'; return (
@@ -52,15 +57,21 @@ function PatternExplorerSidebar( { onClickCategory, filterValue, setFilterValue, + searchValue, + setSearchValue, } ) { const baseClassName = 'block-editor-block-patterns-explorer__sidebar'; return (
+ - { ! filterValue && ( + { ! searchValue && ( + + + ); +} 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 54446b282b93eb..28ca32bdd9d4be 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -16,7 +16,6 @@ import { __experimentalHStack as HStack, FlexBlock, Button, - SelectControl, } from '@wordpress/components'; import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; import { focus } from '@wordpress/dom'; @@ -31,6 +30,11 @@ 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'; +import { + PATTERN_TYPES, + SYNC_FILTERS, + default as BlockPatternsFilter, +} from './block-patterns-filter'; const noop = () => {}; @@ -38,18 +42,8 @@ export const allPatternsCategory = { name: 'allPatterns', label: __( 'All' ), }; -const PATTERN_TYPES = { - synced: 'synced', - unsynced: 'unsynced', - theme: 'theme', -}; -const SYNC_FILTERS = [ - { value: 'all', label: __( 'Unfiltered' ) }, - { value: PATTERN_TYPES.theme, label: __( 'Theme patterns' ) }, - { value: PATTERN_TYPES.synced, label: __( 'My synced patterns' ) }, - { value: PATTERN_TYPES.unsynced, label: __( 'My standard patterns' ) }, -]; -function usePatternsCategories( rootClientId, filter = 'all' ) { + +export function usePatternsCategories( rootClientId, filter = 'all' ) { const { patterns: allPatterns, allCategories } = usePatternsState( undefined, rootClientId @@ -272,7 +266,7 @@ function BlockPatternsTabs( { rootClientId, } ) { const [ showPatternsExplorer, setShowPatternsExplorer ] = useState( false ); - const [ patternFilter, setPatternFilter ] = useState( 'all' ); + const [ patternFilter, setPatternFilter ] = useState( SYNC_FILTERS.all ); const categories = usePatternsCategories( rootClientId, patternFilter ); const initialCategory = selectedCategory || categories[ 0 ]; const isMobile = useViewportMatch( 'medium', '<' ); @@ -285,16 +279,12 @@ function BlockPatternsTabs( { role="list" className="block-editor-inserter__block-patterns-tabs" > - { setPatternFilter( value ); onSelectCategory( selectedCategory, value ); } } - aria-label={ __( 'Filter patterns by type' ) } /> { categories.map( ( category ) => ( setShowPatternsExplorer( false ) } + rootClientId={ rootClientId } /> ) } From f64f04336e39f7bba833e563f35789d2e6189f54 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 7 Sep 2023 14:31:15 +1200 Subject: [PATCH 15/61] Simplify filter --- .../block-patterns-explorer/patterns-list.js | 21 +++++++------------ .../components/inserter/block-patterns-tab.js | 21 +++++++------------ 2 files changed, 14 insertions(+), 28 deletions(-) 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 cf9b5e3d34c86e..76141f78b77cb0 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 @@ -72,23 +72,16 @@ function PatternList( { if ( ! searchValue ) { return allPatterns.filter( ( pattern ) => { if ( - filterValue === PATTERN_TYPES.theme && - pattern.name.startsWith( 'core/block' ) - ) { - return false; - } - if ( - filterValue === PATTERN_TYPES.synced && - pattern.syncStatus !== '' - ) { - return false; - } - if ( - filterValue === PATTERN_TYPES.unsynced && - pattern.syncStatus !== PATTERN_TYPES.unsynced + ( filterValue === PATTERN_TYPES.theme && + pattern.name.startsWith( 'core/block' ) ) || + ( filterValue === PATTERN_TYPES.synced && + pattern.syncStatus !== '' ) || + ( filterValue === PATTERN_TYPES.unsynced && + pattern.syncStatus !== PATTERN_TYPES.unsynced ) ) { return false; } + if ( selectedCategory === allPatternsCategory.name ) { return true; } 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 28ca32bdd9d4be..dd88a436f5c56d 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -171,23 +171,16 @@ export function BlockPatternsCategoryPanel( { () => allPatterns.filter( ( pattern ) => { if ( - patternFilter === PATTERN_TYPES.theme && - pattern.name.startsWith( 'core/block' ) - ) { - return false; - } - if ( - patternFilter === PATTERN_TYPES.synced && - pattern.syncStatus !== '' - ) { - return false; - } - if ( - patternFilter === PATTERN_TYPES.unsynced && - pattern.syncStatus !== PATTERN_TYPES.unsynced + ( patternFilter === PATTERN_TYPES.theme && + pattern.name.startsWith( 'core/block' ) ) || + ( patternFilter === PATTERN_TYPES.synced && + pattern.syncStatus !== '' ) || + ( patternFilter === PATTERN_TYPES.unsynced && + pattern.syncStatus !== PATTERN_TYPES.unsynced ) ) { return false; } + if ( category.name === allPatternsCategory.name ) { return true; } From a8c0785e696605284a3c9f15a542067fea27a8e4 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Thu, 7 Sep 2023 16:36:16 +1200 Subject: [PATCH 16/61] Fix test snapshots --- .../editor/various/__snapshots__/pattern-blocks.test.js.snap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/__snapshots__/pattern-blocks.test.js.snap b/packages/e2e-tests/specs/editor/various/__snapshots__/pattern-blocks.test.js.snap index 4ddcd90ded100c..db3efc512a0a7e 100644 --- a/packages/e2e-tests/specs/editor/various/__snapshots__/pattern-blocks.test.js.snap +++ b/packages/e2e-tests/specs/editor/various/__snapshots__/pattern-blocks.test.js.snap @@ -1,12 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Reusable blocks allows conversion back to blocks when the reusable block has unsaved edits 1`] = ` +exports[`Pattern blocks allows conversion back to blocks when the reusable block has unsaved edits 1`] = ` "

12

" `; -exports[`Reusable blocks can be created from multiselection and converted back to regular blocks 1`] = ` +exports[`Pattern blocks can be created from multiselection and converted back to regular blocks 1`] = ` "

Hello there!

From 684e57e1265673c3225b3bceba1841ae8b289555 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 10:08:31 +1200 Subject: [PATCH 17/61] Extract filtering logic into a separate method --- .../block-patterns-explorer/patterns-list.js | 12 ++------- .../components/inserter/block-patterns-tab.js | 27 +++++++++---------- 2 files changed, 14 insertions(+), 25 deletions(-) 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 76141f78b77cb0..32151a86a24bf7 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 @@ -18,8 +18,7 @@ import InserterListbox from '../../inserter-listbox'; import { searchItems } from '../search-items'; import BlockPatternsPaging from '../../block-patterns-paging'; import usePatternsPaging from '../hooks/use-patterns-paging'; -import { allPatternsCategory } from '../block-patterns-tab'; -import { PATTERN_TYPES } from '../block-patterns-filter'; +import { allPatternsCategory, isPatternFiltered } from '../block-patterns-tab'; function PatternsListHeader( { filterValue, filteredBlockPatternsLength } ) { if ( ! filterValue ) { @@ -71,14 +70,7 @@ function PatternList( { const filteredBlockPatterns = useMemo( () => { if ( ! searchValue ) { return allPatterns.filter( ( pattern ) => { - if ( - ( filterValue === PATTERN_TYPES.theme && - pattern.name.startsWith( 'core/block' ) ) || - ( filterValue === PATTERN_TYPES.synced && - pattern.syncStatus !== '' ) || - ( filterValue === PATTERN_TYPES.unsynced && - pattern.syncStatus !== PATTERN_TYPES.unsynced ) - ) { + if ( isPatternFiltered( pattern, filterValue ) ) { return false; } 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 dd88a436f5c56d..7bd508825f1968 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -43,6 +43,16 @@ export const allPatternsCategory = { label: __( 'All' ), }; +export function isPatternFiltered( pattern, filterValue ) { + return ( + ( filterValue === PATTERN_TYPES.theme && + pattern.name.startsWith( 'core/block' ) ) || + ( filterValue === PATTERN_TYPES.synced && pattern.syncStatus !== '' ) || + ( filterValue === PATTERN_TYPES.unsynced && + pattern.syncStatus !== PATTERN_TYPES.unsynced ) + ); +} + export function usePatternsCategories( rootClientId, filter = 'all' ) { const { patterns: allPatterns, allCategories } = usePatternsState( undefined, @@ -52,13 +62,7 @@ export function usePatternsCategories( rootClientId, filter = 'all' ) { filter === 'all' ? allPatterns : allPatterns.filter( - ( pattern ) => - ( filter === PATTERN_TYPES.unsynced && - pattern.syncStatus === filter ) || - ( filter === PATTERN_TYPES.synced && - pattern.syncStatus === '' ) || - ( filter === PATTERN_TYPES.theme && - ! pattern.name.startsWith( 'core/block' ) ) + ( pattern ) => ! isPatternFiltered( pattern, filter ) ); const hasRegisteredCategory = useCallback( ( pattern ) => { @@ -170,14 +174,7 @@ export function BlockPatternsCategoryPanel( { const currentCategoryPatterns = useMemo( () => allPatterns.filter( ( pattern ) => { - if ( - ( patternFilter === PATTERN_TYPES.theme && - pattern.name.startsWith( 'core/block' ) ) || - ( patternFilter === PATTERN_TYPES.synced && - pattern.syncStatus !== '' ) || - ( patternFilter === PATTERN_TYPES.unsynced && - pattern.syncStatus !== PATTERN_TYPES.unsynced ) - ) { + if ( isPatternFiltered( pattern, patternFilter ) ) { return false; } From 2ad658746843f5135c77b2998cd716fbe2d22a21 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 10:27:34 +1200 Subject: [PATCH 18/61] Remove redundant fragment --- .../components/inserter/block-patterns-filter.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-filter.js b/packages/block-editor/src/components/inserter/block-patterns-filter.js index 4e33a9ea7a1b4b..3971ebff1e63dc 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-filter.js @@ -18,14 +18,12 @@ export const SYNC_FILTERS = [ export default function BlockPatternsFilter( { onChange, value } ) { return ( - <> - - + ); } From a9c4ae7873ceb6276e993c871d30d417aac72c85 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 10:36:10 +1200 Subject: [PATCH 19/61] Improve readability of pattern filter --- .../block-patterns-explorer/patterns-list.js | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) 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 32151a86a24bf7..2acd38ffcc89af 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 @@ -77,15 +77,17 @@ function PatternList( { if ( selectedCategory === allPatternsCategory.name ) { return true; } - return selectedCategory === 'uncategorized' - ? ! pattern.categories?.length || - pattern.categories.every( - ( category ) => - ! registeredPatternCategories.includes( - category - ) - ) - : pattern.categories?.includes( selectedCategory ); + + if ( selectedCategory === 'uncategorized' ) { + const hasKnownCategory = pattern.categories.some( + ( category ) => + registeredPatternCategories.includes( category ) + ); + + return ! pattern.categories?.length || ! hasKnownCategory; + } + + return pattern.categories?.includes( selectedCategory ); } ); } return searchItems( allPatterns, searchValue ); From f60beb846b583faf8df79a01476578beecb2a9bf Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 10:46:34 +1200 Subject: [PATCH 20/61] Spread paging props instead of destructuring --- .../block-patterns-explorer/patterns-list.js | 22 +++++-------------- .../components/inserter/block-patterns-tab.js | 22 +++++-------------- 2 files changed, 10 insertions(+), 34 deletions(-) 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 2acd38ffcc89af..f4b9fa20c96f20 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 @@ -113,14 +113,7 @@ function PatternList( { debouncedSpeak( resultsFoundMessage ); }, [ filterValue, debouncedSpeak, filteredBlockPatterns.length ] ); - const { - totalItems, - categoryPatterns, - categoryPatternsAsyncList, - numPages, - changePage, - currentPage, - } = usePatternsPaging( + const pagingProps = usePatternsPaging( filteredBlockPatterns, selectedCategory, '.components-modal__content.is-scrollable', @@ -140,19 +133,14 @@ function PatternList( { { ! hasItems && } { hasItems && ( ) } - { numPages > 1 && ( - + { pagingProps.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 7bd508825f1968..db211602f88802 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -200,14 +200,7 @@ export function BlockPatternsCategoryPanel( { [ allPatterns, availableCategories, category.name, patternFilter ] ); - const { - totalItems, - categoryPatterns, - categoryPatternsAsyncList, - numPages, - changePage, - currentPage, - } = usePatternsPaging( + const pagingProps = usePatternsPaging( currentCategoryPatterns, category, '.block-editor-inserter__patterns-category-dialog' @@ -227,8 +220,8 @@ export function BlockPatternsCategoryPanel( {

{ category.description }

- { numPages > 1 && ( - + { pagingProps.numPages > 1 && ( + ) }
); From 71271f3544399474f086bf35ad9e88b7ce29976d Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 11:18:20 +1200 Subject: [PATCH 21/61] Switch back to all category when changing filters --- .../components/inserter/block-patterns-explorer/sidebar.js | 6 +++++- .../src/components/inserter/block-patterns-tab.js | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js index 964c0b3bffdb57..31e22671e13a0c 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js @@ -8,6 +8,7 @@ import { __ } from '@wordpress/i18n'; * Internal dependencies */ import { default as BlockPatternsFilter } from '../block-patterns-filter'; +import { allPatternsCategory } from '../block-patterns-tab'; function PatternCategoriesList( { selectedCategory, @@ -69,7 +70,10 @@ function PatternExplorerSidebar( { /> { + setFilterValue( value ); + onClickCategory( allPatternsCategory.name ); + } } /> { ! searchValue && ( { setPatternFilter( value ); - onSelectCategory( selectedCategory, value ); + onSelectCategory( + allPatternsCategory, + value + ); } } /> { categories.map( ( category ) => ( From c62b4fd7a6771b3549a18eface922e58edbc1999 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 12:44:30 +1200 Subject: [PATCH 22/61] Remove duplicate items from inserter and fix icon alignmen --- .../components/block-patterns-list/index.js | 45 ++++++++++--------- .../components/block-patterns-list/style.scss | 9 ++-- packages/block-editor/src/store/selectors.js | 39 +--------------- 3 files changed, 30 insertions(+), 63 deletions(-) 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 daea191920efc6..a518fbf558af4c 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -8,10 +8,11 @@ import { __unstableUseCompositeState as useCompositeState, __unstableCompositeItem as CompositeItem, Tooltip, + __experimentalHStack as HStack, } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; -import { Icon, symbolFilled } from '@wordpress/icons'; +import { Icon, symbol } from '@wordpress/icons'; /** * Internal dependencies @@ -92,31 +93,33 @@ function BlockPattern( { blocks={ blocks } viewportWidth={ viewportWidth } /> - { ! showTooltip && ( -
- { pattern.title } -
- ) } + + { ! showTooltip && ( +
+ { pattern.title } +
+ ) } + { pattern.id && ! pattern.syncStatus && ( + +
+ +
+
+ ) } +
{ !! pattern.description && ( { pattern.description } ) } - { pattern.id && ! pattern.syncStatus && ( - - - - - - ) } diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index fbc1fddbbd1cae..ac830753272300 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -45,9 +45,10 @@ color: var(--wp-admin-theme-color); } - .block-editor-patterns__pattern-icon { - fill: #fff; - background: var(--wp-block-synced-color); - border-radius: 4px; + .block-editor-patterns__pattern-icon-wrapper { + padding-top: $grid-unit-10; + .block-editor-patterns__pattern-icon { + fill: var(--wp-block-synced-color); + } } } diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index fc6fb2d9f43357..d3e5aa4ca19a2e 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -18,7 +18,6 @@ import { } from '@wordpress/blocks'; import { Platform } from '@wordpress/element'; import { applyFilters } from '@wordpress/hooks'; -import { symbol } from '@wordpress/icons'; import { create, remove, toHTMLString } from '@wordpress/rich-text'; import deprecated from '@wordpress/deprecated'; import { createRegistrySelector } from '@wordpress/data'; @@ -1963,41 +1962,6 @@ const buildBlockTypeItem = */ export const getInserterItems = createSelector( ( state, rootClientId = null ) => { - const buildReusableBlockInserterItem = ( reusableBlock ) => { - const icon = ! reusableBlock.wp_pattern_sync_status - ? { - src: symbol, - foreground: 'var(--wp-block-synced-color)', - } - : symbol; - const id = `core/block/${ reusableBlock.id }`; - const { time, count = 0 } = getInsertUsage( state, id ) || {}; - const frecency = calculateFrecency( time, count ); - - return { - id, - name: 'core/block', - initialAttributes: { ref: reusableBlock.id }, - title: reusableBlock.title?.raw, - icon, - category: 'reusable', - keywords: [ 'reusable' ], - isDisabled: false, - utility: 1, // Deprecated. - frecency, - content: reusableBlock.content.raw, - syncStatus: reusableBlock.wp_pattern_sync_status, - }; - }; - - const syncedPatternInserterItems = canInsertBlockTypeUnmemoized( - state, - 'core/block', - rootClientId - ) - ? getReusableBlocks( state ).map( buildReusableBlockInserterItem ) - : []; - const buildBlockTypeInserterItem = buildBlockTypeItem( state, { buildScope: 'inserter', } ); @@ -2038,7 +2002,7 @@ export const getInserterItems = createSelector( { core: [], noncore: [] } ); const sortedBlockTypes = [ ...coreItems, ...nonCoreItems ]; - return [ ...sortedBlockTypes, ...syncedPatternInserterItems ]; + return [ ...sortedBlockTypes ]; }, ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ], @@ -2047,7 +2011,6 @@ export const getInserterItems = createSelector( state.preferences.insertUsage, state.settings.allowedBlockTypes, state.settings.templateLock, - getReusableBlocks( state ), getBlockTypes(), ] ); From de814a6e128cbc3afa6a2a8e044074fe340beba7 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 13:04:10 +1200 Subject: [PATCH 23/61] Pattern title layout --- .../src/components/block-patterns-list/index.js | 12 ++++++------ .../src/components/block-patterns-list/style.scss | 15 ++++++++++----- 2 files changed, 16 insertions(+), 11 deletions(-) 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 a518fbf558af4c..23d7d4f6546b63 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -93,12 +93,7 @@ function BlockPattern( { blocks={ blocks } viewportWidth={ viewportWidth } /> - - { ! showTooltip && ( -
- { pattern.title } -
- ) } + { pattern.id && ! pattern.syncStatus && ( ) } + { ! showTooltip && ( +
+ { pattern.title } +
+ ) }
{ !! pattern.description && ( diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index ac830753272300..d18b0051c0731b 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -29,7 +29,8 @@ .block-editor-block-patterns-list__item-title { padding-top: $grid-unit-10; font-size: 12px; - text-align: center; + text-align: left; + flex-grow: 1; } &:hover .block-editor-block-preview__container { @@ -45,10 +46,14 @@ color: var(--wp-admin-theme-color); } - .block-editor-patterns__pattern-icon-wrapper { - padding-top: $grid-unit-10; - .block-editor-patterns__pattern-icon { - fill: var(--wp-block-synced-color); + .block-editor-patterns__pattern-details { + align-items: flex-start; + .block-editor-patterns__pattern-icon-wrapper { + padding-top: $grid-unit-10; + min-width: 24px; + .block-editor-patterns__pattern-icon { + fill: var(--wp-block-synced-color); + } } } } From 48dcd35c08db49165d019ab6f67d997071a26fb1 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 14:58:53 +1200 Subject: [PATCH 24/61] Fix unit tests --- .../block-editor/src/store/test/selectors.js | 39 +------------------ 1 file changed, 2 insertions(+), 37 deletions(-) diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index dfc27f6d21d090..ccccd1411e07ad 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -7,7 +7,6 @@ import { setFreeformContentHandlerName, } from '@wordpress/blocks'; import { RawHTML } from '@wordpress/element'; -import { symbol } from '@wordpress/icons'; /** * Internal dependencies @@ -3289,7 +3288,7 @@ describe( 'selectors', () => { } ); describe( 'getInserterItems', () => { - it( 'should properly list block type and reusable block items', () => { + it( 'should properly list block type', () => { const state = { blocks: { byClientId: new Map(), @@ -3304,17 +3303,7 @@ describe( 'selectors', () => { } ) ), }, - settings: { - __experimentalReusableBlocks: [ - { - id: 1, - isTemporary: false, - clientId: 'block1', - title: { raw: 'Reusable Block 1' }, - content: { raw: '' }, - }, - ], - }, + settings: {}, // Intentionally include a test case which considers // `insertUsage` as not present within preferences. // @@ -3342,26 +3331,6 @@ describe( 'selectors', () => { utility: 1, variations: [], } ); - const reusableBlockItem = items.find( - ( item ) => item.id === 'core/block/1' - ); - expect( reusableBlockItem ).toEqual( { - category: 'reusable', - content: '', - frecency: 0, - icon: { - src: symbol, - foreground: 'var(--wp-block-synced-color)', - }, - id: 'core/block/1', - initialAttributes: { ref: 1 }, - isDisabled: false, - keywords: [ 'reusable' ], - name: 'core/block', - syncStatus: undefined, - title: 'Reusable Block 1', - utility: 1, - } ); } ); it( 'should correctly cache the return values', () => { @@ -3458,8 +3427,6 @@ describe( 'selectors', () => { 'core/freeform', 'core/test-block-ancestor', 'core/test-block-parent', - 'core/block/1', - 'core/block/2', ] ); const secondBlockFirstCall = getInserterItems( state, 'block4' ); @@ -3474,8 +3441,6 @@ describe( 'selectors', () => { 'core/freeform', 'core/test-block-ancestor', 'core/test-block-parent', - 'core/block/1', - 'core/block/2', ] ); expect( secondBlockSecondCall.map( ( item ) => item.id ) ).toEqual( [ 'core/test-block-b' ] From bb6cec5cee242ce67d06c35a839f545eff3fe001 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 15:53:31 +1200 Subject: [PATCH 25/61] Switch icon to center alignment --- .../src/components/block-patterns-list/index.js | 15 +++++++-------- .../src/components/block-patterns-list/style.scss | 15 +++++---------- 2 files changed, 12 insertions(+), 18 deletions(-) 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 23d7d4f6546b63..8ef3743460e7ee 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -8,7 +8,6 @@ import { __unstableUseCompositeState as useCompositeState, __unstableCompositeItem as CompositeItem, Tooltip, - __experimentalHStack as HStack, } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; @@ -93,7 +92,12 @@ function BlockPattern( { blocks={ blocks } viewportWidth={ viewportWidth } /> - +
+ { ! showTooltip && ( +
+ { pattern.title } +
+ ) } { pattern.id && ! pattern.syncStatus && ( ) } - { ! showTooltip && ( -
- { pattern.title } -
- ) } - +
{ !! pattern.description && ( { pattern.description } diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index d18b0051c0731b..fe5f414c24e842 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -29,8 +29,7 @@ .block-editor-block-patterns-list__item-title { padding-top: $grid-unit-10; font-size: 12px; - text-align: left; - flex-grow: 1; + text-align: center; } &:hover .block-editor-block-preview__container { @@ -46,14 +45,10 @@ color: var(--wp-admin-theme-color); } - .block-editor-patterns__pattern-details { - align-items: flex-start; - .block-editor-patterns__pattern-icon-wrapper { - padding-top: $grid-unit-10; - min-width: 24px; - .block-editor-patterns__pattern-icon { - fill: var(--wp-block-synced-color); - } + .block-editor-patterns__pattern-icon-wrapper { + text-align: center; + .block-editor-patterns__pattern-icon { + fill: var(--wp-block-synced-color); } } } From cec2b9a52f32021568ff7c79dc45e9c620e66100 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 16:29:54 +1200 Subject: [PATCH 26/61] Make the removal of reusable blocks more targeted to keep selector backwards compat --- .../src/components/inserter/search-results.js | 6 ++- packages/block-editor/src/store/selectors.js | 39 ++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/inserter/search-results.js b/packages/block-editor/src/components/inserter/search-results.js index 557a68fff5f23b..46cacb17846479 100644 --- a/packages/block-editor/src/components/inserter/search-results.js +++ b/packages/block-editor/src/components/inserter/search-results.js @@ -105,8 +105,10 @@ function InserterSearchResults( { if ( maxBlockTypesToShow === 0 ) { return []; } - - let orderedItems = orderBy( blockTypes, 'frecency', 'desc' ); + const nonPatternBlockTypes = blockTypes.filter( + ( blockType ) => blockType.name !== 'core/block' + ); + let orderedItems = orderBy( nonPatternBlockTypes, 'frecency', 'desc' ); if ( ! filterValue && prioritizedBlocks.length ) { orderedItems = orderInserterBlockItems( diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d3e5aa4ca19a2e..fc6fb2d9f43357 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -18,6 +18,7 @@ import { } from '@wordpress/blocks'; import { Platform } from '@wordpress/element'; import { applyFilters } from '@wordpress/hooks'; +import { symbol } from '@wordpress/icons'; import { create, remove, toHTMLString } from '@wordpress/rich-text'; import deprecated from '@wordpress/deprecated'; import { createRegistrySelector } from '@wordpress/data'; @@ -1962,6 +1963,41 @@ const buildBlockTypeItem = */ export const getInserterItems = createSelector( ( state, rootClientId = null ) => { + const buildReusableBlockInserterItem = ( reusableBlock ) => { + const icon = ! reusableBlock.wp_pattern_sync_status + ? { + src: symbol, + foreground: 'var(--wp-block-synced-color)', + } + : symbol; + const id = `core/block/${ reusableBlock.id }`; + const { time, count = 0 } = getInsertUsage( state, id ) || {}; + const frecency = calculateFrecency( time, count ); + + return { + id, + name: 'core/block', + initialAttributes: { ref: reusableBlock.id }, + title: reusableBlock.title?.raw, + icon, + category: 'reusable', + keywords: [ 'reusable' ], + isDisabled: false, + utility: 1, // Deprecated. + frecency, + content: reusableBlock.content.raw, + syncStatus: reusableBlock.wp_pattern_sync_status, + }; + }; + + const syncedPatternInserterItems = canInsertBlockTypeUnmemoized( + state, + 'core/block', + rootClientId + ) + ? getReusableBlocks( state ).map( buildReusableBlockInserterItem ) + : []; + const buildBlockTypeInserterItem = buildBlockTypeItem( state, { buildScope: 'inserter', } ); @@ -2002,7 +2038,7 @@ export const getInserterItems = createSelector( { core: [], noncore: [] } ); const sortedBlockTypes = [ ...coreItems, ...nonCoreItems ]; - return [ ...sortedBlockTypes ]; + return [ ...sortedBlockTypes, ...syncedPatternInserterItems ]; }, ( state, rootClientId ) => [ state.blockListSettings[ rootClientId ], @@ -2011,6 +2047,7 @@ export const getInserterItems = createSelector( state.preferences.insertUsage, state.settings.allowedBlockTypes, state.settings.templateLock, + getReusableBlocks( state ), getBlockTypes(), ] ); From 96b9459f04ddfedbd36a74912f9c3448664fbad4 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 16:30:58 +1200 Subject: [PATCH 27/61] Revert "Fix unit tests" This reverts commit 48dcd35c08db49165d019ab6f67d997071a26fb1. --- .../block-editor/src/store/test/selectors.js | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/store/test/selectors.js b/packages/block-editor/src/store/test/selectors.js index ccccd1411e07ad..dfc27f6d21d090 100644 --- a/packages/block-editor/src/store/test/selectors.js +++ b/packages/block-editor/src/store/test/selectors.js @@ -7,6 +7,7 @@ import { setFreeformContentHandlerName, } from '@wordpress/blocks'; import { RawHTML } from '@wordpress/element'; +import { symbol } from '@wordpress/icons'; /** * Internal dependencies @@ -3288,7 +3289,7 @@ describe( 'selectors', () => { } ); describe( 'getInserterItems', () => { - it( 'should properly list block type', () => { + it( 'should properly list block type and reusable block items', () => { const state = { blocks: { byClientId: new Map(), @@ -3303,7 +3304,17 @@ describe( 'selectors', () => { } ) ), }, - settings: {}, + settings: { + __experimentalReusableBlocks: [ + { + id: 1, + isTemporary: false, + clientId: 'block1', + title: { raw: 'Reusable Block 1' }, + content: { raw: '' }, + }, + ], + }, // Intentionally include a test case which considers // `insertUsage` as not present within preferences. // @@ -3331,6 +3342,26 @@ describe( 'selectors', () => { utility: 1, variations: [], } ); + const reusableBlockItem = items.find( + ( item ) => item.id === 'core/block/1' + ); + expect( reusableBlockItem ).toEqual( { + category: 'reusable', + content: '', + frecency: 0, + icon: { + src: symbol, + foreground: 'var(--wp-block-synced-color)', + }, + id: 'core/block/1', + initialAttributes: { ref: 1 }, + isDisabled: false, + keywords: [ 'reusable' ], + name: 'core/block', + syncStatus: undefined, + title: 'Reusable Block 1', + utility: 1, + } ); } ); it( 'should correctly cache the return values', () => { @@ -3427,6 +3458,8 @@ describe( 'selectors', () => { 'core/freeform', 'core/test-block-ancestor', 'core/test-block-parent', + 'core/block/1', + 'core/block/2', ] ); const secondBlockFirstCall = getInserterItems( state, 'block4' ); @@ -3441,6 +3474,8 @@ describe( 'selectors', () => { 'core/freeform', 'core/test-block-ancestor', 'core/test-block-parent', + 'core/block/1', + 'core/block/2', ] ); expect( secondBlockSecondCall.map( ( item ) => item.id ) ).toEqual( [ 'core/test-block-b' ] From 26f486b619cf8637ae8c0eb2a3880b851ebcfb9e Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Fri, 8 Sep 2023 17:29:53 +1200 Subject: [PATCH 28/61] Add show icon labels support to pagination --- .../components/block-patterns-paging/index.js | 21 +++++++++++----- .../block-patterns-paging/style.scss | 25 ++++++++++++++++++- 2 files changed, 39 insertions(+), 7 deletions(-) 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 4b57e9b500b8b3..610ff304e186ec 100644 --- a/packages/block-editor/src/components/block-patterns-paging/index.js +++ b/packages/block-editor/src/components/block-patterns-paging/index.js @@ -33,14 +33,18 @@ export default function Pagination( { justify="flex-start" className="block-editor-patterns__grid-pagination" > - + @@ -59,22 +63,27 @@ export default function Pagination( { numPages ) } - + diff --git a/packages/block-editor/src/components/block-patterns-paging/style.scss b/packages/block-editor/src/components/block-patterns-paging/style.scss index 321f251597e1ec..7de651f1511b65 100644 --- a/packages/block-editor/src/components/block-patterns-paging/style.scss +++ b/packages/block-editor/src/components/block-patterns-paging/style.scss @@ -3,7 +3,7 @@ padding: $grid-unit-05; .components-button.is-tertiary { - width: $button-size-compact; + width: auto; height: $button-size-compact; justify-content: center; @@ -13,7 +13,30 @@ } &:hover:not(:disabled) { + color: $white; background-color: $gray-700; } } } + +.show-icon-labels { + .block-editor-patterns__grid-pagination { + flex-direction: column; + .block-editor-patterns__grid-pagination-previous, + .block-editor-patterns__grid-pagination-next { + flex-direction: column; + } + .components-button { + width: auto; + // Hide the button icons when labels are set to display... + span { + display: none; + } + // ... and display labels. + // Uses ::before as ::after is already used for active tab styling. + &::before { + content: attr(aria-label); + } + } + } +} From e2292a151bc7dc9366ab7f572dafc1fb5d03e1f0 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 11 Sep 2023 10:09:37 +1200 Subject: [PATCH 29/61] Add the show-icons-label to the body element so it also gets applied to modals in the block editor --- packages/edit-post/src/components/layout/index.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/edit-post/src/components/layout/index.js b/packages/edit-post/src/components/layout/index.js index 35969ca1eb47d0..a0b4a2add9ba8e 100644 --- a/packages/edit-post/src/components/layout/index.js +++ b/packages/edit-post/src/components/layout/index.js @@ -220,11 +220,17 @@ function Layout() { [ entitiesSavedStatesCallback ] ); + // We need to add the show-icon-labels class to the body element so it is applied to modals. + if ( showIconLabels ) { + document.body.classList.add( 'show-icon-labels' ); + } else { + document.body.classList.remove( 'show-icon-labels' ); + } + const className = classnames( 'edit-post-layout', 'is-mode-' + mode, { 'is-sidebar-opened': sidebarIsOpened, 'has-fixed-toolbar': hasFixedToolbar, 'has-metaboxes': hasActiveMetaboxes, - 'show-icon-labels': showIconLabels, 'is-distraction-free': isDistractionFree && isLargeViewport, 'is-entity-save-view-open': !! entitiesSavedStatesCallback, } ); From 2f53ea25465d4bb9a1911f0aa678fdfbef408257 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 11 Sep 2023 10:37:10 +1200 Subject: [PATCH 30/61] Switch to using a ref and getScrollContainer to find scroll container --- .../inserter/block-patterns-explorer/patterns-list.js | 11 +++++++---- .../src/components/inserter/block-patterns-tab.js | 8 ++++++-- .../components/inserter/hooks/use-patterns-paging.js | 10 ++++++---- 3 files changed, 19 insertions(+), 10 deletions(-) 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 f4b9fa20c96f20..9396b3fde5363d 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,7 +1,7 @@ /** * WordPress dependencies */ -import { useMemo, useEffect } from '@wordpress/element'; +import { useMemo, useEffect, useRef } from '@wordpress/element'; import { _n, sprintf } from '@wordpress/i18n'; import { useDebounce } from '@wordpress/compose'; import { __experimentalHeading as Heading } from '@wordpress/components'; @@ -50,6 +50,7 @@ function PatternList( { selectedCategory, patternCategories, } ) { + const container = useRef(); const debouncedSpeak = useDebounce( speak, 500 ); const [ destinationRootClientId, onInsertBlocks ] = useInsertionPoint( { shouldFocusBlock: true, @@ -115,14 +116,16 @@ function PatternList( { const pagingProps = usePatternsPaging( filteredBlockPatterns, - selectedCategory, - '.components-modal__content.is-scrollable', + container, filterValue ); const hasItems = !! filteredBlockPatterns?.length; return ( -
+
{ hasItems && ( allPatterns.filter( ( pattern ) => { @@ -203,7 +204,7 @@ export function BlockPatternsCategoryPanel( { const pagingProps = usePatternsPaging( currentCategoryPatterns, category, - '.block-editor-inserter__patterns-category-dialog' + container ); // Hide block pattern preview on unmount. @@ -214,7 +215,10 @@ export function BlockPatternsCategoryPanel( { } return ( -
+
{ category.label }
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 index 5e83a86cb6eea8..02df0f2ca053e8 100644 --- a/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js +++ b/packages/block-editor/src/components/inserter/hooks/use-patterns-paging.js @@ -2,8 +2,8 @@ * WordPress dependencies */ import { useMemo, useState } from '@wordpress/element'; - import { useAsyncList, usePrevious } from '@wordpress/compose'; +import { getScrollContainer } from '@wordpress/dom'; const PAGE_SIZE = 20; const INITIAL_INSERTER_RESULTS = 5; @@ -13,7 +13,7 @@ const INITIAL_INSERTER_RESULTS = 5; * * @param {Array} currentCategoryPatterns An array of the current patterns to display. * @param {string} currentCategory The currently selected category. - * @param {string} scrollContainerClass Class of container to scroll when moving between pages. + * @param {Object} scrollContainerRef Ref of container to to find scroll container for when moving between pages. * @param {string} currentFilter The currently search filter. * * @return {Object} Returns the relevant paging values. (totalItems, categoryPatternsList, numPages, changePage, currentPage) @@ -21,7 +21,7 @@ const INITIAL_INSERTER_RESULTS = 5; export default function usePatternsPaging( currentCategoryPatterns, currentCategory, - scrollContainerClass, + scrollContainerRef, currentFilter = '' ) { const [ currentPage, setCurrentPage ] = useState( 1 ); @@ -47,7 +47,9 @@ export default function usePatternsPaging( } ); const numPages = Math.ceil( currentCategoryPatterns.length / PAGE_SIZE ); const changePage = ( page ) => { - const scrollContainer = document.querySelector( scrollContainerClass ); + const scrollContainer = getScrollContainer( + scrollContainerRef?.current + ); scrollContainer?.scrollTo( 0, 0 ); setCurrentPage( page ); From bf748865941dfcd9f27653276537d08e5f99672c Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 11 Sep 2023 11:36:59 +1200 Subject: [PATCH 31/61] remove the synced icon and instead use synced colored border on hover --- .../components/block-patterns-list/index.js | 29 ++++++++----------- .../components/block-patterns-list/style.scss | 9 +++--- 2 files changed, 17 insertions(+), 21 deletions(-) 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 8ef3743460e7ee..a993e819c8b1d9 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -11,7 +16,6 @@ import { } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; -import { Icon, symbol } from '@wordpress/icons'; /** * Internal dependencies @@ -71,7 +75,13 @@ function BlockPattern( { role="option" as="div" { ...composite } - className="block-editor-block-patterns-list__item" + className={ classnames( + 'block-editor-block-patterns-list__item', + { + 'block-editor-block-patterns-list__list-item-synced': + pattern.id && ! pattern.syncStatus, + } + ) } onClick={ () => { onClick( pattern, blocks ); onHover?.( null ); @@ -98,21 +108,6 @@ function BlockPattern( { { pattern.title }
) } - { pattern.id && ! pattern.syncStatus && ( - -
- -
-
- ) }
{ !! pattern.description && ( diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index fe5f414c24e842..c9cffdad54dd54 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -45,10 +45,11 @@ color: var(--wp-admin-theme-color); } - .block-editor-patterns__pattern-icon-wrapper { - text-align: center; - .block-editor-patterns__pattern-icon { - fill: var(--wp-block-synced-color); + &.block-editor-block-patterns-list__list-item-synced { + .block-editor-block-preview__container:hover { + box-shadow: + 0 0 0 2px var(--wp-block-synced-color), + 0 15px 25px rgb(0 0 0 / 7%); } } } From b8eadf5c6e0955db6f2b1bf4d368444a04200ba9 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 11 Sep 2023 13:38:47 +1200 Subject: [PATCH 32/61] Fix issues with category counts being announced more than once by screen reader --- .../components/inserter/block-patterns-tab.js | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) 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 33f481b055f643..53f645ca5b6adb 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -106,20 +106,20 @@ export function usePatternsCategories( rootClientId, filter = 'all' ) { label: allPatternsCategory.label, } ); } - + speak( + sprintf( + /* translators: %d: number of categories . */ + _n( + '%d category button displayed.', + '%d category buttons displayed.', + categories.length + ), + categories.length + ) + ); return categories; }, [ allCategories, filteredPatterns, hasRegisteredCategory ] ); - speak( - sprintf( - /* translators: %d: number of categories . */ - _n( - '%d category button displayed.', - '%d category buttons displayed.', - populatedCategories.length - ), - populatedCategories.length - ) - ); + return populatedCategories; } From 2153343e8efbeb2f1b08d19e75a78f39726c34a7 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 11 Sep 2023 14:02:22 +1200 Subject: [PATCH 33/61] Revert "remove the synced icon and instead use synced colored border on hover" This reverts commit bf748865941dfcd9f27653276537d08e5f99672c. --- .../components/block-patterns-list/index.js | 29 +++++++++++-------- .../components/block-patterns-list/style.scss | 9 +++--- 2 files changed, 21 insertions(+), 17 deletions(-) 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 a993e819c8b1d9..8ef3743460e7ee 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ @@ -16,6 +11,7 @@ import { } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; +import { Icon, symbol } from '@wordpress/icons'; /** * Internal dependencies @@ -75,13 +71,7 @@ function BlockPattern( { role="option" as="div" { ...composite } - className={ classnames( - 'block-editor-block-patterns-list__item', - { - 'block-editor-block-patterns-list__list-item-synced': - pattern.id && ! pattern.syncStatus, - } - ) } + className="block-editor-block-patterns-list__item" onClick={ () => { onClick( pattern, blocks ); onHover?.( null ); @@ -108,6 +98,21 @@ function BlockPattern( { { pattern.title }
) } + { pattern.id && ! pattern.syncStatus && ( + +
+ +
+
+ ) }
{ !! pattern.description && ( diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index c9cffdad54dd54..fe5f414c24e842 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -45,11 +45,10 @@ color: var(--wp-admin-theme-color); } - &.block-editor-block-patterns-list__list-item-synced { - .block-editor-block-preview__container:hover { - box-shadow: - 0 0 0 2px var(--wp-block-synced-color), - 0 15px 25px rgb(0 0 0 / 7%); + .block-editor-patterns__pattern-icon-wrapper { + text-align: center; + .block-editor-patterns__pattern-icon { + fill: var(--wp-block-synced-color); } } } From 1b4f30a4ae1e3d32e2ca67dc3363e233e49bbc17 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 11 Sep 2023 14:57:14 +1200 Subject: [PATCH 34/61] Put the icon back --- .../components/block-patterns-list/index.js | 47 +++++++++++-------- .../components/block-patterns-list/style.scss | 18 ++++++- 2 files changed, 43 insertions(+), 22 deletions(-) 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 8ef3743460e7ee..302fe731d21875 100644 --- a/packages/block-editor/src/components/block-patterns-list/index.js +++ b/packages/block-editor/src/components/block-patterns-list/index.js @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + /** * WordPress dependencies */ @@ -8,6 +13,7 @@ import { __unstableUseCompositeState as useCompositeState, __unstableCompositeItem as CompositeItem, Tooltip, + __experimentalHStack as HStack, } from '@wordpress/components'; import { useInstanceId } from '@wordpress/compose'; import { __ } from '@wordpress/i18n'; @@ -64,14 +70,20 @@ function BlockPattern( { } } > { onClick( pattern, blocks ); onHover?.( null ); @@ -92,28 +104,23 @@ function BlockPattern( { blocks={ blocks } viewportWidth={ viewportWidth } /> -
- { ! showTooltip && ( + + + { pattern.id && ! pattern.syncStatus && ( +
+ +
+ ) } + { ( ! showTooltip || pattern.id ) && (
{ pattern.title }
) } - { pattern.id && ! pattern.syncStatus && ( - -
- -
-
- ) } -
+
+ { !! pattern.description && ( { pattern.description } diff --git a/packages/block-editor/src/components/block-patterns-list/style.scss b/packages/block-editor/src/components/block-patterns-list/style.scss index fe5f414c24e842..69561aeab2d448 100644 --- a/packages/block-editor/src/components/block-patterns-list/style.scss +++ b/packages/block-editor/src/components/block-patterns-list/style.scss @@ -29,7 +29,8 @@ .block-editor-block-patterns-list__item-title { padding-top: $grid-unit-10; font-size: 12px; - text-align: center; + text-align: left; + flex-grow: 1; } &:hover .block-editor-block-preview__container { @@ -45,8 +46,21 @@ color: var(--wp-admin-theme-color); } + &.block-editor-block-patterns-list__list-item-synced { + .block-editor-block-preview__container:hover { + box-shadow: + 0 0 0 2px var(--wp-block-synced-color), + 0 15px 25px rgb(0 0 0 / 7%); + } + } + + .block-editor-patterns__pattern-details { + align-items: flex-start; + } + .block-editor-patterns__pattern-icon-wrapper { - text-align: center; + min-width: 24px; + padding-top: $grid-unit-10; .block-editor-patterns__pattern-icon { fill: var(--wp-block-synced-color); } From 39e5f8277a525916104bb2584f8234ed9e392044 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Mon, 11 Sep 2023 17:29:51 +1200 Subject: [PATCH 35/61] split out the sync toggle to pattern list page --- .../block-patterns-explorer/explorer.js | 16 ++- .../block-patterns-explorer/patterns-list.js | 11 +- .../inserter/block-patterns-filter.js | 8 +- .../inserter/block-patterns-sync-filter.js | 57 +++++++++ .../components/inserter/block-patterns-tab.js | 111 ++++++++++++++---- 5 files changed, 174 insertions(+), 29 deletions(-) create mode 100644 packages/block-editor/src/components/inserter/block-patterns-sync-filter.js diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js index be4756dcc8ed1f..6dc81f012174ff 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js @@ -4,24 +4,32 @@ import { Modal } from '@wordpress/components'; import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ import PatternExplorerSidebar from './sidebar'; import PatternList from './patterns-list'; -import { SYNC_FILTERS } from '../block-patterns-filter'; +import { PATTERN_FILTERS } from '../block-patterns-filter'; import { usePatternsCategories } from '../block-patterns-tab'; +import { store as blockEditorStore } from '../../../store'; function PatternsExplorer( { initialCategory, rootClientId } ) { const [ searchValue, setSearchValue ] = useState( '' ); - const [ filterValue, setFilterValue ] = useState( SYNC_FILTERS.all ); + const [ filterValue, setFilterValue ] = useState( PATTERN_FILTERS.all ); + const patternSyncFilter = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + const settings = getSettings(); + return settings.patternsSyncFilter || 'all'; + }, [] ); const [ selectedCategory, setSelectedCategory ] = useState( initialCategory?.name ); const patternCategories = usePatternsCategories( rootClientId, - filterValue + filterValue, + patternSyncFilter ); return ( @@ -40,6 +48,8 @@ function PatternsExplorer( { initialCategory, rootClientId } ) { filterValue={ filterValue } selectedCategory={ selectedCategory } patternCategories={ patternCategories } + patternFilter={ filterValue } + patternSyncFilter={ patternSyncFilter } /> ); 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 9396b3fde5363d..317d2f5961243f 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 @@ -19,6 +19,8 @@ import { searchItems } from '../search-items'; import BlockPatternsPaging from '../../block-patterns-paging'; import usePatternsPaging from '../hooks/use-patterns-paging'; import { allPatternsCategory, isPatternFiltered } from '../block-patterns-tab'; +import { BlockPatternsSyncFilter } from '../block-patterns-sync-filter'; +import { PATTERN_TYPES } from '../block-patterns-filter'; function PatternsListHeader( { filterValue, filteredBlockPatternsLength } ) { if ( ! filterValue ) { @@ -49,6 +51,7 @@ function PatternList( { filterValue, selectedCategory, patternCategories, + patternSyncFilter, } ) { const container = useRef(); const debouncedSpeak = useDebounce( speak, 500 ); @@ -71,7 +74,9 @@ function PatternList( { const filteredBlockPatterns = useMemo( () => { if ( ! searchValue ) { return allPatterns.filter( ( pattern ) => { - if ( isPatternFiltered( pattern, filterValue ) ) { + if ( + isPatternFiltered( pattern, filterValue, patternSyncFilter ) + ) { return false; } @@ -98,6 +103,7 @@ function PatternList( { allPatterns, selectedCategory, registeredPatternCategories, + patternSyncFilter, ] ); // Announce search results on change. @@ -134,6 +140,9 @@ function PatternList( { ) } { ! hasItems && } + { filterValue === PATTERN_TYPES.user && ( + + ) } { hasItems && ( { + updateSettings( { + patternsSyncFilter: value, + } ); + updateSyncFilter( value ); + }; + return ( + handleUpdateSyncFilter( value ) } + __nextHasNoMarginBottom + > + { Object.entries( SYNC_FILTERS ).map( ( [ key, syncLabel ] ) => ( + + ) ) } + + ); +} 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 53f645ca5b6adb..7ed574c4513ff9 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -20,6 +20,7 @@ import { import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; import { focus } from '@wordpress/dom'; import { speak } from '@wordpress/a11y'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies @@ -32,9 +33,14 @@ import BlockPatternsPaging from '../block-patterns-paging'; import usePatternsPaging from './hooks/use-patterns-paging'; import { PATTERN_TYPES, - SYNC_FILTERS, + PATTERN_FILTERS, default as BlockPatternsFilter, } from './block-patterns-filter'; +import { + BlockPatternsSyncFilter, + SYNC_TYPES, +} from './block-patterns-sync-filter'; +import { store as blockEditorStore } from '../../store'; const noop = () => {}; @@ -43,27 +49,54 @@ export const allPatternsCategory = { label: __( 'All' ), }; -export function isPatternFiltered( pattern, filterValue ) { - return ( - ( filterValue === PATTERN_TYPES.theme && - pattern.name.startsWith( 'core/block' ) ) || - ( filterValue === PATTERN_TYPES.synced && pattern.syncStatus !== '' ) || - ( filterValue === PATTERN_TYPES.unsynced && - pattern.syncStatus !== PATTERN_TYPES.unsynced ) - ); +export function isPatternFiltered( pattern, filterValue, syncFilter ) { + if ( + filterValue === PATTERN_TYPES.theme && + pattern.name.startsWith( 'core/block' ) + ) { + return true; + } + if ( filterValue === PATTERN_TYPES.user && ! pattern.id ) { + return true; + } + if ( + filterValue === PATTERN_TYPES.user && + syncFilter === SYNC_TYPES.full && + pattern.syncStatus !== '' + ) { + return true; + } + if ( + filterValue === PATTERN_TYPES.user && + syncFilter === SYNC_TYPES.unsynced && + pattern.syncStatus !== 'unsynced' + ) { + return true; + } + return false; } -export function usePatternsCategories( rootClientId, filter = 'all' ) { +export function usePatternsCategories( + rootClientId, + filter = 'all', + syncFilter +) { const { patterns: allPatterns, allCategories } = usePatternsState( undefined, rootClientId ); - const filteredPatterns = - filter === 'all' - ? allPatterns - : allPatterns.filter( - ( pattern ) => ! isPatternFiltered( pattern, filter ) - ); + + const filteredPatterns = useMemo( + () => + filter === 'all' + ? allPatterns + : allPatterns.filter( + ( pattern ) => + ! isPatternFiltered( pattern, filter, syncFilter ) + ), + [ filter, syncFilter, allPatterns ] + ); + const hasRegisteredCategory = useCallback( ( pattern ) => { if ( ! pattern.categories || ! pattern.categories.length ) { @@ -170,12 +203,27 @@ export function BlockPatternsCategoryPanel( { onInsert, rootClientId ); - const availableCategories = usePatternsCategories( rootClientId ); + const patternSyncFilter = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + const settings = getSettings(); + return settings.patternsSyncFilter || 'all'; + }, [] ); + const availableCategories = usePatternsCategories( + rootClientId, + patternFilter, + patternSyncFilter + ); const container = useRef(); const currentCategoryPatterns = useMemo( () => allPatterns.filter( ( pattern ) => { - if ( isPatternFiltered( pattern, patternFilter ) ) { + if ( + isPatternFiltered( + pattern, + patternFilter, + patternSyncFilter + ) + ) { return false; } @@ -198,7 +246,13 @@ export function BlockPatternsCategoryPanel( { return availablePatternCategories.length === 0; } ), - [ allPatterns, availableCategories, category.name, patternFilter ] + [ + allPatterns, + availableCategories, + category.name, + patternFilter, + patternSyncFilter, + ] ); const pagingProps = usePatternsPaging( @@ -223,6 +277,9 @@ export function BlockPatternsCategoryPanel( { { category.label }

{ category.description }

+ { patternFilter === PATTERN_TYPES.user && ( + + ) } { pagingProps.numPages > 1 && ( @@ -248,8 +306,19 @@ function BlockPatternsTabs( { rootClientId, } ) { const [ showPatternsExplorer, setShowPatternsExplorer ] = useState( false ); - const [ patternFilter, setPatternFilter ] = useState( SYNC_FILTERS.all ); - const categories = usePatternsCategories( rootClientId, patternFilter ); + const [ patternFilter, setPatternFilter ] = useState( PATTERN_FILTERS.all ); + const patternSyncFilter = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + const settings = getSettings(); + return settings.patternsSyncFilter || 'all'; + }, [] ); + + const categories = usePatternsCategories( + rootClientId, + patternFilter, + patternSyncFilter + ); + const initialCategory = selectedCategory || categories[ 0 ]; const isMobile = useViewportMatch( 'medium', '<' ); return ( From 48c36e58ca77ac96e34665ffa37165ad790634db Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 10:31:08 +1200 Subject: [PATCH 36/61] Tidy up naming --- .../block-patterns-explorer/explorer.js | 12 +++--- .../block-patterns-explorer/patterns-list.js | 29 +++++++++----- .../block-patterns-explorer/sidebar.js | 12 +++--- ...ter.js => block-patterns-source-filter.js} | 15 +++++-- .../components/inserter/block-patterns-tab.js | 39 ++++++++++--------- 5 files changed, 64 insertions(+), 43 deletions(-) rename packages/block-editor/src/components/inserter/{block-patterns-filter.js => block-patterns-source-filter.js} (62%) diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js index 6dc81f012174ff..5273dabced836b 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js @@ -11,13 +11,12 @@ import { useSelect } from '@wordpress/data'; */ import PatternExplorerSidebar from './sidebar'; import PatternList from './patterns-list'; -import { PATTERN_FILTERS } from '../block-patterns-filter'; import { usePatternsCategories } from '../block-patterns-tab'; import { store as blockEditorStore } from '../../../store'; function PatternsExplorer( { initialCategory, rootClientId } ) { const [ searchValue, setSearchValue ] = useState( '' ); - const [ filterValue, setFilterValue ] = useState( PATTERN_FILTERS.all ); + const [ patternSourceFilter, setPatternSourceFilter ] = useState( 'all' ); const patternSyncFilter = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); const settings = getSettings(); @@ -28,7 +27,7 @@ function PatternsExplorer( { initialCategory, rootClientId } ) { ); const patternCategories = usePatternsCategories( rootClientId, - filterValue, + patternSourceFilter, patternSyncFilter ); @@ -40,15 +39,14 @@ function PatternsExplorer( { initialCategory, rootClientId } ) { onClickCategory={ setSelectedCategory } searchValue={ searchValue } setSearchValue={ setSearchValue } - filterValue={ filterValue } - setFilterValue={ setFilterValue } + patternSourceFilter={ patternSourceFilter } + setPatternSourceFilter={ setPatternSourceFilter } /> 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 317d2f5961243f..28813a1f7881cb 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 @@ -20,7 +20,10 @@ import BlockPatternsPaging from '../../block-patterns-paging'; import usePatternsPaging from '../hooks/use-patterns-paging'; import { allPatternsCategory, isPatternFiltered } from '../block-patterns-tab'; import { BlockPatternsSyncFilter } from '../block-patterns-sync-filter'; -import { PATTERN_TYPES } from '../block-patterns-filter'; +import { + PATTERN_TYPES, + PATTERN_SOURCE_FILTERS, +} from '../block-patterns-source-filter'; function PatternsListHeader( { filterValue, filteredBlockPatternsLength } ) { if ( ! filterValue ) { @@ -48,7 +51,7 @@ function PatternsListHeader( { filterValue, filteredBlockPatternsLength } ) { function PatternList( { searchValue, - filterValue, + patternSourceFilter, selectedCategory, patternCategories, patternSyncFilter, @@ -75,7 +78,11 @@ function PatternList( { if ( ! searchValue ) { return allPatterns.filter( ( pattern ) => { if ( - isPatternFiltered( pattern, filterValue, patternSyncFilter ) + isPatternFiltered( + pattern, + patternSourceFilter, + patternSyncFilter + ) ) { return false; } @@ -99,7 +106,7 @@ function PatternList( { return searchItems( allPatterns, searchValue ); }, [ searchValue, - filterValue, + patternSourceFilter, allPatterns, selectedCategory, registeredPatternCategories, @@ -108,7 +115,7 @@ function PatternList( { // Announce search results on change. useEffect( () => { - if ( ! filterValue ) { + if ( ! searchValue ) { return; } const count = filteredBlockPatterns.length; @@ -118,12 +125,13 @@ function PatternList( { count ); debouncedSpeak( resultsFoundMessage ); - }, [ filterValue, debouncedSpeak, filteredBlockPatterns.length ] ); + }, [ searchValue, debouncedSpeak, filteredBlockPatterns.length ] ); const pagingProps = usePatternsPaging( filteredBlockPatterns, + selectedCategory, container, - filterValue + patternSourceFilter ); const hasItems = !! filteredBlockPatterns?.length; @@ -134,13 +142,16 @@ function PatternList( { > { hasItems && ( ) } { ! hasItems && } - { filterValue === PATTERN_TYPES.user && ( + { patternSourceFilter === PATTERN_TYPES.user && ( ) } { hasItems && ( diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js index 31e22671e13a0c..06ea794aa4daca 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/sidebar.js @@ -7,7 +7,7 @@ import { __ } from '@wordpress/i18n'; /** * Internal dependencies */ -import { default as BlockPatternsFilter } from '../block-patterns-filter'; +import { default as BlockPatternsSourceFilter } from '../block-patterns-source-filter'; import { allPatternsCategory } from '../block-patterns-tab'; function PatternCategoriesList( { @@ -56,8 +56,8 @@ function PatternExplorerSidebar( { selectedCategory, patternCategories, onClickCategory, - filterValue, - setFilterValue, + patternSourceFilter, + setPatternSourceFilter, searchValue, setSearchValue, } ) { @@ -68,10 +68,10 @@ function PatternExplorerSidebar( { searchValue={ searchValue } setSearchValue={ setSearchValue } /> - { - setFilterValue( value ); + setPatternSourceFilter( value ); onClickCategory( allPatternsCategory.name ); } } /> diff --git a/packages/block-editor/src/components/inserter/block-patterns-filter.js b/packages/block-editor/src/components/inserter/block-patterns-source-filter.js similarity index 62% rename from packages/block-editor/src/components/inserter/block-patterns-filter.js rename to packages/block-editor/src/components/inserter/block-patterns-source-filter.js index 145730ac5038c6..85ad89c6a5dcae 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-source-filter.js @@ -10,17 +10,26 @@ export const PATTERN_TYPES = { user: 'user', theme: 'theme', }; -export const PATTERN_FILTERS = [ + +const patternSourceOptions = [ { value: 'all', label: __( 'Unfiltered' ) }, { value: PATTERN_TYPES.theme, label: __( 'Theme patterns' ) }, { value: PATTERN_TYPES.user, label: __( 'My patterns' ) }, ]; -export default function BlockPatternsFilter( { onChange, value } ) { +export const PATTERN_SOURCE_FILTERS = patternSourceOptions.reduce( + ( patternSourceFilters, { value, label } ) => { + patternSourceFilters[ value ] = label; + return patternSourceFilters; + }, + {} +); + +export default function BlockPatternsSourceFilter( { onChange, value } ) { return ( - filter === 'all' + sourceFilter === 'all' ? allPatterns : allPatterns.filter( ( pattern ) => - ! isPatternFiltered( pattern, filter, syncFilter ) + ! isPatternFiltered( + pattern, + sourceFilter, + syncFilter + ) ), - [ filter, syncFilter, allPatterns ] + [ sourceFilter, syncFilter, allPatterns ] ); const hasRegisteredCategory = useCallback( @@ -306,7 +309,7 @@ function BlockPatternsTabs( { rootClientId, } ) { const [ showPatternsExplorer, setShowPatternsExplorer ] = useState( false ); - const [ patternFilter, setPatternFilter ] = useState( PATTERN_FILTERS.all ); + const [ patternSourceFilter, setPatternSourceFilter ] = useState( 'all' ); const patternSyncFilter = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); const settings = getSettings(); @@ -315,7 +318,7 @@ function BlockPatternsTabs( { const categories = usePatternsCategories( rootClientId, - patternFilter, + patternSourceFilter, patternSyncFilter ); @@ -330,10 +333,10 @@ function BlockPatternsTabs( { role="list" className="block-editor-inserter__block-patterns-tabs" > - { - setPatternFilter( value ); + setPatternSourceFilter( value ); onSelectCategory( allPatternsCategory, value @@ -347,7 +350,7 @@ function BlockPatternsTabs( { onClick={ () => onSelectCategory( category, - patternFilter + patternSourceFilter ) } className={ From 351204d865dd90ff66bbde70e6665af9228a2c7d Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 10:49:01 +1200 Subject: [PATCH 37/61] Set height of select filter --- .../src/components/inserter/block-patterns-source-filter.js | 1 + packages/block-editor/src/components/inserter/style.scss | 3 +++ 2 files changed, 4 insertions(+) diff --git a/packages/block-editor/src/components/inserter/block-patterns-source-filter.js b/packages/block-editor/src/components/inserter/block-patterns-source-filter.js index 85ad89c6a5dcae..ca1bc52e64476a 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-source-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-source-filter.js @@ -28,6 +28,7 @@ export const PATTERN_SOURCE_FILTERS = patternSourceOptions.reduce( export default function BlockPatternsSourceFilter( { onChange, value } ) { return ( Date: Tue, 12 Sep 2023 11:54:55 +1200 Subject: [PATCH 38/61] Reset categories if changing sync filter --- .../inserter/block-patterns-sync-filter.js | 12 ++++++++---- .../components/inserter/block-patterns-tab.js | 19 ++++++++++++++++++- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js index 1f7100a347ca1c..acf516cd1ee00f 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js @@ -6,8 +6,7 @@ import { __experimentalToggleGroupControlOption as ToggleGroupControlOption, } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; -import { useDispatch } from '@wordpress/data'; -import { useState } from '@wordpress/element'; +import { useDispatch, useSelect } from '@wordpress/data'; /** * Internal dependencies @@ -25,15 +24,20 @@ const SYNC_FILTERS = { }; export function BlockPatternsSyncFilter() { - const [ syncFilter, updateSyncFilter ] = useState( 'all' ); const { updateSettings } = useDispatch( blockEditorStore ); + const syncFilter = useSelect( ( select ) => { + const { getSettings } = select( blockEditorStore ); + const settings = getSettings(); + return settings.patternsSyncFilter || 'all'; + }, [] ); + const handleUpdateSyncFilter = ( value ) => { updateSettings( { patternsSyncFilter: value, } ); - updateSyncFilter( value ); }; + return ( { + if ( + patternSyncFilter !== null && + previousSyncFilter !== patternSyncFilter + ) { + onSelectCategory( allPatternsCategory, patternSourceFilter ); + } + }, [ + patternSyncFilter, + previousSyncFilter, + onSelectCategory, + patternSourceFilter, + ] ); const categories = usePatternsCategories( rootClientId, From 5199163487df0af14995550c76dc3fb8f5ee6876 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 12:10:11 +1200 Subject: [PATCH 39/61] Reset category when changing sync filter in patterns explorer --- .../block-patterns-explorer/explorer.js | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js index 5273dabced836b..78fc75c9c3a80d 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js @@ -2,9 +2,10 @@ * WordPress dependencies */ import { Modal } from '@wordpress/components'; -import { useState } from '@wordpress/element'; +import { useState, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; +import { usePrevious } from '@wordpress/compose'; /** * Internal dependencies @@ -25,6 +26,25 @@ function PatternsExplorer( { initialCategory, rootClientId } ) { const [ selectedCategory, setSelectedCategory ] = useState( initialCategory?.name ); + + const previousSyncFilter = usePrevious( patternSyncFilter ); + + // If the sync filter changes, we need to select the "All" category to avoid + // showing a confusing no results screen. + useEffect( () => { + if ( + patternSyncFilter !== null && + previousSyncFilter !== patternSyncFilter + ) { + setSelectedCategory( initialCategory?.name ); + } + }, [ + patternSyncFilter, + previousSyncFilter, + patternSourceFilter, + initialCategory?.name, + ] ); + const patternCategories = usePatternsCategories( rootClientId, patternSourceFilter, From 6fbc69941d4c51718986ed889276459fc0fda191 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 12:18:43 +1200 Subject: [PATCH 40/61] remove sync filter when searching --- .../inserter/block-patterns-explorer/patterns-list.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 28813a1f7881cb..79bd8867a75214 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 @@ -151,9 +151,8 @@ function PatternList( { ) } { ! hasItems && } - { patternSourceFilter === PATTERN_TYPES.user && ( - - ) } + { patternSourceFilter === PATTERN_TYPES.user && + ! searchValue && } { hasItems && ( Date: Tue, 12 Sep 2023 12:45:23 +1200 Subject: [PATCH 41/61] constrain width of sync toggle in pattern explorer --- .../src/components/inserter/block-patterns-sync-filter.js | 4 ++-- packages/block-editor/src/components/inserter/style.scss | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js index acf516cd1ee00f..d121a422f96b52 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js @@ -40,7 +40,7 @@ export function BlockPatternsSyncFilter() { return ( { Object.entries( SYNC_FILTERS ).map( ( [ key, syncLabel ] ) => ( Date: Tue, 12 Sep 2023 13:33:00 +1200 Subject: [PATCH 42/61] Also set filter height in patterns explorer --- packages/block-editor/src/components/inserter/style.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/inserter/style.scss b/packages/block-editor/src/components/inserter/style.scss index 5871da26be3888..cae7ca3d3d69eb 100644 --- a/packages/block-editor/src/components/inserter/style.scss +++ b/packages/block-editor/src/components/inserter/style.scss @@ -271,7 +271,8 @@ $block-inserter-tabs-height: 44px; } } -.block-editor-inserter__block-patterns-tabs-container { +.block-editor-inserter__block-patterns-tabs-container, +.block-editor-block-patterns-explorer__sidebar { height: 100%; nav { height: 100%; From f845d6671b7c0e8f25a5ec5a74df7a70761c9557 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 14:01:40 +1200 Subject: [PATCH 43/61] Switch to select for sync filter temporarily --- .../inserter/block-patterns-source-filter.js | 2 +- .../inserter/block-patterns-sync-filter.js | 35 ++++++------------- .../src/components/inserter/style.scss | 12 ++++--- 3 files changed, 20 insertions(+), 29 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-source-filter.js b/packages/block-editor/src/components/inserter/block-patterns-source-filter.js index ca1bc52e64476a..27bb4d4f8ba959 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-source-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-source-filter.js @@ -29,7 +29,7 @@ export default function BlockPatternsSourceFilter( { onChange, value } ) { return ( handleUpdateSyncFilter( value ) } - __nextHasNoMarginBottom - > - { Object.entries( SYNC_FILTERS ).map( ( [ key, syncLabel ] ) => ( - - ) ) } - + aria-label={ __( 'Filter patterns by sync type' ) } + /> ); } diff --git a/packages/block-editor/src/components/inserter/style.scss b/packages/block-editor/src/components/inserter/style.scss index cae7ca3d3d69eb..5cb55ddd279eb4 100644 --- a/packages/block-editor/src/components/inserter/style.scss +++ b/packages/block-editor/src/components/inserter/style.scss @@ -459,10 +459,6 @@ $block-inserter-tabs-height: 44px; padding: $grid-unit-30 0 $grid-unit-40; } - .block-editor-patterns__sync-status-filter { - width: fit-content; - } - .block-editor-block-patterns-list { display: grid; grid-gap: $grid-unit-40; @@ -747,3 +743,11 @@ $block-inserter-tabs-height: 44px; .components-menu-group .reusable-blocks-menu-items__rename-hint { margin: 0; } + +.block-editor-patterns__sync-status-filter +.components-input-control__container { + width: fit-content; + select.components-select-control__input { + height: 40px; + } +} From 720d3cb9e494ebf42f5b485287149ad330735de5 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 14:22:05 +1200 Subject: [PATCH 44/61] Fix filter width --- .../src/components/inserter/style.scss | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/block-editor/src/components/inserter/style.scss b/packages/block-editor/src/components/inserter/style.scss index 5cb55ddd279eb4..b7909902dbb317 100644 --- a/packages/block-editor/src/components/inserter/style.scss +++ b/packages/block-editor/src/components/inserter/style.scss @@ -457,6 +457,11 @@ $block-inserter-tabs-height: 44px; &__list { margin-left: $sidebar-width; padding: $grid-unit-30 0 $grid-unit-40; + .block-editor-patterns__sync-status-filter { + .components-input-control__container { + width: 380px; + } + } } .block-editor-block-patterns-list { @@ -744,10 +749,10 @@ $block-inserter-tabs-height: 44px; margin: 0; } -.block-editor-patterns__sync-status-filter -.components-input-control__container { - width: fit-content; - select.components-select-control__input { - height: 40px; +.block-editor-patterns__sync-status-filter { + .components-input-control__container { + select.components-select-control__input { + height: 40px; + } } } From 0ee4b81f03a07c049be104b8d6b32610a7536d1a Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 15:26:23 +1200 Subject: [PATCH 45/61] Reset sync filter setting to all each time it is mounted --- .../components/inserter/block-patterns-sync-filter.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js index d48e262ccd9729..1a03b5103b6f08 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js @@ -4,6 +4,7 @@ import { SelectControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { useDispatch, useSelect } from '@wordpress/data'; +import { useEffect } from '@wordpress/element'; /** * Internal dependencies @@ -23,6 +24,14 @@ const patternSyncOptions = [ export function BlockPatternsSyncFilter() { const { updateSettings } = useDispatch( blockEditorStore ); + useEffect( () => { + updateSettings( { + patternsSyncFilter: 'all', + } ); + // The first time the component is mounted, we want to reset the sync filter setting. + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [] ); + const syncFilter = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); const settings = getSettings(); From 8839f7a351dde81a5633673a607435989996e430 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 15:28:18 +1200 Subject: [PATCH 46/61] Revert "Reset sync filter setting to all each time it is mounted" This reverts commit 0ee4b81f03a07c049be104b8d6b32610a7536d1a. --- .../components/inserter/block-patterns-sync-filter.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js index 1a03b5103b6f08..d48e262ccd9729 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js @@ -4,7 +4,6 @@ import { SelectControl } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; import { useDispatch, useSelect } from '@wordpress/data'; -import { useEffect } from '@wordpress/element'; /** * Internal dependencies @@ -24,14 +23,6 @@ const patternSyncOptions = [ export function BlockPatternsSyncFilter() { const { updateSettings } = useDispatch( blockEditorStore ); - useEffect( () => { - updateSettings( { - patternsSyncFilter: 'all', - } ); - // The first time the component is mounted, we want to reset the sync filter setting. - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [] ); - const syncFilter = useSelect( ( select ) => { const { getSettings } = select( blockEditorStore ); const settings = getSettings(); From 5951dad7e22d5786bfb035cbbdafb6e0cb63733b Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Tue, 12 Sep 2023 21:45:30 +1200 Subject: [PATCH 47/61] Fix issue with all category auto opening when tab first opened --- .../block-patterns-explorer/explorer.js | 21 +------------------ .../components/inserter/block-patterns-tab.js | 19 +---------------- 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js index 78fc75c9c3a80d..9f91433690fc87 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js @@ -2,10 +2,9 @@ * WordPress dependencies */ import { Modal } from '@wordpress/components'; -import { useState, useEffect } from '@wordpress/element'; +import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; -import { usePrevious } from '@wordpress/compose'; /** * Internal dependencies @@ -27,24 +26,6 @@ function PatternsExplorer( { initialCategory, rootClientId } ) { initialCategory?.name ); - const previousSyncFilter = usePrevious( patternSyncFilter ); - - // If the sync filter changes, we need to select the "All" category to avoid - // showing a confusing no results screen. - useEffect( () => { - if ( - patternSyncFilter !== null && - previousSyncFilter !== patternSyncFilter - ) { - setSelectedCategory( initialCategory?.name ); - } - }, [ - patternSyncFilter, - previousSyncFilter, - patternSourceFilter, - initialCategory?.name, - ] ); - const patternCategories = usePatternsCategories( rootClientId, patternSourceFilter, 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 587692faf91124..a4aa8a84161885 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, __, _n, isRTL, sprintf } from '@wordpress/i18n'; -import { useViewportMatch, usePrevious } from '@wordpress/compose'; +import { useViewportMatch } from '@wordpress/compose'; import { __experimentalItemGroup as ItemGroup, __experimentalItem as Item, @@ -315,23 +315,6 @@ function BlockPatternsTabs( { const settings = getSettings(); return settings.patternsSyncFilter || 'all'; }, [] ); - const previousSyncFilter = usePrevious( patternSyncFilter ); - - // If the sync filter changes, we need to select the "All" category to avoid - // showing a confusing no results screen. - useEffect( () => { - if ( - patternSyncFilter !== null && - previousSyncFilter !== patternSyncFilter - ) { - onSelectCategory( allPatternsCategory, patternSourceFilter ); - } - }, [ - patternSyncFilter, - previousSyncFilter, - onSelectCategory, - patternSourceFilter, - ] ); const categories = usePatternsCategories( rootClientId, From 3a920f9553649a07bfb70c611c60134e3c848613 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Sep 2023 09:07:55 +1200 Subject: [PATCH 48/61] Suggesting wording changes from design review --- .../src/components/inserter/block-patterns-source-filter.js | 3 ++- .../src/components/inserter/block-patterns-sync-filter.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-source-filter.js b/packages/block-editor/src/components/inserter/block-patterns-source-filter.js index 27bb4d4f8ba959..ec2072a0cb4970 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-source-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-source-filter.js @@ -12,7 +12,7 @@ export const PATTERN_TYPES = { }; const patternSourceOptions = [ - { value: 'all', label: __( 'Unfiltered' ) }, + { value: 'all', label: __( 'All' ) }, { value: PATTERN_TYPES.theme, label: __( 'Theme patterns' ) }, { value: PATTERN_TYPES.user, label: __( 'My patterns' ) }, ]; @@ -34,6 +34,7 @@ export default function BlockPatternsSourceFilter( { onChange, value } ) { value={ value } onChange={ onChange } aria-label={ __( 'Filter patterns by type' ) } + hideLabelFromVision /> ); } diff --git a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js index d48e262ccd9729..07c4c0d8fa1b1d 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js +++ b/packages/block-editor/src/components/inserter/block-patterns-sync-filter.js @@ -15,7 +15,7 @@ export const SYNC_TYPES = { }; const patternSyncOptions = [ - { value: 'all', label: __( 'Any' ) }, + { value: 'all', label: __( 'All' ) }, { value: SYNC_TYPES.full, label: __( 'Synced' ) }, { value: SYNC_TYPES.unsynced, label: __( 'Standard' ) }, ]; @@ -38,7 +38,7 @@ export function BlockPatternsSyncFilter() { return ( handleUpdateSyncFilter( value ) } From 546026fb43ab55cb82f3ea60a789ea146f5e4bfe Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Sep 2023 09:09:24 +1200 Subject: [PATCH 49/61] Revert "Fix issue with all category auto opening when tab first opened" This reverts commit 5951dad7e22d5786bfb035cbbdafb6e0cb63733b. --- .../block-patterns-explorer/explorer.js | 21 ++++++++++++++++++- .../components/inserter/block-patterns-tab.js | 19 ++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js index 9f91433690fc87..78fc75c9c3a80d 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js +++ b/packages/block-editor/src/components/inserter/block-patterns-explorer/explorer.js @@ -2,9 +2,10 @@ * WordPress dependencies */ import { Modal } from '@wordpress/components'; -import { useState } from '@wordpress/element'; +import { useState, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { useSelect } from '@wordpress/data'; +import { usePrevious } from '@wordpress/compose'; /** * Internal dependencies @@ -26,6 +27,24 @@ function PatternsExplorer( { initialCategory, rootClientId } ) { initialCategory?.name ); + const previousSyncFilter = usePrevious( patternSyncFilter ); + + // If the sync filter changes, we need to select the "All" category to avoid + // showing a confusing no results screen. + useEffect( () => { + if ( + patternSyncFilter !== null && + previousSyncFilter !== patternSyncFilter + ) { + setSelectedCategory( initialCategory?.name ); + } + }, [ + patternSyncFilter, + previousSyncFilter, + patternSourceFilter, + initialCategory?.name, + ] ); + const patternCategories = usePatternsCategories( rootClientId, patternSourceFilter, 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 a4aa8a84161885..587692faf91124 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, __, _n, isRTL, sprintf } from '@wordpress/i18n'; -import { useViewportMatch } from '@wordpress/compose'; +import { useViewportMatch, usePrevious } from '@wordpress/compose'; import { __experimentalItemGroup as ItemGroup, __experimentalItem as Item, @@ -315,6 +315,23 @@ function BlockPatternsTabs( { const settings = getSettings(); return settings.patternsSyncFilter || 'all'; }, [] ); + const previousSyncFilter = usePrevious( patternSyncFilter ); + + // If the sync filter changes, we need to select the "All" category to avoid + // showing a confusing no results screen. + useEffect( () => { + if ( + patternSyncFilter !== null && + previousSyncFilter !== patternSyncFilter + ) { + onSelectCategory( allPatternsCategory, patternSourceFilter ); + } + }, [ + patternSyncFilter, + previousSyncFilter, + onSelectCategory, + patternSourceFilter, + ] ); const categories = usePatternsCategories( rootClientId, From 389285f3d02b9b6d7c0103bf89cff09a6eb961d9 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Sep 2023 09:13:56 +1200 Subject: [PATCH 50/61] Remove the all category and have all panel open by default --- .../src/components/inserter/block-patterns-tab.js | 6 ------ 1 file changed, 6 deletions(-) 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 587692faf91124..685e38e0735167 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -136,12 +136,6 @@ export function usePatternsCategories( label: _x( 'Uncategorized' ), } ); } - if ( filteredPatterns.length > 0 ) { - categories.unshift( { - name: allPatternsCategory.name, - label: allPatternsCategory.label, - } ); - } speak( sprintf( /* translators: %d: number of categories . */ From 5fd5edc44fda436934dc8877ea681014281ffcf6 Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Sep 2023 09:51:55 +1200 Subject: [PATCH 51/61] Remove spoken announcement of category count from hook as currently to much potential for rerender --- .../src/components/inserter/block-patterns-tab.js | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) 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 685e38e0735167..c4172169442d6c 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -8,7 +8,7 @@ import { useRef, useEffect, } from '@wordpress/element'; -import { _x, __, _n, isRTL, sprintf } from '@wordpress/i18n'; +import { _x, __, isRTL } from '@wordpress/i18n'; import { useViewportMatch, usePrevious } from '@wordpress/compose'; import { __experimentalItemGroup as ItemGroup, @@ -19,7 +19,6 @@ import { } from '@wordpress/components'; import { Icon, chevronRight, chevronLeft } from '@wordpress/icons'; import { focus } from '@wordpress/dom'; -import { speak } from '@wordpress/a11y'; import { useSelect } from '@wordpress/data'; /** @@ -136,17 +135,6 @@ export function usePatternsCategories( label: _x( 'Uncategorized' ), } ); } - speak( - sprintf( - /* translators: %d: number of categories . */ - _n( - '%d category button displayed.', - '%d category buttons displayed.', - categories.length - ), - categories.length - ) - ); return categories; }, [ allCategories, filteredPatterns, hasRegisteredCategory ] ); From 2cb5cfc51efda8e9f95dd499c57cd2e19e8f899a Mon Sep 17 00:00:00 2001 From: Glen Davies Date: Wed, 13 Sep 2023 11:58:25 +1200 Subject: [PATCH 52/61] Move filter above category list --- .../components/inserter/block-patterns-tab.js | 27 +++++++++---------- 1 file changed, 12 insertions(+), 15 deletions(-) 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 c4172169442d6c..66030247a6cd0d 100644 --- a/packages/block-editor/src/components/inserter/block-patterns-tab.js +++ b/packages/block-editor/src/components/inserter/block-patterns-tab.js @@ -327,21 +327,18 @@ function BlockPatternsTabs( { <> { ! isMobile && (
-