@@ -176,6 +176,57 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
176
176
return this . _node ( ) . grid
177
177
}
178
178
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
+
179
230
protected _elNewCoordinates ( event : KeyboardEvent , element : HTMLElement ) {
180
231
const selectedNode = this . _node ( ) ;
181
232
const cellHeight = this . _grid ( ) . getCellHeight ( ) * selectedNode . h
@@ -197,7 +248,10 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
197
248
case 'ArrowUp' :
198
249
if ( selectedNode . y === 0 ) { break }
199
250
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 ( ) )
201
255
break
202
256
case 'ArrowDown' :
203
257
yCoord = cellHeight
0 commit comments