@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.
- package/dist/index.d.mts +1422 -1
- package/dist/index.d.ts +1422 -1
- package/dist/index.js +2096 -4814
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2028 -4837
- package/dist/index.mjs.map +1 -1
- package/package.json +23 -23
- package/src/components/components-tab/components-list.tsx +92 -4
- package/src/components/components-tab/components-pro-notification.tsx +9 -15
- package/src/components/components-tab/components-update-notification.tsx +13 -0
- package/src/components/components-tab/components.tsx +52 -3
- package/src/components/components-tab/loading-components.tsx +26 -14
- package/src/components/components-update-alert.tsx +40 -0
- package/src/components/components-upgrade-alert.tsx +39 -0
- package/src/components/detach-instance-confirmation-dialog.tsx +50 -0
- package/src/components/instance-editing-panel/detach-action.tsx +76 -0
- package/src/components/instance-editing-panel/empty-state.tsx +9 -2
- package/src/components/instance-editing-panel/instance-editing-panel.tsx +34 -6
- package/src/components/instance-editing-panel/override-prop-control.tsx +14 -6
- package/src/components/instance-editing-panel/use-instance-panel-data.ts +2 -2
- package/src/components/instance-editing-panel/utils/correct-exposed-empty-override.ts +28 -0
- package/src/consts.ts +1 -0
- package/src/create-component-type.ts +130 -29
- package/src/index.ts +92 -0
- package/src/init.ts +6 -4
- package/src/store/actions/update-overridable-prop.ts +4 -10
- package/src/store/dispatchers.ts +63 -0
- package/src/store/extensible-slice.ts +168 -0
- package/src/store/selectors.ts +53 -0
- package/src/store/store-types.ts +48 -0
- package/src/store/store.ts +7 -169
- package/src/sync/publish-draft-components-in-page-before-save.ts +42 -1
- package/src/types.ts +1 -1
- package/src/utils/detach-component-instance/detach-component-instance.ts +172 -0
- package/src/utils/detach-component-instance/index.ts +1 -0
- package/src/utils/detach-component-instance/regenerate-local-style-ids.ts +53 -0
- package/src/utils/detach-component-instance/resolve-detached-instance.ts +94 -0
- package/src/utils/detach-component-instance/resolve-overridable-settings.ts +121 -0
- package/src/utils/is-component-instance.ts +1 -1
- package/src/utils/is-pro-components-supported.ts +11 -0
- package/src/utils/tracking.ts +2 -1
- package/src/extended/components/component-introduction.tsx +0 -77
- package/src/extended/components/component-panel-header/component-badge.tsx +0 -73
- package/src/extended/components/component-panel-header/component-panel-header.tsx +0 -98
- package/src/extended/components/component-properties-panel/component-properties-panel-content.tsx +0 -176
- package/src/extended/components/component-properties-panel/component-properties-panel.tsx +0 -43
- package/src/extended/components/component-properties-panel/properties-empty-state.tsx +0 -51
- package/src/extended/components/component-properties-panel/properties-group.tsx +0 -196
- package/src/extended/components/component-properties-panel/property-item.tsx +0 -124
- package/src/extended/components/component-properties-panel/sortable.tsx +0 -92
- package/src/extended/components/component-properties-panel/use-current-editable-item.ts +0 -73
- package/src/extended/components/component-properties-panel/utils/generate-unique-label.ts +0 -21
- package/src/extended/components/component-properties-panel/utils/validate-group-label.ts +0 -24
- package/src/extended/components/components-tab/component-item.tsx +0 -180
- package/src/extended/components/components-tab/components.tsx +0 -58
- package/src/extended/components/components-tab/delete-confirmation-dialog.tsx +0 -26
- package/src/extended/components/create-component-form/create-component-form.tsx +0 -282
- package/src/extended/components/create-component-form/hooks/use-form.ts +0 -72
- package/src/extended/components/create-component-form/utils/get-component-event-data.ts +0 -54
- package/src/extended/components/edit-component/component-modal.tsx +0 -133
- package/src/extended/components/edit-component/edit-component.tsx +0 -166
- package/src/extended/components/edit-component/use-canvas-document.ts +0 -9
- package/src/extended/components/edit-component/use-element-rect.ts +0 -81
- package/src/extended/components/instance-editing-panel/instance-editing-panel.tsx +0 -60
- package/src/extended/components/overridable-props/indicator.tsx +0 -83
- package/src/extended/components/overridable-props/overridable-prop-control.tsx +0 -127
- package/src/extended/components/overridable-props/overridable-prop-form.tsx +0 -135
- package/src/extended/components/overridable-props/overridable-prop-indicator.tsx +0 -138
- package/src/extended/components/overridable-props/utils/validate-prop-label.ts +0 -38
- package/src/extended/consts.ts +0 -3
- package/src/extended/hooks/use-navigate-back.ts +0 -24
- package/src/extended/init.ts +0 -104
- package/src/extended/mcp/index.ts +0 -14
- package/src/extended/mcp/save-as-component-tool.ts +0 -436
- package/src/extended/store/actions/add-overridable-group.ts +0 -59
- package/src/extended/store/actions/archive-component.ts +0 -19
- package/src/extended/store/actions/create-unpublished-component.ts +0 -102
- package/src/extended/store/actions/delete-overridable-group.ts +0 -38
- package/src/extended/store/actions/delete-overridable-prop.ts +0 -70
- package/src/extended/store/actions/rename-component.ts +0 -49
- package/src/extended/store/actions/rename-overridable-group.ts +0 -39
- package/src/extended/store/actions/reorder-group-props.ts +0 -43
- package/src/extended/store/actions/reorder-overridable-groups.ts +0 -30
- package/src/extended/store/actions/reset-sanitized-components.ts +0 -7
- package/src/extended/store/actions/set-overridable-prop.ts +0 -117
- package/src/extended/store/actions/update-component-sanitized-attribute.ts +0 -8
- package/src/extended/store/actions/update-current-component.ts +0 -21
- package/src/extended/store/actions/update-overridable-prop-params.ts +0 -58
- package/src/extended/store/utils/groups-transformers.ts +0 -187
- package/src/extended/sync/before-save.ts +0 -52
- package/src/extended/sync/cleanup-overridable-props-on-delete.ts +0 -85
- package/src/extended/sync/create-components-before-save.ts +0 -113
- package/src/extended/sync/handle-component-edit-mode-container.ts +0 -114
- package/src/extended/sync/prevent-non-atomic-nesting.ts +0 -198
- package/src/extended/sync/revert-overridables-on-copy-or-duplicate.ts +0 -66
- package/src/extended/sync/sanitize-overridable-props.ts +0 -32
- package/src/extended/sync/set-component-overridable-props-settings-before-save.ts +0 -23
- package/src/extended/sync/update-archived-component-before-save.ts +0 -32
- package/src/extended/sync/update-component-title-before-save.ts +0 -19
- package/src/extended/utils/component-form-schema.ts +0 -32
- package/src/extended/utils/component-name-validation.ts +0 -27
- package/src/extended/utils/create-component-model.ts +0 -28
- package/src/extended/utils/get-container-for-new-element.ts +0 -49
- package/src/extended/utils/is-editing-component.ts +0 -13
- package/src/extended/utils/replace-element-with-component.ts +0 -11
- 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 {
|
|
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
|
-
|
|
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
|
-
<
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
|
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;
|
|
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
|
|
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
|
|
119
|
+
// Insert additional actions if needed
|
|
71
120
|
if ( addConfig ) {
|
|
72
|
-
updatedActions.splice( addConfig.index, 0, addConfig.
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
319
|
+
if ( isProOutdatedForComponents() ) {
|
|
320
|
+
notifyComponentEditUpdate();
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
259
323
|
|
|
260
|
-
if ( !
|
|
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()
|
|
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( {
|
|
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 {
|
|
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 =
|
|
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
|
-
|
|
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
|
+
};
|