@elementor/editor-components 3.35.0-432 → 3.35.0-434

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-components",
3
3
  "description": "Elementor editor components",
4
- "version": "3.35.0-432",
4
+ "version": "3.35.0-434",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -40,30 +40,30 @@
40
40
  "dev": "tsup --config=../../tsup.dev.ts"
41
41
  },
42
42
  "dependencies": {
43
- "@elementor/editor": "3.35.0-432",
44
- "@elementor/editor-canvas": "3.35.0-432",
45
- "@elementor/editor-controls": "3.35.0-432",
46
- "@elementor/editor-documents": "3.35.0-432",
47
- "@elementor/editor-editing-panel": "3.35.0-432",
48
- "@elementor/editor-elements": "3.35.0-432",
49
- "@elementor/editor-elements-panel": "3.35.0-432",
50
- "@elementor/editor-mcp": "3.35.0-432",
51
- "@elementor/editor-panels": "3.35.0-432",
52
- "@elementor/editor-props": "3.35.0-432",
53
- "@elementor/editor-styles-repository": "3.35.0-432",
54
- "@elementor/editor-ui": "3.35.0-432",
55
- "@elementor/editor-v1-adapters": "3.35.0-432",
56
- "@elementor/http-client": "3.35.0-432",
43
+ "@elementor/editor": "3.35.0-434",
44
+ "@elementor/editor-canvas": "3.35.0-434",
45
+ "@elementor/editor-controls": "3.35.0-434",
46
+ "@elementor/editor-documents": "3.35.0-434",
47
+ "@elementor/editor-editing-panel": "3.35.0-434",
48
+ "@elementor/editor-elements": "3.35.0-434",
49
+ "@elementor/editor-elements-panel": "3.35.0-434",
50
+ "@elementor/editor-mcp": "3.35.0-434",
51
+ "@elementor/editor-panels": "3.35.0-434",
52
+ "@elementor/editor-props": "3.35.0-434",
53
+ "@elementor/editor-styles-repository": "3.35.0-434",
54
+ "@elementor/editor-ui": "3.35.0-434",
55
+ "@elementor/editor-v1-adapters": "3.35.0-434",
56
+ "@elementor/http-client": "3.35.0-434",
57
57
  "@elementor/icons": "^1.63.0",
58
- "@elementor/mixpanel": "3.35.0-432",
59
- "@elementor/query": "3.35.0-432",
60
- "@elementor/schema": "3.35.0-432",
61
- "@elementor/store": "3.35.0-432",
58
+ "@elementor/mixpanel": "3.35.0-434",
59
+ "@elementor/query": "3.35.0-434",
60
+ "@elementor/schema": "3.35.0-434",
61
+ "@elementor/store": "3.35.0-434",
62
62
  "@elementor/ui": "1.36.17",
63
- "@elementor/utils": "3.35.0-432",
63
+ "@elementor/utils": "3.35.0-434",
64
64
  "@wordpress/i18n": "^5.13.0",
65
- "@elementor/editor-notifications": "3.35.0-432",
66
- "@elementor/editor-current-user": "3.35.0-432"
65
+ "@elementor/editor-notifications": "3.35.0-434",
66
+ "@elementor/editor-current-user": "3.35.0-434"
67
67
  },
