Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve span when changing grid item position #6633

Merged
merged 10 commits into from
Nov 14, 2024

Conversation

ruggi
Copy link
Contributor

@ruggi ruggi commented Nov 13, 2024

Problem:

span values for grid child positioning props are wiped when using gridChangeElementLocationStrategy.

Fix:

Rework the way grid element props are calculated when changing element location pins, so that spans are respected and kept in place if present.

The behavior is now so that:

  • when it makes sense to do so, return shorthand versions of grid positioning props
  • when moving an element with span values, support moving them when the span is in the starting prop as well as the ending prop

Examples for moving a item one cell to the right:

Initial config Result
gridColumn: 'span 2' gridColumn: 'span 2 / 4'
gridColumn: '2 / span 2' gridColumn: '3 / span 2'
gridColumnStart: 'span 2' gridColumn: 'span 2 / 4'
gridColumnEnd: 'span 2' gridColumn: '3 / span 2'

Note: a subsequent PR will take care of also keepign span intact for the reorder strategy.

Fixes #6639

Copy link
Contributor

github-actions bot commented Nov 13, 2024

Try me

Copy link

relativeci bot commented Nov 13, 2024

#15130 Bundle Size — 58.08MiB (~+0.01%).

1485b74(current) vs d1d46c1 master#15127(baseline)

Warning

Bundle contains 70 duplicate packages – View duplicate packages

Bundle metrics  Change 2 changes Regression 1 regression
                 Current
#15130
     Baseline
#15127
Regression  Initial JS 41.05MiB(~+0.01%) 41.05MiB
No change  Initial CSS 0B 0B
Change  Cache Invalidation 18.66% 18.01%
No change  Chunks 20 20
No change  Assets 22 22
No change  Modules 4169 4169
No change  Duplicate Modules 213 213
No change  Duplicate Code 27.3% 27.3%
No change  Packages 477 477
No change  Duplicate Packages 70 70
Bundle size by type  Change 2 changes Regression 1 regression Improvement 1 improvement
                 Current
#15130
     Baseline
#15127
Regression  JS 58.07MiB (~+0.01%) 58.07MiB
Improvement  HTML 7.37KiB (-0.25%) 7.39KiB

Bundle analysis reportBranch feat/preserve-span-change-positi...Project dashboard


Generated by RelativeCIDocumentationReport issue

): {
property:
| 'gridColumn'
| 'gridColumnStart'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this and the other start are currently unused but I figured it's just easy to leave them here if we want to play around with this logic a bit

@@ -594,9 +699,9 @@ export var storyboard = (
child.style
expect({ top, left, gridColumnStart, gridColumnEnd, gridRowStart, gridRowEnd }).toEqual({
gridColumnStart: '1',
gridColumnEnd: '',
gridColumnEnd: 'auto',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reminder: these are NOT being serialized, it's just that the computed style defaults these to auto if a shorthand is used (which is fine)

@ruggi ruggi marked this pull request as ready for review November 13, 2024 18:19
@ruggi ruggi changed the title Preserve span when changing position Preserve span when changing grid item position Nov 13, 2024
# Conflicts:
#	editor/src/components/canvas/canvas-strategies/strategies/grid-change-element-location-strategy.ts
export function isAutoGridPin(v: GridPositionOrSpan): boolean {
return isCSSKeyword(v) && v.value === 'auto'
}

export function setGridPropsCommands(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these command generator functions are usually called get * commands or create * commands. And since this is not setting all grid props, just the placement are props, I would rename it to something like getCommandsForGritItemPlacement

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

renamed in b75261c (#6633)

Comment on lines 140 to 145
(isCSSKeyword(endPosition) && endPosition.value === 'auto') ||
(isGridPositionNumericValue(endPosition) &&
isGridPositionNumericValue(startPosition) &&
(endPosition.numericalPosition ?? 0) >= (startPosition.numericalPosition ?? 0) &&
(endPosition.numericalPosition ?? 0) - (startPosition.numericalPosition ?? 0) <= 1) ||
startValue === endValue
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you move this to a helper function with names? I had to ask Cursor what this code does

(btw here's what it wrote

Is the end position 'auto'?
Are both positions numeric, and is the end position either equal to or one greater than the start position?
Are the start and end values equal?

)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// ... existing code ...
function shouldUseSimplifiedGridFormat(
  startPosition: GridPositionOrSpan,
  endPosition: GridPositionOrSpan,
  startValue: string | number,
  endValue: string | number,
): boolean {
  // Case 1: End position is 'auto'
  if (isCSSKeyword(endPosition) && endPosition.value === 'auto') {
    return true
  }

  // Case 2: Both positions are numeric and span only 1 cell
  if (isGridPositionNumericValue(startPosition) && isGridPositionNumericValue(endPosition)) {
    const start = startPosition.numericalPosition ?? 0
    const end = endPosition.numericalPosition ?? 0
    const isOneOrNoCellSpan = end - start <= 1 && end >= start
    if (isOneOrNoCellSpan) {
      return true
    }
  }

  // Case 3: Start and end values are the same
  return startValue === endValue
}

// Then in the original code:
if (shouldUseSimplifiedGridFormat(startPosition, endPosition, startValue, endValue)) {
  return {
    property: axis === 'column' ? 'gridColumn' : 'gridRow',
    value: startValue,
  }
}
// ... existing code ...

impressive suggestion from Cursor!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in fc142ff (#6633)

(elementProperties) => {
function shouldKeep(shorthandProp: 'gridColumn' | 'gridRow'): boolean {
const longhandProp = shorthandProp === 'gridColumn' ? 'gridColumnEnd' : 'gridRowEnd'
function getUpdatedPins(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please rewrite this to not use mutation!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in 1485b74 (#6633)

Copy link
Contributor

@balazsbajorics balazsbajorics left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some feedback about coding style, but overall looks good!

@ruggi ruggi merged commit 6a652a3 into master Nov 14, 2024
16 checks passed
@ruggi ruggi deleted the feat/preserve-span-change-position branch November 14, 2024 11:01
liady pushed a commit that referenced this pull request Dec 13, 2024
**Problem:**

`span` values for grid child positioning props are wiped when using
`gridChangeElementLocationStrategy`.

**Fix:**

Rework the way grid element props are calculated when changing element
location pins, so that `spans` are respected and kept in place if
present.

The behavior is now so that:
- when it makes sense to do so, return shorthand versions of grid
positioning props
- when moving an element with `span` values, support moving them when
the span is in the starting prop as well as the ending prop

Examples for moving a item one cell to the right:

| Initial config | Result |
|------------|------------|
| `gridColumn: 'span 2'` | `gridColumn: 'span 2 / 4'` |
| `gridColumn: '2 / span 2'` | `gridColumn: '3 / span 2'` |
| `gridColumnStart: 'span 2'` | `gridColumn: 'span 2 / 4'` |
| `gridColumnEnd: 'span 2'` | `gridColumn: '3 / span 2'` |

**Note:** a subsequent PR will take care of also keepign `span` intact
for the reorder strategy.

Fixes #6639
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Preserve span when changing grid item positions
3 participants