Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RNMobile] Allow dragging from block toolbar #40886

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,20 @@ const BlockDraggableWrapper = ( { children } ) => {
* This component serves for animating the block when it is being dragged.
* Hence, it should be wrapped around the rendering of a block.
*
* @param {Object} props Component props.
* @param {JSX.Element} props.children Children to be rendered.
* @param {string[]} props.clientId Client id of the block.
* @param {boolean} [props.enabled] Enables the draggable trigger.
* @param {Object} props Component props.
* @param {JSX.Element} props.children Children to be rendered.
* @param {string} props.clientId Client id of the block.
* @param {string} [props.draggingClientId] Client id to use for dragging. If not defined, the value from `clientId` will be used.
* @param {boolean} [props.enabled] Enables the draggable trigger.
*
* @return {Function} Render function which includes the parameter `isDraggable` to determine if the block can be dragged.
*/
const BlockDraggable = ( { clientId, children, enabled = true } ) => {
const BlockDraggable = ( {
clientId,
children,
draggingClientId,
enabled = true,
} ) => {
const wasBeingDragged = useRef( false );
const [ isEditingText, setIsEditingText ] = useState( false );

Expand Down Expand Up @@ -289,7 +295,6 @@ const BlockDraggable = ( { clientId, children, enabled = true } ) => {
getTemplateLock,
isBlockBeingDragged,
getSelectedBlockClientId,
hasSelectedInnerBlock,
} = _select( blockEditorStore );
const rootClientId = getBlockRootClientId( clientId );
const templateLock = rootClientId
Expand All @@ -301,9 +306,7 @@ const BlockDraggable = ( { clientId, children, enabled = true } ) => {
isBeingDragged: isBlockBeingDragged( clientId ),
isDraggable: 'all' !== templateLock,
isBlockSelected:
selectedBlockClientId &&
( selectedBlockClientId === clientId ||
hasSelectedInnerBlock( clientId, true ) ),
selectedBlockClientId && selectedBlockClientId === clientId,
};
},
[ clientId ]
Expand Down Expand Up @@ -361,7 +364,7 @@ const BlockDraggable = ( { clientId, children, enabled = true } ) => {

return (
<DraggableTrigger
id={ clientId }
id={ draggingClientId || clientId }
enabled={ enabled && canDragBlock }
minDuration={ Platform.select( {
// On iOS, using a lower min duration than the default
Expand Down
24 changes: 21 additions & 3 deletions packages/block-editor/src/components/block-list/block.native.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ class BlockListBlock extends Component {
marginHorizontal,
isInnerBlockSelected,
name,
rootClientId,
draggingEnabled,
draggingClientId,
} = this.props;

if ( ! attributes || ! blockType ) {
Expand All @@ -209,7 +210,6 @@ class BlockListBlock extends Component {
const isScreenWidthEqual = blockWidth === screenWidth;
const isScreenWidthWider = blockWidth < screenWidth;
const isFullWidthToolbar = isFullWidth( align ) || isScreenWidthEqual;
const hasParent = !! rootClientId;

return (
<TouchableWithoutFeedback
Expand Down Expand Up @@ -260,8 +260,9 @@ class BlockListBlock extends Component {
/>
) }
<BlockDraggable
enabled={ ! hasParent }
clientId={ clientId }
draggingClientId={ draggingClientId }
enabled={ draggingEnabled }
>
{ () =>
isValid ? (
Expand All @@ -288,6 +289,7 @@ class BlockListBlock extends Component {
blockWidth={ blockWidth }
anchorNodeRef={ this.anchorNodeRef.current }
isFullWidth={ isFullWidthToolbar }
draggingClientId={ draggingClientId }
/>
) }
</View>
Expand Down Expand Up @@ -318,13 +320,15 @@ export default compose( [
withSelect( ( select, { clientId } ) => {
const {
getBlockIndex,
getBlockCount,
getSettings,
isBlockSelected,
getBlock,
getSelectedBlockClientId,
getLowestCommonAncestorWithSelectedBlock,
getBlockParents,
hasSelectedInnerBlock,
getBlockHierarchyRootClientId,
} = select( blockEditorStore );

const order = getBlockIndex( clientId );
Expand Down Expand Up @@ -369,13 +373,27 @@ export default compose( [
const baseGlobalStyles = getSettings()
?.__experimentalGlobalStylesBaseStyles;

const hasInnerBlocks = getBlockCount( clientId ) > 0;
// For blocks with inner blocks, we only enable the dragging in the nested
// blocks if any of them are selected. This way we prevent the long-press
// gesture from being disabled for elements within the block UI.
const draggingEnabled =
! hasInnerBlocks ||
isSelected ||
! hasSelectedInnerBlock( clientId, true );
// Dragging nested blocks is not supported yet. For this reason, the block to be dragged
// will be the top in the hierarchy.
const draggingClientId = getBlockHierarchyRootClientId( clientId );

return {
icon,
name: name || 'core/missing',
order,
title,
attributes,
blockType,
draggingClientId,
draggingEnabled,
isSelected,
isInnerBlockSelected,
isValid,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { useState, useEffect } from '@wordpress/element';
*/
import styles from './style.scss';
import BlockMover from '../block-mover';
import BlockDraggable from '../block-draggable';
import BlockActionsMenu from './block-actions-menu';
import { BlockSettingsButton } from '../block-settings';
import { store as blockEditorStore } from '../../store';
Expand All @@ -33,6 +34,7 @@ const BlockMobileToolbar = ( {
blockWidth,
anchorNodeRef,
isFullWidth,
draggingClientId,
} ) => {
const [ fillsLength, setFillsLength ] = useState( null );
const [ appenderWidth, setAppenderWidth ] = useState( 0 );
Expand Down Expand Up @@ -73,7 +75,12 @@ const BlockMobileToolbar = ( {
/>
) }

<View style={ styles.spacer } />
<BlockDraggable
clientId={ clientId }
draggingClientId={ draggingClientId }
>
{ () => <View style={ styles.spacer } /> }
geriux marked this conversation as resolved.
Show resolved Hide resolved
</BlockDraggable>

<BlockSettingsButton.Slot>
{ /* Render only one settings icon even if we have more than one fill - need for hooks with controls. */ }
Expand Down