Skip to content

fix(drag-drop): don't move item in list if pointer is too far away #12827

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

Merged
merged 1 commit into from
Aug 25, 2018

Conversation

crisbeto
Copy link
Member

@crisbeto crisbeto commented Aug 25, 2018

Currently the drop container will move an item in a list, no matter how far away the pointer is, as long as it overlaps another item along the proper axis. This can be annoying to users, because it can lead to unwanted re-arrangements of the list. These changes rework the logic so that the list is only re-arranged if the pointer is inside the drop container or within a buffer around it.

For reference, here's the current behavior:
demo

@crisbeto crisbeto added pr: merge safe target: major This PR is targeted for the next major release labels Aug 25, 2018
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Aug 25, 2018
* Buffer, in percent of the width/height, to add around the drop container when
* determining whether an item should affect the list order.
*/
const DROP_BUFFER_PERCENTAGE = 5;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call this DROP_PROXIMITY_THRESHOLD and set it to 0.05. It's generally better to write constants like this as a number between 0 and 1 rather than as a whole number percent because it's more explicit about what it represents.

I suspect that this will also need a min and max value for cases when the drop zone is very small or very large, but I'd have to try it out in different situations to tell.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that eventually we should allow people to customize the value, rather than picking a min and max since this is very much down to personal preference. The 5% value should do for now, because it's small enough that even if a drop container takes up the entire viewport on a 1080p screen, it would still only be 96px.

* @param xOffset Coordinates along the X axis.
* @param yOffset Coordinates along the Y axis.
*/
private _isInRange(xOffset: number, yOffset: number): boolean {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about _isPointerNearDropContainer(pointerX, pointerY)?

const {top, right, bottom, left, width, height} = this._positionCache.self;
const multiplier = DROP_BUFFER_PERCENTAGE / 100;
const xBuffer = width * multiplier;
const yBuffer = height * multiplier;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use threshold here instead of buffer

@crisbeto
Copy link
Member Author

Feedback has been addressed.

* @param xOffset Coordinates along the X axis.
* @param yOffset Coordinates along the Y axis.
*/
private _isPointerNearDropContainer(xOffset: number, yOffset: number): boolean {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I snuck in a suggestion w/ the function name comment on the parameter names too: pointerX and pointerY

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with xOffset and yOffset, because it's what we call them in all the other functions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to rename them in a follow-up PR, then, if they all do represent the pointer position.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -30,6 +30,12 @@ import {moveItemInArray} from './drag-utils';
/** Counter used to generate unique ids for drop zones. */
let _uniqueIdCounter = 0;

/**
* Buffer, in percent of the width/height, to add around the drop container when
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to update the description for the new name, something like

Proximity, as a ratio to width/height, at which a dragged item will affect the drop container.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Currently the drop container will move an item in a list, no matter how far away the pointer is, as long as it overlaps another item along the proper axis. This can be annoying to users, because it can lead to unwanted re-arrangements of the list. These changes rework the logic so that the list is only re-arranged if the pointer is inside the drop container or within a buffer around it.
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jelbourn jelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Aug 25, 2018
@ngbot
Copy link

ngbot bot commented Aug 25, 2018

I see that you just added the pr: merge ready label, but the following checks are still failing:
    failure status "continuous-integration/travis-ci/pr" is failing

If you want your PR to be merged, it has to pass all the CI checks.

If you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help.

@jelbourn jelbourn merged commit cfa2d04 into angular:master Aug 25, 2018
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 9, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants