Skip to content

Commit

Permalink
Group size label (#4257)
Browse files Browse the repository at this point in the history
* use "group" for group size label

* type
  • Loading branch information
ruggi authored Sep 29, 2023
1 parent 1896ad9 commit d6da1ce
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,32 @@ export var storyboard = (
})
})
describe('groups', () => {
it('has a "Group" size label', async () => {
const renderResult = await renderTestEditorWithCode(
formatTestProjectCode(`
import * as React from 'react'
import { Storyboard, Group } from 'utopia-api'
export var storyboard = (
<Storyboard data-uid='storyboard'>
<Group data-uid='group' style={{ position: 'absolute', width: 150, height: 150, background: 'black' }}>
<div data-uid='foo' style={{ position:'absolute', width: 50, height: 50, background: 'red', top: 0, left: 0 }} />
<div data-uid='bar' style={{ position:'absolute', width: 50, height: 50, background: 'blue', top: 100, left: 100 }} />
</Group>
</Storyboard>
)
`),
'await-first-dom-report',
)

await renderResult.dispatch(
[selectComponents([EP.fromString('storyboard/group')], false)],
true,
)

const label = await renderResult.renderedDOM.findByTestId(SizeLabelTestId)
expect(label.textContent).toEqual('Group')
})
it('resizes groups correctly when dragging from top/left without existing left/top props (left)', async () => {
const renderResult = await renderTestEditorWithCode(
formatTestProjectCode(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { CanvasOffsetWrapper } from '../canvas-offset-wrapper'
import { isZeroSizedElement } from '../outline-utils'
import { useMaybeHighlightElement } from './select-mode-hooks'
import { isEdgePositionEqualTo } from '../../canvas-utils'
import { treatElementAsGroupLike } from '../../canvas-strategies/strategies/group-helpers'

export const AbsoluteResizeControlTestId = (targets: Array<ElementPath>): string =>
`${targets.map(EP.toString).sort()}-absolute-resize-control`
Expand Down Expand Up @@ -399,15 +400,45 @@ const sizeLabel = (state: FixedHugFill['type'], actualSize: number): string => {
}
}

export type SizeLabelSize = {
type: 'SIZE_LABEL_WITH_DIMENSIONS'
h: string
v: string
}

function sizeLabelWithDimensions(h: string, v: string): SizeLabelSize {
return {
type: 'SIZE_LABEL_WITH_DIMENSIONS',
h: h,
v: v,
}
}

export type SizeLabelGroup = {
type: 'SIZE_LABEL_GROUP'
}

function sizeLabelGroup(): SizeLabelGroup {
return {
type: 'SIZE_LABEL_GROUP',
}
}

export type SizeLabelContents = SizeLabelSize | SizeLabelGroup

function sizeLabelContents(
metadata: ElementInstanceMetadataMap,
selectedElements: Array<ElementPath>,
): { h: string; v: string } | null {
): SizeLabelContents | null {
if (selectedElements.length === 0) {
return null
}

if (selectedElements.length === 1) {
if (treatElementAsGroupLike(metadata, selectedElements[0])) {
return sizeLabelGroup()
}

const globalFrame = MetadataUtils.findElementByElementPath(
metadata,
selectedElements[0],
Expand All @@ -422,17 +453,17 @@ function sizeLabelContents(
const vertical =
detectFillHugFixedState('vertical', metadata, selectedElements[0]).fixedHugFill?.type ??
'fixed'
return {
h: sizeLabel(horizontal, globalFrame.width),
v: sizeLabel(vertical, globalFrame.height),
}
return sizeLabelWithDimensions(
sizeLabel(horizontal, globalFrame.width),
sizeLabel(vertical, globalFrame.height),
)
}

const boundingBox = boundingRectangleArray(
selectedElements.map((t) => nullIfInfinity(MetadataUtils.getFrameInCanvasCoords(t, metadata))),
)
if (boundingBox != null) {
return { h: `${boundingBox.width}`, v: `${boundingBox.height}` }
return sizeLabelWithDimensions(`${boundingBox.width}`, `${boundingBox.height}`)
}

return null
Expand All @@ -449,6 +480,20 @@ const ExplicitHeightHacked = 20
const BorderRadius = 2
const SizeLabelMarginTop = 8

function getLabelText(label: SizeLabelContents | null): string | null {
if (label == null) {
return null
}
switch (label.type) {
case 'SIZE_LABEL_GROUP':
return 'Group'
case 'SIZE_LABEL_WITH_DIMENSIONS':
return `${label.h} x ${label.v}`
default:
assertNever(label)
}
}

const SizeLabel = React.memo(
React.forwardRef<HTMLDivElement, SizeLabelProps>(({ targets }, ref) => {
const scale = useEditorState(
Expand All @@ -464,8 +509,7 @@ const SizeLabel = React.memo(
)

const label = sizeLabelContents(metadata, targets)

const labelText = label == null ? null : `${label.h} x ${label.v}`
const labelText = getLabelText(label)

return (
<div
Expand Down

0 comments on commit d6da1ce

Please sign in to comment.