diff --git a/editor/src/components/canvas/canvas-strategies/strategies/grid-resize-element-strategy.ts b/editor/src/components/canvas/canvas-strategies/strategies/grid-resize-element-strategy.ts index ed1a5e39d48b..f8b520bfe55f 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/grid-resize-element-strategy.ts +++ b/editor/src/components/canvas/canvas-strategies/strategies/grid-resize-element-strategy.ts @@ -5,7 +5,7 @@ import { isInfinityRectangle, rectangleIntersection, } from '../../../../core/shared/math-utils' -import { isFillOrStretchModeApplied } from '../../../inspector/inspector-common' +import { isFillOrStretchModeAppliedOnAnySide } from '../../../inspector/inspector-common' import { controlsForGridPlaceholders, gridEdgeToEdgePosition, @@ -49,7 +49,7 @@ export const gridResizeElementStrategy: CanvasStrategyFactory = ( return null } - if (!isFillOrStretchModeApplied(canvasState.startingMetadata, selectedElement)) { + if (!isFillOrStretchModeAppliedOnAnySide(canvasState.startingMetadata, selectedElement)) { return null } diff --git a/editor/src/components/canvas/controls/grid-controls.tsx b/editor/src/components/canvas/controls/grid-controls.tsx index 00c211396b2a..47f20a9bc565 100644 --- a/editor/src/components/canvas/controls/grid-controls.tsx +++ b/editor/src/components/canvas/controls/grid-controls.tsx @@ -88,6 +88,7 @@ import { import { useMaybeHighlightElement } from './select-mode/select-mode-hooks' import { useResizeEdges } from './select-mode/use-resize-edges' import { getGridHelperStyleMatchingTargetGrid } from './grid-controls-helpers' +import { isFillOrStretchModeAppliedOnSpecificSide } from '../../inspector/inspector-common' const CELL_ANIMATION_DURATION = 0.15 // seconds @@ -1586,6 +1587,28 @@ export const GridResizeControlsComponent = ({ target }: GridResizeControlProps) }, }) + const resizeDirection = useEditorState( + Substores.metadata, + (store) => { + if (element == null) { + return { horizontal: false, vertical: false } + } + return { + horizontal: isFillOrStretchModeAppliedOnSpecificSide( + store.editor.jsxMetadata, + element.elementPath, + 'horizontal', + ), + vertical: isFillOrStretchModeAppliedOnSpecificSide( + store.editor.jsxMetadata, + element.elementPath, + 'vertical', + ), + } + }, + 'GridResizeControlsComponent resizeDirection', + ) + if ( element == null || element.globalFrame == null || @@ -1618,10 +1641,20 @@ export const GridResizeControlsComponent = ({ target }: GridResizeControlProps) pointerEvents: 'none', }} > - {resizeEdges.top} - {resizeEdges.left} - {resizeEdges.bottom} - {resizeEdges.right} + {when( + resizeDirection.vertical, + + {resizeEdges.top} + {resizeEdges.bottom} + , + )} + {when( + resizeDirection.horizontal, + + {resizeEdges.left} + {resizeEdges.right} + , + )} diff --git a/editor/src/components/canvas/controls/select-mode/absolute-resize-control.tsx b/editor/src/components/canvas/controls/select-mode/absolute-resize-control.tsx index 366453bbf8ad..afa79fca4bc8 100644 --- a/editor/src/components/canvas/controls/select-mode/absolute-resize-control.tsx +++ b/editor/src/components/canvas/controls/select-mode/absolute-resize-control.tsx @@ -24,6 +24,8 @@ import type { FixedHugFill } from '../../../inspector/inspector-common' import { detectFillHugFixedState, invert, + isFillOrStretchModeAppliedOnAnySide, + isFillOrStretchModeAppliedOnSpecificSide, resizeToFitCommands, } from '../../../inspector/inspector-common' import { setPropHugStrategies } from '../../../inspector/inspector-strategies/inspector-strategies' @@ -135,6 +137,38 @@ export const AbsoluteResizeControl = controlForStrategyMemoized( onEdgeDoubleClick, }) + const canResize = useEditorState( + Substores.metadata, + (store) => { + const metadata = store.editor.jsxMetadata + + let horizontally = true + let vertically = true + let diagonally = true + + for (const element of selectedElementsRef.current) { + if (MetadataUtils.isGridCell(metadata, element)) { + if (isFillOrStretchModeAppliedOnAnySide(metadata, element)) { + diagonally = false + } + if (isFillOrStretchModeAppliedOnSpecificSide(metadata, element, 'horizontal')) { + horizontally = false + } + if (isFillOrStretchModeAppliedOnSpecificSide(metadata, element, 'vertical')) { + vertically = false + } + } + } + + return { + horizontally: horizontally, + vertically: vertically, + diagonally: diagonally, + } + }, + 'AbsoluteResizeControl canResize', + ) + return (
- {resizeEdges.top} - {resizeEdges.left} - {resizeEdges.bottom} - {resizeEdges.right} - - - - + {when( + canResize.vertically, + + {resizeEdges.top} + {resizeEdges.bottom} + , + )} + {when( + canResize.horizontally, + + {resizeEdges.left} + {resizeEdges.right} + , + )} + {when( + canResize.diagonally, + + + + + + , + )}
diff --git a/editor/src/components/inspector/inspector-common.ts b/editor/src/components/inspector/inspector-common.ts index 2d6cadf9f718..decc614de98c 100644 --- a/editor/src/components/inspector/inspector-common.ts +++ b/editor/src/components/inspector/inspector-common.ts @@ -921,6 +921,27 @@ export function isFillOrStretchModeApplied( ) } +export function isFillOrStretchModeAppliedOnAnySide( + metadata: ElementInstanceMetadataMap, + element: ElementPath, +): boolean { + return ( + isFixedHugFillModeAppliedOnAnySide(metadata, element, 'fill') || + isFixedHugFillModeAppliedOnAnySide(metadata, element, 'stretch') + ) +} + +export function isFillOrStretchModeAppliedOnSpecificSide( + metadata: ElementInstanceMetadataMap, + element: ElementPath, + side: 'horizontal' | 'vertical', +): boolean { + return ( + detectFillHugFixedState(side, metadata, element).fixedHugFill?.type === 'fill' || + detectFillHugFixedState(side, metadata, element).fixedHugFill?.type === 'stretch' + ) +} + export function isFixedHugFillModeAppliedOnAnySide( metadata: ElementInstanceMetadataMap, element: ElementPath, diff --git a/editor/src/core/performance/__snapshots__/performance-regression-tests.spec.tsx.snap b/editor/src/core/performance/__snapshots__/performance-regression-tests.spec.tsx.snap index d563c0adb06c..1e4ec99abbfc 100644 --- a/editor/src/core/performance/__snapshots__/performance-regression-tests.spec.tsx.snap +++ b/editor/src/core/performance/__snapshots__/performance-regression-tests.spec.tsx.snap @@ -64,30 +64,33 @@ Array [ "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))", + "/Symbol(react.memo)()///UtopiaSpiedExoticType(Symbol(react.fragment))", + "/Symbol(react.memo)()///UtopiaSpiedExoticType(Symbol(react.fragment))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))", + "/Symbol(react.memo)()///UtopiaSpiedExoticType(Symbol(react.fragment))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(SizeLabel))", "/Symbol(react.memo)()///div:data-testid='utopia-storyboard-uid/scene-aaa/app-entity:parent/ccc-absolute-resize-control'", "/Symbol(react.memo)()///Symbol(react.memo)()", "////div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0.5-0'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0-0.5'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0.5-1'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-1-0.5'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-0-0'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-1-0'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-0-1'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-1-1'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0.5-0'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0.5-1'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0-0.5'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-1-0.5'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-0-0'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-1-0'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-0-1'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-1-1'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", "/div/Symbol(react.memo)(Symbol(react.forward_ref)(SizeLabel))/Symbol(react.forward_ref)(SizeLabel)/div:data-testid='SizeLabelTestId'", "/div/Symbol(react.memo)(Symbol(react.forward_ref)(SizeLabel))/Symbol(react.forward_ref)(SizeLabel)/div:data-testid='parent-resize-label'", "/Symbol(react.forward_ref)(Styled(div))/div/Symbol(react.forward_ref)(Styled(div))/div", @@ -848,30 +851,33 @@ Array [ "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))", + "/Symbol(react.memo)()///UtopiaSpiedExoticType(Symbol(react.fragment))", + "/Symbol(react.memo)()///UtopiaSpiedExoticType(Symbol(react.fragment))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))", + "/Symbol(react.memo)()///UtopiaSpiedExoticType(Symbol(react.fragment))", "/Symbol(react.memo)()///Symbol(react.memo)(Symbol(react.forward_ref)(SizeLabel))", "/Symbol(react.memo)()///div:data-testid='utopia-storyboard-uid/scene-aaa/app-entity:parent/ccc-absolute-resize-control'", "/Symbol(react.memo)()///Symbol(react.memo)()", "////div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0.5-0'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0-0.5'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0.5-1'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-1-0.5'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-0-0'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-1-0'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-0-1'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-1-1'", - "/div/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0.5-0'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0.5-1'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-0-0.5'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizeEdge))/Symbol(react.forward_ref)(ResizeEdge)/div:data-testid='resize-control-1-0.5'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-0-0'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-1-0'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-0-1'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div:data-testid='resize-control-1-1'", + "/UtopiaSpiedExoticType(Symbol(react.fragment))/Symbol(react.memo)(Symbol(react.forward_ref)(ResizePoint))/Symbol(react.forward_ref)(ResizePoint)/div", "/div/Symbol(react.memo)(Symbol(react.forward_ref)(SizeLabel))/Symbol(react.forward_ref)(SizeLabel)/div:data-testid='SizeLabelTestId'", "/div/Symbol(react.memo)(Symbol(react.forward_ref)(SizeLabel))/Symbol(react.forward_ref)(SizeLabel)/div:data-testid='parent-resize-label'", "/Symbol(react.forward_ref)(Styled(div))/div/Symbol(react.forward_ref)(Styled(div))/div", diff --git a/editor/src/core/performance/performance-regression-tests.spec.tsx b/editor/src/core/performance/performance-regression-tests.spec.tsx index b11167da5684..57938fa23a2c 100644 --- a/editor/src/core/performance/performance-regression-tests.spec.tsx +++ b/editor/src/core/performance/performance-regression-tests.spec.tsx @@ -183,7 +183,7 @@ describe('React Render Count Tests -', () => { const renderCountAfter = renderResult.getNumberOfRenders() // if this breaks, GREAT NEWS but update the test please :) - expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`654`) + expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`657`) expect(renderResult.getRenderInfo()).toMatchSnapshot() }) @@ -249,7 +249,7 @@ describe('React Render Count Tests -', () => { const renderCountAfter = renderResult.getNumberOfRenders() // if this breaks, GREAT NEWS but update the test please :) - expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`779`) + expect(renderCountAfter - renderCountBefore).toMatchInlineSnapshot(`782`) expect(renderResult.getRenderInfo()).toMatchSnapshot() }) })