Skip to content

Commit

Permalink
turn off selection hover when dragging, useCallback on a few other pa…
Browse files Browse the repository at this point in the history
…ssed functions
  • Loading branch information
gwwar committed Sep 20, 2021
1 parent c7eb9bd commit 7efb06f
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 134 deletions.
1 change: 1 addition & 0 deletions packages/block-editor/src/components/list-view/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ function ListViewBlock( {
withExperimentalPersistentListViewFeatures &&
isLastOfSelectedBranch,
'is-moving': draggingId === clientId, //avoid is-dragging which has an !important rule
'is-hovered': isHovered,
} );

const velocity = useMotionValue( 0 );
Expand Down
274 changes: 141 additions & 133 deletions packages/block-editor/src/components/list-view/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,27 +164,26 @@ function ListView(

const positionsRef = useRef( {} );
const positions = positionsRef.current;
const setPosition = ( clientId, offset ) =>
( positions[ clientId ] = offset );
const setPosition = useCallback(
( clientId, offset ) => ( positions[ clientId ] = offset ),
[ positions ]
);

// Used in dragging to specify a drop target
const lastTarget = useRef( null );

const dragStart = ( clientId ) => {
if ( ! draggingId && stateType === GLOBAL ) {
setDraggingId( clientId );
collapse( clientId );
}
};

const dragEnd = ( clientId ) => {
dropItem();
setDraggingId( null );
expand( clientId );
};
const dragStart = useCallback(
( clientId ) => {
if ( ! draggingId && stateType === GLOBAL ) {
setDraggingId( clientId );
collapse( clientId );
}
},
[ draggingId, stateType, setDraggingId, collapse ]
);

// Fired on item drop
const dropItem = async () => {
const dropItem = useCallback( async () => {
const target = lastTarget.current;
if ( ! target ) {
setStateType( GLOBAL );
Expand All @@ -203,73 +202,143 @@ function ListView(
} catch ( e ) {
setStateType( GLOBAL );
}
};
}, [ lastTarget.current, setStateType ] );

const dragEnd = useCallback(
( clientId ) => {
dropItem();
setDraggingId( null );
expand( clientId );
},
[ dropItem, setDraggingId, expand ]
);

// Note that this is fired on onViewportBoxUpdate instead of onDrag.
const moveItem = ( {
block,
translate,
translateX,
listPosition,
velocity,
} ) => {
const ITEM_HEIGHT = 36;
const LEFT_RIGHT_DRAG_THRESHOLD = 15;
const UP = 'up';
const DOWN = 'down';
const moveItem = useCallback(
( { block, translate, translateX, listPosition, velocity } ) => {
const ITEM_HEIGHT = 36;
const LEFT_RIGHT_DRAG_THRESHOLD = 15;
const UP = 'up';
const DOWN = 'down';

const { clientId } = block;
const { clientId } = block;

const v = velocity?.get() ?? 0;
if ( v === 0 ) {
return;
}
const v = velocity?.get() ?? 0;
if ( v === 0 ) {
return;
}

const direction = v > 0 ? DOWN : UP;
const direction = v > 0 ? DOWN : UP;

const draggingUpPastBounds =
positions[ listPosition + 1 ] === undefined &&
direction === UP &&
translate > 0;
const draggingDownPastBounds =
listPosition === 0 && direction === DOWN && translate < 0;
const draggingUpPastBounds =
positions[ listPosition + 1 ] === undefined &&
direction === UP &&
translate > 0;
const draggingDownPastBounds =
listPosition === 0 && direction === DOWN && translate < 0;

if ( draggingUpPastBounds || draggingDownPastBounds ) {
// If we've dragged past all items with the first or last item, don't start checking for potential swaps
// until we're near other items
return;
}
if ( draggingUpPastBounds || draggingDownPastBounds ) {
// If we've dragged past all items with the first or last item, don't start checking for potential swaps
// until we're near other items
return;
}

if (
( direction === DOWN && translate < 0 ) ||
( direction === UP && translate > 0 )
) {
//We're skipping over multiple items, wait until user catches up to the new slot
return;
}
if (
( direction === DOWN && translate < 0 ) ||
( direction === UP && translate > 0 )
) {
//We're skipping over multiple items, wait until user catches up to the new slot
return;
}

if ( Math.abs( translate ) < ITEM_HEIGHT / 2 ) {
// Don't bother calculating anything if we haven't moved half a step.
return;
}
if ( Math.abs( translate ) < ITEM_HEIGHT / 2 ) {
// Don't bother calculating anything if we haven't moved half a step.
return;
}

if ( Math.abs( translateX ) > LEFT_RIGHT_DRAG_THRESHOLD ) {
// If we move to the right or left as we drag, allow more freeform targeting
// so we can find a new parent container
const steps = Math.ceil( Math.abs( translate / ITEM_HEIGHT ) );
const nextIndex =
direction === UP ? listPosition - steps : listPosition + steps;
if ( Math.abs( translateX ) > LEFT_RIGHT_DRAG_THRESHOLD ) {
// If we move to the right or left as we drag, allow more freeform targeting
// so we can find a new parent container
const steps = Math.ceil( Math.abs( translate / ITEM_HEIGHT ) );
const nextIndex =
direction === UP
? listPosition - steps
: listPosition + steps;

const targetPosition = positions[ nextIndex ];
const targetPosition = positions[ nextIndex ];

if ( ! targetPosition ) {
return;
if ( ! targetPosition ) {
return;
}
if (
targetPosition.dropSibling &&
( translateX < 0 ||
( translateX > 0 && ! targetPosition.dropContainer ) )
) {
//Insert as a sibling
const {
newTree: treeWithoutDragItem,
removeParentId,
} = removeItemFromTree( clientIdsTree, clientId, rootId );
const { newTree, targetIndex, targetId } = addItemToTree(
treeWithoutDragItem,
targetPosition.clientId,
block,
direction === DOWN ||
( direction === UP &&
targetPosition.isLastChild &&
! targetPosition.dropContainer ),
rootId
);
lastTarget.current = {
clientId,
originalParent: removeParentId,
targetId,
targetIndex,
};
setTree( newTree );
return;
}

if (
targetPosition.dropContainer &&
( translateX > 0 ||
( translateX < 0 && ! targetPosition.dropSibling ) )
) {
//Nest block under parent
const {
newTree: treeWithoutDragItem,
removeParentId,
} = removeItemFromTree( clientIdsTree, clientId, rootId );
const newTree = addChildItemToTree(
treeWithoutDragItem,
targetPosition.clientId,
block
);
lastTarget.current = {
clientId,
originalParent: removeParentId,
targetId: targetPosition.clientId,
targetIndex: 0,
};
setTree( newTree );
return;
}
}

// If we drag straight up or down, find the next valid sibling to swap places with:
const [ targetPosition, nextIndex ] = findFirstValidSibling(
positions,
listPosition,
v
);

if (
targetPosition.dropSibling &&
( translateX < 0 ||
( translateX > 0 && ! targetPosition.dropContainer ) )
targetPosition &&
Math.abs( translate ) >
( ITEM_HEIGHT * Math.abs( listPosition - nextIndex ) ) / 2
) {
//Insert as a sibling
//Sibling swap
const {
newTree: treeWithoutDragItem,
removeParentId,
Expand All @@ -278,10 +347,7 @@ function ListView(
treeWithoutDragItem,
targetPosition.clientId,
block,
direction === DOWN ||
( direction === UP &&
targetPosition.isLastChild &&
! targetPosition.dropContainer ),
direction === DOWN,
rootId
);
lastTarget.current = {
Expand All @@ -291,68 +357,10 @@ function ListView(
targetIndex,
};
setTree( newTree );
return;
}

if (
targetPosition.dropContainer &&
( translateX > 0 ||
( translateX < 0 && ! targetPosition.dropSibling ) )
) {
//Nest block under parent
const {
newTree: treeWithoutDragItem,
removeParentId,
} = removeItemFromTree( clientIdsTree, clientId, rootId );
const newTree = addChildItemToTree(
treeWithoutDragItem,
targetPosition.clientId,
block
);
lastTarget.current = {
clientId,
originalParent: removeParentId,
targetId: targetPosition.clientId,
targetIndex: 0,
};
setTree( newTree );
return;
}
}

// If we drag straight up or down, find the next valid sibling to swap places with:
const [ targetPosition, nextIndex ] = findFirstValidSibling(
positions,
listPosition,
v
);

if (
targetPosition &&
Math.abs( translate ) >
( ITEM_HEIGHT * Math.abs( listPosition - nextIndex ) ) / 2
) {
//Sibling swap
const {
newTree: treeWithoutDragItem,
removeParentId,
} = removeItemFromTree( clientIdsTree, clientId, rootId );
const { newTree, targetIndex, targetId } = addItemToTree(
treeWithoutDragItem,
targetPosition.clientId,
block,
direction === DOWN,
rootId
);
lastTarget.current = {
clientId,
originalParent: removeParentId,
targetId,
targetIndex,
};
setTree( newTree );
}
};
},
[ clientIdsTree, positions ]
);

const contextValue = useMemo(
() => ( {
Expand Down
2 changes: 1 addition & 1 deletion packages/block-editor/src/components/list-view/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ $block-navigation-max-indent: 7;
cursor: grabbing;
}

button:hover {
button.is-hovered {
box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color);
}

Expand Down

0 comments on commit 7efb06f

Please sign in to comment.