1
1
import { notice } from '../../../components/common/notice'
2
- import { isLeft , isRight , left } from '../../../core/shared/either'
3
2
import * as EP from '../../../core/shared/element-path'
4
- import {
5
- emptyComments ,
6
- isJSXElement ,
7
- jsExpressionValue ,
8
- } from '../../../core/shared/element-template'
9
- import type { GetModifiableAttributeResult , ValueAtPath } from '../../../core/shared/jsx-attributes'
10
- import {
11
- getModifiableJSXAttributeAtPath ,
12
- jsxSimpleAttributeToValue ,
13
- } from '../../../core/shared/jsx-attribute-utils'
14
3
import { roundTo } from '../../../core/shared/math-utils'
15
4
import type { ElementPath , PropertyPath } from '../../../core/shared/project-file-types'
16
5
import * as PP from '../../../core/shared/property-path'
17
- import type { EditorState , EditorStatePatch } from '../../editor/store/editor-state'
18
- import { withUnderlyingTargetFromEditorState } from '../../editor/store/editor-state'
6
+ import type { EditorState } from '../../editor/store/editor-state'
19
7
import type { CSSKeyword , CSSNumber , FlexDirection } from '../../inspector/common/css-utils'
20
8
import {
21
9
cssPixelLength ,
22
- parseCSSPercent ,
23
10
printCSSNumber ,
24
11
printCSSNumberOrKeyword ,
25
12
} from '../../inspector/common/css-utils'
26
- import type { CreateIfNotExistant } from './adjust-css-length-command'
27
- import { deleteConflictingPropsForWidthHeight } from './adjust-css-length-command'
13
+ import type { LengthProperty } from './adjust-css-length-command'
14
+ import {
15
+ deleteConflictingPropsForWidthHeight ,
16
+ type CreateIfNotExistant ,
17
+ } from './adjust-css-length-command'
28
18
import type { BaseCommand , CommandFunctionResult , WhenToRun } from './commands'
29
19
import { addToastPatch } from './show-toast-command'
30
- import { applyValuesAtPath } from './utils/property-utils'
20
+ import { getCSSNumberFromStyleInfo } from './utils/property-utils'
31
21
import type { InteractionLifecycle } from '../canvas-strategies/canvas-strategy-types'
22
+ import type { StyleUpdate } from '../plugins/style-plugins'
23
+ import { getActivePlugin , runStyleUpdateForStrategy } from '../plugins/style-plugins'
32
24
33
25
type CssNumberOrKeepOriginalUnit =
34
26
| { type : 'EXPLICIT_CSS_NUMBER' ; value : CSSNumber | CSSKeyword }
@@ -45,10 +37,13 @@ export function setValueKeepingOriginalUnit(
45
37
return { type : 'KEEP_ORIGINAL_UNIT' , valuePx : valuePx , parentDimensionPx : parentDimensionPx }
46
38
}
47
39
40
+ type CSSLengthProperty = LengthProperty | 'zIndex'
41
+ type CSSLengthPropertyPath = PropertyPath < [ 'style' , CSSLengthProperty ] >
42
+
48
43
export interface SetCssLengthProperty extends BaseCommand {
49
44
type : 'SET_CSS_LENGTH_PROPERTY'
50
45
target : ElementPath
51
- property : PropertyPath
46
+ property : CSSLengthPropertyPath
52
47
value : CssNumberOrKeepOriginalUnit
53
48
parentFlexDirection : FlexDirection | null
54
49
createIfNonExistant : CreateIfNotExistant
@@ -58,7 +53,7 @@ export interface SetCssLengthProperty extends BaseCommand {
58
53
export function setCssLengthProperty (
59
54
whenToRun : WhenToRun ,
60
55
target : ElementPath ,
61
- property : PropertyPath ,
56
+ property : CSSLengthPropertyPath ,
62
57
value : CssNumberOrKeepOriginalUnit ,
63
58
parentFlexDirection : FlexDirection | null ,
64
59
createIfNonExistant : CreateIfNotExistant = 'create-if-not-existing' , // TODO remove the default value and set it explicitly everywhere
@@ -90,33 +85,22 @@ export const runSetCssLengthProperty = (
90
85
command . parentFlexDirection ,
91
86
)
92
87
93
- // Identify the current value, whatever that may be.
94
- const currentValue : GetModifiableAttributeResult = withUnderlyingTargetFromEditorState (
95
- command . target ,
96
- editorState ,
97
- left ( `no target element was found at path ${ EP . toString ( command . target ) } ` ) ,
98
- ( _ , element ) => {
99
- if ( isJSXElement ( element ) ) {
100
- return getModifiableJSXAttributeAtPath ( element . props , command . property )
101
- } else {
102
- return left ( `No JSXElement was found at path ${ EP . toString ( command . target ) } ` )
103
- }
104
- } ,
105
- )
106
- if ( isLeft ( currentValue ) ) {
88
+ const styleInfo = getActivePlugin ( editorStateWithPropsDeleted ) . styleInfoFactory ( {
89
+ projectContents : editorStateWithPropsDeleted . projectContents ,
90
+ } ) ( command . target )
91
+
92
+ if ( styleInfo == null ) {
107
93
return {
108
94
editorStatePatches : [ ] ,
109
- commandDescription : `Set Css Length Prop: ${ EP . toUid ( command . target ) } /${ PP . toString (
110
- command . property ,
111
- ) } not applied as value is not writeable.`,
95
+ commandDescription : `Set Css Length Prop: Element not found at ${ EP . toUid ( command . target ) } ` ,
112
96
}
113
97
}
114
- const currentModifiableValue = currentValue . value
115
- const simpleValueResult = jsxSimpleAttributeToValue ( currentModifiableValue )
116
98
117
- const targetPropertyNonExistant : boolean = currentModifiableValue . type === 'ATTRIBUTE_NOT_FOUND'
99
+ const property = command . property . propertyElements [ 1 ] // the safety of propertyElements[1] is guaranteed by the LengthPropertyPath type
100
+
101
+ const currentValue = getCSSNumberFromStyleInfo ( styleInfo , property )
118
102
if (
119
- targetPropertyNonExistant &&
103
+ currentValue . type === 'not-found' &&
120
104
command . createIfNonExistant === 'do-not-create-if-doesnt-exist'
121
105
) {
122
106
return {
@@ -127,18 +111,18 @@ export const runSetCssLengthProperty = (
127
111
}
128
112
}
129
113
130
- let propsToUpdate : Array < ValueAtPath > = [ ]
114
+ let propsToUpdate : Array < StyleUpdate > = [ ]
131
115
132
116
let percentageValueWasReplaced : boolean = false
133
- const javascriptExpressionValueWasReplaced : boolean = isLeft ( simpleValueResult ) // Left for jsxSimpleAttributeToValue means " not simple" which means a javascript expression like `5 + props.hello`
117
+ const javascriptExpressionValueWasReplaced = currentValue . type === ' not-css-number'
134
118
135
- const parsePercentResult = parseCSSPercent ( simpleValueResult . value )
136
119
if (
137
- isRight ( parsePercentResult ) &&
120
+ currentValue . type === 'css-number' &&
121
+ currentValue . number . unit === '%' &&
138
122
command . value . type === 'KEEP_ORIGINAL_UNIT' &&
139
123
command . value . parentDimensionPx != null
140
124
) {
141
- const currentValuePercent = parsePercentResult . value
125
+ const currentValuePercent = currentValue . number
142
126
const valueInPercent = roundTo (
143
127
( command . value . valuePx / command . value . parentDimensionPx ) * 100 ,
144
128
2 ,
@@ -150,8 +134,9 @@ export const runSetCssLengthProperty = (
150
134
const newValue = printCSSNumber ( newValueCssNumber , null )
151
135
152
136
propsToUpdate . push ( {
153
- path : command . property ,
154
- value : jsExpressionValue ( newValue , emptyComments ) ,
137
+ type : 'set' ,
138
+ property : property ,
139
+ value : newValue ,
155
140
} )
156
141
} else {
157
142
const newCssValue =
@@ -161,29 +146,31 @@ export const runSetCssLengthProperty = (
161
146
162
147
if (
163
148
command . whenReplacingPercentageValues === 'warn-about-replacement' &&
164
- isRight ( parsePercentResult )
149
+ currentValue . type === 'css-number' &&
150
+ currentValue . number . unit === '%'
165
151
) {
166
152
percentageValueWasReplaced = true
167
153
}
168
154
169
155
const printedValue = printCSSNumberOrKeyword ( newCssValue , 'px' )
170
156
171
157
propsToUpdate . push ( {
172
- path : command . property ,
173
- value : jsExpressionValue ( printedValue , emptyComments ) ,
158
+ type : 'set' ,
159
+ property : property ,
160
+ value : printedValue ,
174
161
} )
175
162
}
176
163
177
164
// Apply the update to the properties.
178
- const { editorStatePatch : propertyUpdatePatch } = applyValuesAtPath (
165
+ const { editorStatePatches } = runStyleUpdateForStrategy (
166
+ interactionLifecycle ,
179
167
editorStateWithPropsDeleted ,
180
168
command . target ,
181
169
propsToUpdate ,
182
170
)
183
171
184
172
// Always include the property update patch, but potentially also include a warning
185
173
// that a percentage based property was replaced with a pixel based one.
186
- let editorStatePatches : Array < EditorStatePatch > = [ propertyUpdatePatch ]
187
174
if ( percentageValueWasReplaced ) {
188
175
editorStatePatches . push (
189
176
addToastPatch (
0 commit comments