Skip to content

Commit 034c3b0

Browse files
Check for the first available space to move the item up
This takes the selected elements width and its position to check for the first item above. When no direct item is found find the first item in the row above and move the item above that.
1 parent e2f1b79 commit 034c3b0

File tree

1 file changed

+55
-1
lines changed

1 file changed

+55
-1
lines changed

src/dd-draggable.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,57 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
176176
return this._node().grid
177177
}
178178

179+
_itemNode(item) {
180+
return item['gridstackNode']
181+
}
182+
183+
_nodePosition(node) {
184+
return {
185+
width: node.w - 1,
186+
height: node.h,
187+
column: node.x,
188+
row: node.y
189+
}
190+
}
191+
192+
_items() {
193+
return document.querySelectorAll('.grid-stack-item:not(.grid-stack-placeholder)')
194+
}
195+
196+
_sortByRow(a, b) {
197+
return this._itemNode(a).y - this._itemNode(b).y
198+
}
199+
200+
// Find the first item above the selectedNode.
201+
// Add the items row and its height, this should be the same as the selectedNodes row, if so, the item is in the row directly
202+
// above the selectedNode.
203+
// Also check if the item column overlaps the selectedNodes columns and include the items width in this calculation
204+
_findItemAbove () {
205+
const selectedNode = this._nodePosition(this._node())
206+
207+
return Array.from(this._items()).filter(item => {
208+
const itemNode = this._nodePosition(this._itemNode(item))
209+
210+
if ((itemNode.row + itemNode.height) !== selectedNode.row) { return false }
211+
if (selectedNode.column < itemNode.column) { return false }
212+
if (selectedNode.column > (itemNode.column + itemNode.width)) { return false }
213+
return item
214+
})[0]
215+
}
216+
217+
// When we have not found any items in the row directly above the selectedNode.
218+
// Look for the first item it can find above the selectedNodes row.
219+
_findFirstItemAbove () {
220+
const selectedNode = this._nodePosition(this._node())
221+
222+
return Array.from(this._items()).filter(item => {
223+
if (item === this.el) { return false }
224+
const itemNode = this._nodePosition(this._itemNode(item))
225+
226+
if (itemNode.row < selectedNode.row) { return item }
227+
}).sort(this._sortByRow).reverse()[0]
228+
}
229+
179230
protected _elNewCoordinates(event: KeyboardEvent, element: HTMLElement) {
180231
const selectedNode = this._node();
181232
const cellHeight = this._grid().getCellHeight() * selectedNode.h
@@ -197,7 +248,10 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
197248
case 'ArrowUp':
198249
if (selectedNode.y === 0) { break }
199250

200-
yCoord = -cellHeight
251+
let itemAbove = this._findItemAbove()
252+
if (itemAbove === undefined) { itemAbove = this._findFirstItemAbove() }
253+
254+
yCoord = -(this._itemNode(itemAbove).h * this._grid().getCellHeight())
201255
break
202256
case 'ArrowDown':
203257
yCoord = cellHeight

0 commit comments

Comments
 (0)