From f3c561a5094c55510a292633680e7b731ebe3979 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Fri, 22 Nov 2019 11:13:02 +0100 Subject: [PATCH] Move the block movers to the block toolbar --- .../developers/data/data-core-block-editor.md | 28 ++++++ packages/block-editor/README.md | 4 - .../src/components/block-draggable/index.js | 43 ++++++--- .../block-list/block-mobile-toolbar.js | 21 ----- .../src/components/block-list/block.js | 55 +---------- .../src/components/block-list/index.js | 2 - .../components/block-list/multi-controls.js | 39 -------- .../src/components/block-list/style.scss | 80 +--------------- .../src/components/block-mover/drag-handle.js | 26 +++--- .../src/components/block-mover/index.js | 28 +++--- .../src/components/block-mover/style.scss | 93 ------------------- .../block-switcher/multi-blocks-switcher.js | 28 ------ .../src/components/block-toolbar/index.js | 58 ++++++------ packages/block-editor/src/components/index.js | 1 - packages/block-editor/src/store/actions.js | 22 +++++ packages/block-editor/src/store/reducer.js | 21 +++++ packages/block-editor/src/store/selectors.js | 11 +++ 17 files changed, 169 insertions(+), 391 deletions(-) delete mode 100644 packages/block-editor/src/components/block-list/block-mobile-toolbar.js delete mode 100644 packages/block-editor/src/components/block-list/multi-controls.js delete mode 100644 packages/block-editor/src/components/block-switcher/multi-blocks-switcher.js diff --git a/docs/designers-developers/developers/data/data-core-block-editor.md b/docs/designers-developers/developers/data/data-core-block-editor.md index 99cc264cc7e2e4..90b74fcd5ad231 100644 --- a/docs/designers-developers/developers/data/data-core-block-editor.md +++ b/docs/designers-developers/developers/data/data-core-block-editor.md @@ -756,6 +756,18 @@ _Returns_ - `boolean`: Whether the caret is within formatted text. +# **isDraggingBlocks** + +Returns true if the user is dragging blocks, or false otherwise. + +_Parameters_ + +- _state_ `Object`: Global application state. + +_Returns_ + +- `boolean`: Whether user is dragging blocks. + # **isFirstMultiSelectedBlock** Returns true if a multi-selection exists, and the block corresponding to the @@ -1177,6 +1189,14 @@ _Returns_ - `Object`: Action object. +# **startDraggingBlocks** + +Returns an action object used in signalling that the user has begun to drag blocks. + +_Returns_ + +- `Object`: Action object. + # **startMultiSelect** Returns an action object used in signalling that a block multi-selection has started. @@ -1193,6 +1213,14 @@ _Returns_ - `Object`: Action object. +# **stopDraggingBlocks** + +Returns an action object used in signalling that the user has stopped dragging blocks. + +_Returns_ + +- `Object`: Action object. + # **stopMultiSelect** Returns an action object used in signalling that block multi-selection stopped. diff --git a/packages/block-editor/README.md b/packages/block-editor/README.md index c90ced2fe3c7c2..a57de4c8463140 100644 --- a/packages/block-editor/README.md +++ b/packages/block-editor/README.md @@ -332,10 +332,6 @@ _Related_ - -# **MultiBlocksSwitcher** - -Undocumented declaration. - # **MultiSelectScrollIntoView** Undocumented declaration. diff --git a/packages/block-editor/src/components/block-draggable/index.js b/packages/block-editor/src/components/block-draggable/index.js index 8818d58be9c2d2..90f9534bf6f7c3 100644 --- a/packages/block-editor/src/components/block-draggable/index.js +++ b/packages/block-editor/src/components/block-draggable/index.js @@ -2,22 +2,44 @@ * WordPress dependencies */ import { Draggable } from '@wordpress/components'; -import { withSelect } from '@wordpress/data'; +import { useSelect, useDispatch } from '@wordpress/data'; -const BlockDraggable = ( { children, clientId, rootClientId, blockElementId, index, onDragStart, onDragEnd } ) => { +const BlockDraggable = ( { children, clientIds } ) => { + const { srcRootClientId, index, isDraggable } = useSelect( ( select ) => { + const { + getBlockIndex, + getBlockRootClientId, + getTemplateLock, + } = select( 'core/block-editor' ); + const rootClientId = clientIds.length === 1 ? getBlockRootClientId( clientIds[ 0 ] ) : null; + const templateLock = rootClientId ? getTemplateLock( rootClientId ) : null; + + return { + index: getBlockIndex( clientIds[ 0 ], rootClientId ), + srcRootClientId: rootClientId, + isDraggable: clientIds.length === 1 && 'all' !== templateLock, + }; + }, [ clientIds ] ); + const { startDraggingBlocks, stopDraggingBlocks } = useDispatch( 'core/block-editor' ); + + if ( ! isDraggable ) { + return null; + } + + const blockElementId = `block-${ clientIds[ 0 ] }`; const transferData = { type: 'block', srcIndex: index, - srcRootClientId: rootClientId, - srcClientId: clientId, + srcClientId: clientIds[ 0 ], + srcRootClientId, }; return ( { ( { onDraggableStart, onDraggableEnd } ) => { @@ -31,11 +53,4 @@ const BlockDraggable = ( { children, clientId, rootClientId, blockElementId, ind ); }; -export default withSelect( ( select, { clientId } ) => { - const { getBlockIndex, getBlockRootClientId } = select( 'core/block-editor' ); - const rootClientId = getBlockRootClientId( clientId ); - return { - index: getBlockIndex( clientId, rootClientId ), - rootClientId, - }; -} )( BlockDraggable ); +export default BlockDraggable; diff --git a/packages/block-editor/src/components/block-list/block-mobile-toolbar.js b/packages/block-editor/src/components/block-list/block-mobile-toolbar.js deleted file mode 100644 index 8af64ec12c021b..00000000000000 --- a/packages/block-editor/src/components/block-list/block-mobile-toolbar.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * WordPress dependencies - */ -import { ifViewportMatches } from '@wordpress/viewport'; - -/** - * Internal dependencies - */ -import BlockMover from '../block-mover'; -import VisualEditorInserter from '../inserter'; - -function BlockMobileToolbar( { clientId, moverDirection } ) { - return ( -
- - -
- ); -} - -export default ifViewportMatches( '< small' )( BlockMobileToolbar ); diff --git a/packages/block-editor/src/components/block-list/block.js b/packages/block-editor/src/components/block-list/block.js index 48b5506e452f2f..24413ee9011b1c 100644 --- a/packages/block-editor/src/components/block-list/block.js +++ b/packages/block-editor/src/components/block-list/block.js @@ -35,7 +35,6 @@ import { compose, pure, ifCondition } from '@wordpress/compose'; * Internal dependencies */ import BlockEdit from '../block-edit'; -import BlockMover from '../block-mover'; import BlockDropZone from '../block-drop-zone'; import BlockInvalidWarning from './block-invalid-warning'; import BlockCrashWarning from './block-crash-warning'; @@ -43,8 +42,6 @@ import BlockCrashBoundary from './block-crash-boundary'; import BlockHtml from './block-html'; import BlockBreadcrumb from './breadcrumb'; import BlockContextualToolbar from './block-contextual-toolbar'; -import BlockMultiControls from './multi-controls'; -import BlockMobileToolbar from './block-mobile-toolbar'; import BlockInsertionPoint from './insertion-point'; import IgnoreNestedEvents from '../ignore-nested-events'; import InserterWithShortcuts from '../inserter-with-shortcuts'; @@ -75,11 +72,10 @@ function BlockListBlock( { isPartOfMultiSelection, isFirstMultiSelected, isTypingWithinBlock, + isDragging, isCaretWithinFormattedText, isEmptyDefaultBlock, - isMovable, isParentOfSelectedBlock, - isDraggable, isSelectionEnabled, className, name, @@ -171,15 +167,6 @@ function BlockListBlock( { } } ); - // Handling the dragging state - const [ isDragging, setBlockDraggingState ] = useState( false ); - const onDragStart = () => { - setBlockDraggingState( true ); - }; - const onDragEnd = () => { - setBlockDraggingState( false ); - }; - // Handling the error state const [ hasError, setErrorState ] = useState( false ); const onBlockError = () => setErrorState( true ); @@ -397,13 +384,6 @@ function BlockListBlock( { ! hasFixedToolbar && isHovered && ! isEmptyDefaultBlock; - // We render block movers and block settings to keep them tabbale even if hidden - const shouldRenderMovers = - ! isNavigationMode && - isSelected && - ! showEmptyBlockSideInserter && - ! isPartOfMultiSelection && - ! isTypingWithinBlock; const shouldShowBreadcrumb = ( isSelected && isNavigationMode ) || ( ! isNavigationMode && ! isFocusMode && isHovered && ! isEmptyDefaultBlock ); @@ -415,7 +395,6 @@ function BlockListBlock( { ( isSelected && ( ! isTypingWithinBlock || isCaretWithinFormattedText ) ) || isFirstMultiSelected ); - const shouldShowMobileToolbar = ! isNavigationMode && shouldAppearSelected; // Insertion point can only be made visible if the block is at the // the extent of a multi-selection, or not in a multi-selection. @@ -451,20 +430,6 @@ function BlockListBlock( { }; } const blockElementId = `block-${ clientId }`; - const blockMover = ( - - ); // We wrap the BlockEdit component in a div that hides it when editing in // HTML mode. This allows us to render all of the ancillary pieces @@ -525,19 +490,12 @@ function BlockListBlock( { clientId={ clientId } rootClientId={ rootClientId } /> - { isFirstMultiSelected && ( - - ) }
- { shouldRenderMovers && ( moverDirection === 'vertical' ) && blockMover } { shouldShowBreadcrumb && ( ) } - { shouldRenderMovers && ( moverDirection === 'horizontal' ) && blockMover } { ! isValid && [ { !! hasError && } - { shouldShowMobileToolbar && ( - - ) }
{ showInserterShortcuts && ( @@ -625,6 +579,7 @@ const applyWithSelect = withSelect( isBlockMultiSelected, isFirstMultiSelectedBlock, isTyping, + isDraggingBlocks, isCaretWithinFormattedText, getBlockMode, isSelectionEnabled, @@ -644,6 +599,7 @@ const applyWithSelect = withSelect( const isParentOfSelectedBlock = hasSelectedInnerBlock( clientId, true ); const index = getBlockIndex( clientId, rootClientId ); const blockOrder = getBlockOrder( rootClientId ); + const isPartOfMultiSelection = isBlockMultiSelected( clientId ) || isAncestorMultiSelected( clientId ); // The fallback to `{}` is a temporary fix. // This function should never be called when a block is not present in the state. @@ -651,8 +607,7 @@ const applyWithSelect = withSelect( const { name, attributes, isValid } = block || {}; return { - isPartOfMultiSelection: - isBlockMultiSelected( clientId ) || isAncestorMultiSelected( clientId ), + isDragging: isDraggingBlocks() && ( isSelected || isPartOfMultiSelection ), isFirstMultiSelected: isFirstMultiSelectedBlock( clientId ), // We only care about this prop when the block is selected // Thus to avoid unnecessary rerenders we avoid updating the prop if the block is not selected. @@ -664,12 +619,12 @@ const applyWithSelect = withSelect( initialPosition: isSelected ? getSelectedBlocksInitialCaretPosition() : null, isEmptyDefaultBlock: name && isUnmodifiedDefaultBlock( { name, attributes } ), - isMovable: 'all' !== templateLock, isLocked: !! templateLock, isFocusMode: focusMode && isLargeViewport, hasFixedToolbar: hasFixedToolbar && isLargeViewport, isLast: index === blockOrder.length - 1, isNavigationMode: isNavigationMode(), + isPartOfMultiSelection, isRTL, // Users of the editor.BlockListBlock filter used to be able to access the block prop diff --git a/packages/block-editor/src/components/block-list/index.js b/packages/block-editor/src/components/block-list/index.js index 54511ac941ecc4..ed7334f5d84c62 100644 --- a/packages/block-editor/src/components/block-list/index.js +++ b/packages/block-editor/src/components/block-list/index.js @@ -196,7 +196,6 @@ class BlockList extends Component { blockClientIds, rootClientId, __experimentalMoverDirection: moverDirection = 'vertical', - isDraggable, selectedBlockClientId, multiSelectedBlockClientIds, hasMultiSelection, @@ -227,7 +226,6 @@ class BlockList extends Component { clientId={ clientId } blockRef={ this.setBlockRef } onSelectionStart={ this.onSelectionStart } - isDraggable={ isDraggable } moverDirection={ moverDirection } // This prop is explicitely computed and passed down diff --git a/packages/block-editor/src/components/block-list/multi-controls.js b/packages/block-editor/src/components/block-list/multi-controls.js deleted file mode 100644 index 2f49ca2ca0a3b4..00000000000000 --- a/packages/block-editor/src/components/block-list/multi-controls.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * WordPress dependencies - */ -import { withSelect } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import BlockMover from '../block-mover'; - -function BlockListMultiControls( { - multiSelectedBlockClientIds, - isSelecting, - moverDirection, -} ) { - if ( isSelecting ) { - return null; - } - - return ( - - ); -} - -export default withSelect( ( select ) => { - const { - getMultiSelectedBlockClientIds, - isMultiSelecting, - } = select( 'core/block-editor' ); - const clientIds = getMultiSelectedBlockClientIds(); - - return { - multiSelectedBlockClientIds: clientIds, - isSelecting: isMultiSelecting(), - }; -} )( BlockListMultiControls ); diff --git a/packages/block-editor/src/components/block-list/style.scss b/packages/block-editor/src/components/block-list/style.scss index e40b7676be37c1..22880eaa8108a1 100644 --- a/packages/block-editor/src/components/block-list/style.scss +++ b/packages/block-editor/src/components/block-list/style.scss @@ -661,82 +661,6 @@ } } - -/** - * Mobile unified toolbar. - */ - -.block-editor-block-list__block { - - // Show side UI inline below the block on mobile. - .block-editor-block-list__block-mobile-toolbar { - display: flex; - flex-direction: row; - - // Make room for the height of the block toolbar above. - transform: translateY($block-padding + $border-width); - margin-top: $block-toolbar-height; - margin-right: -$block-padding; - margin-left: -$block-padding; - border-top: $border-width solid $light-gray-800; - height: $block-toolbar-height; - - @include break-small() { - display: none; - } - - // Add a white background to prevent the block's left border from showing through. - background-color: $white; - - // Show a shadow below the selected block to imply separation. - box-shadow: $shadow-below-only; - @include break-small() { - box-shadow: none; - } - - // Movers, inserter, trash, and ellipsis. - .block-editor-inserter { - position: relative; - left: auto; - top: auto; - margin: 0; - } - - .block-editor-inserter__toggle, - .block-editor-block-mover__control { - width: $icon-button-size; - height: $icon-button-size; - border-radius: $radius-round-rectangle; - padding: 3px; - margin: 0; - justify-content: center; - align-items: center; - - .dashicon { - margin: auto; - } - } - - // Movers - .block-editor-block-mover { - display: flex; - margin-right: auto; - - .block-editor-inserter, - .block-editor-block-mover__control { - float: left; - } - } - } - - // Reset negative margins on mobile for full-width. - &[data-align="full"] .block-editor-block-list__block-mobile-toolbar { - margin-left: 0; - margin-right: 0; - } -} - - /** * In-Canvas Inserter */ @@ -874,12 +798,13 @@ // Position toolbar below the block on mobile. position: absolute; - bottom: $block-toolbar-height - $block-padding - $border-width; + bottom: - $block-toolbar-height - $block-padding - $border-width; left: -$block-padding; right: -$block-padding; // Paint the borders on the toolbar itself on mobile. border-top: $border-width solid $light-gray-800; + border-bottom: $border-width solid $light-gray-800; .components-toolbar { border-top: none; border-bottom: none; @@ -887,6 +812,7 @@ @include break-small() { border-top: none; + border-bottom: none; .components-toolbar { border-top: $border-width solid $light-gray-800; border-bottom: $border-width solid $light-gray-800; diff --git a/packages/block-editor/src/components/block-mover/drag-handle.js b/packages/block-editor/src/components/block-mover/drag-handle.js index 86551bf4be0e30..097d83ba12e72d 100644 --- a/packages/block-editor/src/components/block-mover/drag-handle.js +++ b/packages/block-editor/src/components/block-mover/drag-handle.js @@ -3,36 +3,32 @@ */ import classnames from 'classnames'; +/** + * WordPress dependencies + */ +import { IconButton } from '@wordpress/components'; + /** * Internal dependencies */ import BlockDraggable from '../block-draggable'; +import { dragHandle } from './icons'; -export const IconDragHandle = ( { isVisible, className, icon, onDragStart, onDragEnd, blockElementId, clientId } ) => { - if ( ! isVisible ) { - return null; - } - +export const IconDragHandle = ( { className, clientIds } ) => { const dragHandleClassNames = classnames( 'editor-block-mover__control-drag-handle block-editor-block-mover__control-drag-handle', className ); return ( - + { ( { onDraggableStart, onDraggableEnd } ) => ( - + /> ) } ); diff --git a/packages/block-editor/src/components/block-mover/index.js b/packages/block-editor/src/components/block-mover/index.js index cd1f4483eceb16..d5ab025d6e657c 100644 --- a/packages/block-editor/src/components/block-mover/index.js +++ b/packages/block-editor/src/components/block-mover/index.js @@ -1,14 +1,14 @@ /** * External dependencies */ -import { first, last, partial, castArray } from 'lodash'; +import { first, last, partial } from 'lodash'; import classnames from 'classnames'; /** * WordPress dependencies */ import { __, sprintf } from '@wordpress/i18n'; -import { IconButton } from '@wordpress/components'; +import { IconButton, Toolbar } from '@wordpress/components'; import { getBlockType } from '@wordpress/blocks'; import { Component } from '@wordpress/element'; import { withSelect, withDispatch } from '@wordpress/data'; @@ -18,7 +18,7 @@ import { withInstanceId, compose } from '@wordpress/compose'; * Internal dependencies */ import { getBlockMoverDescription } from './mover-description'; -import { leftArrow, rightArrow, upArrow, downArrow, dragHandle } from './icons'; +import { leftArrow, rightArrow, upArrow, downArrow } from './icons'; import { IconDragHandle } from './drag-handle'; export class BlockMover extends Component { @@ -44,9 +44,9 @@ export class BlockMover extends Component { } render() { - const { onMoveUp, onMoveDown, __experimentalOrientation: orientation, isRTL, isFirst, isLast, isDraggable, onDragStart, onDragEnd, clientIds, blockElementId, blockType, firstIndex, isLocked, instanceId, isHidden, rootClientId } = this.props; + const { onMoveUp, onMoveDown, __experimentalOrientation: orientation, isRTL, isFirst, isLast, clientIds, blockType, firstIndex, isLocked, instanceId, isHidden, rootClientId } = this.props; const { isFocused } = this.state; - const blocksCount = castArray( clientIds ).length; + const blocksCount = clientIds.length; if ( isLocked || ( isFirst && isLast && ! rootClientId ) ) { return null; } @@ -86,7 +86,7 @@ export class BlockMover extends Component { // to an unfocused state (body as active element) without firing blur on, // the rendering parent, leaving it unable to react to focus out. return ( -
+ -
+ ); } } @@ -154,13 +149,12 @@ export class BlockMover extends Component { export default compose( withSelect( ( select, { clientIds } ) => { const { getBlock, getBlockIndex, getTemplateLock, getBlockRootClientId, getBlockOrder } = select( 'core/block-editor' ); - const normalizedClientIds = castArray( clientIds ); - const firstClientId = first( normalizedClientIds ); + const firstClientId = first( clientIds ); const block = getBlock( firstClientId ); - const rootClientId = getBlockRootClientId( first( normalizedClientIds ) ); + const rootClientId = getBlockRootClientId( first( clientIds ) ); const blockOrder = getBlockOrder( rootClientId ); const firstIndex = getBlockIndex( firstClientId, rootClientId ); - const lastIndex = getBlockIndex( last( normalizedClientIds ), rootClientId ); + const lastIndex = getBlockIndex( last( clientIds ), rootClientId ); const { getSettings } = select( 'core/block-editor' ); const { isRTL, diff --git a/packages/block-editor/src/components/block-mover/style.scss b/packages/block-editor/src/components/block-mover/style.scss index 61493ee98b4f03..33b4d13332030c 100644 --- a/packages/block-editor/src/components/block-mover/style.scss +++ b/packages/block-editor/src/components/block-mover/style.scss @@ -1,96 +1,3 @@ -.block-editor-block-mover { - @include break-small() { - opacity: 0; - background: $white; - border: 1px solid $dark-opacity-light-800; - border-radius: $radius-round-rectangle; - transition: box-shadow 0.2s ease-out; - @include reduce-motion("transition"); - - &.is-visible { - @include edit-post__fade-in-animation; - } - - &:hover { - box-shadow: $shadow-toolbar; - } - - // 24px is the smallest size of a good pressable button. - // With 3 pieces of side UI, that comes to a total of 72px. - // To vertically center against a 56px paragraph, move upwards 72px - 56px / 2. - margin-top: -$grid-size; - } - - &.is-horizontal { - margin-top: 5px; // The height of the appender is 36px. This pushes down the mover to be centered according to that. - margin-right: $grid-size; - padding-right: 0; - min-height: auto; - width: ($icon-button-size-small * 2) + ($border-width * 2); - height: $icon-button-size-small + ($border-width * 2); - display: flex; - - .block-editor-block-mover__control { - width: $icon-button-size-small; - height: $icon-button-size-small; - - svg { - width: $icon-button-size-small; - padding: 3px; - } - } - } -} - -// Don't add negative vertical margin for wide, fullwide, or mobile. -// @todo: simplify this selector. -@include break-small() { - .block-editor-block-list__block:not([data-align="wide"]):not([data-align="full"]) .editor-block-mover:not(.is-horizontal) { - margin-top: 0; - } -} - -// Mover icon buttons. -.block-editor-block-mover__control { - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - padding: 0; - border: none; - box-shadow: none; - - // Carefully adjust the size of the side UI to fit one paragraph of text (56px). - width: $block-side-ui-width; - height: $icon-button-size-small; - - svg { - width: $block-side-ui-width; - height: $icon-button-size-small; - padding: #{ ($block-side-ui-width - $icon-button-size-small) / 2 } #{ ($block-side-ui-width - 18px) / 2 }; // This makes the SVG fill the whole available area, without scaling the artwork. - } - - &[aria-disabled="true"] { - cursor: default; - pointer-events: none; - color: $dark-opacity-300; - } - - @include break-small() { - color: $dark-opacity-300; - - &:not(:disabled):not([aria-disabled="true"]):not(.is-default):hover { - background-color: transparent; - box-shadow: none; - } - - &:focus:not(:disabled) { - background-color: transparent; - } - } - -} - .block-editor-block-mover__control-drag-handle { cursor: move; // Fallback for IE/Edge < 14 cursor: grab; diff --git a/packages/block-editor/src/components/block-switcher/multi-blocks-switcher.js b/packages/block-editor/src/components/block-switcher/multi-blocks-switcher.js deleted file mode 100644 index 8adae420dab998..00000000000000 --- a/packages/block-editor/src/components/block-switcher/multi-blocks-switcher.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * WordPress dependencies - */ -import { withSelect } from '@wordpress/data'; - -/** - * Internal dependencies - */ -import BlockSwitcher from './'; - -export function MultiBlocksSwitcher( { isMultiBlockSelection, selectedBlockClientIds } ) { - if ( ! isMultiBlockSelection ) { - return null; - } - return ( - - ); -} - -export default withSelect( - ( select ) => { - const selectedBlockClientIds = select( 'core/block-editor' ).getMultiSelectedBlockClientIds(); - return { - isMultiBlockSelection: selectedBlockClientIds.length > 1, - selectedBlockClientIds, - }; - } -)( MultiBlocksSwitcher ); diff --git a/packages/block-editor/src/components/block-toolbar/index.js b/packages/block-editor/src/components/block-toolbar/index.js index 83edd7814a0ed2..4aa39c53642708 100644 --- a/packages/block-editor/src/components/block-toolbar/index.js +++ b/packages/block-editor/src/components/block-toolbar/index.js @@ -1,56 +1,54 @@ /** * WordPress dependencies */ -import { withSelect } from '@wordpress/data'; +import { useSelect } from '@wordpress/data'; /** * Internal dependencies */ +import BlockMover from '../block-mover'; import BlockSwitcher from '../block-switcher'; -import MultiBlocksSwitcher from '../block-switcher/multi-blocks-switcher'; import BlockControls from '../block-controls'; import BlockFormatControls from '../block-format-controls'; import BlockSettingsMenu from '../block-settings-menu'; -function BlockToolbar( { blockClientIds, isValid, mode } ) { - if ( blockClientIds.length === 0 ) { - return null; - } +function BlockToolbar( { moverDirection } ) { + const { blockIds, isValid, mode } = useSelect( ( select ) => { + const { + getBlockMode, + getSelectedBlockClientIds, + isBlockValid, + } = select( 'core/block-editor' ); + const blockClientIds = getSelectedBlockClientIds(); + return { + blockIds: blockClientIds, + isValid: blockClientIds.length === 1 ? isBlockValid( blockClientIds[ 0 ] ) : null, + mode: blockClientIds.length === 1 ? getBlockMode( blockClientIds[ 0 ] ) : null, + }; + } ); - if ( blockClientIds.length > 1 ) { - return ( -
- - -
- ); + if ( blockIds.length === 0 ) { + return null; } + const shouldShowVisualToolbar = isValid && mode === 'visual'; + const isMultiToolbar = blockIds.length > 1; return (
- { mode === 'visual' && isValid && ( + + { ( shouldShowVisualToolbar || isMultiToolbar ) && } + { shouldShowVisualToolbar && ! isMultiToolbar && ( <> - ) } - +
); } -export default withSelect( ( select ) => { - const { - getBlockMode, - getSelectedBlockClientIds, - isBlockValid, - } = select( 'core/block-editor' ); - const blockClientIds = getSelectedBlockClientIds(); - - return { - blockClientIds, - isValid: blockClientIds.length === 1 ? isBlockValid( blockClientIds[ 0 ] ) : null, - mode: blockClientIds.length === 1 ? getBlockMode( blockClientIds[ 0 ] ) : null, - }; -} )( BlockToolbar ); +export default BlockToolbar; diff --git a/packages/block-editor/src/components/index.js b/packages/block-editor/src/components/index.js index c7792608518acd..2073d08d9cb3b0 100644 --- a/packages/block-editor/src/components/index.js +++ b/packages/block-editor/src/components/index.js @@ -63,7 +63,6 @@ export { default as BlockToolbar } from './block-toolbar'; export { default as CopyHandler } from './copy-handler'; export { default as DefaultBlockAppender } from './default-block-appender'; export { default as Inserter } from './inserter'; -export { default as MultiBlocksSwitcher } from './block-switcher/multi-blocks-switcher'; export { default as MultiSelectScrollIntoView } from './multi-select-scroll-into-view'; export { default as NavigableToolbar } from './navigable-toolbar'; export { default as ObserveTyping } from './observe-typing'; diff --git a/packages/block-editor/src/store/actions.js b/packages/block-editor/src/store/actions.js index a7956c70e0d216..18b54cf22573bd 100644 --- a/packages/block-editor/src/store/actions.js +++ b/packages/block-editor/src/store/actions.js @@ -652,6 +652,28 @@ export function stopTyping() { }; } +/** + * Returns an action object used in signalling that the user has begun to drag blocks. + * + * @return {Object} Action object. + */ +export function startDraggingBlocks() { + return { + type: 'START_DRAGGING_BLOCKS', + }; +} + +/** + * Returns an action object used in signalling that the user has stopped dragging blocks. + * + * @return {Object} Action object. + */ +export function stopDraggingBlocks() { + return { + type: 'STOP_DRAGGING_BLOCKS', + }; +} + /** * Returns an action object used in signalling that the caret has entered formatted text. * diff --git a/packages/block-editor/src/store/reducer.js b/packages/block-editor/src/store/reducer.js index ac663d977e42b9..c84ae07612e665 100644 --- a/packages/block-editor/src/store/reducer.js +++ b/packages/block-editor/src/store/reducer.js @@ -902,6 +902,26 @@ export function isTyping( state = false, action ) { return state; } +/** + * Reducer returning dragging state. + * + * @param {boolean} state Current state. + * @param {Object} action Dispatched action. + * + * @return {boolean} Updated state. + */ +export function isDraggingBlocks( state = false, action ) { + switch ( action.type ) { + case 'START_DRAGGING_BLOCKS': + return true; + + case 'STOP_DRAGGING_BLOCKS': + return false; + } + + return state; +} + /** * Reducer returning whether the caret is within formatted text. * @@ -1329,6 +1349,7 @@ export function automaticChangeStatus( state, action ) { export default combineReducers( { blocks, isTyping, + isDraggingBlocks, isCaretWithinFormattedText, selectionStart, selectionEnd, diff --git a/packages/block-editor/src/store/selectors.js b/packages/block-editor/src/store/selectors.js index d2a009b59c6399..49a6affeadc2bc 100644 --- a/packages/block-editor/src/store/selectors.js +++ b/packages/block-editor/src/store/selectors.js @@ -927,6 +927,17 @@ export function isTyping( state ) { return state.isTyping; } +/** + * Returns true if the user is dragging blocks, or false otherwise. + * + * @param {Object} state Global application state. + * + * @return {boolean} Whether user is dragging blocks. + */ +export function isDraggingBlocks( state ) { + return state.isDraggingBlocks; +} + /** * Returns true if the caret is within formatted text, or false otherwise. *