@elementor/editor-components 4.0.0-manual → 4.0.1

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 (106) hide show
  1. package/dist/index.d.mts +1422 -1
  2. package/dist/index.d.ts +1422 -1
  3. package/dist/index.js +2096 -4814
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +2028 -4837
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +23 -23
  8. package/src/components/components-tab/components-list.tsx +92 -4
  9. package/src/components/components-tab/components-pro-notification.tsx +9 -15
  10. package/src/components/components-tab/components-update-notification.tsx +13 -0
  11. package/src/components/components-tab/components.tsx +52 -3
  12. package/src/components/components-tab/loading-components.tsx +26 -14
  13. package/src/components/components-update-alert.tsx +40 -0
  14. package/src/components/components-upgrade-alert.tsx +39 -0
  15. package/src/components/detach-instance-confirmation-dialog.tsx +50 -0
  16. package/src/components/instance-editing-panel/detach-action.tsx +76 -0
  17. package/src/components/instance-editing-panel/empty-state.tsx +9 -2
  18. package/src/components/instance-editing-panel/instance-editing-panel.tsx +34 -6
  19. package/src/components/instance-editing-panel/override-prop-control.tsx +14 -6
  20. package/src/components/instance-editing-panel/use-instance-panel-data.ts +2 -2
  21. package/src/components/instance-editing-panel/utils/correct-exposed-empty-override.ts +28 -0
  22. package/src/consts.ts +1 -0
  23. package/src/create-component-type.ts +130 -29
  24. package/src/index.ts +92 -0
  25. package/src/init.ts +6 -4
  26. package/src/store/actions/update-overridable-prop.ts +4 -10
  27. package/src/store/dispatchers.ts +63 -0
  28. package/src/store/extensible-slice.ts +168 -0
  29. package/src/store/selectors.ts +53 -0
  30. package/src/store/store-types.ts +48 -0
  31. package/src/store/store.ts +7 -169
  32. package/src/sync/publish-draft-components-in-page-before-save.ts +42 -1
  33. package/src/types.ts +1 -1
  34. package/src/utils/detach-component-instance/detach-component-instance.ts +172 -0
  35. package/src/utils/detach-component-instance/index.ts +1 -0
  36. package/src/utils/detach-component-instance/regenerate-local-style-ids.ts +53 -0
  37. package/src/utils/detach-component-instance/resolve-detached-instance.ts +94 -0
  38. package/src/utils/detach-component-instance/resolve-overridable-settings.ts +121 -0
  39. package/src/utils/is-component-instance.ts +1 -1
  40. package/src/utils/is-pro-components-supported.ts +11 -0
  41. package/src/utils/tracking.ts +2 -1
  42. package/src/extended/components/component-introduction.tsx +0 -77
  43. package/src/extended/components/component-panel-header/component-badge.tsx +0 -73
  44. package/src/extended/components/component-panel-header/component-panel-header.tsx +0 -98
  45. package/src/extended/components/component-properties-panel/component-properties-panel-content.tsx +0 -176
  46. package/src/extended/components/component-properties-panel/component-properties-panel.tsx +0 -43
  47. package/src/extended/components/component-properties-panel/properties-empty-state.tsx +0 -51
  48. package/src/extended/components/component-properties-panel/properties-group.tsx +0 -196
  49. package/src/extended/components/component-properties-panel/property-item.tsx +0 -124
  50. package/src/extended/components/component-properties-panel/sortable.tsx +0 -92
  51. package/src/extended/components/component-properties-panel/use-current-editable-item.ts +0 -73
  52. package/src/extended/components/component-properties-panel/utils/generate-unique-label.ts +0 -21
  53. package/src/extended/components/component-properties-panel/utils/validate-group-label.ts +0 -24
  54. package/src/extended/components/components-tab/component-item.tsx +0 -180
  55. package/src/extended/components/components-tab/components.tsx +0 -58
  56. package/src/extended/components/components-tab/delete-confirmation-dialog.tsx +0 -26
  57. package/src/extended/components/create-component-form/create-component-form.tsx +0 -282
  58. package/src/extended/components/create-component-form/hooks/use-form.ts +0 -72
  59. package/src/extended/components/create-component-form/utils/get-component-event-data.ts +0 -54
  60. package/src/extended/components/edit-component/component-modal.tsx +0 -133
  61. package/src/extended/components/edit-component/edit-component.tsx +0 -166
  62. package/src/extended/components/edit-component/use-canvas-document.ts +0 -9
  63. package/src/extended/components/edit-component/use-element-rect.ts +0 -81
  64. package/src/extended/components/instance-editing-panel/instance-editing-panel.tsx +0 -60
  65. package/src/extended/components/overridable-props/indicator.tsx +0 -83
  66. package/src/extended/components/overridable-props/overridable-prop-control.tsx +0 -127
  67. package/src/extended/components/overridable-props/overridable-prop-form.tsx +0 -135
  68. package/src/extended/components/overridable-props/overridable-prop-indicator.tsx +0 -138
  69. package/src/extended/components/overridable-props/utils/validate-prop-label.ts +0 -38
  70. package/src/extended/consts.ts +0 -3
  71. package/src/extended/hooks/use-navigate-back.ts +0 -24
  72. package/src/extended/init.ts +0 -104
  73. package/src/extended/mcp/index.ts +0 -14
  74. package/src/extended/mcp/save-as-component-tool.ts +0 -436
  75. package/src/extended/store/actions/add-overridable-group.ts +0 -59
  76. package/src/extended/store/actions/archive-component.ts +0 -19
  77. package/src/extended/store/actions/create-unpublished-component.ts +0 -102
  78. package/src/extended/store/actions/delete-overridable-group.ts +0 -38
  79. package/src/extended/store/actions/delete-overridable-prop.ts +0 -70
  80. package/src/extended/store/actions/rename-component.ts +0 -49
  81. package/src/extended/store/actions/rename-overridable-group.ts +0 -39
  82. package/src/extended/store/actions/reorder-group-props.ts +0 -43
  83. package/src/extended/store/actions/reorder-overridable-groups.ts +0 -30
  84. package/src/extended/store/actions/reset-sanitized-components.ts +0 -7
  85. package/src/extended/store/actions/set-overridable-prop.ts +0 -117
  86. package/src/extended/store/actions/update-component-sanitized-attribute.ts +0 -8
  87. package/src/extended/store/actions/update-current-component.ts +0 -21
  88. package/src/extended/store/actions/update-overridable-prop-params.ts +0 -58
  89. package/src/extended/store/utils/groups-transformers.ts +0 -187
  90. package/src/extended/sync/before-save.ts +0 -52
  91. package/src/extended/sync/cleanup-overridable-props-on-delete.ts +0 -85
  92. package/src/extended/sync/create-components-before-save.ts +0 -113
  93. package/src/extended/sync/handle-component-edit-mode-container.ts +0 -114
  94. package/src/extended/sync/prevent-non-atomic-nesting.ts +0 -198
  95. package/src/extended/sync/revert-overridables-on-copy-or-duplicate.ts +0 -66
  96. package/src/extended/sync/sanitize-overridable-props.ts +0 -32
  97. package/src/extended/sync/set-component-overridable-props-settings-before-save.ts +0 -23
  98. package/src/extended/sync/update-archived-component-before-save.ts +0 -32
  99. package/src/extended/sync/update-component-title-before-save.ts +0 -19
  100. package/src/extended/utils/component-form-schema.ts +0 -32
  101. package/src/extended/utils/component-name-validation.ts +0 -27
  102. package/src/extended/utils/create-component-model.ts +0 -28
  103. package/src/extended/utils/get-container-for-new-element.ts +0 -49
  104. package/src/extended/utils/is-editing-component.ts +0 -13
  105. package/src/extended/utils/replace-element-with-component.ts +0 -11
  106. package/src/extended/utils/revert-overridable-settings.ts +0 -207
