1
1
import React from 'react'
2
2
import { useColorTheme } from '../../../../uuiui'
3
- import { Substores , useEditorState , useRefEditorState } from '../../../editor/store/store-hook'
4
- import { useBoundingBox } from '../bounding-box-hooks'
3
+ import { Substores , useEditorState } from '../../../editor/store/store-hook'
5
4
import { CanvasOffsetWrapper } from '../canvas-offset-wrapper'
6
5
import type { Axis } from '../../gap-utils'
7
- import { gridGapControlBoundsFromMetadata , maybeGridGapData } from '../../gap-utils'
8
- import type { ElementPath } from 'utopia-shared/src/types'
9
6
import { useGridData } from '../grid-controls-for-strategies'
10
- import { fallbackEmptyValue } from './controls-common'
11
- import type { CanvasRectangle } from '../../../../core/shared/math-utils'
12
- import type { CSSNumber } from '../../../../components/inspector/common/css-utils'
7
+ import { unitlessCSSNumberWithRenderedValue } from './controls-common'
8
+ import { NO_OP } from '../../../../core/shared/utils'
9
+ import * as EP from '../../../../core/shared/element-path'
10
+ import { GridPaddingOutlineForDimension } from './grid-gap-control-component'
13
11
14
12
export interface SubduedGridGapControlProps {
15
13
hoveredOrFocused : 'hovered' | 'focused'
@@ -18,124 +16,49 @@ export interface SubduedGridGapControlProps {
18
16
19
17
export const SubduedGridGapControl = React . memo < SubduedGridGapControlProps > ( ( props ) => {
20
18
const { hoveredOrFocused, axis } = props
19
+ const colorTheme = useColorTheme ( )
21
20
const targets = useEditorState (
22
21
Substores . selectedViews ,
23
22
( store ) => store . editor . selectedViews ,
24
23
'SubduedGridGapControl selectedViews' ,
25
24
)
26
25
27
- const metadata = useRefEditorState ( ( store ) => store . editor . jsxMetadata )
28
- const selectedElement = targets . at ( 0 )
29
-
30
26
const gridRowColumnInfo = useGridData ( targets )
31
- const selectedGrid = gridRowColumnInfo . at ( 0 )
32
-
33
- const filteredGaps = React . useMemo ( ( ) => {
34
- if ( selectedElement == null || selectedGrid == null ) {
35
- return [ ]
36
- }
37
- const gridGap = maybeGridGapData ( metadata . current , selectedElement )
38
- if ( gridGap == null ) {
39
- return [ ]
40
- }
41
-
42
- const gridGapRow = gridGap . row
43
- const gridGapColumn = gridGap . column
44
27
45
- const controlBounds = gridGapControlBoundsFromMetadata ( selectedGrid , {
46
- row : fallbackEmptyValue ( gridGapRow ) ,
47
- column : fallbackEmptyValue ( gridGapColumn ) ,
48
- } )
49
- return controlBounds . gaps . filter ( ( gap ) => gap . axis === axis || axis === 'both' )
50
- } , [ axis , metadata , selectedElement , selectedGrid ] )
51
-
52
- if ( filteredGaps . length === 0 || selectedElement == null ) {
28
+ if ( gridRowColumnInfo . length === 0 ) {
53
29
return null
54
30
}
55
31
56
- return (
57
- < >
58
- { filteredGaps . map ( ( gap ) => (
59
- < GridGapControl
60
- key = { gap . gapId }
61
- targets = { targets }
62
- selectedElement = { selectedElement }
63
- hoveredOrFocused = { hoveredOrFocused }
64
- gap = { gap }
65
- />
66
- ) ) }
67
- </ >
68
- )
69
- } )
70
-
71
- function GridGapControl ( {
72
- targets,
73
- selectedElement,
74
- hoveredOrFocused,
75
- gap,
76
- } : {
77
- targets : Array < ElementPath >
78
- selectedElement : ElementPath
79
- hoveredOrFocused : 'hovered' | 'focused'
80
- gap : {
81
- bounds : CanvasRectangle
82
- gapId : string
83
- gap : CSSNumber
84
- axis : Axis
85
- }
86
- } ) {
87
- const metadata = useRefEditorState ( ( store ) => store . editor . jsxMetadata )
88
- const scale = useEditorState (
89
- Substores . canvas ,
90
- ( store ) => store . editor . canvas . scale ,
91
- 'GridGapControl scale' ,
92
- )
93
- const gridRowColumnInfo = useGridData ( [ selectedElement ] )
94
-
95
- const sideRef = useBoundingBox ( [ selectedElement ] , ( ref , parentBoundingBox ) => {
96
- const gridGap = maybeGridGapData ( metadata . current , selectedElement )
97
- const selectedGrid = gridRowColumnInfo . at ( 0 )
98
- if ( gridGap == null || selectedGrid == null ) {
99
- return
100
- }
101
-
102
- const controlBounds = gridGapControlBoundsFromMetadata ( selectedGrid , {
103
- row : fallbackEmptyValue ( gridGap . row ) ,
104
- column : fallbackEmptyValue ( gridGap . column ) ,
105
- } )
106
-
107
- const bound = controlBounds . gaps . find ( ( updatedGap ) => updatedGap . gapId === gap . gapId )
108
- if ( bound == null ) {
109
- return
110
- }
111
-
112
- ref . current . style . display = 'block'
113
- ref . current . style . left = `${ bound . bounds . x + parentBoundingBox . x } px`
114
- ref . current . style . top = `${ bound . bounds . y + parentBoundingBox . y } px`
115
- ref . current . style . height = numberToPxValue ( bound . bounds . height )
116
- ref . current . style . width = numberToPxValue ( bound . bounds . width )
117
- } )
118
-
119
- const color = useColorTheme ( ) . brandNeonPink . value
120
-
121
- const solidOrDashed = hoveredOrFocused === 'focused' ? 'solid' : 'dashed'
122
-
123
32
return (
124
33
< CanvasOffsetWrapper >
125
- < div
126
- ref = { sideRef }
127
- style = { {
128
- position : 'absolute' ,
129
- border : `1px ${ solidOrDashed } ${ color } ` ,
130
- } }
131
- data-testid = { getSubduedGridGaplTestID ( hoveredOrFocused ) }
132
- />
34
+ { gridRowColumnInfo . map ( ( gridData ) => {
35
+ return (
36
+ < React . Fragment key = { `grid-gap-${ EP . toString ( gridData . elementPath ) } ` } >
37
+ < GridPaddingOutlineForDimension
38
+ grid = { gridData }
39
+ dimension = { 'rows' }
40
+ onMouseDown = { NO_OP }
41
+ beingDragged = { true }
42
+ onMouseOver = { NO_OP }
43
+ zIndexPriority = { false }
44
+ gridGap = { unitlessCSSNumberWithRenderedValue ( gridData . rowGap ?? 0 ) }
45
+ elementHovered = { hoveredOrFocused === 'hovered' && axis === 'row' }
46
+ draggedOutlineColor = { colorTheme . brandNeonPink }
47
+ />
48
+ < GridPaddingOutlineForDimension
49
+ grid = { gridData }
50
+ dimension = { 'columns' }
51
+ onMouseDown = { NO_OP }
52
+ beingDragged = { true }
53
+ onMouseOver = { NO_OP }
54
+ zIndexPriority = { false }
55
+ gridGap = { unitlessCSSNumberWithRenderedValue ( gridData . columnGap ?? 0 ) }
56
+ elementHovered = { hoveredOrFocused === 'hovered' && axis === 'column' }
57
+ draggedOutlineColor = { colorTheme . brandNeonPink }
58
+ />
59
+ </ React . Fragment >
60
+ )
61
+ } ) }
133
62
</ CanvasOffsetWrapper >
134
63
)
135
- }
136
-
137
- export function getSubduedGridGaplTestID ( hoveredOrFocused : 'hovered' | 'focused' ) : string {
138
- return `SubduedGridGapControl-${ hoveredOrFocused } `
139
- }
140
-
141
- const numberToPxValue = ( n : number ) => n + 'px'
64
+ } )
0 commit comments