diff --git a/packages/block-editor/src/components/block-mover/index.native.js b/packages/block-editor/src/components/block-mover/index.native.js
index aa1892c33e8042..d64509ff17726e 100644
--- a/packages/block-editor/src/components/block-mover/index.native.js
+++ b/packages/block-editor/src/components/block-mover/index.native.js
@@ -2,29 +2,52 @@
* External dependencies
*/
import { first, last, partial, castArray } from 'lodash';
+import { Platform } from 'react-native';
/**
* WordPress dependencies
*/
-import { ToolbarButton } from '@wordpress/components';
-import { withSelect, withDispatch } from '@wordpress/data';
+import { __ } from '@wordpress/i18n';
+import { Picker, ToolbarButton } from '@wordpress/components';
import { withInstanceId, compose } from '@wordpress/compose';
+import { withSelect, withDispatch } from '@wordpress/data';
+import { useRef, useState } from '@wordpress/element';
/**
* Internal dependencies
*/
import { getMoversSetup } from './mover-description';
-const BlockMover = ( {
+export const BLOCK_MOVER_DIRECTION_TOP = 'blockPageMoverOptions-moveToTop';
+export const BLOCK_MOVER_DIRECTION_BOTTOM =
+ 'blockPageMoverOptions-moveToBottom';
+
+export const BlockMover = ( {
isFirst,
isLast,
isLocked,
onMoveDown,
onMoveUp,
+ onLongMove,
firstIndex,
+ numberOfBlocks,
rootClientId,
isStackedHorizontally,
} ) => {
+ const pickerRef = useRef();
+ const [ blockPageMoverState, setBlockPageMoverState ] = useState(
+ undefined
+ );
+ const showBlockPageMover = ( direction ) => () => {
+ if ( ! pickerRef.current ) {
+ setBlockPageMoverState( undefined );
+ return;
+ }
+
+ setBlockPageMoverState( direction );
+ pickerRef.current.presentPicker();
+ };
+
const {
description: {
backwardButtonHint,
@@ -36,6 +59,32 @@ const BlockMover = ( {
title: { backward: backwardButtonTitle, forward: forwardButtonTitle },
} = getMoversSetup( isStackedHorizontally, { firstIndex } );
+ const blockPageMoverOptions = [
+ {
+ icon: backwardButtonIcon,
+ label: __( 'Move to top' ),
+ value: BLOCK_MOVER_DIRECTION_TOP,
+ onSelect: () => {
+ onLongMove()( 0 );
+ },
+ },
+ {
+ icon: forwardButtonIcon,
+ label: __( 'Move to bottom' ),
+ value: BLOCK_MOVER_DIRECTION_BOTTOM,
+ onSelect: () => {
+ onLongMove()( numberOfBlocks );
+ },
+ },
+ ].filter( ( el ) => el.value === blockPageMoverState );
+
+ const onPickerSelect = ( value ) => {
+ const option = blockPageMoverOptions.find(
+ ( el ) => el.value === value
+ );
+ if ( option && option.onSelect ) option.onSelect();
+ };
+
if ( isLocked || ( isFirst && isLast && ! rootClientId ) ) {
return null;
}
@@ -46,6 +95,7 @@ const BlockMover = ( {
title={ ! isFirst ? backwardButtonTitle : firstBlockTitle }
isDisabled={ isFirst }
onClick={ onMoveUp }
+ onLongPress={ showBlockPageMover( BLOCK_MOVER_DIRECTION_TOP ) }
icon={ backwardButtonIcon }
extraProps={ { hint: backwardButtonHint } }
/>
@@ -54,11 +104,23 @@ const BlockMover = ( {
title={ ! isLast ? forwardButtonTitle : lastBlockTitle }
isDisabled={ isLast }
onClick={ onMoveDown }
+ onLongPress={ showBlockPageMover(
+ BLOCK_MOVER_DIRECTION_BOTTOM
+ ) }
icon={ forwardButtonIcon }
extraProps={ {
hint: forwardButtonHint,
} }
/>
+
+
>
);
};
@@ -83,6 +145,7 @@ export default compose(
return {
firstIndex,
+ numberOfBlocks: blockOrder.length - 1,
isFirst: firstIndex === 0,
isLast: lastIndex === blockOrder.length - 1,
isLocked: getTemplateLock( rootClientId ) === 'all',
@@ -90,12 +153,19 @@ export default compose(
};
} ),
withDispatch( ( dispatch, { clientIds, rootClientId } ) => {
- const { moveBlocksDown, moveBlocksUp } = dispatch(
+ const { moveBlocksDown, moveBlocksUp, moveBlocksToPosition } = dispatch(
'core/block-editor'
);
return {
onMoveDown: partial( moveBlocksDown, clientIds, rootClientId ),
onMoveUp: partial( moveBlocksUp, clientIds, rootClientId ),
+ onLongMove: ( targetIndex ) =>
+ partial(
+ moveBlocksToPosition,
+ clientIds,
+ rootClientId,
+ targetIndex
+ ),
};
} ),
withInstanceId
diff --git a/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap b/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap
new file mode 100644
index 00000000000000..65269234f413f3
--- /dev/null
+++ b/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap
@@ -0,0 +1,51 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Block Mover Picker should match snapshot 1`] = `
+
+
+
+
+ }
+ onLongPress={[Function]}
+ title="Move block up from row NaN to row NaN"
+ />
+
+
+
+ }
+ onLongPress={[Function]}
+ title="Move block down from row NaN to row NaN"
+ />
+
+
+`;
diff --git a/packages/block-editor/src/components/block-mover/test/index.native.js b/packages/block-editor/src/components/block-mover/test/index.native.js
new file mode 100644
index 00000000000000..113d61e84cf254
--- /dev/null
+++ b/packages/block-editor/src/components/block-mover/test/index.native.js
@@ -0,0 +1,51 @@
+/**
+ * External dependencies
+ */
+import { shallow } from 'enzyme';
+
+/**
+ * Internal dependencies
+ */
+import { BlockMover } from '../index';
+
+describe( 'Block Mover Picker', () => {
+ it( 'renders without crashing', () => {
+ const wrapper = shallow( , {
+ context: {
+ isFirst: false,
+ isLast: true,
+ isLocked: false,
+ numberOfBlocks: 2,
+ firstIndex: 1,
+
+ onMoveDown: jest.fn(),
+ onMoveUp: jest.fn(),
+ onLongPress: jest.fn(),
+
+ rootClientId: '',
+ isStackedHorizontally: true,
+ },
+ } );
+ expect( wrapper ).toBeTruthy();
+ } );
+
+ it( 'should match snapshot', () => {
+ const wrapper = shallow( , {
+ context: {
+ isFirst: false,
+ isLast: true,
+ isLocked: false,
+ numberOfBlocks: 2,
+ firstIndex: 1,
+
+ onMoveDown: jest.fn(),
+ onMoveUp: jest.fn(),
+ onLongPress: jest.fn(),
+
+ rootClientId: '',
+ isStackedHorizontally: true,
+ },
+ } );
+ expect( wrapper ).toMatchSnapshot();
+ } );
+} );