Skip to content

Commit 60ac268

Browse files
Move the item down to the first available position
First look for the next item in the row directly below the selected item. When nothing is find look for the first item below the selected item. And when that fails because of whitespacing, look for the first item which is below and overlaps the selected item. Also check if the selected item has sibling, because when the item below spans more columns, it can mean there is no space for that item. Instead, move the selected item below the next item.
1 parent 034c3b0 commit 60ac268

File tree

1 file changed

+86
-3
lines changed

1 file changed

+86
-3
lines changed

src/dd-draggable.ts

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)