diff --git a/editor/src/components/canvas/canvas-strategies/strategies/grid-helpers.ts b/editor/src/components/canvas/canvas-strategies/strategies/grid-helpers.ts index 8f871138c922..8091b2456250 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/grid-helpers.ts +++ b/editor/src/components/canvas/canvas-strategies/strategies/grid-helpers.ts @@ -52,12 +52,13 @@ export function runGridRearrangeMove( jsxMetadata: ElementInstanceMetadataMap, interactionData: DragInteractionData, grid: ElementInstanceMetadata, + newPathAfterReparent?: ElementPath, ): CanvasCommand[] { if (interactionData.drag == null) { return [] } - const isReparent = !EP.isParentOf(grid.elementPath, selectedElement) + const isReparent = newPathAfterReparent != null const { gridCellGlobalFrames, containerGridProperties: gridTemplate } = grid.specialSizeMeasurements @@ -97,7 +98,9 @@ export function runGridRearrangeMove( // get the new adjusted column const column = Math.max(targetCellCoords.column - mouseCellPosInOriginalElement.column, 1) - const gridCellMoveCommands = setGridPropsCommands(targetElement, gridTemplate, { + const pathForCommands = newPathAfterReparent ?? targetElement // when reparenting, we want to use the new path for commands + + const gridCellMoveCommands = setGridPropsCommands(pathForCommands, gridTemplate, { gridColumnStart: gridPositionValue(column), gridColumnEnd: gridPositionValue(column + originalCellBounds.height), gridRowStart: gridPositionValue(row), @@ -147,14 +150,12 @@ export function runGridRearrangeMove( EP.pathsEqual(selectedElement, s.path), ) - const moveType = - originalElementMetadata == null - ? 'rearrange' - : getGridMoveType({ - originalElementMetadata: originalElementMetadata, - possiblyReorderIndex: possiblyReorderIndex, - cellsSortedByPosition: cellsSortedByPosition, - }) + const moveType = getGridMoveType({ + elementPath: targetElement, + originalElementMetadata: originalElementMetadata, + possiblyReorderIndex: possiblyReorderIndex, + cellsSortedByPosition: cellsSortedByPosition, + }) const updateGridControlsCommand = showGridControls( 'mid-interaction', @@ -165,6 +166,9 @@ export function runGridRearrangeMove( switch (moveType) { case 'absolute': { + if (isReparent) { + return [] + } const absoluteMoveCommands = gridChildAbsoluteMoveCommands( MetadataUtils.findElementByElementPath(jsxMetadata, targetElement), MetadataUtils.getFrameOrZeroRectInCanvasCoords(grid.elementPath, jsxMetadata), @@ -176,7 +180,7 @@ export function runGridRearrangeMove( const targetRootCell = gridCellCoordinates(row, column) const canvasRect = getGlobalFrameOfGridCell(grid, targetRootCell) const absoluteMoveCommands = - canvasRect == null + canvasRect == null || isReparent ? [] : gridChildAbsoluteMoveCommands( MetadataUtils.findElementByElementPath(jsxMetadata, targetElement), @@ -188,7 +192,7 @@ export function runGridRearrangeMove( ...absoluteMoveCommands, reorderElement( 'always', - selectedElement, + pathForCommands, absolute(Math.max(indexInSortedCellsForRearrange, 0)), ), updateGridControlsCommand, @@ -196,8 +200,8 @@ export function runGridRearrangeMove( } case 'reorder': { return [ - reorderElement('always', selectedElement, absolute(possiblyReorderIndex)), - deleteProperties('always', selectedElement, [ + reorderElement('always', pathForCommands, absolute(possiblyReorderIndex)), + deleteProperties('always', pathForCommands, [ PP.create('style', 'gridColumn'), PP.create('style', 'gridRow'), PP.create('style', 'gridColumnStart'), @@ -451,12 +455,16 @@ type GridMoveType = | 'absolute' // a regular absolute move, relative to the grid function getGridMoveType(params: { - originalElementMetadata: ElementInstanceMetadata + elementPath: ElementPath + originalElementMetadata: ElementInstanceMetadata | null possiblyReorderIndex: number cellsSortedByPosition: SortableGridElementProperties[] }): GridMoveType { - const specialSizeMeasurements = params.originalElementMetadata.specialSizeMeasurements - if (MetadataUtils.isPositionAbsolute(params.originalElementMetadata)) { + const specialSizeMeasurements = params.originalElementMetadata?.specialSizeMeasurements + if ( + specialSizeMeasurements != null && + MetadataUtils.isPositionAbsolute(params.originalElementMetadata) + ) { return MetadataUtils.hasNoGridCellPositioning(specialSizeMeasurements) ? 'absolute' : 'rearrange' @@ -465,11 +473,11 @@ function getGridMoveType(params: { return 'rearrange' } - const elementGridProperties = specialSizeMeasurements.elementGridProperties - const gridRowStart = gridPositionNumberValue(elementGridProperties.gridRowStart) - const gridColumnStart = gridPositionNumberValue(elementGridProperties.gridColumnStart) - const gridRowEnd = gridPositionNumberValue(elementGridProperties.gridRowEnd) - const gridColumnEnd = gridPositionNumberValue(elementGridProperties.gridColumnEnd) + const elementGridProperties = specialSizeMeasurements?.elementGridProperties + const gridRowStart = gridPositionNumberValue(elementGridProperties?.gridRowStart ?? null) + const gridColumnStart = gridPositionNumberValue(elementGridProperties?.gridColumnStart ?? null) + const gridRowEnd = gridPositionNumberValue(elementGridProperties?.gridRowEnd ?? null) + const gridColumnEnd = gridPositionNumberValue(elementGridProperties?.gridColumnEnd ?? null) const isMultiCellChild = (gridRowEnd != null && gridRowStart != null && gridRowEnd > gridRowStart + 1) || @@ -482,10 +490,8 @@ function getGridMoveType(params: { // The first element is intrinsically in order, so try to adjust for that if (params.possiblyReorderIndex === 0) { const isTheOnlyChild = params.cellsSortedByPosition.length === 1 - const isAlreadyTheFirstChild = EP.pathsEqual( - params.cellsSortedByPosition[0].path, - params.originalElementMetadata.elementPath, - ) + const isAlreadyTheFirstChild = + EP.toUid(params.cellsSortedByPosition[0].path) === EP.toUid(params.elementPath) const isAlreadyAtOrigin = gridRowStart === 1 && gridColumnStart === 1 diff --git a/editor/src/components/canvas/canvas-strategies/strategies/grid-reparent-strategies.spec.browser2.tsx b/editor/src/components/canvas/canvas-strategies/strategies/grid-reparent-strategies.spec.browser2.tsx index 15cebb6d6195..368d72977fb0 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/grid-reparent-strategies.spec.browser2.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/grid-reparent-strategies.spec.browser2.tsx @@ -4,7 +4,7 @@ import type { WindowPoint } from '../../../../core/shared/math-utils' import { offsetPoint, windowPoint } from '../../../../core/shared/math-utils' import type { Modifiers } from '../../../../utils/modifiers' import { cmdModifier } from '../../../../utils/modifiers' -import { selectComponentsForTest } from '../../../../utils/utils.test-utils' +import { selectComponentsForTest, wait } from '../../../../utils/utils.test-utils' import { GridCellTestId } from '../../controls/grid-controls-for-strategies' import { CanvasControlsContainerID } from '../../controls/new-canvas-controls' import type { Point } from '../../event-helpers.test-utils' @@ -665,65 +665,187 @@ describe('grid reparent strategies', () => { formatTestProjectCode( makeTestProjectCode({ extraCode: ` +
+
+
+
+
+
+ `, + }), + ), + ) + }) + it('into a grid container with reorder (no explicit gridRow/gridColumn props', async () => { + const editor = await renderTestEditorWithCode( + makeTestProjectCode({ + insideGrid: `
-
-
-
-
-
+ data-uid='dragme' + data-testid='dragme' + /> + `, + extraCode: ` +
+
+
+
+ `, + }), + 'await-first-dom-report', + ) + + await selectComponentsForTest(editor, [EP.fromString('sb/grid/dragme')]) + + await dragOutToAnotherGrid( + editor, + 'another-grid', + { + x: 300, + y: 20, + }, + EP.fromString('sb/grid/dragme'), + ) + + expect(getPrintedUiJsCode(editor.getEditorState())).toEqual( + formatTestProjectCode( + makeTestProjectCode({ + extraCode: ` +
+
+
+
+
`, }), ), diff --git a/editor/src/components/canvas/canvas-strategies/strategies/grid-reparent-strategy.tsx b/editor/src/components/canvas/canvas-strategies/strategies/grid-reparent-strategy.tsx index cd20d3fa7db4..50aed2f5ed0d 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/grid-reparent-strategy.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/grid-reparent-strategy.tsx @@ -272,18 +272,22 @@ function gridReparentCommands( if (reparentResult == null) { return null } - const gridPropsCommands = runGridRearrangeMove(target, target, jsxMetadata, interactionData, grid) - - if (gridPropsCommands == null) { - return null - } const { commands: reparentCommands, newPath } = reparentResult + const gridPropsCommands = runGridRearrangeMove( + target, + target, + jsxMetadata, + interactionData, + grid, + newPath, + ) + const removeAbsolutePositioningPropsCommands = removeAbsolutePositioningProps('always', newPath) return { - commands: [...gridPropsCommands, ...reparentCommands, removeAbsolutePositioningPropsCommands], + commands: [...reparentCommands, ...gridPropsCommands, removeAbsolutePositioningPropsCommands], newPath: newPath, oldPath: target, }