Skip to content

Commit

Permalink
Merge the core of the escape hatch commands (#4360)
Browse files Browse the repository at this point in the history
* chore(editor) Merge the core of the escape hatch commands

* chore(tests) Fix tests

* fix(editor) Converting to absolute now rounds the frame

* chore(tests) Fix tests

* chore(tests) Fix tests broken by merge

* fix(editor) prune bottom and right pins when fixing size
  • Loading branch information
Rheeseyb authored Oct 12, 2023
1 parent c9f299f commit b0c79fe
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ describe('Convert to absolute/escape hatch', () => {
right: 200,
bottom: 320,
top: 0,
left: 0
left: 0,
}}
data-uid='bbb'
data-testid='bbb'
Expand Down Expand Up @@ -1178,7 +1178,14 @@ describe('Convert to absolute/escape hatch', () => {
data-uid='aaa'
>
<View
style={{ backgroundColor: '#aaaaaa33', width: 200, height: 80, right: 185, bottom: 305, top: 15, left: 15, position: 'absolute', }}
style={{
backgroundColor: '#aaaaaa33',
width: 200,
height: 80,
top: 15,
left: 15,
position: 'absolute',
}}
data-uid='bbb'
data-testid='bbb'
/>
Expand Down Expand Up @@ -1298,7 +1305,14 @@ describe('Convert to absolute/escape hatch', () => {
data-uid='aaa'
>
<View
style={{ backgroundColor: '#aaaaaa33', width: 200, height: 80, right: 185, bottom: 305, top: 15, left: 15, position: 'absolute', }}
style={{
backgroundColor: '#aaaaaa33',
width: 200,
height: 80,
top: 15,
left: 15,
position: 'absolute',
}}
data-uid='bbb'
data-testid='bbb'
/>
Expand Down Expand Up @@ -1451,7 +1465,14 @@ describe('Convert to absolute/escape hatch', () => {
makeTestProjectCodeWithSnippet(
`<View style={{ ...(props.style || {}) }} data-uid='aaa'>
<View
style={{ backgroundColor: '#aaaaaa33', width: 200, height: 80, right: 185, bottom: 305, top: 15, left: 15, position: 'absolute', }}
style={{
backgroundColor: '#aaaaaa33',
width: 200,
height: 80,
top: 15,
left: 15,
position: 'absolute',
}}
data-uid='bbb'
data-testid='bbb'
/>
Expand Down Expand Up @@ -1512,7 +1533,14 @@ describe('Convert to absolute/escape hatch', () => {
makeTestProjectCodeWithSnippet(
`<View style={{ ...(props.style || {}) }} data-uid='aaa'>
<View
style={{ backgroundColor: '#aaaaaa33', width: 200, height: 80, right: 185, bottom: 305, top: 15, left: 15, position: 'absolute', }}
style={{
backgroundColor: '#aaaaaa33',
width: 200,
height: 80,
top: 15,
left: 15,
position: 'absolute',
}}
data-uid='bbb'
data-testid='bbb'
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ import type { ElementPathTrees } from '../../../../core/shared/element-path-tree
import { cssPixelLength } from '../../../inspector/common/css-utils'
import type { ProjectContentTreeRoot } from '../../../assets'
import { showToastCommand } from '../../commands/show-toast-command'
import { sizeToVisualDimensions } from '../../../inspector/inspector-common'
import {
getConvertIndividualElementToAbsoluteCommands,
sizeToVisualDimensions,
} from '../../../inspector/inspector-common'

export type SetHuggingParentToFixed =
| 'set-hugging-parent-to-fixed'
Expand Down Expand Up @@ -426,35 +429,29 @@ function collectSetLayoutPropCommands(
intendedBounds: Array<CanvasFrameAndTarget>
} {
const globalFrame = MetadataUtils.getFrameInCanvasCoords(path, metadata)
if (globalFrame != null && isFiniteRectangle(globalFrame)) {
const element = MetadataUtils.findElementByElementPath(metadata, path)
if (element != null && globalFrame != null && isFiniteRectangle(globalFrame)) {
const updatedGlobalFrame = offsetRect(globalFrame, dragDelta ?? zeroCanvasRect)
const intendedBounds: Array<CanvasFrameAndTarget> = [
{ frame: updatedGlobalFrame, target: path },
]

const newLocalFrame = MetadataUtils.getFrameRelativeToTargetContainingBlock(
targetParent ?? EP.parentPath(path),
metadata,
globalFrame,
updatedGlobalFrame,
)

const intendedBounds: Array<CanvasFrameAndTarget> = (() => {
if (globalFrame == null) {
return []
} else {
const updatedGlobalFrame = offsetRect(globalFrame, dragDelta ?? zeroCanvasRect)
return [{ frame: updatedGlobalFrame, target: path }]
}
})()

if (newLocalFrame != null) {
let commands: Array<CanvasCommand> = [
...sizeToVisualDimensions(metadata, canvasState.startingElementPathTree, path),
convertToAbsolute('always', path),
]
const updatePinsCommands = createUpdatePinsCommands(
const parentFlexDirection = element.specialSizeMeasurements.parentFlexDirection

let commands: Array<CanvasCommand> = getConvertIndividualElementToAbsoluteCommands(
path,
metadata,
canvasState,
dragDelta,
canvasState.startingElementPathTree,
newLocalFrame,
parentFlexDirection,
)
commands.push(...updatePinsCommands)

return { commands: commands, intendedBounds: intendedBounds }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import {
stripPinsConvertToVisualSize,
} from './reparent-property-strategies'
import { assertNever } from '../../../../../core/shared/utils'
import { flexChildProps, pruneFlexPropsCommands } from '../../../../inspector/inspector-common'
import { flexChildProps, prunePropsCommands } from '../../../../inspector/inspector-common'
import { setCssLengthProperty } from '../../../commands/set-css-length-command'
import type { ElementPathTrees } from '../../../../../core/shared/element-path-tree'
import {
Expand Down Expand Up @@ -221,7 +221,7 @@ export function positionElementToCoordinatesCommands(
pathLookup: OldPathToNewPathMapping,
): CanvasCommand[] {
const basicCommands = [
...pruneFlexPropsCommands(flexChildProps, elementToReparent.newPath),
...prunePropsCommands(flexChildProps, elementToReparent.newPath),
setCssLengthProperty(
'always',
elementToReparent.newPath,
Expand Down Expand Up @@ -280,7 +280,7 @@ export function positionElementToCoordinatesCommands(
}

return [
...pruneFlexPropsCommands(flexChildProps, targetPath),
...prunePropsCommands(flexChildProps, targetPath),
setProperty('always', targetPath, PP.create('style', 'position'), 'absolute'),
setCssLengthProperty(
'always',
Expand Down
1 change: 0 additions & 1 deletion editor/src/components/editor/global-shortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ import {
import {
detectAreElementsFlexContainers,
nukeAllAbsolutePositioningPropsCommands,
addPositionAbsoluteTopLeft,
sizeToVisualDimensions,
toggleResizeToFitSetToFixed,
isIntrinsicallyInlineElement,
Expand Down
108 changes: 79 additions & 29 deletions editor/src/components/inspector/inspector-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ import {
setPropHugStrategies,
} from './inspector-strategies/inspector-strategies'
import { commandsForFirstApplicableStrategy } from './inspector-strategies/inspector-strategy'
import { isFiniteRectangle, isInfinityRectangle } from '../../core/shared/math-utils'
import {
isFiniteRectangle,
isInfinityRectangle,
roundRectangleToNearestWhole,
type LocalRectangle,
} from '../../core/shared/math-utils'
import { inlineHtmlElements } from '../../utils/html-elements'
import { intersection } from '../../core/shared/set-utils'
import { showToastCommand } from '../canvas/commands/show-toast-command'
Expand All @@ -64,6 +69,7 @@ import {
groupConversionCommands,
} from '../canvas/canvas-strategies/strategies/group-conversion-helpers'
import { fixedSizeDimensionHandlingText } from '../text-editor/text-handling'
import { convertToAbsolute } from '../canvas/commands/convert-to-absolute-command'

export type StartCenterEnd = 'flex-start' | 'center' | 'flex-end'

Expand Down Expand Up @@ -384,7 +390,9 @@ export const flexChildProps = [
styleP('flexBasis'),
]

export function pruneFlexPropsCommands(
const flexChildAndBottomRightProps = [...flexChildProps, styleP('bottom'), styleP('right')]

export function prunePropsCommands(
props: PropertyPath[],
elementPath: ElementPath,
): Array<CanvasCommand> {
Expand Down Expand Up @@ -420,21 +428,30 @@ export function sizeToVisualDimensions(
pathTrees: ElementPathTrees,
elementPath: ElementPath,
): Array<CanvasCommand> {
const element = MetadataUtils.findElementByElementPath(metadata, elementPath)
if (element == null) {
const globalFrame = MetadataUtils.getFrameInCanvasCoords(elementPath, metadata)
if (globalFrame == null || isInfinityRectangle(globalFrame)) {
return []
}

const globalFrame = MetadataUtils.getFrameInCanvasCoords(elementPath, metadata)
if (globalFrame == null || isInfinityRectangle(globalFrame)) {
return sizeToDimensionsFromFrame(metadata, pathTrees, elementPath, globalFrame)
}

function sizeToDimensionsFromFrame(
metadata: ElementInstanceMetadataMap,
pathTrees: ElementPathTrees,
elementPath: ElementPath,
frame: { width: number; height: number },
): Array<CanvasCommand> {
const element = MetadataUtils.findElementByElementPath(metadata, elementPath)
if (element == null) {
return []
}

const width = fixedSizeDimensionHandlingText(metadata, pathTrees, elementPath, globalFrame.width)
const height = globalFrame.height
const width = fixedSizeDimensionHandlingText(metadata, pathTrees, elementPath, frame.width)
const height = frame.height

return [
...pruneFlexPropsCommands(flexChildProps, elementPath),
...prunePropsCommands(flexChildAndBottomRightProps, elementPath),
setCssLengthProperty(
'always',
elementPath,
Expand Down Expand Up @@ -465,7 +482,7 @@ export const sizeToVisualDimensionsAlongAxisInstance =
const value = globalFrame[dimension]

return [
...pruneFlexPropsCommands(flexChildProps, elementPath),
...prunePropsCommands(flexChildProps, elementPath),
setCssLengthProperty(
'always',
elementPath,
Expand Down Expand Up @@ -831,36 +848,27 @@ export function resizeToFillCommands(
return commands
}

export function addPositionAbsoluteTopLeft(
metadata: ElementInstanceMetadataMap,
function addPositionAbsoluteTopLeft(
elementPath: ElementPath,
localFrame: LocalRectangle,
parentFlexDirection: FlexDirection | null,
): Array<CanvasCommand> {
const element = MetadataUtils.findElementByElementPath(metadata, elementPath)
if (element == null) {
return []
}

const left = element.specialSizeMeasurements.offset.x
const top = element.specialSizeMeasurements.offset.y

const parentFlexDirection = element.specialSizeMeasurements.parentFlexDirection

return [
convertToAbsolute('always', elementPath),
setCssLengthProperty(
'always',
elementPath,
styleP('left'),
setExplicitCssValue(cssPixelLength(left)),
setExplicitCssValue(cssPixelLength(localFrame.x)),
parentFlexDirection,
),
setCssLengthProperty(
'always',
elementPath,
styleP('top'),
setExplicitCssValue(cssPixelLength(top)),
setExplicitCssValue(cssPixelLength(localFrame.y)),
parentFlexDirection,
),
setProperty('always', elementPath, styleP('position'), 'absolute'),
]
}

Expand Down Expand Up @@ -1120,12 +1128,54 @@ export function toggleAbsolutePositioningCommands(
: []),
]
} else {
return [
...sizeToVisualDimensions(jsxMetadata, elementPathTree, elementPath),
...addPositionAbsoluteTopLeft(jsxMetadata, elementPath),
]
return getConvertIndividualElementToAbsoluteCommandsFromMetadata(
elementPath,
jsxMetadata,
elementPathTree,
)
}
})

return commands
}

export function getConvertIndividualElementToAbsoluteCommandsFromMetadata(
target: ElementPath,
jsxMetadata: ElementInstanceMetadataMap,
elementPathTree: ElementPathTrees,
): Array<CanvasCommand> {
const localFrame = MetadataUtils.getFrame(target, jsxMetadata)
if (localFrame == null || isInfinityRectangle(localFrame)) {
return []
}

const element = MetadataUtils.findElementByElementPath(jsxMetadata, target)
if (element == null) {
return []
}

const parentFlexDirection = element.specialSizeMeasurements.parentFlexDirection

return getConvertIndividualElementToAbsoluteCommands(
target,
jsxMetadata,
elementPathTree,
localFrame,
parentFlexDirection,
)
}

export function getConvertIndividualElementToAbsoluteCommands(
target: ElementPath,
jsxMetadata: ElementInstanceMetadataMap,
elementPathTree: ElementPathTrees,
frame: LocalRectangle,
parentFlexDirection: FlexDirection | null,
): Array<CanvasCommand> {
// First round the frame so that we don't end up with half pixel values
const roundedFrame = roundRectangleToNearestWhole(frame)
return [
...sizeToDimensionsFromFrame(jsxMetadata, elementPathTree, target, roundedFrame),
...addPositionAbsoluteTopLeft(target, roundedFrame, parentFlexDirection),
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Axis, FlexAlignment, FlexJustifyContent } from '../inspector-commo
import {
filterKeepFlexContainers,
flexChildProps,
pruneFlexPropsCommands,
prunePropsCommands,
sizeToVisualDimensions,
} from '../inspector-common'
import { MetadataUtils } from '../../../core/model/element-metadata-utils'
Expand Down Expand Up @@ -115,7 +115,7 @@ export const updateFlexDirectionStrategies = (
return elements.flatMap((path) => [
setProperty('always', path, PP.create('style', 'flexDirection'), flexDirection),
...MetadataUtils.getChildrenPathsOrdered(metadata, pathTrees, path).flatMap((child) => [
...pruneFlexPropsCommands(flexChildProps, child),
...prunePropsCommands(flexChildProps, child),
...sizeToVisualDimensions(metadata, pathTrees, child),
]),
])
Expand Down
Loading

0 comments on commit b0c79fe

Please sign in to comment.