Skip to content

Commit

Permalink
fix(grids) Handle Non-Offset Parent Grids. (#6649)
Browse files Browse the repository at this point in the history
- `runGridMoveAbsolute` now checks to see if the grid provides
layouting, if it does not then the closest offset global frame is
identified.
- Slightly widened the type of `zeroRectIfNullOrInfinity`.
  • Loading branch information
seanparsons authored and liady committed Dec 13, 2024
1 parent 5723c08 commit 63cc4f0
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import * as EP from '../../../../core/shared/element-path'
import type { WindowPoint } from '../../../../core/shared/math-utils'
import { offsetPoint, windowPoint } from '../../../../core/shared/math-utils'
import type { Modifiers } from '../../../../utils/modifiers'
import { cmdModifier, emptyModifiers } from '../../../../utils/modifiers'
import { CanvasControlsContainerID } from '../../controls/new-canvas-controls'
import type { Point } from '../../event-helpers.test-utils'
import {
mouseClickAtPoint,
mouseDownAtPoint,
mouseMoveToPoint,
mouseUpAtPoint,
} from '../../event-helpers.test-utils'
import type { EditorRenderResult } from '../../ui-jsx.test-utils'
import { getPrintedUiJsCode, renderTestEditorWithCode } from '../../ui-jsx.test-utils'

async function dragElement(
renderResult: EditorRenderResult,
targetTestId: string,
targetControlTestId: string,
dragDelta: WindowPoint,
modifiers: Modifiers,
): Promise<void> {
const targetElement = renderResult.renderedDOM.getByTestId(targetTestId)
const targetElementBounds = targetElement.getBoundingClientRect()
const canvasControlsLayer = renderResult.renderedDOM.getByTestId(CanvasControlsContainerID)

const startPoint = windowPoint({ x: targetElementBounds.x + 5, y: targetElementBounds.y + 5 })
const endPoint = offsetPoint(startPoint, dragDelta)

await mouseClickAtPoint(canvasControlsLayer, startPoint, { modifiers: cmdModifier })

const targetControl = renderResult.renderedDOM.getByTestId(targetControlTestId)

await mouseDownAtPoint(targetControl, startPoint, { modifiers: modifiers })

const delta: Point = {
x: endPoint.x - startPoint.x,
y: endPoint.y - startPoint.y,
}
await mouseMoveToPoint(
targetControl,
{
x: endPoint.x,
y: endPoint.y,
},
{
modifiers: modifiers,
eventOptions: {
movementX: delta.x,
movementY: delta.y,
buttons: 1,
},
},
)

await mouseUpAtPoint(canvasControlsLayer, endPoint, {
modifiers: modifiers,
})
}

describe('grid move absolute strategy', () => {
it('move an absolute element in a non-absolute grid', async () => {
const editor = await renderTestEditorWithCode(
`import * as React from 'react'
import { Storyboard } from 'utopia-api'
export var storyboard = (
<Storyboard data-uid='sb' data-testid='sb'>
<div
style={{
height: 'max-content',
position: 'absolute',
left: 776,
top: 6,
}}
data-uid='container'
data-testid='container'
>
<div
style={{
backgroundColor: '#aaaaaa33',
left: 100,
top: 100,
width: 1000,
height: 1000,
display: 'grid',
gridTemplateColumns: '200px 200px 200px',
gridTemplateRows: '200px 200px 200px',
gridGap: 10,
padding: 10,
}}
data-uid='grid'
data-testid='grid'
>
<div
style={{
gridColumn: 1,
gridRow: 1,
backgroundColor: '#f0f',
position: 'absolute',
left: 500,
top: 500,
width: 79,
height: 86,
}}
data-uid='dragme'
data-testid='dragme'
/>
</div>
</div>
</Storyboard>
)`,
'await-first-dom-report',
)

await dragElement(
editor,
'dragme',
'grid-cell-sb/container/grid/dragme',
windowPoint({ x: -200, y: -200 }),
emptyModifiers,
)

expect(getPrintedUiJsCode(editor.getEditorState())).toEqual(
`import * as React from 'react'
import { Storyboard } from 'utopia-api'
export var storyboard = (
<Storyboard data-uid='sb' data-testid='sb'>
<div
style={{
height: 'max-content',
position: 'absolute',
left: 776,
top: 6,
}}
data-uid='container'
data-testid='container'
>
<div
style={{
backgroundColor: '#aaaaaa33',
left: 100,
top: 100,
width: 1000,
height: 1000,
display: 'grid',
gridTemplateColumns: '200px 200px 200px',
gridTemplateRows: '200px 200px 200px',
gridGap: 10,
padding: 10,
}}
data-uid='grid'
data-testid='grid'
>
<div
style={{
backgroundColor: '#f0f',
position: 'absolute',
width: 79,
height: 86,
gridColumn: 1,
gridRow: 1,
top: 300,
left: 300,
}}
data-uid='dragme'
data-testid='dragme'
/>
</div>
</div>
</Storyboard>
)
`,
)

expect(1).toEqual(1)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,17 @@ function runGridMoveAbsolute(
]
}

function getContainingRect(): CanvasRectangle {
if (selectedElementMetadata.specialSizeMeasurements.immediateParentProvidesLayout) {
const gridCellGlobalFrame = getGlobalFrameOfGridCell(gridCellGlobalFrames, targetRootCell)
return zeroRectIfNullOrInfinity(gridCellGlobalFrame)
} else {
return zeroRectIfNullOrInfinity(
selectedElementMetadata.specialSizeMeasurements.coordinateSystemBounds,
)
}
}

// otherwise, return a change location + absolute adjustment
return [
...runGridChangeElementLocation(
Expand All @@ -225,12 +236,7 @@ function runGridMoveAbsolute(
gridTemplate,
null,
),
...gridChildAbsoluteMoveCommands(
selectedElementMetadata,
getGlobalFrameOfGridCell(gridCellGlobalFrames, targetRootCell) ??
canvasRectangle(zeroRectangle),
interactionData,
),
...gridChildAbsoluteMoveCommands(selectedElementMetadata, getContainingRect(), interactionData),
]
}

Expand Down
2 changes: 1 addition & 1 deletion editor/src/core/shared/math-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export function windowRectangle(
}

export function zeroRectIfNullOrInfinity<C extends CoordinateMarker>(
r: MaybeInfinityRectangle<C> | null,
r: MaybeInfinityRectangle<C> | null | undefined,
): Rectangle<C> {
return r == null || isInfinityRectangle(r) ? (zeroRectangle as Rectangle<C>) : r
}
Expand Down

0 comments on commit 63cc4f0

Please sign in to comment.