68
68
  "peerDependencies": {
69
69
  "react": "^18.3.1",
@@ -1 +1,2 @@
1
1
  export const COMPONENT_DOCUMENT_TYPE = 'elementor_component';
2
+ export const OVERRIDABLE_PROP_REPLACEMENT_ID = 'overridable-prop';
@@ -4,7 +4,7 @@ import { getFieldIndicators } from '@elementor/editor-editing-panel';
4
4
  import { useSelectedElement } from '@elementor/editor-elements';
5
5
  import { PanelBody, PanelHeader, PanelHeaderTitle } from '@elementor/editor-panels';
6
6
  import { ComponentsIcon, PencilIcon } from '@elementor/icons';
7
- import { IconButton, Stack, Tooltip } from '@elementor/ui';
7
+ import { Divider, IconButton, Stack, Tooltip } from '@elementor/ui';
8
8
  import { __ } from '@wordpress/i18n';
9
9
 
10
10
  import { useComponentInstanceSettings } from '../../hooks/use-component-instance-settings';
@@ -64,12 +64,14 @@ export function InstanceEditingPanel() {
64
64
  ) : (
65
65
  <Stack direction="column" alignItems="stretch">
66
66
  { groups.map( ( group ) => (
67
- <OverridePropsGroup
68
- key={ group.id }
69
- group={ group }
70
- props={ overridableProps.props }
71
- overrides={ overrides }
72
- />
67
+ <React.Fragment key={ group.id }>
68
+ <OverridePropsGroup
69
+ group={ group }
70
+ props={ overridableProps.props }
71
+ overrides={ overrides }
72
+ />
73
+ <Divider />
74
+ </React.Fragment>
73
75
  ) ) }
74
76
  </Stack>
75
77
  ) }
@@ -1,13 +1,16 @@
1
1
  import * as React from 'react';
2
- import { PropKeyProvider, PropProvider, useBoundProp } from '@elementor/editor-controls';
2
+ import { ControlReplacementsProvider, PropKeyProvider, PropProvider, useBoundProp } from '@elementor/editor-controls';
3
3
  import {
4
+ BaseControl,
4
5
  controlsRegistry,
5
6
  type ControlType,
6
7
  createTopLevelObjectType,
8
+ ElementProvider,
9
+ getControlReplacements,
7
10
  SettingsField,
11
+ useElement,
8
12
  } from '@elementor/editor-editing-panel';
9
- import { type Control } from '@elementor/editor-elements';
10
- import { type PropValue, type TransformablePropValue } from '@elementor/editor-props';
13
+ import { type Control, getElementType } from '@elementor/editor-elements';
11
14
  import { Stack } from '@elementor/ui';
12
15
 
13
16
  import { useControlsByWidgetType } from '../../hooks/use-controls-by-widget-type';
@@ -16,18 +19,21 @@ import {
16
19
  componentInstanceOverridePropTypeUtil,
17
20
  } from '../../prop-types/component-instance-override-prop-type';
18
21
  import {
22
+ type ComponentInstanceOverride,
19
23
  componentInstanceOverridesPropTypeUtil,
20
24
  type ComponentInstanceOverridesPropValue,
21
25
  } from '../../prop-types/component-instance-overrides-prop-type';
22
26
  import { componentInstancePropTypeUtil } from '../../prop-types/component-instance-prop-type';
23
27
  import {
28
+ type ComponentOverridableProp,
24
29
  componentOverridablePropTypeUtil,
25
- type ComponentOverridablePropValue,
26
30
  } from '../../prop-types/component-overridable-prop-type';
31
+ import { OverridablePropProvider } from '../../provider/overridable-prop-context';
27
32
  import { updateOverridableProp } from '../../store/actions/update-overridable-prop';
28
33
  import { useCurrentComponentId } from '../../store/store';
29
34
  import { type OriginPropFields, type OverridableProp } from '../../types';
30
35
  import { getPropTypeForComponentOverride } from '../../utils/get-prop-type-for-component-override';
36
+ import { resolveOverridePropValue } from '../../utils/resolve-override-prop-value';
31
37
  import { ControlLabel } from '../control-label';
32
38
 
