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(); + } ); +} );