Skip to content

Commit

Permalink
Extract block mover buttons so that they can be individually imported (
Browse files Browse the repository at this point in the history
…#22122)

* Extract block mover buttons so that they can be individually imported

* Name buttons in a consistent way
  • Loading branch information
talldan authored May 7, 2020
1 parent 969a928 commit d433129
Show file tree
Hide file tree
Showing 3 changed files with 220 additions and 137 deletions.
174 changes: 174 additions & 0 deletions packages/block-editor/src/components/block-mover/button.js
Original file line number Diff line number Diff line change
@@ -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 (
<>
<Button
ref={ ref }
className={ classnames(
'block-editor-block-mover-button',
`is-${ direction }-button`
) }
icon={ getArrowIcon( direction, moverOrientation, isRTL ) }
label={ getMovementDirectionLabel(
direction,
moverOrientation,
isRTL
) }
aria-describedby={ descriptionId }
onClick={ onClick }
aria-disabled={ isDisabled }
{ ...props }
/>
<span
id={ descriptionId }
className="block-editor-block-mover-button__description"
>
{ getBlockMoverDescription(
blocksCount,
blockType && blockType.title,
firstIndex,
isFirst,
isLast,
direction === 'up' ? -1 : 1,
moverOrientation,
isRTL
) }
</span>
</>
);
}
);

export const BlockMoverUpButton = forwardRef( ( props, ref ) => {
return <BlockMoverButton direction="up" ref={ ref } { ...props } />;
} );

export const BlockMoverDownButton = forwardRef( ( props, ref ) => {
return <BlockMoverButton direction="down" ref={ ref } { ...props } />;
} );
167 changes: 38 additions & 129 deletions packages/block-editor/src/components/block-mover/index.js
Original file line number Diff line number Diff line change
@@ -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() {
Expand All @@ -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,
Expand All @@ -114,57 +73,16 @@ export class BlockMover extends Component {
onDragEnd={ onDraggableEnd }
>
<ToolbarGroup>
<Button
className="block-editor-block-mover__control block-editor-block-mover__control-up"
onClick={ isFirst ? null : onMoveUp }
icon={ getArrowIcon( 'up' ) }
label={ getMovementDirectionLabel( 'up' ) }
aria-describedby={ `block-editor-block-mover__up-description-${ instanceId }` }
aria-disabled={ isFirst }
<BlockMoverUpButton
clientIds={ clientIds }
onFocus={ this.onFocus }
onBlur={ this.onBlur }
/>

<Button
className="block-editor-block-mover__control block-editor-block-mover__control-down"
onClick={ isLast ? null : onMoveDown }
icon={ getArrowIcon( 'down' ) }
label={ getMovementDirectionLabel( 'down' ) }
aria-describedby={ `block-editor-block-mover__down-description-${ instanceId }` }
aria-disabled={ isLast }
<BlockMoverDownButton
clientIds={ clientIds }
onFocus={ this.onFocus }
onBlur={ this.onBlur }
/>
<span
id={ `block-editor-block-mover__up-description-${ instanceId }` }
className="block-editor-block-mover__description"
>
{ getBlockMoverDescription(
blocksCount,
blockType && blockType.title,
firstIndex,
isFirst,
isLast,
-1,
orientation,
isRTL
) }
</span>
<span
id={ `block-editor-block-mover__down-description-${ instanceId }` }
className="block-editor-block-mover__description"
>
{ getBlockMoverDescription(
blocksCount,
blockType && blockType.title,
firstIndex,
isFirst,
isLast,
1,
orientation,
isRTL
) }
</span>
</ToolbarGroup>
</div>
) }
Expand All @@ -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 );
Loading

0 comments on commit d433129

Please sign in to comment.