diff --git a/editor/src/components/canvas/canvas-strategies/strategies/absolute-resize-bounding-box-strategy.spec.browser2.tsx b/editor/src/components/canvas/canvas-strategies/strategies/absolute-resize-bounding-box-strategy.spec.browser2.tsx index 303c77e91494..5b407d1423b8 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/absolute-resize-bounding-box-strategy.spec.browser2.tsx +++ b/editor/src/components/canvas/canvas-strategies/strategies/absolute-resize-bounding-box-strategy.spec.browser2.tsx @@ -47,6 +47,7 @@ import { mouseDoubleClickAtPoint, mouseDownAtPoint, mouseDragFromPointWithDelta, + mouseMoveToPoint, } from '../../event-helpers.test-utils' import { CanvasControlsContainerID } from '../../controls/new-canvas-controls' import type { CSSProperties } from 'react' @@ -3008,7 +3009,7 @@ describe('Absolute Resize Control', () => { expect(resizeControlLeft.style.width).toEqual('5px') expect(resizeControlLeft.style.height).toEqual(`${height + RESIZE_CONTROL_SAFE_GAP * 2}px`) }) - it("Doesn't show the safe gap during resize and mouse down", async () => { + it("Doesn't show the safe gap during resize after threshold is passed", async () => { const width = SmallElementSize const height = SmallElementSize const renderResult = await renderTestEditorWithCode( @@ -3033,6 +3034,9 @@ describe('Absolute Resize Control', () => { const bottomLeftHandle = await renderResult.renderedDOM.findByTestId(`resize-control-0-1`) await mouseDownAtPoint(bottomRightHandle, { x: 2, y: 2 }) + await mouseMoveToPoint(bottomRightHandle, { x: 10, y: 0 }) + + const threshold = 2 // px expect(bottomRightHandle.parentElement?.style.visibility).toEqual('visible') expect(topRightHandle.parentElement?.style.visibility).toEqual('hidden') @@ -3045,25 +3049,25 @@ describe('Absolute Resize Control', () => { expect(resizeControlTop.style.transform).toEqual('translate(0px, -5px)') expect(resizeControlTop.style.top).toEqual('') expect(resizeControlTop.style.left).toEqual('') - expect(resizeControlTop.style.width).toEqual(`${width}px`) + expect(resizeControlTop.style.width).toEqual(`${width + 10 - threshold}px`) expect(resizeControlTop.style.height).toEqual('5px') const resizeControlRight = renderResult.renderedDOM.getByTestId( `resize-control-${EdgePositionRight.x}-${EdgePositionRight.y}`, ) - expect(resizeControlRight.style.transform).toEqual('translate(0px, 0px)') + expect(resizeControlRight.style.transform).toEqual('translate(-5px, 0px)') expect(resizeControlRight.style.top).toEqual('') - expect(resizeControlRight.style.left).toEqual(`${width}px`) - expect(resizeControlRight.style.width).toEqual('5px') - expect(resizeControlRight.style.height).toEqual(`${height}px`) + expect(resizeControlRight.style.left).toEqual(`${width + 10 - threshold}px`) + expect(resizeControlRight.style.width).toEqual('10px') + expect(resizeControlRight.style.height).toEqual(`${height - threshold}px`) const resizeControlBottom = renderResult.renderedDOM.getByTestId( `resize-control-${EdgePositionBottom.x}-${EdgePositionBottom.y}`, ) expect(resizeControlBottom.style.transform).toEqual('translate(0px, 0px)') - expect(resizeControlBottom.style.top).toEqual(`${height}px`) + expect(resizeControlBottom.style.top).toEqual(`${height - 2}px`) expect(resizeControlBottom.style.left).toEqual('') - expect(resizeControlBottom.style.width).toEqual(`${width}px`) + expect(resizeControlBottom.style.width).toEqual(`${width + 10 - threshold}px`) expect(resizeControlBottom.style.height).toEqual('5px') const resizeControlLeft = renderResult.renderedDOM.getByTestId( @@ -3072,8 +3076,8 @@ describe('Absolute Resize Control', () => { expect(resizeControlLeft.style.transform).toEqual('translate(-5px, 0px)') expect(resizeControlLeft.style.top).toEqual('') expect(resizeControlLeft.style.left).toEqual('') - expect(resizeControlLeft.style.width).toEqual('5px') - expect(resizeControlLeft.style.height).toEqual(`${height}px`) + expect(resizeControlLeft.style.width).toEqual('10px') + expect(resizeControlLeft.style.height).toEqual(`${height - threshold}px`) }) }) it('Resize control on non-small elements extend into the draggable frame area', async () => { diff --git a/editor/src/components/canvas/controls/bounding-box-hooks.ts b/editor/src/components/canvas/controls/bounding-box-hooks.ts index e3b1dd503a9a..58a1061fa0e9 100644 --- a/editor/src/components/canvas/controls/bounding-box-hooks.ts +++ b/editor/src/components/canvas/controls/bounding-box-hooks.ts @@ -16,6 +16,8 @@ import { } from '../../editor/store/store-hook' import { MetadataUtils } from '../../../core/model/element-metadata-utils' import { getMetadata } from '../../editor/store/editor-state' +import { elementHasOnlyTextChildren } from '../canvas-utils' +import { isFixedHugFillModeApplied } from '../../inspector/inspector-common' interface NotNullRefObject { readonly current: T @@ -51,19 +53,37 @@ function useBoundingBoxFromMetadataRef( const metadataRef = useRefEditorState((store) => getMetadata(store.editor)) const scaleRef = useRefEditorState((store) => store.editor.canvas.scale) - const isNotDuringInteraction = useEditorState( + const isInteractionDraggingPastThreshold = useEditorState( Substores.canvas, (store) => { - return store.editor.canvas.interactionSession?.interactionData == null + return ( + store.editor.canvas.interactionSession?.interactionData.type === 'DRAG' && + store.editor.canvas.interactionSession?.interactionData.drag != null + ) }, - 'useBoundingBoxFromMetadataRef isNotDuringInteraction', + 'useBoundingBoxFromMetadataRef isInteractionDraggingPastThreshold', ) const shouldApplySafeGap = React.useCallback( (dimension: number, scale: number): boolean => { - return isNotDuringInteraction && dimension <= SafeGapSmallElementSize / scale + if (selectedElements.length === 1) { + // For text elements only show the safe gaps if they have been resized past the initial max-content dimensions + const meta = MetadataUtils.findElementByElementPath( + metadataRef.current, + selectedElements[0], + ) + if ( + meta != null && + elementHasOnlyTextChildren(meta) && + isFixedHugFillModeApplied(metadataRef.current, selectedElements[0], 'hug') + ) { + return false + } + } + + return !isInteractionDraggingPastThreshold && dimension <= SmallElementSize / scale }, - [isNotDuringInteraction], + [isInteractionDraggingPastThreshold, metadataRef, selectedElements], ) const boundingBoxCallbackRef = React.useRef(boundingBoxCallback)