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) => `
+
+
+
+ ${innards} +
` + + it('when reparented from absolute, it snaps to new parent and children of new parent', async () => { + const renderResult = await renderTestEditorWithCode( + makeTestProjectCodeWithSnippet( + project(` +
+ Utopia logo +
+ `), + ), + '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(` +
+ Utopia logo +
+ `), + ), + '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(` +
+ Utopia logo +
+ `), + ), + '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,