From 95c19951b11667fabc12b90c3f6affa3a73dd5bd Mon Sep 17 00:00:00 2001 From: Maggie Date: Fri, 6 Sep 2024 14:56:13 +0100 Subject: [PATCH] Zoom out: Try vertical displacement when dragging a pattern between existing patterns/sections (#63896) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 * Don’t show seperator if opertation is not insert * Fix bug where rootClientId was not within sectionRoot * Ignore Group operations on drag in Zoom Out mode * Check for ZoomOut separators when firing onDragEnd * Refine function to detect zoom out separator * Update detection based on data attribute * Make generic * Add comment for clarity * Improve code comments * Remove blue line inserter in ZoomOutmode * Move logic into consuming hook * Consume new API for getting root * Move pure function * Fix background showing through * Add UI feedback on dragover separator --------- Co-authored-by: Dave Smith Co-authored-by: MaggieCabrera Co-authored-by: getdave Co-authored-by: Mamaduka Co-authored-by: scruffian Co-authored-by: andrewserong Co-authored-by: richtabor --- .../src/components/block-list/content.scss | 21 ++++ .../src/components/block-list/index.js | 97 +++++++++------ .../block-list/zoom-out-separator.js | 110 ++++++++++++++++++ .../src/components/block-tools/index.js | 2 +- .../block-tools/zoom-out-mode-inserters.js | 12 -- .../components/use-block-drop-zone/index.js | 34 +++++- .../compose/src/hooks/use-drop-zone/index.js | 2 + 7 files changed, 226 insertions(+), 52 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..3f4b4c508aeb02 100644 --- a/packages/block-editor/src/components/block-list/content.scss +++ b/packages/block-editor/src/components/block-list/content.scss @@ -453,3 +453,24 @@ _::-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; + // 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. +.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; + // 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; +} 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..be5af549630607 --- /dev/null +++ b/packages/block-editor/src/components/block-list/zoom-out-separator.js @@ -0,0 +1,110 @@ +/** + * External dependencies + */ +import clsx from 'clsx'; + +/** + * WordPress dependencies + */ +import { + __unstableMotion as motion, + __unstableAnimatePresence as AnimatePresence, +} from '@wordpress/components'; +import { useReducedMotion } from '@wordpress/compose'; +import { useSelect } from '@wordpress/data'; +import { useState } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; +import { unlock } from '../../lock-unlock'; + +export function ZoomOutSeparator( { + clientId, + rootClientId = '', + position = 'top', +} ) { + const [ isDraggedOver, setIsDraggedOver ] = useState( false ); + const { + sectionRootClientId, + sectionClientIds, + blockInsertionPoint, + blockInsertionPointVisible, + } = useSelect( ( select ) => { + const { + getBlockInsertionPoint, + getBlockOrder, + isBlockInsertionPointVisible, + getSectionRootClientId, + } = unlock( select( blockEditorStore ) ); + + const root = getSectionRootClientId(); + const sectionRootClientIds = getBlockOrder( root ); + return { + sectionRootClientId: root, + sectionClientIds: sectionRootClientIds, + blockOrder: getBlockOrder( root ), + blockInsertionPoint: getBlockInsertionPoint(), + blockInsertionPointVisible: isBlockInsertionPointVisible(), + }; + }, [] ); + + const isReducedMotion = useReducedMotion(); + + if ( ! clientId ) { + return; + } + + let isVisible = false; + + const isSectionBlock = + rootClientId === sectionRootClientId && + sectionClientIds && + sectionClientIds.includes( clientId ); + + 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 && ( + setIsDraggedOver( true ) } + onDragLeave={ () => setIsDraggedOver( false ) } + > + ) } + + ); +} 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 && ( 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 && (