@@ -28,11 +28,9 @@ let dragHandle: any;
2828let dragged : HTMLDivElement | undefined ;
2929let clone : any ;
3030let draggedId : string | undefined ;
31- let lanesScrollableEl : HTMLElement | undefined ;
3231
33- export function onReorderMouseDown ( e : MouseEvent , element : HTMLDivElement | undefined ) {
32+ export function onReorderMouseDown ( e : MouseEvent ) {
3433 dragHandle = e . target ;
35- lanesScrollableEl = element ;
3634}
3735
3836export function onReorderStart (
@@ -81,43 +79,45 @@ export function onReorderEnd() {
8179 clone ?. remove ( ) ;
8280}
8381
84- export function onReorderDragOver (
82+ export function onDragOver (
8583 e : MouseEvent & { currentTarget : HTMLDivElement } ,
86- sortedStacks : Stack [ ]
84+ sortedStacks : Stack [ ] ,
85+ thisStackId : string
8786) {
88- e . preventDefault ( ) ;
89- if ( ! dragged ) {
90- return ; // Something other than a lane is being dragged.
87+ // Return early if we are currently dragging over ourself.
88+ if ( draggedId === thisStackId ) {
89+ return ;
90+ }
91+
92+ const thisIdx = sortedStacks . findIndex ( ( stack ) => stack . id === thisStackId ) ;
93+ const draggedIdx = sortedStacks . findIndex ( ( stack ) => stack . id === draggedId ) ;
94+ if ( draggedIdx === - 1 || thisIdx === - 1 ) {
95+ return ;
9196 }
9297
93- const children = Array . from ( e . currentTarget . children ) ;
94- const currentPosition = sortedStacks . findIndex ( ( stack ) => stack . id === draggedId ) ;
98+ // If we are dragging over an adjacent stack, only swap if the mouse is half
99+ // way over the adjacent stack.
100+ if ( Math . abs ( thisIdx - draggedIdx ) === 1 ) {
101+ // The mouse position relative to the LHS of the current stack.
102+ const mouseLeft = e . clientX - ( e . currentTarget ?. getBoundingClientRect ( ) . left ?? 0 ) ;
95103
96- let dropPosition = 0 ;
97- const mouseLeft = e . clientX - ( lanesScrollableEl ?. getBoundingClientRect ( ) . left ?? 0 ) ;
98- let cumulativeWidth = lanesScrollableEl ?. offsetLeft ?? 0 ;
104+ const isRightOfTarget = thisIdx > draggedIdx ;
99105
100- for ( let i = 0 ; i < children . length ; i ++ ) {
101- const childWidth = ( children [ i ] as HTMLElement ) . offsetWidth ;
102- // The commented out code below is necessary if the drag handle is
103- // aligned with the left side of the stack. Leaving it here until
104- // we are more certain about the layout.
105- // if (i === currentPosition) {
106- // continue;
107- // }
108- if ( mouseLeft > cumulativeWidth + childWidth / 2 ) {
109- // New position depends on drag direction.
110- dropPosition = i < currentPosition ? i + 1 : i ;
111- cumulativeWidth += childWidth ;
106+ const midpoint = ( e . currentTarget ?. clientWidth ?? 0 ) / 2 ;
107+
108+ let pastOfMidpoint = false ;
109+ if ( isRightOfTarget ) {
110+ pastOfMidpoint = mouseLeft > midpoint ;
112111 } else {
113- break ;
112+ pastOfMidpoint = mouseLeft < midpoint ;
114113 }
115- }
116114
117- // Update sorted branch array manually.
118- if ( currentPosition !== dropPosition ) {
119- const el = sortedStacks . splice ( currentPosition , 1 ) ;
120- sortedStacks . splice ( dropPosition , 0 , ...el ) ;
115+ if ( pastOfMidpoint ) {
116+ const draggedStack = sortedStacks . splice ( draggedIdx , 1 ) ;
117+ sortedStacks . splice ( thisIdx , 0 , ...draggedStack ) ;
118+ }
119+ } else {
120+ const draggedStack = sortedStacks . splice ( draggedIdx , 1 ) ;
121+ sortedStacks . splice ( thisIdx , 0 , ...draggedStack ) ;
121122 }
122- return sortedStacks ;
123123}
0 commit comments