From 2cd8e5c2d76f62a4a7cc9f4b09201d2d76bba784 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Thu, 22 Aug 2024 12:36:50 +0200 Subject: [PATCH] Paste into grid (#6254) **Problem:** Pasting an element into a grid doesn't place the new element _into_ the grid's placement logic. **Fix:** If the target parent is a grid, remove flow properties from the pasted element, which will be then placed at the first valid coordinates following `auto` logic. In the future we might revisit this with a bit more heuristics to determine "empty" cells to place the element into, but for now the current logic should be more than enough. | Before | After | |-------|----------| | ![Kapture 2024-08-22 at 11 30 59](https://github.com/user-attachments/assets/16a4b479-6fa8-4962-8990-5fb1356d8537) | ![Kapture 2024-08-22 at 11 29 34](https://github.com/user-attachments/assets/f248cb1c-453d-4051-b2c0-30257c54ee2a) | **Manual Tests:** I hereby swear that: - [x] I opened a hydrogen project and it loaded - [x] I could navigate to various routes in Preview mode Fixes #6253 --- .../post-action-options/post-action-paste.ts | 55 +++++++++++++------ 1 file changed, 39 insertions(+), 16 deletions(-) diff --git a/editor/src/components/canvas/canvas-strategies/post-action-options/post-action-paste.ts b/editor/src/components/canvas/canvas-strategies/post-action-options/post-action-paste.ts index 0822696d0bb2..283bbdacce1b 100644 --- a/editor/src/components/canvas/canvas-strategies/post-action-options/post-action-paste.ts +++ b/editor/src/components/canvas/canvas-strategies/post-action-options/post-action-paste.ts @@ -14,6 +14,7 @@ import { stripNulls, zip } from '../../../../core/shared/array-utils' import type { Either } from '../../../../core/shared/either' import { isLeft, left, right } from '../../../../core/shared/either' import * as EP from '../../../../core/shared/element-path' +import * as PP from '../../../../core/shared/property-path' import type { ElementPathTrees } from '../../../../core/shared/element-path-tree' import type { ElementInstanceMetadataMap } from '../../../../core/shared/element-template' import { @@ -53,6 +54,7 @@ import type { CanvasCommand } from '../../commands/commands' import { foldAndApplyCommandsInner } from '../../commands/commands' import { deleteElement } from '../../commands/delete-element-command' import { queueTrueUpElement } from '../../commands/queue-true-up-command' +import { propertyToDelete, updateBulkProperties } from '../../commands/set-property-command' import { showToastCommand } from '../../commands/show-toast-command' import { updateFunctionCommand } from '../../commands/update-function-command' import { updateSelectedViews } from '../../commands/update-selected-views-command' @@ -287,6 +289,13 @@ export function staticReparentAndUpdatePosition( target.parentPath.intendedParentPath, ) + const isGrid = MetadataUtils.isGridLayoutedContainer( + MetadataUtils.findElementByElementPath( + editorStateContext.startingMetadata, + target.parentPath.intendedParentPath, + ), + ) + const commands = elementsToInsert.flatMap((elementToInsert) => { return [ updateFunctionCommand('always', (editor, commandLifecycle) => { @@ -317,22 +326,36 @@ export function staticReparentAndUpdatePosition( oldPathToNewPathMapping, ) - const absolutePositioningCommands = - strategy === 'REPARENT_AS_STATIC' - ? [] - : positionElementToCoordinatesCommands( - { oldPath: elementToInsert.elementPath, newPath: newPath }, - pasteContext.originalAllElementProps, - { - originalTargetMetadata: - pasteContext.elementPasteWithMetadata.targetOriginalContextMetadata, - originalPathTrees: pasteContext.targetOriginalPathTrees, - currentMetadata: editor.jsxMetadata, - currentPathTrees: editor.elementPathTree, - }, - elementToInsert.intendedCoordinates, - oldPathToNewPathMapping, - ) + function getAbsolutePositioningCommands(targetPath: ElementPath): Array { + if (isGrid) { + return [ + updateBulkProperties('always', targetPath, [ + propertyToDelete(PP.create('style', 'position')), + propertyToDelete(PP.create('style', 'top')), + propertyToDelete(PP.create('style', 'left')), + propertyToDelete(PP.create('style', 'bottom')), + propertyToDelete(PP.create('style', 'right')), + ]), + ] + } else if (strategy === 'REPARENT_AS_ABSOLUTE') { + return positionElementToCoordinatesCommands( + { oldPath: elementToInsert.elementPath, newPath: targetPath }, + pasteContext.originalAllElementProps, + { + originalTargetMetadata: + pasteContext.elementPasteWithMetadata.targetOriginalContextMetadata, + originalPathTrees: pasteContext.targetOriginalPathTrees, + currentMetadata: editor.jsxMetadata, + currentPathTrees: editor.elementPathTree, + }, + elementToInsert.intendedCoordinates, + oldPathToNewPathMapping, + ) + } else { + return [] + } + } + const absolutePositioningCommands = getAbsolutePositioningCommands(newPath) const propertyCommands = [...propertyChangeCommands, ...absolutePositioningCommands]