Skip to content

Commit

Permalink
Hide safe gaps after drag threshold (#4254)
Browse files Browse the repository at this point in the history
* hide gaps after drag threshold, adjust for text elements

* update snaps

* fix condition

* use drag != null, remove hasBeenPastThreshold

* restore
  • Loading branch information
ruggi authored Sep 29, 2023
1 parent da0b564 commit 62eb165
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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(
Expand All @@ -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')
Expand All @@ -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(
Expand All @@ -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 () => {
Expand Down
30 changes: 25 additions & 5 deletions editor/src/components/canvas/controls/bounding-box-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> {
readonly current: T
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 62eb165

Please sign in to comment.