From f7805a36f5969bb8f0183f89320618e9db894dbe Mon Sep 17 00:00:00 2001 From: Kiril Zhelyazkov Date: Mon, 17 Aug 2020 11:12:37 +0300 Subject: [PATCH 1/2] Show inserter on click --- .../components/block-list/insertion-point.js | 119 +++++------------- .../src/components/block-list/style.scss | 7 +- 2 files changed, 38 insertions(+), 88 deletions(-) diff --git a/packages/block-editor/src/components/block-list/insertion-point.js b/packages/block-editor/src/components/block-list/insertion-point.js index c7eb0e8d6ee80..940b0d6ab4db1 100644 --- a/packages/block-editor/src/components/block-list/insertion-point.js +++ b/packages/block-editor/src/components/block-list/insertion-point.js @@ -98,7 +98,6 @@ function InsertionPointPopover( { isInserterForced, setIsInserterForced, containerRef, - showInsertionPoint, } ) { const element = getBlockDOMNode( clientId ); @@ -116,9 +115,7 @@ function InsertionPointPopover( { className="block-editor-block-list__insertion-point" style={ { width: element?.offsetWidth } } > - { showInsertionPoint && ( -
- ) } +
{ ( isInserterShown || isInserterForced ) && ( { - const { - isMultiSelecting: _isMultiSelecting, - isBlockInsertionPointVisible, - getBlockInsertionPoint, - getBlockOrder, - } = select( 'core/block-editor' ); - - const insertionPoint = getBlockInsertionPoint(); - const order = getBlockOrder( insertionPoint.rootClientId ); - - return { - isMultiSelecting: _isMultiSelecting(), - isInserterVisible: isBlockInsertionPointVisible(), - selectedClientId: order[ insertionPoint.index ], - }; - }, - [] - ); - - function onMouseMove( event ) { - if ( - ! event.target.classList.contains( - 'block-editor-block-list__layout' - ) - ) { - if ( isInserterShown ) { - setIsInserterShown( false ); - } - return; - } - - const rect = event.target.getBoundingClientRect(); - const offset = event.clientY - rect.top; - const element = Array.from( event.target.children ).find( - ( blockEl ) => { - return blockEl.offsetTop > offset; - } - ); - - if ( ! element ) { - return; - } - - const clientId = element.id.slice( 'block-'.length ); - - if ( ! clientId ) { - return; - } - - const elementRect = element.getBoundingClientRect(); - - if ( - event.clientX > elementRect.right || - event.clientX < elementRect.left - ) { - if ( isInserterShown ) { - setIsInserterShown( false ); - } - return; - } - - setIsInserterShown( true ); - setInserterClientId( clientId ); - } - - const isVisible = isInserterShown || isInserterForced || isInserterVisible; + const { + isMultiSelecting, + isInserterVisible, + selectedClientId, + isNestedBlock, + } = useSelect( ( select ) => { + const { + isMultiSelecting: _isMultiSelecting, + isBlockInsertionPointVisible, + getBlockInsertionPoint, + getBlockOrder, + } = select( 'core/block-editor' ); + + const insertionPoint = getBlockInsertionPoint(); + const order = getBlockOrder( insertionPoint.rootClientId ); + + return { + isMultiSelecting: _isMultiSelecting(), + isInserterVisible: isBlockInsertionPointVisible(), + selectedClientId: order[ insertionPoint.index ], + isNestedBlock: Boolean( insertionPoint.rootClientId ), + }; + }, [] ); + + const isVisible = + Boolean( selectedClientId ) || isInserterForced || isInserterVisible; + + const isInserterShown = Boolean( selectedClientId ) && ! isNestedBlock; return ( <> - { ! isMultiSelecting && isVisible && ( + { ! isMultiSelecting && isVisible && isInserterShown && ( ) } -
- { children } -
+ { children } ); } diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index 3244777ce8dda..5a191cf4e9407 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -364,7 +364,6 @@ .block-editor-block-list__insertion-point { position: relative; z-index: z-index(".block-editor-block-list__insertion-point"); - margin-top: -$block-padding; } .block-editor-block-list__insertion-point-indicator { @@ -428,6 +427,12 @@ } } +.block-editor-block-list__insertion-point-indicator { + animation: block-editor-inserter__toggle__fade-in-animation-delayed 0.3s ease; + animation-fill-mode: forwards; + @include reduce-motion("animation"); +} + .block-editor-block-list__insertion-point-inserter, .block-editor-block-list__block-popover-inserter { From 8a3b53f5a17016f85e2355984565485b3b82f567 Mon Sep 17 00:00:00 2001 From: Kiril Zhelyazkov Date: Fri, 11 Sep 2020 11:48:13 +0300 Subject: [PATCH 2/2] overhauled current implementation and started from scratch --- .../components/block-list/insertion-point.js | 188 ++++-------------- packages/components/src/popover/style.scss | 6 +- 2 files changed, 41 insertions(+), 153 deletions(-) diff --git a/packages/block-editor/src/components/block-list/insertion-point.js b/packages/block-editor/src/components/block-list/insertion-point.js index 940b0d6ab4db1..52dcde533b17a 100644 --- a/packages/block-editor/src/components/block-list/insertion-point.js +++ b/packages/block-editor/src/components/block-list/insertion-point.js @@ -1,175 +1,63 @@ -/** - * External dependencies - */ -import classnames from 'classnames'; - /** * WordPress dependencies */ import { useSelect } from '@wordpress/data'; -import { useState, useRef } from '@wordpress/element'; import { Popover } from '@wordpress/components'; -import { placeCaretAtVerticalEdge } from '@wordpress/dom'; /** * Internal dependencies */ import Inserter from '../inserter'; -import { getClosestTabbable } from '../writing-flow'; import { getBlockDOMNode } from '../../utils/dom'; -function InsertionPointInserter( { - clientId, - setIsInserterForced, - containerRef, -} ) { - const ref = useRef(); - // Hide the inserter above the selected block and during multi-selection. - const isInserterHidden = useSelect( - ( select ) => { - const { - getMultiSelectedBlockClientIds, - getSelectedBlockClientId, - hasMultiSelection, - } = select( 'core/block-editor' ); - const multiSelectedBlockClientIds = getMultiSelectedBlockClientIds(); - const selectedBlockClientId = getSelectedBlockClientId(); - - return hasMultiSelection() - ? multiSelectedBlockClientIds.includes( clientId ) - : clientId === selectedBlockClientId; - }, - [ clientId ] - ); - - function focusClosestTabbable( event ) { - const { clientX, clientY, target } = event; - - // Only handle click on the wrapper specifically, and not an event - // bubbled from the inserter itself. - if ( target !== ref.current ) { - return; - } - - const targetRect = target.getBoundingClientRect(); - const isReverse = clientY < targetRect.top + targetRect.height / 2; - const blockNode = getBlockDOMNode( clientId ); - const container = isReverse ? containerRef.current : blockNode; - const closest = - getClosestTabbable( blockNode, true, container ) || blockNode; - const rect = new window.DOMRect( clientX, clientY, 0, 16 ); - - placeCaretAtVerticalEdge( closest, isReverse, rect, false ); - } - - return ( - /* eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ -
setIsInserterForced( true ) } - onBlur={ () => setIsInserterForced( false ) } - onClick={ focusClosestTabbable } - // While ideally it would be enough to capture the - // bubbling focus event from the Inserter, due to the - // characteristics of click focusing of `button`s in - // Firefox and Safari, it is not reliable. - // - // See: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#Clicking_and_focus - tabIndex={ -1 } - className={ classnames( - 'block-editor-block-list__insertion-point-inserter', - { - 'is-inserter-hidden': isInserterHidden, - } - ) } - > - -
- ); -} - -function InsertionPointPopover( { - clientId, - isInserterShown, - isInserterForced, - setIsInserterForced, - containerRef, -} ) { - const element = getBlockDOMNode( clientId ); - - return ( - -
-
- { ( isInserterShown || isInserterForced ) && ( - - ) } -
- - ); -} - -export default function InsertionPoint( { children, containerRef } ) { - const [ isInserterForced, setIsInserterForced ] = useState( false ); - const { - isMultiSelecting, - isInserterVisible, - selectedClientId, - isNestedBlock, - } = useSelect( ( select ) => { - const { - isMultiSelecting: _isMultiSelecting, - isBlockInsertionPointVisible, - getBlockInsertionPoint, - getBlockOrder, - } = select( 'core/block-editor' ); +export default function InsertionPoint( { children } ) { + const { order, IP } = useSelect( ( select ) => { + const { getBlockInsertionPoint, getBlockOrder } = select( + 'core/block-editor' + ); const insertionPoint = getBlockInsertionPoint(); - const order = getBlockOrder( insertionPoint.rootClientId ); return { - isMultiSelecting: _isMultiSelecting(), - isInserterVisible: isBlockInsertionPointVisible(), - selectedClientId: order[ insertionPoint.index ], - isNestedBlock: Boolean( insertionPoint.rootClientId ), + IP: insertionPoint, + order: getBlockOrder( insertionPoint.rootClientId ), }; - }, [] ); + } ); - const isVisible = - Boolean( selectedClientId ) || isInserterForced || isInserterVisible; + const clientId = order[ IP.index - 1 ]; + const element = getBlockDOMNode( clientId ); - const isInserterShown = Boolean( selectedClientId ) && ! isNestedBlock; + // should be visible only when the user has hovered over the inserter + const shouldShow = order.length !== IP.index; return ( <> - { ! isMultiSelecting && isVisible && isInserterShown && ( - + { shouldShow && ( + +
+ +
+
+ ) } { children } diff --git a/packages/components/src/popover/style.scss b/packages/components/src/popover/style.scss index 75fef0850bf4f..ad7da8aa25083 100644 --- a/packages/components/src/popover/style.scss +++ b/packages/components/src/popover/style.scss @@ -206,9 +206,9 @@ $arrow-size: 8px; left: 100%; } - .components-popover:not([data-y-axis="middle"])[data-x-axis="right"] & { - margin-left: -($grid-unit-30 + $border-width); - } + //.components-popover:not([data-y-axis="middle"])[data-x-axis="right"] & { + // margin-left: -($grid-unit-30 + $border-width); + //} .components-popover[data-x-axis="left"] & { position: absolute;