@elementor/editor-variables 4.0.0-683 → 4.0.0

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.mjs CHANGED
@@ -1,205 +1,16 @@
1
1
  // src/init.ts
2
2
  import { injectIntoLogic, injectIntoTop } from "@elementor/editor";
3
3
  import { registerControlReplacement } from "@elementor/editor-controls";
4
+ import { getMCPByDomain } from "@elementor/editor-mcp";
4
5
  import { __registerPanel as registerPanel } from "@elementor/editor-panels";
5
6
  import { isTransformable as isTransformable2 } from "@elementor/editor-props";
6
7
  import { controlActionsMenu } from "@elementor/menus";
7
8
 
8
- // src/components/open-panel-from-event.tsx
9
- import { useEffect as useEffect4, useRef as useRef7, useState as useState7 } from "react";
10
- import {
11
- __privateListenTo as listenTo,
12
- __privateOpenRoute as openRoute,
13
- routeOpenEvent
14
- } from "@elementor/editor-v1-adapters";
15
-
16
- // src/components/variables-manager/variables-manager-panel.tsx
17
- import * as React14 from "react";
18
- import { useCallback as useCallback6, useEffect as useEffect3, useState as useState6 } from "react";
19
- import { useSuppressedMessage } from "@elementor/editor-current-user";
20
- import {
21
- __createPanel as createPanel,
22
- Panel,
23
- PanelBody,
24
- PanelFooter,
25
- PanelHeader,
26
- PanelHeaderTitle
27
- } from "@elementor/editor-panels";
28
- import { ConfirmationDialog as ConfirmationDialog2, SaveChangesDialog, SearchField, ThemeProvider, useDialog } from "@elementor/editor-ui";
29
- import { changeEditMode } from "@elementor/editor-v1-adapters";
30
- import { AlertTriangleFilledIcon as AlertTriangleFilledIcon2, ColorFilterIcon, TrashIcon } from "@elementor/icons";
31
- import {
32
- Alert,
33
- AlertAction,
34
- AlertTitle,
35
- Button as Button2,
36
- CloseButton,
37
- Divider,
38
- Infotip,
39
- Stack as Stack6,
40
- usePopupState as usePopupState2
41
- } from "@elementor/ui";
42
- import { __ as __10 } from "@wordpress/i18n";
43
-
44
- // src/utils/tracking.ts
45
- import { getMixpanel } from "@elementor/events";
46
- var trackVariableEvent = ({ varType, controlPath, action }) => {
47
- const { dispatchEvent, config } = getMixpanel();
48
- if (!config?.names?.variables?.[action]) {
49
- return;
50
- }
51
- const name = config.names.variables[action];
52
- dispatchEvent?.(name, {
53
- location: config?.locations?.variables || "",
54
- secondaryLocation: config?.secondaryLocations?.variablesPopover || "",
55
- trigger: config?.triggers?.click || "",
56
- var_type: varType,
57
- control_path: controlPath,
58
- action_type: name
59
- });
60
- };
61
- var trackVariablesManagerEvent = ({ action, varType, controlPath }) => {
62
- const { dispatchEvent, config } = getMixpanel();
63
- if (!config?.names?.variables?.[action]) {
64
- return;
65
- }
66
- const name = config.names.variables[action];
67
- const eventData = {
68
- location: config?.locations?.variablesManager || "",
69
- trigger: config?.triggers?.click || "",
70
- action_type: name
71
- };
72
- if (varType) {
73
- eventData.var_type = varType;
74
- }
75
- if (controlPath) {
76
- eventData.style_control_path = controlPath;
77
- }
78
- dispatchEvent?.(name, eventData);
79
- };
80
-
81
- // src/utils/validations.ts
82
- import { AlertTriangleFilledIcon, InfoCircleFilledIcon } from "@elementor/icons";
83
- import { __, sprintf } from "@wordpress/i18n";
84
- var ERROR_MESSAGES = {
85
- MISSING_VARIABLE_NAME: __("Give your variable a name.", "elementor"),
86
- MISSING_VARIABLE_VALUE: __("Add a value to complete your variable.", "elementor"),
87
- INVALID_CHARACTERS: __("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor"),
88
- NO_NON_SPECIAL_CHARACTER: __("Names have to include at least one non-special character.", "elementor"),
89
- VARIABLE_LABEL_MAX_LENGTH: __("Keep names up to 50 characters.", "elementor"),
90
- DUPLICATED_LABEL: __("This variable name already exists. Please choose a unique name.", "elementor"),
91
- UNEXPECTED_ERROR: __("There was a glitch. Try saving your variable again.", "elementor"),
92
- BATCH: {
93
- DUPLICATED_LABELS: (count, name) => (
94
- // eslint-disable-next-line @wordpress/i18n-translator-comments
95
- sprintf(__("We found %1$d duplicated %2$s.", "elementor"), count, name)
96
- ),
97
- UNEXPECTED_ERROR: __("There was a glitch.", "elementor"),
98
- DUPLICATED_LABEL_ACTION: __("Take me there", "elementor"),
99
- DUPLICATED_LABEL_ACTION_MESSAGE: __("Please rename the variables.", "elementor"),
100
- UNEXPECTED_ERROR_ACTION_MESSAGE: __("Try saving your variables again.", "elementor")
101
- }
102
- };
103
- var VARIABLE_LABEL_MAX_LENGTH = 50;
104
- var mapServerError = (error) => {
105
- if (error?.response?.data?.code === "duplicated_label") {
106
- return {
107
- field: "label",
108
- message: ERROR_MESSAGES.DUPLICATED_LABEL
109
- };
110
- }
111
- if (error?.response?.data?.code === "batch_duplicated_label") {
112
- const errorData = error?.response?.data?.data ?? {};
113
- const count = Object.keys(errorData).length;
114
- const name = count === 1 ? "name" : "names";
115
- const duplicatedIds = Object.keys(errorData);
116
- return {
117
- field: "label",
118
- message: ERROR_MESSAGES.BATCH.DUPLICATED_LABELS(count, name),
119
- severity: "error",
120
- IconComponent: AlertTriangleFilledIcon,
121
- action: {
122
- label: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION,
123
- message: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION_MESSAGE,
124
- data: {
125
- duplicatedIds
126
- }
127
- }
128
- };
129
- }
130
- if (error?.response?.data?.code === "batch_operation_failed") {
131
- return {
132
- field: "label",
133
- message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR,
134
- severity: "secondary",
135
- IconComponent: InfoCircleFilledIcon,
136
- action: {
137
- message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR_ACTION_MESSAGE
138
- }
139
- };
140
- }
141
- return void 0;
142
- };
143
- var validateLabel = (name, variables) => {
144
- if (!name.trim()) {
145
- return ERROR_MESSAGES.MISSING_VARIABLE_NAME;
146
- }
147
- const allowedChars = /^[a-zA-Z0-9_-]+$/;
148
- if (!allowedChars.test(name)) {
149
- return ERROR_MESSAGES.INVALID_CHARACTERS;
150
- }
151
- const hasAlphanumeric = /[a-zA-Z0-9]/;
152
- if (!hasAlphanumeric.test(name)) {
153
- return ERROR_MESSAGES.NO_NON_SPECIAL_CHARACTER;
154
- }
155
- if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
156
- return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
157
- }
158
- if (Object.values(variables ?? {}).some((variable) => variable.label === name)) {
159
- return ERROR_MESSAGES.DUPLICATED_LABEL;
160
- }
161
- return "";
162
- };
163
- var labelHint = (name) => {
164
- const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
165
- if (hintThreshold < name.length) {
166
- return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
167
- }
168
- return "";
169
- };
170
- var validateValue = (value) => {
171
- if (!value.trim()) {
172
- return ERROR_MESSAGES.MISSING_VARIABLE_VALUE;
173
- }
174
- return "";
175
- };
176
-
177
- // src/variables-registry/create-variable-type-registry.ts
178
- import {
179
- stylesInheritanceTransformersRegistry,
180
- styleTransformersRegistry
181
- } from "@elementor/editor-canvas";
182
-
183
- // src/transformers/inheritance-transformer.tsx
184
- import * as React from "react";
185
- import { createTransformer } from "@elementor/editor-canvas";
186
- import { Stack, Typography } from "@elementor/ui";
187
- import { __ as __3 } from "@wordpress/i18n";
188
-
189
- // src/components/ui/color-indicator.tsx
190
- import { styled, UnstableColorIndicator } from "@elementor/ui";
191
- var ColorIndicator = styled(UnstableColorIndicator)(({ theme }) => ({
192
- borderRadius: `${theme.shape.borderRadius / 2}px`,
193
- marginRight: theme.spacing(0.25)
194
- }));
195
-
196
- // src/prop-types/color-variable-prop-type.ts
197
- import { createPropUtils } from "@elementor/editor-props";
198
- import { z } from "@elementor/schema";
199
- var colorVariablePropTypeUtil = createPropUtils("global-color-variable", z.string());
9
+ // src/components/global-styles-import-listener.tsx
10
+ import { useEffect } from "react";
200
11
 
