@@ -227,9 +227,74 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
227227 } ) . sort ( this . _sortByRow ) . reverse ( ) [ 0 ]
228228 }
229229
230+ // Find the first item below the selectedNode.
231+ // Add the selectedNodes row and its height, this should be the same as the items row, if so, the item is in the row directly
232+ // below the selectedNode.
233+ // Also check if the item column overlaps the selectedNodes columns and include the items width in this calculation
234+ _findItemBelow ( ) {
235+ const selectedNode = this . _nodePosition ( this . _node ( ) )
236+
237+ return Array . from ( this . _items ( ) ) . filter ( item => {
238+ const itemNode = this . _nodePosition ( this . _itemNode ( item ) )
239+ const row = selectedNode . height + selectedNode . row
240+
241+ if ( itemNode . row !== row ) { return false }
242+ if ( selectedNode . column < itemNode . column ) { return false }
243+ if ( selectedNode . column > ( itemNode . column + itemNode . width ) ) { return false }
244+ return item
245+ } ) [ 0 ]
246+ }
247+
248+ // When we have not found any items in the row directly below the selectedNode.
249+ // Look for the first item it can find below the selectedNodes row.
250+ _findFirstItemBelow ( ) {
251+ const selectedNode = this . _nodePosition ( this . _node ( ) )
252+
253+ return Array . from ( this . _items ( ) ) . filter ( item => {
254+ const itemNode = this . _nodePosition ( this . _itemNode ( item ) )
255+
256+ if ( item === this . el ) { return false }
257+ if ( selectedNode . column < itemNode . column ) { return false }
258+ if ( selectedNode . column > ( itemNode . column + itemNode . width ) ) { return false }
259+ if ( itemNode . row <= selectedNode . row ) { return false }
260+
261+ return item
262+ } ) . sort ( this . _sortByRow ) [ 0 ]
263+ }
264+
265+ // When the selected item spans more than one column and the position directly below are all empty.
266+ // When this happens we want to look for the first item in the row below which overlap the selected item on the columns.
267+ _findFirstRowBelow ( ) {
268+ const selectedNode = this . _nodePosition ( this . _node ( ) )
269+
270+ return Array . from ( this . _items ( ) ) . filter ( item => {
271+ if ( item === this . el ) { return false }
272+ const itemNode = this . _nodePosition ( this . _itemNode ( item ) )
273+
274+ if ( itemNode . row < ( selectedNode . row + selectedNode . height ) ) { return false }
275+ return item
276+ } ) . sort ( this . _sortByRow ) [ 0 ]
277+ }
278+
279+ // Check if the selectedNode has any siblings to the left or right
280+ _findSiblings ( itemBelow : Element ) {
281+ const itemBelowNode = this . _nodePosition ( this . _itemNode ( itemBelow ) )
282+ const selectedNode = this . _nodePosition ( this . _node ( ) )
283+
284+ return Array . from ( this . _items ( ) ) . filter ( item => {
285+ const itemNode = this . _nodePosition ( this . _itemNode ( item ) )
286+
287+ if ( item === this . el ) { return false }
288+ if ( itemNode . row !== selectedNode . row ) { return false }
289+
290+ if ( itemNode . column < itemBelowNode . column ) { return false }
291+ if ( itemNode . column > ( itemBelowNode . column + itemBelowNode . width ) ) { return false }
292+ return item
293+ } )
294+ }
295+
230296 protected _elNewCoordinates ( event : KeyboardEvent , element : HTMLElement ) {
231297 const selectedNode = this . _node ( ) ;
232- const cellHeight = this . _grid ( ) . getCellHeight ( ) * selectedNode . h
233298 let xCoord : number , yCoord : number
234299
235300 switch ( event . code ) {
@@ -254,8 +319,26 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
254319 yCoord = - ( this . _itemNode ( itemAbove ) . h * this . _grid ( ) . getCellHeight ( ) )
255320 break
256321 case 'ArrowDown' :
257- yCoord = cellHeight
258- break
322+ let itemBelow = this . _findItemBelow ( )
323+
324+ if ( itemBelow === undefined ) { itemBelow = this . _findFirstItemBelow ( ) }
325+ if ( itemBelow === undefined ) { itemBelow = this . _findFirstRowBelow ( ) }
326+
327+ const itemBelowNode = this . _nodePosition ( this . _itemNode ( itemBelow ) )
328+ const siblings = this . _findSiblings ( itemBelow )
329+
330+ if ( siblings . length >= 1 ) {
331+ const rowPosition = ( itemBelowNode . row - selectedNode . y ) * this . _grid ( ) . getCellHeight ( ) ;
332+
333+ yCoord = rowPosition + ( itemBelowNode . height * this . _grid ( ) . getCellHeight ( ) )
334+ } else if ( selectedNode . h < itemBelowNode . height ) {
335+ yCoord = ( itemBelowNode . height * this . _grid ( ) . getCellHeight ( ) )
336+ } else {
337+ const cellHeight = this . _grid ( ) . getCellHeight ( ) * selectedNode . h ;
338+
339+ yCoord = ( cellHeight + this . _grid ( ) . getCellHeight ( ) )
340+ }
341+ break ;
259342 }
260343
261344 return this . _setCoordinates ( element , xCoord , yCoord ) ;
0 commit comments