@elementor/editor-components 3.35.0-389 → 3.35.0-390

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.
Files changed (29) hide show
  1. package/dist/index.js +407 -173
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +381 -143
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +22 -22
  6. package/src/component-instance-transformer.ts +2 -2
  7. package/src/component-override-transformer.ts +2 -2
  8. package/src/components/component-properties-panel/component-properties-panel-content.tsx +4 -4
  9. package/src/components/control-label.tsx +15 -0
  10. package/src/components/instance-editing-panel/instance-editing-panel.tsx +27 -20
  11. package/src/components/instance-editing-panel/override-prop-control.tsx +207 -0
  12. package/src/components/instance-editing-panel/override-props-group.tsx +13 -7
  13. package/src/components/overridable-props/overridable-prop-control.tsx +23 -5
  14. package/src/components/overridable-props/overridable-prop-indicator.tsx +10 -6
  15. package/src/create-component-type.ts +4 -3
  16. package/src/hooks/regenerate-override-keys.ts +6 -4
  17. package/src/hooks/use-controls-by-widget-type.ts +40 -0
  18. package/src/prop-types/component-instance-override-prop-type.ts +0 -1
  19. package/src/prop-types/component-instance-overrides-prop-type.ts +5 -1
  20. package/src/prop-types/component-instance-prop-type.ts +2 -1
  21. package/src/store/actions/set-overridable-prop.ts +4 -1
  22. package/src/store/actions/update-overridable-prop-params.ts +58 -0
  23. package/src/store/actions/update-overridable-prop.ts +30 -38
  24. package/src/store/store.ts +8 -0
  25. package/src/sync/create-components-before-save.ts +9 -5
  26. package/src/types.ts +3 -20
  27. package/src/utils/get-component-ids.ts +11 -6
  28. package/src/utils/get-prop-type-for-component-override.ts +23 -0
  29. package/src/store/actions/update-overridable-prop-origin-value.ts +0 -37
@@ -0,0 +1,40 @@
1
+ import { type Control, type ControlItem, getElementType } from '@elementor/editor-elements';
2
+
3
+ export function useControlsByWidgetType( type: string ): Record< string, Control > {
4
+ const elementType = getElementType( type );
5
+
6
+ if ( ! elementType ) {
7
+ return {};
8
+ }
9
+
10
+ const controls = iterateControls( elementType.controls );
11
+
12
+ return getControlsByBind( controls );
13
+ }
14
+
15
+ function iterateControls( controls: ControlItem[] ): Control[] {
16
+ return controls
17
+ .map( ( control ) => {
18
+ if ( control.type === 'control' && 'bind' in control.value ) {
19
+ return control;
20
+ }
21
+
22
+ if ( control.type === 'section' ) {
23
+ return iterateControls( control.value.items );
24
+ }
25
+
26
+ return null;
27
+ } )
28
+ .filter( Boolean )
29
+ .flat() as Control[];
30
+ }
31
+
32
+ function getControlsByBind( controls: Control[] ): Record< string, Control > {
33
+ return controls.reduce(
34
+ ( controlsByBind: Record< string, Control >, control ) => ( {
35
+ ...controlsByBind,
36
+ [ control.value.bind ]: control,
37
+ } ),
38
+ {}
39
+ );
40
+ }
@@ -14,5 +14,4 @@ export const componentInstanceOverridePropTypeUtil = createPropUtils(
14
14
  );
15
15
 
16
16
  export type ComponentInstanceOverrideProp = z.infer< typeof componentInstanceOverridePropTypeUtil.schema >;
17
-
18
17
  export type ComponentInstanceOverridePropValue = ComponentInstanceOverrideProp[ 'value' ];
@@ -2,10 +2,14 @@ import { createPropUtils } from '@elementor/editor-props';
2
2
  import { z } from '@elementor/schema';
3
3
 
4
4
  import { componentInstanceOverridePropTypeUtil } from './component-instance-override-prop-type';
5
+ import { componentOverridablePropTypeUtil } from './component-overridable-prop-type';
5
6
 
6
7
  export const componentInstanceOverridesPropTypeUtil = createPropUtils(
7
8
  'overrides',
8
- z.array( componentInstanceOverridePropTypeUtil.schema ).optional().default( [] )
9
+ z
10
+ .array( z.union( [ componentInstanceOverridePropTypeUtil.schema, componentOverridablePropTypeUtil.schema ] ) )
11
+ .optional()
12
+ .default( [] )
9
13
  );