201
12
  // src/service.ts
202
- import { __ as __2 } from "@wordpress/i18n";
13
+ import { __ } from "@wordpress/i18n";
203
14
 
204
15
  // src/api.ts
205
16
  import { httpService } from "@elementor/http-client";
@@ -364,9 +175,9 @@ var Storage = class {
364
175
  import { enqueueFont } from "@elementor/editor-v1-adapters";
365
176
 
366
177
  // src/prop-types/font-variable-prop-type.ts
367
- import { createPropUtils as createPropUtils2 } from "@elementor/editor-props";
368
- import { z as z2 } from "@elementor/schema";
369
- var fontVariablePropTypeUtil = createPropUtils2("global-font-variable", z2.string());
178
+ import { createPropUtils } from "@elementor/editor-props";
179
+ import { z } from "@elementor/schema";
180
+ var fontVariablePropTypeUtil = createPropUtils("global-font-variable", z.string());
370
181
 
371
182
  // src/create-style-variables-repository.ts
372
183
  var createStyleVariablesRepository = () => {
@@ -478,7 +289,7 @@ var service = {
478
289
  return apiClient.create(type, label, value).then((response) => {
479
290
  const { success, data: payload } = response.data;
480
291
  if (!success) {
481
- const errorMessage = payload?.message || __2("Unexpected response from server", "elementor");
292
+ const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
482
293
  throw new Error(errorMessage);
483
294
  }
484
295
  return payload;
@@ -500,7 +311,7 @@ var service = {
500
311
  return apiClient.update(id2, label, value, type).then((response) => {
501
312
  const { success, data: payload } = response.data;
502
313
  if (!success) {
503
- const errorMessage = payload?.message || __2("Unexpected response from server", "elementor");
314
+ const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
504
315
  throw new Error(errorMessage);
505
316
  }
506
317
  return payload;
@@ -581,15 +392,15 @@ var service = {
581
392
  handleWatermark(OP_RW, watermark);
582
393
  if (results) {
583
394
  results.forEach((result) => {
395
+ const variableId = result.id;
584
396
  if (result.variable) {
585
- const { id: variableId, ...variableData } = result.variable;
586
397
  if (result.type === "create") {
587
- storage.add(variableId, variableData);
398
+ storage.add(variableId, result.variable);
588
399
  } else {
589
- storage.update(variableId, variableData);
400
+ storage.update(variableId, result.variable);
590
401
  }
591
402
  styleVariablesRepository.update({
592
- [variableId]: variableData
403
+ [variableId]: result.variable
593
404
  });
594
405
  }
595
406
  });
@@ -609,6 +420,243 @@ var handleWatermark = (operation, newWatermark) => {
609
420
  storage.watermark(newWatermark);
610
421
  };
611
422
 
423
+ // src/components/global-styles-import-listener.tsx
424
+ function GlobalStylesImportListener() {
425
+ useEffect(() => {
426
+ const handleGlobalStylesImported = (event) => {
427
+ const importedVars = event.detail?.global_variables;
428
+ if (!importedVars) {
429
+ return;
430
+ }
431
+ if (importedVars.data && typeof importedVars.data === "object") {
432
+ styleVariablesRepository.update(importedVars.data);
433
+ }
434
+ service.load();
435
+ };
436
+ window.addEventListener("elementor/global-styles/imported", handleGlobalStylesImported);
437
+ return () => {
438
+ window.removeEventListener(
439
+ "elementor/global-styles/imported",
440
+ handleGlobalStylesImported
441
+ );
442
+ };
443
+ }, []);
444
+ return null;
445
+ }
446
+
447
+ // src/components/open-panel-from-event.tsx
448
+ import { useEffect as useEffect5, useRef as useRef7, useState as useState7 } from "react";
449
+ import {
450
+ __privateListenTo as listenTo,
451
+ __privateOpenRoute as openRoute,
452
+ routeOpenEvent
453
+ } from "@elementor/editor-v1-adapters";
454
+
455
+ // src/components/variables-manager/variables-manager-panel.tsx
456
+ import * as React14 from "react";
457
+ import { useCallback as useCallback6, useEffect as useEffect4, useState as useState6 } from "react";
458
+ import { useSuppressedMessage } from "@elementor/editor-current-user";
459
+ import {
460
+ __createPanel as createPanel,
461
+ Panel,
462
+ PanelBody,
463
+ PanelFooter,
464
+ PanelHeader,
465
+ PanelHeaderTitle
466
+ } from "@elementor/editor-panels";
467
+ import { ConfirmationDialog as ConfirmationDialog2, SaveChangesDialog, SearchField, ThemeProvider, useDialog } from "@elementor/editor-ui";
468
+ import { changeEditMode } from "@elementor/editor-v1-adapters";
469
+ import { AlertTriangleFilledIcon as AlertTriangleFilledIcon2, ColorFilterIcon, TrashIcon } from "@elementor/icons";
470
+ import {
471
+ Alert,
472
+ AlertAction,
473
+ AlertTitle,
474
+ Button as Button2,
475
+ CloseButton,
476
+ Divider,
477
+ Infotip,
478
+ Stack as Stack6,
479
+ usePopupState as usePopupState2
480
+ } from "@elementor/ui";
481
+ import { __ as __10 } from "@wordpress/i18n";
482
+
483
+ // src/utils/tracking.ts
484
+ import { getMixpanel } from "@elementor/events";
485
+ var trackVariableEvent = ({ varType, controlPath, action }) => {
486
+ const { dispatchEvent, config } = getMixpanel();
487
+ if (!config?.names?.variables?.[action]) {
488
+ return;
489
+ }
490
+ const name = config.names.variables[action];
491
+ dispatchEvent?.(name, {
492
+ location: config?.locations?.variables || "",
493
+ secondaryLocation: config?.secondaryLocations?.variablesPopover || "",
494
+ trigger: config?.triggers?.click || "",
495
+ var_type: varType,
496
+ control_path: controlPath,
497
+ action_type: name
498
+ });
499
+ };
500
+ var trackVariablesManagerEvent = ({ action, varType, controlPath }) => {
501
+ const { dispatchEvent, config } = getMixpanel();
502
+ if (!config?.names?.variables?.[action]) {
503
+ return;
504
+ }
505
+ const name = config.names.variables[action];
506
+ const eventData = {
507
+ location: config?.locations?.variablesManager || "",
508
+ trigger: config?.triggers?.click || "",
509
+ action_type: name
510
+ };
511
+ if (varType) {
512
+ eventData.var_type = varType;
513
+ }
514
+ if (controlPath) {
515
+ eventData.style_control_path = controlPath;
516
+ }
517
+ dispatchEvent?.(name, eventData);
518
+ };
519
+ var trackVariableSyncToV3 = ({ variableLabel, action }) => {
520
+ try {
521
+ const { dispatchEvent, config } = getMixpanel();
522
+ if (!config?.names?.variables?.variableSyncToV3) {
523
+ return;
524
+ }
525
+ const name = config.names.variables.variableSyncToV3;
526
+ const isSync = action === "sync";
527
+ dispatchEvent?.(name, {
528
+ interaction_type: "click",
529
+ target_type: variableLabel,
530
+ target_name: isSync ? "sync_to_v3" : "unsync_to_v3",
531
+ interaction_result: isSync ? "var_is_synced_to_V3" : "var_is_unsynced_from_V3",
532
+ target_location: "widget_panel",
533
+ location_l1: "var_manager",
534
+ interaction_description: isSync ? `user_synced_${variableLabel}_to_v3` : `user_unsync_${variableLabel}_from_v3`
535
+ });
536
+ } catch {
537
+ }
538
+ };
539
+
540
+ // src/utils/validations.ts
541
+ import { AlertTriangleFilledIcon, InfoCircleFilledIcon } from "@elementor/icons";
542
+ import { __ as __2, sprintf } from "@wordpress/i18n";
543
+ var ERROR_MESSAGES = {
544
+ MISSING_VARIABLE_NAME: __2("Give your variable a name.", "elementor"),
545
+ MISSING_VARIABLE_VALUE: __2("Add a value to complete your variable.", "elementor"),
546
+ INVALID_CHARACTERS: __2("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor"),
547
+ NO_NON_SPECIAL_CHARACTER: __2("Names have to include at least one non-special character.", "elementor"),
548
+ VARIABLE_LABEL_MAX_LENGTH: __2("Keep names up to 50 characters.", "elementor"),
549
+ DUPLICATED_LABEL: __2("This variable name already exists. Please choose a unique name.", "elementor"),
550
+ UNEXPECTED_ERROR: __2("There was a glitch. Try saving your variable again.", "elementor"),
551
+ BATCH: {
552
+ DUPLICATED_LABELS: (count, name) => (
553
+ // eslint-disable-next-line @wordpress/i18n-translator-comments
554
+ sprintf(__2("We found %1$d duplicated %2$s.", "elementor"), count, name)
555
+ ),
556
+ UNEXPECTED_ERROR: __2("There was a glitch.", "elementor"),
557
+ DUPLICATED_LABEL_ACTION: __2("Take me there", "elementor"),
558
+ DUPLICATED_LABEL_ACTION_MESSAGE: __2("Please rename the variables.", "elementor"),
559
+ UNEXPECTED_ERROR_ACTION_MESSAGE: __2("Try saving your variables again.", "elementor")
560
+ }
561
+ };
562
+ var VARIABLE_LABEL_MAX_LENGTH = 50;
563
+ var mapServerError = (error) => {
564
+ if (error?.response?.data?.code === "duplicated_label") {
565
+ return {
566
+ field: "label",
567
+ message: ERROR_MESSAGES.DUPLICATED_LABEL
568
+ };
569
+ }
570
+ if (error?.response?.data?.code === "batch_duplicated_label") {
571
+ const errorData = error?.response?.data?.data ?? {};
572
+ const count = Object.keys(errorData).length;
573
+ const name = count === 1 ? "name" : "names";
574
+ const duplicatedIds = Object.keys(errorData);
575
+ return {
576
+ field: "label",
577
+ message: ERROR_MESSAGES.BATCH.DUPLICATED_LABELS(count, name),
578
+ severity: "error",
579
+ IconComponent: AlertTriangleFilledIcon,
580
+ action: {
581
+ label: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION,
582
+ message: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION_MESSAGE,
583
+ data: {
584
+ duplicatedIds
585
+ }
586
+ }
587
+ };
588
+ }
589
+ if (error?.response?.data?.code === "batch_operation_failed") {
590
+ return {
591
+ field: "label",
592
+ message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR,
593
+ severity: "secondary",
594
+ IconComponent: InfoCircleFilledIcon,
595
+ action: {
596
+ message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR_ACTION_MESSAGE
597
+ }
598
+ };
599
+ }
600
+ return void 0;
601
+ };
602
+ var validateLabel = (name, variables) => {
603
+ if (!name.trim()) {
604
+ return ERROR_MESSAGES.MISSING_VARIABLE_NAME;
605
+ }
606
+ const allowedChars = /^[a-zA-Z0-9_-]+$/;
607
+ if (!allowedChars.test(name)) {
608
+ return ERROR_MESSAGES.INVALID_CHARACTERS;
609
+ }
610
+ const hasAlphanumeric = /[a-zA-Z0-9]/;
611
+ if (!hasAlphanumeric.test(name)) {
612
+ return ERROR_MESSAGES.NO_NON_SPECIAL_CHARACTER;
613
+ }
614
+ if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
615
+ return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
616
+ }
617
+ if (Object.values(variables ?? {}).some((variable) => variable.label === name)) {
618
+ return ERROR_MESSAGES.DUPLICATED_LABEL;
619
+ }
620
+ return "";
621
+ };
622
+ var labelHint = (name) => {
623
+ const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
624
+ if (hintThreshold < name.length) {
625
+ return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
626
+ }
627
+ return "";
628
+ };
629
+ var validateValue = (value) => {
630
+ if (!value.trim()) {
631
+ return ERROR_MESSAGES.MISSING_VARIABLE_VALUE;
632
+ }
633
+ return "";
634
+ };
635
+
636
+ // src/variables-registry/create-variable-type-registry.ts
637
+ import {
638
+ stylesInheritanceTransformersRegistry,
639
+ styleTransformersRegistry
640
+ } from "@elementor/editor-canvas";
641
+
642
+ // src/transformers/inheritance-transformer.tsx
643
+ import * as React from "react";
644
+ import { createTransformer } from "@elementor/editor-canvas";
645
+ import { Stack, Typography } from "@elementor/ui";
646
+ import { __ as __3 } from "@wordpress/i18n";
647
+
648
+ // src/components/ui/color-indicator.tsx
649
+ import { styled, UnstableColorIndicator } from "@elementor/ui";
650
+ var ColorIndicator = styled(UnstableColorIndicator)(({ theme }) => ({
651
+ borderRadius: `${theme.shape.borderRadius / 2}px`,
652
+ marginRight: theme.spacing(0.25)
653
+ }));
654
+
655
+ // src/prop-types/color-variable-prop-type.ts
656
+ import { createPropUtils as createPropUtils2 } from "@elementor/editor-props";
657
+ import { z as z2 } from "@elementor/schema";
658
+ var colorVariablePropTypeUtil = createPropUtils2("global-color-variable", z2.string());
659
+
612
660
  // src/transformers/utils/resolve-css-variable.ts
613
661
  var resolveCssVariable = (id2, variable) => {
614
662
  let name = id2;
@@ -1275,7 +1323,7 @@ var getDefaultName = (variables, baseName) => {
1275
1323
 
1276
1324
  // src/components/variables-manager/variables-manager-table.tsx
1277
1325
  import * as React13 from "react";
1278
- import { useEffect as useEffect2, useRef as useRef6 } from "react";
1326
+ import { useEffect as useEffect3, useRef as useRef6 } from "react";
1279
1327
  import {
1280
1328
  Table,
1281
1329
  TableBody,
@@ -1400,7 +1448,7 @@ var LabelField = ({
1400
1448
 
1401
1449
  // src/components/variables-manager/variable-editable-cell.tsx
1402
1450
  import * as React10 from "react";
1403
- import { useCallback as useCallback5, useEffect, useRef as useRef4, useState as useState5 } from "react";
1451
+ import { useCallback as useCallback5, useEffect as useEffect2, useRef as useRef4, useState as useState5 } from "react";
1404
1452
  import { ClickAwayListener, Stack as Stack4 } from "@elementor/ui";
1405
1453
  var VariableEditableCell = React10.memo(
1406
1454
  ({
@@ -1428,10 +1476,10 @@ var VariableEditableCell = React10.memo(
1428
1476
  }
1429
1477
  setIsEditing(false);
1430
1478
  }, [value, onChange, fieldType, labelFieldError, valueFieldError]);
1431
- useEffect(() => {
1479
+ useEffect2(() => {
1432
1480
  onRowRef?.(rowRef?.current);
1433
1481
  }, [onRowRef]);
1434
- useEffect(() => {
1482
+ useEffect2(() => {
1435
1483
  if (autoEdit && !isEditing && !disabled) {
1436
1484
  setIsEditing(true);
1437
1485
  onAutoEditComplete?.();
@@ -1772,7 +1820,7 @@ var VariablesManagerTable = ({
1772
1820
  }) => {
1773
1821
  const tableContainerRef = useRef6(null);
1774
1822
  const variableRowRefs = useRef6(/* @__PURE__ */ new Map());
1775
- useEffect2(() => {
1823
+ useEffect3(() => {
1776
1824
  if (autoEditVariableId && tableContainerRef.current) {
1777
1825
  const rowElement = variableRowRefs.current.get(autoEditVariableId);
1778
1826
  if (rowElement) {
@@ -1893,8 +1941,8 @@ function VariablesManagerPanel() {
1893
1941
  handleOnChange,
1894
1942
  createVariable: createVariable2,
1895
1943
  handleDeleteVariable,
1896
- handleStartSync,
1897
- handleStopSync,
1944
+ handleStartSync: startSyncFromState,
1945
+ handleStopSync: stopSyncFromState,
1898
1946
  handleSave,
1899
1947
  isSaving,
1900
1948
  handleSearch,
@@ -1955,22 +2003,35 @@ function VariablesManagerPanel() {
1955
2003
  },
1956
2004
  [handleDeleteVariable]
1957
2005
  );
1958
- const handleStopSyncWithConfirmation = useCallback6(
2006
+ const commitStopSync = useCallback6(
1959
2007
  (itemId) => {
1960
- handleStopSync(itemId);
1961
- setStopSyncConfirmation(null);
2008
+ stopSyncFromState(itemId);
2009
+ const variable = variables[itemId];
2010
+ if (variable) {
2011
+ trackVariableSyncToV3({ variableLabel: variable.label, action: "unsync" });
2012
+ }
1962
2013
  },
1963
- [handleStopSync]
2014
+ [stopSyncFromState, variables]
1964
2015
  );
1965
- const handleShowStopSyncDialog = useCallback6(
2016
+ const handleStartSync = useCallback6(
2017
+ (itemId) => {
2018
+ startSyncFromState(itemId);
2019
+ const variable = variables[itemId];
2020
+ if (variable) {
2021
+ trackVariableSyncToV3({ variableLabel: variable.label, action: "sync" });
2022
+ }
2023
+ },
2024
+ [startSyncFromState, variables]
2025
+ );
2026
+ const handleStopSync = useCallback6(
1966
2027
  (itemId) => {
1967
2028
  if (!isStopSyncSuppressed) {
1968
2029
  setStopSyncConfirmation(itemId);
1969
2030
  } else {
1970
- handleStopSync(itemId);
2031
+ commitStopSync(itemId);
1971
2032
  }
1972
2033
  },
1973
- [isStopSyncSuppressed, handleStopSync]
2034
+ [isStopSyncSuppressed, commitStopSync]
1974
2035
  );
1975
2036
  const buildMenuActions = useCallback6(
1976
2037
  (variableId) => {
@@ -1983,7 +2044,7 @@ function VariablesManagerPanel() {
1983
2044
  variableId,
1984
2045
  handlers: {
1985
2046
  onStartSync: handleStartSync,
1986
- onStopSync: handleShowStopSyncDialog
2047
+ onStopSync: handleStopSync
1987
2048
  }
1988
2049
  });
1989
2050
  const deleteAction = {
@@ -2001,7 +2062,7 @@ function VariablesManagerPanel() {
2001
2062
  };
2002
2063
  return [...typeActions, deleteAction];
2003
2064
  },
2004
- [variables, handleStartSync, handleShowStopSyncDialog]
2065
+ [variables, handleStartSync, handleStopSync]
2005
2066
  );
2006
2067
  const hasVariables = Object.keys(variables).length > 0;
2007
2068
  return /* @__PURE__ */ React14.createElement(ThemeProvider, null, /* @__PURE__ */ React14.createElement(Panel, null, /* @__PURE__ */ React14.createElement(
@@ -2136,7 +2197,10 @@ function VariablesManagerPanel() {
2136
2197
  {
2137
2198
  open: true,
2138
2199
  onClose: () => setStopSyncConfirmation(null),
2139
- onConfirm: () => handleStopSyncWithConfirmation(stopSyncConfirmation)
2200
+ onConfirm: () => {
2201
+ commitStopSync(stopSyncConfirmation);
2202
+ setStopSyncConfirmation(null);
2203
+ }
2140
2204
  }
2141
2205
  ), isSaveChangesDialogOpen && /* @__PURE__ */ React14.createElement(SaveChangesDialog, null, /* @__PURE__ */ React14.createElement(SaveChangesDialog.Title, { onClose: closeSaveChangesDialog }, __10("You have unsaved changes", "elementor")), /* @__PURE__ */ React14.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React14.createElement(SaveChangesDialog.ContentText, null, __10("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React14.createElement(
2142
2206
  SaveChangesDialog.Actions,
@@ -2164,7 +2228,7 @@ function VariablesManagerPanel() {
2164
2228
  )));
2165
2229
  }
2166
2230
  var usePreventUnload = (isDirty) => {
2167
- useEffect3(() => {
2231
+ useEffect4(() => {
2168
2232
  const handleBeforeUnload = (event) => {
2169
2233
  if (isDirty) {
2170
2234
  event.preventDefault();
@@ -2202,13 +2266,13 @@ function OpenPanelFromEvent() {
2202
2266
  const { open } = usePanelActions();
2203
2267
  const pendingRef = useRef7(false);
2204
2268
  const [readyToOpen, setReadyToOpen] = useState7(false);
2205
- useEffect4(() => {
2269
+ useEffect5(() => {
2206
2270
  if (readyToOpen) {
2207
2271
  setReadyToOpen(false);
2208
2272
  open();
2209
2273
  }
2210
2274
  }, [readyToOpen, open]);
2211
- useEffect4(() => {
2275
+ useEffect5(() => {
2212
2276
  return listenTo(routeOpenEvent(DEFAULT_PANEL_ROUTE), () => {
2213
2277
  if (pendingRef.current) {
2214
2278
  pendingRef.current = false;
@@ -2216,7 +2280,7 @@ function OpenPanelFromEvent() {
2216
2280
  }
2217
2281
  });
2218
2282
  }, []);
2219
- useEffect4(() => {
2283
+ useEffect5(() => {
2220
2284
  const handler = () => {
2221
2285
  pendingRef.current = true;
2222
2286
  openRoute(DEFAULT_PANEL_ROUTE);
@@ -2228,7 +2292,7 @@ function OpenPanelFromEvent() {
2228
2292
  }
2229
2293
 
2230
2294
  // src/components/open-panel-from-url.tsx
2231
- import { useEffect as useEffect5, useRef as useRef8 } from "react";
2295
+ import { useEffect as useEffect6, useRef as useRef8 } from "react";
2232
2296
  import { __privateListenTo as listenTo2, routeOpenEvent as routeOpenEvent2 } from "@elementor/editor-v1-adapters";
2233
2297
  var ACTIVE_PANEL_PARAM = "active-panel";
2234
2298
  var PANEL_ID = "variables-manager";
@@ -2236,7 +2300,7 @@ var DEFAULT_PANEL_ROUTE2 = "panel/elements";
2236
2300
  function OpenPanelFromUrl() {
2237
2301
  const { open } = usePanelActions();
2238
2302
  const hasOpened = useRef8(false);
2239
- useEffect5(() => {
2303
+ useEffect6(() => {
2240
2304
  const urlParams = new URLSearchParams(window.location.search);
2241
2305
  const activePanel = urlParams.get(ACTIVE_PANEL_PARAM);
2242
2306
  if (activePanel !== PANEL_ID) {
@@ -2452,11 +2516,12 @@ var VariableCreation = ({ onGoBack, onClose }) => {
2452
2516
  },
2453
2517
  onErrorChange: (errorMsg) => {
2454
2518
  setLabelFieldError({
2455
- value: label,
2519
+ value: "",
2456
2520
  message: errorMsg
2457
2521
  });
2458
2522
  },
2459
- onKeyDown: handleKeyDown
2523
+ onKeyDown: handleKeyDown,
2524
+ focusOnShow: true
2460
2525
  }
2461
2526
  )
2462
2527
  ), ValueField && /* @__PURE__ */ React17.createElement(FormField, { errorMsg: valueFieldError, label: __11("Value", "elementor") }, /* @__PURE__ */ React17.createElement(Typography6, { variant: "h5", id: "variable-value-wrapper" }, /* @__PURE__ */ React17.createElement(
@@ -2488,7 +2553,7 @@ var VariableCreation = ({ onGoBack, onClose }) => {
2488
2553
 
2489
2554
  // src/components/variable-edit.tsx
2490
2555
  import * as React19 from "react";
2491
- import { useEffect as useEffect6, useState as useState11 } from "react";
2556
+ import { useEffect as useEffect7, useState as useState11 } from "react";
2492
2557
  import { PopoverContent as PopoverContent2, useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
2493
2558
  import { useSuppressedMessage as useSuppressedMessage2 } from "@elementor/editor-current-user";
2494
2559
  import { PopoverHeader as PopoverHeader2, SectionPopoverBody as SectionPopoverBody2 } from "@elementor/editor-ui";
@@ -2565,7 +2630,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2565
2630
  const userPermissions = usePermissions();
2566
2631
  const [value, setValue] = useState11(() => variable.value);
2567
2632
  const [label, setLabel] = useState11(() => variable.label);
2568
- useEffect6(() => {
2633
+ useEffect7(() => {
2569
2634
  styleVariablesRepository.update({
2570
2635
  [editId]: {
2571
2636
  ...variable,
@@ -2688,11 +2753,12 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2688
2753
  },
2689
2754
  onErrorChange: (errorMsg) => {
2690
2755
  setLabelFieldError({
2691
- value: label,
2756
+ value: "",
2692
2757
  message: errorMsg
2693
2758
  });
2694
2759
  },
2695
- onKeyDown: handleKeyDown
2760
+ onKeyDown: handleKeyDown,
2761
+ focusOnShow: true
2696
2762
  }
2697
2763
  )
2698
2764
  ), ValueField && /* @__PURE__ */ React19.createElement(FormField, { errorMsg: valueFieldError, label: __13("Value", "elementor") }, /* @__PURE__ */ React19.createElement(Typography8, { variant: "h5" }, /* @__PURE__ */ React19.createElement(
@@ -2729,7 +2795,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2729
2795
  };
2730
2796
 
2731
2797
  // src/components/variables-selection.tsx
2732
- import { useEffect as useEffect7, useState as useState12 } from "react";
2798
+ import { useEffect as useEffect8, useState as useState12 } from "react";
2733
2799
  import * as React21 from "react";
2734
2800
  import { trackUpgradePromotionClick as trackUpgradePromotionClick2, trackViewPromotion as trackViewPromotion2 } from "@elementor/editor-controls";
2735
2801
  import {
@@ -2919,7 +2985,7 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings, disabled =
2919
2985
  const handleClearSearch = () => {
2920
2986
  setSearchValue("");
2921
2987
  };
2922
- useEffect7(() => {
2988
+ useEffect8(() => {
2923
2989
  if (disabled) {
2924
2990
  trackViewPromotion2({
2925
2991
  target_name: "variables_popover",
@@ -3278,11 +3344,12 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
3278
3344
  },
3279
3345
  onErrorChange: (errorMsg) => {
3280
3346
  setLabelFieldError({
3281
- value: label,
3347
+ value: "",
3282
3348
  message: errorMsg
3283
3349
  });
3284
3350
  },
3285
- onKeyDown: handleKeyDown
3351
+ onKeyDown: handleKeyDown,
3352
+ focusOnShow: true
3286
3353
  }
3287
3354
  )
3288
3355
  ), ValueField && /* @__PURE__ */ React25.createElement(FormField, { errorMsg: valueFieldError, label: __17("Value", "elementor") }, /* @__PURE__ */ React25.createElement(Typography11, { variant: "h5" }, /* @__PURE__ */ React25.createElement(
@@ -3687,22 +3754,15 @@ var trackOpenVariablePopover = (path, variableType) => {
3687
3754
  });
3688
3755
  };
3689
3756
 
3690
- // src/mcp/index.ts
3691
- import { isAngieAvailable } from "@elementor/editor-mcp";
3692
-
3693
3757
  // src/mcp/manage-variable-tool.ts
3694
- import { getMCPByDomain as getMCPByDomain2 } from "@elementor/editor-mcp";
3695
3758
  import { z as z3 } from "@elementor/schema";
3696
3759
 
3697
3760
  // src/mcp/variables-resource.ts
3698
- import { getMCPByDomain } from "@elementor/editor-mcp";
3699
3761
  var GLOBAL_VARIABLES_URI = "elementor://global-variables";
3700
- var initVariablesResource = () => {
3701
- const canvasMcpEntry = getMCPByDomain("canvas");
3702
- const variablesMcpEntry = getMCPByDomain("variables");
3762
+ var initVariablesResource = (variablesMcpEntry, canvasMcpEntry) => {
3703
3763
  [canvasMcpEntry, variablesMcpEntry].forEach((entry) => {
3704
- const { mcpServer } = entry;
3705
- mcpServer.resource(
3764
+ const { resource, sendResourceUpdated } = entry;
3765
+ resource(
3706
3766
  "global-variables",
3707
3767
  GLOBAL_VARIABLES_URI,
3708
3768
  {
@@ -3721,7 +3781,7 @@ var initVariablesResource = () => {
3721
3781
  }
3722
3782
  );
3723
3783
  window.addEventListener("variables:updated", () => {
3724
- mcpServer.server.sendResourceUpdated({
3784
+ sendResourceUpdated({
3725
3785
  uri: GLOBAL_VARIABLES_URI
3726
3786
  });
3727
3787
  });
@@ -3729,8 +3789,9 @@ var initVariablesResource = () => {
3729
3789
  };
3730
3790
 
3731
3791
  // src/mcp/manage-variable-tool.ts
3732
- var initManageVariableTool = () => {
3733
- getMCPByDomain2("variables").addTool({
3792
+ var initManageVariableTool = (reg) => {
3793
+ const { addTool } = reg;
3794
+ addTool({
3734
3795
  name: "manage-global-variable",
3735
3796
  schema: {
3736
3797
  action: z3.enum(["create", "update", "delete"]).describe("Operation to perform"),
@@ -3800,12 +3861,18 @@ function getServiceActions(svc) {
3800
3861
  }
3801
3862
 
3802
3863
  // src/mcp/index.ts
3803
- function initMcp() {
3804
- if (!isAngieAvailable()) {
3805
- return;
3806
- }
3807
- initManageVariableTool();
3808
- initVariablesResource();
3864
+ function initMcp(reg, canvasMcpEntry) {
3865
+ const { setMCPDescription } = reg;
3866
+ setMCPDescription(
3867
+ `Everything related to V4 ( Atomic ) variables.
3868
+ # Global variables
3869
+ - Create/update/delete global variables
3870
+ - Get list of global variables
3871
+ - Get details of a global variable
3872
+ `
3873
+ );
3874
+ initManageVariableTool(reg);
3875
+ initVariablesResource(reg, canvasMcpEntry);
3809
3876
  }
3810
3877
 
3811
3878
  // src/register-variable-types.tsx
@@ -3813,8 +3880,7 @@ import * as React37 from "react";
3813
3880
  import { trackUpgradePromotionClick as trackUpgradePromotionClick3 } from "@elementor/editor-controls";
3814
3881
  import { colorPropTypeUtil, sizePropTypeUtil, stringPropTypeUtil } from "@elementor/editor-props";
3815
3882
  import { CtaButton } from "@elementor/editor-ui";
3816
- import { isExperimentActive as isExperimentActive2 } from "@elementor/editor-v1-adapters";
3817
- import { BrushIcon, ExpandDiagonalIcon, ResetIcon, TextIcon as TextIcon2 } from "@elementor/icons";
3883
+ import { BrushIcon, ExpandDiagonalIcon, RefreshIcon, RefreshOffIcon, TextIcon as TextIcon2 } from "@elementor/icons";
3818
3884
  import { __ as __26 } from "@wordpress/i18n";
3819
3885
 
3820
3886
  // src/components/fields/color-field.tsx
@@ -3955,20 +4021,17 @@ function registerVariableTypes() {
3955
4021
  defaultValue: "#ffffff",
3956
4022
  menuActionsFactory: ({ variable, variableId, handlers }) => {
3957
4023
  const actions = [];
3958
- if (!isExperimentActive2("e_design_system_sync")) {
3959
- return [];
3960
- }
3961
4024
  if (variable.sync_to_v3) {
3962
4025
  actions.push({
3963
4026
  name: __26("Stop syncing to Global Colors", "elementor"),
3964
- icon: ResetIcon,
4027
+ icon: RefreshOffIcon,
3965
4028
  color: "text.primary",
3966
4029
  onClick: () => handlers.onStopSync(variableId)
3967
4030
  });
3968
4031
  } else {
3969
4032
  actions.push({
3970
4033
  name: __26("Sync to Global Colors", "elementor"),
3971
- icon: ResetIcon,
4034
+ icon: RefreshIcon,
3972
4035
  color: "text.primary",
3973
4036
  onClick: () => handlers.onStartSync(variableId)
3974
4037
  });
@@ -4015,7 +4078,7 @@ function registerVariableTypes() {
4015
4078
 
4016
4079
  // src/renderers/style-variables-renderer.tsx
4017
4080
  import * as React38 from "react";
4018
- import { useEffect as useEffect8, useState as useState20 } from "react";
4081
+ import { useEffect as useEffect9, useState as useState20 } from "react";
4019
4082
  import {
4020
4083
  __privateUseListenTo as useListenTo,
4021
4084
  commandEndEvent,
@@ -4039,7 +4102,7 @@ function usePortalContainer() {
4039
4102
  }
4040
4103
  function useStyleVariables() {
4041
4104
  const [variables, setVariables] = useState20({});
4042
- useEffect8(() => {
4105
+ useEffect9(() => {
4043
4106
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
4044
4107
  return () => {
4045
4108
  unsubscribe();
@@ -4131,12 +4194,16 @@ function init() {
4131
4194
  useProps: usePropVariableAction
4132
4195
  });
4133
4196
  service.init().then(() => {
4134
- initMcp();
4197
+ initMcp(getMCPByDomain("variables"), getMCPByDomain("canvas"));
4135
4198
  });
4136
4199
  injectIntoTop({
4137
4200
  id: "canvas-style-variables-render",
4138
4201
  component: StyleVariablesRenderer
4139
4202
  });
4203
+ injectIntoLogic({
4204
+ id: "variables-import-listener",
4205
+ component: GlobalStylesImportListener
4206
+ });
4140
4207
  injectIntoLogic({
4141
4208
  id: "variables-open-panel-from-url",
4142
4209
  component: OpenPanelFromUrl