-
Notifications
You must be signed in to change notification settings - Fork 6.8k
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
fix(drag-drop): incorrectly laying out items with different height or margins #13849
fix(drag-drop): incorrectly laying out items with different height or margins #13849
Conversation
src/cdk/drag-drop/drop-list.ts
Outdated
@@ -37,6 +37,34 @@ let _uniqueIdCounter = 0; | |||
*/ | |||
const DROP_PROXIMITY_THRESHOLD = 0.05; | |||
|
|||
/** Object used to cache the position of a drag list, its items and siblings. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@docs-private
for this and the other related interfaces?
nit: add comma after "items"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK they don't need to have docs-private, because they're not exported.
src/cdk/drag-drop/drop-list.ts
Outdated
@@ -449,6 +471,56 @@ export class CdkDropList<T = any> implements OnInit, OnDestroy { | |||
return pointerY > top - yThreshold && pointerY < bottom + yThreshold && | |||
pointerX > left - xThreshold && pointerX < right + xThreshold; | |||
} | |||
|
|||
/** | |||
* Gets the offset by which the item that is being dragged should be moved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function doesn't make clear whether this is an index offset or a pixel offset. Maybe getItemOffsetPx
?
src/cdk/drag-drop/drop-list.ts
Outdated
* @param newPosition Position of the item where the current item should be moved. | ||
* @param delta Direction in which the user is moving. | ||
*/ | ||
private _getItemOffset(currentPosition: ClientRect, newPosition: ClientRect, delta: number) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should delta
be -1 | 1
?
newPosition.top - currentPosition.top; | ||
|
||
// Account for differences in the item width/height. | ||
if (delta === -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite follow this. If you're always dealing with the top/left position, how does the difference in size come into play?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It comes into play when you're swapping a tall item with a shorter one. If we only swapped their top
, the layout would be messed up, because there'll be extra space under the short item and and the taller one will overlap it.
const start = isHorizontal ? 'left' : 'top'; | ||
const end = isHorizontal ? 'right' : 'bottom'; | ||
|
||
if (delta === -1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also don't quite follow the calculation that's going on here- could you clarify it a bit further?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've expanded the comment.
… margins Currently the `CdkDropList` makes some assumptions about the items not having a margin between each other. It also won't lay out and animate items with varying heights, in some cases. The following changes rework the directive to allow it to handle both varying heights and different margins. Fixes angular#13483.
6867190
to
d5d5030
Compare
I've addressed the feedback @jelbourn. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
… margins (angular#13849) Currently the `CdkDropList` makes some assumptions about the items not having a margin between each other. It also won't lay out and animate items with varying heights, in some cases. The following changes rework the directive to allow it to handle both varying heights and different margins. Fixes angular#13483.
… margins (#13849) Currently the `CdkDropList` makes some assumptions about the items not having a margin between each other. It also won't lay out and animate items with varying heights, in some cases. The following changes rework the directive to allow it to handle both varying heights and different margins. Fixes #13483.
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Currently the
CdkDropList
makes some assumptions about the items not having a margin between each other. It also won't lay out and animate items with varying heights, in some cases. The following changes rework the directive to allow it to handle both varying heights and different margins.Fixes #13483.
Note: marking as a P2, because this a long-standing issue on a somewhat common use case.