diff --git a/packages/block-editor/src/components/block-mover/button.js b/packages/block-editor/src/components/block-mover/button.js
new file mode 100644
index 00000000000000..5015caf62d408c
--- /dev/null
+++ b/packages/block-editor/src/components/block-mover/button.js
@@ -0,0 +1,174 @@
+/**
+ * External dependencies
+ */
+import classnames from 'classnames';
+import { castArray, first, last, partial } from 'lodash';
+
+/**
+ * WordPress dependencies
+ */
+import { getBlockType } from '@wordpress/blocks';
+import { Button } from '@wordpress/components';
+import { useInstanceId } from '@wordpress/compose';
+import { useSelect, useDispatch } from '@wordpress/data';
+import { forwardRef } from '@wordpress/element';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies
+ */
+import { leftArrow, rightArrow } from './icons';
+import { chevronUp, chevronDown } from '@wordpress/icons';
+import { getBlockMoverDescription } from './mover-description';
+
+const getArrowIcon = ( direction, orientation, isRTL ) => {
+ if ( direction === 'up' ) {
+ if ( orientation === 'horizontal' ) {
+ return isRTL ? rightArrow : leftArrow;
+ }
+ return chevronUp;
+ } else if ( direction === 'down' ) {
+ if ( orientation === 'horizontal' ) {
+ return isRTL ? leftArrow : rightArrow;
+ }
+ return chevronDown;
+ }
+ return null;
+};
+
+const getMovementDirectionLabel = ( moveDirection, orientation, isRTL ) => {
+ if ( moveDirection === 'up' ) {
+ if ( orientation === 'horizontal' ) {
+ return isRTL ? __( 'Move right' ) : __( 'Move left' );
+ }
+ return __( 'Move up' );
+ } else if ( moveDirection === 'down' ) {
+ if ( orientation === 'horizontal' ) {
+ return isRTL ? __( 'Move left' ) : __( 'Move right' );
+ }
+ return __( 'Move down' );
+ }
+ return null;
+};
+
+const BlockMoverButton = forwardRef(
+ (
+ {
+ clientIds,
+ direction,
+ __experimentalOrientation: orientation,
+ ...props
+ },
+ ref
+ ) => {
+ const instanceId = useInstanceId( BlockMoverButton );
+ const blocksCount = castArray( clientIds ).length;
+
+ const {
+ blockType,
+ isDisabled,
+ rootClientId,
+ isFirst,
+ isLast,
+ firstIndex,
+ isRTL,
+ moverOrientation,
+ } = useSelect(
+ ( select ) => {
+ const {
+ getBlockIndex,
+ getBlockRootClientId,
+ getBlockOrder,
+ getBlock,
+ getSettings,
+ getBlockListSettings,
+ } = select( 'core/block-editor' );
+ const normalizedClientIds = castArray( clientIds );
+ const firstClientId = first( normalizedClientIds );
+ const blockRootClientId = getBlockRootClientId( firstClientId );
+ const firstBlockIndex = getBlockIndex(
+ firstClientId,
+ blockRootClientId
+ );
+ const lastBlockIndex = getBlockIndex(
+ last( normalizedClientIds ),
+ blockRootClientId
+ );
+ const blockOrder = getBlockOrder( blockRootClientId );
+ const block = getBlock( firstClientId );
+ const isFirstBlock = firstBlockIndex === 0;
+ const isLastBlock = lastBlockIndex === blockOrder.length - 1;
+ const { __experimentalMoverDirection = 'vertical' } =
+ getBlockListSettings( blockRootClientId ) || {};
+
+ return {
+ blockType: block ? getBlockType( block.name ) : null,
+ isDisabled: direction === 'up' ? isFirstBlock : isLastBlock,
+ rootClientId: blockRootClientId,
+ firstIndex: firstBlockIndex,
+ isFirst: isFirstBlock,
+ isLast: isLastBlock,
+ isRTL: getSettings().isRTL,
+ moverOrientation:
+ orientation || __experimentalMoverDirection,
+ };
+ },
+ [ clientIds, direction ]
+ );
+
+ const { moveBlocksDown, moveBlocksUp } = useDispatch(
+ 'core/block-editor'
+ );
+ const moverFunction =
+ direction === 'up' ? moveBlocksUp : moveBlocksDown;
+ const onClick = isDisabled
+ ? null
+ : partial( moverFunction, clientIds, rootClientId );
+ const descriptionId = `block-editor-block-mover-button__description-${ instanceId }`;
+
+ return (
+ <>
+
+
+ { getBlockMoverDescription(
+ blocksCount,
+ blockType && blockType.title,
+ firstIndex,
+ isFirst,
+ isLast,
+ direction === 'up' ? -1 : 1,
+ moverOrientation,
+ isRTL
+ ) }
+
+ >
+ );
+ }
+);
+
+export const BlockMoverUpButton = forwardRef( ( props, ref ) => {
+ return ;
+} );
+
+export const BlockMoverDownButton = forwardRef( ( props, ref ) => {
+ return ;
+} );
diff --git a/packages/block-editor/src/components/block-mover/index.js b/packages/block-editor/src/components/block-mover/index.js
index 71c35561e90aa2..b7dff01d926593 100644
--- a/packages/block-editor/src/components/block-mover/index.js
+++ b/packages/block-editor/src/components/block-mover/index.js
@@ -1,26 +1,22 @@
/**
* External dependencies
*/
-import { first, last, partial } from 'lodash';
+import { first, last, castArray } from 'lodash';
import classnames from 'classnames';
/**
* WordPress dependencies
*/
-import { __ } from '@wordpress/i18n';
-import { Button, ToolbarGroup } from '@wordpress/components';
+import { ToolbarGroup } from '@wordpress/components';
import { getBlockType } from '@wordpress/blocks';
import { Component } from '@wordpress/element';
-import { withSelect, withDispatch } from '@wordpress/data';
-import { withInstanceId, compose } from '@wordpress/compose';
+import { withSelect } from '@wordpress/data';
/**
* Internal dependencies
*/
-import { getBlockMoverDescription } from './mover-description';
-import { leftArrow, rightArrow } from './icons';
-import { chevronUp, chevronDown } from '@wordpress/icons';
import BlockDraggable from '../block-draggable';
+import { BlockMoverUpButton, BlockMoverDownButton } from './button';
export class BlockMover extends Component {
constructor() {
@@ -46,57 +42,20 @@ export class BlockMover extends Component {
render() {
const {
- onMoveUp,
- onMoveDown,
- __experimentalOrientation: orientation,
- isRTL,
isFirst,
isLast,
clientIds,
- blockType,
- firstIndex,
isLocked,
- instanceId,
isHidden,
rootClientId,
hideDragHandle,
+ __experimentalOrientation: orientation,
} = this.props;
const { isFocused } = this.state;
- const blocksCount = clientIds.length;
if ( isLocked || ( isFirst && isLast && ! rootClientId ) ) {
return null;
}
- const getArrowIcon = ( moveDirection ) => {
- if ( moveDirection === 'up' ) {
- if ( orientation === 'horizontal' ) {
- return isRTL ? rightArrow : leftArrow;
- }
- return chevronUp;
- } else if ( moveDirection === 'down' ) {
- if ( orientation === 'horizontal' ) {
- return isRTL ? leftArrow : rightArrow;
- }
- return chevronDown;
- }
- return null;
- };
-
- const getMovementDirectionLabel = ( moveDirection ) => {
- if ( moveDirection === 'up' ) {
- if ( orientation === 'horizontal' ) {
- return isRTL ? __( 'Move right' ) : __( 'Move left' );
- }
- return __( 'Move up' );
- } else if ( moveDirection === 'down' ) {
- if ( orientation === 'horizontal' ) {
- return isRTL ? __( 'Move left' ) : __( 'Move right' );
- }
- return __( 'Move down' );
- }
- return null;
- };
-
// We emulate a disabled state because forcefully applying the `disabled`
// attribute on the buttons while it has focus causes the screen to change
// to an unfocused state (body as active element) without firing blur on,
@@ -114,57 +73,16 @@ export class BlockMover extends Component {
onDragEnd={ onDraggableEnd }
>
-
-
-
-
- { getBlockMoverDescription(
- blocksCount,
- blockType && blockType.title,
- firstIndex,
- isFirst,
- isLast,
- -1,
- orientation,
- isRTL
- ) }
-
-
- { getBlockMoverDescription(
- blocksCount,
- blockType && blockType.title,
- firstIndex,
- isFirst,
- isLast,
- 1,
- orientation,
- isRTL
- ) }
-
) }
@@ -173,42 +91,33 @@ export class BlockMover extends Component {
}
}
-export default compose(
- withSelect( ( select, { clientIds } ) => {
- const {
- getBlock,
- getBlockIndex,
- getTemplateLock,
- getBlockRootClientId,
- getBlockOrder,
- } = select( 'core/block-editor' );
- const firstClientId = first( clientIds );
- const block = getBlock( firstClientId );
- const rootClientId = getBlockRootClientId( first( clientIds ) );
- const blockOrder = getBlockOrder( rootClientId );
- const firstIndex = getBlockIndex( firstClientId, rootClientId );
- const lastIndex = getBlockIndex( last( clientIds ), rootClientId );
- const { getSettings } = select( 'core/block-editor' );
- const { isRTL } = getSettings();
+export default withSelect( ( select, { clientIds } ) => {
+ const {
+ getBlock,
+ getBlockIndex,
+ getTemplateLock,
+ getBlockOrder,
+ getBlockRootClientId,
+ } = select( 'core/block-editor' );
+ const normalizedClientIds = castArray( clientIds );
+ const firstClientId = first( normalizedClientIds );
+ const block = getBlock( firstClientId );
+ const rootClientId = getBlockRootClientId( first( normalizedClientIds ) );
+ const firstIndex = getBlockIndex( firstClientId, rootClientId );
+ const lastIndex = getBlockIndex(
+ last( normalizedClientIds ),
+ rootClientId
+ );
+ const blockOrder = getBlockOrder( rootClientId );
+ const isFirst = firstIndex === 0;
+ const isLast = lastIndex === blockOrder.length - 1;
- return {
- blockType: block ? getBlockType( block.name ) : null,
- isLocked: getTemplateLock( rootClientId ) === 'all',
- rootClientId,
- firstIndex,
- isRTL,
- isFirst: firstIndex === 0,
- isLast: lastIndex === blockOrder.length - 1,
- };
- } ),
- withDispatch( ( dispatch, { clientIds, rootClientId } ) => {
- const { moveBlocksDown, moveBlocksUp } = dispatch(
- 'core/block-editor'
- );
- return {
- onMoveDown: partial( moveBlocksDown, clientIds, rootClientId ),
- onMoveUp: partial( moveBlocksUp, clientIds, rootClientId ),
- };
- } ),
- withInstanceId
-)( BlockMover );
+ return {
+ blockType: block ? getBlockType( block.name ) : null,
+ isLocked: getTemplateLock( rootClientId ) === 'all',
+ rootClientId,
+ firstIndex,
+ isFirst,
+ isLast,
+ };
+} )( BlockMover );
diff --git a/packages/block-editor/src/components/block-mover/style.scss b/packages/block-editor/src/components/block-mover/style.scss
index e60bbcaacdb902..52cbcd2f0cf8fb 100644
--- a/packages/block-editor/src/components/block-mover/style.scss
+++ b/packages/block-editor/src/components/block-mover/style.scss
@@ -3,11 +3,11 @@
flex-direction: row;
}
-.block-editor-block-mover__description {
+.block-editor-block-mover-button__description {
display: none;
}
-.block-editor-block-mover__control.has-icon {
+.block-editor-block-mover-button.has-icon {
padding: 0;
}
@@ -21,12 +21,12 @@
flex-direction: row;
}
- .block-editor-block-mover__control {
+ .block-editor-block-mover-button {
height: $block-toolbar-height/2;
}
// Position the icons correctly.
- .components-toolbar .block-editor-block-mover__control-up {
+ .components-toolbar .block-editor-block-mover-button.is-up-button {
svg {
margin-bottom: -$grid-unit-10;
}
@@ -38,7 +38,7 @@
}
}
- .components-toolbar .block-editor-block-mover__control-down {
+ .components-toolbar .block-editor-block-mover-button.is-down-button {
svg {
margin-top: -$grid-unit-10;
}
@@ -52,7 +52,7 @@
// Mover is horizontal.
&.is-horizontal {
- .block-editor-block-mover__control.has-icon {
+ .block-editor-block-mover-button.has-icon {
height: $block-toolbar-height;
width: $block-toolbar-height/2 !important;
min-width: $grid-unit-30;
@@ -70,7 +70,7 @@
}
// Position the icons correctly.
- .block-editor-block-mover__control-up.has-icon {
+ .block-editor-block-mover-button.is-up-button.has-icon {
svg {
margin-left: 0;
margin-right: -$grid-unit-10;
@@ -84,7 +84,7 @@
}
}
- .block-editor-block-mover__control-down.has-icon {
+ .block-editor-block-mover-button.is-down-button.has-icon {
svg {
margin-left: -$grid-unit-10;
margin-right: 0;