Skip to content

Commit

Permalink
fix(grids) Handle Spans In Pin Outlines (#6644)
Browse files Browse the repository at this point in the history
- Extracted out the `printPin` function.
- Implemented `nullHandlingPrintPin` as a thin wrapper around
`printPin`.
- `GridElementContainingBlock` now uses `nullHandlingPrintPin` instead
of `gridPositionToValue` to build the grid column/row start/end values.
  • Loading branch information
seanparsons authored and liady committed Dec 13, 2024
1 parent 63cc4f0 commit 2010de5
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,29 @@ export function isAutoGridPin(v: GridPositionOrSpan): boolean {
return isCSSKeyword(v) && v.value === 'auto'
}

export function printPin(
gridTemplate: GridContainerProperties,
pin: GridPositionOrSpan,
axis: 'row' | 'column',
): string | number {
if (isGridSpan(pin)) {
return stringifyGridSpan(pin)
}
if (isCSSKeyword(pin)) {
return pin.value
}
const tracks =
axis === 'column' ? gridTemplate.gridTemplateColumns : gridTemplate.gridTemplateRows
const maybeLineName =
tracks?.type === 'DIMENSIONS'
? tracks.dimensions.find((_, index) => index + 1 === pin.numericalPosition)?.lineName
: null
if (maybeLineName != null) {
return maybeLineName
}
return pin.numericalPosition ?? 'auto'
}

export function getCommandsForGridItemPlacement(
elementPath: ElementPath,
gridTemplate: GridContainerProperties,
Expand All @@ -94,25 +117,6 @@ export function getCommandsForGridItemPlacement(
]),
]

function printPin(pin: GridPositionOrSpan, axis: 'row' | 'column'): string | number {
if (isGridSpan(pin)) {
return stringifyGridSpan(pin)
}
if (isCSSKeyword(pin)) {
return pin.value
}
const tracks =
axis === 'column' ? gridTemplate.gridTemplateColumns : gridTemplate.gridTemplateRows
const maybeLineName =
tracks?.type === 'DIMENSIONS'
? tracks.dimensions.find((_, index) => index + 1 === pin.numericalPosition)?.lineName
: null
if (maybeLineName != null) {
return maybeLineName
}
return pin.numericalPosition ?? 'auto'
}

