Skip to content

Commit

Permalink
Add move to top bottom when long pressing block movers (#27554)
Browse files Browse the repository at this point in the history
* WC: Added move to top and bottom functionality via long pressing BlockMover buttons and clicking the button on the BottomSheet Picker.

* WIP: Unit tests.

* WC: WIP unit tests for add move to top and bottom

* WC: Moving UI tests to gutenberg with other UI tests instead of keeping at gutenberg-mobile. Adding more convenience functions to EditorPage.

* WIP: Unit tests.

* WC: Adding icon and title to picker for move to top/bottom.

* WC: Cleaning up code.

* WC: Fixing merge issue where import was changed to const.

* WC: Changing all imports to requires as per jest bug.

* WC: Removing before/afterAll blocks from UI tests.

* WC: Removing e2e tests to issue-1191-add-move-to-top-bottom-ui-tests branch.

* WC: Updating imports to fall in line with other files.

Co-authored-by: Wendy Chen <[email protected]>
  • Loading branch information
illusaen and Wendy Chen authored Dec 23, 2020
1 parent db9da4a commit 7f7910f
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 4 deletions.
78 changes: 74 additions & 4 deletions packages/block-editor/src/components/block-mover/index.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
}
Expand All @@ -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 } }
/>
Expand All @@ -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,
} }
/>

<Picker
ref={ pickerRef }
options={ blockPageMoverOptions }
onChange={ onPickerSelect }
title={ __( 'Move block position' ) }
leftAlign={ true }
hideCancelButton={ Platform.OS !== 'ios' }
/>
</>
);
};
Expand All @@ -83,19 +145,27 @@ export default compose(

return {
firstIndex,
numberOfBlocks: blockOrder.length - 1,
isFirst: firstIndex === 0,
isLast: lastIndex === blockOrder.length - 1,
isLocked: getTemplateLock( rootClientId ) === 'all',
rootClientId,
};
} ),
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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Block Mover Picker should match snapshot 1`] = `
<Fragment>
<ForwardRef(ToolbarButton)
extraProps={
Object {
"hint": "Double tap to move the block up",
}
}
icon={
<SVG
viewBox="-2 -2 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<Path
d="M11 18H9V6l-4 4-2-1 7-7 7 7-2 1-4-4v12z"
/>
</SVG>
}
onLongPress={[Function]}
title="Move block up from row NaN to row NaN"
/>
<ForwardRef(ToolbarButton)
extraProps={
Object {
"hint": "Double tap to move the block down",
}
}
icon={
<SVG
viewBox="-2 -2 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<Path
d="M9 2h2v12l4-4 2 1-7 7-7-7 2-1 4 4V2z"
/>
</SVG>
}
onLongPress={[Function]}
title="Move block down from row NaN to row NaN"
/>
<Picker
hideCancelButton={true}
leftAlign={true}
onChange={[Function]}
options={Array []}
title="Move block position"
/>
</Fragment>
`;
Original file line number Diff line number Diff line change
@@ -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( <BlockMover />, {
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( <BlockMover />, {
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();
} );
} );

0 comments on commit 7f7910f

Please sign in to comment.