@@ -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