@elementor/editor-components 3.33.0-98 → 3.35.0-324
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.js +2225 -128
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2236 -111
- package/dist/index.mjs.map +1 -1
- package/package.json +23 -12
- package/src/api.ts +71 -11
- package/src/component-instance-transformer.ts +24 -0
- package/src/component-overridable-transformer.ts +28 -0
- package/src/components/component-panel-header/component-badge.tsx +62 -0
- package/src/components/component-panel-header/component-panel-header.tsx +58 -0
- package/src/components/component-panel-header/use-overridable-props.ts +14 -0
- package/src/components/components-tab/component-search.tsx +32 -0
- package/src/components/components-tab/components-item.tsx +115 -0
- package/src/components/components-tab/components-list.tsx +141 -0
- package/src/components/components-tab/components.tsx +17 -0
- package/src/components/components-tab/loading-components.tsx +43 -0
- package/src/components/components-tab/search-provider.tsx +38 -0
- package/src/components/consts.ts +1 -0
- package/src/components/create-component-form/create-component-form.tsx +109 -100
- package/src/components/create-component-form/utils/get-component-event-data.ts +54 -0
- package/src/components/create-component-form/utils/replace-element-with-component.ts +28 -10
- package/src/components/edit-component/component-modal.tsx +134 -0
- package/src/components/edit-component/edit-component.tsx +96 -0
- package/src/components/in-edit-mode.tsx +43 -0
- package/src/components/overridable-props/indicator.tsx +80 -0
- package/src/components/overridable-props/overridable-prop-control.tsx +67 -0
- package/src/components/overridable-props/overridable-prop-form.tsx +98 -0
- package/src/components/overridable-props/overridable-prop-indicator.tsx +124 -0
- package/src/components/overridable-props/utils/get-overridable-prop.ts +20 -0
- package/src/create-component-type.ts +194 -0
- package/src/hooks/use-canvas-document.ts +6 -0
- package/src/hooks/use-components.ts +6 -9
- package/src/hooks/use-element-rect.ts +81 -0
- package/src/hooks/use-navigate-back.ts +34 -0
- package/src/init.ts +100 -3
- package/src/mcp/index.ts +14 -0
- package/src/mcp/save-as-component-tool.ts +92 -0
- package/src/populate-store.ts +12 -0
- package/src/prop-types/component-overridable-prop-type.ts +17 -0
- package/src/store/actions/archive-component.ts +16 -0
- package/src/store/actions/create-unpublished-component.ts +40 -0
- package/src/store/actions/load-components-assets.ts +29 -0
- package/src/store/actions/load-components-overridable-props.ts +33 -0
- package/src/store/actions/load-components-styles.ts +44 -0
- package/src/store/actions/remove-component-styles.ts +9 -0
- package/src/store/actions/set-overridable-prop.ts +200 -0
- package/src/store/actions/update-current-component.ts +33 -0
- package/src/store/actions/update-overridable-prop-origin-value.ts +37 -0
- package/src/store/components-styles-provider.ts +24 -0
- package/src/store/store.ts +193 -0
- package/src/store/thunks.ts +10 -0
- package/src/sync/before-save.ts +31 -0
- package/src/sync/create-components-before-save.ts +102 -0
- package/src/sync/set-component-overridable-props-settings-before-save.ts +23 -0
- package/src/sync/update-archived-component-before-save.ts +44 -0
- package/src/sync/update-components-before-save.ts +35 -0
- package/src/types.ts +83 -0
- package/src/utils/component-document-data.ts +19 -0
- package/src/utils/get-component-ids.ts +36 -0
- package/src/utils/get-container-for-new-element.ts +49 -0
- package/src/utils/tracking.ts +47 -0
- package/src/components/components-tab.tsx +0 -6
- package/src/hooks/use-create-component.ts +0 -13
package/dist/index.js
CHANGED
|
@@ -36,62 +36,1083 @@ module.exports = __toCommonJS(index_exports);
|
|
|
36
36
|
|
|
37
37
|
// src/init.ts
|
|
38
38
|
var import_editor = require("@elementor/editor");
|
|
39
|
+
var import_editor_canvas6 = require("@elementor/editor-canvas");
|
|
40
|
+
var import_editor_documents11 = require("@elementor/editor-documents");
|
|
41
|
+
var import_editor_editing_panel3 = require("@elementor/editor-editing-panel");
|
|
39
42
|
var import_editor_elements_panel = require("@elementor/editor-elements-panel");
|
|
40
|
-
var
|
|
43
|
+
var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
|
|
44
|
+
var import_editor_v1_adapters7 = require("@elementor/editor-v1-adapters");
|
|
45
|
+
var import_store48 = require("@elementor/store");
|
|
46
|
+
var import_i18n15 = require("@wordpress/i18n");
|
|
41
47
|
|
|
42
|
-
// src/
|
|
43
|
-
var
|
|
44
|
-
var
|
|
45
|
-
function ComponentsTab() {
|
|
46
|
-
return /* @__PURE__ */ React.createElement(import_ui.Box, { px: 2 }, "This is the Components tab.");
|
|
47
|
-
}
|
|
48
|
+
// src/component-instance-transformer.ts
|
|
49
|
+
var import_editor_canvas = require("@elementor/editor-canvas");
|
|
50
|
+
var import_store3 = require("@elementor/store");
|
|
48
51
|
|
|
49
|
-
// src/
|
|
50
|
-
var
|
|
51
|
-
var import_react2 = require("react");
|
|
52
|
-
var import_editor_elements2 = require("@elementor/editor-elements");
|
|
53
|
-
var import_editor_ui = require("@elementor/editor-ui");
|
|
54
|
-
var import_icons = require("@elementor/icons");
|
|
55
|
-
var import_ui2 = require("@elementor/ui");
|
|
56
|
-
var import_i18n2 = require("@wordpress/i18n");
|
|
52
|
+
// src/store/store.ts
|
|
53
|
+
var import_store2 = require("@elementor/store");
|
|
57
54
|
|
|
58
|
-
// src/
|
|
59
|
-
var
|
|
55
|
+
// src/store/thunks.ts
|
|
56
|
+
var import_store = require("@elementor/store");
|
|
60
57
|
|
|
61
58
|
// src/api.ts
|
|
59
|
+
var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
|
|
62
60
|
var import_http_client = require("@elementor/http-client");
|
|
63
61
|
var BASE_URL = "elementor/v1/components";
|
|
62
|
+
var getParams = (id) => ({
|
|
63
|
+
action: "get_document_config",
|
|
64
|
+
unique_id: `document-config-${id}`,
|
|
65
|
+
data: { id }
|
|
66
|
+
});
|
|
64
67
|
var apiClient = {
|
|
65
68
|
get: () => (0, import_http_client.httpService)().get(`${BASE_URL}`).then((res) => res.data.data),
|
|
66
|
-
create: (payload) => (0, import_http_client.httpService)().post(`${BASE_URL}`, payload).then((res) => res.data.data)
|
|
69
|
+
create: (payload) => (0, import_http_client.httpService)().post(`${BASE_URL}`, payload).then((res) => res.data.data),
|
|
70
|
+
updateStatuses: (ids, status) => (0, import_http_client.httpService)().put(`${BASE_URL}/status`, {
|
|
71
|
+
ids,
|
|
72
|
+
status
|
|
73
|
+
}),
|
|
74
|
+
getComponentConfig: (id) => import_editor_v1_adapters.ajax.load(getParams(id)),
|
|
75
|
+
invalidateComponentConfigCache: (id) => import_editor_v1_adapters.ajax.invalidateCache(getParams(id)),
|
|
76
|
+
getComponentLockStatus: async (componentId) => await (0, import_http_client.httpService)().get(`${BASE_URL}/lock-status`, {
|
|
77
|
+
params: {
|
|
78
|
+
componentId
|
|
79
|
+
}
|
|
80
|
+
}).then((res) => {
|
|
81
|
+
const { is_current_user_allow_to_edit: isAllowedToSwitchDocument, locked_by: lockedBy } = res.data.data;
|
|
82
|
+
return { isAllowedToSwitchDocument, lockedBy: lockedBy || "" };
|
|
83
|
+
}),
|
|
84
|
+
lockComponent: async (componentId) => await (0, import_http_client.httpService)().post(`${BASE_URL}/lock`, {
|
|
85
|
+
componentId
|
|
86
|
+
}).then((res) => res.data),
|
|
87
|
+
unlockComponent: async (componentId) => await (0, import_http_client.httpService)().post(`${BASE_URL}/unlock`, {
|
|
88
|
+
componentId
|
|
89
|
+
}).then((res) => res.data),
|
|
90
|
+
getOverridableProps: async (componentId) => await (0, import_http_client.httpService)().get(`${BASE_URL}/overridable-props`, {
|
|
91
|
+
params: {
|
|
92
|
+
componentId: componentId.toString()
|
|
93
|
+
}
|
|
94
|
+
}).then((res) => res.data.data),
|
|
95
|
+
updateArchivedComponents: async (componentIds) => await (0, import_http_client.httpService)().post(
|
|
96
|
+
`${BASE_URL}/archive`,
|
|
97
|
+
{
|
|
98
|
+
componentIds
|
|
99
|
+
}
|
|
100
|
+
).then((res) => res.data.data)
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// src/store/thunks.ts
|
|
104
|
+
var loadComponents = (0, import_store.__createAsyncThunk)("components/load", async () => {
|
|
105
|
+
const response = await apiClient.get();
|
|
106
|
+
return response;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// src/store/store.ts
|
|
110
|
+
var initialState = {
|
|
111
|
+
data: [],
|
|
112
|
+
unpublishedData: [],
|
|
113
|
+
loadStatus: "idle",
|
|
114
|
+
styles: {},
|
|
115
|
+
createdThisSession: [],
|
|
116
|
+
archivedData: [],
|
|
117
|
+
path: [],
|
|
118
|
+
currentComponentId: null
|
|
119
|
+
};
|
|
120
|
+
var SLICE_NAME = "components";
|
|
121
|
+
var slice = (0, import_store2.__createSlice)({
|
|
122
|
+
name: SLICE_NAME,
|
|
123
|
+
initialState,
|
|
124
|
+
reducers: {
|
|
125
|
+
add: (state, { payload }) => {
|
|
126
|
+
if (Array.isArray(payload)) {
|
|
127
|
+
state.data = [...state.data, ...payload];
|
|
128
|
+
} else {
|
|
129
|
+
state.data.unshift(payload);
|
|
130
|
+
}
|
|
131
|
+
},
|
|
132
|
+
load: (state, { payload }) => {
|
|
133
|
+
state.data = payload;
|
|
134
|
+
},
|
|
135
|
+
addUnpublished: (state, { payload }) => {
|
|
136
|
+
state.unpublishedData.unshift(payload);
|
|
137
|
+
},
|
|
138
|
+
resetUnpublished: (state) => {
|
|
139
|
+
state.unpublishedData = [];
|
|
140
|
+
},
|
|
141
|
+
removeStyles(state, { payload }) {
|
|
142
|
+
const { [payload.id]: _, ...rest } = state.styles;
|
|
143
|
+
state.styles = rest;
|
|
144
|
+
},
|
|
145
|
+
addStyles: (state, { payload }) => {
|
|
146
|
+
state.styles = { ...state.styles, ...payload };
|
|
147
|
+
},
|
|
148
|
+
addCreatedThisSession: (state, { payload }) => {
|
|
149
|
+
state.createdThisSession.push(payload);
|
|
150
|
+
},
|
|
151
|
+
archive: (state, { payload }) => {
|
|
152
|
+
state.data = state.data.filter((component) => {
|
|
153
|
+
const isArchived = component.id === payload;
|
|
154
|
+
if (isArchived) {
|
|
155
|
+
state.archivedData.push(component);
|
|
156
|
+
}
|
|
157
|
+
return !isArchived;
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
setCurrentComponentId: (state, { payload }) => {
|
|
161
|
+
state.currentComponentId = payload;
|
|
162
|
+
},
|
|
163
|
+
setPath: (state, { payload }) => {
|
|
164
|
+
state.path = payload;
|
|
165
|
+
},
|
|
166
|
+
setOverridableProps: (state, { payload }) => {
|
|
167
|
+
const component = state.data.find((comp) => comp.id === payload.componentId);
|
|
168
|
+
if (!component) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
component.overridableProps = payload.overridableProps;
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
extraReducers: (builder) => {
|
|
175
|
+
builder.addCase(loadComponents.fulfilled, (state, { payload }) => {
|
|
176
|
+
state.data = payload;
|
|
177
|
+
state.loadStatus = "idle";
|
|
178
|
+
});
|
|
179
|
+
builder.addCase(loadComponents.pending, (state) => {
|
|
180
|
+
state.loadStatus = "pending";
|
|
181
|
+
});
|
|
182
|
+
builder.addCase(loadComponents.rejected, (state) => {
|
|
183
|
+
state.loadStatus = "error";
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
var selectData = (state) => state[SLICE_NAME].data;
|
|
188
|
+
var selectArchivedData = (state) => state[SLICE_NAME].archivedData;
|
|
189
|
+
var selectLoadStatus = (state) => state[SLICE_NAME].loadStatus;
|
|
190
|
+
var selectStylesDefinitions = (state) => state[SLICE_NAME].styles ?? {};
|
|
191
|
+
var selectUnpublishedData = (state) => state[SLICE_NAME].unpublishedData;
|
|
192
|
+
var getCreatedThisSession = (state) => state[SLICE_NAME].createdThisSession;
|
|
193
|
+
var getPath = (state) => state[SLICE_NAME].path;
|
|
194
|
+
var getCurrentComponentId = (state) => state[SLICE_NAME].currentComponentId;
|
|
195
|
+
var selectComponent = (state, componentId) => state[SLICE_NAME].data.find((component) => component.id === componentId);
|
|
196
|
+
var selectComponents = (0, import_store2.__createSelector)(
|
|
197
|
+
selectData,
|
|
198
|
+
selectUnpublishedData,
|
|
199
|
+
(data, unpublishedData) => [
|
|
200
|
+
...unpublishedData.map((item) => ({ uid: item.uid, name: item.name })),
|
|
201
|
+
...data
|
|
202
|
+
]
|
|
203
|
+
);
|
|
204
|
+
var selectUnpublishedComponents = (0, import_store2.__createSelector)(
|
|
205
|
+
selectUnpublishedData,
|
|
206
|
+
(unpublishedData) => unpublishedData
|
|
207
|
+
);
|
|
208
|
+
var selectLoadIsPending = (0, import_store2.__createSelector)(selectLoadStatus, (status) => status === "pending");
|
|
209
|
+
var selectLoadIsError = (0, import_store2.__createSelector)(selectLoadStatus, (status) => status === "error");
|
|
210
|
+
var selectStyles = (state) => state[SLICE_NAME].styles ?? {};
|
|
211
|
+
var selectFlatStyles = (0, import_store2.__createSelector)(selectStylesDefinitions, (data) => Object.values(data).flat());
|
|
212
|
+
var selectCreatedThisSession = (0, import_store2.__createSelector)(
|
|
213
|
+
getCreatedThisSession,
|
|
214
|
+
(createdThisSession) => createdThisSession
|
|
215
|
+
);
|
|
216
|
+
var DEFAULT_OVERRIDABLE_PROPS = {
|
|
217
|
+
props: {},
|
|
218
|
+
groups: {
|
|
219
|
+
items: {},
|
|
220
|
+
order: []
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
var selectOverridableProps = (0, import_store2.__createSelector)(
|
|
224
|
+
selectComponent,
|
|
225
|
+
(component) => {
|
|
226
|
+
if (!component) {
|
|
227
|
+
return void 0;
|
|
228
|
+
}
|
|
229
|
+
return component.overridableProps ?? DEFAULT_OVERRIDABLE_PROPS;
|
|
230
|
+
}
|
|
231
|
+
);
|
|
232
|
+
var selectIsOverridablePropsLoaded = (0, import_store2.__createSelector)(
|
|
233
|
+
selectComponent,
|
|
234
|
+
(component) => {
|
|
235
|
+
return !!component?.overridableProps;
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
var selectPath = (0, import_store2.__createSelector)(getPath, (path) => path);
|
|
239
|
+
var selectCurrentComponentId = (0, import_store2.__createSelector)(
|
|
240
|
+
getCurrentComponentId,
|
|
241
|
+
(currentComponentId) => currentComponentId
|
|
242
|
+
);
|
|
243
|
+
var selectArchivedComponents = (0, import_store2.__createSelector)(
|
|
244
|
+
selectArchivedData,
|
|
245
|
+
(archivedData) => archivedData
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
// src/utils/component-document-data.ts
|
|
249
|
+
var import_editor_documents = require("@elementor/editor-documents");
|
|
250
|
+
var getComponentDocumentData = async (id) => {
|
|
251
|
+
const documentManager = (0, import_editor_documents.getV1DocumentsManager)();
|
|
252
|
+
try {
|
|
253
|
+
return await documentManager.request(id);
|
|
254
|
+
} catch {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
var invalidateComponentDocumentData = (id) => {
|
|
259
|
+
const documentManager = (0, import_editor_documents.getV1DocumentsManager)();
|
|
260
|
+
documentManager.invalidateCache(id);
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// src/component-instance-transformer.ts
|
|
264
|
+
var componentInstanceTransformer = (0, import_editor_canvas.createTransformer)(
|
|
265
|
+
async ({ component_id: id }) => {
|
|
266
|
+
const unpublishedComponents = selectUnpublishedComponents((0, import_store3.__getState)());
|
|
267
|
+
const unpublishedComponent = unpublishedComponents.find(({ uid }) => uid === id);
|
|
268
|
+
if (unpublishedComponent) {
|
|
269
|
+
return structuredClone(unpublishedComponent.elements);
|
|
270
|
+
}
|
|
271
|
+
if (typeof id !== "number") {
|
|
272
|
+
throw new Error(`Component ID "${id}" not found.`);
|
|
273
|
+
}
|
|
274
|
+
const data = await getComponentDocumentData(id);
|
|
275
|
+
return data?.elements ?? [];
|
|
276
|
+
}
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
// src/component-overridable-transformer.ts
|
|
280
|
+
var import_editor_canvas2 = require("@elementor/editor-canvas");
|
|
281
|
+
var componentOverridableTransformer = (0, import_editor_canvas2.createTransformer)(
|
|
282
|
+
async (value, options) => {
|
|
283
|
+
return await transformOriginValue(value, options);
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
async function transformOriginValue(value, options) {
|
|
287
|
+
if (!value.origin_value || !value.origin_value.value || !value.origin_value.$$type) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
const transformer = import_editor_canvas2.settingsTransformersRegistry.get(value.origin_value.$$type);
|
|
291
|
+
if (!transformer) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
try {
|
|
295
|
+
return await transformer(value.origin_value.value, options);
|
|
296
|
+
} catch {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// src/components/component-panel-header/component-panel-header.tsx
|
|
302
|
+
var React2 = __toESM(require("react"));
|
|
303
|
+
var import_editor_documents3 = require("@elementor/editor-documents");
|
|
304
|
+
var import_icons2 = require("@elementor/icons");
|
|
305
|
+
var import_store9 = require("@elementor/store");
|
|
306
|
+
var import_ui2 = require("@elementor/ui");
|
|
307
|
+
var import_i18n2 = require("@wordpress/i18n");
|
|
308
|
+
|
|
309
|
+
// src/hooks/use-navigate-back.ts
|
|
310
|
+
var import_react = require("react");
|
|
311
|
+
var import_editor_documents2 = require("@elementor/editor-documents");
|
|
312
|
+
var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
|
|
313
|
+
var import_store5 = require("@elementor/store");
|
|
314
|
+
function useNavigateBack() {
|
|
315
|
+
const path = (0, import_store5.__useSelector)(selectPath);
|
|
316
|
+
const documentsManager = (0, import_editor_documents2.getV1DocumentsManager)();
|
|
317
|
+
return (0, import_react.useCallback)(() => {
|
|
318
|
+
const { componentId: prevComponentId, instanceId: prevComponentInstanceId } = path.at(-2) ?? {};
|
|
319
|
+
const switchToDocument = (id, selector) => {
|
|
320
|
+
(0, import_editor_v1_adapters2.__privateRunCommand)("editor/documents/switch", {
|
|
321
|
+
id,
|
|
322
|
+
selector,
|
|
323
|
+
mode: "autosave",
|
|
324
|
+
setAsInitial: false,
|
|
325
|
+
shouldScroll: false
|
|
326
|
+
});
|
|
327
|
+
};
|
|
328
|
+
if (prevComponentId && prevComponentInstanceId) {
|
|
329
|
+
switchToDocument(prevComponentId, `[data-id="${prevComponentInstanceId}"]`);
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
switchToDocument(documentsManager.getInitialId());
|
|
333
|
+
}, [path, documentsManager]);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// src/components/component-panel-header/component-badge.tsx
|
|
337
|
+
var React = __toESM(require("react"));
|
|
338
|
+
var import_react2 = require("react");
|
|
339
|
+
var import_icons = require("@elementor/icons");
|
|
340
|
+
var import_ui = require("@elementor/ui");
|
|
341
|
+
var import_i18n = require("@wordpress/i18n");
|
|
342
|
+
var ComponentsBadge = ({ overridesCount }) => {
|
|
343
|
+
const prevCount = usePrevious(overridesCount);
|
|
344
|
+
const isFirstOverride = prevCount === 0 && overridesCount === 1;
|
|
345
|
+
return /* @__PURE__ */ React.createElement(
|
|
346
|
+
StyledBadge,
|
|
347
|
+
{
|
|
348
|
+
color: "primary",
|
|
349
|
+
key: overridesCount,
|
|
350
|
+
invisible: overridesCount === 0,
|
|
351
|
+
animate: isFirstOverride,
|
|
352
|
+
anchorOrigin: { vertical: "top", horizontal: "right" },
|
|
353
|
+
badgeContent: /* @__PURE__ */ React.createElement(import_ui.Box, { sx: { animation: !isFirstOverride ? `${slideUp} 300ms ease-out` : "none" } }, overridesCount)
|
|
354
|
+
},
|
|
355
|
+
/* @__PURE__ */ React.createElement(import_ui.ToggleButton, { value: "overrides", size: "tiny", "aria-label": (0, import_i18n.__)("View overrides", "elementor") }, /* @__PURE__ */ React.createElement(import_icons.SettingsIcon, { fontSize: "tiny" }))
|
|
356
|
+
);
|
|
357
|
+
};
|
|
358
|
+
var StyledBadge = (0, import_ui.styled)(import_ui.Badge, { shouldForwardProp: (prop) => prop !== "animate" })(
|
|
359
|
+
({ theme, animate }) => ({
|
|
360
|
+
"& .MuiBadge-badge": {
|
|
361
|
+
minWidth: theme.spacing(2),
|
|
362
|
+
height: theme.spacing(2),
|
|
363
|
+
minHeight: theme.spacing(2),
|
|
364
|
+
maxWidth: theme.spacing(2),
|
|
365
|
+
fontSize: theme.typography.caption.fontSize,
|
|
366
|
+
animation: animate ? `${bounceIn} 300ms ease-out` : "none"
|
|
367
|
+
}
|
|
368
|
+
})
|
|
369
|
+
);
|
|
370
|
+
function usePrevious(value) {
|
|
371
|
+
const ref = (0, import_react2.useRef)(value);
|
|
372
|
+
(0, import_react2.useEffect)(() => {
|
|
373
|
+
ref.current = value;
|
|
374
|
+
}, [value]);
|
|
375
|
+
return ref.current;
|
|
376
|
+
}
|
|
377
|
+
var bounceIn = import_ui.keyframes`
|
|
378
|
+
0% { transform: scale(0) translate(50%, 50%); opacity: 0; }
|
|
379
|
+
70% { transform: scale(1.1) translate(50%, -50%); opacity: 1; }
|
|
380
|
+
100% { transform: scale(1) translate(50%, -50%); opacity: 1; }
|
|
381
|
+
`;
|
|
382
|
+
var slideUp = import_ui.keyframes`
|
|
383
|
+
from { transform: translateY(100%); opacity: 0; }
|
|
384
|
+
to { transform: translateY(0); opacity: 1; }
|
|
385
|
+
`;
|
|
386
|
+
|
|
387
|
+
// src/components/component-panel-header/use-overridable-props.ts
|
|
388
|
+
var import_store7 = require("@elementor/store");
|
|
389
|
+
function useOverridableProps(componentId) {
|
|
390
|
+
return (0, import_store7.__useSelector)((state) => {
|
|
391
|
+
if (!componentId) {
|
|
392
|
+
return void 0;
|
|
393
|
+
}
|
|
394
|
+
return selectOverridableProps(state, componentId);
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// src/components/component-panel-header/component-panel-header.tsx
|
|
399
|
+
var ComponentPanelHeader = () => {
|
|
400
|
+
const currentComponentId = (0, import_store9.__useSelector)(selectCurrentComponentId);
|
|
401
|
+
const overridableProps = useOverridableProps(currentComponentId);
|
|
402
|
+
const onBack = useNavigateBack();
|
|
403
|
+
const componentName = getComponentName();
|
|
404
|
+
const overridesCount = overridableProps ? Object.keys(overridableProps.props).length : 0;
|
|
405
|
+
if (!currentComponentId) {
|
|
406
|
+
return null;
|
|
407
|
+
}
|
|
408
|
+
return /* @__PURE__ */ React2.createElement(import_ui2.Box, null, /* @__PURE__ */ React2.createElement(
|
|
409
|
+
import_ui2.Stack,
|
|
410
|
+
{
|
|
411
|
+
direction: "row",
|
|
412
|
+
alignItems: "center",
|
|
413
|
+
justifyContent: "space-between",
|
|
414
|
+
sx: { height: 48, pl: 1.5, pr: 2, py: 1 }
|
|
415
|
+
},
|
|
416
|
+
/* @__PURE__ */ React2.createElement(import_ui2.Stack, { direction: "row", alignItems: "center", gap: 0.5 }, /* @__PURE__ */ React2.createElement(import_ui2.Tooltip, { title: (0, import_i18n2.__)("Back", "elementor") }, /* @__PURE__ */ React2.createElement(import_ui2.IconButton, { size: "tiny", onClick: onBack, "aria-label": (0, import_i18n2.__)("Back", "elementor") }, /* @__PURE__ */ React2.createElement(import_icons2.ArrowLeftIcon, null))), /* @__PURE__ */ React2.createElement(import_ui2.Stack, { direction: "row", alignItems: "center", gap: 0.5 }, /* @__PURE__ */ React2.createElement(import_icons2.ComponentsIcon, { color: "secondary", fontSize: "tiny" }), /* @__PURE__ */ React2.createElement(import_ui2.Typography, { variant: "caption", sx: { fontWeight: 500 } }, componentName))),
|
|
417
|
+
/* @__PURE__ */ React2.createElement(ComponentsBadge, { overridesCount })
|
|
418
|
+
), /* @__PURE__ */ React2.createElement(import_ui2.Divider, null));
|
|
67
419
|
};
|
|
420
|
+
function getComponentName() {
|
|
421
|
+
const documentsManager = (0, import_editor_documents3.getV1DocumentsManager)();
|
|
422
|
+
const currentDocument = documentsManager.getCurrent();
|
|
423
|
+
return currentDocument?.container?.settings?.get("post_title") ?? "";
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// src/components/components-tab/components.tsx
|
|
427
|
+
var React8 = __toESM(require("react"));
|
|
428
|
+
var import_editor_ui2 = require("@elementor/editor-ui");
|
|
429
|
+
|
|
430
|
+
// src/components/components-tab/component-search.tsx
|
|
431
|
+
var React4 = __toESM(require("react"));
|
|
432
|
+
var import_icons3 = require("@elementor/icons");
|
|
433
|
+
var import_ui3 = require("@elementor/ui");
|
|
434
|
+
var import_i18n3 = require("@wordpress/i18n");
|
|
435
|
+
|
|
436
|
+
// src/components/components-tab/search-provider.tsx
|
|
437
|
+
var React3 = __toESM(require("react"));
|
|
438
|
+
var import_react3 = require("react");
|
|
439
|
+
var import_utils = require("@elementor/utils");
|
|
440
|
+
var SearchContext = (0, import_react3.createContext)(void 0);
|
|
441
|
+
var SearchProvider = ({
|
|
442
|
+
children,
|
|
443
|
+
localStorageKey
|
|
444
|
+
}) => {
|
|
445
|
+
const { debouncedValue, handleChange, inputValue } = (0, import_utils.useSearchState)({ localStorageKey });
|
|
446
|
+
const clearSearch = () => {
|
|
447
|
+
handleChange("");
|
|
448
|
+
};
|
|
449
|
+
return /* @__PURE__ */ React3.createElement(SearchContext.Provider, { value: { handleChange, clearSearch, searchValue: debouncedValue, inputValue } }, children);
|
|
450
|
+
};
|
|
451
|
+
var useSearch = () => {
|
|
452
|
+
const context = (0, import_react3.useContext)(SearchContext);
|
|
453
|
+
if (!context) {
|
|
454
|
+
throw new Error("useSearch must be used within a SearchProvider");
|
|
455
|
+
}
|
|
456
|
+
return context;
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
// src/components/components-tab/component-search.tsx
|
|
460
|
+
var ComponentSearch = () => {
|
|
461
|
+
const { inputValue, handleChange } = useSearch();
|
|
462
|
+
return /* @__PURE__ */ React4.createElement(import_ui3.Stack, { direction: "row", gap: 0.5, sx: { width: "100%", px: 2, py: 1.5 } }, /* @__PURE__ */ React4.createElement(import_ui3.Box, { sx: { flexGrow: 1 } }, /* @__PURE__ */ React4.createElement(
|
|
463
|
+
import_ui3.TextField,
|
|
464
|
+
{
|
|
465
|
+
role: "search",
|
|
466
|
+
fullWidth: true,
|
|
467
|
+
size: "tiny",
|
|
468
|
+
value: inputValue,
|
|
469
|
+
placeholder: (0, import_i18n3.__)("Search", "elementor"),
|
|
470
|
+
onChange: (e) => handleChange(e.target.value),
|
|
471
|
+
InputProps: {
|
|
472
|
+
startAdornment: /* @__PURE__ */ React4.createElement(import_ui3.InputAdornment, { position: "start" }, /* @__PURE__ */ React4.createElement(import_icons3.SearchIcon, { fontSize: "tiny" }))
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
)));
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
// src/components/components-tab/components-list.tsx
|
|
479
|
+
var React7 = __toESM(require("react"));
|
|
480
|
+
var import_icons5 = require("@elementor/icons");
|
|
481
|
+
var import_ui6 = require("@elementor/ui");
|
|
482
|
+
var import_i18n6 = require("@wordpress/i18n");
|
|
68
483
|
|
|
69
484
|
// src/hooks/use-components.ts
|
|
70
|
-
var
|
|
485
|
+
var import_store11 = require("@elementor/store");
|
|
71
486
|
var useComponents = () => {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
487
|
+
const components = (0, import_store11.__useSelector)(selectComponents);
|
|
488
|
+
const isLoading = (0, import_store11.__useSelector)(selectLoadIsPending);
|
|
489
|
+
return { components, isLoading };
|
|
490
|
+
};
|
|
491
|
+
|
|
492
|
+
// src/components/components-tab/components-item.tsx
|
|
493
|
+
var React5 = __toESM(require("react"));
|
|
494
|
+
var import_editor_canvas4 = require("@elementor/editor-canvas");
|
|
495
|
+
var import_editor_elements3 = require("@elementor/editor-elements");
|
|
496
|
+
var import_editor_ui = require("@elementor/editor-ui");
|
|
497
|
+
var import_icons4 = require("@elementor/icons");
|
|
498
|
+
var import_ui4 = require("@elementor/ui");
|
|
499
|
+
var import_i18n5 = require("@wordpress/i18n");
|
|
500
|
+
|
|
501
|
+
// src/store/actions/archive-component.ts
|
|
502
|
+
var import_editor_documents4 = require("@elementor/editor-documents");
|
|
503
|
+
var import_store13 = require("@elementor/store");
|
|
504
|
+
var archiveComponent = (componentId) => {
|
|
505
|
+
const store = (0, import_store13.__getStore)();
|
|
506
|
+
const dispatch9 = store?.dispatch;
|
|
507
|
+
if (!dispatch9) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
dispatch9(slice.actions.archive(componentId));
|
|
511
|
+
(0, import_editor_documents4.setDocumentModifiedStatus)(true);
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
// src/store/actions/load-components-assets.ts
|
|
515
|
+
var import_editor_documents6 = require("@elementor/editor-documents");
|
|
516
|
+
|
|
517
|
+
// src/create-component-type.ts
|
|
518
|
+
var import_editor_canvas3 = require("@elementor/editor-canvas");
|
|
519
|
+
var import_editor_documents5 = require("@elementor/editor-documents");
|
|
520
|
+
var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
|
|
521
|
+
var import_i18n4 = require("@wordpress/i18n");
|
|
522
|
+
|
|
523
|
+
// src/utils/tracking.ts
|
|
524
|
+
var import_mixpanel = require("@elementor/mixpanel");
|
|
525
|
+
var import_store15 = require("@elementor/store");
|
|
526
|
+
var trackComponentEvent = ({ action, ...data }) => {
|
|
527
|
+
const { dispatchEvent, config } = (0, import_mixpanel.getMixpanel)();
|
|
528
|
+
if (!config?.names?.components?.[action]) {
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
const name = config.names.components[action];
|
|
532
|
+
dispatchEvent?.(name, data);
|
|
533
|
+
};
|
|
534
|
+
var onElementDrop = (_args, element) => {
|
|
535
|
+
if (!(element.model.get("widgetType") === "e-component")) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const editorSettings = element.model.get("editor_settings");
|
|
539
|
+
const componentName = editorSettings?.title;
|
|
540
|
+
const componentUID = editorSettings?.component_uid;
|
|
541
|
+
const instanceId = element.id;
|
|
542
|
+
const createdThisSession = selectCreatedThisSession((0, import_store15.__getState)());
|
|
543
|
+
const isSameSessionReuse = componentUID && createdThisSession.includes(componentUID);
|
|
544
|
+
const eventsManagerConfig = window.elementorCommon.eventsManager.config;
|
|
545
|
+
const { locations, secondaryLocations } = eventsManagerConfig;
|
|
546
|
+
trackComponentEvent({
|
|
547
|
+
action: "instanceAdded",
|
|
548
|
+
instance_id: instanceId,
|
|
549
|
+
component_uid: componentUID,
|
|
550
|
+
component_name: componentName,
|
|
551
|
+
is_same_session_reuse: isSameSessionReuse,
|
|
552
|
+
location: locations.widgetPanel,
|
|
553
|
+
secondary_location: secondaryLocations.componentsTab
|
|
554
|
+
});
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
// src/create-component-type.ts
|
|
558
|
+
var TYPE = "e-component";
|
|
559
|
+
function createComponentType(options) {
|
|
560
|
+
const legacyWindow = window;
|
|
561
|
+
return class extends legacyWindow.elementor.modules.elements.types.Widget {
|
|
562
|
+
getType() {
|
|
563
|
+
return options.type;
|
|
564
|
+
}
|
|
565
|
+
getView() {
|
|
566
|
+
return createComponentView(options);
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
function createComponentView(options) {
|
|
571
|
+
return class extends (0, import_editor_canvas3.createTemplatedElementView)(options) {
|
|
572
|
+
legacyWindow = window;
|
|
573
|
+
eventsManagerConfig = this.legacyWindow.elementorCommon.eventsManager.config;
|
|
574
|
+
isComponentCurrentlyEdited() {
|
|
575
|
+
const currentDocument = (0, import_editor_documents5.getCurrentDocument)();
|
|
576
|
+
return currentDocument?.id === this.getComponentId();
|
|
577
|
+
}
|
|
578
|
+
afterSettingsResolve(settings) {
|
|
579
|
+
if (settings.component_instance) {
|
|
580
|
+
this.collection = this.legacyWindow.elementor.createBackboneElementsCollection(
|
|
581
|
+
settings.component_instance
|
|
582
|
+
);
|
|
583
|
+
this.collection.models.forEach(setInactiveRecursively);
|
|
584
|
+
settings.component_instance = "<template data-children-placeholder></template>";
|
|
585
|
+
}
|
|
586
|
+
return settings;
|
|
587
|
+
}
|
|
588
|
+
getDomElement() {
|
|
589
|
+
return this.children.findByIndex(0)?.getDomElement() ?? this.$el;
|
|
590
|
+
}
|
|
591
|
+
attachBuffer(collectionView, buffer) {
|
|
592
|
+
const childrenPlaceholder = collectionView.$el.find("[data-children-placeholder]").get(0);
|
|
593
|
+
if (!childrenPlaceholder) {
|
|
594
|
+
super.attachBuffer(collectionView, buffer);
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
childrenPlaceholder.replaceWith(buffer);
|
|
598
|
+
}
|
|
599
|
+
getComponentId() {
|
|
600
|
+
const componentInstance = this.options?.model?.get("settings")?.get("component_instance")?.value;
|
|
601
|
+
return componentInstance.component_id;
|
|
602
|
+
}
|
|
603
|
+
getContextMenuGroups() {
|
|
604
|
+
const filteredGroups = super.getContextMenuGroups().filter((group) => group.name !== "save");
|
|
605
|
+
const componentId = this.getComponentId();
|
|
606
|
+
if (!componentId) {
|
|
607
|
+
return filteredGroups;
|
|
608
|
+
}
|
|
609
|
+
const newGroup = [
|
|
610
|
+
{
|
|
611
|
+
name: "edit component",
|
|
612
|
+
actions: [
|
|
613
|
+
{
|
|
614
|
+
name: "edit component",
|
|
615
|
+
icon: "eicon-edit",
|
|
616
|
+
title: () => (0, import_i18n4.__)("Edit Component", "elementor"),
|
|
617
|
+
isEnabled: () => true,
|
|
618
|
+
callback: (_, eventData) => this.editComponent(eventData)
|
|
619
|
+
}
|
|
620
|
+
]
|
|
621
|
+
}
|
|
622
|
+
];
|
|
623
|
+
return [...filteredGroups, ...newGroup];
|
|
624
|
+
}
|
|
625
|
+
async switchDocument() {
|
|
626
|
+
const { isAllowedToSwitchDocument, lockedBy } = await apiClient.getComponentLockStatus(
|
|
627
|
+
this.getComponentId()
|
|
628
|
+
);
|
|
629
|
+
if (!isAllowedToSwitchDocument) {
|
|
630
|
+
options.showLockedByModal?.(lockedBy || "");
|
|
631
|
+
} else {
|
|
632
|
+
(0, import_editor_v1_adapters3.__privateRunCommand)("editor/documents/switch", {
|
|
633
|
+
id: this.getComponentId(),
|
|
634
|
+
mode: "autosave",
|
|
635
|
+
selector: `[data-id="${this.model.get("id")}"]`,
|
|
636
|
+
shouldScroll: false
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
editComponent({ trigger, location, secondaryLocation }) {
|
|
641
|
+
if (this.isComponentCurrentlyEdited()) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
this.switchDocument();
|
|
645
|
+
const editorSettings = this.model.get("editor_settings");
|
|
646
|
+
trackComponentEvent({
|
|
647
|
+
action: "edited",
|
|
648
|
+
component_uid: editorSettings?.component_uid,
|
|
649
|
+
component_name: editorSettings?.title,
|
|
650
|
+
location,
|
|
651
|
+
secondary_location: secondaryLocation,
|
|
652
|
+
trigger
|
|
653
|
+
});
|
|
654
|
+
}
|
|
655
|
+
handleDblClick(e) {
|
|
656
|
+
e.stopPropagation();
|
|
657
|
+
const { triggers, locations, secondaryLocations } = this.eventsManagerConfig;
|
|
658
|
+
this.editComponent({
|
|
659
|
+
trigger: triggers.doubleClick,
|
|
660
|
+
location: locations.canvas,
|
|
661
|
+
secondaryLocation: secondaryLocations.canvasElement
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
events() {
|
|
665
|
+
return {
|
|
666
|
+
...super.events(),
|
|
667
|
+
dblclick: this.handleDblClick
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
attributes() {
|
|
671
|
+
return {
|
|
672
|
+
...super.attributes(),
|
|
673
|
+
"data-elementor-id": this.getComponentId()
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
function setInactiveRecursively(model) {
|
|
679
|
+
const editSettings = model.get("editSettings");
|
|
680
|
+
if (editSettings) {
|
|
681
|
+
editSettings.set("inactive", true);
|
|
682
|
+
}
|
|
683
|
+
const elements = model.get("elements");
|
|
684
|
+
if (elements) {
|
|
685
|
+
elements.forEach((childModel) => {
|
|
686
|
+
setInactiveRecursively(childModel);
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// src/utils/get-component-ids.ts
|
|
692
|
+
var getComponentIds = async (elements) => {
|
|
693
|
+
const components = elements.map(async ({ widgetType, elType, elements: childElements, settings }) => {
|
|
694
|
+
const ids = [];
|
|
695
|
+
const isComponent = [widgetType, elType].includes(TYPE);
|
|
696
|
+
if (isComponent) {
|
|
697
|
+
const componentId = settings?.component_instance?.value?.component_id;
|
|
698
|
+
const document = await getComponentDocumentData(componentId);
|
|
699
|
+
childElements = document?.elements;
|
|
700
|
+
if (Boolean(componentId)) {
|
|
701
|
+
ids.push(componentId);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
if (!!childElements?.length) {
|
|
705
|
+
ids.push(...await getComponentIds(childElements));
|
|
706
|
+
}
|
|
707
|
+
return ids;
|
|
76
708
|
});
|
|
709
|
+
const result = (await Promise.all(components)).flat();
|
|
710
|
+
return Array.from(new Set(result));
|
|
77
711
|
};
|
|
78
712
|
|
|
79
|
-
// src/
|
|
80
|
-
var
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
713
|
+
// src/store/actions/load-components-overridable-props.ts
|
|
714
|
+
var import_store17 = require("@elementor/store");
|
|
715
|
+
function loadComponentsOverridableProps(componentIds) {
|
|
716
|
+
if (!componentIds.length) {
|
|
717
|
+
return;
|
|
718
|
+
}
|
|
719
|
+
componentIds.forEach(loadComponentOverrides);
|
|
720
|
+
}
|
|
721
|
+
async function loadComponentOverrides(componentId) {
|
|
722
|
+
const isOverridablePropsLoaded = selectIsOverridablePropsLoaded((0, import_store17.__getState)(), componentId);
|
|
723
|
+
if (isOverridablePropsLoaded) {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
const overridableProps = await apiClient.getOverridableProps(componentId);
|
|
727
|
+
if (!overridableProps) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
(0, import_store17.__dispatch)(
|
|
731
|
+
slice.actions.setOverridableProps({
|
|
732
|
+
componentId,
|
|
733
|
+
overridableProps
|
|
734
|
+
})
|
|
735
|
+
);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// src/store/actions/load-components-styles.ts
|
|
739
|
+
var import_store19 = require("@elementor/store");
|
|
740
|
+
async function loadComponentsStyles(componentIds) {
|
|
741
|
+
if (!componentIds.length) {
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
const knownComponents = selectStyles((0, import_store19.__getState)());
|
|
745
|
+
const unknownComponentIds = componentIds.filter((id) => !knownComponents[id]);
|
|
746
|
+
if (!unknownComponentIds.length) {
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
addComponentStyles(unknownComponentIds);
|
|
750
|
+
}
|
|
751
|
+
async function addComponentStyles(ids) {
|
|
752
|
+
const newComponents = await loadStyles(ids);
|
|
753
|
+
addStyles(newComponents);
|
|
754
|
+
}
|
|
755
|
+
async function loadStyles(ids) {
|
|
756
|
+
return Promise.all(ids.map(async (id) => [id, await apiClient.getComponentConfig(id)]));
|
|
757
|
+
}
|
|
758
|
+
function addStyles(data) {
|
|
759
|
+
const styles = Object.fromEntries(
|
|
760
|
+
data.map(([componentId, componentData]) => [componentId, extractStyles(componentData)])
|
|
761
|
+
);
|
|
762
|
+
(0, import_store19.__dispatch)(slice.actions.addStyles(styles));
|
|
763
|
+
}
|
|
764
|
+
function extractStyles(element) {
|
|
765
|
+
return [...Object.values(element.styles ?? {}), ...(element.elements ?? []).flatMap(extractStyles)];
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
// src/store/actions/load-components-assets.ts
|
|
769
|
+
async function loadComponentsAssets(elements) {
|
|
770
|
+
const componentIds = await getComponentIds(elements);
|
|
771
|
+
return Promise.all([
|
|
772
|
+
updateDocumentState(componentIds),
|
|
773
|
+
loadComponentsOverridableProps(componentIds),
|
|
774
|
+
loadComponentsStyles(componentIds)
|
|
775
|
+
]);
|
|
776
|
+
}
|
|
777
|
+
async function updateDocumentState(componentIds) {
|
|
778
|
+
const components = (await Promise.all(componentIds.map(getComponentDocumentData))).filter(
|
|
779
|
+
(document) => !!document
|
|
780
|
+
);
|
|
781
|
+
const isDrafted = components.some(import_editor_documents6.isDocumentDirty);
|
|
782
|
+
if (isDrafted) {
|
|
783
|
+
(0, import_editor_documents6.setDocumentModifiedStatus)(true);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
// src/utils/get-container-for-new-element.ts
|
|
788
|
+
var import_editor_elements = require("@elementor/editor-elements");
|
|
789
|
+
var getContainerForNewElement = () => {
|
|
790
|
+
const currentDocumentContainer = (0, import_editor_elements.getCurrentDocumentContainer)();
|
|
791
|
+
const selectedElement = getSelectedElementContainer();
|
|
792
|
+
let container, options;
|
|
793
|
+
if (selectedElement) {
|
|
794
|
+
switch (selectedElement.model.get("elType")) {
|
|
795
|
+
case "widget": {
|
|
796
|
+
container = selectedElement?.parent;
|
|
797
|
+
const selectedElIndex = selectedElement.view?._index ?? -1;
|
|
798
|
+
if (selectedElIndex > -1) {
|
|
799
|
+
options = { at: selectedElIndex + 1 };
|
|
800
|
+
}
|
|
801
|
+
break;
|
|
802
|
+
}
|
|
803
|
+
case "section": {
|
|
804
|
+
container = selectedElement?.children?.[0];
|
|
805
|
+
break;
|
|
806
|
+
}
|
|
807
|
+
default: {
|
|
808
|
+
container = selectedElement;
|
|
809
|
+
break;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
return { container: container ?? currentDocumentContainer, options };
|
|
814
|
+
};
|
|
815
|
+
function getSelectedElementContainer() {
|
|
816
|
+
const selectedElements = (0, import_editor_elements.getSelectedElements)();
|
|
817
|
+
if (selectedElements.length !== 1) {
|
|
818
|
+
return void 0;
|
|
819
|
+
}
|
|
820
|
+
return (0, import_editor_elements.getContainer)(selectedElements[0].id);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
// src/components/create-component-form/utils/replace-element-with-component.ts
|
|
824
|
+
var import_editor_elements2 = require("@elementor/editor-elements");
|
|
825
|
+
var replaceElementWithComponent = (element, component) => {
|
|
826
|
+
(0, import_editor_elements2.replaceElement)({
|
|
827
|
+
currentElement: element,
|
|
828
|
+
newElement: createComponentModel(component),
|
|
829
|
+
withHistory: false
|
|
830
|
+
});
|
|
831
|
+
};
|
|
832
|
+
var createComponentModel = (component) => {
|
|
833
|
+
return {
|
|
834
|
+
elType: "widget",
|
|
835
|
+
widgetType: "e-component",
|
|
836
|
+
settings: {
|
|
837
|
+
component_instance: {
|
|
838
|
+
$$type: "component-instance",
|
|
839
|
+
value: {
|
|
840
|
+
component_id: component.id ?? component.uid
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
},
|
|
844
|
+
editor_settings: {
|
|
845
|
+
title: component.name,
|
|
846
|
+
component_uid: component.uid
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
};
|
|
850
|
+
|
|
851
|
+
// src/components/components-tab/components-item.tsx
|
|
852
|
+
var ComponentItem = ({ component }) => {
|
|
853
|
+
const componentModel = createComponentModel(component);
|
|
854
|
+
const popupState = (0, import_ui4.usePopupState)({
|
|
855
|
+
variant: "popover",
|
|
856
|
+
disableAutoFocus: true
|
|
857
|
+
});
|
|
858
|
+
const handleClick = () => {
|
|
859
|
+
addComponentToPage(componentModel);
|
|
860
|
+
};
|
|
861
|
+
const handleDragEnd = () => {
|
|
862
|
+
loadComponentsAssets([componentModel]);
|
|
863
|
+
(0, import_editor_canvas4.endDragElementFromPanel)();
|
|
864
|
+
};
|
|
865
|
+
const handleArchiveClick = () => {
|
|
866
|
+
popupState.close();
|
|
867
|
+
if (!component.id) {
|
|
868
|
+
throw new Error("Component ID is required");
|
|
869
|
+
}
|
|
870
|
+
archiveComponent(component.id);
|
|
871
|
+
};
|
|
872
|
+
return /* @__PURE__ */ React5.createElement(React5.Fragment, null, /* @__PURE__ */ React5.createElement(
|
|
873
|
+
import_ui4.ListItemButton,
|
|
874
|
+
{
|
|
875
|
+
draggable: true,
|
|
876
|
+
onDragStart: () => (0, import_editor_canvas4.startDragElementFromPanel)(componentModel),
|
|
877
|
+
onDragEnd: handleDragEnd,
|
|
878
|
+
shape: "rounded",
|
|
879
|
+
sx: { border: "solid 1px", borderColor: "divider", py: 0.5, px: 1 }
|
|
880
|
+
},
|
|
881
|
+
/* @__PURE__ */ React5.createElement(import_ui4.Box, { sx: { display: "flex", width: "100%", alignItems: "center", gap: 1 }, onClick: handleClick }, /* @__PURE__ */ React5.createElement(import_ui4.ListItemIcon, { size: "tiny" }, /* @__PURE__ */ React5.createElement(import_icons4.ComponentsIcon, { fontSize: "tiny" })), /* @__PURE__ */ React5.createElement(
|
|
882
|
+
import_ui4.ListItemText,
|
|
883
|
+
{
|
|
884
|
+
primary: /* @__PURE__ */ React5.createElement(import_ui4.Typography, { variant: "caption", sx: { color: "text.primary" } }, component.name)
|
|
885
|
+
}
|
|
886
|
+
)),
|
|
887
|
+
/* @__PURE__ */ React5.createElement(import_ui4.IconButton, { size: "tiny", ...(0, import_ui4.bindTrigger)(popupState), "aria-label": "More actions" }, /* @__PURE__ */ React5.createElement(import_icons4.DotsVerticalIcon, { fontSize: "tiny" }))
|
|
888
|
+
), /* @__PURE__ */ React5.createElement(
|
|
889
|
+
import_ui4.Menu,
|
|
890
|
+
{
|
|
891
|
+
...(0, import_ui4.bindMenu)(popupState),
|
|
892
|
+
anchorOrigin: {
|
|
893
|
+
vertical: "bottom",
|
|
894
|
+
horizontal: "right"
|
|
895
|
+
},
|
|
896
|
+
transformOrigin: {
|
|
897
|
+
vertical: "top",
|
|
898
|
+
horizontal: "right"
|
|
899
|
+
}
|
|
900
|
+
},
|
|
901
|
+
/* @__PURE__ */ React5.createElement(import_editor_ui.MenuListItem, { sx: { minWidth: "160px" }, onClick: handleArchiveClick }, (0, import_i18n5.__)("Archive", "elementor"))
|
|
902
|
+
));
|
|
903
|
+
};
|
|
904
|
+
var addComponentToPage = (model) => {
|
|
905
|
+
const { container, options } = getContainerForNewElement();
|
|
906
|
+
if (!container) {
|
|
907
|
+
throw new Error(`Can't find container to drop new component instance at`);
|
|
908
|
+
}
|
|
909
|
+
loadComponentsAssets([model]);
|
|
910
|
+
(0, import_editor_elements3.dropElement)({
|
|
911
|
+
containerId: container.id,
|
|
912
|
+
model,
|
|
913
|
+
options: { ...options, useHistory: false, scrollIntoView: true }
|
|
86
914
|
});
|
|
87
915
|
};
|
|
88
916
|
|
|
917
|
+
// src/components/components-tab/loading-components.tsx
|
|
918
|
+
var React6 = __toESM(require("react"));
|
|
919
|
+
var import_ui5 = require("@elementor/ui");
|
|
920
|
+
var ROWS_COUNT = 6;
|
|
921
|
+
var rows = Array.from({ length: ROWS_COUNT }, (_, index) => index);
|
|
922
|
+
var LoadingComponents = () => {
|
|
923
|
+
return /* @__PURE__ */ React6.createElement(
|
|
924
|
+
import_ui5.Stack,
|
|
925
|
+
{
|
|
926
|
+
"aria-label": "Loading components",
|
|
927
|
+
gap: 1,
|
|
928
|
+
sx: {
|
|
929
|
+
pointerEvents: "none",
|
|
930
|
+
position: "relative",
|
|
931
|
+
maxHeight: "300px",
|
|
932
|
+
overflow: "hidden",
|
|
933
|
+
"&:after": {
|
|
934
|
+
position: "absolute",
|
|
935
|
+
top: 0,
|
|
936
|
+
content: '""',
|
|
937
|
+
left: 0,
|
|
938
|
+
width: "100%",
|
|
939
|
+
height: "300px",
|
|
940
|
+
background: "linear-gradient(to top, white, transparent)",
|
|
941
|
+
pointerEvents: "none"
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
},
|
|
945
|
+
rows.map((row) => /* @__PURE__ */ React6.createElement(
|
|
946
|
+
import_ui5.ListItemButton,
|
|
947
|
+
{
|
|
948
|
+
key: row,
|
|
949
|
+
sx: { border: "solid 1px", borderColor: "divider", py: 0.5, px: 1 },
|
|
950
|
+
shape: "rounded"
|
|
951
|
+
},
|
|
952
|
+
/* @__PURE__ */ React6.createElement(import_ui5.Box, { display: "flex", gap: 1, width: "100%" }, /* @__PURE__ */ React6.createElement(import_ui5.Skeleton, { variant: "text", width: "24px", height: "36px" }), /* @__PURE__ */ React6.createElement(import_ui5.Skeleton, { variant: "text", width: "100%", height: "36px" }))
|
|
953
|
+
))
|
|
954
|
+
);
|
|
955
|
+
};
|
|
956
|
+
|
|
957
|
+
// src/components/components-tab/components-list.tsx
|
|
958
|
+
function ComponentsList() {
|
|
959
|
+
const { components, isLoading, searchValue } = useFilteredComponents();
|
|
960
|
+
if (isLoading) {
|
|
961
|
+
return /* @__PURE__ */ React7.createElement(LoadingComponents, null);
|
|
962
|
+
}
|
|
963
|
+
const isEmpty = !components || components.length === 0;
|
|
964
|
+
if (isEmpty) {
|
|
965
|
+
if (searchValue.length > 0) {
|
|
966
|
+
return /* @__PURE__ */ React7.createElement(EmptySearchResult, null);
|
|
967
|
+
}
|
|
968
|
+
return /* @__PURE__ */ React7.createElement(EmptyState, null);
|
|
969
|
+
}
|
|
970
|
+
return /* @__PURE__ */ React7.createElement(import_ui6.List, { sx: { display: "flex", flexDirection: "column", gap: 1, px: 2 } }, components.map((component) => /* @__PURE__ */ React7.createElement(ComponentItem, { key: component.uid, component })));
|
|
971
|
+
}
|
|
972
|
+
var EmptyState = () => {
|
|
973
|
+
return /* @__PURE__ */ React7.createElement(
|
|
974
|
+
import_ui6.Stack,
|
|
975
|
+
{
|
|
976
|
+
alignItems: "center",
|
|
977
|
+
justifyContent: "center",
|
|
978
|
+
height: "100%",
|
|
979
|
+
sx: { px: 2.5, pt: 10 },
|
|
980
|
+
gap: 1.75,
|
|
981
|
+
overflow: "hidden"
|
|
982
|
+
},
|
|
983
|
+
/* @__PURE__ */ React7.createElement(import_ui6.Icon, { fontSize: "large" }, /* @__PURE__ */ React7.createElement(import_icons5.EyeIcon, { fontSize: "large" })),
|
|
984
|
+
/* @__PURE__ */ React7.createElement(import_ui6.Typography, { align: "center", variant: "subtitle2", color: "text.secondary", fontWeight: "bold" }, (0, import_i18n6.__)("Text that explains that there are no Components yet.", "elementor")),
|
|
985
|
+
/* @__PURE__ */ React7.createElement(import_ui6.Typography, { variant: "caption", align: "center", color: "text.secondary" }, (0, import_i18n6.__)(
|
|
986
|
+
"Once you have Components, this is where you can manage them\u2014rearrange, duplicate, rename and delete irrelevant classes.",
|
|
987
|
+
"elementor"
|
|
988
|
+
)),
|
|
989
|
+
/* @__PURE__ */ React7.createElement(import_ui6.Divider, { sx: { width: "100%" }, color: "text.secondary" }),
|
|
990
|
+
/* @__PURE__ */ React7.createElement(import_ui6.Typography, { align: "left", variant: "caption", color: "text.secondary" }, (0, import_i18n6.__)("To create a component, first design it, then choose one of three options:", "elementor")),
|
|
991
|
+
/* @__PURE__ */ React7.createElement(
|
|
992
|
+
import_ui6.Typography,
|
|
993
|
+
{
|
|
994
|
+
align: "left",
|
|
995
|
+
variant: "caption",
|
|
996
|
+
color: "text.secondary",
|
|
997
|
+
sx: { display: "flex", flexDirection: "column" }
|
|
998
|
+
},
|
|
999
|
+
/* @__PURE__ */ React7.createElement("span", null, (0, import_i18n6.__)("1. Right-click and select Create Component", "elementor")),
|
|
1000
|
+
/* @__PURE__ */ React7.createElement("span", null, (0, import_i18n6.__)("2. Use the component icon in the Structure panel", "elementor")),
|
|
1001
|
+
/* @__PURE__ */ React7.createElement("span", null, (0, import_i18n6.__)("3. Use the component icon in the Edit panel header", "elementor"))
|
|
1002
|
+
)
|
|
1003
|
+
);
|
|
1004
|
+
};
|
|
1005
|
+
var EmptySearchResult = () => {
|
|
1006
|
+
const { searchValue, clearSearch } = useSearch();
|
|
1007
|
+
return /* @__PURE__ */ React7.createElement(
|
|
1008
|
+
import_ui6.Stack,
|
|
1009
|
+
{
|
|
1010
|
+
color: "text.secondary",
|
|
1011
|
+
pt: 5,
|
|
1012
|
+
alignItems: "center",
|
|
1013
|
+
gap: 1,
|
|
1014
|
+
overflow: "hidden",
|
|
1015
|
+
justifySelf: "center"
|
|
1016
|
+
},
|
|
1017
|
+
/* @__PURE__ */ React7.createElement(import_icons5.ComponentsIcon, null),
|
|
1018
|
+
/* @__PURE__ */ React7.createElement(
|
|
1019
|
+
import_ui6.Box,
|
|
1020
|
+
{
|
|
1021
|
+
sx: {
|
|
1022
|
+
width: "100%"
|
|
1023
|
+
}
|
|
1024
|
+
},
|
|
1025
|
+
/* @__PURE__ */ React7.createElement(import_ui6.Typography, { align: "center", variant: "subtitle2", color: "inherit" }, (0, import_i18n6.__)("Sorry, nothing matched", "elementor")),
|
|
1026
|
+
searchValue && /* @__PURE__ */ React7.createElement(
|
|
1027
|
+
import_ui6.Typography,
|
|
1028
|
+
{
|
|
1029
|
+
variant: "subtitle2",
|
|
1030
|
+
color: "inherit",
|
|
1031
|
+
sx: {
|
|
1032
|
+
display: "flex",
|
|
1033
|
+
width: "100%",
|
|
1034
|
+
justifyContent: "center"
|
|
1035
|
+
}
|
|
1036
|
+
},
|
|
1037
|
+
/* @__PURE__ */ React7.createElement("span", null, "\u201C"),
|
|
1038
|
+
/* @__PURE__ */ React7.createElement(
|
|
1039
|
+
"span",
|
|
1040
|
+
{
|
|
1041
|
+
style: {
|
|
1042
|
+
maxWidth: "80%",
|
|
1043
|
+
overflow: "hidden",
|
|
1044
|
+
textOverflow: "ellipsis"
|
|
1045
|
+
}
|
|
1046
|
+
},
|
|
1047
|
+
searchValue
|
|
1048
|
+
),
|
|
1049
|
+
/* @__PURE__ */ React7.createElement("span", null, "\u201D.")
|
|
1050
|
+
)
|
|
1051
|
+
),
|
|
1052
|
+
/* @__PURE__ */ React7.createElement(import_ui6.Typography, { align: "center", variant: "caption", color: "inherit" }, (0, import_i18n6.__)("Try something else.", "elementor")),
|
|
1053
|
+
/* @__PURE__ */ React7.createElement(import_ui6.Typography, { align: "center", variant: "caption", color: "inherit" }, /* @__PURE__ */ React7.createElement(import_ui6.Link, { color: "secondary", variant: "caption", component: "button", onClick: clearSearch }, (0, import_i18n6.__)("Clear & try again", "elementor")))
|
|
1054
|
+
);
|
|
1055
|
+
};
|
|
1056
|
+
var useFilteredComponents = () => {
|
|
1057
|
+
const { components, isLoading } = useComponents();
|
|
1058
|
+
const { searchValue } = useSearch();
|
|
1059
|
+
return {
|
|
1060
|
+
components: components.filter(
|
|
1061
|
+
(component) => component.name.toLowerCase().includes(searchValue.toLowerCase())
|
|
1062
|
+
),
|
|
1063
|
+
isLoading,
|
|
1064
|
+
searchValue
|
|
1065
|
+
};
|
|
1066
|
+
};
|
|
1067
|
+
|
|
1068
|
+
// src/components/components-tab/components.tsx
|
|
1069
|
+
var Components = () => {
|
|
1070
|
+
return /* @__PURE__ */ React8.createElement(import_editor_ui2.ThemeProvider, null, /* @__PURE__ */ React8.createElement(SearchProvider, { localStorageKey: "elementor-components-search" }, /* @__PURE__ */ React8.createElement(ComponentSearch, null), /* @__PURE__ */ React8.createElement(ComponentsList, null)));
|
|
1071
|
+
};
|
|
1072
|
+
|
|
1073
|
+
// src/components/consts.ts
|
|
1074
|
+
var COMPONENT_DOCUMENT_TYPE = "elementor_component";
|
|
1075
|
+
|
|
1076
|
+
// src/components/create-component-form/create-component-form.tsx
|
|
1077
|
+
var React9 = __toESM(require("react"));
|
|
1078
|
+
var import_react5 = require("react");
|
|
1079
|
+
var import_editor_elements4 = require("@elementor/editor-elements");
|
|
1080
|
+
var import_editor_ui3 = require("@elementor/editor-ui");
|
|
1081
|
+
var import_icons6 = require("@elementor/icons");
|
|
1082
|
+
var import_ui7 = require("@elementor/ui");
|
|
1083
|
+
var import_i18n8 = require("@wordpress/i18n");
|
|
1084
|
+
|
|
1085
|
+
// src/store/actions/create-unpublished-component.ts
|
|
1086
|
+
var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
|
|
1087
|
+
var import_store21 = require("@elementor/store");
|
|
1088
|
+
var import_utils2 = require("@elementor/utils");
|
|
1089
|
+
function createUnpublishedComponent(name, element, eventData) {
|
|
1090
|
+
const uid = (0, import_utils2.generateUniqueId)("component");
|
|
1091
|
+
const componentBase = { uid, name };
|
|
1092
|
+
(0, import_store21.__dispatch)(
|
|
1093
|
+
slice.actions.addUnpublished({
|
|
1094
|
+
...componentBase,
|
|
1095
|
+
elements: [element]
|
|
1096
|
+
})
|
|
1097
|
+
);
|
|
1098
|
+
(0, import_store21.__dispatch)(slice.actions.addCreatedThisSession(uid));
|
|
1099
|
+
replaceElementWithComponent(element, componentBase);
|
|
1100
|
+
trackComponentEvent({
|
|
1101
|
+
action: "created",
|
|
1102
|
+
component_uid: uid,
|
|
1103
|
+
component_name: name,
|
|
1104
|
+
...eventData
|
|
1105
|
+
});
|
|
1106
|
+
(0, import_editor_v1_adapters4.__privateRunCommand)("document/save/auto");
|
|
1107
|
+
return uid;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
89
1110
|
// src/components/create-component-form/hooks/use-form.ts
|
|
90
|
-
var
|
|
1111
|
+
var import_react4 = require("react");
|
|
91
1112
|
var useForm = (initialValues) => {
|
|
92
|
-
const [values, setValues] = (0,
|
|
93
|
-
const [errors, setErrors] = (0,
|
|
94
|
-
const isValid = (0,
|
|
1113
|
+
const [values, setValues] = (0, import_react4.useState)(initialValues);
|
|
1114
|
+
const [errors, setErrors] = (0, import_react4.useState)({});
|
|
1115
|
+
const isValid = (0, import_react4.useMemo)(() => {
|
|
95
1116
|
return !Object.values(errors).some((error) => error);
|
|
96
1117
|
}, [errors]);
|
|
97
1118
|
const handleChange = (e, field, validationSchema) => {
|
|
@@ -137,16 +1158,16 @@ var validateForm = (values, schema) => {
|
|
|
137
1158
|
|
|
138
1159
|
// src/components/create-component-form/utils/component-form-schema.ts
|
|
139
1160
|
var import_schema = require("@elementor/schema");
|
|
140
|
-
var
|
|
1161
|
+
var import_i18n7 = require("@wordpress/i18n");
|
|
141
1162
|
var MIN_NAME_LENGTH = 2;
|
|
142
1163
|
var MAX_NAME_LENGTH = 50;
|
|
143
1164
|
var createBaseComponentSchema = (existingNames) => {
|
|
144
1165
|
return import_schema.z.object({
|
|
145
1166
|
componentName: import_schema.z.string().trim().max(
|
|
146
1167
|
MAX_NAME_LENGTH,
|
|
147
|
-
(0,
|
|
1168
|
+
(0, import_i18n7.__)("Component name is too long. Please keep it under 50 characters.", "elementor")
|
|
148
1169
|
).refine((value) => !existingNames.includes(value), {
|
|
149
|
-
message: (0,
|
|
1170
|
+
message: (0, import_i18n7.__)("Component name already exists", "elementor")
|
|
150
1171
|
})
|
|
151
1172
|
});
|
|
152
1173
|
};
|
|
@@ -154,104 +1175,115 @@ var createSubmitComponentSchema = (existingNames) => {
|
|
|
154
1175
|
const baseSchema = createBaseComponentSchema(existingNames);
|
|
155
1176
|
return baseSchema.extend({
|
|
156
1177
|
componentName: baseSchema.shape.componentName.refine((value) => value.length > 0, {
|
|
157
|
-
message: (0,
|
|
1178
|
+
message: (0, import_i18n7.__)("Component name is required.", "elementor")
|
|
158
1179
|
}).refine((value) => value.length >= MIN_NAME_LENGTH, {
|
|
159
|
-
message: (0,
|
|
1180
|
+
message: (0, import_i18n7.__)("Component name is too short. Please enter at least 2 characters.", "elementor")
|
|
160
1181
|
})
|
|
161
1182
|
});
|
|
162
1183
|
};
|
|
163
1184
|
|
|
164
|
-
// src/components/create-component-form/utils/
|
|
165
|
-
var
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
withHistory: false
|
|
178
|
-
});
|
|
1185
|
+
// src/components/create-component-form/utils/get-component-event-data.ts
|
|
1186
|
+
var getComponentEventData = (containerElement, options) => {
|
|
1187
|
+
const { elementsCount, componentsCount } = countNestedElements(containerElement);
|
|
1188
|
+
return {
|
|
1189
|
+
nested_elements_count: elementsCount,
|
|
1190
|
+
nested_components_count: componentsCount,
|
|
1191
|
+
top_element_type: containerElement.elType,
|
|
1192
|
+
location: options?.location,
|
|
1193
|
+
secondary_location: options?.secondaryLocation,
|
|
1194
|
+
trigger: options?.trigger
|
|
1195
|
+
};
|
|
179
1196
|
};
|
|
1197
|
+
function countNestedElements(container) {
|
|
1198
|
+
if (!container.elements || container.elements.length === 0) {
|
|
1199
|
+
return { elementsCount: 0, componentsCount: 0 };
|
|
1200
|
+
}
|
|
1201
|
+
let elementsCount = container.elements.length;
|
|
1202
|
+
let componentsCount = 0;
|
|
1203
|
+
for (const element of container.elements) {
|
|
1204
|
+
if (element.widgetType === "e-component") {
|
|
1205
|
+
componentsCount++;
|
|
1206
|
+
}
|
|
1207
|
+
const { elementsCount: nestedElementsCount, componentsCount: nestedComponentsCount } = countNestedElements(element);
|
|
1208
|
+
elementsCount += nestedElementsCount;
|
|
1209
|
+
componentsCount += nestedComponentsCount;
|
|
1210
|
+
}
|
|
1211
|
+
return { elementsCount, componentsCount };
|
|
1212
|
+
}
|
|
180
1213
|
|
|
181
1214
|
// src/components/create-component-form/create-component-form.tsx
|
|
182
1215
|
function CreateComponentForm() {
|
|
183
|
-
const [element, setElement] = (0,
|
|
184
|
-
const [anchorPosition, setAnchorPosition] = (0,
|
|
185
|
-
const [resultNotification, setResultNotification] = (0,
|
|
186
|
-
const
|
|
187
|
-
(0,
|
|
1216
|
+
const [element, setElement] = (0, import_react5.useState)(null);
|
|
1217
|
+
const [anchorPosition, setAnchorPosition] = (0, import_react5.useState)();
|
|
1218
|
+
const [resultNotification, setResultNotification] = (0, import_react5.useState)(null);
|
|
1219
|
+
const eventData = (0, import_react5.useRef)(null);
|
|
1220
|
+
(0, import_react5.useEffect)(() => {
|
|
188
1221
|
const OPEN_SAVE_AS_COMPONENT_FORM_EVENT = "elementor/editor/open-save-as-component-form";
|
|
189
1222
|
const openPopup = (event) => {
|
|
190
|
-
setElement({ element: event.detail.element, elementLabel: (0,
|
|
1223
|
+
setElement({ element: event.detail.element, elementLabel: (0, import_editor_elements4.getElementLabel)(event.detail.element.id) });
|
|
191
1224
|
setAnchorPosition(event.detail.anchorPosition);
|
|
1225
|
+
eventData.current = getComponentEventData(event.detail.element, event.detail.options);
|
|
1226
|
+
trackComponentEvent({
|
|
1227
|
+
action: "createClicked",
|
|
1228
|
+
...eventData.current
|
|
1229
|
+
});
|
|
192
1230
|
};
|
|
193
|
-
window.addEventListener(OPEN_SAVE_AS_COMPONENT_FORM_EVENT, openPopup);
|
|
194
|
-
return () => {
|
|
195
|
-
window.removeEventListener(OPEN_SAVE_AS_COMPONENT_FORM_EVENT, openPopup);
|
|
196
|
-
};
|
|
197
|
-
}, []);
|
|
198
|
-
const handleSave =
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
createComponent(
|
|
203
|
-
{
|
|
204
|
-
name: values.componentName,
|
|
205
|
-
content: [element.element.model.toJSON({ remove: ["default"] })]
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
onSuccess: (result) => {
|
|
209
|
-
if (!element) {
|
|
210
|
-
throw new Error(`Can't replace element with component: element not found`);
|
|
211
|
-
}
|
|
212
|
-
replaceElementWithComponent(element.element, result.component_id);
|
|
213
|
-
setResultNotification({
|
|
214
|
-
show: true,
|
|
215
|
-
// Translators: %1$s: Component name, %2$s: Component ID
|
|
216
|
-
message: (0, import_i18n2.__)("Component saved successfully as: %1$s (ID: %2$s)", "elementor").replace("%1$s", values.componentName).replace("%2$s", result.component_id.toString()),
|
|
217
|
-
type: "success"
|
|
218
|
-
});
|
|
219
|
-
resetAndClosePopup();
|
|
220
|
-
},
|
|
221
|
-
onError: () => {
|
|
222
|
-
const errorMessage = (0, import_i18n2.__)("Failed to save component. Please try again.", "elementor");
|
|
223
|
-
setResultNotification({
|
|
224
|
-
show: true,
|
|
225
|
-
message: errorMessage,
|
|
226
|
-
type: "error"
|
|
227
|
-
});
|
|
228
|
-
}
|
|
1231
|
+
window.addEventListener(OPEN_SAVE_AS_COMPONENT_FORM_EVENT, openPopup);
|
|
1232
|
+
return () => {
|
|
1233
|
+
window.removeEventListener(OPEN_SAVE_AS_COMPONENT_FORM_EVENT, openPopup);
|
|
1234
|
+
};
|
|
1235
|
+
}, []);
|
|
1236
|
+
const handleSave = (values) => {
|
|
1237
|
+
try {
|
|
1238
|
+
if (!element) {
|
|
1239
|
+
throw new Error(`Can't save element as component: element not found`);
|
|
229
1240
|
}
|
|
230
|
-
|
|
1241
|
+
const uid = createUnpublishedComponent(values.componentName, element.element, eventData.current);
|
|
1242
|
+
setResultNotification({
|
|
1243
|
+
show: true,
|
|
1244
|
+
// Translators: %1$s: Component name, %2$s: Component UID
|
|
1245
|
+
message: (0, import_i18n8.__)("Component saved successfully as: %1$s (UID: %2$s)", "elementor").replace("%1$s", values.componentName).replace("%2$s", uid),
|
|
1246
|
+
type: "success"
|
|
1247
|
+
});
|
|
1248
|
+
resetAndClosePopup();
|
|
1249
|
+
} catch {
|
|
1250
|
+
const errorMessage = (0, import_i18n8.__)("Failed to save component. Please try again.", "elementor");
|
|
1251
|
+
setResultNotification({
|
|
1252
|
+
show: true,
|
|
1253
|
+
message: errorMessage,
|
|
1254
|
+
type: "error"
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
231
1257
|
};
|
|
232
1258
|
const resetAndClosePopup = () => {
|
|
233
1259
|
setElement(null);
|
|
234
1260
|
setAnchorPosition(void 0);
|
|
235
1261
|
};
|
|
236
|
-
|
|
237
|
-
|
|
1262
|
+
const cancelSave = () => {
|
|
1263
|
+
resetAndClosePopup();
|
|
1264
|
+
trackComponentEvent({
|
|
1265
|
+
action: "createCancelled",
|
|
1266
|
+
...eventData.current
|
|
1267
|
+
});
|
|
1268
|
+
};
|
|
1269
|
+
return /* @__PURE__ */ React9.createElement(import_editor_ui3.ThemeProvider, null, /* @__PURE__ */ React9.createElement(
|
|
1270
|
+
import_ui7.Popover,
|
|
238
1271
|
{
|
|
239
1272
|
open: element !== null,
|
|
240
|
-
onClose:
|
|
1273
|
+
onClose: cancelSave,
|
|
241
1274
|
anchorReference: "anchorPosition",
|
|
242
1275
|
anchorPosition
|
|
243
1276
|
},
|
|
244
|
-
element !== null && /* @__PURE__ */
|
|
1277
|
+
element !== null && /* @__PURE__ */ React9.createElement(
|
|
245
1278
|
Form,
|
|
246
1279
|
{
|
|
247
1280
|
initialValues: { componentName: element.elementLabel },
|
|
248
1281
|
handleSave,
|
|
249
|
-
|
|
250
|
-
closePopup: resetAndClosePopup
|
|
1282
|
+
closePopup: cancelSave
|
|
251
1283
|
}
|
|
252
1284
|
)
|
|
253
|
-
), /* @__PURE__ */
|
|
254
|
-
|
|
1285
|
+
), /* @__PURE__ */ React9.createElement(import_ui7.Snackbar, { open: resultNotification?.show, onClose: () => setResultNotification(null) }, /* @__PURE__ */ React9.createElement(
|
|
1286
|
+
import_ui7.Alert,
|
|
255
1287
|
{
|
|
256
1288
|
onClose: () => setResultNotification(null),
|
|
257
1289
|
severity: resultNotification?.type,
|
|
@@ -264,19 +1296,18 @@ var FONT_SIZE = "tiny";
|
|
|
264
1296
|
var Form = ({
|
|
265
1297
|
initialValues,
|
|
266
1298
|
handleSave,
|
|
267
|
-
isSubmitting,
|
|
268
1299
|
closePopup
|
|
269
1300
|
}) => {
|
|
270
1301
|
const { values, errors, isValid, handleChange, validateForm: validateForm2 } = useForm(initialValues);
|
|
271
|
-
const {
|
|
272
|
-
const existingComponentNames = (0,
|
|
1302
|
+
const { components } = useComponents();
|
|
1303
|
+
const existingComponentNames = (0, import_react5.useMemo)(() => {
|
|
273
1304
|
return components?.map((component) => component.name) ?? [];
|
|
274
1305
|
}, [components]);
|
|
275
|
-
const changeValidationSchema = (0,
|
|
1306
|
+
const changeValidationSchema = (0, import_react5.useMemo)(
|
|
276
1307
|
() => createBaseComponentSchema(existingComponentNames),
|
|
277
1308
|
[existingComponentNames]
|
|
278
1309
|
);
|
|
279
|
-
const submitValidationSchema = (0,
|
|
1310
|
+
const submitValidationSchema = (0, import_react5.useMemo)(
|
|
280
1311
|
() => createSubmitComponentSchema(existingComponentNames),
|
|
281
1312
|
[existingComponentNames]
|
|
282
1313
|
);
|
|
@@ -286,8 +1317,15 @@ var Form = ({
|
|
|
286
1317
|
handleSave(parsedValues);
|
|
287
1318
|
}
|
|
288
1319
|
};
|
|
289
|
-
|
|
290
|
-
|
|
1320
|
+
const texts = {
|
|
1321
|
+
heading: (0, import_i18n8.__)("Save as a component", "elementor"),
|
|
1322
|
+
name: (0, import_i18n8.__)("Name", "elementor"),
|
|
1323
|
+
cancel: (0, import_i18n8.__)("Cancel", "elementor"),
|
|
1324
|
+
create: (0, import_i18n8.__)("Create", "elementor")
|
|
1325
|
+
};
|
|
1326
|
+
const nameInputId = "component-name";
|
|
1327
|
+
return /* @__PURE__ */ React9.createElement(import_editor_ui3.Form, { onSubmit: handleSubmit }, /* @__PURE__ */ React9.createElement(import_ui7.Stack, { alignItems: "start", width: "268px" }, /* @__PURE__ */ React9.createElement(
|
|
1328
|
+
import_ui7.Stack,
|
|
291
1329
|
{
|
|
292
1330
|
direction: "row",
|
|
293
1331
|
alignItems: "center",
|
|
@@ -295,12 +1333,12 @@ var Form = ({
|
|
|
295
1333
|
px: 1.5,
|
|
296
1334
|
sx: { columnGap: 0.5, borderBottom: "1px solid", borderColor: "divider", width: "100%" }
|
|
297
1335
|
},
|
|
298
|
-
/* @__PURE__ */
|
|
299
|
-
/* @__PURE__ */
|
|
300
|
-
), /* @__PURE__ */
|
|
301
|
-
|
|
1336
|
+
/* @__PURE__ */ React9.createElement(import_icons6.StarIcon, { fontSize: FONT_SIZE }),
|
|
1337
|
+
/* @__PURE__ */ React9.createElement(import_ui7.Typography, { variant: "caption", sx: { color: "text.primary", fontWeight: "500", lineHeight: 1 } }, texts.heading)
|
|
1338
|
+
), /* @__PURE__ */ React9.createElement(import_ui7.Grid, { container: true, gap: 0.75, alignItems: "start", p: 1.5 }, /* @__PURE__ */ React9.createElement(import_ui7.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(import_ui7.FormLabel, { htmlFor: nameInputId, size: "tiny" }, texts.name)), /* @__PURE__ */ React9.createElement(import_ui7.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React9.createElement(
|
|
1339
|
+
import_ui7.TextField,
|
|
302
1340
|
{
|
|
303
|
-
id:
|
|
1341
|
+
id: nameInputId,
|
|
304
1342
|
size: FONT_SIZE,
|
|
305
1343
|
fullWidth: true,
|
|
306
1344
|
value: values.componentName,
|
|
@@ -309,30 +1347,1089 @@ var Form = ({
|
|
|
309
1347
|
error: Boolean(errors.componentName),
|
|
310
1348
|
helperText: errors.componentName
|
|
311
1349
|
}
|
|
312
|
-
))), /* @__PURE__ */
|
|
313
|
-
|
|
1350
|
+
))), /* @__PURE__ */ React9.createElement(import_ui7.Stack, { direction: "row", justifyContent: "flex-end", alignSelf: "end", py: 1, px: 1.5 }, /* @__PURE__ */ React9.createElement(import_ui7.Button, { onClick: closePopup, color: "secondary", variant: "text", size: "small" }, texts.cancel), /* @__PURE__ */ React9.createElement(import_ui7.Button, { type: "submit", disabled: !isValid, variant: "contained", color: "primary", size: "small" }, texts.create))));
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1353
|
+
// src/components/edit-component/edit-component.tsx
|
|
1354
|
+
var React11 = __toESM(require("react"));
|
|
1355
|
+
var import_react8 = require("react");
|
|
1356
|
+
var import_editor_documents8 = require("@elementor/editor-documents");
|
|
1357
|
+
var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
|
|
1358
|
+
var import_store25 = require("@elementor/store");
|
|
1359
|
+
|
|
1360
|
+
// src/store/actions/update-current-component.ts
|
|
1361
|
+
var import_editor_documents7 = require("@elementor/editor-documents");
|
|
1362
|
+
var import_store23 = require("@elementor/store");
|
|
1363
|
+
function updateCurrentComponent({
|
|
1364
|
+
path,
|
|
1365
|
+
currentComponentId
|
|
1366
|
+
}) {
|
|
1367
|
+
const dispatch9 = (0, import_store23.__getStore)()?.dispatch;
|
|
1368
|
+
if (!dispatch9) {
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
dispatch9(slice.actions.setPath(path));
|
|
1372
|
+
dispatch9(slice.actions.setCurrentComponentId(currentComponentId));
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
// src/components/edit-component/component-modal.tsx
|
|
1376
|
+
var React10 = __toESM(require("react"));
|
|
1377
|
+
var import_react7 = require("react");
|
|
1378
|
+
var import_react_dom = require("react-dom");
|
|
1379
|
+
var import_i18n9 = require("@wordpress/i18n");
|
|
1380
|
+
|
|
1381
|
+
// src/hooks/use-canvas-document.ts
|
|
1382
|
+
var import_editor_canvas5 = require("@elementor/editor-canvas");
|
|
1383
|
+
var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
|
|
1384
|
+
function useCanvasDocument() {
|
|
1385
|
+
return (0, import_editor_v1_adapters5.__privateUseListenTo)((0, import_editor_v1_adapters5.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_canvas5.getCanvasIframeDocument)());
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
// src/hooks/use-element-rect.ts
|
|
1389
|
+
var import_react6 = require("react");
|
|
1390
|
+
var import_utils3 = require("@elementor/utils");
|
|
1391
|
+
function useElementRect(element) {
|
|
1392
|
+
const [rect, setRect] = (0, import_react6.useState)(new DOMRect(0, 0, 0, 0));
|
|
1393
|
+
const onChange = (0, import_utils3.throttle)(
|
|
1394
|
+
() => {
|
|
1395
|
+
setRect(element?.getBoundingClientRect() ?? new DOMRect(0, 0, 0, 0));
|
|
1396
|
+
},
|
|
1397
|
+
20,
|
|
1398
|
+
true
|
|
1399
|
+
);
|
|
1400
|
+
useScrollListener({ element, onChange });
|
|
1401
|
+
useResizeListener({ element, onChange });
|
|
1402
|
+
useMutationsListener({ element, onChange });
|
|
1403
|
+
(0, import_react6.useEffect)(
|
|
1404
|
+
() => () => {
|
|
1405
|
+
onChange.cancel();
|
|
1406
|
+
},
|
|
1407
|
+
[onChange]
|
|
1408
|
+
);
|
|
1409
|
+
return rect;
|
|
1410
|
+
}
|
|
1411
|
+
function useScrollListener({ element, onChange }) {
|
|
1412
|
+
(0, import_react6.useEffect)(() => {
|
|
1413
|
+
if (!element) {
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
const win = element.ownerDocument?.defaultView;
|
|
1417
|
+
win?.addEventListener("scroll", onChange, { passive: true });
|
|
1418
|
+
return () => {
|
|
1419
|
+
win?.removeEventListener("scroll", onChange);
|
|
1420
|
+
};
|
|
1421
|
+
}, [element, onChange]);
|
|
1422
|
+
}
|
|
1423
|
+
function useResizeListener({ element, onChange }) {
|
|
1424
|
+
(0, import_react6.useEffect)(() => {
|
|
1425
|
+
if (!element) {
|
|
1426
|
+
return;
|
|
1427
|
+
}
|
|
1428
|
+
const resizeObserver = new ResizeObserver(onChange);
|
|
1429
|
+
resizeObserver.observe(element);
|
|
1430
|
+
const win = element.ownerDocument?.defaultView;
|
|
1431
|
+
win?.addEventListener("resize", onChange, { passive: true });
|
|
1432
|
+
return () => {
|
|
1433
|
+
resizeObserver.disconnect();
|
|
1434
|
+
win?.removeEventListener("resize", onChange);
|
|
1435
|
+
};
|
|
1436
|
+
}, [element, onChange]);
|
|
1437
|
+
}
|
|
1438
|
+
function useMutationsListener({ element, onChange }) {
|
|
1439
|
+
(0, import_react6.useEffect)(() => {
|
|
1440
|
+
if (!element) {
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
const mutationObserver = new MutationObserver(onChange);
|
|
1444
|
+
mutationObserver.observe(element, { childList: true, subtree: true });
|
|
1445
|
+
return () => {
|
|
1446
|
+
mutationObserver.disconnect();
|
|
1447
|
+
};
|
|
1448
|
+
}, [element, onChange]);
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1451
|
+
// src/components/edit-component/component-modal.tsx
|
|
1452
|
+
function ComponentModal({ element, onClose }) {
|
|
1453
|
+
const canvasDocument = useCanvasDocument();
|
|
1454
|
+
(0, import_react7.useEffect)(() => {
|
|
1455
|
+
const handleEsc = (event) => {
|
|
1456
|
+
if (event.key === "Escape") {
|
|
1457
|
+
onClose();
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1460
|
+
canvasDocument?.body.addEventListener("keydown", handleEsc);
|
|
1461
|
+
return () => {
|
|
1462
|
+
canvasDocument?.body.removeEventListener("keydown", handleEsc);
|
|
1463
|
+
};
|
|
1464
|
+
}, [canvasDocument, onClose]);
|
|
1465
|
+
if (!canvasDocument?.body) {
|
|
1466
|
+
return null;
|
|
1467
|
+
}
|
|
1468
|
+
return (0, import_react_dom.createPortal)(
|
|
1469
|
+
/* @__PURE__ */ React10.createElement(React10.Fragment, null, /* @__PURE__ */ React10.createElement(BlockEditPage, null), /* @__PURE__ */ React10.createElement(Backdrop, { canvas: canvasDocument, element, onClose })),
|
|
1470
|
+
canvasDocument.body
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1473
|
+
function Backdrop({ canvas, element, onClose }) {
|
|
1474
|
+
const rect = useElementRect(element);
|
|
1475
|
+
const backdropStyle = {
|
|
1476
|
+
position: "fixed",
|
|
1477
|
+
top: 0,
|
|
1478
|
+
left: 0,
|
|
1479
|
+
width: "100vw",
|
|
1480
|
+
height: "100vh",
|
|
1481
|
+
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
1482
|
+
zIndex: 999,
|
|
1483
|
+
pointerEvents: "painted",
|
|
1484
|
+
cursor: "pointer",
|
|
1485
|
+
clipPath: getRoundedRectPath(rect, canvas.defaultView, 5)
|
|
1486
|
+
};
|
|
1487
|
+
const handleKeyDown = (event) => {
|
|
1488
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
1489
|
+
event.preventDefault();
|
|
1490
|
+
onClose();
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1493
|
+
return /* @__PURE__ */ React10.createElement(
|
|
1494
|
+
"div",
|
|
314
1495
|
{
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
1496
|
+
style: backdropStyle,
|
|
1497
|
+
onClick: onClose,
|
|
1498
|
+
onKeyDown: handleKeyDown,
|
|
1499
|
+
role: "button",
|
|
1500
|
+
tabIndex: 0,
|
|
1501
|
+
"aria-label": (0, import_i18n9.__)("Exit component editing mode", "elementor")
|
|
1502
|
+
}
|
|
1503
|
+
);
|
|
1504
|
+
}
|
|
1505
|
+
function getRoundedRectPath(rect, viewport, borderRadius) {
|
|
1506
|
+
const padding = borderRadius / 2;
|
|
1507
|
+
const { x: originalX, y: originalY, width: originalWidth, height: originalHeight } = rect;
|
|
1508
|
+
const x = originalX - padding;
|
|
1509
|
+
const y = originalY - padding;
|
|
1510
|
+
const width = originalWidth + 2 * padding;
|
|
1511
|
+
const height = originalHeight + 2 * padding;
|
|
1512
|
+
const radius = Math.min(borderRadius, width / 2, height / 2);
|
|
1513
|
+
const { innerWidth: vw, innerHeight: vh } = viewport;
|
|
1514
|
+
const path = `path(evenodd, 'M 0 0
|
|
1515
|
+
L ${vw} 0
|
|
1516
|
+
L ${vw} ${vh}
|
|
1517
|
+
L 0 ${vh}
|
|
1518
|
+
Z
|
|
1519
|
+
M ${x + radius} ${y}
|
|
1520
|
+
L ${x + width - radius} ${y}
|
|
1521
|
+
A ${radius} ${radius} 0 0 1 ${x + width} ${y + radius}
|
|
1522
|
+
L ${x + width} ${y + height - radius}
|
|
1523
|
+
A ${radius} ${radius} 0 0 1 ${x + width - radius} ${y + height}
|
|
1524
|
+
L ${x + radius} ${y + height}
|
|
1525
|
+
A ${radius} ${radius} 0 0 1 ${x} ${y + height - radius}
|
|
1526
|
+
L ${x} ${y + radius}
|
|
1527
|
+
A ${radius} ${radius} 0 0 1 ${x + radius} ${y}
|
|
1528
|
+
Z'
|
|
1529
|
+
)`;
|
|
1530
|
+
return path.replace(/\s{2,}/g, " ");
|
|
1531
|
+
}
|
|
1532
|
+
function BlockEditPage() {
|
|
1533
|
+
const blockV3DocumentHandlesStyles = `
|
|
1534
|
+
.elementor-editor-active {
|
|
1535
|
+
& .elementor-section-wrap.ui-sortable {
|
|
1536
|
+
display: contents;
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
& *[data-editable-elementor-document]:not(.elementor-edit-mode):hover {
|
|
1540
|
+
& .elementor-document-handle:not(.elementor-document-save-back-handle) {
|
|
1541
|
+
display: none;
|
|
1542
|
+
|
|
1543
|
+
&::before,
|
|
1544
|
+
& .elementor-document-handle__inner {
|
|
1545
|
+
display: none;
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
`;
|
|
1551
|
+
return /* @__PURE__ */ React10.createElement("style", { "data-e-style-id": "e-block-v3-document-handles-styles" }, blockV3DocumentHandlesStyles);
|
|
1552
|
+
}
|
|
1553
|
+
|
|
1554
|
+
// src/components/edit-component/edit-component.tsx
|
|
1555
|
+
function EditComponent() {
|
|
1556
|
+
const currentComponentId = (0, import_store25.__useSelector)(selectCurrentComponentId);
|
|
1557
|
+
useHandleDocumentSwitches();
|
|
1558
|
+
const onBack = useNavigateBack();
|
|
1559
|
+
const elementDom = getComponentDOMElement(currentComponentId ?? void 0);
|
|
1560
|
+
if (!elementDom) {
|
|
1561
|
+
return null;
|
|
1562
|
+
}
|
|
1563
|
+
return /* @__PURE__ */ React11.createElement(ComponentModal, { element: elementDom, onClose: onBack });
|
|
1564
|
+
}
|
|
1565
|
+
function useHandleDocumentSwitches() {
|
|
1566
|
+
const documentsManager = (0, import_editor_documents8.getV1DocumentsManager)();
|
|
1567
|
+
const currentComponentId = (0, import_store25.__useSelector)(selectCurrentComponentId);
|
|
1568
|
+
const path = (0, import_store25.__useSelector)(selectPath);
|
|
1569
|
+
(0, import_react8.useEffect)(() => {
|
|
1570
|
+
return (0, import_editor_v1_adapters6.__privateListenTo)((0, import_editor_v1_adapters6.commandEndEvent)("editor/documents/attach-preview"), () => {
|
|
1571
|
+
const nextDocument = documentsManager.getCurrent();
|
|
1572
|
+
if (nextDocument.id === currentComponentId) {
|
|
1573
|
+
return;
|
|
1574
|
+
}
|
|
1575
|
+
if (currentComponentId) {
|
|
1576
|
+
apiClient.unlockComponent(currentComponentId);
|
|
1577
|
+
}
|
|
1578
|
+
const isComponent = nextDocument.config.type === COMPONENT_DOCUMENT_TYPE;
|
|
1579
|
+
if (!isComponent) {
|
|
1580
|
+
updateCurrentComponent({ path: [], currentComponentId: null });
|
|
1581
|
+
return;
|
|
1582
|
+
}
|
|
1583
|
+
updateCurrentComponent({
|
|
1584
|
+
path: getUpdatedComponentPath(path, nextDocument),
|
|
1585
|
+
currentComponentId: nextDocument.id
|
|
1586
|
+
});
|
|
1587
|
+
});
|
|
1588
|
+
}, [path, documentsManager, currentComponentId]);
|
|
1589
|
+
}
|
|
1590
|
+
function getUpdatedComponentPath(path, nextDocument) {
|
|
1591
|
+
const componentIndex = path.findIndex(({ componentId }) => componentId === nextDocument.id);
|
|
1592
|
+
if (componentIndex >= 0) {
|
|
1593
|
+
return path.slice(0, componentIndex + 1);
|
|
1594
|
+
}
|
|
1595
|
+
return [
|
|
1596
|
+
...path,
|
|
1597
|
+
{
|
|
1598
|
+
instanceId: nextDocument?.container.view?.el?.dataset.id,
|
|
1599
|
+
componentId: nextDocument.id
|
|
1600
|
+
}
|
|
1601
|
+
];
|
|
1602
|
+
}
|
|
1603
|
+
function getComponentDOMElement(id) {
|
|
1604
|
+
if (!id) {
|
|
1605
|
+
return null;
|
|
1606
|
+
}
|
|
1607
|
+
const documentsManager = (0, import_editor_documents8.getV1DocumentsManager)();
|
|
1608
|
+
const currentComponent = documentsManager.get(id);
|
|
1609
|
+
const widget = currentComponent?.container;
|
|
1610
|
+
const container = widget?.view?.el?.children?.[0] ?? null;
|
|
1611
|
+
const elementDom = container?.children[0];
|
|
1612
|
+
return elementDom ?? null;
|
|
1613
|
+
}
|
|
1614
|
+
|
|
1615
|
+
// src/components/in-edit-mode.tsx
|
|
1616
|
+
var React12 = __toESM(require("react"));
|
|
1617
|
+
var import_editor_ui4 = require("@elementor/editor-ui");
|
|
1618
|
+
var import_icons7 = require("@elementor/icons");
|
|
1619
|
+
var import_ui8 = require("@elementor/ui");
|
|
1620
|
+
var import_i18n10 = require("@wordpress/i18n");
|
|
1621
|
+
var openEditModeDialog = (lockedBy) => {
|
|
1622
|
+
(0, import_editor_ui4.openDialog)({
|
|
1623
|
+
component: /* @__PURE__ */ React12.createElement(EditModeDialog, { lockedBy })
|
|
1624
|
+
});
|
|
1625
|
+
};
|
|
1626
|
+
var EditModeDialog = ({ lockedBy }) => {
|
|
1627
|
+
const content = (0, import_i18n10.__)("%s is currently editing this document", "elementor").replace("%s", lockedBy);
|
|
1628
|
+
return /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(import_ui8.DialogHeader, { logo: false }, /* @__PURE__ */ React12.createElement(import_ui8.Box, { display: "flex", alignItems: "center", gap: 1 }, /* @__PURE__ */ React12.createElement(import_ui8.Icon, { color: "secondary" }, /* @__PURE__ */ React12.createElement(import_icons7.InfoCircleFilledIcon, { fontSize: "medium" })), /* @__PURE__ */ React12.createElement(import_ui8.Typography, { variant: "subtitle1" }, content))), /* @__PURE__ */ React12.createElement(import_ui8.DialogContent, null, /* @__PURE__ */ React12.createElement(import_ui8.Stack, { spacing: 2, direction: "column" }, /* @__PURE__ */ React12.createElement(import_ui8.Typography, { variant: "body2" }, (0, import_i18n10.__)(
|
|
1629
|
+
"You can wait for them to finish or reach out to coordinate your changes together.",
|
|
1630
|
+
"elementor"
|
|
1631
|
+
)), /* @__PURE__ */ React12.createElement(import_ui8.DialogActions, null, /* @__PURE__ */ React12.createElement(import_ui8.Button, { color: "secondary", variant: "contained", onClick: import_editor_ui4.closeDialog }, (0, import_i18n10.__)("Close", "elementor"))))));
|
|
1632
|
+
};
|
|
1633
|
+
|
|
1634
|
+
// src/components/overridable-props/overridable-prop-control.tsx
|
|
1635
|
+
var React13 = __toESM(require("react"));
|
|
1636
|
+
var import_editor_controls = require("@elementor/editor-controls");
|
|
1637
|
+
var import_editor_editing_panel = require("@elementor/editor-editing-panel");
|
|
1638
|
+
var import_store29 = require("@elementor/store");
|
|
1639
|
+
|
|
1640
|
+
// src/prop-types/component-overridable-prop-type.ts
|
|
1641
|
+
var import_editor_props = require("@elementor/editor-props");
|
|
1642
|
+
var import_schema2 = require("@elementor/schema");
|
|
1643
|
+
var componentOverridablePropTypeUtil = (0, import_editor_props.createPropUtils)(
|
|
1644
|
+
"overridable",
|
|
1645
|
+
import_schema2.z.object({
|
|
1646
|
+
override_key: import_schema2.z.string(),
|
|
1647
|
+
origin_value: import_schema2.z.object({
|
|
1648
|
+
$$type: import_schema2.z.string(),
|
|
1649
|
+
value: import_schema2.z.unknown()
|
|
1650
|
+
}).nullable()
|
|
1651
|
+
})
|
|
1652
|
+
);
|
|
1653
|
+
|
|
1654
|
+
// src/store/actions/update-overridable-prop-origin-value.ts
|
|
1655
|
+
var import_store27 = require("@elementor/store");
|
|
1656
|
+
function updateOverridablePropOriginValue(componentId, propValue) {
|
|
1657
|
+
const overridableProps = selectOverridableProps((0, import_store27.__getState)(), componentId);
|
|
1658
|
+
if (!overridableProps) {
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1661
|
+
const existingOverridableProp = overridableProps.props[propValue.override_key];
|
|
1662
|
+
if (!existingOverridableProp) {
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
const newOverridableProps = {
|
|
1666
|
+
...overridableProps,
|
|
1667
|
+
props: {
|
|
1668
|
+
...overridableProps.props,
|
|
1669
|
+
[existingOverridableProp.overrideKey]: {
|
|
1670
|
+
...existingOverridableProp,
|
|
1671
|
+
originValue: propValue.origin_value
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
};
|
|
1675
|
+
(0, import_store27.__dispatch)(
|
|
1676
|
+
slice.actions.setOverridableProps({
|
|
1677
|
+
componentId,
|
|
1678
|
+
overridableProps: newOverridableProps
|
|
1679
|
+
})
|
|
1680
|
+
);
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
// src/components/overridable-props/overridable-prop-control.tsx
|
|
1684
|
+
function OverridablePropControl({
|
|
1685
|
+
OriginalControl,
|
|
1686
|
+
...props
|
|
1687
|
+
}) {
|
|
1688
|
+
const { elementType } = (0, import_editor_editing_panel.useElement)();
|
|
1689
|
+
const { value, bind, setValue, placeholder, ...propContext } = (0, import_editor_controls.useBoundProp)(componentOverridablePropTypeUtil);
|
|
1690
|
+
const componentId = selectCurrentComponentId((0, import_store29.__getState)());
|
|
1691
|
+
if (!componentId) {
|
|
1692
|
+
throw new Error("Component ID is required");
|
|
1693
|
+
}
|
|
1694
|
+
if (!value?.override_key) {
|
|
1695
|
+
throw new Error("Override key is required");
|
|
1696
|
+
}
|
|
1697
|
+
const setOverridableValue = (newValue) => {
|
|
1698
|
+
const propValue = {
|
|
1699
|
+
...value,
|
|
1700
|
+
origin_value: newValue[bind]
|
|
1701
|
+
};
|
|
1702
|
+
setValue(propValue);
|
|
1703
|
+
updateOverridablePropOriginValue(componentId, propValue);
|
|
1704
|
+
};
|
|
1705
|
+
const propType = (0, import_editor_editing_panel.createTopLevelObjectType)({
|
|
1706
|
+
schema: {
|
|
1707
|
+
[bind]: elementType.propsSchema[bind]
|
|
1708
|
+
}
|
|
1709
|
+
});
|
|
1710
|
+
const objectPlaceholder = placeholder ? { [bind]: placeholder } : void 0;
|
|
1711
|
+
return /* @__PURE__ */ React13.createElement(
|
|
1712
|
+
import_editor_controls.PropProvider,
|
|
1713
|
+
{
|
|
1714
|
+
...propContext,
|
|
1715
|
+
propType,
|
|
1716
|
+
setValue: setOverridableValue,
|
|
1717
|
+
value: { [bind]: value.origin_value },
|
|
1718
|
+
placeholder: objectPlaceholder
|
|
320
1719
|
},
|
|
321
|
-
|
|
322
|
-
)
|
|
1720
|
+
/* @__PURE__ */ React13.createElement(import_editor_controls.PropKeyProvider, { bind }, /* @__PURE__ */ React13.createElement(import_editor_controls.ControlReplacementsProvider, { replacements: [] }, /* @__PURE__ */ React13.createElement(OriginalControl, { ...props })))
|
|
1721
|
+
);
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
// src/components/overridable-props/overridable-prop-indicator.tsx
|
|
1725
|
+
var React16 = __toESM(require("react"));
|
|
1726
|
+
var import_editor_controls2 = require("@elementor/editor-controls");
|
|
1727
|
+
var import_editor_documents9 = require("@elementor/editor-documents");
|
|
1728
|
+
var import_editor_editing_panel2 = require("@elementor/editor-editing-panel");
|
|
1729
|
+
var import_editor_elements5 = require("@elementor/editor-elements");
|
|
1730
|
+
var import_store35 = require("@elementor/store");
|
|
1731
|
+
var import_ui11 = require("@elementor/ui");
|
|
1732
|
+
var import_i18n14 = require("@wordpress/i18n");
|
|
1733
|
+
|
|
1734
|
+
// src/store/actions/set-overridable-prop.ts
|
|
1735
|
+
var import_store31 = require("@elementor/store");
|
|
1736
|
+
var import_utils4 = require("@elementor/utils");
|
|
1737
|
+
var import_i18n11 = require("@wordpress/i18n");
|
|
1738
|
+
function setOverridableProp({
|
|
1739
|
+
componentId,
|
|
1740
|
+
overrideKey,
|
|
1741
|
+
elementId,
|
|
1742
|
+
label,
|
|
1743
|
+
groupId,
|
|
1744
|
+
propKey,
|
|
1745
|
+
elType,
|
|
1746
|
+
widgetType,
|
|
1747
|
+
originValue
|
|
1748
|
+
}) {
|
|
1749
|
+
const overridableProps = selectOverridableProps((0, import_store31.__getState)(), componentId);
|
|
1750
|
+
if (!overridableProps) {
|
|
1751
|
+
return;
|
|
1752
|
+
}
|
|
1753
|
+
const existingOverridableProp = overrideKey ? overridableProps.props[overrideKey] : null;
|
|
1754
|
+
const duplicatedTargetProps = Object.values(overridableProps.props).filter(
|
|
1755
|
+
(prop) => prop.elementId === elementId && prop.propKey === propKey && prop !== existingOverridableProp
|
|
1756
|
+
);
|
|
1757
|
+
const { props: prevProps, groups: prevGroups } = { ...overridableProps };
|
|
1758
|
+
const { groups: updatedGroups, currentGroupId } = getUpdatedGroups(
|
|
1759
|
+
prevGroups,
|
|
1760
|
+
groupId || existingOverridableProp?.groupId
|
|
1761
|
+
);
|
|
1762
|
+
const overridableProp = {
|
|
1763
|
+
overrideKey: existingOverridableProp?.overrideKey || (0, import_utils4.generateUniqueId)("prop"),
|
|
1764
|
+
label,
|
|
1765
|
+
elementId,
|
|
1766
|
+
propKey,
|
|
1767
|
+
widgetType,
|
|
1768
|
+
elType,
|
|
1769
|
+
originValue,
|
|
1770
|
+
groupId: currentGroupId
|
|
1771
|
+
};
|
|
1772
|
+
const { props: propsWithoutDuplicates, groups: groupsWithoutDuplicates } = removeProps({
|
|
1773
|
+
props: prevProps,
|
|
1774
|
+
groups: updatedGroups,
|
|
1775
|
+
propsToRemove: duplicatedTargetProps
|
|
1776
|
+
});
|
|
1777
|
+
const props = {
|
|
1778
|
+
...propsWithoutDuplicates,
|
|
1779
|
+
[overridableProp.overrideKey]: overridableProp
|
|
1780
|
+
};
|
|
1781
|
+
const groups = {
|
|
1782
|
+
items: {
|
|
1783
|
+
...groupsWithoutDuplicates.items,
|
|
1784
|
+
[currentGroupId]: getGroupWithProp(groupsWithoutDuplicates, currentGroupId, overridableProp)
|
|
1785
|
+
},
|
|
1786
|
+
order: groupsWithoutDuplicates.order.includes(currentGroupId) ? groupsWithoutDuplicates.order : [...groupsWithoutDuplicates.order, currentGroupId]
|
|
1787
|
+
};
|
|
1788
|
+
const isChangingGroups = existingOverridableProp && existingOverridableProp.groupId !== currentGroupId;
|
|
1789
|
+
if (isChangingGroups) {
|
|
1790
|
+
groups.items[existingOverridableProp.groupId] = getGroupWithoutProp(
|
|
1791
|
+
groupsWithoutDuplicates,
|
|
1792
|
+
existingOverridableProp.groupId,
|
|
1793
|
+
overridableProp
|
|
1794
|
+
);
|
|
1795
|
+
}
|
|
1796
|
+
(0, import_store31.__dispatch)(
|
|
1797
|
+
slice.actions.setOverridableProps({
|
|
1798
|
+
componentId,
|
|
1799
|
+
overridableProps: {
|
|
1800
|
+
props,
|
|
1801
|
+
groups
|
|
1802
|
+
}
|
|
1803
|
+
})
|
|
1804
|
+
);
|
|
1805
|
+
return overridableProp;
|
|
1806
|
+
}
|
|
1807
|
+
function getUpdatedGroups(groups, groupId) {
|
|
1808
|
+
if (!groupId) {
|
|
1809
|
+
if (groups.order.length > 0) {
|
|
1810
|
+
return { groups, currentGroupId: groups.order[0] };
|
|
1811
|
+
}
|
|
1812
|
+
return addNewGroup(groups);
|
|
1813
|
+
}
|
|
1814
|
+
if (!groups.items[groupId]) {
|
|
1815
|
+
return addNewGroup(groups, groupId);
|
|
1816
|
+
}
|
|
1817
|
+
return { groups, currentGroupId: groupId };
|
|
1818
|
+
}
|
|
1819
|
+
function addNewGroup(groups, groupId) {
|
|
1820
|
+
const currentGroupId = groupId || (0, import_utils4.generateUniqueId)("group");
|
|
1821
|
+
const updatedGroups = {
|
|
1822
|
+
...groups,
|
|
1823
|
+
items: {
|
|
1824
|
+
...groups.items,
|
|
1825
|
+
[currentGroupId]: {
|
|
1826
|
+
id: currentGroupId,
|
|
1827
|
+
label: (0, import_i18n11.__)("Default", "elementor"),
|
|
1828
|
+
props: []
|
|
1829
|
+
}
|
|
1830
|
+
},
|
|
1831
|
+
order: [...groups.order, currentGroupId]
|
|
1832
|
+
};
|
|
1833
|
+
return { groups: updatedGroups, currentGroupId };
|
|
1834
|
+
}
|
|
1835
|
+
function getGroupWithProp(groups, groupId, overridableProp) {
|
|
1836
|
+
const group = { ...groups.items[groupId] };
|
|
1837
|
+
if (!group.props.includes(overridableProp.overrideKey)) {
|
|
1838
|
+
group.props = [...group.props, overridableProp.overrideKey];
|
|
1839
|
+
}
|
|
1840
|
+
return group;
|
|
1841
|
+
}
|
|
1842
|
+
function getGroupWithoutProp(groups, groupId, overridableProp) {
|
|
1843
|
+
const group = { ...groups.items[groupId] };
|
|
1844
|
+
if (group) {
|
|
1845
|
+
group.props = group.props.filter((key) => key !== overridableProp.overrideKey);
|
|
1846
|
+
}
|
|
1847
|
+
return group;
|
|
1848
|
+
}
|
|
1849
|
+
function removeProps({
|
|
1850
|
+
props,
|
|
1851
|
+
groups,
|
|
1852
|
+
propsToRemove
|
|
1853
|
+
}) {
|
|
1854
|
+
const allProps = Object.fromEntries(
|
|
1855
|
+
Object.entries(props).filter(([, prop]) => !propsToRemove.includes(prop))
|
|
1856
|
+
);
|
|
1857
|
+
const overrideKeysToRemove = propsToRemove.map((prop) => prop.overrideKey);
|
|
1858
|
+
const allGroupItems = Object.fromEntries(
|
|
1859
|
+
Object.entries(groups.items).map(([groupId, group]) => [
|
|
1860
|
+
groupId,
|
|
1861
|
+
{
|
|
1862
|
+
...group,
|
|
1863
|
+
props: group.props.filter((prop) => !overrideKeysToRemove.includes(prop))
|
|
1864
|
+
}
|
|
1865
|
+
])
|
|
1866
|
+
);
|
|
1867
|
+
return {
|
|
1868
|
+
props: allProps,
|
|
1869
|
+
groups: {
|
|
1870
|
+
items: allGroupItems,
|
|
1871
|
+
order: groups.order.filter((groupId) => !overrideKeysToRemove.includes(groupId))
|
|
1872
|
+
}
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1876
|
+
// src/components/overridable-props/indicator.tsx
|
|
1877
|
+
var React14 = __toESM(require("react"));
|
|
1878
|
+
var import_react9 = require("react");
|
|
1879
|
+
var import_icons8 = require("@elementor/icons");
|
|
1880
|
+
var import_ui9 = require("@elementor/ui");
|
|
1881
|
+
var import_i18n12 = require("@wordpress/i18n");
|
|
1882
|
+
var SIZE = "tiny";
|
|
1883
|
+
var IconContainer = (0, import_ui9.styled)(import_ui9.Box)`
|
|
1884
|
+
pointer-events: none;
|
|
1885
|
+
opacity: 0;
|
|
1886
|
+
transition: opacity 0.2s ease-in-out;
|
|
1887
|
+
|
|
1888
|
+
& > svg {
|
|
1889
|
+
position: absolute;
|
|
1890
|
+
top: 50%;
|
|
1891
|
+
left: 50%;
|
|
1892
|
+
transform: translate( -50%, -50% );
|
|
1893
|
+
width: 10px;
|
|
1894
|
+
height: 10px;
|
|
1895
|
+
fill: ${({ theme }) => theme.palette.primary.contrastText};
|
|
1896
|
+
stroke: ${({ theme }) => theme.palette.primary.contrastText};
|
|
1897
|
+
stroke-width: 2px;
|
|
1898
|
+
}
|
|
1899
|
+
`;
|
|
1900
|
+
var Content = (0, import_ui9.styled)(import_ui9.Box)`
|
|
1901
|
+
position: relative;
|
|
1902
|
+
display: flex;
|
|
1903
|
+
align-items: center;
|
|
1904
|
+
justify-content: center;
|
|
1905
|
+
cursor: pointer;
|
|
1906
|
+
width: 16px;
|
|
1907
|
+
height: 16px;
|
|
1908
|
+
margin-inline: ${({ theme }) => theme.spacing(0.5)};
|
|
1909
|
+
|
|
1910
|
+
&:before {
|
|
1911
|
+
content: '';
|
|
1912
|
+
display: block;
|
|
1913
|
+
position: absolute;
|
|
1914
|
+
top: 50%;
|
|
1915
|
+
left: 50%;
|
|
1916
|
+
transform: translate( -50%, -50% ) rotate( 45deg );
|
|
1917
|
+
width: 5px;
|
|
1918
|
+
height: 5px;
|
|
1919
|
+
border-radius: 1px;
|
|
1920
|
+
background-color: ${({ theme }) => theme.palette.primary.main};
|
|
1921
|
+
transition: all 0.1s ease-in-out;
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
&:hover,
|
|
1925
|
+
&.enlarged {
|
|
1926
|
+
&:before {
|
|
1927
|
+
width: 12px;
|
|
1928
|
+
height: 12px;
|
|
1929
|
+
border-radius: 2px;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
.icon {
|
|
1933
|
+
opacity: 1;
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
`;
|
|
1937
|
+
var Indicator = (0, import_react9.forwardRef)(({ isOpen, isOverridable, ...props }, ref) => /* @__PURE__ */ React14.createElement(Content, { ref, ...props, className: isOpen || isOverridable ? "enlarged" : "" }, /* @__PURE__ */ React14.createElement(
|
|
1938
|
+
IconContainer,
|
|
1939
|
+
{
|
|
1940
|
+
className: "icon",
|
|
1941
|
+
"aria-label": isOverridable ? (0, import_i18n12.__)("Overridable property", "elementor") : (0, import_i18n12.__)("Make prop overridable", "elementor")
|
|
1942
|
+
},
|
|
1943
|
+
isOverridable ? /* @__PURE__ */ React14.createElement(import_icons8.CheckIcon, { fontSize: SIZE }) : /* @__PURE__ */ React14.createElement(import_icons8.PlusIcon, { fontSize: SIZE })
|
|
1944
|
+
)));
|
|
1945
|
+
|
|
1946
|
+
// src/components/overridable-props/overridable-prop-form.tsx
|
|
1947
|
+
var React15 = __toESM(require("react"));
|
|
1948
|
+
var import_react10 = require("react");
|
|
1949
|
+
var import_editor_ui5 = require("@elementor/editor-ui");
|
|
1950
|
+
var import_ui10 = require("@elementor/ui");
|
|
1951
|
+
var import_i18n13 = require("@wordpress/i18n");
|
|
1952
|
+
var SIZE2 = "tiny";
|
|
1953
|
+
var DEFAULT_GROUP = { value: null, label: (0, import_i18n13.__)("Default", "elementor") };
|
|
1954
|
+
function OverridablePropForm({ onSubmit, groups, currentValue }) {
|
|
1955
|
+
const [propLabel, setPropLabel] = (0, import_react10.useState)(currentValue?.label ?? null);
|
|
1956
|
+
const [group, setGroup] = (0, import_react10.useState)(currentValue?.groupId ?? groups?.[0]?.value ?? null);
|
|
1957
|
+
const name = (0, import_i18n13.__)("Name", "elementor");
|
|
1958
|
+
const groupName = (0, import_i18n13.__)("Group Name", "elementor");
|
|
1959
|
+
const isCreate = currentValue === void 0;
|
|
1960
|
+
const title = isCreate ? (0, import_i18n13.__)("Create new property", "elementor") : (0, import_i18n13.__)("Update property", "elementor");
|
|
1961
|
+
const ctaLabel = isCreate ? (0, import_i18n13.__)("Create", "elementor") : (0, import_i18n13.__)("Update", "elementor");
|
|
1962
|
+
return /* @__PURE__ */ React15.createElement(import_editor_ui5.Form, { onSubmit: () => onSubmit({ label: propLabel ?? "", group }) }, /* @__PURE__ */ React15.createElement(import_ui10.Stack, { alignItems: "start", width: "268px" }, /* @__PURE__ */ React15.createElement(
|
|
1963
|
+
import_ui10.Stack,
|
|
1964
|
+
{
|
|
1965
|
+
direction: "row",
|
|
1966
|
+
alignItems: "center",
|
|
1967
|
+
py: 1,
|
|
1968
|
+
px: 1.5,
|
|
1969
|
+
sx: { columnGap: 0.5, borderBottom: "1px solid", borderColor: "divider", width: "100%", mb: 1.5 }
|
|
1970
|
+
},
|
|
1971
|
+
/* @__PURE__ */ React15.createElement(import_ui10.Typography, { variant: "caption", sx: { color: "text.primary", fontWeight: "500", lineHeight: 1 } }, title)
|
|
1972
|
+
), /* @__PURE__ */ React15.createElement(import_ui10.Grid, { container: true, gap: 0.75, alignItems: "start", px: 1.5, mb: 1.5 }, /* @__PURE__ */ React15.createElement(import_ui10.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React15.createElement(import_ui10.FormLabel, { size: "tiny" }, name)), /* @__PURE__ */ React15.createElement(import_ui10.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React15.createElement(
|
|
1973
|
+
import_ui10.TextField,
|
|
1974
|
+
{
|
|
1975
|
+
name,
|
|
1976
|
+
size: SIZE2,
|
|
1977
|
+
fullWidth: true,
|
|
1978
|
+
placeholder: (0, import_i18n13.__)("Enter value", "elementor"),
|
|
1979
|
+
value: propLabel ?? "",
|
|
1980
|
+
onChange: (e) => setPropLabel(e.target.value)
|
|
1981
|
+
}
|
|
1982
|
+
))), /* @__PURE__ */ React15.createElement(import_ui10.Grid, { container: true, gap: 0.75, alignItems: "start", px: 1.5, mb: 1.5 }, /* @__PURE__ */ React15.createElement(import_ui10.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React15.createElement(import_ui10.FormLabel, { size: "tiny" }, groupName)), /* @__PURE__ */ React15.createElement(import_ui10.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React15.createElement(
|
|
1983
|
+
import_ui10.Select,
|
|
1984
|
+
{
|
|
1985
|
+
name: groupName,
|
|
1986
|
+
size: SIZE2,
|
|
1987
|
+
fullWidth: true,
|
|
1988
|
+
value: group ?? null,
|
|
1989
|
+
onChange: setGroup,
|
|
1990
|
+
displayEmpty: true,
|
|
1991
|
+
renderValue: (selectedValue) => {
|
|
1992
|
+
if (!selectedValue || selectedValue === "") {
|
|
1993
|
+
const [firstGroup = DEFAULT_GROUP] = groups ?? [];
|
|
1994
|
+
return firstGroup.label;
|
|
1995
|
+
}
|
|
1996
|
+
return groups?.find(({ value }) => value === selectedValue)?.label ?? selectedValue;
|
|
1997
|
+
}
|
|
1998
|
+
},
|
|
1999
|
+
(groups ?? [DEFAULT_GROUP]).map(({ label: groupLabel, ...props }) => /* @__PURE__ */ React15.createElement(import_editor_ui5.MenuListItem, { key: props.value, ...props, value: props.value ?? "" }, groupLabel))
|
|
2000
|
+
))), /* @__PURE__ */ React15.createElement(import_ui10.Stack, { direction: "row", justifyContent: "flex-end", alignSelf: "end", mt: 1.5, py: 1, px: 1.5 }, /* @__PURE__ */ React15.createElement(import_ui10.Button, { type: "submit", disabled: !propLabel, variant: "contained", color: "primary", size: "small" }, ctaLabel))));
|
|
2001
|
+
}
|
|
2002
|
+
|
|
2003
|
+
// src/components/overridable-props/utils/get-overridable-prop.ts
|
|
2004
|
+
var import_store33 = require("@elementor/store");
|
|
2005
|
+
function getOverridableProp({
|
|
2006
|
+
componentId,
|
|
2007
|
+
overrideKey
|
|
2008
|
+
}) {
|
|
2009
|
+
const overridableProps = selectOverridableProps((0, import_store33.__getState)(), componentId);
|
|
2010
|
+
if (!overridableProps) {
|
|
2011
|
+
return void 0;
|
|
2012
|
+
}
|
|
2013
|
+
return overridableProps.props[overrideKey];
|
|
2014
|
+
}
|
|
2015
|
+
|
|
2016
|
+
// src/components/overridable-props/overridable-prop-indicator.tsx
|
|
2017
|
+
var FORBIDDEN_KEYS = ["_cssid", "attributes"];
|
|
2018
|
+
function OverridablePropIndicator() {
|
|
2019
|
+
const { bind } = (0, import_editor_controls2.useBoundProp)();
|
|
2020
|
+
const currentDocument = (0, import_editor_documents9.getV1CurrentDocument)();
|
|
2021
|
+
if (currentDocument.config.type !== COMPONENT_DOCUMENT_TYPE || !currentDocument.id) {
|
|
2022
|
+
return null;
|
|
2023
|
+
}
|
|
2024
|
+
if (!isPropAllowed(bind)) {
|
|
2025
|
+
return null;
|
|
2026
|
+
}
|
|
2027
|
+
const overridableProps = selectOverridableProps((0, import_store35.__getState)(), currentDocument.id);
|
|
2028
|
+
return /* @__PURE__ */ React16.createElement(Content2, { componentId: currentDocument.id, overridableProps });
|
|
2029
|
+
}
|
|
2030
|
+
function Content2({ componentId, overridableProps }) {
|
|
2031
|
+
const {
|
|
2032
|
+
element: { id: elementId },
|
|
2033
|
+
elementType
|
|
2034
|
+
} = (0, import_editor_editing_panel2.useElement)();
|
|
2035
|
+
const { value, bind, propType } = (0, import_editor_controls2.useBoundProp)();
|
|
2036
|
+
const { value: overridableValue, setValue: setOverridableValue } = (0, import_editor_controls2.useBoundProp)(componentOverridablePropTypeUtil);
|
|
2037
|
+
const popupState = (0, import_ui11.usePopupState)({
|
|
2038
|
+
variant: "popover"
|
|
2039
|
+
});
|
|
2040
|
+
const triggerProps = (0, import_ui11.bindTrigger)(popupState);
|
|
2041
|
+
const popoverProps = (0, import_ui11.bindPopover)(popupState);
|
|
2042
|
+
const { elType } = (0, import_editor_elements5.getWidgetsCache)()?.[elementType.key] ?? { elType: "widget" };
|
|
2043
|
+
const handleSubmit = ({ label, group }) => {
|
|
2044
|
+
const originValue = !overridableValue ? value ?? propType.default : overridableValue?.origin_value ?? {};
|
|
2045
|
+
const overridablePropConfig = setOverridableProp({
|
|
2046
|
+
componentId,
|
|
2047
|
+
overrideKey: overridableValue?.override_key ?? null,
|
|
2048
|
+
elementId,
|
|
2049
|
+
label,
|
|
2050
|
+
groupId: group,
|
|
2051
|
+
propKey: bind,
|
|
2052
|
+
elType: elType ?? "widget",
|
|
2053
|
+
widgetType: elementType.key,
|
|
2054
|
+
originValue
|
|
2055
|
+
});
|
|
2056
|
+
if (!overridableValue && overridablePropConfig) {
|
|
2057
|
+
setOverridableValue({
|
|
2058
|
+
override_key: overridablePropConfig.overrideKey,
|
|
2059
|
+
origin_value: originValue
|
|
2060
|
+
});
|
|
2061
|
+
}
|
|
2062
|
+
popupState.close();
|
|
2063
|
+
};
|
|
2064
|
+
const overridableConfig = overridableValue ? getOverridableProp({ componentId, overrideKey: overridableValue.override_key }) : void 0;
|
|
2065
|
+
return /* @__PURE__ */ React16.createElement(React16.Fragment, null, /* @__PURE__ */ React16.createElement(import_ui11.Tooltip, { placement: "top", title: (0, import_i18n14.__)("Override Property", "elementor") }, /* @__PURE__ */ React16.createElement(Indicator, { ...triggerProps, isOpen: !!popoverProps.open, isOverridable: !!overridableValue })), /* @__PURE__ */ React16.createElement(
|
|
2066
|
+
import_ui11.Popover,
|
|
2067
|
+
{
|
|
2068
|
+
disableScrollLock: true,
|
|
2069
|
+
anchorOrigin: {
|
|
2070
|
+
vertical: "bottom",
|
|
2071
|
+
horizontal: "right"
|
|
2072
|
+
},
|
|
2073
|
+
transformOrigin: {
|
|
2074
|
+
vertical: "top",
|
|
2075
|
+
horizontal: "right"
|
|
2076
|
+
},
|
|
2077
|
+
PaperProps: {
|
|
2078
|
+
sx: { my: 2.5 }
|
|
2079
|
+
},
|
|
2080
|
+
...popoverProps
|
|
2081
|
+
},
|
|
2082
|
+
/* @__PURE__ */ React16.createElement(
|
|
2083
|
+
OverridablePropForm,
|
|
2084
|
+
{
|
|
2085
|
+
onSubmit: handleSubmit,
|
|
2086
|
+
groups: overridableProps?.groups.order.map((groupId) => ({
|
|
2087
|
+
value: groupId,
|
|
2088
|
+
label: overridableProps.groups.items[groupId].label
|
|
2089
|
+
})),
|
|
2090
|
+
currentValue: overridableConfig
|
|
2091
|
+
}
|
|
2092
|
+
)
|
|
2093
|
+
));
|
|
2094
|
+
}
|
|
2095
|
+
function isPropAllowed(bind) {
|
|
2096
|
+
return !FORBIDDEN_KEYS.includes(bind);
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
// src/mcp/index.ts
|
|
2100
|
+
var import_editor_mcp2 = require("@elementor/editor-mcp");
|
|
2101
|
+
|
|
2102
|
+
// src/mcp/save-as-component-tool.ts
|
|
2103
|
+
var import_editor_elements6 = require("@elementor/editor-elements");
|
|
2104
|
+
var import_editor_mcp = require("@elementor/editor-mcp");
|
|
2105
|
+
var import_schema3 = require("@elementor/schema");
|
|
2106
|
+
var InputSchema = {
|
|
2107
|
+
element_id: import_schema3.z.string().describe(
|
|
2108
|
+
'The unique identifier of the element to save as a component. Use the "list-elements" tool to find available element IDs in the current document.'
|
|
2109
|
+
),
|
|
2110
|
+
component_name: import_schema3.z.string().describe("The name for the new component. Should be descriptive and unique among existing components.")
|
|
2111
|
+
};
|
|
2112
|
+
var OutputSchema = {
|
|
2113
|
+
message: import_schema3.z.string().optional().describe("Additional information about the operation result"),
|
|
2114
|
+
component_uid: import_schema3.z.string().optional().describe("The unique identifier of the newly created component (only present on success)")
|
|
2115
|
+
};
|
|
2116
|
+
var VALID_ELEMENT_TYPES = ["e-div-block", "e-flexbox", "e-tabs"];
|
|
2117
|
+
var ERROR_MESSAGES = {
|
|
2118
|
+
ELEMENT_NOT_FOUND: "Element not found. Use 'list-elements' to get valid element IDs.",
|
|
2119
|
+
ELEMENT_NOT_ONE_OF_TYPES: `Element is not one of the following types: ${VALID_ELEMENT_TYPES.join(", ")}`,
|
|
2120
|
+
ELEMENT_IS_LOCKED: "Cannot save a locked element as a component."
|
|
2121
|
+
};
|
|
2122
|
+
var handleSaveAsComponent = async (params) => {
|
|
2123
|
+
const { element_id: elementId, component_name: componentName } = params;
|
|
2124
|
+
const container = (0, import_editor_elements6.getContainer)(elementId);
|
|
2125
|
+
if (!container) {
|
|
2126
|
+
throw new Error(ERROR_MESSAGES.ELEMENT_NOT_FOUND);
|
|
2127
|
+
}
|
|
2128
|
+
const elType = container.model.get("elType");
|
|
2129
|
+
if (!VALID_ELEMENT_TYPES.includes(elType)) {
|
|
2130
|
+
throw new Error(ERROR_MESSAGES.ELEMENT_NOT_ONE_OF_TYPES);
|
|
2131
|
+
}
|
|
2132
|
+
const element = container.model.toJSON({ remove: ["default"] });
|
|
2133
|
+
if (element?.isLocked) {
|
|
2134
|
+
throw new Error(ERROR_MESSAGES.ELEMENT_IS_LOCKED);
|
|
2135
|
+
}
|
|
2136
|
+
const uid = createUnpublishedComponent(componentName, element, null);
|
|
2137
|
+
return {
|
|
2138
|
+
status: "ok",
|
|
2139
|
+
message: `Component "${componentName}" created successfully.`,
|
|
2140
|
+
component_uid: uid
|
|
2141
|
+
};
|
|
2142
|
+
};
|
|
2143
|
+
var initSaveAsComponentTool = () => {
|
|
2144
|
+
return (0, import_editor_mcp.getMCPByDomain)("components").addTool({
|
|
2145
|
+
name: "save-as-component",
|
|
2146
|
+
schema: InputSchema,
|
|
2147
|
+
outputSchema: OutputSchema,
|
|
2148
|
+
description: `Save an existing element as a reusable component in the Elementor editor.
|
|
2149
|
+
|
|
2150
|
+
## When NOT to use this tool:
|
|
2151
|
+
- Do not use for elements that are already components (widgetType: 'e-component').
|
|
2152
|
+
- Do not use for locked elements.
|
|
2153
|
+
- Do not guess element IDs. Always use "list-elements" first to get valid IDs.
|
|
2154
|
+
|
|
2155
|
+
## Prerequisites:
|
|
2156
|
+
- **Verify element type**: Ensure the element is not already a component (widgetType should not be 'e-component').
|
|
2157
|
+
- **Check if element is unlocked**: Locked elements cannot be saved as components.
|
|
2158
|
+
- **Check that the element is one of the following types**: ${VALID_ELEMENT_TYPES.join(", ")}
|
|
2159
|
+
|
|
2160
|
+
## Required parameters:
|
|
2161
|
+
- **element_id**: The unique ID of the element to save.
|
|
2162
|
+
- **component_name**: A descriptive name for the component (2-50 characters).
|
|
2163
|
+
|
|
2164
|
+
## Example tool call:
|
|
2165
|
+
\`\`\`json
|
|
2166
|
+
{ "element_id": "abc123", "component_name": "Hero Section" }
|
|
2167
|
+
\`\`\`
|
|
2168
|
+
`,
|
|
2169
|
+
handler: handleSaveAsComponent
|
|
2170
|
+
});
|
|
2171
|
+
};
|
|
2172
|
+
|
|
2173
|
+
// src/mcp/index.ts
|
|
2174
|
+
function initMcp() {
|
|
2175
|
+
const { setMCPDescription } = (0, import_editor_mcp2.getMCPByDomain)("components");
|
|
2176
|
+
setMCPDescription(
|
|
2177
|
+
`Elementor Editor Components MCP - Tools for creating and managing reusable components.
|
|
2178
|
+
Components are reusable blocks of content that can be used multiple times across the pages, its a widget which contains a set of elements and styles.`
|
|
2179
|
+
);
|
|
2180
|
+
initSaveAsComponentTool();
|
|
2181
|
+
}
|
|
2182
|
+
|
|
2183
|
+
// src/populate-store.ts
|
|
2184
|
+
var import_react11 = require("react");
|
|
2185
|
+
var import_store37 = require("@elementor/store");
|
|
2186
|
+
function PopulateStore() {
|
|
2187
|
+
(0, import_react11.useEffect)(() => {
|
|
2188
|
+
(0, import_store37.__dispatch)(loadComponents());
|
|
2189
|
+
}, []);
|
|
2190
|
+
return null;
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
// src/store/actions/remove-component-styles.ts
|
|
2194
|
+
var import_store38 = require("@elementor/store");
|
|
2195
|
+
function removeComponentStyles(id) {
|
|
2196
|
+
apiClient.invalidateComponentConfigCache(id);
|
|
2197
|
+
(0, import_store38.__dispatch)(slice.actions.removeStyles({ id }));
|
|
2198
|
+
}
|
|
2199
|
+
|
|
2200
|
+
// src/store/components-styles-provider.ts
|
|
2201
|
+
var import_editor_styles_repository = require("@elementor/editor-styles-repository");
|
|
2202
|
+
var import_store40 = require("@elementor/store");
|
|
2203
|
+
var componentsStylesProvider = (0, import_editor_styles_repository.createStylesProvider)({
|
|
2204
|
+
key: "components-styles",
|
|
2205
|
+
priority: 100,
|
|
2206
|
+
subscribe: (cb) => (0, import_store40.__subscribeWithSelector)(
|
|
2207
|
+
(state) => state[SLICE_NAME],
|
|
2208
|
+
() => {
|
|
2209
|
+
cb();
|
|
2210
|
+
}
|
|
2211
|
+
),
|
|
2212
|
+
actions: {
|
|
2213
|
+
all: () => {
|
|
2214
|
+
return selectFlatStyles((0, import_store40.__getState)());
|
|
2215
|
+
},
|
|
2216
|
+
get: (id) => {
|
|
2217
|
+
return selectFlatStyles((0, import_store40.__getState)()).find((style) => style.id === id) ?? null;
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2220
|
+
});
|
|
2221
|
+
|
|
2222
|
+
// src/sync/create-components-before-save.ts
|
|
2223
|
+
var import_editor_elements7 = require("@elementor/editor-elements");
|
|
2224
|
+
var import_store42 = require("@elementor/store");
|
|
2225
|
+
async function createComponentsBeforeSave({
|
|
2226
|
+
elements,
|
|
2227
|
+
status
|
|
2228
|
+
}) {
|
|
2229
|
+
const unpublishedComponents = selectUnpublishedComponents((0, import_store42.__getState)());
|
|
2230
|
+
if (!unpublishedComponents.length) {
|
|
2231
|
+
return;
|
|
2232
|
+
}
|
|
2233
|
+
try {
|
|
2234
|
+
const uidToComponentId = await createComponents(unpublishedComponents, status);
|
|
2235
|
+
updateComponentInstances(elements, uidToComponentId);
|
|
2236
|
+
(0, import_store42.__dispatch)(
|
|
2237
|
+
slice.actions.add(
|
|
2238
|
+
unpublishedComponents.map((component) => ({
|
|
2239
|
+
id: uidToComponentId.get(component.uid),
|
|
2240
|
+
name: component.name,
|
|
2241
|
+
uid: component.uid
|
|
2242
|
+
}))
|
|
2243
|
+
)
|
|
2244
|
+
);
|
|
2245
|
+
(0, import_store42.__dispatch)(slice.actions.resetUnpublished());
|
|
2246
|
+
} catch (error) {
|
|
2247
|
+
throw new Error(`Failed to publish components and update component instances: ${error}`);
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
async function createComponents(components, status) {
|
|
2251
|
+
const response = await apiClient.create({
|
|
2252
|
+
status,
|
|
2253
|
+
items: components.map((component) => ({
|
|
2254
|
+
uid: component.uid,
|
|
2255
|
+
title: component.name,
|
|
2256
|
+
elements: component.elements
|
|
2257
|
+
}))
|
|
2258
|
+
});
|
|
2259
|
+
const map = /* @__PURE__ */ new Map();
|
|
2260
|
+
Object.entries(response).forEach(([key, value]) => {
|
|
2261
|
+
map.set(key, value);
|
|
2262
|
+
});
|
|
2263
|
+
return map;
|
|
2264
|
+
}
|
|
2265
|
+
function updateComponentInstances(elements, uidToComponentId) {
|
|
2266
|
+
elements.forEach((element) => {
|
|
2267
|
+
const { shouldUpdate, newComponentId } = shouldUpdateElement(element, uidToComponentId);
|
|
2268
|
+
if (shouldUpdate) {
|
|
2269
|
+
updateElementComponentId(element.id, newComponentId);
|
|
2270
|
+
}
|
|
2271
|
+
if (element.elements) {
|
|
2272
|
+
updateComponentInstances(element.elements, uidToComponentId);
|
|
2273
|
+
}
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
function shouldUpdateElement(element, uidToComponentId) {
|
|
2277
|
+
if (element.widgetType === "e-component") {
|
|
2278
|
+
const currentComponentId = element.settings?.component_instance?.value?.component_id;
|
|
2279
|
+
if (currentComponentId && uidToComponentId.has(currentComponentId)) {
|
|
2280
|
+
return { shouldUpdate: true, newComponentId: uidToComponentId.get(currentComponentId) };
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
return { shouldUpdate: false, newComponentId: null };
|
|
2284
|
+
}
|
|
2285
|
+
function updateElementComponentId(elementId, componentId) {
|
|
2286
|
+
(0, import_editor_elements7.updateElementSettings)({
|
|
2287
|
+
id: elementId,
|
|
2288
|
+
props: {
|
|
2289
|
+
component_instance: {
|
|
2290
|
+
$$type: "component-instance",
|
|
2291
|
+
value: { component_id: componentId }
|
|
2292
|
+
}
|
|
2293
|
+
},
|
|
2294
|
+
withHistory: false
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2297
|
+
|
|
2298
|
+
// src/sync/set-component-overridable-props-settings-before-save.ts
|
|
2299
|
+
var import_store44 = require("@elementor/store");
|
|
2300
|
+
var setComponentOverridablePropsSettingsBeforeSave = ({
|
|
2301
|
+
container
|
|
2302
|
+
}) => {
|
|
2303
|
+
const currentDocument = container.document;
|
|
2304
|
+
if (!currentDocument || currentDocument.config.type !== COMPONENT_DOCUMENT_TYPE) {
|
|
2305
|
+
return;
|
|
2306
|
+
}
|
|
2307
|
+
const overridableProps = selectOverridableProps((0, import_store44.__getState)(), currentDocument.id);
|
|
2308
|
+
if (overridableProps) {
|
|
2309
|
+
container.settings.set("overridable_props", overridableProps);
|
|
2310
|
+
}
|
|
2311
|
+
};
|
|
2312
|
+
|
|
2313
|
+
// src/sync/update-archived-component-before-save.ts
|
|
2314
|
+
var import_editor_notifications = require("@elementor/editor-notifications");
|
|
2315
|
+
var import_store46 = require("@elementor/store");
|
|
2316
|
+
var failedNotification = (message) => ({
|
|
2317
|
+
type: "error",
|
|
2318
|
+
message: `Failed to archive components: ${message}`,
|
|
2319
|
+
id: "failed-archived-components-notification"
|
|
2320
|
+
});
|
|
2321
|
+
var successNotification = (message) => ({
|
|
2322
|
+
type: "success",
|
|
2323
|
+
message: `Successfully archived components: ${message}`,
|
|
2324
|
+
id: "success-archived-components-notification"
|
|
2325
|
+
});
|
|
2326
|
+
var updateArchivedComponentBeforeSave = async () => {
|
|
2327
|
+
try {
|
|
2328
|
+
const archivedComponents = selectArchivedComponents((0, import_store46.__getState)());
|
|
2329
|
+
if (!archivedComponents.length) {
|
|
2330
|
+
return;
|
|
2331
|
+
}
|
|
2332
|
+
const result = await apiClient.updateArchivedComponents(
|
|
2333
|
+
archivedComponents.map((component) => component.id)
|
|
2334
|
+
);
|
|
2335
|
+
const failedIds = result.failedIds.join(", ");
|
|
2336
|
+
const successIds = result.successIds.join(", ");
|
|
2337
|
+
if (failedIds) {
|
|
2338
|
+
(0, import_editor_notifications.notify)(failedNotification(failedIds));
|
|
2339
|
+
}
|
|
2340
|
+
if (successIds) {
|
|
2341
|
+
(0, import_editor_notifications.notify)(successNotification(successIds));
|
|
2342
|
+
}
|
|
2343
|
+
} catch (error) {
|
|
2344
|
+
throw new Error(`Failed to update archived components: ${error}`);
|
|
2345
|
+
}
|
|
2346
|
+
};
|
|
2347
|
+
|
|
2348
|
+
// src/sync/update-components-before-save.ts
|
|
2349
|
+
var import_editor_documents10 = require("@elementor/editor-documents");
|
|
2350
|
+
async function updateComponentsBeforeSave({ status, elements }) {
|
|
2351
|
+
if (status !== "publish") {
|
|
2352
|
+
return;
|
|
2353
|
+
}
|
|
2354
|
+
const componentIds = await getComponentIds(elements);
|
|
2355
|
+
const componentDocumentData = await Promise.all(componentIds.map(getComponentDocumentData));
|
|
2356
|
+
const draftIds = componentDocumentData.filter((document) => !!document).filter(import_editor_documents10.isDocumentDirty).map((document) => document.id);
|
|
2357
|
+
if (draftIds.length === 0) {
|
|
2358
|
+
return;
|
|
2359
|
+
}
|
|
2360
|
+
await apiClient.updateStatuses(draftIds, "publish");
|
|
2361
|
+
draftIds.forEach((id) => invalidateComponentDocumentData(id));
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
// src/sync/before-save.ts
|
|
2365
|
+
var beforeSave = ({ container, status }) => {
|
|
2366
|
+
const elements = container.model.get("elements")?.toJSON() ?? [];
|
|
2367
|
+
return Promise.all([
|
|
2368
|
+
updateArchivedComponentBeforeSave(),
|
|
2369
|
+
createComponentsBeforeSave({ elements, status }),
|
|
2370
|
+
updateComponentsBeforeSave({ elements, status }),
|
|
2371
|
+
setComponentOverridablePropsSettingsBeforeSave({ container })
|
|
2372
|
+
]);
|
|
323
2373
|
};
|
|
324
2374
|
|
|
325
2375
|
// src/init.ts
|
|
326
2376
|
function init() {
|
|
2377
|
+
import_editor_styles_repository2.stylesRepository.register(componentsStylesProvider);
|
|
2378
|
+
(0, import_store48.__registerSlice)(slice);
|
|
2379
|
+
(0, import_editor_canvas6.registerElementType)(
|
|
2380
|
+
TYPE,
|
|
2381
|
+
(options) => createComponentType({ ...options, showLockedByModal: openEditModeDialog })
|
|
2382
|
+
);
|
|
2383
|
+
(0, import_editor_v1_adapters7.registerDataHook)("dependency", "editor/documents/close", (args) => {
|
|
2384
|
+
const document = (0, import_editor_documents11.getV1CurrentDocument)();
|
|
2385
|
+
if (document.config.type === COMPONENT_DOCUMENT_TYPE) {
|
|
2386
|
+
args.mode = "autosave";
|
|
2387
|
+
}
|
|
2388
|
+
return true;
|
|
2389
|
+
});
|
|
2390
|
+
(0, import_editor_v1_adapters7.registerDataHook)("after", "preview/drop", onElementDrop);
|
|
2391
|
+
window.elementorCommon.__beforeSave = beforeSave;
|
|
327
2392
|
(0, import_editor_elements_panel.injectTab)({
|
|
328
2393
|
id: "components",
|
|
329
|
-
label: (0,
|
|
330
|
-
component:
|
|
2394
|
+
label: (0, import_i18n15.__)("Components", "elementor"),
|
|
2395
|
+
component: Components
|
|
331
2396
|
});
|
|
332
2397
|
(0, import_editor.injectIntoTop)({
|
|
333
2398
|
id: "create-component-popup",
|
|
334
2399
|
component: CreateComponentForm
|
|
335
2400
|
});
|
|
2401
|
+
(0, import_editor.injectIntoLogic)({
|
|
2402
|
+
id: "components-populate-store",
|
|
2403
|
+
component: PopulateStore
|
|
2404
|
+
});
|
|
2405
|
+
(0, import_editor.injectIntoTop)({
|
|
2406
|
+
id: "edit-component",
|
|
2407
|
+
component: EditComponent
|
|
2408
|
+
});
|
|
2409
|
+
(0, import_editor_editing_panel3.injectIntoPanelHeaderTop)({
|
|
2410
|
+
id: "component-panel-header",
|
|
2411
|
+
component: ComponentPanelHeader
|
|
2412
|
+
});
|
|
2413
|
+
(0, import_editor_v1_adapters7.registerDataHook)("after", "editor/documents/attach-preview", async () => {
|
|
2414
|
+
const { id, config } = (0, import_editor_documents11.getV1CurrentDocument)();
|
|
2415
|
+
if (id) {
|
|
2416
|
+
removeComponentStyles(id);
|
|
2417
|
+
}
|
|
2418
|
+
await loadComponentsAssets(config?.elements ?? []);
|
|
2419
|
+
});
|
|
2420
|
+
(0, import_editor_editing_panel3.registerFieldIndicator)({
|
|
2421
|
+
fieldType: import_editor_editing_panel3.FIELD_TYPE.SETTINGS,
|
|
2422
|
+
id: "component-overridable-prop",
|
|
2423
|
+
priority: 1,
|
|
2424
|
+
indicator: OverridablePropIndicator
|
|
2425
|
+
});
|
|
2426
|
+
(0, import_editor_editing_panel3.registerControlReplacement)({
|
|
2427
|
+
component: OverridablePropControl,
|
|
2428
|
+
condition: ({ value }) => componentOverridablePropTypeUtil.isValid(value)
|
|
2429
|
+
});
|
|
2430
|
+
import_editor_canvas6.settingsTransformersRegistry.register("component-instance", componentInstanceTransformer);
|
|
2431
|
+
import_editor_canvas6.settingsTransformersRegistry.register("overridable", componentOverridableTransformer);
|
|
2432
|
+
initMcp();
|
|
336
2433
|
}
|
|
337
2434
|
// Annotate the CommonJS export names for ESM import in node:
|
|
338
2435
|
0 && (module.exports = {
|