Skip to content

Commit

Permalink
Absolute move should use the root cell in calculations (#6342)
Browse files Browse the repository at this point in the history
  • Loading branch information
bkrmendy authored Sep 10, 2024
1 parent 1293ce4 commit c929e92
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,23 @@ export function getGridCellBoundsFromCanvas(
height: cellHeight,
}
}

export function getGridPlaceholderDomElementFromCoordinates(params: {
row: number
column: number
}): HTMLElement | null {
return document.querySelector(
`[data-grid-row="${params.row}"]` + `[data-grid-column="${params.column}"]`,
)
}

export function getCellWindowRect(coords: GridCellCoordinates): WindowRectangle | null {
const element = getGridPlaceholderDomElementFromCoordinates(coords)
if (element == null) {
return null
}

const domRect = element!.getBoundingClientRect()
const windowRect = windowRectangle(domRect)
return windowRect
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { cssNumber, isCSSKeyword } from '../../../inspector/common/css-utils'
import { setCssLengthProperty } from '../../commands/set-css-length-command'
import type { GridCellCoordinates } from './grid-cell-bounds'
import {
getCellWindowRect,
getGridCellUnderMouse,
getGridCellUnderMouseRecursive,
gridCellCoordinates,
Expand Down Expand Up @@ -86,16 +87,6 @@ export function runGridRearrangeMove(

const targetCellUnderMouse = targetCellData?.gridCellCoordinates ?? null

const absoluteMoveCommands =
targetCellData == null
? []
: gridChildAbsoluteMoveCommands(
MetadataUtils.findElementByElementPath(jsxMetadata, targetElement),
targetCellData.cellWindowRectangle,
interactionData,
{ scale: canvasScale, canvasOffset: canvasOffset },
)

const originalElementMetadata = MetadataUtils.findElementByElementPath(
jsxMetadata,
selectedElement,
Expand Down Expand Up @@ -148,6 +139,18 @@ export function runGridRearrangeMove(

const targetRootCell = gridCellCoordinates(row.start, column.start)

const windowRect = getCellWindowRect(targetRootCell)

const absoluteMoveCommands =
windowRect == null
? []
: gridChildAbsoluteMoveCommands(
MetadataUtils.findElementByElementPath(jsxMetadata, targetElement),
windowRect,
interactionData,
{ scale: canvasScale, canvasOffset: canvasOffset },
)

const gridCellMoveCommands = setGridPropsCommands(targetElement, gridTemplate, {
gridColumnStart: gridPositionValue(column.start),
gridColumnEnd: gridPositionValue(column.end),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,89 @@ export var storyboard = (
})
}
})

it("can move element spanning multiple cell by a cell that isn't the root cell", async () => {
const editor = await renderTestEditorWithCode(
`import { Scene, Storyboard } from 'utopia-api'
export var storyboard = (
<Storyboard data-uid='sb'>
<Scene
data-uid='scene'
id='playground-scene'
commentId='playground-scene'
style={{
width: 700,
height: 759,
position: 'absolute',
left: 212,
top: 128,
}}
data-label='Playground'
>
<div
data-uid='grid'
style={{
backgroundColor: '#fefefe',
position: 'absolute',
left: 123,
top: 133,
width: 461,
height: 448,
display: 'grid',
gridTemplateColumns: '1fr 1fr 1fr 1fr',
gridTemplateRows: '1fr 1fr 1fr 1fr',
border: '5px solid #000',
gridGap: 10,
}}
>
<div
data-uid='child'
data-testid='child'
style={{
position: 'absolute',
wordBreak: 'break-word',
width: 127,
height: 122,
backgroundColor: '#ff2800',
gridColumn: 2,
gridRow: 2,
top: 45,
left: 41.25,
}}
/>
</div>
</Scene>
</Storyboard>
)
`,
'await-first-dom-report',
)

await selectComponentsForTest(editor, [EP.fromString('sb/scene/grid/child')])

const child = editor.renderedDOM.getByTestId('child')
const childBounds = child.getBoundingClientRect()
const startPoint = windowPoint({
x: Math.floor(childBounds.left + childBounds.width - 3),
y: Math.floor(childBounds.top + childBounds.height - 3),
})

await mouseDragFromPointToPoint(
editor.renderedDOM.getByTestId(GridCellTestId(EP.fromString('sb/scene/grid/child'))),
startPoint,
offsetPoint(startPoint, windowPoint({ x: -100, y: -100 })),
)

{
const { top, left, gridColumn, gridRow } = child.style
expect({ top, left, gridColumn, gridRow }).toEqual({
gridColumn: '1',
gridRow: '1',
left: '60.5px',
top: '61px',
})
}
})
})
})

Expand Down
14 changes: 4 additions & 10 deletions editor/src/components/canvas/controls/grid-controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ import { CanvasOffsetWrapper } from './canvas-offset-wrapper'
import { CanvasLabel } from './select-mode/controls-common'
import { useMaybeHighlightElement } from './select-mode/select-mode-hooks'
import type { GridCellCoordinates } from '../canvas-strategies/strategies/grid-cell-bounds'
import { gridCellTargetId } from '../canvas-strategies/strategies/grid-cell-bounds'
import {
getGridPlaceholderDomElementFromCoordinates,
gridCellTargetId,
} from '../canvas-strategies/strategies/grid-cell-bounds'

const CELL_ANIMATION_DURATION = 0.15 // seconds

Expand Down Expand Up @@ -1686,15 +1689,6 @@ export function getGridPlaceholderDomElement(elementPath: ElementPath): HTMLElem
return document.getElementById(gridKeyFromPath(elementPath))
}

export function getGridPlaceholderDomElementFromCoordinates(params: {
row: number
column: number
}): HTMLElement | null {
return document.querySelector(
`[data-grid-row="${params.row}"]` + `[data-grid-column="${params.column}"]`,
)
}

const gridPlaceholderBorder = (color: string) => `2px solid ${color}`

export function controlsForGridPlaceholders(gridPath: ElementPath): ControlWithProps<any> {
Expand Down

0 comments on commit c929e92

Please sign in to comment.