10
14
 
11
15
  export type ComponentInstanceOverridesPropValue = z.infer<
@@ -11,4 +11,5 @@ export const componentInstancePropTypeUtil = createPropUtils(
11
11
  } )
12
12
  );
13
13
 
14
- export type ComponentInstancePropValue = z.infer< typeof componentInstancePropTypeUtil.schema >[ 'value' ];
14
+ export type ComponentInstanceProp = z.infer< typeof componentInstancePropTypeUtil.schema >;
15
+ export type ComponentInstancePropValue = ComponentInstanceProp[ 'value' ];
@@ -2,7 +2,7 @@ import { type PropValue } from '@elementor/editor-props';
2
2
  import { __dispatch as dispatch, __getState as getState } from '@elementor/store';
3
3
  import { generateUniqueId } from '@elementor/utils';
4
4
 
5
- import { type OverridableProp } from '../../types';
5
+ import { type OriginPropFields, type OverridableProp } from '../../types';
6
6
  import { selectOverridableProps, slice } from '../store';
7
7
  import {
8
8
  addPropToGroup,
@@ -22,6 +22,7 @@ type Props = {
22
22
  elType: string;
23
23
  widgetType: string;
24
24
  originValue: PropValue;
25
+ originPropFields?: OriginPropFields;
25
26
  };
26
27
 
27
28
  export function setOverridableProp( {
@@ -34,6 +35,7 @@ export function setOverridableProp( {
34
35
  elType,
35
36
  widgetType,
36
37
  originValue,
38
+ originPropFields,
37
39
  }: Props ): OverridableProp | undefined {
38
40
  const overridableProps = selectOverridableProps( getState(), componentId );
39
41
 
@@ -60,6 +62,7 @@ export function setOverridableProp( {
60
62
  elType,
61
63
  originValue,
62
64
  groupId: currentGroupId,
65
+ originPropFields,
63
66
  };
64
67
 
65
68
  const stateAfterRemovingDuplicates = removePropsFromState(
@@ -0,0 +1,58 @@
1
+ import { __dispatch as dispatch, __getState as getState } from '@elementor/store';
2
+
3
+ import { type ComponentId, type OverridableProp } from '../../types';
4
+ import { selectOverridableProps, slice } from '../store';
5
+ import { movePropBetweenGroups } from '../utils/groups-transformers';
6
+
7
+ type UpdatePropParams = {
8
+ componentId: ComponentId;
9
+ overrideKey: string;
10
+ label: string;
11
+ groupId: string | null;
12
+ };
13
+
14
+ export function updateOverridablePropParams( {
15
+ componentId,
16
+ overrideKey,
17
+ label,
18
+ groupId,
19
+ }: UpdatePropParams ): OverridableProp | undefined {
20
+ const overridableProps = selectOverridableProps( getState(), componentId );
21
+
22
+ if ( ! overridableProps ) {
23
+ return;
24
+ }
25
+
26
+ const prop = overridableProps.props[ overrideKey ];
27
+
28
+ if ( ! prop ) {
29
+ return;
30
+ }
31
+
32
+ const oldGroupId = prop.groupId;
33
+ const newGroupId = groupId ?? oldGroupId;
34
+
35
+ const updatedProp: OverridableProp = {
36
+ ...prop,
37
+ label,
38
+ groupId: newGroupId,
39
+ };
40
+
41
+ const updatedGroups = movePropBetweenGroups( overridableProps.groups, overrideKey, oldGroupId, newGroupId );
42
+
43
+ dispatch(
44
+ slice.actions.setOverridableProps( {
45
+ componentId,
46
+ overridableProps: {
47
+ ...overridableProps,
48
+ props: {
49
+ ...overridableProps.props,
50
+ [ overrideKey ]: updatedProp,
51
+ },
52
+ groups: updatedGroups,
53
+ },
54
+ } )
55
+ );
56
+
57
+ return updatedProp;
58
+ }
@@ -1,58 +1,50 @@
1
1
  import { __dispatch as dispatch, __getState as getState } from '@elementor/store';
2
2
 
3
- import { type ComponentId, type OverridableProp } from '../../types';
3
+ import { type ComponentOverridablePropValue } from '../../prop-types/component-overridable-prop-type';
4
+ import { type OriginPropFields, type OverridableProps } from '../../types';
4
5
  import { selectOverridableProps, slice } from '../store';
5
- import { movePropBetweenGroups } from '../utils/groups-transformers';
6
-
7
- type UpdatePropParams = {
8
- componentId: ComponentId;
9
- propKey: string;
10
- label: string;
11
- groupId: string | null;
12
- };
13
-
14
- export function updateOverridableProp( {
15
- componentId,
16
- propKey,
17
- label,
18
- groupId,
19
- }: UpdatePropParams ): OverridableProp | undefined {
6
+
7
+ export function updateOverridableProp(
8
+ componentId: number,
9
+ propValue: ComponentOverridablePropValue,
10
+ originPropFields?: OriginPropFields
11
+ ) {
20
12
  const overridableProps = selectOverridableProps( getState(), componentId );
21
13
 
22
14
  if ( ! overridableProps ) {
23
15
  return;
24
16
  }
25
17
 
26
- const prop = overridableProps.props[ propKey ];
18
+ const existingOverridableProp = overridableProps.props[ propValue.override_key ];
27
19
 
28
- if ( ! prop ) {
20
+ if ( ! existingOverridableProp ) {
29
21
  return;
30
22
  }
31
23
 
32
- const oldGroupId = prop.groupId;
33
- const newGroupId = groupId ?? oldGroupId;
34
-
35
- const updatedProp: OverridableProp = {
36
- ...prop,
37
- label,
38
- groupId: newGroupId,
39
- };
40
-
41
- const updatedGroups = movePropBetweenGroups( overridableProps.groups, propKey, oldGroupId, newGroupId );
24
+ const newOverridableProp = originPropFields
25
+ ? {
26
+ originValue: propValue.origin_value,
27
+ originPropFields,
28
+ }
29
+ : {
30
+ originValue: propValue.origin_value,
31
+ };
32
+
33
+ const newOverridableProps = {
34
+ ...overridableProps,
35
+ props: {
36
+ ...overridableProps.props,
37
+ [ existingOverridableProp.overrideKey ]: {
38
+ ...existingOverridableProp,
39
+ ...newOverridableProp,
40
+ },
41
+ },
42
+ } satisfies OverridableProps;
42
43
 
43
44
  dispatch(
44
45
  slice.actions.setOverridableProps( {
45
46
  componentId,
46
- overridableProps: {
47
- ...overridableProps,
48
- props: {
49
- ...overridableProps.props,
50
- [ propKey ]: updatedProp,
51
- },
52
- groups: updatedGroups,
53
- },
47
+ overridableProps: newOverridableProps,
54
48
  } )
55
49
  );
56
-
57
- return updatedProp;
58
50
  }
@@ -136,6 +136,9 @@ const getPath = ( state: ComponentsSlice ) => state[ SLICE_NAME ].path;
136
136
  const getCurrentComponentId = ( state: ComponentsSlice ) => state[ SLICE_NAME ].currentComponentId;
137
137
  export const selectComponent = ( state: ComponentsSlice, componentId: ComponentId ) =>
138
138
  state[ SLICE_NAME ].data.find( ( component ) => component.id === componentId );
139
+ export const useComponent = ( componentId: ComponentId | null ) => {
140
+ return useSelector( ( state: ComponentsSlice ) => ( componentId ? selectComponent( state, componentId ) : null ) );
141
+ };
139
142
 
140
143
  export const selectComponents = createSelector(
141
144
  selectData,
@@ -180,6 +183,11 @@ export const selectOverridableProps = createSelector(
180
183
  return component.overridableProps ?? DEFAULT_OVERRIDABLE_PROPS;
181
184
  }
182
185
  );
186
+ export const useOverridableProps = ( componentId: ComponentId | null ) => {
187
+ return useSelector( ( state: ComponentsSlice ) =>
188
+ componentId ? selectOverridableProps( state, componentId ) : null
189
+ );
190
+ };
183
191
  export const selectIsOverridablePropsLoaded = createSelector(
184
192
  selectComponent,
185
193
  ( component: PublishedComponent | undefined ) => {
@@ -2,8 +2,9 @@ import { updateElementSettings, type V1ElementData } from '@elementor/editor-ele
2
2
  import { __dispatch as dispatch, __getState as getState } from '@elementor/store';
3
3
 
4
4
  import { apiClient } from '../api';
5
+ import { type ComponentInstanceProp } from '../prop-types/component-instance-prop-type';
5
6
  import { selectUnpublishedComponents, slice } from '../store/store';
6
- import { type ComponentInstancePropValue, type DocumentSaveStatus, type UnpublishedComponent } from '../types';
7
+ import { type DocumentSaveStatus, type UnpublishedComponent } from '../types';
7
8
 
8
9
  export async function createComponentsBeforeSave( {
9
10
  elements,
@@ -80,11 +81,14 @@ function shouldUpdateElement(
80
81
  uidToComponentId: Map< string, number >
81
82
  ): { shouldUpdate: true; newComponentId: number } | { shouldUpdate: false; newComponentId: null } {
82
83
  if ( element.widgetType === 'e-component' ) {
83
- const currentComponentId = ( element.settings?.component_instance as ComponentInstancePropValue< string > )
84
- ?.value?.component_id.value;
84
+ const currentComponentId = ( element.settings?.component_instance as ComponentInstanceProp )?.value
85
+ ?.component_id.value;
85
86
 
86
- if ( currentComponentId && uidToComponentId.has( currentComponentId ) ) {
87
- return { shouldUpdate: true, newComponentId: uidToComponentId.get( currentComponentId ) as number };
87
+ if ( currentComponentId && uidToComponentId.has( currentComponentId.toString() ) ) {
88
+ return {
89
+ shouldUpdate: true,
90
+ newComponentId: uidToComponentId.get( currentComponentId.toString() ) as number,
91
+ };
88
92
  }
89
93
  }
90
94
  return { shouldUpdate: false, newComponentId: null };
package/src/types.ts CHANGED
@@ -2,11 +2,6 @@ import { type V1ElementData } from '@elementor/editor-elements';
2
2
  import { type PropValue, type TransformablePropValue } from '@elementor/editor-props';
3
3
  import type { StyleDefinition } from '@elementor/editor-styles';
4
4
 
5
- import {
6
- type ComponentInstanceOverrideProp,
7
- type ComponentInstanceOverridePropValue,
8
- } from './prop-types/component-instance-override-prop-type';
9
-
10
5
  export type ComponentFormValues = {
11
6
  componentName: string;
12
7
  };
@@ -25,6 +20,8 @@ export type UnpublishedComponent = BaseComponent & {
25
20
  elements: V1ElementData[];
26
21
  };
27
22
 
23
+ export type OriginPropFields = Pick< OverridableProp, 'propKey' | 'widgetType' | 'elType' >;
24
+
28
25
  export type OverridableProp = {
29
26
  overrideKey: string;
30
27
  label: string;
@@ -34,6 +31,7 @@ export type OverridableProp = {
34
31
  widgetType: string;
35
32
  originValue: PropValue;
36
33
  groupId: string;
34
+ originPropFields?: OriginPropFields;
37
35
  };
38
36
 
39
37
  export type OverridablePropsGroup = {
@@ -71,21 +69,6 @@ export type ExtendedWindow = Window & {
71
69
  };
72
70
  };
73
71
 
74
- export type ComponentInstancePropValue< TComponentId extends number | string = number | string > =
75
- TransformablePropValue<
76
- 'component-instance',
77
- {
78
- component_id: TransformablePropValue< 'number', TComponentId >;
79
- overrides?: TransformablePropValue< 'overrides', ComponentOverrides >;
80
- }
81
- >;
82
-
83
- type ComponentOverrides = TransformablePropValue< 'overrides', ComponentOverride[] >;
84
-
85
- export type ComponentOverride = ComponentInstanceOverrideProp;
86
-
87
- export type ComponentOverridePropValue = ComponentInstanceOverridePropValue;
88
-
89
72
  export type ComponentOverridable = {
90
73
  override_key: string;
91
74
  origin_value: TransformablePropValue< string >;
@@ -1,18 +1,21 @@
1
1
  import { type V1ElementData } from '@elementor/editor-elements';
2
2
 
3
- import { type ComponentInstancePropValue } from '../types';
3
+ import { type ComponentInstanceProp } from '../prop-types/component-instance-prop-type';
4
4
  import { getComponentDocumentData } from './component-document-data';
5
5
  import { isComponentInstance } from './is-component-instance';
6
6
 
7
- export const getComponentIds = async ( elements: V1ElementData[] ) => {
7
+ export const getComponentIds = async ( elements: V1ElementData[] ): Promise< number[] > => {
8
8
  const components = elements.map( async ( { widgetType, elType, elements: childElements, settings } ) => {
9
9
  const ids: number[] = [];
10
10
 
11
11
  const isComponent = isComponentInstance( { widgetType, elType } );
12
12
 
13
13
  if ( isComponent ) {
14
- const componentId = ( settings?.component_instance as ComponentInstancePropValue< number > )?.value
15
- ?.component_id.value;
14
+ const componentId = ( settings?.component_instance as ComponentInstanceProp )?.value?.component_id.value;
15
+
16
+ if ( ! componentId ) {
17
+ return;
18
+ }
16
19
 
17
20
  const document = await getComponentDocumentData( componentId );
18
21
 
@@ -24,7 +27,9 @@ export const getComponentIds = async ( elements: V1ElementData[] ) => {
24
27
  }
25
28
 
26
29
  if ( !! childElements?.length ) {
27
- ids.push( ...( await getComponentIds( childElements ) ) );
30
+ const newIds = await getComponentIds( childElements );
31
+
32
+ ids.push( ...Array.from( new Set( newIds ) ) );
28
33
  }
29
34
 
30
35
  return ids;
@@ -32,5 +37,5 @@ export const getComponentIds = async ( elements: V1ElementData[] ) => {
32
37
 
33
38
  const result = ( await Promise.all( components ) ).flat();
34
39
 
35
- return Array.from( new Set( result ) );
40
+ return Array.from( new Set( result ) ).filter( ( value ) => value !== undefined );
36
41
  };
@@ -0,0 +1,23 @@
1
+ import { getWidgetsCache } from '@elementor/editor-elements';
2
+
3
+ import { type OriginPropFields, type OverridableProp } from '../types';
4
+
5
+ export const getPropTypeForComponentOverride = ( overridableProp: OverridableProp ) => {
6
+ if ( overridableProp.originPropFields ) {
7
+ return getPropType( overridableProp.originPropFields );
8
+ }
9
+
10
+ const { elType, widgetType, propKey } = overridableProp;
11
+
12
+ return getPropType( {
13
+ elType,
14
+ widgetType,
15
+ propKey,
16
+ } );
17
+ };
18
+
19
+ function getPropType( { widgetType, propKey }: OriginPropFields ) {
20
+ const widgetPropsSchema = getWidgetsCache()?.[ widgetType ]?.atomic_props_schema;
21
+
22
+ return widgetPropsSchema?.[ propKey ];
23
+ }
@@ -1,37 +0,0 @@
1
- import { __dispatch as dispatch, __getState as getState } from '@elementor/store';
2
-
3
- import { type ComponentOverridablePropValue } from '../../prop-types/component-overridable-prop-type';
4
- import { type OverridableProps } from '../../types';
5
- import { selectOverridableProps, slice } from '../store';
6
-
7
- export function updateOverridablePropOriginValue( componentId: number, propValue: ComponentOverridablePropValue ) {
8
- const overridableProps = selectOverridableProps( getState(), componentId );
9
-
10
- if ( ! overridableProps ) {
11
- return;
12
- }
13
-
14
- const existingOverridableProp = overridableProps.props[ propValue.override_key ];
15
-
16
- if ( ! existingOverridableProp ) {
17
- return;
18
- }
19
-
20
- const newOverridableProps = {
21
- ...overridableProps,
22
- props: {
23
- ...overridableProps.props,
24
- [ existingOverridableProp.overrideKey ]: {
25
- ...existingOverridableProp,
26
- originValue: propValue.origin_value,
27
- },
28
- },
29
- } satisfies OverridableProps;
30
-
31
- dispatch(
32
- slice.actions.setOverridableProps( {
33
- componentId,
34
- overridableProps: newOverridableProps,
35
- } )
36
- );
37
- }