diff --git a/editor/src/components/canvas/canvas-strategies/strategies/resize-grid-strategy.ts b/editor/src/components/canvas/canvas-strategies/strategies/resize-grid-strategy.ts index cc741fbd5515..f1f7627bcb37 100644 --- a/editor/src/components/canvas/canvas-strategies/strategies/resize-grid-strategy.ts +++ b/editor/src/components/canvas/canvas-strategies/strategies/resize-grid-strategy.ts @@ -31,7 +31,13 @@ export const resizeGridStrategy: CanvasStrategyFactory = ( const selectedElement = selectedElements[0] - if (!MetadataUtils.isGridCell(canvasState.startingMetadata, selectedElement)) { + const isGridCell = MetadataUtils.isGridCell(canvasState.startingMetadata, selectedElement) + const isGrid = MetadataUtils.isGridLayoutedContainer( + MetadataUtils.findElementByElementPath(canvasState.startingMetadata, selectedElement), + ) + const isGridOrGridCell = isGridCell || isGrid + + if (!isGridOrGridCell) { return null } @@ -65,17 +71,19 @@ export const resizeGridStrategy: CanvasStrategyFactory = ( const control = interactionSession.activeControl const drag = interactionSession.interactionData.drag const dragAmount = control.axis === 'column' ? drag.x : drag.y - const parentPath = EP.parentPath(selectedElement) - const parentSpecialSizeMeasurements = - canvasState.startingMetadata[EP.toString(parentPath)].specialSizeMeasurements + + const gridPath = isGrid ? selectedElement : EP.parentPath(selectedElement) + + const gridSpecialSizeMeasurements = + canvasState.startingMetadata[EP.toString(gridPath)].specialSizeMeasurements const originalValues = control.axis === 'column' - ? parentSpecialSizeMeasurements.containerGridPropertiesFromProps.gridTemplateColumns - : parentSpecialSizeMeasurements.containerGridPropertiesFromProps.gridTemplateRows + ? gridSpecialSizeMeasurements.containerGridPropertiesFromProps.gridTemplateColumns + : gridSpecialSizeMeasurements.containerGridPropertiesFromProps.gridTemplateRows const calculatedValues = control.axis === 'column' - ? parentSpecialSizeMeasurements.containerGridProperties.gridTemplateColumns - : parentSpecialSizeMeasurements.containerGridProperties.gridTemplateRows + ? gridSpecialSizeMeasurements.containerGridProperties.gridTemplateColumns + : gridSpecialSizeMeasurements.containerGridProperties.gridTemplateRows if ( calculatedValues == null || @@ -115,14 +123,14 @@ export const resizeGridStrategy: CanvasStrategyFactory = ( const commands = [ setProperty( 'always', - parentPath, + gridPath, PP.create( 'style', control.axis === 'column' ? 'gridTemplateColumns' : 'gridTemplateRows', ), propertyValueAsString, ), - setElementsToRerenderCommand([parentPath]), + setElementsToRerenderCommand([gridPath]), ] return strategyApplicationResult(commands) diff --git a/editor/src/components/canvas/controls/grid-controls.tsx b/editor/src/components/canvas/controls/grid-controls.tsx index 3a05b4a2b8fd..d44752a6d657 100644 --- a/editor/src/components/canvas/controls/grid-controls.tsx +++ b/editor/src/components/canvas/controls/grid-controls.tsx @@ -1,3 +1,6 @@ +/** @jsxRuntime classic */ +/** @jsx jsx */ +import { jsx } from '@emotion/react' import type { AnimationControls } from 'framer-motion' import { motion, useAnimationControls } from 'framer-motion' import React from 'react' @@ -51,7 +54,7 @@ import { } from '../canvas-strategies/interaction-state' import { windowToCanvasCoordinates } from '../dom-lookup' import { CanvasOffsetWrapper } from './canvas-offset-wrapper' -import { useColorTheme } from '../../../uuiui' +import { useColorTheme, UtopiaStyles } from '../../../uuiui' import { gridCellTargetId } from '../canvas-strategies/strategies/grid-helpers' import { resizeBoundingBoxFromSide } from '../canvas-strategies/strategies/resize-helpers' import type { EdgePosition } from '../canvas-types' @@ -65,6 +68,7 @@ import { import { useCanvasAnimation } from '../ui-jsx-canvas-renderer/animation-context' import { CanvasLabel } from './select-mode/controls-common' import { optionalMap } from '../../../core/shared/optional-utils' +import type { Sides } from 'utopia-api/core' const CELL_ANIMATION_DURATION = 0.15 // seconds @@ -122,16 +126,16 @@ function getLabelForAxis( } const SHADOW_SNAP_ANIMATION = 'shadow-snap' - -const GridResizingContainerSize = 100 +const GRID_RESIZE_HANDLE_CONTAINER_SIZE = 30 // px +const GRID_RESIZE_HANDLE_SIZE = 15 // px export interface GridResizingControlProps { dimension: GridCSSNumber dimensionIndex: number axis: 'row' | 'column' containingFrame: CanvasRectangle - workingPrefix: number fromPropsAxisValues: GridAutoOrTemplateBase | null + padding: number | null } export const GridResizingControl = React.memo((props: GridResizingControlProps) => { @@ -148,13 +152,22 @@ export const GridResizingControl = React.memo((props: GridResizingControlProps) const dispatch = useDispatch() const colorTheme = useColorTheme() + const [resizing, setResizing] = React.useState(false) + const mouseDownHandler = React.useCallback( (event: React.MouseEvent): void => { + function mouseUpHandler() { + setResizing(false) + window.removeEventListener('mouseup', mouseUpHandler) + } + window.addEventListener('mouseup', mouseUpHandler) + const start = windowToCanvasCoordinates( scale, canvasOffset, windowPoint({ x: event.nativeEvent.x, y: event.nativeEvent.y }), ) + setResizing(true) dispatch([ CanvasActions.createInteractionSession( @@ -175,34 +188,84 @@ export const GridResizingControl = React.memo((props: GridResizingControlProps) const labelId = `grid-${props.axis}-handle-${props.dimensionIndex}` const containerId = `${labelId}-container` + const shadowSize = React.useMemo(() => { + return props.axis === 'column' + ? props.containingFrame.height + GRID_RESIZE_HANDLE_CONTAINER_SIZE + : props.containingFrame.width + GRID_RESIZE_HANDLE_CONTAINER_SIZE + }, [props.containingFrame, props.axis]) + return (