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