diff --git a/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.spec.browser2.tsx b/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.spec.browser2.tsx index 44f04cebecde..b019f6c32c5b 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.spec.browser2.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.spec.browser2.tsx @@ -632,6 +632,90 @@ describe('Convert to Absolute', () => { getCodeForTestProject(childTagAfter), ) }) + it('snaps to parent and sibling after being converted', async () => { + const renderResult = await renderTestEditorWithCode( + makeTestProjectCodeWithSnippet(`
+
+
+
`), + 'await-first-dom-report', + ) + + const canvasControlsLayer = renderResult.renderedDOM.getByTestId(CanvasControlsContainerID) + const element = renderResult.renderedDOM.getByTestId('child') + const elementBounds = element.getBoundingClientRect() + + await mouseDownAtPoint( + canvasControlsLayer, + { + x: elementBounds.x + elementBounds.width / 2, + y: elementBounds.y + elementBounds.width / 2, + }, + { modifiers: cmdModifier }, + ) + + // move so that the bottom right corner snaps to the center of the parent + await mouseMoveToPoint(canvasControlsLayer, { + x: elementBounds.x + elementBounds.width / 2 + 25, + y: elementBounds.y + elementBounds.width / 2 + 25, + }) + + { + const activeStrategy = renderResult.getEditorState().strategyState.currentStrategy + expect(activeStrategy).not.toBeNull() + expect(activeStrategy).not.toEqual(ConvertToAbsoluteAndMoveStrategyID) + expect(renderResult.getEditorState().editor.canvas.controls.snappingGuidelines).toHaveLength( + 2, + ) + } + + // move so that the bottom edge snaps to the top edge of the sibling + await mouseMoveToPoint(canvasControlsLayer, { + x: elementBounds.x + elementBounds.width / 2 + 5, + y: elementBounds.y + elementBounds.width / 2 + 35, + }) + + { + const activeStrategy = renderResult.getEditorState().strategyState.currentStrategy + expect(activeStrategy).not.toBeNull() + expect(activeStrategy).not.toEqual(ConvertToAbsoluteAndMoveStrategyID) + expect(renderResult.getEditorState().editor.canvas.controls.snappingGuidelines).toHaveLength( + 1, + ) + } + }) }) describe('Convert to absolute/escape hatch', () => { diff --git a/editor/src/components/canvas/canvas-utils.ts b/editor/src/components/canvas/canvas-utils.ts index 2c9c45ba00d1..92374c9f77e6 100644 --- a/editor/src/components/canvas/canvas-utils.ts +++ b/editor/src/components/canvas/canvas-utils.ts @@ -904,7 +904,7 @@ export function collectGuidelines( // For any images create guidelines at the current multiplier setting. if (resizingFromPosition != null) { Utils.fastForEach(selectedViews, (selectedView) => { - if (MetadataUtils.isPinnedAndNotAbsolutePositioned(metadata, selectedView)) { + if (MetadataUtils.isLayoutedByFlowAndNotAbsolutePositioned(metadata, selectedView)) { return } @@ -1218,7 +1218,7 @@ export function snapPoint( guidelinesWithSnappingVector: Array } { const anythingPinnedAndNotAbsolutePositioned = selectedViews.some((elementToTarget) => { - return MetadataUtils.isPinnedAndNotAbsolutePositioned(jsxMetadata, elementToTarget) + return MetadataUtils.isLayoutedByFlowAndNotAbsolutePositioned(jsxMetadata, elementToTarget) }) const anyElementFragmentLike = selectedViews.some((elementPath) => diff --git a/editor/src/components/canvas/controls/guideline-helpers.ts b/editor/src/components/canvas/controls/guideline-helpers.ts index 8067bbe3fab0..d8c36395685f 100644 --- a/editor/src/components/canvas/controls/guideline-helpers.ts +++ b/editor/src/components/canvas/controls/guideline-helpers.ts @@ -67,29 +67,11 @@ export function gatherParentAndSiblingTargets( pathTrees: ElementPathTrees, targets: Array, ) { - return targets.flatMap((target) => { - const pinnedAndNotAbsolutePositioned = MetadataUtils.isPinnedAndNotAbsolutePositioned( - componentMetadata, - target, - ) - - const isElementFragmentLike = treatElementAsFragmentLike( - componentMetadata, - allElementProps, - pathTrees, - target, - ) - - if (isElementFragmentLike || !pinnedAndNotAbsolutePositioned) { - return getSnapTargetsForElementPath( - componentMetadata, - allElementProps, - pathTrees, - target, - ).filter((snapTarget) => targets.every((t) => !EP.pathsEqual(snapTarget, t))) - } - return [] - }) + return targets.flatMap((target) => + getSnapTargetsForElementPath(componentMetadata, allElementProps, pathTrees, target).filter( + (snapTarget) => targets.every((t) => !EP.pathsEqual(snapTarget, t)), + ), + ) } export function collectParentAndSiblingGuidelines( diff --git a/editor/src/core/model/element-metadata-utils.spec.tsx b/editor/src/core/model/element-metadata-utils.spec.tsx index 458bf7e2ff95..4fa40c9a7b76 100644 --- a/editor/src/core/model/element-metadata-utils.spec.tsx +++ b/editor/src/core/model/element-metadata-utils.spec.tsx @@ -801,7 +801,7 @@ describe('isPinnedAndNotAbsolutePositioned', () => { }, } expect( - MetadataUtils.isPinnedAndNotAbsolutePositioned( + MetadataUtils.isLayoutedByFlowAndNotAbsolutePositioned( elementMapForTest, EP.elementPath([[BakedInStoryboardUID, TestScenePath], ['View']]), ), @@ -819,7 +819,7 @@ describe('isPinnedAndNotAbsolutePositioned', () => { }, } expect( - MetadataUtils.isPinnedAndNotAbsolutePositioned( + MetadataUtils.isLayoutedByFlowAndNotAbsolutePositioned( elementMapForTest, EP.elementPath([[BakedInStoryboardUID, TestScenePath], ['View']]), ), @@ -837,7 +837,7 @@ describe('isPinnedAndNotAbsolutePositioned', () => { }, } expect( - MetadataUtils.isPinnedAndNotAbsolutePositioned( + MetadataUtils.isLayoutedByFlowAndNotAbsolutePositioned( elementMapForTest, EP.elementPath([[BakedInStoryboardUID, TestScenePath], ['View']]), ), @@ -855,7 +855,7 @@ describe('isPinnedAndNotAbsolutePositioned', () => { }, } expect( - MetadataUtils.isPinnedAndNotAbsolutePositioned( + MetadataUtils.isLayoutedByFlowAndNotAbsolutePositioned( elementMapForTest, EP.elementPath([[BakedInStoryboardUID, TestScenePath], ['View']]), ), diff --git a/editor/src/core/model/element-metadata-utils.ts b/editor/src/core/model/element-metadata-utils.ts index 370036e698e0..8ef9c7905659 100644 --- a/editor/src/core/model/element-metadata-utils.ts +++ b/editor/src/core/model/element-metadata-utils.ts @@ -1830,11 +1830,10 @@ export const MetadataUtils = { const elementName = MetadataUtils.getStaticElementName(path, rootElements) return elementName != null && !isIntrinsicHTMLElement(elementName) }, - isPinnedAndNotAbsolutePositioned( + isLayoutedByFlowAndNotAbsolutePositioned( metadata: ElementInstanceMetadataMap, view: ElementPath, ): boolean { - // Disable snapping and guidelines for pinned elements marked with relative positioning: const elementMetadata = MetadataUtils.findElementByElementPath(metadata, view) return ( elementMetadata != null &&