Skip to content

Commit

Permalink
Resize A Grid (#6032)
Browse files Browse the repository at this point in the history
- Added `resizeGridStrategy` to `resizeStrategies`.
- Added `GridAxisHandle` to `CanvasControlType`.
- Implemented `resizeGridStrategy`.
- Added `GridControls`.
  • Loading branch information
seanparsons authored Jul 2, 2024
1 parent 551feb3 commit 042a958
Show file tree
Hide file tree
Showing 9 changed files with 772 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import type { InsertionSubject, InsertionSubjectWrapper } from '../../editor/edi
import { generateUidWithExistingComponents } from '../../../core/model/element-template-utils'
import { retargetStrategyToChildrenOfFragmentLikeElements } from './strategies/fragment-like-helpers'
import { MetadataUtils } from '../../../core/model/element-metadata-utils'
import { resizeGridStrategy } from './strategies/resize-grid-strategy'

export type CanvasStrategyFactory = (
canvasState: InteractionCanvasState,
Expand Down Expand Up @@ -100,13 +101,14 @@ const resizeStrategies: MetaCanvasStrategy = (
customStrategyState: CustomStrategyState,
): Array<CanvasStrategy> => {
return mapDropNulls(
(factory) => factory(canvasState, interactionSession),
(factory) => factory(canvasState, interactionSession, customStrategyState),
[
keyboardAbsoluteResizeStrategy,
absoluteResizeBoundingBoxStrategy,
flexResizeBasicStrategy,
flexResizeStrategy,
basicResizeStrategy,
resizeGridStrategy,
],
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,20 @@ export function flexGapHandle(): FlexGapHandle {
}
}

export interface GridAxisHandle {
type: 'GRID_AXIS_HANDLE'
axis: 'column' | 'row'
columnOrRow: number
}

export function gridAxisHandle(axis: 'column' | 'row', columnOrRow: number): GridAxisHandle {
return {
type: 'GRID_AXIS_HANDLE',
axis: axis,
columnOrRow: columnOrRow,
}
}

export interface PaddingResizeHandle {
type: 'PADDING_RESIZE_HANDLE'
edgePiece: EdgePiece
Expand Down Expand Up @@ -610,6 +624,7 @@ export type CanvasControlType =
| KeyboardCatcherControl
| ReorderSlider
| BorderRadiusResizeHandle
| GridAxisHandle

export function isDragToPan(
interaction: InteractionSession | null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,324 @@
import { getPrintedUiJsCode, renderTestEditorWithCode } from '../../ui-jsx.test-utils'
import * as EP from '../../../../core/shared/element-path'
import { selectComponents } from '../../../../components/editor/actions/meta-actions'
import { CanvasControlsContainerID } from '../../controls/new-canvas-controls'
import { mouseDownAtPoint, mouseMoveToPoint, mouseUpAtPoint } from '../../event-helpers.test-utils'
import { canvasPoint } from '../../../../core/shared/math-utils'

const testProject = `
import * as React from 'react'
import { Storyboard } from 'utopia-api'
export var storyboard = (
<Storyboard data-uid='sb'>
<div
data-uid='grid'
data-testid='grid'
style={{
position: 'absolute',
left: 25,
top: 305,
display: 'grid',
gap: 10,
width: 600,
height: 600,
gridTemplateColumns: '2.4fr 1fr 1fr',
gridTemplateRows: '99px 109px 90px',
height: 'max-content',
}}
>
<div
data-uid='row-1-column-1'
data-testid='row-1-column-1'
style={{
backgroundColor: 'green',
gridColumnStart: 1,
gridColumnEnd: 1,
gridRowStart: 2,
gridRowEnd: 2,
}}
/>
<div
data-uid='row-1-column-2'
data-testid='row-1-column-2'
style={{ backgroundColor: 'blue' }}
/>
<div
data-uid='row-1-column-3'
data-testid='row-1-column-3'
style={{ backgroundColor: 'pink' }}
/>
<div
data-uid='row-2-column-1'
data-testid='row-2-column-1'
style={{
backgroundColor: 'green',
gridColumnStart: 3,
gridColumnEnd: 4,
gridRowStart: 2,
gridRowEnd: 4,
}}
/>
<div
data-uid='row-2-column-2'
data-testid='row-2-column-2'
style={{
backgroundColor: 'blue',
gridColumnStart: 2,
gridColumnEnd: 2,
gridRowStart: 2,
gridRowEnd: 2,
}}
/>
<div
data-uid='row-2-column-3'
data-testid='row-2-column-3'
style={{ backgroundColor: 'pink' }}
/>
<div
data-uid='row-3-column-1'
data-testid='row-3-column-1'
style={{ backgroundColor: 'green' }}
/>
<div
data-uid='row-3-column-2'
data-testid='row-3-column-2'
style={{ backgroundColor: 'blue' }}
/>
<div
data-uid='row-3-column-3'
data-testid='row-3-column-3'
style={{ backgroundColor: 'pink' }}
/>
</div>
</Storyboard>
)
`

describe('resize a grid', () => {
it('update a fractionally sized column', async () => {
const renderResult = await renderTestEditorWithCode(testProject, 'await-first-dom-report')
const target = EP.fromString(`sb/grid/row-1-column-2`)
await renderResult.dispatch(selectComponents([target], false), true)
await renderResult.getDispatchFollowUpActionsFinished()
const canvasControlsLayer = renderResult.renderedDOM.getByTestId(CanvasControlsContainerID)
const resizeControl = renderResult.renderedDOM.getByTestId(`grid-column-handle-1`)
const resizeControlRect = resizeControl.getBoundingClientRect()
const startPoint = canvasPoint({
x: resizeControlRect.x + resizeControlRect.width / 2,
y: resizeControlRect.y + resizeControlRect.height / 2,
})
const endPoint = canvasPoint({
x: startPoint.x + 20,
y: startPoint.y,
})
await mouseMoveToPoint(resizeControl, startPoint)
await mouseDownAtPoint(resizeControl, startPoint)
await mouseMoveToPoint(canvasControlsLayer, endPoint)
await mouseUpAtPoint(canvasControlsLayer, endPoint)
await renderResult.getDispatchFollowUpActionsFinished()

expect(getPrintedUiJsCode(renderResult.getEditorState()))
.toEqual(`import * as React from 'react'
import { Storyboard } from 'utopia-api'
export var storyboard = (
<Storyboard data-uid='sb'>
<div
data-uid='grid'
data-testid='grid'
style={{
position: 'absolute',
left: 25,
top: 305,
display: 'grid',
gap: 10,
width: 600,
height: 600,
gridTemplateColumns: '2.4fr 2.5fr 1fr',
gridTemplateRows: '99px 109px 90px',
height: 'max-content',
}}
>
<div
data-uid='row-1-column-1'
data-testid='row-1-column-1'
style={{
backgroundColor: 'green',
gridColumnStart: 1,
gridColumnEnd: 1,
gridRowStart: 2,
gridRowEnd: 2,
}}
/>
<div
data-uid='row-1-column-2'
data-testid='row-1-column-2'
style={{ backgroundColor: 'blue' }}
/>
<div
data-uid='row-1-column-3'
data-testid='row-1-column-3'
style={{ backgroundColor: 'pink' }}
/>
<div
data-uid='row-2-column-1'
data-testid='row-2-column-1'
style={{
backgroundColor: 'green',
gridColumnStart: 3,
gridColumnEnd: 4,
gridRowStart: 2,
gridRowEnd: 4,
}}
/>
<div
data-uid='row-2-column-2'
data-testid='row-2-column-2'
style={{
backgroundColor: 'blue',
gridColumnStart: 2,
gridColumnEnd: 2,
gridRowStart: 2,
gridRowEnd: 2,
}}
/>
<div
data-uid='row-2-column-3'
data-testid='row-2-column-3'
style={{ backgroundColor: 'pink' }}
/>
<div
data-uid='row-3-column-1'
data-testid='row-3-column-1'
style={{ backgroundColor: 'green' }}
/>
<div
data-uid='row-3-column-2'
data-testid='row-3-column-2'
style={{ backgroundColor: 'blue' }}
/>
<div
data-uid='row-3-column-3'
data-testid='row-3-column-3'
style={{ backgroundColor: 'pink' }}
/>
</div>
</Storyboard>
)
`)
})

it('update a pixel sized row', async () => {
const renderResult = await renderTestEditorWithCode(testProject, 'await-first-dom-report')
const target = EP.fromString(`sb/grid/row-1-column-2`)
await renderResult.dispatch(selectComponents([target], false), true)
await renderResult.getDispatchFollowUpActionsFinished()
const canvasControlsLayer = renderResult.renderedDOM.getByTestId(CanvasControlsContainerID)
const resizeControl = renderResult.renderedDOM.getByTestId(`grid-row-handle-1`)
const resizeControlRect = resizeControl.getBoundingClientRect()
const startPoint = canvasPoint({
x: resizeControlRect.x + resizeControlRect.width / 2,
y: resizeControlRect.y + resizeControlRect.height / 2,
})
const endPoint = canvasPoint({
x: startPoint.x,
y: startPoint.y + 20,
})
await mouseMoveToPoint(resizeControl, startPoint)
await mouseDownAtPoint(resizeControl, startPoint)
await mouseMoveToPoint(canvasControlsLayer, endPoint)
await mouseUpAtPoint(canvasControlsLayer, endPoint)
await renderResult.getDispatchFollowUpActionsFinished()

expect(getPrintedUiJsCode(renderResult.getEditorState()))
.toEqual(`import * as React from 'react'
import { Storyboard } from 'utopia-api'
export var storyboard = (
<Storyboard data-uid='sb'>
<div
data-uid='grid'
data-testid='grid'
style={{
position: 'absolute',
left: 25,
top: 305,
display: 'grid',
gap: 10,
width: 600,
height: 600,
gridTemplateColumns: '2.4fr 1fr 1fr',
gridTemplateRows: '99px 129px 90px',
height: 'max-content',
}}
>
<div
data-uid='row-1-column-1'
data-testid='row-1-column-1'
style={{
backgroundColor: 'green',
gridColumnStart: 1,
gridColumnEnd: 1,
gridRowStart: 2,
gridRowEnd: 2,
}}
/>
<div
data-uid='row-1-column-2'
data-testid='row-1-column-2'
style={{ backgroundColor: 'blue' }}
/>
<div
data-uid='row-1-column-3'
data-testid='row-1-column-3'
style={{ backgroundColor: 'pink' }}
/>
<div
data-uid='row-2-column-1'
data-testid='row-2-column-1'
style={{
backgroundColor: 'green',
gridColumnStart: 3,
gridColumnEnd: 4,
gridRowStart: 2,
gridRowEnd: 4,
}}
/>
<div
data-uid='row-2-column-2'
data-testid='row-2-column-2'
style={{
backgroundColor: 'blue',
gridColumnStart: 2,
gridColumnEnd: 2,
gridRowStart: 2,
gridRowEnd: 2,
}}
/>
<div
data-uid='row-2-column-3'
data-testid='row-2-column-3'
style={{ backgroundColor: 'pink' }}
/>
<div
data-uid='row-3-column-1'
data-testid='row-3-column-1'
style={{ backgroundColor: 'green' }}
/>
<div
data-uid='row-3-column-2'
data-testid='row-3-column-2'
style={{ backgroundColor: 'blue' }}
/>
<div
data-uid='row-3-column-3'
data-testid='row-3-column-3'
style={{ backgroundColor: 'pink' }}
/>
</div>
</Storyboard>
)
`)
})
})
Loading

0 comments on commit 042a958

Please sign in to comment.