diff --git a/packages/base-styles/_z-index.scss b/packages/base-styles/_z-index.scss index 4d5f22e02fa7d1..cc99df6dbeaafc 100644 --- a/packages/base-styles/_z-index.scss +++ b/packages/base-styles/_z-index.scss @@ -131,7 +131,6 @@ $z-layers: ( ".block-editor-template-part__selection-modal": 1000001, ".block-editor-block-rename-modal": 1000001, ".edit-site-list__rename-modal": 1000001, - ".dataviews-bulk-actions__modal": 1000001, ".dataviews-action-modal": 1000001, ".editor-action-modal": 1000001, ".editor-post-template__swap-template-modal": 1000001, @@ -194,7 +193,6 @@ $z-layers: ( // Site editor layout ".edit-site-page-header": 2, ".edit-site-page-content": 1, - ".edit-site-patterns__dataviews-list-pagination": 2, ".edit-site-templates__dataviews-list-pagination": 2, ".edit-site-layout__canvas-container": 2, ".edit-site-layout__sidebar": 1, @@ -211,8 +209,8 @@ $z-layers: ( // Ensure selection checkbox stays above the preview field. ".dataviews-view-grid__card .dataviews-selection-checkbox": 1, - // Ensure quick actions toolbar appear above pagination - ".dataviews-bulk-actions-toolbar": 2, + // Ensure footer stays above the preview field. + ".dataviews-footer": 2, ); @function z-index( $key ) { diff --git a/packages/dataviews/src/components/dataviews-bulk-actions-toolbar/index.tsx b/packages/dataviews/src/components/dataviews-bulk-actions-toolbar/index.tsx deleted file mode 100644 index 09e9d5f9df8120..00000000000000 --- a/packages/dataviews/src/components/dataviews-bulk-actions-toolbar/index.tsx +++ /dev/null @@ -1,288 +0,0 @@ -/** - * WordPress dependencies - */ -import { - ToolbarButton, - Toolbar, - ToolbarGroup, - __unstableMotion as motion, - __unstableAnimatePresence as AnimatePresence, -} from '@wordpress/components'; -import { useMemo, useState, useRef, useContext } from '@wordpress/element'; -import { _n, sprintf, __ } from '@wordpress/i18n'; -import { closeSmall } from '@wordpress/icons'; -import { useReducedMotion } from '@wordpress/compose'; -import { useRegistry } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import { useSomeItemHasAPossibleBulkAction } from '../dataviews-bulk-actions'; -import DataViewsContext from '../dataviews-context'; -import { ActionWithModal } from '../dataviews-item-actions'; -import { LAYOUT_GRID, LAYOUT_TABLE } from '../../constants'; -import type { Action } from '../../types'; -import type { ActionTriggerProps } from '../dataviews-item-actions'; -import type { SetSelection } from '../../private-types'; - -interface ActionButtonProps< Item > { - action: Action< Item >; - selectedItems: Item[]; - actionInProgress: string | null; - setActionInProgress: ( actionId: string | null ) => void; -} - -interface ToolbarContentProps< Item > { - selection: string[]; - actionsToShow: Action< Item >[]; - selectedItems: Item[]; - onChangeSelection: SetSelection; -} - -const SNACKBAR_VARIANTS = { - init: { - bottom: -48, - }, - open: { - bottom: 24, - transition: { - bottom: { type: 'tween', duration: 0.2, ease: [ 0, 0, 0.2, 1 ] }, - }, - }, - exit: { - opacity: 0, - bottom: 24, - transition: { - opacity: { type: 'tween', duration: 0.2, ease: [ 0, 0, 0.2, 1 ] }, - }, - }, -}; - -function ActionTrigger< Item >( { - action, - onClick, - isBusy, - items, -}: ActionTriggerProps< Item > ) { - const label = - typeof action.label === 'string' ? action.label : action.label( items ); - return ( - - ); -} - -const EMPTY_ARRAY: [] = []; - -function ActionButton< Item >( { - action, - selectedItems, - actionInProgress, - setActionInProgress, -}: ActionButtonProps< Item > ) { - const registry = useRegistry(); - const selectedEligibleItems = useMemo( () => { - return selectedItems.filter( ( item ) => { - return ! action.isEligible || action.isEligible( item ); - } ); - }, [ action, selectedItems ] ); - if ( 'RenderModal' in action ) { - return ( - - ); - } - return ( - { - setActionInProgress( action.id ); - action.callback( selectedItems, { - registry, - } ); - } } - items={ selectedEligibleItems } - isBusy={ actionInProgress === action.id } - /> - ); -} - -function renderToolbarContent< Item >( - selection: string[], - actionsToShow: Action< Item >[], - selectedItems: Item[], - actionInProgress: string | null, - setActionInProgress: ( actionId: string | null ) => void, - onChangeSelection: SetSelection -) { - return ( - <> - -
- { selection.length === 1 - ? __( '1 item selected' ) - : sprintf( - // translators: %s: Total number of selected items. - _n( - '%s item selected', - '%s items selected', - selection.length - ), - selection.length - ) } -
-
- - { actionsToShow.map( ( action ) => { - return ( - - ); - } ) } - - - { - onChangeSelection( EMPTY_ARRAY ); - } } - /> - - - ); -} - -function ToolbarContent< Item >( { - selection, - actionsToShow, - selectedItems, - onChangeSelection, -}: ToolbarContentProps< Item > ) { - const [ actionInProgress, setActionInProgress ] = useState< string | null >( - null - ); - const buttonsRef = useRef< JSX.Element | null >( null ); - if ( ! actionInProgress ) { - if ( buttonsRef.current ) { - buttonsRef.current = null; - } - return renderToolbarContent( - selection, - actionsToShow, - selectedItems, - actionInProgress, - setActionInProgress, - onChangeSelection - ); - } else if ( ! buttonsRef.current ) { - buttonsRef.current = renderToolbarContent( - selection, - actionsToShow, - selectedItems, - actionInProgress, - setActionInProgress, - onChangeSelection - ); - } - return buttonsRef.current; -} - -function _BulkActionsToolbar() { - const { - data, - selection, - actions = EMPTY_ARRAY, - onChangeSelection, - getItemId, - } = useContext( DataViewsContext ); - const isReducedMotion = useReducedMotion(); - const selectedItems = useMemo( () => { - return data.filter( ( item ) => - selection.includes( getItemId( item ) ) - ); - }, [ selection, data, getItemId ] ); - - const actionsToShow = useMemo( - () => - actions.filter( ( action ) => { - return ( - action.supportsBulk && - action.icon && - selectedItems.some( - ( item ) => - ! action.isEligible || action.isEligible( item ) - ) - ); - } ), - [ actions, selectedItems ] - ); - - if ( - ( selection && selection.length === 0 ) || - actionsToShow.length === 0 - ) { - return null; - } - - return ( - - - -
- -
-
-
-
- ); -} - -export default function BulkActionsToolbar() { - const { data, actions = [], view } = useContext( DataViewsContext ); - const hasPossibleBulkAction = useSomeItemHasAPossibleBulkAction( - actions, - data - ); - if ( - ! [ LAYOUT_TABLE, LAYOUT_GRID ].includes( view.type ) || - ! hasPossibleBulkAction - ) { - return null; - } - - return <_BulkActionsToolbar />; -} diff --git a/packages/dataviews/src/components/dataviews-bulk-actions-toolbar/style.scss b/packages/dataviews/src/components/dataviews-bulk-actions-toolbar/style.scss deleted file mode 100644 index 5672234d8cbbb7..00000000000000 --- a/packages/dataviews/src/components/dataviews-bulk-actions-toolbar/style.scss +++ /dev/null @@ -1,45 +0,0 @@ -.dataviews-bulk-actions-toolbar { - position: sticky; - display: flex; - flex-direction: column; - align-content: center; - flex-wrap: wrap; - width: fit-content; - margin-left: auto; - margin-right: auto; - bottom: $grid-unit-30; - z-index: z-index(".dataviews-bulk-actions-toolbar"); - - .components-accessible-toolbar { - border-color: $gray-300; - box-shadow: $elevation-x-small; - - .components-toolbar-group { - border-color: $gray-200; - - &:last-child { - border: 0; - } - } - } - - .dataviews-bulk-actions-toolbar__selection-count { - display: flex; - align-items: center; - margin: 0 $grid-unit-10 0 $grid-unit-10; - } -} - -.dataviews-bulk-actions-toolbar__wrapper { - display: flex; - flex-grow: 1; - width: 100%; - - .components-toolbar-group { - align-items: center; - } - - .components-button.is-busy { - max-height: $button-size; - } -} diff --git a/packages/dataviews/src/components/dataviews-bulk-actions/index.tsx b/packages/dataviews/src/components/dataviews-bulk-actions/index.tsx index 279126c597bc82..5eb9c5e1b6a4d0 100644 --- a/packages/dataviews/src/components/dataviews-bulk-actions/index.tsx +++ b/packages/dataviews/src/components/dataviews-bulk-actions/index.tsx @@ -2,42 +2,23 @@ * WordPress dependencies */ import { - privateApis as componentsPrivateApis, Button, - Modal, + CheckboxControl, + __experimentalHStack as HStack, } from '@wordpress/components'; import { __, sprintf, _n } from '@wordpress/i18n'; -import { useMemo, useState, useCallback, useContext } from '@wordpress/element'; +import { useMemo, useState, useRef, useContext } from '@wordpress/element'; import { useRegistry } from '@wordpress/data'; +import { closeSmall } from '@wordpress/icons'; /** * Internal dependencies */ import DataViewsContext from '../dataviews-context'; -import { LAYOUT_TABLE, LAYOUT_GRID } from '../../constants'; -import { unlock } from '../../lock-unlock'; -import type { Action, ActionModal } from '../../types'; - -const { DropdownMenuV2 } = unlock( componentsPrivateApis ); - -interface ActionWithModalProps< Item > { - action: ActionModal< Item >; - selectedItems: Item[]; - setActionWithModal: ( action?: ActionModal< Item > ) => void; - onMenuOpenChange: ( isOpen: boolean ) => void; -} - -interface BulkActionsItemProps< Item > { - action: Action< Item >; - selectedItems: Item[]; - setActionWithModal: ( action?: ActionModal< Item > ) => void; -} - -interface ActionsMenuGroupProps< Item > { - actions: Action< Item >[]; - selectedItems: Item[]; - setActionWithModal: ( action?: ActionModal< Item > ) => void; -} +import { ActionWithModal } from '../dataviews-item-actions'; +import type { Action } from '../../types'; +import type { SetSelection } from '../../private-types'; +import type { ActionTriggerProps } from '../dataviews-item-actions'; export function useHasAPossibleBulkAction< Item >( actions: Action< Item >[], @@ -69,126 +50,231 @@ export function useSomeItemHasAPossibleBulkAction< Item >( }, [ actions, data ] ); } -function ActionWithModal< Item >( { - action, - selectedItems, - setActionWithModal, - onMenuOpenChange, -}: ActionWithModalProps< Item > ) { - const eligibleItems = useMemo( () => { - return selectedItems.filter( - ( item ) => ! action.isEligible || action.isEligible( item ) - ); - }, [ action, selectedItems ] ); - const { RenderModal, hideModalHeader } = action; - const onCloseModal = useCallback( () => { - setActionWithModal( undefined ); - }, [ setActionWithModal ] ); +interface BulkSelectionCheckboxProps< Item > { + selection: string[]; + onChangeSelection: SetSelection; + data: Item[]; + actions: Action< Item >[]; + getItemId: ( item: Item ) => string; +} - if ( ! eligibleItems.length ) { - return null; - } +export function BulkSelectionCheckbox< Item >( { + selection, + onChangeSelection, + data, + actions, + getItemId, +}: BulkSelectionCheckboxProps< Item > ) { + const selectableItems = useMemo( () => { + return data.filter( ( item ) => { + return actions.some( + ( action ) => + action.supportsBulk && + ( ! action.isEligible || action.isEligible( item ) ) + ); + } ); + }, [ data, actions ] ); + const selectedItems = data.filter( + ( item ) => + selection.includes( getItemId( item ) ) && + selectableItems.includes( item ) + ); + const areAllSelected = selectedItems.length === selectableItems.length; + return ( + { + if ( areAllSelected ) { + onChangeSelection( [] ); + } else { + onChangeSelection( + selectableItems.map( ( item ) => getItemId( item ) ) + ); + } + } } + aria-label={ + areAllSelected ? __( 'Deselect all' ) : __( 'Select all' ) + } + /> + ); +} + +interface ActionButtonProps< Item > { + action: Action< Item >; + selectedItems: Item[]; + actionInProgress: string | null; + setActionInProgress: ( actionId: string | null ) => void; +} + +interface ToolbarContentProps< Item > { + selection: string[]; + onChangeSelection: SetSelection; + data: Item[]; + actions: Action< Item >[]; + getItemId: ( item: Item ) => string; +} +function ActionTrigger< Item >( { + action, + onClick, + isBusy, + items, +}: ActionTriggerProps< Item > ) { const label = - typeof action.label === 'string' - ? action.label - : action.label( selectedItems ); + typeof action.label === 'string' ? action.label : action.label( items ); return ( - - onMenuOpenChange( false ) } - /> - + - } - > - - - { - onChangeSelection( - selectableItems.map( ( item ) => - getItemId( item ) - ) - ); - } } - suffix={ numberSelectableItems } - > - { __( 'Select all' ) } - - { - onChangeSelection( [] ); - } } - > - { __( 'Deselect' ) } - - - - { actionWithModal && ( - - ) } - + const actionsToShow = useMemo( + () => + actions.filter( ( action ) => { + return ( + action.supportsBulk && + action.icon && + selectedItems.some( + ( item ) => + ! action.isEligible || action.isEligible( item ) + ) + ); + } ), + [ actions, selectedItems ] ); + if ( ! actionInProgress ) { + if ( footerContent.current ) { + footerContent.current = null; + } + return renderFooterContent( + data, + actions, + getItemId, + selection, + actionsToShow, + selectedItems, + actionInProgress, + setActionInProgress, + onChangeSelection + ); + } else if ( ! footerContent.current ) { + footerContent.current = renderFooterContent( + data, + actions, + getItemId, + selection, + actionsToShow, + selectedItems, + actionInProgress, + setActionInProgress, + onChangeSelection + ); + } + return footerContent.current; } -export default function BulkActions() { - const { data, actions = [], view } = useContext( DataViewsContext ); - const hasPossibleBulkAction = useSomeItemHasAPossibleBulkAction( - actions, - data +export function BulkActionsFooter() { + const { + data, + selection, + actions = EMPTY_ARRAY, + onChangeSelection, + getItemId, + } = useContext( DataViewsContext ); + return ( + ); - if ( - ! [ LAYOUT_TABLE, LAYOUT_GRID ].includes( view.type ) || - ! hasPossibleBulkAction - ) { - return null; - } - - return <_BulkActions />; } diff --git a/packages/dataviews/src/components/dataviews-bulk-actions/style.scss b/packages/dataviews/src/components/dataviews-bulk-actions/style.scss index 71f76ce9a6c16f..b2e946aa202abe 100644 --- a/packages/dataviews/src/components/dataviews-bulk-actions/style.scss +++ b/packages/dataviews/src/components/dataviews-bulk-actions/style.scss @@ -1,7 +1,12 @@ -.dataviews-bulk-actions__modal { - z-index: z-index(".dataviews-bulk-actions__modal"); + +.dataviews-bulk-actions-footer__item-count { + color: $gray-900; + font-weight: 500; + font-size: 11px; + text-transform: uppercase; } -.dataviews-bulk-actions__edit-button.components-button { - flex-shrink: 0; +.dataviews-bulk-actions-footer__container { + margin-right: auto; + min-height: $grid-unit-40; } diff --git a/packages/dataviews/src/components/dataviews-footer/index.tsx b/packages/dataviews/src/components/dataviews-footer/index.tsx new file mode 100644 index 00000000000000..191e16f47e2c96 --- /dev/null +++ b/packages/dataviews/src/components/dataviews-footer/index.tsx @@ -0,0 +1,50 @@ +/** + * WordPress dependencies + */ +import { __experimentalHStack as HStack } from '@wordpress/components'; +import { useContext } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import DataViewsContext from '../dataviews-context'; +import DataViewsPagination from '../dataviews-pagination'; +import { + BulkActionsFooter, + useSomeItemHasAPossibleBulkAction, +} from '../dataviews-bulk-actions'; +import { LAYOUT_GRID, LAYOUT_TABLE } from '../../constants'; + +const EMPTY_ARRAY: [] = []; + +export default function DataViewsFooter() { + const { + view, + paginationInfo: { totalItems = 0, totalPages }, + data, + actions = EMPTY_ARRAY, + } = useContext( DataViewsContext ); + const hasBulkActions = + useSomeItemHasAPossibleBulkAction( actions, data ) && + [ LAYOUT_TABLE, LAYOUT_GRID ].includes( view.type ); + + if ( + ! totalItems || + ! totalPages || + ( totalPages <= 1 && ! hasBulkActions ) + ) { + return null; + } + return ( + !! totalItems && ( + + { hasBulkActions && } + + + ) + ); +} diff --git a/packages/dataviews/src/components/dataviews-footer/style.scss b/packages/dataviews/src/components/dataviews-footer/style.scss new file mode 100644 index 00000000000000..cdb1359ccee393 --- /dev/null +++ b/packages/dataviews/src/components/dataviews-footer/style.scss @@ -0,0 +1,40 @@ +.dataviews-footer { + position: sticky; + bottom: 0; + left: 0; + background-color: $white; + padding: $grid-unit-15 $grid-unit-60; + border-top: $border-width solid $gray-100; + flex-shrink: 0; + transition: padding ease-out 0.1s; + @include reduce-motion("transition"); + z-index: z-index(".dataviews-footer"); +} + + +/* stylelint-disable-next-line scss/at-rule-no-unknown -- '@container' not globally permitted */ +@container (max-width: 430px) { + .dataviews-footer { + padding: $grid-unit-15 $grid-unit-30; + } +} + +/* stylelint-disable-next-line scss/at-rule-no-unknown -- '@container' not globally permitted */ +@container (max-width: 560px) { + .dataviews-footer { + flex-direction: column !important; + + .dataviews-bulk-actions-footer__container { + width: 100%; + } + + .dataviews-bulk-actions-footer__item-count { + flex-grow: 1; + } + + .dataviews-pagination { + width: 100%; + justify-content: space-between; + } + } +} diff --git a/packages/dataviews/src/components/dataviews-pagination/index.tsx b/packages/dataviews/src/components/dataviews-pagination/index.tsx index f022b382cdb70d..d2744b0c39bc0b 100644 --- a/packages/dataviews/src/components/dataviews-pagination/index.tsx +++ b/packages/dataviews/src/components/dataviews-pagination/index.tsx @@ -51,9 +51,9 @@ function DataViewsPagination() { totalPages !== 1 && ( ( { expanded={ false } style={ { flexShrink: 0 } } > - ( { { isShowingFilter && } - - + ); diff --git a/packages/dataviews/src/dataviews-layouts/table/index.tsx b/packages/dataviews/src/dataviews-layouts/table/index.tsx index a4adde7fb382f3..b12082a55623b2 100644 --- a/packages/dataviews/src/dataviews-layouts/table/index.tsx +++ b/packages/dataviews/src/dataviews-layouts/table/index.tsx @@ -8,18 +8,11 @@ import clsx from 'clsx'; */ import { __ } from '@wordpress/i18n'; import { - CheckboxControl, Spinner, __experimentalHStack as HStack, __experimentalVStack as VStack, } from '@wordpress/components'; -import { - useEffect, - useId, - useRef, - useState, - useMemo, -} from '@wordpress/element'; +import { useEffect, useId, useRef, useState } from '@wordpress/element'; /** * Internal dependencies @@ -30,6 +23,7 @@ import { sortValues } from '../../constants'; import { useSomeItemHasAPossibleBulkAction, useHasAPossibleBulkAction, + BulkSelectionCheckbox, } from '../../components/dataviews-bulk-actions'; import type { Action, @@ -41,14 +35,6 @@ import type { import type { SetSelection } from '../../private-types'; import ColumnHeaderMenu from './column-header-menu'; -interface BulkSelectionCheckboxProps< Item > { - selection: string[]; - onChangeSelection: SetSelection; - data: Item[]; - actions: Action< Item >[]; - getItemId: ( item: Item ) => string; -} - interface TableColumnFieldProps< Item > { primaryField?: NormalizedField< Item >; field: NormalizedField< Item >; @@ -84,50 +70,6 @@ interface TableRowProps< Item > { onChangeSelection: SetSelection; } -function BulkSelectionCheckbox< Item >( { - selection, - onChangeSelection, - data, - actions, - getItemId, -}: BulkSelectionCheckboxProps< Item > ) { - const selectableItems = useMemo( () => { - return data.filter( ( item ) => { - return actions.some( - ( action ) => - action.supportsBulk && - ( ! action.isEligible || action.isEligible( item ) ) - ); - } ); - }, [ data, actions ] ); - const selectedItems = data.filter( - ( item ) => - selection.includes( getItemId( item ) ) && - selectableItems.includes( item ) - ); - const areAllSelected = selectedItems.length === selectableItems.length; - return ( - { - if ( areAllSelected ) { - onChangeSelection( [] ); - } else { - onChangeSelection( - selectableItems.map( ( item ) => getItemId( item ) ) - ); - } - } } - aria-label={ - areAllSelected ? __( 'Deselect all' ) : __( 'Select all' ) - } - /> - ); -} - function TableColumn< Item >( { column, fields, diff --git a/packages/dataviews/src/style.scss b/packages/dataviews/src/style.scss index 7be92273663a87..087e812fffa192 100644 --- a/packages/dataviews/src/style.scss +++ b/packages/dataviews/src/style.scss @@ -1,7 +1,7 @@ @import "./components/dataviews/style.scss"; @import "./components/dataviews-bulk-actions/style.scss"; -@import "./components/dataviews-bulk-actions-toolbar/style.scss"; @import "./components/dataviews-filters/style.scss"; +@import "./components/dataviews-footer/style.scss"; @import "./components/dataviews-pagination/style.scss"; @import "./components/dataviews-item-actions/style.scss"; @import "./components/dataviews-selection-checkbox/style.scss"; diff --git a/packages/edit-site/src/components/page-patterns/style.scss b/packages/edit-site/src/components/page-patterns/style.scss index 34b258e3a92041..a5aa1eb9ac796e 100644 --- a/packages/edit-site/src/components/page-patterns/style.scss +++ b/packages/edit-site/src/components/page-patterns/style.scss @@ -105,10 +105,6 @@ } .edit-site-page-patterns-dataviews { - .dataviews-pagination { - z-index: z-index(".edit-site-patterns__dataviews-list-pagination"); - } - .dataviews-view-grid__badge-fields { .dataviews-view-grid__field-value:has(.edit-site-patterns__field-sync-status-fully) { background: rgba(var(--wp-block-synced-color--rgb), 0.04); diff --git a/packages/editor/src/dataviews/actions/export-pattern.tsx b/packages/editor/src/dataviews/actions/export-pattern.tsx index f4e5c91c7cabfa..b6be83eeda84b4 100644 --- a/packages/editor/src/dataviews/actions/export-pattern.tsx +++ b/packages/editor/src/dataviews/actions/export-pattern.tsx @@ -9,6 +9,7 @@ import { downloadZip } from 'client-zip'; */ import { downloadBlob } from '@wordpress/blob'; import { __ } from '@wordpress/i18n'; +import { download } from '@wordpress/icons'; import type { Action } from '@wordpress/dataviews'; /** @@ -36,6 +37,7 @@ function getJsonFromItem( item: Pattern ) { const exportPattern: Action< Pattern > = { id: 'export-pattern', label: __( 'Export as JSON' ), + icon: download, supportsBulk: true, isEligible: ( item ) => item.type === 'wp_block', callback: async ( items ) => { diff --git a/packages/editor/src/dataviews/actions/permanently-delete-post.tsx b/packages/editor/src/dataviews/actions/permanently-delete-post.tsx index 2124fdc0ffa4ce..afbb84ae12c74c 100644 --- a/packages/editor/src/dataviews/actions/permanently-delete-post.tsx +++ b/packages/editor/src/dataviews/actions/permanently-delete-post.tsx @@ -5,6 +5,7 @@ import { store as coreStore } from '@wordpress/core-data'; import { __, sprintf } from '@wordpress/i18n'; import { store as noticesStore } from '@wordpress/notices'; import type { Action } from '@wordpress/dataviews'; +import { trash } from '@wordpress/icons'; /** * Internal dependencies @@ -16,6 +17,7 @@ const permanentlyDeletePost: Action< PostWithPermissions > = { id: 'permanently-delete', label: __( 'Permanently delete' ), supportsBulk: true, + icon: trash, isEligible( item ) { if ( isTemplateOrTemplatePart( item ) || item.type === 'wp_block' ) { return false;