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