diff --git a/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy.spec.browser2.tsx b/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy.spec.browser2.tsx
index e0b6f200de40..e623e270bf52 100644
--- a/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy.spec.browser2.tsx
+++ b/editor/src/components/canvas/canvas-strategies/strategies/absolute-reparent-strategy.spec.browser2.tsx
@@ -26,6 +26,7 @@ import { getCursorFromEditor } from '../../controls/select-mode/cursor-component
import {
mouseClickAtPoint,
mouseDownAtPoint,
+ mouseDragFromPointToPoint,
mouseDragFromPointToPointNoMouseDown,
mouseDragFromPointWithDelta,
mouseMoveToPoint,
@@ -38,6 +39,7 @@ import {
makeTestProjectCodeWithSnippet,
renderTestEditorWithCode,
TestAppUID,
+ TestScenePath,
TestSceneUID,
} from '../../ui-jsx.test-utils'
import type { FragmentLikeType } from './fragment-like-helpers'
@@ -50,7 +52,11 @@ import {
import { queryHelpers } from '@testing-library/react'
import { forceNotNull } from '../../../../core/shared/optional-utils'
import { getDomRectCenter } from '../../../../core/shared/dom-utils'
-import { boundingClientRectToCanvasRectangle } from '../../../../utils/utils.test-utils'
+import {
+ boundingClientRectToCanvasRectangle,
+ selectComponentsForTest,
+ wait,
+} from '../../../../utils/utils.test-utils'
interface CheckCursor {
cursor: CSSCursor | null
@@ -1221,62 +1227,6 @@ export var ${BakedInStoryboardVariableName} = (props) => {
)
})
})
- // TODO reenable this after conditionals work well with reparent
- xit('renders correctly with ChildrenHider set to hide children', async () => {
- const renderResult = await renderTestEditorWithCode(
- getChildrenHiderProjectCode(true),
- 'await-first-dom-report',
- )
-
- const dragDelta = windowPoint({ x: 0, y: -150 })
- await dragElement(
- renderResult,
- 'child-to-reparent',
- dragDelta,
- cmdModifier,
- {
- cursor: CSSCursor.NotPermitted,
- },
- null,
- )
-
- await renderResult.getDispatchFollowUpActionsFinished()
-
- expect(Object.keys(renderResult.getEditorState().editor.spyMetadata)).toEqual([
- 'utopia-storyboard-uid',
- 'utopia-storyboard-uid/scene-aaa',
- 'utopia-storyboard-uid/scene-aaa/outer-div',
- 'utopia-storyboard-uid/scene-aaa/outer-div/children-hider',
- ])
- })
- xit('renders correctly with ChildrenHider set to show children', async () => {
- const renderResult = await renderTestEditorWithCode(
- getChildrenHiderProjectCode(false),
- 'await-first-dom-report',
- )
-
- const dragDelta = windowPoint({ x: 0, y: -150 })
- await dragElement(
- renderResult,
- 'child-to-reparent',
- dragDelta,
- cmdModifier,
- {
- cursor: CSSCursor.Move,
- },
- null,
- )
-
- await renderResult.getDispatchFollowUpActionsFinished()
-
- expect(Object.keys(renderResult.getEditorState().editor.spyMetadata)).toEqual([
- 'utopia-storyboard-uid',
- 'utopia-storyboard-uid/scene-aaa',
- 'utopia-storyboard-uid/scene-aaa/outer-div',
- 'utopia-storyboard-uid/scene-aaa/outer-div/children-hider',
- 'utopia-storyboard-uid/scene-aaa/outer-div/children-hider/child-to-reparent',
- ])
- })
describe('fragment-like reparent tests', () => {
AllFragmentLikeTypes.forEach((type) => {
@@ -1876,6 +1826,221 @@ export var ${BakedInStoryboardVariableName} = (props) => {
)
})
})
+ describe('snapping', () => {
+ const NewParentTestId = 'new-parent'
+ const NewSiblingTestId = 'new-sibling'
+ const project = (innards: string) => `
`
+
+ it('when reparented from absolute, it snaps to new parent and children of new parent', async () => {
+ const renderResult = await renderTestEditorWithCode(
+ makeTestProjectCodeWithSnippet(
+ project(`
+
+
+
+ `),
+ ),
+ 'await-first-dom-report',
+ )
+
+ const newParentCenterX = getElementCenterCoords(renderResult, NewParentTestId).x
+ const newSiblingCenterY = getElementCenterCoords(renderResult, NewSiblingTestId).y
+ const elementToDragCenter = getElementCenterCoords(renderResult, 'drag-me')
+ const canvasControlsLayer = renderResult.renderedDOM.getByTestId(CanvasControlsContainerID)
+
+ await selectComponentsForTest(renderResult, [
+ EP.appendNewElementPath(TestScenePath, ['root', 'container', 'drag-me']),
+ ])
+
+ await mouseDragFromPointToPoint(
+ canvasControlsLayer,
+ elementToDragCenter,
+ windowPoint({ x: newParentCenterX, y: newSiblingCenterY }),
+ {
+ midDragCallback: async () => {
+ const guidelines =
+ renderResult.getEditorState().editor.canvas.controls.snappingGuidelines
+ expect(guidelines).toHaveLength(2)
+ await wait(5000)
+ },
+ },
+ )
+ })
+ it('when reparented from flex, it snaps to new parent and children of new parent', async () => {
+ const renderResult = await renderTestEditorWithCode(
+ makeTestProjectCodeWithSnippet(
+ project(`
+
+
+
+ `),
+ ),
+ 'await-first-dom-report',
+ )
+
+ const newParentCenterX = getElementCenterCoords(renderResult, NewParentTestId).x
+ const newSiblingCenterY = getElementCenterCoords(renderResult, NewSiblingTestId).y
+ const elementToDragCenter = getElementCenterCoords(renderResult, 'drag-me')
+ const canvasControlsLayer = renderResult.renderedDOM.getByTestId(CanvasControlsContainerID)
+
+ await selectComponentsForTest(renderResult, [
+ EP.appendNewElementPath(TestScenePath, ['root', 'container', 'drag-me']),
+ ])
+
+ await mouseDragFromPointToPoint(
+ canvasControlsLayer,
+ elementToDragCenter,
+ windowPoint({ x: newParentCenterX, y: newSiblingCenterY }),
+ {
+ midDragCallback: async () => {
+ const guidelines =
+ renderResult.getEditorState().editor.canvas.controls.snappingGuidelines
+ expect(guidelines).toHaveLength(2)
+ await wait(5000)
+ },
+ },
+ )
+ })
+ it('when reparented from flow, it snaps to new parent and children of new parent', async () => {
+ const renderResult = await renderTestEditorWithCode(
+ makeTestProjectCodeWithSnippet(
+ project(`
+
+
+
+ `),
+ ),
+ 'await-first-dom-report',
+ )
+
+ const newParentCenterX = getElementCenterCoords(renderResult, NewParentTestId).x
+ const newSiblingCenterY = getElementCenterCoords(renderResult, NewSiblingTestId).y
+ const elementToDragCenter = getElementCenterCoords(renderResult, 'drag-me')
+ const canvasControlsLayer = renderResult.renderedDOM.getByTestId(CanvasControlsContainerID)
+
+ await selectComponentsForTest(renderResult, [
+ EP.appendNewElementPath(TestScenePath, ['root', 'container', 'drag-me']),
+ ])
+
+ await mouseDragFromPointToPoint(
+ canvasControlsLayer,
+ elementToDragCenter,
+ windowPoint({ x: newParentCenterX, y: newSiblingCenterY }),
+ {
+ midDragCallback: async () => {
+ const guidelines =
+ renderResult.getEditorState().editor.canvas.controls.snappingGuidelines
+ expect(guidelines).toHaveLength(2)
+ await wait(5000)
+ },
+ },
+ )
+ })
+ })
})
function testProjectWithUnstyledDivOrFragment(type: FragmentLikeType): string {
@@ -2111,3 +2276,10 @@ function testProjectWithUnstyledDivOrFragmentOnCanvas(type: FragmentLikeType): s
`
return formatTestProjectCode(code)
}
+
+function getElementCenterCoords(editor: EditorRenderResult, testId: string): WindowPoint {
+ const element = editor.renderedDOM.getByTestId(testId)
+ const bounds = element.getBoundingClientRect()
+ const center = windowPoint({ x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 })
+ return center
+}
diff --git a/editor/src/components/canvas/canvas-strategies/strategies/shared-move-strategies-helpers.ts b/editor/src/components/canvas/canvas-strategies/strategies/shared-move-strategies-helpers.ts
index 93ce895d5e1b..dce71e288632 100644
--- a/editor/src/components/canvas/canvas-strategies/strategies/shared-move-strategies-helpers.ts
+++ b/editor/src/components/canvas/canvas-strategies/strategies/shared-move-strategies-helpers.ts
@@ -129,15 +129,14 @@ export function applyMoveCommon(
} else {
const constrainedDragAxis =
shiftKeyPressed && drag != null ? determineConstrainedDragAxis(drag) : null
-
- const targetsForSnapping = targets.map(
+ const targetsForSnapping = originalTargets.map(
(path) => interactionSession.updatedTargetPaths[EP.toString(path)] ?? path,
)
const snapTargets: ElementPath[] = gatherParentAndSiblingTargets(
canvasState.startingMetadata,
canvasState.startingAllElementProps,
canvasState.startingElementPathTree,
- originalTargets,
+ targetsForSnapping,
)
const moveGuidelines = collectParentAndSiblingGuidelines(
snapTargets,