33
39
  type Props = {
@@ -35,7 +41,7 @@ type Props = {
35
41
  overrides?: ComponentInstanceOverridesPropValue;
36
42
  };
37
43
 
38
- type OverridesSchema = Record< string, NonNullable< ComponentInstanceOverridesPropValue >[ number ] >;
44
+ type OverridesSchema = Record< string, ComponentInstanceOverride >;
39
45
 
40
46
  export function OverridePropControl( { overridableProp, overrides }: Props ) {
41
47
  return (
@@ -46,11 +52,13 @@ export function OverridePropControl( { overridableProp, overrides }: Props ) {
46
52
  }
47
53
 
48
54
  function OverrideControl( { overridableProp, overrides }: Props ) {
55
+ const componentInstanceElement = useElement();
49
56
  const componentId = useCurrentComponentId();
50
57
  const { value: instanceValue, setValue: setInstanceValue } = useBoundProp( componentInstancePropTypeUtil );
51
58
  const controls = useControlsByWidgetType(
52
59
  overridableProp?.originPropFields?.widgetType ?? overridableProp.widgetType
53
60
  );
61
+ const controlReplacements = getControlReplacements();
54
62
 
55
63
  const propType = getPropTypeForComponentOverride( overridableProp );
56
64
 
@@ -72,7 +80,7 @@ function OverrideControl( { overridableProp, overrides }: Props ) {
72
80
 
73
81
  const matchingOverride = getMatchingOverride( overrides, overridableProp.overrideKey );
74
82
 
75
- const propValue = matchingOverride ? getPropValue( matchingOverride ) : overridableProp.originValue;
83
+ const propValue = matchingOverride ? resolveOverridePropValue( matchingOverride ) : overridableProp.originValue;
76
84
 
77
85
  const value = {
78
86
  [ overridableProp.overrideKey ]: propValue,
@@ -81,9 +89,14 @@ function OverrideControl( { overridableProp, overrides }: Props ) {
81
89
  const setValue = ( newValue: OverridesSchema ) => {
82
90
  const newPropValue = newValue[ overridableProp.overrideKey ] as
83
91
  | ComponentInstanceOverrideProp
84
- | ComponentOverridablePropValue;
92
+ | ComponentOverridableProp;
85
93
 
86
- const newOverrideValue = createOverrideValue( overridableProp.overrideKey, newPropValue, componentInstanceId );
94
+ const newOverrideValue = createOverrideValue( {
95
+ matchingOverride,
96
+ overrideKey: overridableProp.overrideKey,
97
+ overrideValue: newPropValue,
98
+ componentId: componentInstanceId,
99
+ } );
87
100
 
88
101
  let newOverrides =
89
102
  overrides?.map( ( override ) => ( override === matchingOverride ? newOverrideValue : override ) ) ?? [];
@@ -105,49 +118,60 @@ function OverrideControl( { overridableProp, overrides }: Props ) {
105
118
  return;
106
119
  }
107
120
 
108
- const { elType, widgetType, propKey } = overridableProp;
109
- updateOverridableProp( componentId, overridableValue, { elType, widgetType, propKey } );
121
+ const { elType, widgetType, propKey, elementId } = overridableProp;
122
+ updateOverridableProp( componentId, overridableValue, { elType, widgetType, propKey, elementId } );
110
123
  }
111
124
  };
112
125
 
113
- return (
114
- <PropProvider
115
- propType={ propTypeSchema }
116
- value={ value }
117
- setValue={ setValue }
118
- isDisabled={ () => {
119
- return false;
120
- } }
121
- >
122
- <PropKeyProvider bind={ overridableProp.overrideKey }>
123
- <Stack direction="column" gap={ 1 } mb={ 1.5 }>
124
- <ControlLabel>{ overridableProp.label }</ControlLabel>
125
- { getControl( controls, overridableProp?.originPropFields ?? overridableProp ) }
126
- </Stack>
127
- </PropKeyProvider>
128
- </PropProvider>
126
+ const { control, controlProps, layout } = getControlParams(
127
+ controls,
128
+ overridableProp?.originPropFields ?? overridableProp,
129
+ overridableProp.label
129
130
  );
130
- }
131
131
 
132
- function getPropValue( value: PropValue ): TransformablePropValue< string, unknown > | null {
133
- const overridableValue = componentOverridablePropTypeUtil.extract( value );
132
+ const { elementId, widgetType, elType, propKey } = overridableProp.originPropFields ?? overridableProp;
134
133
 
135
- if ( overridableValue ) {
136
- // if overridable - return as is and let the control replacement handle the overridable value
137
- return value as TransformablePropValue< string, unknown >;
138
- }
134
+ const type = elType === 'widget' ? widgetType : elType;
135
+ const elementType = getElementType( type );
139
136
 
140
- if ( componentInstanceOverridePropTypeUtil.isValid( value ) ) {
141
- return value.value.override_value as TransformablePropValue< string, unknown >;
137
+ if ( ! elementType ) {
138
+ return null;
142
139
  }
143
140
 
144
- return null;
141
+ return (
142
+ <OverridablePropProvider
143
+ value={ componentOverridablePropTypeUtil.extract( matchingOverride ) ?? undefined }
144
+ componentInstanceElement={ componentInstanceElement }
145
+ >
146
+ <ElementProvider element={ { id: elementId, type } } elementType={ elementType }>
147
+ <SettingsField bind={ propKey } propDisplayName={ overridableProp.label }>
148
+ <PropProvider
149
+ propType={ propTypeSchema }
150
+ value={ value }
151
+ setValue={ setValue }
152
+ isDisabled={ () => {
153
+ return false;
154
+ } }
155
+ >
156
+ <PropKeyProvider bind={ overridableProp.overrideKey }>
157
+ <ControlReplacementsProvider replacements={ controlReplacements }>
158
+ <Stack direction="column" gap={ 1 } mb={ 1.5 }>
159
+ { layout !== 'custom' && <ControlLabel>{ overridableProp.label }</ControlLabel> }
160
+ <OriginalControl control={ control } controlProps={ controlProps } />
161
+ </Stack>
162
+ </ControlReplacementsProvider>
163
+ </PropKeyProvider>
164
+ </PropProvider>
165
+ </SettingsField>
166
+ </ElementProvider>
167
+ </OverridablePropProvider>
168
+ );
145
169
  }
146
170
 
147
171
  function getMatchingOverride(
148
172
  overrides: ComponentInstanceOverridesPropValue,
149
173
  overrideKey: string
150
- ): NonNullable< ComponentInstanceOverridesPropValue >[ number ] | null {
174
+ ): ComponentInstanceOverride | null {
151
175
  return (
152
176
  overrides?.find( ( override ) => {
153
177
  const overridableValue = componentOverridablePropTypeUtil.extract( override );
@@ -165,17 +189,29 @@ function getMatchingOverride(
165
189
  );
166
190
  }
167
191
 
168
- function createOverrideValue(
169
- overrideKey: string,
170
- overrideValue: ComponentInstanceOverrideProp | ComponentOverridablePropValue,
171
- componentId: number
172
- ): NonNullable< ComponentInstanceOverridesPropValue >[ number ] {
173
- const overridableValue = componentOverridablePropTypeUtil.extract( overrideValue );
174
-
175
- if ( overridableValue ) {
192
+ function createOverrideValue( {
193
+ matchingOverride,
194
+ overrideKey,
195
+ overrideValue,
196
+ componentId,
197
+ }: {
198
+ matchingOverride: ComponentInstanceOverride | null;
199
+ overrideKey: string;
200
+ overrideValue: ComponentInstanceOverrideProp | ComponentOverridableProp;
201
+ componentId: number;
202
+ } ): ComponentInstanceOverride {
203
+ // this is for an override that's already set as overridable
204
+ const overridableValue = componentOverridablePropTypeUtil.extract( matchingOverride );
205
+
206
+ // this is for changes via the overridable-prop-indicator
207
+ const newOverridableValue = componentOverridablePropTypeUtil.extract( overrideValue );
208
+
209
+ const anyOverridable = newOverridableValue ?? overridableValue;
210
+
211
+ if ( anyOverridable ) {
176
212
  const innerOverride = componentInstanceOverridePropTypeUtil.create( {
177
213
  override_key: overrideKey,
178
- override_value: overridableValue.origin_value,
214
+ override_value: resolveOverridePropValue( overrideValue ),
179
215
  schema_source: {
180
216
  type: 'component',
181
217
  id: componentId,
@@ -183,7 +219,7 @@ function createOverrideValue(
183
219
  } );
184
220
 
185
221
  return componentOverridablePropTypeUtil.create( {
186
- override_key: overridableValue.override_key,
222
+ override_key: anyOverridable.override_key,
187
223
  origin_value: innerOverride,
188
224
  } );
189
225
  }
@@ -198,10 +234,48 @@ function createOverrideValue(
198
234
  } );
199
235
  }
200
236
 
201
- function getControl( controls: Record< string, Control >, originPropFields: OriginPropFields ) {
202
- const ControlComponent = controlsRegistry.get( controls[ originPropFields.propKey ].value.type as ControlType );
237
+ function getControlParams( controls: Record< string, Control >, originPropFields: OriginPropFields, label?: string ) {
238
+ const control = controls[ originPropFields.propKey ];
239
+ const { value } = control;
240
+
241
+ const layout = getControlLayout( control );
242
+
243
+ const controlProps = populateChildControlProps( value.props );
244
+
245
+ if ( layout === 'custom' ) {
246
+ controlProps.label = label ?? value.label;
247
+ }
248
+
249
+ return {
250
+ control,
251
+ controlProps,
252
+ layout,
253
+ };
254
+ }
255
+
256
+ function OriginalControl( { control, controlProps }: { control: Control; controlProps: Record< string, unknown > } ) {
257
+ const { value } = control;
203
258
 
204
- const controlProps = controls[ originPropFields.propKey ].value.props;
259
+ return <BaseControl type={ value.type as ControlType } props={ controlProps } />;
260
+ }
261
+
262
+ function getControlLayout( control: Control ) {
263
+ return control.value.meta?.layout || controlsRegistry.getLayout( control.value.type as ControlType );
264
+ }
265
+
266
+ function populateChildControlProps( props: Record< string, unknown > ) {
267
+ if ( props.childControlType ) {
268
+ const childComponent = controlsRegistry.get( props.childControlType as ControlType );
269
+ const childPropType = controlsRegistry.getPropTypeUtil( props.childControlType as ControlType );
270
+ props = {
271
+ ...props,
272
+ childControlConfig: {
273
+ component: childComponent,
274
+ props: props.childControlProps || {},
275
+ propTypeUtil: childPropType,
276
+ },
277
+ };
278
+ }
205
279
 
206
- return <ControlComponent { ...controlProps } />;
280
+ return props;
207
281
  }
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import { type ComponentType } from 'react';
3
3
  import { ControlReplacementsProvider, PropKeyProvider, PropProvider, useBoundProp } from '@elementor/editor-controls';
4
- import { createTopLevelObjectType, useElement } from '@elementor/editor-editing-panel';
4
+ import { createTopLevelObjectType, getControlReplacements, useElement } from '@elementor/editor-editing-panel';
5
5
  import { type PropValue } from '@elementor/editor-props';
6
6
 
7
7
  import { type ComponentInstanceOverridePropValue } from '../../prop-types/component-instance-override-prop-type';
@@ -13,6 +13,7 @@ import { OverridablePropProvider } from '../../provider/overridable-prop-context
13
13
  import { updateOverridableProp } from '../../store/actions/update-overridable-prop';
14
14
  import { useCurrentComponentId, useOverridableProps } from '../../store/store';
15
15
  import { getPropTypeForComponentOverride } from '../../utils/get-prop-type-for-component-override';
16
+ import { OVERRIDABLE_PROP_REPLACEMENT_ID } from '../consts';
16
17
 
17
18
  export function OverridablePropControl< T extends object >( {
18
19
  OriginalControl,
@@ -23,6 +24,9 @@ export function OverridablePropControl< T extends object >( {
23
24
  const { value, bind, setValue, placeholder, ...propContext } = useBoundProp( componentOverridablePropTypeUtil );
24
25
  const componentId = useCurrentComponentId();
25
26
  const overridableProps = useOverridableProps( componentId );
27
+ const filteredReplacements = getControlReplacements().filter(
28
+ ( r ) => ! r.id || r.id !== OVERRIDABLE_PROP_REPLACEMENT_ID
29
+ );
26
30
 
27
31
  if ( ! componentId ) {
28
32
  return null;
@@ -33,6 +37,7 @@ export function OverridablePropControl< T extends object >( {
33
37
  }
34
38
 
35
39
  const isComponentInstance = elementType.key === 'e-component';
40
+ const overridablePropData = overridableProps?.props?.[ value.override_key ];
36
41
 
37
42
  const setOverridableValue = ( newValue: Record< typeof bind, PropValue | null > ) => {
38
43
  const propValue = {
@@ -43,19 +48,22 @@ export function OverridablePropControl< T extends object >( {
43
48
  setValue( propValue );
44
49
 
45
50
  if ( ! isComponentInstance ) {
46
- const existingProp = overridableProps?.props?.[ propValue.override_key ];
47
- updateOverridableProp( componentId, propValue, existingProp?.originPropFields );
51
+ updateOverridableProp( componentId, propValue, overridablePropData?.originPropFields );
48
52
  }
49
53
  };
50
54
 
51
55
  const defaultPropType = elementType.propsSchema[ bind ];
56
+ const overridePropType = overridablePropData ? getPropTypeForComponentOverride( overridablePropData ) : undefined;
57
+
58
+ const resolvedPropType = overridePropType ?? defaultPropType;
59
+
60
+ if ( ! resolvedPropType ) {
61
+ return null;
62
+ }
52
63
 
53
64
  const propType = createTopLevelObjectType( {
54
65
  schema: {
55
- [ bind ]:
56
- isComponentInstance && overridableProps
57
- ? getPropTypeForComponentOverride( overridableProps.props[ value.override_key ] ) ?? defaultPropType
58
- : defaultPropType,
66
+ [ bind ]: resolvedPropType,
59
67
  },
60
68
  } );
61
69
 
@@ -81,7 +89,7 @@ export function OverridablePropControl< T extends object >( {
81
89
  placeholder={ objectPlaceholder }
82
90
  >
83
91
  <PropKeyProvider bind={ bind }>
84
- <ControlReplacementsProvider replacements={ [] }>
92
+ <ControlReplacementsProvider replacements={ filteredReplacements }>
85
93
  <OriginalControl { ...( props as T ) } />
86
94
  </ControlReplacementsProvider>
87
95
  </PropKeyProvider>
@@ -7,10 +7,11 @@ import { bindPopover, bindTrigger, Popover, Tooltip, usePopupState } from '@elem
7
7
  import { __ } from '@wordpress/i18n';
8
8
 
9
9
  import { componentOverridablePropTypeUtil } from '../../prop-types/component-overridable-prop-type';
10
- import { useOverridablePropValue } from '../../provider/overridable-prop-context';
10
+ import { useComponentInstanceElement, useOverridablePropValue } from '../../provider/overridable-prop-context';
11
11
  import { setOverridableProp } from '../../store/actions/set-overridable-prop';
12
12
  import { useCurrentComponentId, useOverridableProps } from '../../store/store';
13
13
  import { type OverridableProps } from '../../types';
14
+ import { resolveOverridePropValue } from '../../utils/resolve-override-prop-value';
14
15
  import { Indicator } from './indicator';
15
16
  import { OverridablePropForm } from './overridable-prop-form';
16
17
  import { getOverridableProp } from './utils/get-overridable-prop';
@@ -41,6 +42,8 @@ export function Content( { componentId, overridableProps }: Props ) {
41
42
  const { value, bind, propType } = useBoundProp();
42
43
 
43
44
  const contextOverridableValue = useOverridablePropValue();
45
+ const componentInstanceElement = useComponentInstanceElement();
46
+
44
47
  const { value: boundPropOverridableValue, setValue: setOverridableValue } = useBoundProp(
45
48
  componentOverridablePropTypeUtil
46
49
  );
@@ -62,7 +65,8 @@ export function Content( { componentId, overridableProps }: Props ) {
62
65
 
63
66
  const handleSubmit = ( { label, group }: { label: string; group: string | null } ) => {
64
67
  const propTypeDefault = propType.default ?? {};
65
- const originValue = ( ! overridableValue ? value : overridableValue?.origin_value ) ?? propTypeDefault;
68
+
69
+ const originValue = resolveOverridePropValue( overridableValue?.origin_value ) ?? value ?? propTypeDefault;
66
70
 
67
71
  const matchingOverridableProp = overridableValue
68
72
  ? overridableProps?.props?.[ overridableValue.override_key ]
@@ -71,12 +75,12 @@ export function Content( { componentId, overridableProps }: Props ) {
71
75
  const overridablePropConfig = setOverridableProp( {
72
76
  componentId,
73
77
  overrideKey: overridableValue?.override_key ?? null,
74
- elementId,
78
+ elementId: componentInstanceElement?.element.id ?? elementId,
75
79
  label,
76
80
  groupId: group,
77
81
  propKey: bind,
78
82
  elType: elType ?? 'widget',
79
- widgetType: elementType.key,
83
+ widgetType: componentInstanceElement?.elementType.key ?? elementType.key,
80
84
  originValue,
81
85
  originPropFields: matchingOverridableProp?.originPropFields,
82
86
  } );
package/src/init.ts CHANGED
@@ -26,7 +26,7 @@ import { componentOverrideTransformer } from './component-override-transformer';
26
26
  import { ComponentPanelHeader } from './components/component-panel-header/component-panel-header';
27
27
  import { panel as componentPropertiesPanel } from './components/component-properties-panel/component-properties-panel';
28
28
  import { Components } from './components/components-tab/components';
29
- import { COMPONENT_DOCUMENT_TYPE } from './components/consts';
29
+ import { COMPONENT_DOCUMENT_TYPE, OVERRIDABLE_PROP_REPLACEMENT_ID } from './components/consts';
30
30
  import { CreateComponentForm } from './components/create-component-form/create-component-form';
31
31
  import { EditComponent } from './components/edit-component/edit-component';
32
32
  import { openEditModeDialog } from './components/in-edit-mode';
@@ -115,6 +115,7 @@ export function init() {
115
115
  } );
116
116
 
117
117
  registerControlReplacement( {
118
+ id: OVERRIDABLE_PROP_REPLACEMENT_ID,
118
119
  component: OverridablePropControl,
119
120
  condition: ( { value } ) => componentOverridablePropTypeUtil.isValid( value ),
120
121
  } );
@@ -15,3 +15,5 @@ export const componentInstanceOverridesPropTypeUtil = createPropUtils(
15
15
  export type ComponentInstanceOverridesPropValue = z.infer<
16
16
  typeof componentInstanceOverridesPropTypeUtil.schema
17
17
  >[ 'value' ];
18
+
19
+ export type ComponentInstanceOverride = NonNullable< ComponentInstanceOverridesPropValue >[ number ];
@@ -14,4 +14,6 @@ export const componentOverridablePropTypeUtil = createPropUtils(
14
14
  } )
15
15
  );
16
16
 
17
- export type ComponentOverridablePropValue = z.infer< typeof componentOverridablePropTypeUtil.schema >[ 'value' ];
17
+ export type ComponentOverridableProp = z.infer< typeof componentOverridablePropTypeUtil.schema >;
18
+
19
+ export type ComponentOverridablePropValue = ComponentOverridableProp[ 'value' ];
@@ -1,10 +1,12 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, type PropsWithChildren, useContext } from 'react';
3
+ import { type useElement } from '@elementor/editor-editing-panel';
3
4
 
4
5
  import { type ComponentOverridablePropValue } from '../prop-types/component-overridable-prop-type';
5
6
 
6
7
  type OverridablePropData = {
7
- value: ComponentOverridablePropValue;
8
+ value?: ComponentOverridablePropValue;
9
+ componentInstanceElement?: ReturnType< typeof useElement >;
8
10
  };
9
11
 
10
12
  const OverridablePropContext = createContext< OverridablePropData | null >( null );
@@ -14,3 +16,5 @@ export function OverridablePropProvider( { children, ...props }: PropsWithChildr
14
16
  }
15
17
 
16
18
  export const useOverridablePropValue = () => useContext( OverridablePropContext )?.value;
19
+
20
+ export const useComponentInstanceElement = () => useContext( OverridablePropContext )?.componentInstanceElement;
@@ -2,6 +2,7 @@ import { __dispatch as dispatch, __getState as getState } from '@elementor/store
2
2
 
3
3
  import { type ComponentOverridablePropValue } from '../../prop-types/component-overridable-prop-type';
4
4
  import { type OriginPropFields, type OverridableProps } from '../../types';
5
+ import { resolveOverridePropValue } from '../../utils/resolve-override-prop-value';
5
6
  import { selectOverridableProps, slice } from '../store';
6
7
 
7
8
  export function updateOverridableProp(
@@ -21,13 +22,15 @@ export function updateOverridableProp(
21
22
  return;
22
23
  }
23
24
 
25
+ const originValue = resolveOverridePropValue( propValue.origin_value );
26
+
24
27
  const newOverridableProp = originPropFields
25
28
  ? {
26
- originValue: propValue.origin_value,
29
+ originValue,
27
30
  originPropFields,
28
31
  }
29
32
  : {
30
- originValue: propValue.origin_value,
33
+ originValue,
31
34
  };
32
35
 
33
36
  const newOverridableProps = {
package/src/types.ts CHANGED
@@ -21,7 +21,7 @@ export type UnpublishedComponent = BaseComponent & {
21
21
  elements: V1ElementData[];
22
22
  };
23
23
 
24
- export type OriginPropFields = Pick< OverridableProp, 'propKey' | 'widgetType' | 'elType' >;
24
+ export type OriginPropFields = Pick< OverridableProp, 'propKey' | 'widgetType' | 'elType' | 'elementId' >;
25
25
 
26
26
  export type OverridableProp = {
27
27
  overrideKey: string;
@@ -7,12 +7,13 @@ export const getPropTypeForComponentOverride = ( overridableProp: OverridablePro
7
7
  return getPropType( overridableProp.originPropFields );
8
8
  }
9
9
 
10
- const { elType, widgetType, propKey } = overridableProp;
10
+ const { elType, widgetType, propKey, elementId } = overridableProp;
11
11
 
12
12
  return getPropType( {
13
13
  elType,
14
14
  widgetType,
15
15
  propKey,
16
+ elementId,
16
17
  } );
17
18
  };
18
19
 
@@ -0,0 +1,51 @@
1
+ import { type PropValue } from '@elementor/editor-props';
2
+
3
+ import {
4
+ type ComponentInstanceOverrideProp,
5
+ componentInstanceOverridePropTypeUtil,
6
+ } from '../prop-types/component-instance-override-prop-type';
7
+ import { type ComponentInstanceOverride } from '../prop-types/component-instance-overrides-prop-type';
8
+ import {
9
+ type ComponentOverridableProp,
10
+ componentOverridablePropTypeUtil,
11
+ } from '../prop-types/component-overridable-prop-type';
12
+
13
+ export const resolveOverridePropValue = ( originalPropValue: ComponentInstanceOverride | PropValue ): PropValue => {
14
+ const isOverridable = componentOverridablePropTypeUtil.isValid( originalPropValue );
15
+ if ( isOverridable ) {
16
+ return getOverridableValue( originalPropValue as ComponentOverridableProp );
17
+ }
18
+
19
+ const isOverride = componentInstanceOverridePropTypeUtil.isValid( originalPropValue );
20
+ if ( isOverride ) {
21
+ return getOverrideValue( originalPropValue );
22
+ }
23
+
24
+ return originalPropValue;
25
+ };
26
+
27
+ function getOverridableValue( overridableProp: ComponentOverridableProp | null ): PropValue {
28
+ const overridableValue = componentOverridablePropTypeUtil.extract( overridableProp );
29
+
30
+ if ( ! overridableValue ) {
31
+ return null;
32
+ }
33
+
34
+ const isOverride = componentInstanceOverridePropTypeUtil.isValid( overridableValue.origin_value );
35
+
36
+ if ( isOverride ) {
37
+ return getOverrideValue( overridableValue.origin_value as ComponentInstanceOverrideProp );
38
+ }
39
+
40
+ return overridableValue.origin_value;
41
+ }
42
+
43
+ function getOverrideValue( overrideProp: ComponentInstanceOverrideProp | null ): PropValue {
44
+ const overrideValue = componentInstanceOverridePropTypeUtil.extract( overrideProp );
45
+
46
+ if ( ! overrideValue ) {
47
+ return null;
48
+ }
49
+
50
+ return overrideValue.override_value as PropValue;
51
+ }