PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.1
Elementor Website Builder – more than just a page builder v4.3.1
4.3.1 4.3.0 4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 All 454 releases
elementor / assets / js / packages / editor-design-system / editor-design-system.js

editor-design-system.js in Elementor Website Builder – more than just a page builder 4.3.1, at assets/js/packages/editor-design-system/editor-design-system.js

941 lines 36.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function(_elementor_editor, _elementor_editor_app_bar, _elementor_editor_panels, react, _elementor_editor_documents, _elementor_editor_ui, _elementor_editor_v1_adapters, _wordpress_i18n, _elementor_editor_default_styles, _elementor_editor_global_classes, _elementor_editor_variables, _elementor_icons, _elementor_ui, _elementor_editor_current_user, _elementor_query, _elementor_editor_notifications, _elementor_http_client, _elementor_editor_canvas, _elementor_events) {
2
3 //#region \0rolldown/runtime.js
4 var __create = Object.create;
5 var __defProp = Object.defineProperty;
6 var __name = (target, value) => __defProp(target, "name", {
7 value,
8 configurable: true
9 });
10 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
11 var __getOwnPropNames = Object.getOwnPropertyNames;
12 var __getProtoOf = Object.getPrototypeOf;
13 var __hasOwnProp = Object.prototype.hasOwnProperty;
14 var __exportAll = (all, no_symbols) => {
15 let target = {};
16 for (var name in all) {
17 __defProp(target, name, {
18 get: all[name],
19 enumerable: true
20 });
21 }
22 if (!no_symbols) {
23 __defProp(target, Symbol.toStringTag, { value: "Module" });
24 }
25 return target;
26 };
27 var __copyProps = (to, from, except, desc) => {
28 if (from && typeof from === "object" || typeof from === "function") {
29 for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
30 key = keys[i];
31 if (!__hasOwnProp.call(to, key) && key !== except) {
32 __defProp(to, key, {
33 get: ((k) => from[k]).bind(null, key),
34 enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
35 });
36 }
37 }
38 }
39 return to;
40 };
41 var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
42 value: mod,
43 enumerable: true
44 }) : target, mod));
45
46 //#endregion
47 react = __toESM(react);
48
49 //#region packages/packages/core/editor-design-system/src/initial-tab.ts
50 var STORAGE_KEY = "elementor_editor_design_system_active_tab";
51 function readStoredTab() {
52 if (typeof window === "undefined") return "defaults";
53 try {
54 const raw = window.localStorage.getItem(STORAGE_KEY);
55 if (raw === "defaults" || raw === "classes" || raw === "variables") return raw;
56 } catch {}
57 return "defaults";
58 }
59 var pendingTabForOpen = null;
60 var activeTabInMemory = readStoredTab();
61 function normalizeDesignSystemTab(tab) {
62 return tab;
63 }
64 function setPendingDesignSystemTab(tab) {
65 pendingTabForOpen = tab;
66 }
67 function getInitialDesignSystemTab() {
68 if (pendingTabForOpen) {
69 const t2 = pendingTabForOpen;
70 pendingTabForOpen = null;
71 activeTabInMemory = t2;
72 persistDesignSystemTab(t2);
73 return t2;
74 }
75 const t = readStoredTab();
76 activeTabInMemory = t;
77 return t;
78 }
79 function notifyDesignSystemTabChange(tab) {
80 activeTabInMemory = tab;
81 }
82 function getActiveDesignSystemTab() {
83 return activeTabInMemory;
84 }
85 function persistDesignSystemTab(tab) {
86 if (typeof window === "undefined") return;
87 try {
88 window.localStorage.setItem(STORAGE_KEY, tab);
89 } catch {}
90 }
91
92 //#endregion
93 //#region packages/packages/core/editor-design-system/src/export/download.ts
94 var downloadBlob = (blob, fileName) => {
95 const url = URL.createObjectURL(blob);
96 const anchor = document.createElement("a");
97 anchor.href = url;
98 anchor.download = fileName;
99 anchor.rel = "noopener";
100 document.body.appendChild(anchor);
101 anchor.click();
102 document.body.removeChild(anchor);
103 URL.revokeObjectURL(url);
104 };
105
106 //#endregion
107 //#region packages/packages/core/editor-design-system/src/export/export-notifications.ts
108 var EXPORT_STARTED_NOTIFICATION_ID = "design-system-export-started";
109 var SUCCESS_NOTIFICATION_ID$1 = "design-system-export-succeeded";
110 var FAILURE_NOTIFICATION_ID$1 = "design-system-export-failed";
111 var notifyExportInProgress = () => {
112 (0, _elementor_editor_notifications.notify)({
113 id: EXPORT_STARTED_NOTIFICATION_ID,
114 type: "info",
115 message: (0, _wordpress_i18n.__)("Export in progress. Your file will download when it’s ready.", "elementor")
116 });
117 };
118 var notifyExportSuccess = () => {
119 (0, _elementor_editor_notifications.dismissNotification)(EXPORT_STARTED_NOTIFICATION_ID);
120 (0, _elementor_editor_notifications.notify)({
121 id: SUCCESS_NOTIFICATION_ID$1,
122 type: "success",
123 message: (0, _wordpress_i18n.__)("Design system exported", "elementor")
124 });
125 };
126 var notifyExportFailure = (onRetry) => {
127 (0, _elementor_editor_notifications.dismissNotification)(EXPORT_STARTED_NOTIFICATION_ID);
128 (0, _elementor_editor_notifications.notify)({
129 id: FAILURE_NOTIFICATION_ID$1,
130 type: "error",
131 message: (0, _wordpress_i18n.__)("Your design system export failed", "elementor"),
132 additionalActionProps: [{
133 size: "small",
134 variant: "outlined",
135 color: "error",
136 children: (0, _wordpress_i18n.__)("Try again", "elementor"),
137 onClick: () => {
138 (0, _elementor_editor_notifications.dismissNotification)(FAILURE_NOTIFICATION_ID$1);
139 onRetry();
140 }
141 }]
142 });
143 };
144
145 //#endregion
146 //#region packages/packages/core/editor-design-system/src/export/hooks/use-export-request.ts
147 var EXPORT_BASE_PATH = "elementor/v1/import-export-customization";
148 var EXPORT_DESIGN_SYSTEM_MUTATION_KEY = "design-system-export";
149 var DEFAULT_EXPORT_FILE_NAME = "design-system-export.zip";
150 var EXPORT_REQUEST_TIMEOUT_MS = 12e4;
151 var EXPORT_REQUEST_BODY = {
152 include: ["settings"],
153 kitInfo: {
154 title: "design-system",
155 description: "",
156 source: "local"
157 },
158 customization: { settings: {
159 theme: false,
160 classes: true,
161 variables: true
162 } }
163 };
164 var DesignSystemExportError = class extends Error {
165 constructor(cause) {
166 super("Design system export failed");
167 this.name = "DesignSystemExportError";
168 this.cause = cause;
169 }
170 };
171 var useExportRequest = () => {
172 return (0, _elementor_query.useMutation)({
173 mutationKey: [EXPORT_DESIGN_SYSTEM_MUTATION_KEY],
174 mutationFn: async () => {
175 try {
176 const { data } = await (0, _elementor_http_client.httpService)().post(`${EXPORT_BASE_PATH}/export`, EXPORT_REQUEST_BODY, { timeout: EXPORT_REQUEST_TIMEOUT_MS });
177 return {
178 fileName: DEFAULT_EXPORT_FILE_NAME,
179 blob: base64ToZipBlob(data.data.file)
180 };
181 } catch (error) {
182 throw new DesignSystemExportError(error);
183 }
184 }
185 });
186 };
187 var base64ToZipBlob = (base64) => {
188 const binary = atob(base64);
189 const bytes = new Uint8Array(binary.length);
190 for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
191 return new Blob([bytes], { type: "application/zip" });
192 };
193
194 //#endregion
195 //#region packages/packages/core/editor-design-system/src/import/hooks/use-import-request.ts
196 var IMPORT_BASE_PATH = "elementor/v1/import-export-customization";
197 var IMPORT_REQUEST_TIMEOUT_MS = 12e4;
198 var SUPPORTED_RUNNERS = ["global-classes", "global-variables"];
199 var IMPORT_DESIGN_SYSTEM_MUTATION_KEY = "design-system-import";
200 var useImportRequest = () => {
201 return (0, _elementor_query.useMutation)({
202 mutationKey: [IMPORT_DESIGN_SYSTEM_MUTATION_KEY],
203 mutationFn: async ({ file, conflictStrategy }) => {
204 await (0, _elementor_editor_v1_adapters.__privateRunCommand)("document/save/auto", { force: true });
205 const session = await uploadKit(file);
206 const runners = await startImport(session, conflictStrategy);
207 await runRunners(session, runners);
208 window.dispatchEvent(new CustomEvent(_elementor_editor_canvas.GLOBAL_STYLES_IMPORTED_EVENT));
209 }
210 });
211 };
212 var DesignSystemUploadValidationError = class extends Error {
213 constructor(cause) {
214 super("Design system upload validation failed");
215 this.name = "DesignSystemUploadValidationError";
216 this.cause = cause;
217 }
218 };
219 var uploadKit = async (file) => {
220 const formData = new FormData();
221 formData.append("e_import_file", file);
222 try {
223 const { data } = await (0, _elementor_http_client.httpService)().post(`${IMPORT_BASE_PATH}/upload`, formData, {
224 headers: { "Content-Type": "multipart/form-data" },
225 timeout: IMPORT_REQUEST_TIMEOUT_MS
226 });
227 return data.data.session;
228 } catch (error) {
229 throw new DesignSystemUploadValidationError(error);
230 }
231 };
232 var startImport = async (session, conflictStrategy) => {
233 const customization = { "design-system": { conflict_resolution: conflictStrategy === "keep" ? "skip" : "replace" } };
234 const { data } = await (0, _elementor_http_client.httpService)().post(`${IMPORT_BASE_PATH}/import`, {
235 session,
236 include: ["design-system"],
237 customization
238 }, { timeout: IMPORT_REQUEST_TIMEOUT_MS });
239 return (data.data.runners ?? []).filter((runner) => SUPPORTED_RUNNERS.includes(runner));
240 };
241 var runRunners = async (session, runners) => {
242 for (const runner of runners) await (0, _elementor_http_client.httpService)().post(`${IMPORT_BASE_PATH}/import-runner`, {
243 session,
244 runner
245 }, { timeout: IMPORT_REQUEST_TIMEOUT_MS });
246 };
247
248 //#endregion
249 //#region packages/packages/core/editor-design-system/src/import/components/conflict-options.tsx
250 var getOptions = () => [{
251 value: "replace",
252 title: (0, _wordpress_i18n.__)("Replace existing values", "elementor"),
253 description: (0, _wordpress_i18n.__)("Imported design system values will overwrite existing variables and classes.", "elementor")
254 }, {
255 value: "keep",
256 title: (0, _wordpress_i18n.__)("Keep existing values", "elementor"),
257 description: (0, _wordpress_i18n.__)("Existing variables and classes will not change.", "elementor")
258 }];
259 var ConflictOptions = ({ value, onChange }) => {
260 const options = getOptions();
261 return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, { spacing: 1 }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "body1" }, (0, _wordpress_i18n.__)("How to handle conflicts with existing variables or classes?", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.RadioGroup, {
262 value: value ?? "",
263 onChange: (_, next) => onChange(next)
264 }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, { spacing: 1 }, options.map((option) => /* @__PURE__ */ react.createElement(_elementor_ui.Card, {
265 key: option.value,
266 variant: "outlined"
267 }, /* @__PURE__ */ react.createElement(_elementor_ui.CardActionArea, { onClick: () => onChange(option.value) }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
268 direction: "row",
269 alignItems: "center",
270 spacing: 2,
271 padding: 2
272 }, /* @__PURE__ */ react.createElement(_elementor_ui.Radio, {
273 value: option.value,
274 checked: value === option.value,
275 inputProps: { "aria-label": option.title }
276 }), /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
277 direction: "column",
278 spacing: .5
279 }, /* @__PURE__ */ react.createElement(_elementor_ui.Typography, { variant: "subtitle2" }, option.title), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
280 variant: "caption",
281 color: "text.secondary"
282 }, option.description)))))))));
283 };
284
285 //#endregion
286 //#region packages/packages/core/editor-design-system/src/import/hooks/use-dialog-state.ts
287 var initialState = {
288 file: null,
289 conflictStrategy: null
290 };
291 var useDialogState = () => {
292 const [state, setState] = (0, react.useState)(initialState);
293 const setFile = (file) => setState((prev) => ({
294 ...prev,
295 file
296 }));
297 const setConflictStrategy = (conflictStrategy) => setState((prev) => ({
298 ...prev,
299 conflictStrategy
300 }));
301 return {
302 ...state,
303 setFile,
304 setConflictStrategy
305 };
306 };
307
308 //#endregion
309 //#region packages/packages/core/editor-design-system/src/import/import-notifications.tsx
310 var IMPORT_STARTED_NOTIFICATION_ID = "design-system-import-started";
311 var SUCCESS_NOTIFICATION_ID = "design-system-import-succeeded";
312 var FAILURE_NOTIFICATION_ID = "design-system-import-failed";
313 var notifyImportInProgress = () => {
314 (0, _elementor_editor_notifications.notify)({
315 id: IMPORT_STARTED_NOTIFICATION_ID,
316 type: "info",
317 message: (0, _wordpress_i18n.__)("Import in Progress. You will be notified when the import is complete.", "elementor")
318 });
319 };
320 var notifyImportSuccess = () => {
321 (0, _elementor_editor_notifications.dismissNotification)(IMPORT_STARTED_NOTIFICATION_ID);
322 (0, _elementor_editor_notifications.notify)({
323 id: SUCCESS_NOTIFICATION_ID,
324 type: "success",
325 message: (0, _wordpress_i18n.__)("Design system imported", "elementor")
326 });
327 };
328 var notifyImportFailure = (onRetry) => {
329 (0, _elementor_editor_notifications.dismissNotification)(IMPORT_STARTED_NOTIFICATION_ID);
330 (0, _elementor_editor_notifications.notify)({
331 id: FAILURE_NOTIFICATION_ID,
332 type: "error",
333 message: (0, _wordpress_i18n.__)("Your design system import failed", "elementor"),
334 additionalActionProps: [{
335 size: "small",
336 variant: "outlined",
337 color: "error",
338 children: (0, _wordpress_i18n.__)("Try again", "elementor"),
339 onClick: () => {
340 (0, _elementor_editor_notifications.dismissNotification)(FAILURE_NOTIFICATION_ID);
341 if ((0, _elementor_query.getQueryClient)().isMutating({ mutationKey: ["design-system-import"] }) > 0) return;
342 onRetry();
343 }
344 }]
345 });
346 };
347
348 //#endregion
349 //#region packages/packages/core/editor-design-system/src/import/tracking.ts
350 var FILE_TYPE_DESIGN_SYSTEM = "design_system";
351 var trackDesignSystem = (payload) => {
352 const { dispatchEvent, config } = (0, _elementor_events.getMixpanel)();
353 const name = config?.names?.design_system?.[payload.event];
354 if (!name) return;
355 const { event, ...eventData } = payload;
356 try {
357 dispatchEvent?.(name, {
358 event,
359 ...eventData
360 });
361 } catch {}
362 };
363
364 //#endregion
365 //#region packages/packages/core/editor-design-system/src/import/import-design-system-dialog.tsx
366 var ALLOWED_FILE_TYPES = ["application/zip"];
367 var FILE_INPUT_ACCEPT = "application/zip,.zip";
368 var MAX_FILE_SIZE_MB = 3;
369 var LEARN_MORE_URL = "https://go.elementor.com/wp-dash-import-export-design-system/";
370 var reopenSelf = () => {
371 trackDesignSystem({ event: "importOpened" });
372 (0, _elementor_editor_ui.openDialog)({ component: /* @__PURE__ */ react.createElement(ImportDesignSystemDialog, { onClose: _elementor_editor_ui.closeDialog }) });
373 };
374 var ImportDesignSystemDialog = ({ onClose }) => {
375 const { file, conflictStrategy, setFile, setConflictStrategy } = useDialogState();
376 const importMutation = useImportRequest();
377 const isImportEnabled = Boolean(file && conflictStrategy);
378 const handleFileSelected = (selected) => {
379 setFile(selected);
380 trackDesignSystem({
381 event: "fileSelected",
382 file_type: FILE_TYPE_DESIGN_SYSTEM
383 });
384 };
385 const handleConflictChange = (choice) => {
386 setConflictStrategy(choice);
387 trackDesignSystem({
388 event: "conflictChoice",
389 choice
390 });
391 };
392 const handleImport = async () => {
393 if (!file || !conflictStrategy) return;
394 trackDesignSystem({
395 event: "confirmed",
396 conflict_choice: conflictStrategy
397 });
398 notifyImportInProgress();
399 onClose();
400 try {
401 await importMutation.mutateAsync({
402 file,
403 conflictStrategy
404 });
405 trackDesignSystem({ event: "imported" });
406 notifyImportSuccess();
407 } catch (error) {
408 if (error instanceof DesignSystemUploadValidationError) trackDesignSystem({
409 event: "validationFailed",
410 file_type: FILE_TYPE_DESIGN_SYSTEM
411 });
412 else trackDesignSystem({ event: "importFailed" });
413 notifyImportFailure(reopenSelf);
414 }
415 };
416 return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.DialogHeader, { logo: false }, /* @__PURE__ */ react.createElement(_elementor_ui.DialogTitle, null, (0, _wordpress_i18n.__)("Import Design System", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_ui.DialogContent, null, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, { spacing: 3 }, file ? /* @__PURE__ */ react.createElement(_elementor_editor_ui.FileUploadRow, {
417 file,
418 onRemove: () => setFile(null)
419 }) : /* @__PURE__ */ react.createElement(_elementor_editor_ui.FileUploadDropzone, {
420 onFileSelected: handleFileSelected,
421 allowedFileTypes: ALLOWED_FILE_TYPES,
422 accept: FILE_INPUT_ACCEPT,
423 regionLabel: (0, _wordpress_i18n.__)("Design system file dropzone", "elementor"),
424 helperText: (0, _wordpress_i18n.sprintf)((0, _wordpress_i18n.__)("zip (max. %dMB)", "elementor"), MAX_FILE_SIZE_MB)
425 }), /* @__PURE__ */ react.createElement(ConflictOptions, {
426 value: conflictStrategy,
427 onChange: handleConflictChange
428 }), /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
429 direction: "row",
430 spacing: .5,
431 alignItems: "center",
432 justifyContent: "flex-start"
433 }, /* @__PURE__ */ react.createElement(_elementor_icons.HelpIcon, { sx: {
434 fontSize: 16,
435 color: "text.tertiary"
436 } }), /* @__PURE__ */ react.createElement(_elementor_ui.Link, {
437 href: LEARN_MORE_URL,
438 target: "_blank",
439 rel: "noopener noreferrer",
440 underline: "always",
441 variant: "caption",
442 color: "text.tertiary"
443 }, (0, _wordpress_i18n.__)("Learn how design system imports work", "elementor"))))), /* @__PURE__ */ react.createElement(_elementor_ui.DialogActions, null, /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
444 size: "medium",
445 color: "secondary",
446 onClick: onClose
447 }, (0, _wordpress_i18n.__)("Cancel", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
448 size: "medium",
449 variant: "contained",
450 color: "primary",
451 disabled: !isImportEnabled,
452 onClick: handleImport
453 }, (0, _wordpress_i18n.__)("Import", "elementor"))));
454 };
455
456 //#endregion
457 //#region packages/packages/core/editor-design-system/src/components/design-system-header-menu.tsx
458 var POPUP_STATE_ID = "design-system-header-menu";
459 var DesignSystemHeaderMenu = () => {
460 const { isAdmin } = (0, _elementor_editor_current_user.useCurrentUserCapabilities)();
461 const popupState = (0, _elementor_ui.usePopupState)({
462 variant: "popover",
463 popupId: POPUP_STATE_ID
464 });
465 const exportMutation = useExportRequest();
466 const isImporting = (0, _elementor_query.useIsMutating)({ mutationKey: [IMPORT_DESIGN_SYSTEM_MUTATION_KEY] }) > 0;
467 const isExporting = (0, _elementor_query.useIsMutating)({ mutationKey: [EXPORT_DESIGN_SYSTEM_MUTATION_KEY] }) > 0;
468 const isInProgress = isImporting || isExporting;
469 const triggerProps = (0, _elementor_ui.bindTrigger)(popupState);
470 const handleImport = () => {
471 popupState.close();
472 trackDesignSystem({ event: "importOpened" });
473 (0, _elementor_editor_ui.openDialog)({ component: /* @__PURE__ */ react.createElement(ImportDesignSystemDialog, { onClose: _elementor_editor_ui.closeDialog }) });
474 };
475 const runExport = async () => {
476 notifyExportInProgress();
477 try {
478 const { blob, fileName } = await exportMutation.mutateAsync();
479 downloadBlob(blob, fileName);
480 notifyExportSuccess();
481 } catch {
482 notifyExportFailure(runExport);
483 }
484 };
485 const handleExport = () => {
486 popupState.close();
487 trackDesignSystem({ event: "export" });
488 runExport();
489 };
490 const triggerLabel = (0, _wordpress_i18n.__)("Design system actions", "elementor");
491 const currentlyExportingLabel = (0, _wordpress_i18n.__)(`Export is in progress. The file will be downloaded when it's complete.`, "elementor");
492 const currentlyImportingLabel = (0, _wordpress_i18n.__)(`Import is in progress. You will receive a notification when it's complete.`, "elementor");
493 let tooltipLabel = triggerLabel;
494 if (isInProgress) tooltipLabel = isExporting ? currentlyExportingLabel : currentlyImportingLabel;
495 return /* @__PURE__ */ react.createElement(react.Fragment, null, isAdmin && /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
496 title: tooltipLabel,
497 placement: "top"
498 }, /* @__PURE__ */ react.createElement("span", null, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
499 ...triggerProps,
500 size: "small",
501 "aria-label": triggerLabel,
502 disabled: isInProgress
503 }, /* @__PURE__ */ react.createElement(_elementor_icons.DotsVerticalIcon, { fontSize: "small" })))), /* @__PURE__ */ react.createElement(_elementor_ui.Menu, {
504 ...(0, _elementor_ui.bindMenu)(popupState),
505 MenuListProps: { dense: true },
506 PaperProps: { elevation: 6 },
507 anchorOrigin: {
508 vertical: "bottom",
509 horizontal: "right"
510 },
511 transformOrigin: {
512 vertical: "top",
513 horizontal: "right"
514 }
515 }, /* @__PURE__ */ react.createElement(_elementor_ui.MenuItem, {
516 onClick: handleImport,
517 disabled: isImporting
518 }, /* @__PURE__ */ react.createElement(_elementor_ui.ListItemIcon, null, /* @__PURE__ */ react.createElement(_elementor_icons.DownloadIcon, { fontSize: "tiny" })), /* @__PURE__ */ react.createElement(_elementor_ui.ListItemText, null, (0, _wordpress_i18n.__)("Import", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_ui.MenuItem, {
519 onClick: handleExport,
520 disabled: isExporting
521 }, /* @__PURE__ */ react.createElement(_elementor_ui.ListItemIcon, null, /* @__PURE__ */ react.createElement(_elementor_icons.UploadIcon, { fontSize: "tiny" })), /* @__PURE__ */ react.createElement(_elementor_ui.ListItemText, null, (0, _wordpress_i18n.__)("Export", "elementor")))));
522 };
523
524 //#endregion
525 //#region packages/packages/core/editor-design-system/src/components/design-system-panel-content.tsx
526 var stickyTabRowStyles = {
527 position: "sticky",
528 zIndex: 1100,
529 opacity: 1,
530 backgroundColor: "background.default",
531 transition: "top 300ms ease"
532 };
533 var EVENT_SET_TAB$1 = "elementor/design-system/set-tab";
534 var trackDesignSystemTabOpened = (tab) => {
535 switch (tab) {
536 case "classes":
537 (0, _elementor_editor_global_classes.trackGlobalClasses)({
538 event: "classManagerOpened",
539 source: "system-panel"
540 });
541 break;
542 case "variables":
543 (0, _elementor_editor_variables.trackVariablesManagerEvent)({
544 action: "openManager",
545 source: "system-panel"
546 });
547 break;
548 }
549 };
550 function DesignSystemPanelContent({ onRequestClose }) {
551 const [currentTab, setCurrentTab] = (0, react.useState)(() => getInitialDesignSystemTab());
552 const defaultsCloseAttemptRef = (0, react.useRef)(null);
553 const variablesCloseAttemptRef = (0, react.useRef)(null);
554 const classesCloseAttemptRef = (0, react.useRef)(null);
555 const isChainingRef = (0, react.useRef)(false);
556 const { getTabProps, getTabPanelProps, getTabsProps } = (0, _elementor_ui.useTabs)(currentTab);
557 const chainedThroughClasses = (0, react.useCallback)(() => {
558 if (!isChainingRef.current && classesCloseAttemptRef.current) {
559 isChainingRef.current = true;
560 classesCloseAttemptRef.current();
561 isChainingRef.current = false;
562 return;
563 }
564 onRequestClose();
565 }, [onRequestClose]);
566 const chainedThroughVariables = (0, react.useCallback)(() => {
567 if (!isChainingRef.current && variablesCloseAttemptRef.current) {
568 isChainingRef.current = true;
569 variablesCloseAttemptRef.current();
570 isChainingRef.current = false;
571 return;
572 }
573 onRequestClose();
574 }, [onRequestClose]);
575 const chainedThroughDefaults = (0, react.useCallback)(() => {
576 if (!isChainingRef.current && defaultsCloseAttemptRef.current) {
577 isChainingRef.current = true;
578 defaultsCloseAttemptRef.current();
579 isChainingRef.current = false;
580 return;
581 }
582 onRequestClose();
583 }, [onRequestClose]);
584 (0, react.useEffect)(() => {
585 notifyDesignSystemTabChange(currentTab);
586 }, [currentTab]);
587 (0, react.useEffect)(() => {
588 const handler = (event) => {
589 const tab = event.detail?.tab;
590 if (!tab) return;
591 const normalizedTab = normalizeDesignSystemTab(tab);
592 setCurrentTab(normalizedTab);
593 persistDesignSystemTab(normalizedTab);
594 notifyDesignSystemTabChange(normalizedTab);
595 trackDesignSystemTabOpened(normalizedTab);
596 };
597 window.addEventListener(EVENT_SET_TAB$1, handler);
598 return () => {
599 window.removeEventListener(EVENT_SET_TAB$1, handler);
600 };
601 }, []);
602 const handleHeaderClose = () => {
603 if (currentTab === "defaults" && defaultsCloseAttemptRef.current) {
604 defaultsCloseAttemptRef.current();
605 return;
606 }
607 if (currentTab === "variables" && variablesCloseAttemptRef.current) {
608 variablesCloseAttemptRef.current();
609 return;
610 }
611 if (currentTab === "classes" && classesCloseAttemptRef.current) {
612 classesCloseAttemptRef.current();
613 return;
614 }
615 onRequestClose();
616 };
617 return /* @__PURE__ */ react.createElement(_elementor_editor_ui.ThemeProvider, null, /* @__PURE__ */ react.createElement(_elementor_editor_panels.Panel, null, /* @__PURE__ */ react.createElement(_elementor_editor_panels.PanelHeader, null, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
618 p: 1,
619 pl: 2,
620 width: "100%",
621 direction: "row",
622 alignItems: "center",
623 spacing: .5
624 }, /* @__PURE__ */ react.createElement(_elementor_editor_panels.PanelHeaderTitle, { sx: {
625 flex: 1,
626 minWidth: 0
627 } }, (0, _wordpress_i18n.__)("Design system", "elementor")), /* @__PURE__ */ react.createElement(DesignSystemHeaderMenu, null), /* @__PURE__ */ react.createElement(_elementor_ui.CloseButton, {
628 "aria-label": (0, _wordpress_i18n.__)("Close", "elementor"),
629 sx: { flexShrink: 0 },
630 onClick: () => void handleHeaderClose()
631 }))), /* @__PURE__ */ react.createElement(_elementor_editor_panels.PanelBody, { sx: {
632 display: "flex",
633 flexDirection: "column",
634 height: "100%",
635 overflow: "hidden",
636 minHeight: 0
637 } }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
638 direction: "column",
639 sx: {
640 width: "100%",
641 flex: 1,
642 minHeight: 0,
643 overflow: "hidden"
644 }
645 }, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, { sx: {
646 ...stickyTabRowStyles,
647 top: 0,
648 flexShrink: 0
649 } }, /* @__PURE__ */ react.createElement(_elementor_ui.Tabs, {
650 variant: "fullWidth",
651 size: "small",
652 sx: { mt: .5 },
653 ...getTabsProps(),
654 onChange: (e, newValue) => {
655 getTabsProps().onChange(e, newValue);
656 setCurrentTab(newValue);
657 persistDesignSystemTab(newValue);
658 notifyDesignSystemTabChange(newValue);
659 trackDesignSystemTabOpened(newValue);
660 }
661 }, /* @__PURE__ */ react.createElement(_elementor_ui.Tab, {
662 label: (0, _wordpress_i18n.__)("Defaults", "elementor"),
663 icon: /* @__PURE__ */ react.createElement(_elementor_icons.TextIcon, { fontSize: "small" }),
664 iconPosition: "start",
665 ...getTabProps("defaults")
666 }), /* @__PURE__ */ react.createElement(_elementor_ui.Tab, {
667 label: (0, _wordpress_i18n.__)("Variables", "elementor"),
668 icon: /* @__PURE__ */ react.createElement(_elementor_icons.ColorFilterIcon, { fontSize: "small" }),
669 iconPosition: "start",
670 ...getTabProps("variables")
671 }), /* @__PURE__ */ react.createElement(_elementor_ui.Tab, {
672 label: (0, _wordpress_i18n.__)("Classes", "elementor"),
673 icon: /* @__PURE__ */ react.createElement(_elementor_icons.ColorSwatchIcon, { fontSize: "small" }),
674 iconPosition: "start",
675 ...getTabProps("classes")
676 })), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null)), /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
677 role: "tabpanel",
678 ...getTabPanelProps("defaults"),
679 sx: {
680 flex: 1,
681 minHeight: 0,
682 display: currentTab === "defaults" ? "flex" : "none",
683 flexDirection: "column",
684 overflow: "hidden",
685 pt: 1
686 }
687 }, /* @__PURE__ */ react.createElement(_elementor_editor_default_styles.DefaultStylesTabEmbedded, {
688 onRequestClose: chainedThroughVariables,
689 onExposeCloseAttempt: (fn) => {
690 defaultsCloseAttemptRef.current = fn;
691 }
692 })), /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
693 role: "tabpanel",
694 ...getTabPanelProps("variables"),
695 sx: {
696 flex: 1,
697 minHeight: 0,
698 display: currentTab === "variables" ? "flex" : "none",
699 flexDirection: "column",
700 overflow: "hidden",
701 pt: 1
702 }
703 }, /* @__PURE__ */ react.createElement(_elementor_editor_variables.VariablesManagerPanelEmbedded, {
704 onRequestClose: chainedThroughClasses,
705 onExposeCloseAttempt: (fn) => {
706 variablesCloseAttemptRef.current = fn;
707 }
708 })), /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
709 role: "tabpanel",
710 ...getTabPanelProps("classes"),
711 sx: {
712 flex: 1,
713 minHeight: 0,
714 display: currentTab === "classes" ? "flex" : "none",
715 flexDirection: "column",
716 overflow: "hidden",
717 pt: 1
718 }
719 }, /* @__PURE__ */ react.createElement(_elementor_editor_global_classes.ClassManagerPanelEmbedded, {
720 onRequestClose: chainedThroughDefaults,
721 onExposeCloseAttempt: (fn) => {
722 classesCloseAttemptRef.current = fn;
723 },
724 isActive: currentTab === "classes"
725 }))))));
726 }
727
728 //#endregion
729 //#region packages/packages/core/editor-design-system/src/design-system-panel.tsx
730 var PANEL_ID$1 = "design-system";
731 var { panel, usePanelStatus, usePanelActions } = (0, _elementor_editor_panels.createPanel)({
732 id: PANEL_ID$1,
733 component: DesignSystemPanelRoot,
734 allowedEditModes: ["edit", PANEL_ID$1],
735 onOpen: () => {
736 (0, _elementor_editor_v1_adapters.changeEditMode)(PANEL_ID$1);
737 },
738 onClose: async () => {
739 (0, _elementor_editor_v1_adapters.changeEditMode)("edit");
740 await (0, _elementor_editor_documents.reloadCurrentDocument)();
741 },
742 isOpenPreviousElement: true
743 });
744 function DesignSystemPanelRoot() {
745 const { close: closePanel } = usePanelActions();
746 return /* @__PURE__ */ react.createElement(DesignSystemPanelContent, { onRequestClose: closePanel });
747 }
748
749 //#endregion
750 //#region packages/packages/core/editor-design-system/src/components/design-system-entrypoints.tsx
751 var V1_ELEMENTS_PANEL_ROUTE = "panel/elements/categories";
752 var EVENT_OPEN_DEFAULTS = "elementor/open-default-styles";
753 var EVENT_OPEN_VARIABLES = "elementor/open-variables-manager";
754 var EVENT_OPEN_CLASSES = "elementor/open-global-classes-manager";
755 var EVENT_TOGGLE$1 = "elementor/toggle-design-system";
756 var EVENT_SET_TAB = "elementor/design-system/set-tab";
757 var ACTIVE_PANEL_PARAM = "active-panel";
758 var PANEL_ID = "design-system";
759 var LEGACY_DEFAULT_STYLES_PANEL = "default-styles";
760 var LEGACY_GLOBAL_CLASSES_PANEL = "global-classes-manager";
761 var LEGACY_VARIABLES_PANEL = "variables-manager";
762 var OPEN_EVENT_BY_TAB = {
763 defaults: EVENT_OPEN_DEFAULTS,
764 variables: EVENT_OPEN_VARIABLES,
765 classes: EVENT_OPEN_CLASSES
766 };
767 function DesignSystemEntrypoints() {
768 const { open, close } = usePanelActions();
769 const { isOpen } = usePanelStatus();
770 const document = (0, _elementor_editor_documents.__useActiveDocument)();
771 const { save: saveDocument } = (0, _elementor_editor_documents.__useActiveDocumentActions)();
772 const { open: openSaveDialog, close: closeSaveDialog, isOpen: isSaveDialogOpen } = (0, _elementor_editor_ui.useDialog)();
773 const documentRef = (0, react.useRef)(document);
774 documentRef.current = document;
775 const pendingOpenRef = (0, react.useRef)(null);
776 const gatedOpen = (0, react.useCallback)((onClean) => {
777 if (documentRef.current?.isDirty) {
778 pendingOpenRef.current = onClean;
779 openSaveDialog();
780 return;
781 }
782 onClean();
783 }, [openSaveDialog]);
784 const handleSaveAndContinue = (0, react.useCallback)(async () => {
785 try {
786 await saveDocument();
787 closeSaveDialog();
788 pendingOpenRef.current?.();
789 pendingOpenRef.current = null;
790 } catch {}
791 }, [saveDocument, closeSaveDialog]);
792 const handleStayHere = (0, react.useCallback)(() => {
793 closeSaveDialog();
794 pendingOpenRef.current = null;
795 }, [closeSaveDialog]);
796 const isOpenRef = (0, react.useRef)(isOpen);
797 isOpenRef.current = isOpen;
798 (0, react.useEffect)(() => {
799 const handler = (event) => {
800 const tab = event.detail?.tab;
801 if (tab !== "defaults" && tab !== "variables" && tab !== "classes") return;
802 if (isOpenRef.current && getActiveDesignSystemTab() === tab) {
803 close();
804 return;
805 }
806 if (isOpenRef.current) {
807 window.dispatchEvent(new CustomEvent(EVENT_SET_TAB, { detail: { tab } }));
808 return;
809 }
810 gatedOpen(() => {
811 window.dispatchEvent(new CustomEvent(OPEN_EVENT_BY_TAB[tab]));
812 });
813 };
814 window.addEventListener(EVENT_TOGGLE$1, handler);
815 return () => {
816 window.removeEventListener(EVENT_TOGGLE$1, handler);
817 };
818 }, [close, gatedOpen]);
819 const pendingTabRef = (0, react.useRef)(null);
820 const [readyToOpenFromEvent, setReadyToOpenFromEvent] = (0, react.useState)(false);
821 (0, react.useEffect)(() => {
822 if (readyToOpenFromEvent) {
823 setReadyToOpenFromEvent(false);
824 open();
825 }
826 }, [readyToOpenFromEvent, open]);
827 (0, react.useEffect)(() => {
828 return (0, _elementor_editor_v1_adapters.__privateListenTo)((0, _elementor_editor_v1_adapters.routeOpenEvent)(V1_ELEMENTS_PANEL_ROUTE), () => {
829 const tab = pendingTabRef.current;
830 if (tab) {
831 pendingTabRef.current = null;
832 setPendingDesignSystemTab(tab);
833 setReadyToOpenFromEvent(true);
834 }
835 });
836 }, []);
837 (0, react.useEffect)(() => {
838 const bind = (eventName, tab) => {
839 const handler = () => {
840 pendingTabRef.current = tab;
841 (0, _elementor_editor_v1_adapters.__privateOpenRoute)(V1_ELEMENTS_PANEL_ROUTE);
842 };
843 window.addEventListener(eventName, handler);
844 return () => window.removeEventListener(eventName, handler);
845 };
846 const unlistenDefaults = bind(EVENT_OPEN_DEFAULTS, "defaults");
847 const unlistenVariables = bind(EVENT_OPEN_VARIABLES, "variables");
848 const unlistenClasses = bind(EVENT_OPEN_CLASSES, "classes");
849 return () => {
850 unlistenDefaults();
851 unlistenVariables();
852 unlistenClasses();
853 };
854 }, []);
855 const hasOpenedFromUrl = (0, react.useRef)(false);
856 (0, react.useEffect)(() => {
857 const urlParams = new URLSearchParams(window.location.search);
858 const activePanel = urlParams.get(ACTIVE_PANEL_PARAM);
859 if (!activePanel) return;
860 let targetTab = null;
861 if (activePanel === PANEL_ID) {
862 const tab = urlParams.get("design-system-tab");
863 if (tab === "classes") targetTab = "classes";
864 else if (tab === "variables") targetTab = "variables";
865 else targetTab = "defaults";
866 } else if (activePanel === LEGACY_DEFAULT_STYLES_PANEL) targetTab = "defaults";
867 else if (activePanel === LEGACY_GLOBAL_CLASSES_PANEL) targetTab = "classes";
868 else if (activePanel === LEGACY_VARIABLES_PANEL) targetTab = "variables";
869 else return;
870 return (0, _elementor_editor_v1_adapters.__privateListenTo)((0, _elementor_editor_v1_adapters.routeOpenEvent)(V1_ELEMENTS_PANEL_ROUTE), () => {
871 if (hasOpenedFromUrl.current) return;
872 hasOpenedFromUrl.current = true;
873 requestAnimationFrame(() => {
874 if (targetTab) setPendingDesignSystemTab(targetTab);
875 gatedOpen(() => void open());
876 });
877 });
878 }, [open, gatedOpen]);
879 return isSaveDialogOpen ? /* @__PURE__ */ react.createElement(_elementor_editor_ui.ThemeProvider, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Title, null, (0, _wordpress_i18n.__)("You have unsaved changes", "elementor")), /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Content, null, /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.ContentText, { sx: { mb: 2 } }, (0, _wordpress_i18n.__)("To open the Design System, save your page first. You can't continue without saving.", "elementor"))), /* @__PURE__ */ react.createElement(_elementor_editor_ui.SaveChangesDialog.Actions, { actions: {
880 cancel: {
881 label: (0, _wordpress_i18n.__)("Stay here", "elementor"),
882 action: handleStayHere
883 },
884 confirm: {
885 label: (0, _wordpress_i18n.__)("Save & Continue", "elementor"),
886 action: handleSaveAndContinue
887 }
888 } }))) : null;
889 }
890
891 //#endregion
892 //#region packages/packages/core/editor-design-system/src/use-open-design-system-toolbar.ts
893 var EVENT_TOGGLE = "elementor/toggle-design-system";
894 function useOpenDesignSystemToolbar() {
895 const { isOpen } = usePanelStatus();
896 return {
897 title: (0, _wordpress_i18n.__)("Design System", "elementor"),
898 icon: _elementor_icons.DropletHalfFilledIcon,
899 onClick: () => {
900 if (!isOpen) trackDesignSystem({ event: "opened" });
901 const tab = getActiveDesignSystemTab();
902 window.dispatchEvent(new CustomEvent(EVENT_TOGGLE, { detail: { tab } }));
903 },
904 selected: isOpen
905 };
906 }
907
908 //#endregion
909 //#region packages/packages/core/editor-design-system/src/init.ts
910 function init() {
911 (0, _elementor_editor_panels.registerPanel)(panel);
912 (0, _elementor_editor.injectIntoLogic)({
913 id: "design-system-entrypoints",
914 component: DesignSystemEntrypoints
915 });
916 _elementor_editor_app_bar.toolsMenu.registerToggleAction({
917 id: "open-design-system-toolbar",
918 priority: 4,
919 useProps: useOpenDesignSystemToolbar
920 });
921 }
922
923 //#endregion
924 //#region packages/packages/core/editor-design-system/src/index.ts
925 var src_exports = /* @__PURE__ */ __exportAll({
926 getInitialDesignSystemTab: () => getInitialDesignSystemTab,
927 init: () => init,
928 panel: () => panel,
929 persistDesignSystemTab: () => persistDesignSystemTab,
930 usePanelActions: () => usePanelActions,
931 usePanelStatus: () => usePanelStatus
932 });
933
934 //#endregion
935 //#region \0elementor-package-library-entry
936 (window.elementorV2 = window.elementorV2 || {}).editorDesignSystem = src_exports;
937
938 //#endregion
939 })(elementorV2.editor, elementorV2.editorAppBar, elementorV2.editorPanels, React, elementorV2.editorDocuments, elementorV2.editorUi, elementorV2.editorV1Adapters, wp.i18n, elementorV2.editorDefaultStyles, elementorV2.editorGlobalClasses, elementorV2.editorVariables, elementorV2.icons, elementorV2.ui, elementorV2.editorCurrentUser, elementorV2.query, elementorV2.editorNotifications, elementorV2.httpClient, elementorV2.editorCanvas, elementorV2.events);
940 window.elementorV2.editorDesignSystem?.init?.();
941 //# sourceMappingURL=editor-design-system.js.map