From 45b0bcf2730fcf6f8c1e4669dadac6e521cb0b9f Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:28:13 +0100 Subject: [PATCH 1/2] marker labels, adjust offsets, respect verbatim css --- .../canvas/controls/grid-controls.tsx | 176 ++++++++++++++---- 1 file changed, 140 insertions(+), 36 deletions(-) diff --git a/editor/src/components/canvas/controls/grid-controls.tsx b/editor/src/components/canvas/controls/grid-controls.tsx index aa6503487aee..1bc48c94ac1b 100644 --- a/editor/src/components/canvas/controls/grid-controls.tsx +++ b/editor/src/components/canvas/controls/grid-controls.tsx @@ -76,7 +76,6 @@ import { getGlobalFrameOfGridCellFromMetadata, getGridRelatedIndexes, getGridElementPinState, - gridPositionToValue, printPin, getGridIdentifierContainerOrComponentPath, gridIdentifierToString, @@ -2186,6 +2185,7 @@ function useSelectedGridItems(): ElementPath[] { const rulerMarkerIconSize = 12 // px type RulerMarkerData = { + parentGrid: GridContainerProperties columnStart: RulerMarkerPositionData columnEnd: RulerMarkerPositionData rowStart: RulerMarkerPositionData @@ -2196,7 +2196,6 @@ type RulerMarkerPositionData = { top: number left: number position: GridPositionOrSpan | null - counterpart: GridPositionOrSpan | null bound: 'start' | 'end' } @@ -2217,6 +2216,8 @@ const RulerMarkers = React.memo((props: { path: ElementPath }) => { return null } + const parentGrid = elementMetadata.specialSizeMeasurements.parentContainerGridProperties + const originalGrid = findOriginalGrid(store.editor.jsxMetadata, EP.parentPath(props.path)) if (originalGrid == null) { return null @@ -2269,32 +2270,29 @@ const RulerMarkers = React.memo((props: { path: ElementPath }) => { ) return { + parentGrid: parentGrid, columnStart: { top: gridRect.y, left: left, position: elementGridProperties.gridColumnStart, - counterpart: elementGridProperties.gridColumnEnd, bound: 'start', }, columnEnd: { top: gridRect.y, left: left + width, position: elementGridProperties.gridColumnEnd, - counterpart: elementGridProperties.gridColumnStart, bound: 'end', }, rowStart: { top: top, left: gridRect.x, position: elementGridProperties.gridRowStart, - counterpart: elementGridProperties.gridRowEnd, bound: 'start', }, rowEnd: { top: top + height, left: gridRect.x, position: elementGridProperties.gridRowEnd, - counterpart: elementGridProperties.gridRowStart, bound: 'end', }, } @@ -2308,22 +2306,37 @@ const RulerMarkers = React.memo((props: { path: ElementPath }) => { return ( - - - - + + + + ) }) RulerMarkers.displayName = 'RulerMarkers' const RulerMarkerIndicator = React.memo( - (props: { marker: RulerMarkerPositionData; axis: 'row' | 'column' }) => { + (props: { + parentGrid: GridContainerProperties + marker: RulerMarkerPositionData + axis: 'row' | 'column' + }) => { const colorTheme = useColorTheme() const markerType = getRulerMarkerType({ position: props.marker.position, - counterpart: props.marker.counterpart, bound: props.marker.bound, }) const markerIcon = rulerMarkerIcons[markerType][props.axis] @@ -2334,21 +2347,24 @@ const RulerMarkerIndicator = React.memo( 'RulerMarkerIndicator canvasScale', ) - function skewMarkerPosition(axis: 'column' | 'row') { - if (props.axis === axis) { - return rulerMarkerIconSize - } else if (markerType === 'span-end') { - return rulerMarkerIconSize - 1 // adjust span end position so it just touches the grid line - } else { - return rulerMarkerIconSize / 2 - } - } - const scaledTop = props.marker.top * canvasScale - const top = scaledTop - skewMarkerPosition('column') + const top = + scaledTop - + skewMarkerPosition(props.axis === 'column', props.axis, props.marker.bound, markerType) const scaledLeft = props.marker.left * canvasScale - const left = scaledLeft - skewMarkerPosition('row') + const left = + scaledLeft - + skewMarkerPosition(props.axis === 'row', props.axis, props.marker.bound, markerType) + + const labelText = React.useMemo(() => { + if (props.marker.position == null) { + return null + } + return printPin(props.parentGrid, props.marker.position, props.axis) + }, [props.marker, props.parentGrid, props.axis]) + + const labelClass = 'ruler-marker-label' return (
.${labelClass}`]: { + visibility: 'hidden', + }, + ':hover': { + [`> .${labelClass}`]: { + visibility: 'visible', + }, + }, + }} > {markerIcon} + {when( + labelText != null, +
+ {labelText} +
, + )}
) }, @@ -2374,16 +2420,11 @@ RulerMarkerIndicator.displayName = 'RulerMarkerIndicator' function getRulerMarkerType(props: { position: GridPositionOrSpan | null - counterpart: GridPositionOrSpan | null bound: 'start' | 'end' }): RulerMarkerType { - const isAuto = - isAutoGridPin(props.position) || - (props.bound === 'start' && isGridSpan(props.position) && isAutoGridPin(props.counterpart)) - const isSpanStart = - props.bound === 'start' && isGridSpan(props.position) && isGridSpan(props.counterpart) - const isSpanEnd = - props.bound === 'end' && (isGridSpan(props.position) || isGridSpan(props.counterpart)) + const isAuto = isAutoGridPin(props.position) + const isSpanStart = props.bound === 'start' && isGridSpan(props.position) + const isSpanEnd = props.bound === 'end' && isGridSpan(props.position) if (isSpanStart) { return 'span-start' @@ -2454,3 +2495,66 @@ function getCellCanvasHeightFromBounds( return acc + curr.height + padding }, currentColumn.height) } + +// This function returns the amount of pixels used to adjust the position of +// individual ruler markers, which need specific skews based on their shape. +function skewMarkerPosition( + isOnTheSameAxis: boolean, + axis: 'column' | 'row', + bound: 'start' | 'end', + markerType: RulerMarkerType, +): number { + if (isOnTheSameAxis) { + return rulerMarkerIconSize + } + + // span-end triangle, on the column + const spanEndColumn = axis === 'column' && markerType === 'span-end' + if (spanEndColumn) { + return 10 + } + const pinnedEndColumn = axis === 'column' && markerType === 'pinned' + if (pinnedEndColumn) { + return 5 + } + // any other ending marker, on the column + const endColumn = bound === 'end' && axis === 'column' + if (endColumn) { + return 2 + } + + // span-end triangle, on the row + const spanEndRow = axis === 'row' && markerType === 'span-end' + if (spanEndRow) { + return 9 + } + // any other ending marker, on the row + const endRow = bound === 'end' && axis === 'row' + if (endRow) { + return 6 + } + + // span-start triangle, on the column + const spanStartColumn = axis === 'column' && markerType === 'span-start' + if (spanStartColumn) { + return 0 + } + // any starting marker, on the column + const startColumn = bound === 'start' && axis === 'column' + if (startColumn) { + return 5 + } + + // span-start starting triangle, on the row + const spanStartRow = axis === 'row' && markerType === 'span-start' + if (spanStartRow) { + return 0 + } + // any other starting marker, on the row + const startRow = bound === 'start' && axis === 'row' + if (startRow) { + return 4 + } + + return 0 +} From 41c991101f8e88e6d5f6174c6fd51ba3e20524d4 Mon Sep 17 00:00:00 2001 From: Federico Ruggi <1081051+ruggi@users.noreply.github.com> Date: Thu, 21 Nov 2024 11:26:30 +0100 Subject: [PATCH 2/2] feature switch --- .../src/components/canvas/controls/grid-controls.tsx | 10 +++++++--- editor/src/utils/feature-switches.ts | 3 +++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/editor/src/components/canvas/controls/grid-controls.tsx b/editor/src/components/canvas/controls/grid-controls.tsx index 1bc48c94ac1b..c7d500b72dfc 100644 --- a/editor/src/components/canvas/controls/grid-controls.tsx +++ b/editor/src/components/canvas/controls/grid-controls.tsx @@ -119,6 +119,7 @@ import { styleStringInArray } from '../../../utils/common-constants' import { gridContainerIdentifier, type GridIdentifier } from '../../editor/store/editor-state' import type { RulerMarkerType } from './grid-controls-ruler-markers' import { rulerMarkerIcons } from './grid-controls-ruler-markers' +import { isFeatureEnabled } from '../../../utils/feature-switches' const CELL_ANIMATION_DURATION = 0.15 // seconds @@ -1212,9 +1213,12 @@ export const GridControlsComponent = ({ targets }: GridControlsProps) => { ) })} {/* Ruler markers */} - {selectedGridItems.map((path) => { - return - })} + {when( + isFeatureEnabled('Grid Ruler Markers'), + selectedGridItems.map((path) => { + return + }), + )} diff --git a/editor/src/utils/feature-switches.ts b/editor/src/utils/feature-switches.ts index fab803319515..4b3344b20189 100644 --- a/editor/src/utils/feature-switches.ts +++ b/editor/src/utils/feature-switches.ts @@ -24,6 +24,7 @@ export type FeatureName = | 'Tailwind' | 'Import Wizard' | 'Show Debug Features' + | 'Grid Ruler Markers' export const AllFeatureNames: FeatureName[] = [ // 'Dragging Reparents By Default', // Removing this option so that we can experiment on this later @@ -48,6 +49,7 @@ export const AllFeatureNames: FeatureName[] = [ 'Canvas Fast Selection Hack', 'Tailwind', 'Import Wizard', + 'Grid Ruler Markers', ] let FeatureSwitches: { [feature in FeatureName]: boolean } = { @@ -72,6 +74,7 @@ let FeatureSwitches: { [feature in FeatureName]: boolean } = { 'Canvas Fast Selection Hack': true, 'Import Wizard': !IS_TEST_ENVIRONMENT, 'Show Debug Features': false, + 'Grid Ruler Markers': false, } export const STEGANOGRAPHY_ENABLED = false