From e673bd4f177c8dfc27839a920ea24f6a2ee57bfa Mon Sep 17 00:00:00 2001 From: Mike Harvey <43474485+mikeharv@users.noreply.github.com> Date: Wed, 17 Jun 2026 14:40:23 -0400 Subject: [PATCH 1/2] fix: constrained move mode improvements --- .../core/dragging/block_drag_strategy.ts | 57 +++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/packages/blockly/core/dragging/block_drag_strategy.ts b/packages/blockly/core/dragging/block_drag_strategy.ts index b32c59c7ac9..2a700fac820 100644 --- a/packages/blockly/core/dragging/block_drag_strategy.ts +++ b/packages/blockly/core/dragging/block_drag_strategy.ts @@ -604,12 +604,10 @@ export class BlockDragStrategy implements IDragStrategy { private determineConnectionOffset(): Coordinate { const {local, neighbour} = this.connectionCandidate!; - const dx = neighbour.x - local.x; - const dy = neighbour.y - local.y; + const connOffset = local.getOffsetInBlock(); - // Base aligned position - let x = this.startLoc!.x + dx; - let y = this.startLoc!.y + dy; + let x = neighbour.x - connOffset.x; + let y = neighbour.y - connOffset.y; // Decide offset direction const becomingChild = @@ -650,51 +648,52 @@ export class BlockDragStrategy implements IDragStrategy { const newCandidate = this.getInitialCandidate() ?? this.getConnectionCandidate(delta); + this.connectionPreviewer?.hidePreview(); + this.connectionCandidate = null; if (!newCandidate) { // Position above or below the first/last block. if (this.moveMode === MoveMode.CONSTRAINED) { - const connectedBlock = currCandidate?.neighbour.getSourceBlock(); + const connectedBlock = currCandidate?.neighbour.getSourceBlock() ?? null; let root = connectedBlock?.getRootBlock() ?? connectedBlock; if (root === draggingBlock) root = connectedBlock; - const direction = this.getDirectionToNewLocation( - Coordinate.sum(this.startLoc!, delta), - ); - const bounds = root?.getBoundingRectangle(); - if (!bounds) return; + if (!root) return; const blockRects = draggingBlock.workspace .getTopBlocks() + .filter((block) => block !== draggingBlock.getRootBlock()) .map((block) => block.getBoundingRectangle()); - const blocksLeft = Math.min(...blockRects.map((rect) => rect.left)); + if (!blockRects.length) return; + + // If the block was previously connected, position the block near its previous connection. + const destinationX = + currCandidate?.neighbour.x ?? + draggingBlock.getRelativeToSurfaceXY().x; + let destinationY: number; + const offset = this.BLOCK_CONNECTION_OFFSET * 2; - let destination: Coordinate; - let blockBound: number; + const direction = this.getDirectionToNewLocation( + Coordinate.sum(this.startLoc!, delta), + ); switch (direction) { case Direction.LEFT: case Direction.UP: - blockBound = Math.min(...blockRects.map((rect) => rect.top)); - destination = new Coordinate( - blocksLeft, - blockBound - - this.BLOCK_CONNECTION_OFFSET * 2 - - draggingBlock.getHeightWidth().height, - ); + const blocksTop = Math.min(...blockRects.map((rect) => rect.top)); + destinationY = + blocksTop - offset - draggingBlock.getHeightWidth().height; break; case Direction.RIGHT: case Direction.DOWN: default: - blockBound = Math.max(...blockRects.map((rect) => rect.bottom)); - destination = new Coordinate( - blocksLeft, - blockBound + this.BLOCK_CONNECTION_OFFSET * 2, + const blocksBottom = Math.max( + ...blockRects.map((rect) => rect.bottom), ); + destinationY = blocksBottom + offset; break; } - draggingBlock.moveDuringDrag(destination); + draggingBlock.moveDuringDrag( + new Coordinate(destinationX, destinationY), + ); } - - this.connectionPreviewer?.hidePreview(); - this.connectionCandidate = null; return; } const candidate = From 2a11197b70d87075162596c22f8171716a28a4d5 Mon Sep 17 00:00:00 2001 From: Mike Harvey <43474485+mikeharv@users.noreply.github.com> Date: Wed, 17 Jun 2026 15:08:43 -0400 Subject: [PATCH 2/2] chore: linting --- .../blockly/core/dragging/block_drag_strategy.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/blockly/core/dragging/block_drag_strategy.ts b/packages/blockly/core/dragging/block_drag_strategy.ts index 2a700fac820..f95bdd1b080 100644 --- a/packages/blockly/core/dragging/block_drag_strategy.ts +++ b/packages/blockly/core/dragging/block_drag_strategy.ts @@ -653,7 +653,8 @@ export class BlockDragStrategy implements IDragStrategy { if (!newCandidate) { // Position above or below the first/last block. if (this.moveMode === MoveMode.CONSTRAINED) { - const connectedBlock = currCandidate?.neighbour.getSourceBlock() ?? null; + const connectedBlock = + currCandidate?.neighbour.getSourceBlock() ?? null; let root = connectedBlock?.getRootBlock() ?? connectedBlock; if (root === draggingBlock) root = connectedBlock; if (!root) return; @@ -677,17 +678,16 @@ export class BlockDragStrategy implements IDragStrategy { switch (direction) { case Direction.LEFT: case Direction.UP: - const blocksTop = Math.min(...blockRects.map((rect) => rect.top)); destinationY = - blocksTop - offset - draggingBlock.getHeightWidth().height; + Math.min(...blockRects.map((rect) => rect.top)) - + offset - + draggingBlock.getHeightWidth().height; break; case Direction.RIGHT: case Direction.DOWN: default: - const blocksBottom = Math.max( - ...blockRects.map((rect) => rect.bottom), - ); - destinationY = blocksBottom + offset; + destinationY = + Math.max(...blockRects.map((rect) => rect.bottom)) + offset; break; } draggingBlock.moveDuringDrag(