diff --git a/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.tsx b/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.tsx
index 422708377163..eb8bf8f0b0dc 100644
--- a/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.tsx
+++ b/editor/src/components/canvas/canvas-strategies/strategies/convert-to-absolute-and-move-strategy.tsx
@@ -44,7 +44,6 @@ import { getFullFrame } from '../../../frame'
import { stylePropPathMappingFn } from '../../../inspector/common/property-path-hooks'
import type { CanvasFrameAndTarget } from '../../canvas-types'
import type { CanvasCommand } from '../../commands/commands'
-import { convertToAbsolute } from '../../commands/convert-to-absolute-command'
import type { SetCssLengthProperty } from '../../commands/set-css-length-command'
import {
setCssLengthProperty,
diff --git a/editor/src/components/canvas/canvas-strategies/strategies/set-padding-strategy.tsx b/editor/src/components/canvas/canvas-strategies/strategies/set-padding-strategy.tsx
index bb69d4fc2a7c..607524af53b9 100644
--- a/editor/src/components/canvas/canvas-strategies/strategies/set-padding-strategy.tsx
+++ b/editor/src/components/canvas/canvas-strategies/strategies/set-padding-strategy.tsx
@@ -72,10 +72,6 @@ import { elementHasOnlyTextChildren } from '../../canvas-utils'
import type { Modifiers } from '../../../../utils/modifiers'
import type { Axis } from '../../../inspector/inspector-common'
import { detectFillHugFixedState, isHuggingFixedHugFill } from '../../../inspector/inspector-common'
-import {
- AdjustCssLengthProperties,
- adjustCssLengthProperties,
-} from '../../commands/adjust-css-length-command'
import type { ElementPathTrees } from '../../../../core/shared/element-path-tree'
import { activeFrameTargetPath, setActiveFrames } from '../../commands/set-active-frames-command'
diff --git a/editor/src/components/canvas/canvas-strategies/strategies/shared-absolute-resize-strategy-helpers.ts b/editor/src/components/canvas/canvas-strategies/strategies/shared-absolute-resize-strategy-helpers.ts
index 17c7d5f55b7e..a70ebc28d65c 100644
--- a/editor/src/components/canvas/canvas-strategies/strategies/shared-absolute-resize-strategy-helpers.ts
+++ b/editor/src/components/canvas/canvas-strategies/strategies/shared-absolute-resize-strategy-helpers.ts
@@ -40,11 +40,6 @@ import {
EdgePositionBottom,
} from '../../canvas-types'
import { pickPointOnRect, snapPoint } from '../../canvas-utils'
-import type { AdjustCssLengthProperties } from '../../commands/adjust-css-length-command'
-import {
- adjustCssLengthProperties,
- lengthPropertyToAdjust,
-} from '../../commands/adjust-css-length-command'
import { pointGuidelineToBoundsEdge } from '../../controls/guideline-helpers'
import type { AbsolutePin } from './resize-helpers'
import { ensureAtLeastTwoPinsForEdgePosition, resizeBoundingBox } from './resize-helpers'
diff --git a/editor/src/components/canvas/commands/add-contain-layout-if-needed-command.ts b/editor/src/components/canvas/commands/add-contain-layout-if-needed-command.ts
index 19364723ad6d..f9d67d83cb80 100644
--- a/editor/src/components/canvas/commands/add-contain-layout-if-needed-command.ts
+++ b/editor/src/components/canvas/commands/add-contain-layout-if-needed-command.ts
@@ -2,11 +2,10 @@ import { MetadataUtils } from '../../../core/model/element-metadata-utils'
import * as EP from '../../../core/shared/element-path'
import { emptyComments, jsExpressionValue } from '../../../core/shared/element-template'
import type { ElementPath } from '../../../core/shared/project-file-types'
-import { PropertyPath } from '../../../core/shared/project-file-types'
import * as PP from '../../../core/shared/property-path'
import type { EditorState } from '../../editor/store/editor-state'
-import { applyValuesAtPath } from './adjust-number-command'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
+import { applyValuesAtPath } from './utils/property-utils'
export interface AddContainLayoutIfNeeded extends BaseCommand {
type: 'ADD_CONTAIN_LAYOUT_IF_NEEDED'
diff --git a/editor/src/components/canvas/commands/adjust-css-length-command.ts b/editor/src/components/canvas/commands/adjust-css-length-command.ts
index 90daf3c850e6..c7186760ec23 100644
--- a/editor/src/components/canvas/commands/adjust-css-length-command.ts
+++ b/editor/src/components/canvas/commands/adjust-css-length-command.ts
@@ -22,8 +22,8 @@ import { modifyUnderlyingForOpenFile } from '../../editor/store/editor-state'
import type { CSSNumber, FlexDirection } from '../../inspector/common/css-utils'
import { parseCSSPercent, parseCSSPx, printCSSNumber } from '../../inspector/common/css-utils'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
-import { deleteValuesAtPath } from './delete-properties-command'
import { patchParseSuccessAtElementPath } from './patch-utils'
+import { deleteValuesAtPath } from './utils/property-utils'
export type CreateIfNotExistant = 'create-if-not-existing' | 'do-not-create-if-doesnt-exist'
@@ -416,7 +416,7 @@ function getConflictingPropertiesToDelete(
return propertiesToDelete
}
-export function deleteConflictingPropsForWidthHeightFromAttributes(
+function deleteConflictingPropsForWidthHeightFromAttributes(
attributes: JSXAttributes,
propertyPath: PropertyPath,
parentFlexDirection: FlexDirection | null,
diff --git a/editor/src/components/canvas/commands/adjust-number-command.spec.tsx b/editor/src/components/canvas/commands/adjust-number-command.spec.tsx
deleted file mode 100644
index 41ac2e58d9f5..000000000000
--- a/editor/src/components/canvas/commands/adjust-number-command.spec.tsx
+++ /dev/null
@@ -1,143 +0,0 @@
-import update from 'immutability-helper'
-import { styleStringInArray } from '../../../utils/common-constants'
-import { createBuiltInDependenciesList } from '../../../core/es-modules/package-manager/built-in-dependencies-list'
-import * as EP from '../../../core/shared/element-path'
-import { getNumberPropertyFromProps } from '../../../core/shared/jsx-attributes'
-import { complexDefaultProjectPreParsed } from '../../../sample-projects/sample-project-utils.test-utils'
-import { withUnderlyingTargetFromEditorState } from '../../editor/store/editor-state'
-import { stylePropPathMappingFn } from '../../inspector/common/property-path-hooks'
-import {
- DefaultStartingFeatureSwitches,
- makeTestProjectCodeWithSnippet,
- renderTestEditorWithCode,
- renderTestEditorWithModel,
-} from '../ui-jsx.test-utils'
-import { adjustNumberProperty, runAdjustNumberProperty } from './adjust-number-command'
-import { updateEditorStateWithPatches } from './commands'
-import { isJSXElement } from '../../../core/shared/element-template'
-
-describe('adjustNumberProperty', () => {
- it('works for left style prop', async () => {
- const renderResult = await renderTestEditorWithModel(
- complexDefaultProjectPreParsed(),
- 'dont-await-first-dom-report',
- DefaultStartingFeatureSwitches,
- createBuiltInDependenciesList(null),
- )
-
- const cardInstancePath = EP.elementPath([
- ['storyboard-entity', 'scene-1-entity', 'app-entity'],
- ['app-outer-div', 'card-instance'],
- ])
-
- const originalEditorState = renderResult.getEditorState().editor
-
- const originalLeftStyleProp = withUnderlyingTargetFromEditorState(
- cardInstancePath,
- originalEditorState,
- null,
- (success, element, underlyingTarget, underlyingFilePath) => {
- if (isJSXElement(element)) {
- return getNumberPropertyFromProps(
- element.props,
- stylePropPathMappingFn('left', styleStringInArray),
- )
- } else {
- return null
- }
- },
- )!
-
- const delta = 10
-
- const adjustNumberPropertyCommand = adjustNumberProperty(
- 'always',
- cardInstancePath,
- stylePropPathMappingFn('left', styleStringInArray),
- delta,
- true,
- )
-
- const result = runAdjustNumberProperty(
- renderResult.getEditorState().editor,
- adjustNumberPropertyCommand,
- )
-
- const patchedEditor = updateEditorStateWithPatches(
- renderResult.getEditorState().editor,
- result.editorStatePatches,
- )
-
- const updatedLeftStyleProp = withUnderlyingTargetFromEditorState(
- cardInstancePath,
- patchedEditor,
- null,
- (success, element, underlyingTarget, underlyingFilePath) => {
- if (isJSXElement(element)) {
- return getNumberPropertyFromProps(
- element.props,
- stylePropPathMappingFn('left', styleStringInArray),
- )
- } else {
- return null
- }
- },
- )
-
- expect(updatedLeftStyleProp).toEqual(originalLeftStyleProp + delta)
- })
- it('works for missing left style prop', async () => {
- const renderResult = await renderTestEditorWithCode(
- makeTestProjectCodeWithSnippet(`
-
- `),
- 'dont-await-first-dom-report',
- )
-
- const elementPath = EP.elementPath([
- ['scene-aaa', 'app-entity'],
- ['parent', 'child'],
- ])
-
- const delta = 10
-
- // left prop is missing, it should be just set to the delta value
- const adjustNumberPropertyCommand = adjustNumberProperty(
- 'always',
- elementPath,
- stylePropPathMappingFn('left', styleStringInArray),
- delta,
- true,
- )
-
- const result = runAdjustNumberProperty(
- renderResult.getEditorState().editor,
- adjustNumberPropertyCommand,
- )
-
- const patchedEditor = updateEditorStateWithPatches(
- renderResult.getEditorState().editor,
- result.editorStatePatches,
- )
- const updatedLeftStyleProp = withUnderlyingTargetFromEditorState(
- elementPath,
- patchedEditor,
- null,
- (success, element, underlyingTarget, underlyingFilePath) => {
- if (isJSXElement(element)) {
- return getNumberPropertyFromProps(
- element.props,
- stylePropPathMappingFn('left', styleStringInArray),
- )
- } else {
- return null
- }
- },
- )
-
- expect(updatedLeftStyleProp).toEqual(delta)
- })
-})
diff --git a/editor/src/components/canvas/commands/adjust-number-command.ts b/editor/src/components/canvas/commands/adjust-number-command.ts
deleted file mode 100644
index 6750b8a0b328..000000000000
--- a/editor/src/components/canvas/commands/adjust-number-command.ts
+++ /dev/null
@@ -1,211 +0,0 @@
-import { foldEither } from '../../../core/shared/either'
-import * as EP from '../../../core/shared/element-path'
-import type { JSXElement } from '../../../core/shared/element-template'
-import {
- emptyComments,
- isJSXElement,
- jsExpressionValue,
-} from '../../../core/shared/element-template'
-import type { ValueAtPath } from '../../../core/shared/jsx-attributes'
-import {
- getNumberPropertyFromProps,
- setJSXValuesAtPaths,
-} from '../../../core/shared/jsx-attributes'
-import type { ElementPath, PropertyPath } from '../../../core/shared/project-file-types'
-import * as PP from '../../../core/shared/property-path'
-import type { EditorState, EditorStatePatch } from '../../editor/store/editor-state'
-import {
- modifyUnderlyingElementForOpenFile,
- withUnderlyingTargetFromEditorState,
-} from '../../editor/store/editor-state'
-import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
-import { patchParseSuccessAtElementPath } from './patch-utils'
-
-export interface AdjustNumberProperty extends BaseCommand {
- type: 'ADJUST_NUMBER_PROPERTY'
- target: ElementPath
- property: PropertyPath
- value: number | AdjustNumberInequalityCondition
- createIfNonExistant: boolean
-}
-
-export function adjustNumberProperty(
- whenToRun: WhenToRun,
- target: ElementPath,
- property: PropertyPath,
- value: number | AdjustNumberInequalityCondition,
- createIfNonExistant: boolean,
-): AdjustNumberProperty {
- return {
- type: 'ADJUST_NUMBER_PROPERTY',
- whenToRun: whenToRun,
- target: target,
- property: property,
- value: value,
- createIfNonExistant: createIfNonExistant,
- }
-}
-
-export type AdjustNumberCondition = 'less-than' | 'greater-than'
-
-export interface AdjustNumberInequalityCondition {
- property: PropertyPath
- condition: AdjustNumberCondition
-}
-
-export function adjustNumberInequalityCondition(
- property: PropertyPath,
- condition: AdjustNumberCondition,
-): AdjustNumberInequalityCondition {
- return {
- property: property,
- condition: condition,
- }
-}
-
-export const runAdjustNumberProperty: CommandFunction = (
- editorState: EditorState,
- command: AdjustNumberProperty,
-) => {
- // Handle updating the existing value, treating a value that can't be parsed
- // as zero.
- let newValue: number = 0
-
- // Identify the current value, whatever that may be.
- let targetPropertyNonExistant: boolean = false
- let inequalityValue: number | null = null
- const currentValue = withUnderlyingTargetFromEditorState(
- command.target,
- editorState,
- null,
- (success, element, underlyingTarget, underlyingFilePath) => {
- if (isJSXElement(element)) {
- // Check for the inequality adjustment target while we're here.
- if (typeof command.value !== 'number') {
- inequalityValue = getNumberPropertyFromProps(element.props, command.value.property)
- }
-
- // Try the property we're updating.
- const fromProperty = getNumberPropertyFromProps(element.props, command.property)
- if (fromProperty == null) {
- targetPropertyNonExistant = true
- } else {
- return fromProperty
- }
- }
- return null
- },
- )
-
- if (targetPropertyNonExistant && !command.createIfNonExistant) {
- return {
- editorStatePatches: [],
- commandDescription: `Adjust Number Prop: ${EP.toUid(command.target)}/${PP.toString(
- command.property,
- )} not applied as the property does not exist.`,
- }
- } else {
- if (typeof command.value === 'number') {
- if (currentValue != null) {
- newValue += currentValue
- }
-
- // Change the value.
- newValue += command.value
- } else {
- if (currentValue != null && inequalityValue != null) {
- switch (command.value.condition) {
- case 'less-than':
- if (inequalityValue <= currentValue) {
- return {
- editorStatePatches: [],
- commandDescription: `Adjust Number Prop: ${EP.toUid(command.target)}/${PP.toString(
- command.property,
- )} not applied as value is large enough already.`,
- }
- } else {
- newValue = inequalityValue
- }
- break
- case 'greater-than':
- if (inequalityValue >= currentValue) {
- return {
- editorStatePatches: [],
- commandDescription: `Adjust Number Prop: ${EP.toUid(command.target)}/${PP.toString(
- command.property,
- )} not applied as value is small enough already.`,
- }
- } else {
- newValue = inequalityValue
- }
- break
- default:
- const _exhaustiveCheck: never = command.value.condition
- throw new Error(`Unhandled command condition of ${JSON.stringify(command.value)}`)
- }
- }
- }
-
- const propsToUpdate: Array = [
- {
- path: command.property,
- value: jsExpressionValue(newValue, emptyComments),
- },
- ]
-
- // Apply the update to the properties.
- const { editorStatePatch: propertyUpdatePatch } = applyValuesAtPath(
- editorState,
- command.target,
- propsToUpdate,
- )
-
- return {
- editorStatePatches: [propertyUpdatePatch],
- commandDescription: `Adjust Number Prop: ${EP.toUid(command.target)}/${PP.toString(
- command.property,
- )} by ${command.value}`,
- }
- }
-}
-
-export function applyValuesAtPath(
- editorState: EditorState,
- target: ElementPath,
- jsxValuesAndPathsToSet: ValueAtPath[],
-): { editorStateWithChanges: EditorState; editorStatePatch: EditorStatePatch } {
- const workingEditorState = modifyUnderlyingElementForOpenFile(
- target,
- editorState,
- (element: JSXElement) => {
- return foldEither(
- () => {
- return element
- },
- (updatedProps) => {
- return {
- ...element,
- props: updatedProps,
- }
- },
- setJSXValuesAtPaths(element.props, jsxValuesAndPathsToSet),
- )
- },
- )
-
- const editorStatePatch = patchParseSuccessAtElementPath(target, workingEditorState, (success) => {
- return {
- topLevelElements: {
- $set: success.topLevelElements,
- },
- imports: {
- $set: success.imports,
- },
- }
- })
-
- return {
- editorStateWithChanges: workingEditorState,
- editorStatePatch: editorStatePatch,
- }
-}
diff --git a/editor/src/components/canvas/commands/commands.ts b/editor/src/components/canvas/commands/commands.ts
index cf7428ce5209..816ad0c558cd 100644
--- a/editor/src/components/canvas/commands/commands.ts
+++ b/editor/src/components/canvas/commands/commands.ts
@@ -6,8 +6,6 @@ import type { EditorState, EditorStatePatch } from '../../editor/store/editor-st
import type { CommandDescription } from '../canvas-strategies/interaction-state'
import type { AdjustCssLengthProperties } from './adjust-css-length-command'
import { runAdjustCssLengthProperties } from './adjust-css-length-command'
-import type { AdjustNumberProperty } from './adjust-number-command'
-import { runAdjustNumberProperty } from './adjust-number-command'
import type { ConvertToAbsolute } from './convert-to-absolute-command'
import { runConvertToAbsolute } from './convert-to-absolute-command'
import type { ReorderElement } from './reorder-element-command'
@@ -47,8 +45,6 @@ import type { InsertElementInsertionSubject } from './insert-element-insertion-s
import { runInsertElementInsertionSubject } from './insert-element-insertion-subject'
import type { AddElement } from './add-element-command'
import { runAddElement } from './add-element-command'
-import type { UpdatePropIfExists } from './update-prop-if-exists-command'
-import { runUpdatePropIfExists } from './update-prop-if-exists-command'
import type { HighlightElementsCommand } from './highlight-element-command'
import { runHighlightElementsCommand } from './highlight-element-command'
import type { InteractionLifecycle } from '../canvas-strategies/canvas-strategy-types'
@@ -102,7 +98,6 @@ export type CanvasCommand =
| WildcardPatch
| UpdateFunctionCommand
| StrategySwitched
- | AdjustNumberProperty
| AdjustCssLengthProperties
| ReparentElement
| DuplicateElement
@@ -119,7 +114,6 @@ export type CanvasCommand =
| PushIntendedBoundsAndUpdateHuggingElements
| DeleteProperties
| SetProperty
- | UpdatePropIfExists
| AddImportsToFile
| AddToReparentedToPaths
| InsertElementInsertionSubject
@@ -151,8 +145,6 @@ export function runCanvasCommand(
return runUpdateFunctionCommand(editorState, command, commandLifecycle)
case 'STRATEGY_SWITCHED':
return runStrategySwitchedCommand(command)
- case 'ADJUST_NUMBER_PROPERTY':
- return runAdjustNumberProperty(editorState, command)
case 'ADJUST_CSS_LENGTH_PROPERTY':
return runAdjustCssLengthProperties(editorState, command)
case 'REPARENT_ELEMENT':
@@ -187,8 +179,6 @@ export function runCanvasCommand(
return runSetProperty(editorState, command)
case 'UPDATE_BULK_PROPERTIES':
return runBulkUpdateProperties(editorState, command)
- case 'UPDATE_PROP_IF_EXISTS':
- return runUpdatePropIfExists(editorState, command)
case 'ADD_IMPORTS_TO_FILE':
return runAddImportsToFile(editorState, command)
case 'ADD_TO_REPARENTED_TO_PATHS':
diff --git a/editor/src/components/canvas/commands/convert-css-percent-to-px-command.ts b/editor/src/components/canvas/commands/convert-css-percent-to-px-command.ts
index 990dbc2ac63c..8b77cf92a033 100644
--- a/editor/src/components/canvas/commands/convert-css-percent-to-px-command.ts
+++ b/editor/src/components/canvas/commands/convert-css-percent-to-px-command.ts
@@ -16,8 +16,8 @@ import type { EditorState } from '../../editor/store/editor-state'
import { withUnderlyingTargetFromEditorState } from '../../editor/store/editor-state'
import type { CSSNumber } from '../../inspector/common/css-utils'
import { parseCSSPercent, printCSSNumber } from '../../inspector/common/css-utils'
-import { applyValuesAtPath } from './adjust-number-command'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
+import { applyValuesAtPath } from './utils/property-utils'
export interface ConvertCssPercentToPx extends BaseCommand {
type: 'CONVERT_CSS_PERCENT_TO_PX'
diff --git a/editor/src/components/canvas/commands/convert-to-absolute-command.ts b/editor/src/components/canvas/commands/convert-to-absolute-command.ts
index 7ecb5b1726ab..2effb0eef891 100644
--- a/editor/src/components/canvas/commands/convert-to-absolute-command.ts
+++ b/editor/src/components/canvas/commands/convert-to-absolute-command.ts
@@ -7,8 +7,8 @@ import type { ValueAtPath } from '../../../core/shared/jsx-attributes'
import type { ElementPath } from '../../../core/shared/project-file-types'
import type { EditorState, EditorStatePatch } from '../../editor/store/editor-state'
import { stylePropPathMappingFn } from '../../inspector/common/property-path-hooks'
-import { applyValuesAtPath } from './adjust-number-command'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
+import { applyValuesAtPath } from './utils/property-utils'
export interface ConvertToAbsolute extends BaseCommand {
type: 'CONVERT_TO_ABSOLUTE'
diff --git a/editor/src/components/canvas/commands/delete-properties-command.ts b/editor/src/components/canvas/commands/delete-properties-command.ts
index f1d8501385b3..65565b21d922 100644
--- a/editor/src/components/canvas/commands/delete-properties-command.ts
+++ b/editor/src/components/canvas/commands/delete-properties-command.ts
@@ -1,13 +1,9 @@
-import type { JSXElement } from '../../../core/shared/element-template'
-import type { EditorState, EditorStatePatch } from '../../../components/editor/store/editor-state'
-import { modifyUnderlyingElementForOpenFile } from '../../../components/editor/store/editor-state'
-import { foldEither } from '../../../core/shared/either'
-import { unsetJSXValuesAtPaths } from '../../../core/shared/jsx-attributes'
+import type { EditorState } from '../../../components/editor/store/editor-state'
import type { ElementPath, PropertyPath } from '../../../core/shared/project-file-types'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
import * as EP from '../../../core/shared/element-path'
import * as PP from '../../../core/shared/property-path'
-import { patchParseSuccessAtElementPath } from './patch-utils'
+import { deleteValuesAtPath } from './utils/property-utils'
export interface DeleteProperties extends BaseCommand {
type: 'DELETE_PROPERTIES'
@@ -46,43 +42,3 @@ export const runDeleteProperties: CommandFunction = (
.join(',')} on ${EP.toUid(command.element)}`,
}
}
-
-export function deleteValuesAtPath(
- editorState: EditorState,
- target: ElementPath,
- properties: Array,
-): { editorStateWithChanges: EditorState; editorStatePatch: EditorStatePatch } {
- const workingEditorState = modifyUnderlyingElementForOpenFile(
- target,
- editorState,
- (element: JSXElement) => {
- return foldEither(
- () => {
- return element
- },
- (updatedProps) => {
- return {
- ...element,
- props: updatedProps,
- }
- },
- unsetJSXValuesAtPaths(element.props, properties),
- )
- },
- )
-
- const editorStatePatch = patchParseSuccessAtElementPath(target, workingEditorState, (success) => {
- return {
- topLevelElements: {
- $set: success.topLevelElements,
- },
- imports: {
- $set: success.imports,
- },
- }
- })
- return {
- editorStateWithChanges: workingEditorState,
- editorStatePatch: editorStatePatch,
- }
-}
diff --git a/editor/src/components/canvas/commands/set-css-length-command.ts b/editor/src/components/canvas/commands/set-css-length-command.ts
index cde200d644a5..0a4bafc4d315 100644
--- a/editor/src/components/canvas/commands/set-css-length-command.ts
+++ b/editor/src/components/canvas/commands/set-css-length-command.ts
@@ -25,9 +25,9 @@ import {
} from '../../inspector/common/css-utils'
import type { CreateIfNotExistant } from './adjust-css-length-command'
import { deleteConflictingPropsForWidthHeight } from './adjust-css-length-command'
-import { applyValuesAtPath } from './adjust-number-command'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
import { addToastPatch } from './show-toast-command'
+import { applyValuesAtPath } from './utils/property-utils'
type CssNumberOrKeepOriginalUnit =
| { type: 'EXPLICIT_CSS_NUMBER'; value: CSSNumber | CSSKeyword }
diff --git a/editor/src/components/canvas/commands/set-property-command.ts b/editor/src/components/canvas/commands/set-property-command.ts
index a7b06f27de13..ca791fd81306 100644
--- a/editor/src/components/canvas/commands/set-property-command.ts
+++ b/editor/src/components/canvas/commands/set-property-command.ts
@@ -8,9 +8,8 @@ import type {
} from '../../../core/shared/project-file-types'
import * as PP from '../../../core/shared/property-path'
import type { EditorState } from '../../editor/store/editor-state'
-import { applyValuesAtPath } from './adjust-number-command'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
-import { deleteValuesAtPath } from './delete-properties-command'
+import { applyValuesAtPath, deleteValuesAtPath } from './utils/property-utils'
type PositionProp = 'left' | 'top' | 'right' | 'bottom' | 'width' | 'height'
diff --git a/editor/src/components/canvas/commands/update-class-list-command.ts b/editor/src/components/canvas/commands/update-class-list-command.ts
index 208c80719ec8..1643ccbeea3c 100644
--- a/editor/src/components/canvas/commands/update-class-list-command.ts
+++ b/editor/src/components/canvas/commands/update-class-list-command.ts
@@ -14,8 +14,8 @@ import {
import { getTailwindConfigCached } from '../../../core/tailwind/tailwind-compilation'
import { getClassNameAttribute } from '../../../core/tailwind/tailwind-options'
import { getElementFromProjectContents, type EditorState } from '../../editor/store/editor-state'
-import { applyValuesAtPath } from './adjust-number-command'
import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
+import { applyValuesAtPath } from './utils/property-utils'
export interface UpdateClassList extends BaseCommand {
type: 'UPDATE_CLASS_LIST'
diff --git a/editor/src/components/canvas/commands/update-prop-if-exists-command.ts b/editor/src/components/canvas/commands/update-prop-if-exists-command.ts
deleted file mode 100644
index 3f8677579462..000000000000
--- a/editor/src/components/canvas/commands/update-prop-if-exists-command.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import { foldEither, isRight } from '../../../core/shared/either'
-import * as EP from '../../../core/shared/element-path'
-import {
- emptyComments,
- modifiableAttributeIsAttributeNotFound,
- isJSXElement,
- jsExpressionValue,
-} from '../../../core/shared/element-template'
-import { getModifiableJSXAttributeAtPath } from '../../../core/shared/jsx-attribute-utils'
-import type { ElementPath, PropertyPath } from '../../../core/shared/project-file-types'
-import * as PP from '../../../core/shared/property-path'
-import type { EditorState } from '../../editor/store/editor-state'
-import { withUnderlyingTargetFromEditorState } from '../../editor/store/editor-state'
-import { applyValuesAtPath } from './adjust-number-command'
-import type { BaseCommand, CommandFunction, WhenToRun } from './commands'
-
-export interface UpdatePropIfExists extends BaseCommand {
- type: 'UPDATE_PROP_IF_EXISTS'
- element: ElementPath
- property: PropertyPath
- value: string
-}
-
-export function updatePropIfExists(
- whenToRun: WhenToRun,
- element: ElementPath,
- property: PropertyPath,
- value: string,
-): UpdatePropIfExists {
- return {
- type: 'UPDATE_PROP_IF_EXISTS',
- whenToRun: whenToRun,
- element: element,
- property: property,
- value: value,
- }
-}
-
-export const runUpdatePropIfExists: CommandFunction = (
- editorState: EditorState,
- command: UpdatePropIfExists,
-) => {
- // check if the prop exists
- const propertyExists = withUnderlyingTargetFromEditorState(
- command.element,
- editorState,
- false,
- (_, element) => {
- if (isJSXElement(element)) {
- return foldEither(
- () => false,
- (value) => !modifiableAttributeIsAttributeNotFound(value),
- getModifiableJSXAttributeAtPath(element.props, command.property),
- )
- } else {
- return false
- }
- },
- )
-
- if (propertyExists) {
- // Apply the update to the properties.
- const { editorStatePatch: propertyUpdatePatch } = applyValuesAtPath(
- editorState,
- command.element,
- [{ path: command.property, value: jsExpressionValue(command.value, emptyComments) }],
- )
-
- return {
- editorStatePatches: [propertyUpdatePatch],
- commandDescription: `Update Prop if Exists ${PP.toString(command.property)}=${JSON.stringify(
- command.property,
- null,
- 2,
- )} on ${EP.toUid(command.element)}`,
- }
- } else {
- // no op return to prevent updating a nonexistant prop. if you want to set a prop regardless whether it exists or not, use the setPropertyCommand
- return {
- editorStatePatches: [],
- commandDescription: `Update Prop if Exists did not find existing prop for ${PP.toString(
- command.property,
- )}`,
- }
- }
-}
diff --git a/editor/src/components/canvas/commands/utils/property-utils.ts b/editor/src/components/canvas/commands/utils/property-utils.ts
new file mode 100644
index 000000000000..0198ad74bcc7
--- /dev/null
+++ b/editor/src/components/canvas/commands/utils/property-utils.ts
@@ -0,0 +1,88 @@
+import type { ElementPath, JSXElement, PropertyPath } from 'utopia-shared/src/types'
+import { foldEither } from '../../../../core/shared/either'
+import type { ValueAtPath } from '../../../../core/shared/jsx-attributes'
+import { setJSXValuesAtPaths, unsetJSXValuesAtPaths } from '../../../../core/shared/jsx-attributes'
+import type { EditorState, EditorStatePatch } from '../../../editor/store/editor-state'
+import { modifyUnderlyingElementForOpenFile } from '../../../editor/store/editor-state'
+import { patchParseSuccessAtElementPath } from '../patch-utils'
+
+export function applyValuesAtPath(
+ editorState: EditorState,
+ target: ElementPath,
+ jsxValuesAndPathsToSet: ValueAtPath[],
+): { editorStateWithChanges: EditorState; editorStatePatch: EditorStatePatch } {
+ const workingEditorState = modifyUnderlyingElementForOpenFile(
+ target,
+ editorState,
+ (element: JSXElement) => {
+ return foldEither(
+ () => {
+ return element
+ },
+ (updatedProps) => {
+ return {
+ ...element,
+ props: updatedProps,
+ }
+ },
+ setJSXValuesAtPaths(element.props, jsxValuesAndPathsToSet),
+ )
+ },
+ )
+
+ const editorStatePatch = patchParseSuccessAtElementPath(target, workingEditorState, (success) => {
+ return {
+ topLevelElements: {
+ $set: success.topLevelElements,
+ },
+ imports: {
+ $set: success.imports,
+ },
+ }
+ })
+
+ return {
+ editorStateWithChanges: workingEditorState,
+ editorStatePatch: editorStatePatch,
+ }
+}
+
+export function deleteValuesAtPath(
+ editorState: EditorState,
+ target: ElementPath,
+ properties: Array,
+): { editorStateWithChanges: EditorState; editorStatePatch: EditorStatePatch } {
+ const workingEditorState = modifyUnderlyingElementForOpenFile(
+ target,
+ editorState,
+ (element: JSXElement) => {
+ return foldEither(
+ () => {
+ return element
+ },
+ (updatedProps) => {
+ return {
+ ...element,
+ props: updatedProps,
+ }
+ },
+ unsetJSXValuesAtPaths(element.props, properties),
+ )
+ },
+ )
+
+ const editorStatePatch = patchParseSuccessAtElementPath(target, workingEditorState, (success) => {
+ return {
+ topLevelElements: {
+ $set: success.topLevelElements,
+ },
+ imports: {
+ $set: success.imports,
+ },
+ }
+ })
+ return {
+ editorStateWithChanges: workingEditorState,
+ editorStatePatch: editorStatePatch,
+ }
+}
diff --git a/editor/src/components/editor/actions/action-utils.ts b/editor/src/components/editor/actions/action-utils.ts
index 5f00da49b4c8..2cba7eaa684a 100644
--- a/editor/src/components/editor/actions/action-utils.ts
+++ b/editor/src/components/editor/actions/action-utils.ts
@@ -370,7 +370,6 @@ export function getElementsToNormalizeFromCommands(commands: CanvasCommand[]): E
switch (command.type) {
case 'ADJUST_CSS_LENGTH_PROPERTY':
case 'SET_CSS_LENGTH_PROPERTY':
- case 'ADJUST_NUMBER_PROPERTY':
case 'CONVERT_CSS_PERCENT_TO_PX':
case 'CONVERT_TO_ABSOLUTE':
return command.target
diff --git a/editor/src/components/editor/actions/actions.tsx b/editor/src/components/editor/actions/actions.tsx
index b70275861002..05968e0c0bbf 100644
--- a/editor/src/components/editor/actions/actions.tsx
+++ b/editor/src/components/editor/actions/actions.tsx
@@ -544,10 +544,7 @@ import {
replaceWithElementsWrappedInFragmentBehaviour,
} from '../store/insertion-path'
import { getConditionalCaseCorrespondingToBranchPath } from '../../../core/model/conditionals'
-import {
- deleteProperties,
- deleteValuesAtPath,
-} from '../../canvas/commands/delete-properties-command'
+import { deleteProperties } from '../../canvas/commands/delete-properties-command'
import { treatElementAsFragmentLike } from '../../canvas/canvas-strategies/strategies/fragment-like-helpers'
import {
fixParentContainingBlockSettings,
@@ -628,8 +625,8 @@ import { isReplaceKeepChildrenAndStyleTarget } from '../../navigator/navigator-i
import { canCondenseJSXElementChild } from '../../../utils/can-condense'
import { getNavigatorTargetsFromEditorState } from '../../navigator/navigator-utils'
import { getParseCacheOptions } from '../../../core/shared/parse-cache-utils'
-import { applyValuesAtPath } from '../../canvas/commands/adjust-number-command'
import { styleP } from '../../inspector/inspector-common'
+import { applyValuesAtPath, deleteValuesAtPath } from '../../canvas/commands/utils/property-utils'
export const MIN_CODE_PANE_REOPEN_WIDTH = 100