From 8ec69c642221418bff79f17fc39cff318ace6349 Mon Sep 17 00:00:00 2001 From: Maggie Cabrera Date: Wed, 24 Jul 2024 11:38:15 +0100 Subject: [PATCH 01/16] create a function to check when we can add the separators Attempt to define sectionClientIds Pass sectionClientIds to isSectionBlock Rename sectionClientIds to sectionRootClientIds check if it's zoom out mode, add some CSS to the separator expand separators when the insertion point is changed fix animation only open the first separator if the insertion point index is 0 conditionally render the separators and animate them using framer instead of on class change remove unused code refactor separators do displacement on drag --- .../src/components/block-list/content.scss | 12 +++ .../src/components/block-list/index.js | 97 +++++++++++------- .../block-list/zoom-out-separator.js | 98 +++++++++++++++++++ .../block-tools/zoom-out-mode-inserters.js | 12 --- 4 files changed, 169 insertions(+), 50 deletions(-) create mode 100644 packages/block-editor/src/components/block-list/zoom-out-separator.js diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss index 95bb610da9967c..cc71b3f32b4515 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -453,3 +453,15 @@ _::-webkit-full-page-media, _:future, :root .has-multi-selection .block-editor-b margin-bottom: auto; } } + +.block-editor-block-list__zoom-out-separator { + /* same color as the iframe's background */ + background: $gray-300; +} + +// In Post Editor allow the separator to occupy the full width by ignoring (cancelling out) the global padding. +.has-global-padding > .block-editor-block-list__zoom-out-separator, +.block-editor-block-list__layout.is-root-container.has-global-padding > .block-editor-block-list__zoom-out-separator { + max-width: none; + margin: 0 calc(-1 * var(--wp--style--root--padding-right)) 0 calc(-1 * var(--wp--style--root--padding-left)) !important; +} diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 37dba80511d920..ea6128f1534642 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -39,6 +39,7 @@ import { DEFAULT_BLOCK_EDIT_CONTEXT, } from '../block-edit/context'; import { useTypingObserver } from '../observe-typing'; +import { ZoomOutSeparator } from './zoom-out-separator'; import { unlock } from '../../lock-unlock'; export const IntersectionObserver = createContext(); @@ -174,49 +175,55 @@ function Items( { // function on every render. const hasAppender = CustomAppender !== false; const hasCustomAppender = !! CustomAppender; - const { order, selectedBlocks, visibleBlocks, shouldRenderAppender } = - useSelect( - ( select ) => { - const { - getSettings, - getBlockOrder, - getSelectedBlockClientId, - getSelectedBlockClientIds, - __unstableGetVisibleBlocks, - getTemplateLock, - getBlockEditingMode, - __unstableGetEditorMode, - } = select( blockEditorStore ); - - const _order = getBlockOrder( rootClientId ); + const { + order, + isZoomOut, + selectedBlocks, + visibleBlocks, + shouldRenderAppender, + } = useSelect( + ( select ) => { + const { + getSettings, + getBlockOrder, + getSelectedBlockClientId, + getSelectedBlockClientIds, + __unstableGetVisibleBlocks, + getTemplateLock, + getBlockEditingMode, + __unstableGetEditorMode, + } = select( blockEditorStore ); - if ( getSettings().__unstableIsPreviewMode ) { - return { - order: _order, - selectedBlocks: EMPTY_ARRAY, - visibleBlocks: EMPTY_SET, - }; - } + const _order = getBlockOrder( rootClientId ); - const selectedBlockClientId = getSelectedBlockClientId(); + if ( getSettings().__unstableIsPreviewMode ) { return { order: _order, - selectedBlocks: getSelectedBlockClientIds(), - visibleBlocks: __unstableGetVisibleBlocks(), - shouldRenderAppender: - hasAppender && - __unstableGetEditorMode() !== 'zoom-out' && - ( hasCustomAppender - ? ! getTemplateLock( rootClientId ) && - getBlockEditingMode( rootClientId ) !== 'disabled' - : rootClientId === selectedBlockClientId || - ( ! rootClientId && - ! selectedBlockClientId && - ! _order.length ) ), + selectedBlocks: EMPTY_ARRAY, + visibleBlocks: EMPTY_SET, }; - }, - [ rootClientId, hasAppender, hasCustomAppender ] - ); + } + + const selectedBlockClientId = getSelectedBlockClientId(); + return { + order: _order, + selectedBlocks: getSelectedBlockClientIds(), + visibleBlocks: __unstableGetVisibleBlocks(), + isZoomOut: __unstableGetEditorMode() === 'zoom-out', + shouldRenderAppender: + hasAppender && + __unstableGetEditorMode() !== 'zoom-out' && + ( hasCustomAppender + ? ! getTemplateLock( rootClientId ) && + getBlockEditingMode( rootClientId ) !== 'disabled' + : rootClientId === selectedBlockClientId || + ( ! rootClientId && + ! selectedBlockClientId && + ! _order.length ) ), + }; + }, + [ rootClientId, hasAppender, hasCustomAppender ] + ); return ( @@ -230,10 +237,24 @@ function Items( { ! selectedBlocks.includes( clientId ) } > + { isZoomOut && ( + + ) } + { isZoomOut && ( + + ) } ) ) } { order.length < 1 && placeholder } 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 new file mode 100644 index 00000000000000..e9e3f7a29d9a21 --- /dev/null +++ b/packages/block-editor/src/components/block-list/zoom-out-separator.js @@ -0,0 +1,98 @@ +/** + * WordPress dependencies + */ +import { + __unstableMotion as motion, + __unstableAnimatePresence as AnimatePresence, +} from '@wordpress/components'; +import { useReducedMotion } from '@wordpress/compose'; +import { useSelect } from '@wordpress/data'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; +import { unlock } from '../../lock-unlock'; + +export function ZoomOutSeparator( { + clientId, + rootClientId, + position = 'top', +} ) { + const { + sectionRootClientId, + sectionClientIds, + blockInsertionPoint, + blockInsertionPointVisible, + } = useSelect( ( select ) => { + const { + getSettings, + getBlockInsertionPoint, + getBlockOrder, + isBlockInsertionPointVisible, + } = unlock( select( blockEditorStore ) ); + + const { sectionRootClientId: root } = unlock( getSettings() ); + const sectionRootClientIds = getBlockOrder( root ); + return { + sectionRootClientId: root, + sectionClientIds: sectionRootClientIds, + blockOrder: getBlockOrder( root ), + blockInsertionPoint: getBlockInsertionPoint(), + blockInsertionPointVisible: isBlockInsertionPointVisible(), + }; + }, [] ); + + const isReducedMotion = useReducedMotion(); + if ( ! clientId ) { + return; + } + + let isSectionBlock = false; + let isVisible = false; + + if ( + ( sectionRootClientId && + sectionClientIds && + sectionClientIds.includes( clientId ) ) || + ( clientId && ! rootClientId ) + ) { + isSectionBlock = true; + } + + if ( ! isSectionBlock ) { + return null; + } + + if ( position === 'top' ) { + isVisible = + blockInsertionPointVisible && + blockInsertionPoint.index === 0 && + clientId === sectionClientIds[ blockInsertionPoint.index ]; + } + + if ( position === 'bottom' ) { + isVisible = + blockInsertionPointVisible && + clientId === sectionClientIds[ blockInsertionPoint.index - 1 ]; + } + + return ( + + { isVisible && ( + + ) } + + ); +} diff --git a/packages/block-editor/src/components/block-tools/zoom-out-mode-inserters.js b/packages/block-editor/src/components/block-tools/zoom-out-mode-inserters.js index 30d51654b77cf4..79f8be3f9cfe97 100644 --- a/packages/block-editor/src/components/block-tools/zoom-out-mode-inserters.js +++ b/packages/block-editor/src/components/block-tools/zoom-out-mode-inserters.js @@ -88,18 +88,6 @@ function ZoomOutModeInserters() { previousClientId={ previousClientId } nextClientId={ nextClientId } > - { shouldRenderInsertionPoint && ( -
- ) } { ! shouldRenderInsertionPoint && ( Date: Wed, 21 Aug 2024 11:09:07 +0100 Subject: [PATCH 02/16] =?UTF-8?q?Don=E2=80=99t=20show=20seperator=20if=20o?= =?UTF-8?q?pertation=20is=20not=20insert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/block-list/zoom-out-separator.js | 6 ++++++ 1 file changed, 6 insertions(+) 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 e9e3f7a29d9a21..d7896e5da8d571 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 @@ -44,6 +44,7 @@ export function ZoomOutSeparator( { }, [] ); const isReducedMotion = useReducedMotion(); + if ( ! clientId ) { return; } @@ -64,6 +65,11 @@ export function ZoomOutSeparator( { return null; } + // Only allow insertion and not grouping in Zoom Out mode. + if ( blockInsertionPoint?.operation !== 'insert' ) { + return null; + } + if ( position === 'top' ) { isVisible = blockInsertionPointVisible && From 63586dbd2db7f9752cc7897f51159b7e52371fed Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 21 Aug 2024 11:53:26 +0100 Subject: [PATCH 03/16] Fix bug where rootClientId was not within sectionRoot --- .../block-list/zoom-out-separator.js | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) 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 d7896e5da8d571..863ce30ca4d3b0 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 @@ -16,7 +16,7 @@ import { unlock } from '../../lock-unlock'; export function ZoomOutSeparator( { clientId, - rootClientId, + rootClientId = '', position = 'top', } ) { const { @@ -49,27 +49,17 @@ export function ZoomOutSeparator( { return; } - let isSectionBlock = false; let isVisible = false; - if ( - ( sectionRootClientId && - sectionClientIds && - sectionClientIds.includes( clientId ) ) || - ( clientId && ! rootClientId ) - ) { - isSectionBlock = true; - } + const isSectionBlock = + rootClientId === sectionRootClientId && + sectionClientIds && + sectionClientIds.includes( clientId ); if ( ! isSectionBlock ) { return null; } - // Only allow insertion and not grouping in Zoom Out mode. - if ( blockInsertionPoint?.operation !== 'insert' ) { - return null; - } - if ( position === 'top' ) { isVisible = blockInsertionPointVisible && From 69fd429a5537b8810fcc75f3f73d7676829c7d45 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 21 Aug 2024 13:52:40 +0100 Subject: [PATCH 04/16] Ignore Group operations on drag in Zoom Out mode --- .../block-editor/src/components/use-block-drop-zone/index.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/block-editor/src/components/use-block-drop-zone/index.js b/packages/block-editor/src/components/use-block-drop-zone/index.js index 5af82915233703..3dedafd24ad064 100644 --- a/packages/block-editor/src/components/use-block-drop-zone/index.js +++ b/packages/block-editor/src/components/use-block-drop-zone/index.js @@ -422,6 +422,10 @@ export default function useBlockDropZone( { const [ targetIndex, operation, nearestSide ] = dropTargetPosition; + if ( isZoomOutMode() && operation !== 'insert' ) { + return; + } + if ( operation === 'group' ) { const targetBlock = blocks[ targetIndex ]; const areAllImages = [ From 229c2ae8244beb47afb6d8eb0a7ef3cd78eed343 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 22 Aug 2024 11:34:26 +0100 Subject: [PATCH 05/16] Check for ZoomOut separators when firing onDragEnd --- .../compose/src/hooks/use-drop-zone/index.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/compose/src/hooks/use-drop-zone/index.js b/packages/compose/src/hooks/use-drop-zone/index.js index b537f0a5ab6227..4a75894c7035ad 100644 --- a/packages/compose/src/hooks/use-drop-zone/index.js +++ b/packages/compose/src/hooks/use-drop-zone/index.js @@ -30,6 +30,18 @@ function useFreshRef( value ) { return ref; } +/** + * Checks if the given element is a zoom out separator. + * + * @param {EventTarget} maybeZoomOutSeparator - The element to check. + * @return {boolean} True if the element is a zoom out separator, false otherwise. + */ +const isZoomOutSeparator = ( maybeZoomOutSeparator ) => + maybeZoomOutSeparator && + maybeZoomOutSeparator?.classList.contains( + 'block-editor-block-list__zoom-out-separator' + ); + /** * A hook to facilitate drag and drop handling. * @@ -165,10 +177,20 @@ export default function useDropZone( { // zone. // Note: This is not entirely reliable in Safari due to this bug // https://bugs.webkit.org/show_bug.cgi?id=66547 + if ( isElementInZone( event.relatedTarget ) ) { return; } + // If we're moving in/out of a ZoomOutSeparator, don't trigger + // the onDragLeave event. + if ( + isZoomOutSeparator( event.relatedTarget ) || + isZoomOutSeparator( event.target ) + ) { + return; + } + if ( onDragLeaveRef.current ) { onDragLeaveRef.current( event ); } From 2be4551faa7087e4e0f2ea6b5a230559ef02728d Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 22 Aug 2024 13:48:45 +0100 Subject: [PATCH 06/16] Refine function to detect zoom out separator --- .../compose/src/hooks/use-drop-zone/index.js | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/compose/src/hooks/use-drop-zone/index.js b/packages/compose/src/hooks/use-drop-zone/index.js index 4a75894c7035ad..eb81816477a137 100644 --- a/packages/compose/src/hooks/use-drop-zone/index.js +++ b/packages/compose/src/hooks/use-drop-zone/index.js @@ -30,18 +30,6 @@ function useFreshRef( value ) { return ref; } -/** - * Checks if the given element is a zoom out separator. - * - * @param {EventTarget} maybeZoomOutSeparator - The element to check. - * @return {boolean} True if the element is a zoom out separator, false otherwise. - */ -const isZoomOutSeparator = ( maybeZoomOutSeparator ) => - maybeZoomOutSeparator && - maybeZoomOutSeparator?.classList.contains( - 'block-editor-block-list__zoom-out-separator' - ); - /** * A hook to facilitate drag and drop handling. * @@ -119,6 +107,24 @@ export default function useDropZone( { return false; } + /** + * Checks if the given element is a zoom out separator. + * + * @param {EventTarget|null} maybeZoomOutSeparator - The element to check. + * @return {boolean} True if the element is a zoom out separator, false otherwise. + */ + function isZoomOutSeparator( maybeZoomOutSeparator ) { + const { defaultView } = ownerDocument; + + return !! ( + defaultView && + maybeZoomOutSeparator instanceof defaultView.HTMLElement && + maybeZoomOutSeparator.classList.contains( + 'block-editor-block-list__zoom-out-separator' + ) + ); + } + function maybeDragStart( /** @type {DragEvent} */ event ) { if ( isDragging ) { return; @@ -183,7 +189,9 @@ export default function useDropZone( { } // If we're moving in/out of a ZoomOutSeparator, don't trigger - // the onDragLeave event. + // the onDragLeave event. This is to prevent the dropzone from + // being hidden when the user is dragging a block in/over/around + // a block and the separator. if ( isZoomOutSeparator( event.relatedTarget ) || isZoomOutSeparator( event.target ) From 692e511d869a8e69948aa64217f678c5f78b58f2 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 22 Aug 2024 13:52:13 +0100 Subject: [PATCH 07/16] Update detection based on data attribute --- .../src/components/block-list/zoom-out-separator.js | 1 + packages/compose/src/hooks/use-drop-zone/index.js | 10 ++++------ 2 files changed, 5 insertions(+), 6 deletions(-) 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 863ce30ca4d3b0..9e2c5b5ce53ca1 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 @@ -87,6 +87,7 @@ export function ZoomOutSeparator( { ease: [ 0.6, 0, 0.4, 1 ], } } className="block-editor-block-list__zoom-out-separator" + data-is-zoom-out-separator="true" > ) } diff --git a/packages/compose/src/hooks/use-drop-zone/index.js b/packages/compose/src/hooks/use-drop-zone/index.js index eb81816477a137..acbfc176cb229e 100644 --- a/packages/compose/src/hooks/use-drop-zone/index.js +++ b/packages/compose/src/hooks/use-drop-zone/index.js @@ -110,18 +110,16 @@ export default function useDropZone( { /** * Checks if the given element is a zoom out separator. * - * @param {EventTarget|null} maybeZoomOutSeparator - The element to check. + * @param {EventTarget|null} targetToCheck - The element to check. * @return {boolean} True if the element is a zoom out separator, false otherwise. */ - function isZoomOutSeparator( maybeZoomOutSeparator ) { + function isZoomOutSeparator( targetToCheck ) { const { defaultView } = ownerDocument; return !! ( defaultView && - maybeZoomOutSeparator instanceof defaultView.HTMLElement && - maybeZoomOutSeparator.classList.contains( - 'block-editor-block-list__zoom-out-separator' - ) + targetToCheck instanceof defaultView.HTMLElement && + targetToCheck.dataset.isZoomOutSeparator ); } From 6ed65629ac252a5c75d9c857ab48bad7fbd85436 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 22 Aug 2024 14:10:46 +0100 Subject: [PATCH 08/16] Make generic --- .../components/block-list/zoom-out-separator.js | 2 +- .../compose/src/hooks/use-drop-zone/index.js | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) 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 9e2c5b5ce53ca1..8accfce573ddd8 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 @@ -87,7 +87,7 @@ export function ZoomOutSeparator( { ease: [ 0.6, 0, 0.4, 1 ], } } className="block-editor-block-list__zoom-out-separator" - data-is-zoom-out-separator="true" + data-is-insertion-point="true" > ) } diff --git a/packages/compose/src/hooks/use-drop-zone/index.js b/packages/compose/src/hooks/use-drop-zone/index.js index acbfc176cb229e..bd6956fac73688 100644 --- a/packages/compose/src/hooks/use-drop-zone/index.js +++ b/packages/compose/src/hooks/use-drop-zone/index.js @@ -86,6 +86,7 @@ export default function useDropZone( { */ function isElementInZone( targetToCheck ) { const { defaultView } = ownerDocument; + if ( ! targetToCheck || ! defaultView || @@ -108,18 +109,18 @@ export default function useDropZone( { } /** - * Checks if the given element is a zoom out separator. + * Checks if the given element is an insertion point. * * @param {EventTarget|null} targetToCheck - The element to check. - * @return {boolean} True if the element is a zoom out separator, false otherwise. + * @return {boolean} True if the element is a insertion point, false otherwise. */ - function isZoomOutSeparator( targetToCheck ) { + function isInsertionPoint( targetToCheck ) { const { defaultView } = ownerDocument; return !! ( defaultView && targetToCheck instanceof defaultView.HTMLElement && - targetToCheck.dataset.isZoomOutSeparator + targetToCheck.dataset.isInsertionPoint ); } @@ -186,13 +187,13 @@ export default function useDropZone( { return; } - // If we're moving in/out of a ZoomOutSeparator, don't trigger + // If we're moving in/out of an insertion point then don't trigger // the onDragLeave event. This is to prevent the dropzone from // being hidden when the user is dragging a block in/over/around - // a block and the separator. + // a block and a nearby insertion point. if ( - isZoomOutSeparator( event.relatedTarget ) || - isZoomOutSeparator( event.target ) + isInsertionPoint( event.relatedTarget ) || + isInsertionPoint( event.target ) ) { return; } From f35ae443f210adb68ae6081c099e92ccec13b23b Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 22 Aug 2024 14:11:40 +0100 Subject: [PATCH 09/16] Add comment for clarity --- .../src/components/block-list/zoom-out-separator.js | 2 ++ 1 file changed, 2 insertions(+) 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 8accfce573ddd8..7903b347338827 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 @@ -87,6 +87,8 @@ export function ZoomOutSeparator( { ease: [ 0.6, 0, 0.4, 1 ], } } className="block-editor-block-list__zoom-out-separator" + // Indicate that this is an insertion point and should not trigger + // dropleave events for any parent drop zone. data-is-insertion-point="true" > ) } From d87b7d642b7e539d22952c98febb21820656aa2f Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 22 Aug 2024 14:15:32 +0100 Subject: [PATCH 10/16] Improve code comments --- packages/compose/src/hooks/use-drop-zone/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/compose/src/hooks/use-drop-zone/index.js b/packages/compose/src/hooks/use-drop-zone/index.js index bd6956fac73688..d155978110342f 100644 --- a/packages/compose/src/hooks/use-drop-zone/index.js +++ b/packages/compose/src/hooks/use-drop-zone/index.js @@ -189,8 +189,8 @@ export default function useDropZone( { // If we're moving in/out of an insertion point then don't trigger // the onDragLeave event. This is to prevent the dropzone from - // being hidden when the user is dragging a block in/over/around - // a block and a nearby insertion point. + // trigger any unwanted side effects when the user is likely to + // be moving the cursor quickly over the insertion point. if ( isInsertionPoint( event.relatedTarget ) || isInsertionPoint( event.target ) From e8a0ab8af86f76e80af1b9afb7bf6199486f29b1 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Thu, 22 Aug 2024 14:29:28 +0100 Subject: [PATCH 11/16] Remove blue line inserter in ZoomOutmode --- packages/block-editor/src/components/block-tools/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-tools/index.js b/packages/block-editor/src/components/block-tools/index.js index 163c35b54e4381..24f60dbbf970aa 100644 --- a/packages/block-editor/src/components/block-tools/index.js +++ b/packages/block-editor/src/components/block-tools/index.js @@ -202,7 +202,7 @@ export default function BlockTools( { // eslint-disable-next-line jsx-a11y/no-static-element-interactions
- { ! isTyping && ( + { ! isTyping && ! isZoomOutMode && ( From dfcc570c8d74a169e7b5d1c361f3f95f468418c5 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 23 Aug 2024 14:03:46 +0100 Subject: [PATCH 12/16] Move logic into consuming hook --- .../components/use-block-drop-zone/index.js | 30 ++++++++++++++++++- .../compose/src/hooks/use-drop-zone/index.js | 27 ----------------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/packages/block-editor/src/components/use-block-drop-zone/index.js b/packages/block-editor/src/components/use-block-drop-zone/index.js index 3dedafd24ad064..851661e46a9d09 100644 --- a/packages/block-editor/src/components/use-block-drop-zone/index.js +++ b/packages/block-editor/src/components/use-block-drop-zone/index.js @@ -515,6 +515,23 @@ export default function useBlockDropZone( { 200 ); + /** + * Checks if the given element is an insertion point. + * + * @param {EventTarget|null} targetToCheck - The element to check. + * @param {Document} ownerDocument - The owner document of the element. + * @return {boolean} True if the element is a insertion point, false otherwise. + */ + function isInsertionPoint( targetToCheck, ownerDocument ) { + const { defaultView } = ownerDocument; + + return !! ( + defaultView && + targetToCheck instanceof defaultView.HTMLElement && + targetToCheck.dataset.isInsertionPoint + ); + } + return useDropZone( { dropZoneElement, isDisabled, @@ -525,7 +542,18 @@ export default function useBlockDropZone( { // https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget throttled( event, event.currentTarget.ownerDocument ); }, - onDragLeave() { + onDragLeave( event ) { + const { ownerDocument } = event.currentTarget; + + // If the drag event is leaving the drop zone and entering an insertion point, + // do not hide the insertion point as it is conceptually within the dropzone. + if ( + isInsertionPoint( event.relatedTarget, ownerDocument ) || + isInsertionPoint( event.target, ownerDocument ) + ) { + return; + } + throttled.cancel(); hideInsertionPoint(); }, diff --git a/packages/compose/src/hooks/use-drop-zone/index.js b/packages/compose/src/hooks/use-drop-zone/index.js index d155978110342f..c570c034415923 100644 --- a/packages/compose/src/hooks/use-drop-zone/index.js +++ b/packages/compose/src/hooks/use-drop-zone/index.js @@ -108,22 +108,6 @@ export default function useDropZone( { return false; } - /** - * Checks if the given element is an insertion point. - * - * @param {EventTarget|null} targetToCheck - The element to check. - * @return {boolean} True if the element is a insertion point, false otherwise. - */ - function isInsertionPoint( targetToCheck ) { - const { defaultView } = ownerDocument; - - return !! ( - defaultView && - targetToCheck instanceof defaultView.HTMLElement && - targetToCheck.dataset.isInsertionPoint - ); - } - function maybeDragStart( /** @type {DragEvent} */ event ) { if ( isDragging ) { return; @@ -187,17 +171,6 @@ export default function useDropZone( { return; } - // If we're moving in/out of an insertion point then don't trigger - // the onDragLeave event. This is to prevent the dropzone from - // trigger any unwanted side effects when the user is likely to - // be moving the cursor quickly over the insertion point. - if ( - isInsertionPoint( event.relatedTarget ) || - isInsertionPoint( event.target ) - ) { - return; - } - if ( onDragLeaveRef.current ) { onDragLeaveRef.current( event ); } From 55fc09ec25a44518a23abdce3c3743f7bb823e5d Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 4 Sep 2024 12:34:44 +0100 Subject: [PATCH 13/16] Consume new API for getting root --- .../src/components/block-list/zoom-out-separator.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 7903b347338827..853f56284cc6ce 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 @@ -26,13 +26,13 @@ export function ZoomOutSeparator( { blockInsertionPointVisible, } = useSelect( ( select ) => { const { - getSettings, getBlockInsertionPoint, getBlockOrder, isBlockInsertionPointVisible, + getSectionRootClientId, } = unlock( select( blockEditorStore ) ); - const { sectionRootClientId: root } = unlock( getSettings() ); + const root = getSectionRootClientId(); const sectionRootClientIds = getBlockOrder( root ); return { sectionRootClientId: root, From bdcb6a49fe36feacde2446e949e5bee985178c26 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 4 Sep 2024 12:34:57 +0100 Subject: [PATCH 14/16] Move pure function --- .../components/use-block-drop-zone/index.js | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/block-editor/src/components/use-block-drop-zone/index.js b/packages/block-editor/src/components/use-block-drop-zone/index.js index 851661e46a9d09..ff4d52aaa493bc 100644 --- a/packages/block-editor/src/components/use-block-drop-zone/index.js +++ b/packages/block-editor/src/components/use-block-drop-zone/index.js @@ -274,6 +274,23 @@ export function isDropTargetValid( return areBlocksAllowed && targetMatchesDraggedBlockParents; } +/** + * Checks if the given element is an insertion point. + * + * @param {EventTarget|null} targetToCheck - The element to check. + * @param {Document} ownerDocument - The owner document of the element. + * @return {boolean} True if the element is a insertion point, false otherwise. + */ +function isInsertionPoint( targetToCheck, ownerDocument ) { + const { defaultView } = ownerDocument; + + return !! ( + defaultView && + targetToCheck instanceof defaultView.HTMLElement && + targetToCheck.dataset.isInsertionPoint + ); +} + /** * @typedef {Object} WPBlockDropZoneConfig * @property {?HTMLElement} dropZoneElement Optional element to be used as the drop zone. @@ -515,23 +532,6 @@ export default function useBlockDropZone( { 200 ); - /** - * Checks if the given element is an insertion point. - * - * @param {EventTarget|null} targetToCheck - The element to check. - * @param {Document} ownerDocument - The owner document of the element. - * @return {boolean} True if the element is a insertion point, false otherwise. - */ - function isInsertionPoint( targetToCheck, ownerDocument ) { - const { defaultView } = ownerDocument; - - return !! ( - defaultView && - targetToCheck instanceof defaultView.HTMLElement && - targetToCheck.dataset.isInsertionPoint - ); - } - return useDropZone( { dropZoneElement, isDisabled, From 94a8a1405661e7ebef88707ca509b3a1400caf23 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Wed, 4 Sep 2024 12:53:26 +0100 Subject: [PATCH 15/16] Fix background showing through --- .../block-editor/src/components/block-list/content.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss index cc71b3f32b4515..42ec8bae39c0a1 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -457,11 +457,15 @@ _::-webkit-full-page-media, _:future, :root .has-multi-selection .block-editor-b .block-editor-block-list__zoom-out-separator { /* same color as the iframe's background */ background: $gray-300; + // Additional -1px is required to avoid sub pixel rounding errors allowing background to show. + margin-left: -1px; + margin-right: -1px; } // In Post Editor allow the separator to occupy the full width by ignoring (cancelling out) the global padding. .has-global-padding > .block-editor-block-list__zoom-out-separator, .block-editor-block-list__layout.is-root-container.has-global-padding > .block-editor-block-list__zoom-out-separator { max-width: none; - margin: 0 calc(-1 * var(--wp--style--root--padding-right)) 0 calc(-1 * var(--wp--style--root--padding-left)) !important; + // Additional -1px is required to avoid sub pixel rounding errors allowing background to show. + margin: 0 calc(-1 * var(--wp--style--root--padding-right) - 1px) 0 calc(-1 * var(--wp--style--root--padding-left) - 1px) !important; } From 7ab2a929ae1de88993c6e6834c40ed61f6fcafa3 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Fri, 6 Sep 2024 10:03:22 +0100 Subject: [PATCH 16/16] Add UI feedback on dragover separator --- .../src/components/block-list/content.scss | 5 +++++ .../block-list/zoom-out-separator.js | 19 ++++++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/block-list/content.scss b/packages/block-editor/src/components/block-list/content.scss index 42ec8bae39c0a1..3f4b4c508aeb02 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -460,6 +460,11 @@ _::-webkit-full-page-media, _:future, :root .has-multi-selection .block-editor-b // Additional -1px is required to avoid sub pixel rounding errors allowing background to show. margin-left: -1px; margin-right: -1px; + transition: background-color 0.3s ease; + + &.is-dragged-over { + background: $gray-400; + } } // In Post Editor allow the separator to occupy the full width by ignoring (cancelling out) the global padding. 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 853f56284cc6ce..be5af549630607 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 @@ -1,3 +1,8 @@ +/** + * External dependencies + */ +import clsx from 'clsx'; + /** * WordPress dependencies */ @@ -7,6 +12,7 @@ import { } from '@wordpress/components'; import { useReducedMotion } from '@wordpress/compose'; import { useSelect } from '@wordpress/data'; +import { useState } from '@wordpress/element'; /** * Internal dependencies @@ -19,6 +25,7 @@ export function ZoomOutSeparator( { rootClientId = '', position = 'top', } ) { + const [ isDraggedOver, setIsDraggedOver ] = useState( false ); const { sectionRootClientId, sectionClientIds, @@ -77,6 +84,7 @@ export function ZoomOutSeparator( { { isVisible && ( setIsDraggedOver( true ) } + onDragLeave={ () => setIsDraggedOver( false ) } > ) }