@@ -227,9 +227,74 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
227
227
} ) . sort ( this . _sortByRow ) . reverse ( ) [ 0 ]
228
228
}
229
229
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
+
230
296
protected _elNewCoordinates ( event : KeyboardEvent , element : HTMLElement ) {
231
297
const selectedNode = this . _node ( ) ;
232
- const cellHeight = this . _grid ( ) . getCellHeight ( ) * selectedNode . h
233
298
let xCoord : number , yCoord : number
234
299
235
300
switch ( event . code ) {
@@ -254,8 +319,26 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
254
319
yCoord = - ( this . _itemNode ( itemAbove ) . h * this . _grid ( ) . getCellHeight ( ) )
255
320
break
256
321
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 ;
259
342
}
260
343
261
344
return this . _setCoordinates ( element , xCoord , yCoord ) ;
0 commit comments