@@ -327,14 +327,53 @@ function handleDragStart(e) {
327327 }
328328}
329329
330+ /**
331+ * NEW: Auto-scroll helper function.
332+ * Scrolls the window smoothly at a variable speed depending on the distance from the viewport edges.
333+ * @param {DragEvent } e - The dragover event.
334+ */
335+ function autoScroll ( e ) {
336+ const scrollThreshold = 220 ; // Pixels from edge where scrolling starts
337+ const maxScrollSpeed = 400 ; // Maximum scroll speed in pixels per tick
338+
339+ const { innerWidth, innerHeight } = window ;
340+ let scrollX = 0 , scrollY = 0 ;
341+
342+ // Vertical scroll: if near the top edge
343+ if ( e . clientY < scrollThreshold ) {
344+ scrollY = - maxScrollSpeed * ( ( scrollThreshold - e . clientY ) / scrollThreshold ) ;
345+ } else if ( innerHeight - e . clientY < scrollThreshold ) {
346+ scrollY = maxScrollSpeed * ( ( scrollThreshold - ( innerHeight - e . clientY ) ) / scrollThreshold ) ;
347+ }
348+
349+ // Horizontal scroll: if near the left edge
350+ if ( e . clientX < scrollThreshold ) {
351+ scrollX = - maxScrollSpeed * ( ( scrollThreshold - e . clientX ) / scrollThreshold ) ;
352+ } else if ( innerWidth - e . clientX < scrollThreshold ) {
353+ scrollX = maxScrollSpeed * ( ( scrollThreshold - ( innerWidth - e . clientX ) ) / scrollThreshold ) ;
354+ }
355+
356+ if ( scrollX !== 0 || scrollY !== 0 ) {
357+ window . scrollBy ( {
358+ top : scrollY ,
359+ left : scrollX ,
360+ behavior : 'smooth'
361+ } ) ;
362+ }
363+ }
364+
330365function handleDragOver ( e ) {
331366 e . preventDefault ( ) ;
332367 if ( ! isDragging ) return ;
333368
334369 e . dataTransfer . dropEffect = 'move' ;
370+
371+ // Call custom auto-scroll based on pointer position
372+ autoScroll ( e ) ;
373+
335374 lastDragPosition = { x : e . clientX , y : e . clientY } ;
336375
337- // Identify potential target
376+ // Identify potential target for reordering
338377 const target = e . target . closest ( '.button-item' ) ;
339378 if ( ! target || target === draggedItem ) return ;
340379
@@ -343,13 +382,12 @@ function handleDragOver(e) {
343382 const offsetY = e . clientY - bounding . top ;
344383 const isBefore = offsetY < bounding . height / 2 ;
345384
346- // Re-insert draggedItem before or after ' target'
385+ // Re-insert draggedItem before or after target based on pointer location
347386 if ( isBefore ) {
348387 parent . insertBefore ( draggedItem , target ) ;
349388 } else {
350389 parent . insertBefore ( draggedItem , target . nextSibling ) ;
351390 }
352-
353391}
354392
355393function handleDrop ( e ) {
@@ -358,7 +396,7 @@ function handleDrop(e) {
358396
359397 if ( ! isDragging || ! draggedItem ) return ;
360398
361- // Finalize position, save the new order
399+ // Finalize position and save new order
362400 finalizeDrag ( ) ;
363401 logToConsole ( 'Reordered buttons' ) ;
364402}
@@ -505,5 +543,4 @@ function clearText() {
505543 logToConsole ( 'Cleared button text input.' ) ;
506544 document . getElementById ( 'buttonIcon' ) . value = '' ;
507545 showToast ( 'Button text cleared' , 'info' ) ;
508-
509546}
0 commit comments