@@ -10,6 +10,7 @@ import {
10
10
  BaseControl,
11
11
  controlsRegistry,
12
12
  type ControlType,
13
+ ControlTypeContainer,
13
14
  createTopLevelObjectType,
14
15
  ElementProvider,
15
16
  isDynamicPropValue,
@@ -18,7 +19,7 @@ import {
18
19
  } from '@elementor/editor-editing-panel';
19
20
  import { type Control, getElementSettings, getElementType } from '@elementor/editor-elements';
20
21
  import { type AnyTransformable, type PropType, type PropValue } from '@elementor/editor-props';
21
- import { Stack } from '@elementor/ui';
22
+ import { Box } from '@elementor/ui';
22
23
 
23
24
  import { useControlsByWidgetType } from '../../hooks/use-controls-by-widget-type';
24
25
  import {
@@ -50,6 +51,7 @@ import { resolveOverridePropValue } from '../../utils/resolve-override-prop-valu
50
51
  import { ControlLabel } from '../control-label';
51
52
  import { OverrideControlInnerElementNotFoundError } from '../errors';
52
53
  import { useResolvedOriginValue } from './use-resolved-origin-value';
54
+ import { correctExposedEmptyOverride } from './utils/correct-exposed-empty-override';
53
55
 
54
56
  type Props = {
55
57
  overrideKey: string;
@@ -123,12 +125,14 @@ function OverrideControl( { overridableProp }: InternalProps ) {
123
125
  return;
124
126
  }
125
127
 
126
- const newPropValue = getTempNewValueForDynamicProp(
128
+ let newPropValue = getTempNewValueForDynamicProp(
127
129
  propType,
128
130
  propValue,
129
131
  newValue[ overridableProp.overrideKey ]
130
132
  );
131
133
 
134
+ newPropValue = correctExposedEmptyOverride( newPropValue, matchingOverride );
135
+
132
136
  const newOverrideValue = createOverrideValue( {
133
137
  matchingOverride,
134
138
  overrideKey: overridableProp.overrideKey,
@@ -214,10 +218,14 @@ function OverrideControl( { overridableProp }: InternalProps ) {
214
218
  >
215
219
  <PropKeyProvider bind={ overridableProp.overrideKey }>
216
220
  <ControlReplacementsProvider replacements={ controlReplacements }>
217
- <Stack direction="column" gap={ 1 } mb={ 1.5 }>
218
- { layout !== 'custom' && <ControlLabel>{ overridableProp.label }</ControlLabel> }
219
- <OriginalControl control={ control } controlProps={ controlProps } />
220
- </Stack>
221
+ <Box mb={ 1.5 }>
222
+ <ControlTypeContainer layout={ layout }>
223
+ { layout !== 'custom' && (
224
+ <ControlLabel>{ overridableProp.label }</ControlLabel>
225
+ ) }
226
+ <OriginalControl control={ control } controlProps={ controlProps } />
227
+ </ControlTypeContainer>
228
+ </Box>
221
229
  </ControlReplacementsProvider>
222
230
  </PropKeyProvider>
223
231
  </PropProvider>
@@ -13,7 +13,7 @@ type InstancePanelData = {
13
13
  overridableProps: NonNullable< ReturnType< typeof useSanitizeOverridableProps > >;
14
14
  groups: OverridablePropsGroup[];
15
15
  isEmpty: boolean;
16
- componentInstanceId: string | undefined;
16
+ componentInstanceId: string;
17
17
  };
18
18
 
19
19
  export function useInstancePanelData(): InstancePanelData | null {
@@ -29,7 +29,7 @@ export function useInstancePanelData(): InstancePanelData | null {
29
29
 
30
30
  const overridableProps = useSanitizeOverridableProps( componentId ?? null, componentInstanceId );
31
31
 
32
- if ( ! componentId || ! overridableProps || ! component ) {
32
+ if ( ! componentId || ! overridableProps || ! component || ! componentInstanceId ) {
33
33
  return null;
34
34
  }
35
35
 
@@ -0,0 +1,28 @@
1
+ import { type ComponentInstanceOverrideProp } from '../../../prop-types/component-instance-override-prop-type';
2
+ import { type ComponentInstanceOverride } from '../../../prop-types/component-instance-overrides-prop-type';
3
+ import {
4
+ type ComponentOverridableProp,
5
+ componentOverridablePropTypeUtil,
6
+ } from '../../../prop-types/component-overridable-prop-type';
7
+
8
+ type OverrideValue = ComponentInstanceOverrideProp | ComponentOverridableProp;
9
+
10
+ // The control receives the resolved value, so when exposing a prop that was never overridden,
11
+ // origin_value will be the resolved value instead of null.
12
+ // So here, we correct this by resetting origin_value to null.
13
+ export function correctExposedEmptyOverride(
14
+ newPropValue: OverrideValue,
15
+ matchingOverride: ComponentInstanceOverride | null
16
+ ): OverrideValue {
17
+ const newOverridableValue = componentOverridablePropTypeUtil.extract( newPropValue );
18
+ const isExposingEmptyOverride = newOverridableValue && matchingOverride === null;
19
+
20
+ if ( ! isExposingEmptyOverride ) {
21
+ return newPropValue;
22
+ }
23
+
24
+ return componentOverridablePropTypeUtil.create( {
25
+ override_key: newOverridableValue.override_key,
26
+ origin_value: null,
27
+ } );
28
+ }
package/src/consts.ts ADDED
@@ -0,0 +1 @@
1
+ export const COMPONENT_WIDGET_TYPE = 'e-component';
@@ -2,6 +2,7 @@ import {
2
2
  type BackboneModel,
3
3
  type BackboneModelConstructor,
4
4
  type ContextMenuAction,
5
+ type ContextMenuEventData,
5
6
  type CreateTemplatedElementTypeOptions,
6
7
  createTemplatedElementView,
7
8
  type ElementModel,
@@ -13,6 +14,7 @@ import {
13
14
  } from '@elementor/editor-canvas';
14
15
  import { getCurrentDocument } from '@elementor/editor-documents';
15
16
  import { type V1ElementData } from '@elementor/editor-elements';
17
+ import { notify } from '@elementor/editor-notifications';
16
18
  import { __getState as getState } from '@elementor/store';
17
19
  import { hasProInstalled } from '@elementor/utils';
18
20
  import { __ } from '@wordpress/i18n';
@@ -21,15 +23,15 @@ import { apiClient } from './api';
21
23
  import { type ComponentInstanceProp } from './prop-types/component-instance-prop-type';
22
24
  import { type ComponentsSlice, selectComponentByUid } from './store/store';
23
25
  import { type ComponentRenderContext, type ExtendedWindow } from './types';
26
+ import { detachComponentInstance } from './utils/detach-component-instance';
24
27
  import { formatComponentElementsId } from './utils/format-component-elements-id';
28
+ import { isProComponentsSupported, isProOutdatedForComponents } from './utils/is-pro-components-supported';
25
29
  import { switchToComponent } from './utils/switch-to-component';
26
30
  import { trackComponentEvent } from './utils/tracking';
27
31
 
28
- type ContextMenuEventData = { location: string; secondaryLocation: string; trigger: string };
29
-
30
32
  type ContextMenuGroupConfig = {
31
33
  disable: Record< string, string[] >;
32
- add: Record< string, { index: number; action: ContextMenuAction } >;
34
+ add: Record< string, { index: number; actions: ContextMenuAction[] } >;
33
35
  };
34
36
 
35
37
  type ContextMenuGroup = {
@@ -52,7 +54,54 @@ type ComponentModelInstance = BackboneModel< ComponentModel > & {
52
54
 
53
55
  export const COMPONENT_WIDGET_TYPE = 'e-component';
54
56
 
55
- const EDIT_COMPONENT_UPGRADE_URL = 'https://go.elementor.com/go-pro-components-edit/';
57
+ const EDIT_COMPONENT_DB_CLICK_UPGRADE_URL =
58
+ 'https://go.elementor.com/go-pro-components-Instance-edit-canvas-double-click/';
59
+ const EDIT_COMPONENT_CONTEXT_MENU_UPGRADE_URL =
60
+ 'https://go.elementor.com/go-pro-components-Instance-edit-context-menu/';
61
+
62
+ const UPDATE_PLUGINS_URL = '/wp-admin/plugins.php';
63
+
64
+ const COMPONENT_EDIT_UPGRADE_NOTIFICATION_ID = 'component-edit-upgrade';
65
+ const COMPONENT_EDIT_UPDATE_NOTIFICATION_ID = 'component-edit-update';
66
+
67
+ const COMPONENT_EDIT_UPGRADE_AUTO_HIDE_DURATION = 2000;
68
+
69
+ function notifyComponentEditUpgrade() {
70
+ notify( {
71
+ type: 'promotion',
72
+ id: COMPONENT_EDIT_UPGRADE_NOTIFICATION_ID,
73
+ message: __( 'Editing components requires an active Pro subscription.', 'elementor' ),
74
+ autoHideDuration: COMPONENT_EDIT_UPGRADE_AUTO_HIDE_DURATION,
75
+ additionalActionProps: [
76
+ {
77
+ size: 'small',
78
+ variant: 'contained',
79
+ color: 'promotion',
80
+ href: EDIT_COMPONENT_DB_CLICK_UPGRADE_URL,
81
+ target: '_blank',
82
+ children: __( 'Upgrade Now', 'elementor' ),
83
+ },
84
+ ],
85
+ } );
86
+ }
87
+
88
+ function notifyComponentEditUpdate() {
89
+ notify( {
90
+ type: 'info',
91
+ id: COMPONENT_EDIT_UPDATE_NOTIFICATION_ID,
92
+ message: __( 'To edit components, update Elementor Pro to the latest version.', 'elementor' ),
93
+ additionalActionProps: [
94
+ {
95
+ size: 'small',
96
+ variant: 'contained',
97
+ color: 'info',
98
+ href: UPDATE_PLUGINS_URL,
99
+ target: '_blank',
100
+ children: __( 'Update Now', 'elementor' ),
101
+ },
102
+ ],
103
+ } );
104
+ }
56
105
 
57
106
  const updateGroups = ( groups: ContextMenuGroup[], config: ContextMenuGroupConfig ): ContextMenuGroup[] => {
58
107
  const disableMap = new Map( Object.entries( config.disable ?? {} ) );
@@ -67,18 +116,21 @@ const updateGroups = ( groups: ContextMenuGroup[], config: ContextMenuGroupConfi
67
116
  disabledActions.includes( action.name ) ? { ...action, isEnabled: () => false } : action
68
117
  );
69
118
 
70
- // Insert additional action if needed
119
+ // Insert additional actions if needed
71
120
  if ( addConfig ) {
72
- updatedActions.splice( addConfig.index, 0, addConfig.action );
121
+ updatedActions.splice( addConfig.index, 0, ...addConfig.actions );
73
122
  }
74
123
 
75
124
  return { ...group, actions: updatedActions };
76
125
  } );
77
126
  };
78
127
 
79
- export function createComponentType(
80
- options: CreateTemplatedElementTypeOptions & { showLockedByModal?: ( lockedBy: string ) => void }
81
- ): typeof ElementType {
128
+ type ComponentTypeOptions = CreateTemplatedElementTypeOptions & {
129
+ showLockedByModal?: ( lockedBy: string ) => void;
130
+ showDetachConfirmDialog?: ( onConfirm: () => void ) => void;
131
+ };
132
+
133
+ export function createComponentType( options: ComponentTypeOptions ): typeof ElementType {
82
134
  const legacyWindow = window as unknown as LegacyWindow;
83
135
  const WidgetType = legacyWindow.elementor.modules.elements.types.Widget;
84
136
 
@@ -99,11 +151,7 @@ export function createComponentType(
99
151
  };
100
152
  }
101
153
 
102
- function createComponentView(
103
- options: CreateTemplatedElementTypeOptions & {
104
- showLockedByModal?: ( lockedBy: string ) => void;
105
- }
106
- ): typeof ElementView {
154
+ function createComponentView( options: ComponentTypeOptions ): typeof ElementView {
107
155
  const legacyWindow = window as unknown as LegacyWindow & ExtendedWindow;
108
156
 
109
157
  return class extends createTemplatedElementView( options ) {
@@ -215,22 +263,35 @@ function createComponentView(
215
263
  _getContextMenuConfig() {
216
264
  const isAdministrator = isUserAdministrator();
217
265
  const hasPro = hasProInstalled();
266
+ const isOutdated = isProOutdatedForComponents();
267
+ const showPromoBadge = ! hasPro && ! isOutdated;
268
+
269
+ const badgeClass = 'elementor-context-menu-list__item__shortcut__promotion-badge';
270
+ const proBadge = `<a href="${ EDIT_COMPONENT_CONTEXT_MENU_UPGRADE_URL }" target="_blank" onclick="event.stopPropagation()" class="${ badgeClass }"><i class="eicon-upgrade-crown"></i></a>`;
271
+
272
+ const editComponentAction: ContextMenuAction = {
273
+ name: 'edit component',
274
+ icon: 'eicon-edit',
275
+ title: () => __( 'Edit Component', 'elementor' ),
276
+ ...( showPromoBadge && { shortcut: proBadge, hasShortcutAction: true } ),
277
+ isEnabled: () => isProComponentsSupported() || isOutdated,
278
+ callback: ( _: unknown, eventData: ContextMenuEventData ) => this.editComponent( eventData ),
279
+ };
280
+
281
+ const detachInstanceAction: ContextMenuAction = {
282
+ name: 'detach instance',
283
+ icon: 'eicon-chain-broken',
284
+ title: () => __( 'Detach from Component', 'elementor' ),
285
+ isEnabled: () => true,
286
+ callback: ( _: unknown, eventData: ContextMenuEventData ) => this.detachInstance( eventData ),
287
+ };
218
288
 
219
- const proLabel = __( 'PRO', 'elementor' );
220
- const badgeClass = 'elementor-context-menu-list__item__shortcut__new-badge';
221
- const proBadge = `<a href="${ EDIT_COMPONENT_UPGRADE_URL }" target="_blank" onclick="event.stopPropagation()" class="${ badgeClass }">${ proLabel }</a>`;
289
+ const actions = isAdministrator ? [ editComponentAction, detachInstanceAction ] : [ detachInstanceAction ];
222
290
 
223
291
  const addedGroup = {
224
292
  general: {
225
293
  index: 1,
226
- action: {
227
- name: 'edit component',
228
- icon: 'eicon-edit',
229
- title: () => __( 'Edit Component', 'elementor' ),
230
- ...( ! hasPro && { shortcut: proBadge, hasShortcutAction: true } ),
231
- isEnabled: () => hasPro,
232
- callback: ( _: unknown, eventData: ContextMenuEventData ) => this.editComponent( eventData ),
233
- },
294
+ actions,
234
295
  },
235
296
  };
236
297
 
@@ -238,7 +299,7 @@ function createComponentView(
238
299
  clipboard: [ 'pasteStyle', 'resetStyle' ],
239
300
  };
240
301
 
241
- return { add: isAdministrator ? addedGroup : {}, disable: disabledGroup };
302
+ return { add: addedGroup, disable: disabledGroup };
242
303
  }
243
304
 
244
305
  async switchDocument() {
@@ -255,9 +316,12 @@ function createComponentView(
255
316
  }
256
317
 
257
318
  editComponent( { trigger, location, secondaryLocation }: ContextMenuEventData ) {
258
- const hasPro = hasProInstalled();
319
+ if ( isProOutdatedForComponents() ) {
320
+ notifyComponentEditUpdate();
321
+ return;
322
+ }
259
323
 
260
- if ( ! hasPro || this.isComponentCurrentlyEdited() ) {
324
+ if ( ! isProComponentsSupported() || this.isComponentCurrentlyEdited() ) {
261
325
  return;
262
326
  }
263
327
 
@@ -276,10 +340,47 @@ function createComponentView(
276
340
  } );
277
341
  }
278
342
 
343
+ detachInstance( { trigger, location, secondaryLocation }: ContextMenuEventData ) {
344
+ const componentId = this.getComponentId();
345
+ const instanceId = this.model.get( 'id' );
346
+
347
+ if ( ! componentId || ! instanceId ) {
348
+ return;
349
+ }
350
+
351
+ const handleConfirm = async () => {
352
+ try {
353
+ await detachComponentInstance( {
354
+ instanceId,
355
+ componentId,
356
+ trackingInfo: { location, secondaryLocation, trigger },
357
+ } );
358
+ } catch {
359
+ notify( {
360
+ type: 'error',
361
+ message: __( 'Failed to detach component instance.', 'elementor' ),
362
+ id: 'detach-component-instance-failed',
363
+ } );
364
+ }
365
+ };
366
+
367
+ options.showDetachConfirmDialog?.( handleConfirm );
368
+ }
369
+
279
370
  handleDblClick( e: MouseEvent ) {
280
371
  e.stopPropagation();
281
372
 
282
- if ( ! isUserAdministrator() || ! hasProInstalled() ) {
373
+ if ( ! isUserAdministrator() ) {
374
+ return;
375
+ }
376
+
377
+ if ( isProOutdatedForComponents() ) {
378
+ notifyComponentEditUpdate();
379
+ return;
380
+ }
381
+
382
+ if ( ! hasProInstalled() ) {
383
+ notifyComponentEditUpgrade();
283
384
  return;
284
385
  }
285
386
 
package/src/index.ts CHANGED
@@ -1 +1,93 @@
1
1
  export { init } from './init';
2
+
3
+ export { apiClient } from './api';
4
+
5
+ export { ComponentSearch } from './components/components-tab/component-search';
6
+ export { ComponentItem, ComponentName } from './components/components-tab/components-item';
7
+ export type { ComponentItemProps } from './components/components-tab/components-item';
8
+ export { ComponentsList, EmptySearchResult, useFilteredComponents } from './components/components-tab/components-list';
9
+ export { LoadingComponents } from './components/components-tab/loading-components';
10
+ export { SearchProvider } from './components/components-tab/search-provider';
11
+ export { EmptyState as InstanceEmptyState } from './components/instance-editing-panel/empty-state';
12
+ export { InstancePanelBody } from './components/instance-editing-panel/instance-panel-body';
13
+ export { EditComponentAction, InstancePanelHeader } from './components/instance-editing-panel/instance-panel-header';
14
+ export { useInstancePanelData } from './components/instance-editing-panel/use-instance-panel-data';
15
+ export { DetachAction } from './components/instance-editing-panel/detach-action';
16
+
17
+ export { COMPONENT_WIDGET_TYPE } from './create-component-type';
18
+
19
+ export { useComponents } from './hooks/use-components';
20
+ export { useComponentsPermissions } from './hooks/use-components-permissions';
21
+ export { useSanitizeOverridableProps } from './hooks/use-sanitize-overridable-props';
22
+
23
+ export { componentInstanceOverridePropTypeUtil } from './prop-types/component-instance-override-prop-type';
24
+ export type {
25
+ ComponentInstanceOverrideProp,
26
+ ComponentInstanceOverridePropValue,
27
+ } from './prop-types/component-instance-override-prop-type';
28
+ export { componentInstanceOverridesPropTypeUtil } from './prop-types/component-instance-overrides-prop-type';
29
+ export type {
30
+ ComponentInstanceOverride,
31
+ ComponentInstanceOverridesPropValue,
32
+ } from './prop-types/component-instance-overrides-prop-type';
33
+ export { componentInstancePropTypeUtil } from './prop-types/component-instance-prop-type';
34
+ export type { ComponentInstanceProp, ComponentInstancePropValue } from './prop-types/component-instance-prop-type';
35
+ export { componentOverridablePropTypeUtil } from './prop-types/component-overridable-prop-type';
36
+ export type {
37
+ ComponentOverridableProp,
38
+ ComponentOverridablePropValue,
39
+ } from './prop-types/component-overridable-prop-type';
40
+
41
+ export { ComponentInstanceProvider } from './provider/component-instance-context';
42
+ export {
43
+ OverridablePropProvider,
44
+ useComponentInstanceElement,
45
+ useOverridablePropValue,
46
+ } from './provider/overridable-prop-context';
47
+
48
+ export { loadComponentsAssets } from './store/actions/load-components-assets';
49
+ export { updateOverridableProp } from './store/actions/update-overridable-prop';
50
+ export { componentsActions } from './store/dispatchers';
51
+ export { componentsSelectors } from './store/selectors';
52
+ export {
53
+ SLICE_NAME,
54
+ createComponentsAction,
55
+ registerComponentsReducer,
56
+ selectOverridableProps,
57
+ selectPath,
58
+ slice,
59
+ useCurrentComponent,
60
+ useCurrentComponentId,
61
+ useIsSanitizedComponent,
62
+ useOverridableProps,
63
+ } from './store/store';
64
+ export type { ComponentsPathItem, ComponentsSlice, ComponentsState, SanitizeAttributes } from './store/store';
65
+
66
+ export { publishDraftComponentsInPageBeforeSave } from './sync/publish-draft-components-in-page-before-save';
67
+
68
+ export type {
69
+ Component,
70
+ ComponentFormValues,
71
+ ComponentId,
72
+ DocumentSaveStatus,
73
+ ExtendedWindow,
74
+ OriginalElementData,
75
+ OriginPropFields,
76
+ OverridableProp,
77
+ OverridableProps,
78
+ OverridablePropsGroup,
79
+ PublishedComponent,
80
+ StylesDefinition,
81
+ UnpublishedComponent,
82
+ UpdatedComponentName,
83
+ } from './types';
84
+
85
+ export { filterValidOverridableProps } from './utils/filter-valid-overridable-props';
86
+ export { getContainerByOriginId } from './utils/get-container-by-origin-id';
87
+ export { getOverridableProp } from './utils/get-overridable-prop';
88
+ export { getPropTypeForComponentOverride } from './utils/get-prop-type-for-component-override';
89
+ export { isComponentInstance } from './utils/is-component-instance';
90
+ export { resolveOverridePropValue } from './utils/resolve-override-prop-value';
91
+ export { switchToComponent } from './utils/switch-to-component';
92
+ export { onElementDrop, trackComponentEvent } from './utils/tracking';
93
+ export type { Source } from './utils/tracking';
package/src/init.ts CHANGED
@@ -17,11 +17,11 @@ import { componentInstanceTransformer } from './component-instance-transformer';
17
17
  import { componentOverridableTransformer } from './component-overridable-transformer';
18
18
  import { componentOverrideTransformer } from './component-override-transformer';
19
19
  import { Components } from './components/components-tab/components';
20
+ import { openDetachConfirmDialog } from './components/detach-instance-confirmation-dialog';
20
21
  import { openEditModeDialog } from './components/in-edit-mode';
21
22
  import { InstanceEditingPanel } from './components/instance-editing-panel/instance-editing-panel';
22
23
  import { LoadTemplateComponents } from './components/load-template-components';
23
24
  import { COMPONENT_WIDGET_TYPE, createComponentType } from './create-component-type';
24
- import { initExtended } from './extended/init';
25
25
  import { PopulateStore } from './populate-store';
26
26
  import { initCircularNestingPrevention } from './prevent-circular-nesting';
27
27
  import { loadComponentsAssets } from './store/actions/load-components-assets';
@@ -38,7 +38,11 @@ export function init() {
38
38
  registerSlice( slice );
39
39
 
40
40
  registerElementType( COMPONENT_WIDGET_TYPE, ( options: CreateTemplatedElementTypeOptions ) =>
41
- createComponentType( { ...options, showLockedByModal: openEditModeDialog } )
41
+ createComponentType( {
42
+ ...options,
43
+ showLockedByModal: openEditModeDialog,
44
+ showDetachConfirmDialog: openDetachConfirmDialog,
45
+ } )
42
46
  );
43
47
 
44
48
  ( window as unknown as ExtendedWindow ).elementorCommon.__beforeSave = beforeSave;
@@ -83,6 +87,4 @@ export function init() {
83
87
  initCircularNestingPrevention();
84
88
 
85
89
  initLoadComponentDataAfterInstanceAdded();
86
-
87
- initExtended();
88
90
  }
@@ -1,16 +1,15 @@
1
- import { __dispatch as dispatch, __getState as getState } from '@elementor/store';
2
-
3
1
  import { type ComponentOverridablePropValue } from '../../prop-types/component-overridable-prop-type';
4
2
  import { type OriginPropFields, type OverridableProps } from '../../types';
5
3
  import { resolveOverridePropValue } from '../../utils/resolve-override-prop-value';
6
- import { selectOverridableProps, slice } from '../store';
4
+ import { componentsActions } from '../dispatchers';
5
+ import { componentsSelectors } from '../selectors';
7
6
 
8
7
  export function updateOverridableProp(
9
8
  componentId: number,
10
9
  propValue: ComponentOverridablePropValue,
11
10
  originPropFields?: OriginPropFields
12
11
  ) {
13
- const overridableProps = selectOverridableProps( getState(), componentId );
12
+ const overridableProps = componentsSelectors.getOverridableProps( componentId );
14
13
 
15
14
  if ( ! overridableProps ) {
16
15
  return;
@@ -44,10 +43,5 @@ export function updateOverridableProp(
44
43
  },
45
44
  } satisfies OverridableProps;
46
45
 
47
- dispatch(
48
- slice.actions.setOverridableProps( {
49
- componentId,
50
- overridableProps: newOverridableProps,
51
- } )
52
- );
46
+ componentsActions.setOverridableProps( componentId, newOverridableProps );
53
47
  }
@@ -0,0 +1,63 @@
1
+ import { type V1Document } from '@elementor/editor-documents';
2
+ import { __dispatch as dispatch, __getStore as getStore } from '@elementor/store';
3
+
4
+ import { type ComponentId, type OverridableProps, type PublishedComponent, type UnpublishedComponent } from '../types';
5
+ import { type ComponentsPathItem, type SanitizeAttributes, slice } from './store';
6
+
7
+ function safeDispatch() {
8
+ return getStore()?.dispatch;
9
+ }
10
+
11
+ export const componentsActions = {
12
+ add( components: PublishedComponent | PublishedComponent[] ) {
13
+ dispatch( slice.actions.add( components ) );
14
+ },
15
+ load( components: PublishedComponent[] ) {
16
+ dispatch( slice.actions.load( components ) );
17
+ },
18
+ addUnpublished( component: UnpublishedComponent ) {
19
+ dispatch( slice.actions.addUnpublished( component ) );
20
+ },
21
+ removeUnpublished( uids: string | string[] ) {
22
+ dispatch( slice.actions.removeUnpublished( uids ) );
23
+ },
24
+ resetUnpublished() {
25
+ dispatch( slice.actions.resetUnpublished() );
26
+ },
27
+ removeStyles( id: ComponentId ) {
28
+ dispatch( slice.actions.removeStyles( { id } ) );
29
+ },
30
+ addStyles( styles: Record< string, unknown > ) {
31
+ dispatch( slice.actions.addStyles( styles ) );
32
+ },
33
+ addCreatedThisSession( uid: string ) {
34
+ dispatch( slice.actions.addCreatedThisSession( uid ) );
35
+ },
36
+ removeCreatedThisSession( uid: string ) {
37
+ dispatch( slice.actions.removeCreatedThisSession( uid ) );
38
+ },
39
+ archive( componentId: ComponentId ) {
40
+ dispatch( slice.actions.archive( componentId ) );
41
+ },
42
+ setCurrentComponentId( id: V1Document[ 'id' ] | null ) {
43
+ safeDispatch()?.( slice.actions.setCurrentComponentId( id ) );
44
+ },
45
+ setPath( path: ComponentsPathItem[] ) {
46
+ safeDispatch()?.( slice.actions.setPath( path ) );
47
+ },
48
+ setOverridableProps( componentId: ComponentId, overridableProps: OverridableProps ) {
49
+ dispatch( slice.actions.setOverridableProps( { componentId, overridableProps } ) );
50
+ },
51
+ rename( componentUid: string, name: string ) {
52
+ dispatch( slice.actions.rename( { componentUid, name } ) );
53
+ },
54
+ cleanUpdatedComponentNames() {
55
+ dispatch( slice.actions.cleanUpdatedComponentNames() );
56
+ },
57
+ updateComponentSanitizedAttribute( componentId: ComponentId, attribute: SanitizeAttributes ) {
58
+ dispatch( slice.actions.updateComponentSanitizedAttribute( { componentId, attribute } ) );
59
+ },
60
+ resetSanitizedComponents() {
61
+ dispatch( slice.actions.resetSanitizedComponents() );
62
+ },
63
+ };