diff --git a/docs/reference-guides/data/data-core-block-editor.md b/docs/reference-guides/data/data-core-block-editor.md index 437f7be20f770..44059145be076 100644 --- a/docs/reference-guides/data/data-core-block-editor.md +++ b/docs/reference-guides/data/data-core-block-editor.md @@ -1227,6 +1227,18 @@ _Returns_ - `?boolean`: Whether the template is valid or not. +### showZoomOutModeInserter + +Returns whether the zoom out mode inserter is enabled or not. + +_Parameters_ + +- _state_ `Object`: Global application state. + +_Returns_ + +- `boolean`: Whether the drop pattern is enabled or not. + ### wasBlockJustInserted Tells if the block with the passed clientId was just inserted. @@ -1721,6 +1733,18 @@ _Parameters_ - _isNavigationMode_ `boolean`: Enable/Disable navigation mode. +### setShowZoomOutModeInserter + +Action that shows the zoom out mode inserter. + +_Parameters_ + +- _showZoomOutModeInserter_ `boolean`: show the zoom out mode inserter. + +_Returns_ + +- `Object`: Action object. + ### setTemplateValidity Action that resets the template validity. diff --git a/packages/block-editor/src/components/block-list/zoom-out-separator.js b/packages/block-editor/src/components/block-list/zoom-out-separator.js index f2e6d050141fb..d6c8e13c4f8ea 100644 --- a/packages/block-editor/src/components/block-list/zoom-out-separator.js +++ b/packages/block-editor/src/components/block-list/zoom-out-separator.js @@ -11,8 +11,8 @@ import { __unstableAnimatePresence as AnimatePresence, } from '@wordpress/components'; import { useReducedMotion } from '@wordpress/compose'; -import { useSelect } from '@wordpress/data'; -import { useState } from '@wordpress/element'; +import { useDispatch, useSelect } from '@wordpress/data'; +import { useState, useEffect } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; /** @@ -21,6 +21,80 @@ import { __ } from '@wordpress/i18n'; import { store as blockEditorStore } from '../../store'; import { unlock } from '../../lock-unlock'; +const useRenderDropZone = ( { + position, + insertionPoint, + blockInsertionPointVisible, + blockInsertionPoint, + clientId, + sectionClientIds, + selectedBlockIds, +} ) => { + const [ isVisible, setIsVisible ] = useState( false ); + const { setShowZoomOutModeInserter } = useDispatch( blockEditorStore ); + + useEffect( () => { + const hasTopInsertionPoint = + insertionPoint?.index === 0 && + clientId === sectionClientIds[ insertionPoint.index ]; + const hasBottomInsertionPoint = + insertionPoint && + insertionPoint.hasOwnProperty( 'index' ) && + clientId === sectionClientIds[ insertionPoint.index - 1 ]; + + let visibility = false; + let selectedBlockId = null; + + if ( position === 'top' ) { + visibility = + hasTopInsertionPoint || + ( blockInsertionPointVisible && + blockInsertionPoint.index === 0 && + clientId === + sectionClientIds[ blockInsertionPoint.index ] ); + selectedBlockId = + sectionClientIds[ + hasTopInsertionPoint + ? insertionPoint.index + : blockInsertionPoint.index + ]; + } + + if ( position === 'bottom' ) { + visibility = + hasBottomInsertionPoint || + ( blockInsertionPointVisible && + clientId === + sectionClientIds[ blockInsertionPoint.index - 1 ] ); + selectedBlockId = + sectionClientIds[ + hasBottomInsertionPoint + ? insertionPoint.index - 1 + : blockInsertionPoint.index - 1 + ]; + } + + if ( visibility ) { + setShowZoomOutModeInserter( + ! selectedBlockIds.includes( selectedBlockId ) + ); + } + + setIsVisible( visibility ); + }, [ + position, + insertionPoint, + blockInsertionPointVisible, + blockInsertionPoint, + clientId, + sectionClientIds, + selectedBlockIds, + setShowZoomOutModeInserter, + ] ); + + return isVisible; +}; + export function ZoomOutSeparator( { clientId, rootClientId = '', @@ -33,11 +107,13 @@ export function ZoomOutSeparator( { insertionPoint, blockInsertionPointVisible, blockInsertionPoint, + selectedBlockIds, } = useSelect( ( select ) => { const { getInsertionPoint, getBlockOrder, getSectionRootClientId, + getSelectedBlockClientIds, isBlockInsertionPointVisible, getBlockInsertionPoint, } = unlock( select( blockEditorStore ) ); @@ -51,50 +127,33 @@ export function ZoomOutSeparator( { insertionPoint: getInsertionPoint(), blockInsertionPoint: getBlockInsertionPoint(), blockInsertionPointVisible: isBlockInsertionPointVisible(), + selectedBlockIds: getSelectedBlockClientIds(), }; }, [] ); - const isReducedMotion = useReducedMotion(); - - if ( ! clientId ) { - return; - } - - let isVisible = false; + const isVisible = useRenderDropZone( { + position, + insertionPoint, + blockInsertionPointVisible, + blockInsertionPoint, + clientId, + sectionClientIds, + selectedBlockIds, + } ); const isSectionBlock = rootClientId === sectionRootClientId && sectionClientIds && sectionClientIds.includes( clientId ); - if ( ! isSectionBlock ) { - return null; - } + const isReducedMotion = useReducedMotion(); - const hasTopInsertionPoint = - insertionPoint?.index === 0 && - clientId === sectionClientIds[ insertionPoint.index ]; - const hasBottomInsertionPoint = - insertionPoint && - insertionPoint.hasOwnProperty( 'index' ) && - clientId === sectionClientIds[ insertionPoint.index - 1 ]; - // We want to show the zoom out separator in either of these conditions: - // 1. If the inserter has an insertion index set - // 2. We are dragging a pattern over an insertion point - if ( position === 'top' ) { - isVisible = - hasTopInsertionPoint || - ( blockInsertionPointVisible && - blockInsertionPoint.index === 0 && - clientId === sectionClientIds[ blockInsertionPoint.index ] ); + if ( ! clientId ) { + return; } - if ( position === 'bottom' ) { - isVisible = - hasBottomInsertionPoint || - ( blockInsertionPointVisible && - clientId === - sectionClientIds[ blockInsertionPoint.index - 1 ] ); + if ( ! isSectionBlock ) { + return null; } return ( diff --git a/packages/block-editor/src/components/block-tools/index.js b/packages/block-editor/src/components/block-tools/index.js index 0d8a15fa00bf9..863aa6f8d1573 100644 --- a/packages/block-editor/src/components/block-tools/index.js +++ b/packages/block-editor/src/components/block-tools/index.js @@ -33,6 +33,7 @@ function selector( select ) { isTyping, isDragging, isZoomOut, + showZoomOutModeInserter, } = unlock( select( blockEditorStore ) ); const clientId = @@ -44,7 +45,7 @@ function selector( select ) { isTyping: isTyping(), isZoomOutMode: isZoomOut(), isDragging: isDragging(), - isInserterOpened: getSettings().__experimentalIsInserterOpened, + showZoomOutModeInserter: showZoomOutModeInserter(), }; } @@ -68,7 +69,7 @@ export default function BlockTools( { isTyping, isZoomOutMode, isDragging, - isInserterOpened, + showZoomOutModeInserter, } = useSelect( selector, [] ); const isMatch = useShortcutEventMatch(); @@ -200,6 +201,7 @@ export default function BlockTools( { } } } + const blockToolbarRef = usePopoverScroll( __unstableContentRef ); const blockToolbarAfterRef = usePopoverScroll( __unstableContentRef ); @@ -241,7 +243,7 @@ export default function BlockTools( { name="__unstable-block-tools-after" ref={ blockToolbarAfterRef } /> - { isZoomOutMode && ! isDragging && ! isInserterOpened && ( + { isZoomOutMode && ! isDragging && showZoomOutModeInserter && ( diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index 6edc5cb4da039..5147dfc3c0ad5 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -656,6 +656,20 @@ export function setTemplateValidity( isValid ) { }; } +/** + * Action that shows the zoom out mode inserter. + * + * @param {boolean} showZoomOutModeInserter show the zoom out mode inserter. + * + * @return {Object} Action object. + */ +export function setShowZoomOutModeInserter( showZoomOutModeInserter ) { + return { + type: 'SET_ZOOM_OUT_MODE_INSERTER', + showZoomOutModeInserter, + }; +} + /** * Action that synchronizes the template with the list of blocks. * diff --git a/packages/block-editor/src/store/defaults.js b/packages/block-editor/src/store/defaults.js index 8314ad872468b..afde286ef3b60 100644 --- a/packages/block-editor/src/store/defaults.js +++ b/packages/block-editor/src/store/defaults.js @@ -170,6 +170,8 @@ export const SETTINGS_DEFAULTS = { isPreviewMode: false, + showZoomOutModeInserter: true, + // These settings will be completely revamped in the future. // The goal is to evolve this into an API which will instruct // the block inspector to animate transitions between what it diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index edae9c392c37d..b3a871e819f18 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -1659,6 +1659,29 @@ export function template( state = { isValid: true }, action ) { return state; } +/** + * Reducer returning whether the zoom out mode inserter should be shown or not. + * + * @param {Object} state Current state. + * @param {Object} action Dispatched action. + * + * @return {Object} Updated state. + */ +export function zoomOutModeInserter( + state = { showZoomOutModeInserter: true }, + action +) { + switch ( action.type ) { + case 'SET_ZOOM_OUT_MODE_INSERTER': + return { + ...state, + showZoomOutModeInserter: action.showZoomOutModeInserter, + }; + } + + return state; +} + /** * Reducer returning the editor setting. * @@ -2119,6 +2142,7 @@ const combinedReducers = combineReducers( { insertionPoint, insertionCue, template, + zoomOutModeInserter, settings, preferences, lastBlockAttributesChange, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index dc90f35173252..5def9ff8b499c 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -1537,6 +1537,17 @@ export function isBlockInsertionPointVisible( state ) { return state.insertionCue !== null; } +/** + * Returns whether the zoom out mode inserter is enabled or not. + * + * @param {Object} state Global application state. + * + * @return {boolean} Whether the drop pattern is enabled or not. + */ +export function showZoomOutModeInserter( state ) { + return state.zoomOutModeInserter.showZoomOutModeInserter; +} + /** * Returns whether the blocks matches the template or not. * diff --git a/packages/editor/src/components/provider/use-block-editor-settings.js b/packages/editor/src/components/provider/use-block-editor-settings.js index c4c23d16836b4..f5c45f431e2c8 100644 --- a/packages/editor/src/components/provider/use-block-editor-settings.js +++ b/packages/editor/src/components/provider/use-block-editor-settings.js @@ -274,11 +274,6 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) { const forceDisableFocusMode = settings.focusMode === false; - const isInserterOpened = useSelect( - ( select ) => select( editorStore ).isInserterOpened(), - [] - ); - return useMemo( () => { const blockEditorSettings = { ...Object.fromEntries( @@ -331,7 +326,6 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) { postType === 'wp_navigation' ? [ [ 'core/navigation', {}, [] ] ] : settings.template, - __experimentalIsInserterOpened: isInserterOpened, __experimentalSetIsInserterOpened: setIsInserterOpened, [ sectionRootClientIdKey ]: sectionRootClientId, editorTool: @@ -366,7 +360,6 @@ function useBlockEditorSettings( settings, postType, postId, renderingMode ) { globalStylesData, globalStylesLinksData, renderingMode, - isInserterOpened, ] ); }