function serializeAxis(
startPosition: GridPositionOrSpan,
endPosition: GridPositionOrSpan,
Expand All @@ -127,8 +131,8 @@ export function getCommandsForGridItemPlacement(
| 'gridRowEnd'
value: string | number
} {
const startValue = printPin(startPosition, axis)
const endValue = printPin(endPosition, axis)
const startValue = printPin(gridTemplate, startPosition, axis)
const endValue = printPin(gridTemplate, endPosition, axis)

if (isAutoGridPin(startPosition) && !isAutoGridPin(endPosition)) {
return {
Expand Down
121 changes: 121 additions & 0 deletions editor/src/components/canvas/controls/grid-controls.spec.browser2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -615,4 +615,125 @@ describe('Grid Pin Outlines', () => {
bottom: { x: 1781.5, y: 555.5, width: 1, height: 5 },
})
})

it('pinned top and left, grid rows and columns fully specified and not absolutely positioned, with a row start span', async () => {
const result = await testGridOutlines('storyboard/scene/grid/grid-child', {
top: 5,
left: 12,
gridRowStart: 'span 2',
gridColumnStart: 3,
gridRowEnd: 2,
gridColumnEnd: 3,
width: 50,
height: 50,
})
expect(result).toEqual({})
})
it('pinned top and left, grid rows and columns fully specified and absolutely positioned, with a row start span', async () => {
const result = await testGridOutlines('storyboard/scene/grid/grid-child', {
position: 'absolute',
top: 5,
left: 12,
gridRowStart: 'span 2',
gridColumnStart: 3,
gridRowEnd: 2,
gridColumnEnd: 3,
width: 50,
height: 50,
})
expect(result).toEqual({
left: { x: 688.5, y: 190.5, width: 12, height: 1 },
top: { x: 725.5, y: 160.5, width: 1, height: 5 },
})
})
it('pinned bottom and right, grid rows and columns fully specified and not absolutely positioned, with a row start span', async () => {
const result = await testGridOutlines('storyboard/scene/grid/grid-child', {
bottom: 5,
right: 12,
gridRowStart: 'span 2',
gridColumnStart: 3,
gridRowEnd: 2,
gridColumnEnd: 3,
width: 50,
height: 50,
})
expect(result).toEqual({})
})
it('pinned bottom and right, grid rows and columns fully specified and absolutely positioned, with a row start span', async () => {
const result = await testGridOutlines('storyboard/scene/grid/grid-child', {
position: 'absolute',
bottom: 5,
right: 12,
gridRowStart: 'span 2',
gridColumnStart: 3,
gridRowEnd: 2,
gridColumnEnd: 3,
width: 50,
height: 50,
})
expect(result).toEqual({
right: { x: 777.5, y: 240.5, width: 12, height: 1 },
bottom: { x: 751.5, y: 266.5, width: 1, height: 5 },
})
})
it('pinned top and left, grid rows and columns fully specified and not absolutely positioned, with a row end span', async () => {
const result = await testGridOutlines('storyboard/scene/grid/grid-child', {
top: 5,
left: 12,
gridRowStart: 2,
gridColumnStart: 3,
gridRowEnd: 'span 2',
gridColumnEnd: 3,
width: 50,
height: 50,
})
expect(result).toEqual({})
})
it('pinned top and left, grid rows and columns fully specified and absolutely positioned, with a row end span', async () => {
const result = await testGridOutlines('storyboard/scene/grid/grid-child', {
position: 'absolute',
top: 5,
left: 12,
gridRowStart: 2,
gridColumnStart: 3,
gridRowEnd: 'span 2',
gridColumnEnd: 3,
width: 50,
height: 50,
})
expect(result).toEqual({
left: { x: 688.5, y: 315.5, width: 12, height: 1 },
top: { x: 725.5, y: 285.5, width: 1, height: 5 },
})
})
it('pinned bottom and right, grid rows and columns fully specified and not absolutely positioned, with a row end span', async () => {
const result = await testGridOutlines('storyboard/scene/grid/grid-child', {
bottom: 5,
right: 12,
gridRowStart: 2,
gridColumnStart: 3,
gridRowEnd: 'span 2',
gridColumnEnd: 3,
width: 50,
height: 50,
})
expect(result).toEqual({})
})
it('pinned bottom and right, grid rows and columns fully specified and absolutely positioned, with a row end span', async () => {
const result = await testGridOutlines('storyboard/scene/grid/grid-child', {
position: 'absolute',
bottom: 5,
right: 12,
gridRowStart: 2,
gridColumnStart: 3,
gridRowEnd: 'span 2',
gridColumnEnd: 3,
width: 50,
height: 50,
})
expect(result).toEqual({
right: { x: 777.5, y: 470.5, width: 12, height: 1 },
bottom: { x: 751.5, y: 496.5, width: 1, height: 5 },
})
})
})
51 changes: 33 additions & 18 deletions editor/src/components/canvas/controls/grid-controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import * as EP from '../../../core/shared/element-path'
import type {
ElementInstanceMetadataMap,
GridAutoOrTemplateDimensions,
GridContainerProperties,
GridPositionOrSpan,
} from '../../../core/shared/element-template'
import {
Expand Down Expand Up @@ -73,6 +74,7 @@ import {
getGridRelatedIndexes,
getGridElementPinState,
gridPositionToValue,
printPin,
getGridIdentifierContainerOrComponentPath,
gridIdentifierToString,
gridIdentifiersSimilar,
Expand Down Expand Up @@ -1944,6 +1946,17 @@ export interface GridElementContainingBlockProps {
gridChild: ElementPath
}

function nullHandlingPrintPin(
gridTemplate: GridContainerProperties | null | undefined,
pin: GridPositionOrSpan | null | undefined,
axis: 'row' | 'column',
): string | number | undefined {
if (gridTemplate == null || pin == null) {
return undefined
}
return printPin(gridTemplate, pin, axis)
}

const GridElementContainingBlock = React.memo<GridElementContainingBlockProps>((props) => {
const gridData = useGridMeasurementHelperData(props.gridPath, 'element')
const scale = useEditorState(
Expand Down Expand Up @@ -1975,24 +1988,26 @@ const GridElementContainingBlock = React.memo<GridElementContainingBlockProps>((
const gridFromProps = childMetadata.specialSizeMeasurements.elementGridPropertiesFromProps
const gridComputed = childMetadata.specialSizeMeasurements.elementGridProperties
return {
gridColumnStart:
gridPositionToValue(
gridFromProps.gridColumnStart ?? gridComputed.gridColumnStart,
null,
) ?? undefined,
gridColumnEnd:
gridPositionToValue(
gridFromProps.gridColumnEnd ?? gridComputed.gridColumnEnd,
gridFromProps.gridColumnStart ?? gridComputed.gridColumnStart,
) ?? undefined,
gridRowStart:
gridPositionToValue(gridFromProps.gridRowStart ?? gridComputed.gridRowStart, null) ??
undefined,
gridRowEnd:
gridPositionToValue(
gridFromProps.gridRowEnd ?? gridComputed.gridRowEnd,
gridFromProps.gridRowStart ?? gridComputed.gridRowStart,
) ?? undefined,
gridColumnStart: nullHandlingPrintPin(
childMetadata.specialSizeMeasurements.containerGridProperties,
gridFromProps.gridColumnStart ?? gridComputed.gridColumnStart,
'column',
),
gridColumnEnd: nullHandlingPrintPin(
childMetadata.specialSizeMeasurements.containerGridProperties,
gridFromProps.gridColumnEnd ?? gridComputed.gridColumnEnd,
'column',
),
gridRowStart: nullHandlingPrintPin(
childMetadata.specialSizeMeasurements.containerGridProperties,
gridFromProps.gridRowStart ?? gridComputed.gridRowStart,
'row',
),
gridRowEnd: nullHandlingPrintPin(
childMetadata.specialSizeMeasurements.containerGridProperties,
gridFromProps.gridRowEnd ?? gridComputed.gridRowEnd,
'row',
),
position: childMetadata.specialSizeMeasurements.position ?? undefined,
}
},
Expand Down

0 comments on commit 2010de5

Please sign in to comment.