@elementor/editor-variables 4.0.0-manual → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,201 +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-url.tsx
9
- import { useEffect as useEffect4, useRef as useRef7 } from "react";
10
- import { __privateListenTo as listenTo, routeOpenEvent } from "@elementor/editor-v1-adapters";
11
-
12
- // src/components/variables-manager/variables-manager-panel.tsx
13
- import * as React14 from "react";
14
- import { useCallback as useCallback5, useEffect as useEffect3, useState as useState6 } from "react";
15
- import { useSuppressedMessage } from "@elementor/editor-current-user";
16
- import {
17
- __createPanel as createPanel,
18
- Panel,
19
- PanelBody,
20
- PanelFooter,
21
- PanelHeader,
22
- PanelHeaderTitle
23
- } from "@elementor/editor-panels";
24
- import { ConfirmationDialog as ConfirmationDialog2, SaveChangesDialog, SearchField, ThemeProvider, useDialog } from "@elementor/editor-ui";
25
- import { changeEditMode } from "@elementor/editor-v1-adapters";
26
- import { AlertTriangleFilledIcon as AlertTriangleFilledIcon2, ColorFilterIcon, TrashIcon } from "@elementor/icons";
27
- import {
28
- Alert,
29
- AlertAction,
30
- AlertTitle,
31
- Button as Button2,
32
- CloseButton,
33
- Divider,
34
- Infotip,
35
- Stack as Stack6,
36
- usePopupState as usePopupState2
37
- } from "@elementor/ui";
38
- import { __ as __10 } from "@wordpress/i18n";
39
-
40
- // src/utils/tracking.ts
41
- import { getMixpanel } from "@elementor/events";
42
- var trackVariableEvent = ({ varType, controlPath, action }) => {
43
- const { dispatchEvent, config } = getMixpanel();
44
- if (!config?.names?.variables?.[action]) {
45
- return;
46
- }
47
- const name = config.names.variables[action];
48
- dispatchEvent?.(name, {
49
- location: config?.locations?.variables || "",
50
- secondaryLocation: config?.secondaryLocations?.variablesPopover || "",
51
- trigger: config?.triggers?.click || "",
52
- var_type: varType,
53
- control_path: controlPath,
54
- action_type: name
55
- });
56
- };
57
- var trackVariablesManagerEvent = ({ action, varType, controlPath }) => {
58
- const { dispatchEvent, config } = getMixpanel();
59
- if (!config?.names?.variables?.[action]) {
60
- return;
61
- }
62
- const name = config.names.variables[action];
63
- const eventData = {
64
- location: config?.locations?.variablesManager || "",
65
- trigger: config?.triggers?.click || "",
66
- action_type: name
67
- };
68
- if (varType) {
69
- eventData.var_type = varType;
70
- }
71
- if (controlPath) {
72
- eventData.style_control_path = controlPath;
73
- }
74
- dispatchEvent?.(name, eventData);
75
- };
76
-
77
- // src/utils/validations.ts
78
- import { AlertTriangleFilledIcon, InfoCircleFilledIcon } from "@elementor/icons";
79
- import { __, sprintf } from "@wordpress/i18n";
80
- var ERROR_MESSAGES = {
81
- MISSING_VARIABLE_NAME: __("Give your variable a name.", "elementor"),
82
- MISSING_VARIABLE_VALUE: __("Add a value to complete your variable.", "elementor"),
83
- INVALID_CHARACTERS: __("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor"),
84
- NO_NON_SPECIAL_CHARACTER: __("Names have to include at least one non-special character.", "elementor"),
85
- VARIABLE_LABEL_MAX_LENGTH: __("Keep names up to 50 characters.", "elementor"),
86
- DUPLICATED_LABEL: __("This variable name already exists. Please choose a unique name.", "elementor"),
87
- UNEXPECTED_ERROR: __("There was a glitch. Try saving your variable again.", "elementor"),
88
- BATCH: {
89
- DUPLICATED_LABELS: (count, name) => (
90
- // eslint-disable-next-line @wordpress/i18n-translator-comments
91
- sprintf(__("We found %1$d duplicated %2$s.", "elementor"), count, name)
92
- ),
93
- UNEXPECTED_ERROR: __("There was a glitch.", "elementor"),
94
- DUPLICATED_LABEL_ACTION: __("Take me there", "elementor"),
95
- DUPLICATED_LABEL_ACTION_MESSAGE: __("Please rename the variables.", "elementor"),
96
- UNEXPECTED_ERROR_ACTION_MESSAGE: __("Try saving your variables again.", "elementor")
97
- }
98
- };
99
- var VARIABLE_LABEL_MAX_LENGTH = 50;
100
- var mapServerError = (error) => {
101
- if (error?.response?.data?.code === "duplicated_label") {
102
- return {
103
- field: "label",
104
- message: ERROR_MESSAGES.DUPLICATED_LABEL
105
- };
106
- }
107
- if (error?.response?.data?.code === "batch_duplicated_label") {
108
- const errorData = error?.response?.data?.data ?? {};
109
- const count = Object.keys(errorData).length;
110
- const name = count === 1 ? "name" : "names";
111
- const duplicatedIds = Object.keys(errorData);
112
- return {
113
- field: "label",
114
- message: ERROR_MESSAGES.BATCH.DUPLICATED_LABELS(count, name),
115
- severity: "error",
116
- IconComponent: AlertTriangleFilledIcon,
117
- action: {
118
- label: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION,
119
- message: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION_MESSAGE,
120
- data: {
121
- duplicatedIds
122
- }
123
- }
124
- };
125
- }
126
- if (error?.response?.data?.code === "batch_operation_failed") {
127
- return {
128
- field: "label",
129
- message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR,
130
- severity: "secondary",
131
- IconComponent: InfoCircleFilledIcon,
132
- action: {
133
- message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR_ACTION_MESSAGE
134
- }
135
- };
136
- }
137
- return void 0;
138
- };
139
- var validateLabel = (name, variables) => {
140
- if (!name.trim()) {
141
- return ERROR_MESSAGES.MISSING_VARIABLE_NAME;
142
- }
143
- const allowedChars = /^[a-zA-Z0-9_-]+$/;
144
- if (!allowedChars.test(name)) {
145
- return ERROR_MESSAGES.INVALID_CHARACTERS;
146
- }
147
- const hasAlphanumeric = /[a-zA-Z0-9]/;
148
- if (!hasAlphanumeric.test(name)) {
149
- return ERROR_MESSAGES.NO_NON_SPECIAL_CHARACTER;
150
- }
151
- if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
152
- return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
153
- }
154
- if (Object.values(variables ?? {}).some((variable) => variable.label === name)) {
155
- return ERROR_MESSAGES.DUPLICATED_LABEL;
156
- }
157
- return "";
158
- };
159
- var labelHint = (name) => {
160
- const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
161
- if (hintThreshold < name.length) {
162
- return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
163
- }
164
- return "";
165
- };
166
- var validateValue = (value) => {
167
- if (!value.trim()) {
168
- return ERROR_MESSAGES.MISSING_VARIABLE_VALUE;
169
- }
170
- return "";
171
- };
172
-
173
- // src/variables-registry/create-variable-type-registry.ts
174
- import {
175
- stylesInheritanceTransformersRegistry,
176
- styleTransformersRegistry
177
- } from "@elementor/editor-canvas";
178
-
179
- // src/transformers/inheritance-transformer.tsx
180
- import * as React from "react";
181
- import { createTransformer } from "@elementor/editor-canvas";
182
- import { Stack, Typography } from "@elementor/ui";
183
- import { __ as __3 } from "@wordpress/i18n";
184
-
185
- // src/components/ui/color-indicator.tsx
186
- import { styled, UnstableColorIndicator } from "@elementor/ui";
187
- var ColorIndicator = styled(UnstableColorIndicator)(({ theme }) => ({
188
- borderRadius: `${theme.shape.borderRadius / 2}px`,
189
- marginRight: theme.spacing(0.25)
190
- }));
191
-
192
- // src/prop-types/color-variable-prop-type.ts
193
- import { createPropUtils } from "@elementor/editor-props";
194
- import { z } from "@elementor/schema";
195
- var colorVariablePropTypeUtil = createPropUtils("global-color-variable", z.string());
9
+ // src/components/global-styles-import-listener.tsx
10
+ import { useEffect } from "react";
196
11
 
197
12
  // src/service.ts
198
- import { __ as __2 } from "@wordpress/i18n";
13
+ import { __ } from "@wordpress/i18n";
199
14
 
200
15
  // src/api.ts
201
16
  import { httpService } from "@elementor/http-client";
@@ -360,9 +175,9 @@ var Storage = class {
360
175
  import { enqueueFont } from "@elementor/editor-v1-adapters";
361
176
 
362
177
  // src/prop-types/font-variable-prop-type.ts
363
- import { createPropUtils as createPropUtils2 } from "@elementor/editor-props";
364
- import { z as z2 } from "@elementor/schema";
365
- 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());
366
181
 
367
182
  // src/create-style-variables-repository.ts
368
183
  var createStyleVariablesRepository = () => {
@@ -474,7 +289,7 @@ var service = {
474
289
  return apiClient.create(type, label, value).then((response) => {
475
290
  const { success, data: payload } = response.data;
476
291
  if (!success) {
477
- const errorMessage = payload?.message || __2("Unexpected response from server", "elementor");
292
+ const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
478
293
  throw new Error(errorMessage);
479
294
  }
480
295
  return payload;
@@ -496,7 +311,7 @@ var service = {
496
311
  return apiClient.update(id2, label, value, type).then((response) => {
497
312
  const { success, data: payload } = response.data;
498
313
  if (!success) {
499
- const errorMessage = payload?.message || __2("Unexpected response from server", "elementor");
314
+ const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
500
315
  throw new Error(errorMessage);
501
316
  }
502
317
  return payload;
@@ -577,15 +392,15 @@ var service = {
577
392
  handleWatermark(OP_RW, watermark);
578
393
  if (results) {
579
394
  results.forEach((result) => {
395
+ const variableId = result.id;
580
396
  if (result.variable) {
581
- const { id: variableId, ...variableData } = result.variable;
582
397
  if (result.type === "create") {
583
- storage.add(variableId, variableData);
398
+ storage.add(variableId, result.variable);
584
399
  } else {
585
- storage.update(variableId, variableData);
400
+ storage.update(variableId, result.variable);
586
401
  }
587
402
  styleVariablesRepository.update({
588
- [variableId]: variableData
403
+ [variableId]: result.variable
589
404
  });
590
405
  }
591
406
  });
@@ -605,6 +420,243 @@ var handleWatermark = (operation, newWatermark) => {
605
420
  storage.watermark(newWatermark);
606
421
  };
607
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
+
608
660
  // src/transformers/utils/resolve-css-variable.ts
609
661
  var resolveCssVariable = (id2, variable) => {
610
662
  let name = id2;
@@ -1102,17 +1154,25 @@ var useQuotaPermissions = (variableType) => {
1102
1154
 
1103
1155
  // src/components/ui/variable-promotion-chip.tsx
1104
1156
  import * as React6 from "react";
1105
- import { forwardRef, useImperativeHandle, useState as useState3 } from "react";
1157
+ import { forwardRef, useCallback as useCallback4, useImperativeHandle, useState as useState3 } from "react";
1158
+ import { trackUpgradePromotionClick, trackViewPromotion } from "@elementor/editor-controls";
1106
1159
  import { PromotionChip, PromotionPopover, useCanvasClickHandler } from "@elementor/editor-ui";
1107
1160
  import { Box } from "@elementor/ui";
1108
1161
  import { capitalize } from "@elementor/utils";
1109
1162
  import { __ as __7, sprintf as sprintf2 } from "@wordpress/i18n";
1110
1163
  var VariablePromotionChip = forwardRef(
1111
- ({ variableType, upgradeUrl }, ref) => {
1164
+ ({ variableType, upgradeUrl, trackingData }, ref) => {
1112
1165
  const [isOpen, setIsOpen] = useState3(false);
1113
1166
  useCanvasClickHandler(isOpen, () => setIsOpen(false));
1114
- const toggle = () => setIsOpen((prev) => !prev);
1115
- useImperativeHandle(ref, () => ({ toggle }), []);
1167
+ const toggle = useCallback4(() => {
1168
+ setIsOpen((prev) => {
1169
+ if (!prev) {
1170
+ trackViewPromotion(trackingData);
1171
+ }
1172
+ return !prev;
1173
+ });
1174
+ }, [trackingData]);
1175
+ useImperativeHandle(ref, () => ({ toggle }), [toggle]);
1116
1176
  const title = sprintf2(
1117
1177
  /* translators: %s: Variable Type. */
1118
1178
  __7("%s variables", "elementor"),
@@ -1134,7 +1194,8 @@ var VariablePromotionChip = forwardRef(
1134
1194
  onClose: (e) => {
1135
1195
  e.stopPropagation();
1136
1196
  setIsOpen(false);
1137
- }
1197
+ },
1198
+ onCtaClick: () => trackUpgradePromotionClick(trackingData)
1138
1199
  },
1139
1200
  /* @__PURE__ */ React6.createElement(
1140
1201
  Box,
@@ -1152,6 +1213,11 @@ var VariablePromotionChip = forwardRef(
1152
1213
  );
1153
1214
 
1154
1215
  // src/components/variables-manager/variables-manager-create-menu.tsx
1216
+ var TRACKING_DATA = {
1217
+ target_name: "variables_manager",
1218
+ target_location: "variables_manager",
1219
+ location_l1: "create variable menu"
1220
+ };
1155
1221
  var SIZE = "tiny";
1156
1222
  var VariableManagerCreateMenu = ({ variables, onCreate, menuState }) => {
1157
1223
  const buttonRef = useRef2(null);
@@ -1234,24 +1300,30 @@ var MenuOption = ({
1234
1300
  {
1235
1301
  variableType: config.variableType,
1236
1302
  upgradeUrl: `https://go.elementor.com/go-pro-manager-${config.variableType}-variable/`,
1237
- ref: promotionRef
1303
+ ref: promotionRef,
1304
+ trackingData: TRACKING_DATA
1238
1305
  }
1239
1306
  ));
1240
1307
  };
1241
1308
  var getDefaultName = (variables, baseName) => {
1242
1309
  const pattern = new RegExp(`^${baseName}-(\\d+)$`, "i");
1243
- let counter = 1;
1310
+ const takenNumbers = /* @__PURE__ */ new Set();
1244
1311
  Object.values(variables).forEach((variable) => {
1245
- if (pattern.test(variable.label)) {
1246
- counter = Math.max(counter, parseInt(variable.label.match(pattern)?.[1] ?? "0", 10) + 1);
1312
+ const match = variable.label.match(pattern);
1313
+ if (match) {
1314
+ takenNumbers.add(parseInt(match[1], 10));
1247
1315
  }
1248
1316
  });
1317
+ let counter = 1;
1318
+ while (takenNumbers.has(counter)) {
1319
+ counter++;
1320
+ }
1249
1321
  return `${baseName}-${counter}`;
1250
1322
  };
1251
1323
 
1252
1324
  // src/components/variables-manager/variables-manager-table.tsx
1253
1325
  import * as React13 from "react";
1254
- import { useEffect as useEffect2, useRef as useRef6 } from "react";
1326
+ import { useEffect as useEffect3, useRef as useRef6 } from "react";
1255
1327
  import {
1256
1328
  Table,
1257
1329
  TableBody,
@@ -1376,7 +1448,7 @@ var LabelField = ({
1376
1448
 
1377
1449
  // src/components/variables-manager/variable-editable-cell.tsx
1378
1450
  import * as React10 from "react";
1379
- import { useCallback as useCallback4, 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";
1380
1452
  import { ClickAwayListener, Stack as Stack4 } from "@elementor/ui";
1381
1453
  var VariableEditableCell = React10.memo(
1382
1454
  ({
@@ -1397,17 +1469,17 @@ var VariableEditableCell = React10.memo(
1397
1469
  const { labelFieldError, setLabelFieldError } = useLabelError();
1398
1470
  const [valueFieldError, setValueFieldError] = useState5("");
1399
1471
  const rowRef = useRef4(null);
1400
- const handleSave = useCallback4(() => {
1472
+ const handleSave = useCallback5(() => {
1401
1473
  const hasError = fieldType === "label" && labelFieldError?.message || fieldType === "value" && valueFieldError;
1402
1474
  if (!hasError) {
1403
1475
  onChange(value);
1404
1476
  }
1405
1477
  setIsEditing(false);
1406
1478
  }, [value, onChange, fieldType, labelFieldError, valueFieldError]);
1407
- useEffect(() => {
1479
+ useEffect2(() => {
1408
1480
  onRowRef?.(rowRef?.current);
1409
1481
  }, [onRowRef]);
1410
- useEffect(() => {
1482
+ useEffect2(() => {
1411
1483
  if (autoEdit && !isEditing && !disabled) {
1412
1484
  setIsEditing(true);
1413
1485
  onAutoEditComplete?.();
@@ -1433,10 +1505,10 @@ var VariableEditableCell = React10.memo(
1433
1505
  setIsEditing(true);
1434
1506
  }
1435
1507
  };
1436
- const handleChange = useCallback4((newValue) => {
1508
+ const handleChange = useCallback5((newValue) => {
1437
1509
  setValue(newValue);
1438
1510
  }, []);
1439
- const handleValidationChange = useCallback4(
1511
+ const handleValidationChange = useCallback5(
1440
1512
  (errorMsg) => {
1441
1513
  if (fieldType === "label") {
1442
1514
  setLabelFieldError({
@@ -1567,6 +1639,7 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
1567
1639
  };
1568
1640
 
1569
1641
  // src/components/variables-manager/ui/variable-table-row.tsx
1642
+ var TRACKING_DATA2 = { target_name: "variables_manager", target_location: "variables_manager" };
1570
1643
  var VariableRow = (props) => {
1571
1644
  const {
1572
1645
  row,
@@ -1729,7 +1802,8 @@ var VariableRow = (props) => {
1729
1802
  {
1730
1803
  variableType: row.variableType,
1731
1804
  upgradeUrl: `https://go.elementor.com/renew-license-manager-${row.variableType}-variable`,
1732
- ref: promotionRef
1805
+ ref: promotionRef,
1806
+ trackingData: TRACKING_DATA2
1733
1807
  }
1734
1808
  ), /* @__PURE__ */ React12.createElement(VariableEditMenu, { menuActions: menuActions(row.id), disabled: isSorting, itemId: row.id })))
1735
1809
  );
@@ -1746,7 +1820,7 @@ var VariablesManagerTable = ({
1746
1820
  }) => {
1747
1821
  const tableContainerRef = useRef6(null);
1748
1822
  const variableRowRefs = useRef6(/* @__PURE__ */ new Map());
1749
- useEffect2(() => {
1823
+ useEffect3(() => {
1750
1824
  if (autoEditVariableId && tableContainerRef.current) {
1751
1825
  const rowElement = variableRowRefs.current.get(autoEditVariableId);
1752
1826
  if (rowElement) {
@@ -1867,8 +1941,8 @@ function VariablesManagerPanel() {
1867
1941
  handleOnChange,
1868
1942
  createVariable: createVariable2,
1869
1943
  handleDeleteVariable,
1870
- handleStartSync,
1871
- handleStopSync,
1944
+ handleStartSync: startSyncFromState,
1945
+ handleStopSync: stopSyncFromState,
1872
1946
  handleSave,
1873
1947
  isSaving,
1874
1948
  handleSearch,
@@ -1888,7 +1962,7 @@ function VariablesManagerPanel() {
1888
1962
  }
1889
1963
  closePanel();
1890
1964
  };
1891
- const handleCreateVariable = useCallback5(
1965
+ const handleCreateVariable = useCallback6(
1892
1966
  (type, defaultName, defaultValue) => {
1893
1967
  const newId = createVariable2(type, defaultName, defaultValue);
1894
1968
  if (newId) {
@@ -1922,31 +1996,44 @@ function VariablesManagerPanel() {
1922
1996
  setIsSaving(false);
1923
1997
  }
1924
1998
  };
1925
- const handleDeleteVariableWithConfirmation = useCallback5(
1999
+ const handleDeleteVariableWithConfirmation = useCallback6(
1926
2000
  (itemId) => {
1927
2001
  handleDeleteVariable(itemId);
1928
2002
  setDeleteConfirmation(null);
1929
2003
  },
1930
2004
  [handleDeleteVariable]
1931
2005
  );
1932
- const handleStopSyncWithConfirmation = useCallback5(
2006
+ const commitStopSync = useCallback6(
1933
2007
  (itemId) => {
1934
- handleStopSync(itemId);
1935
- setStopSyncConfirmation(null);
2008
+ stopSyncFromState(itemId);
2009
+ const variable = variables[itemId];
2010
+ if (variable) {
2011
+ trackVariableSyncToV3({ variableLabel: variable.label, action: "unsync" });
2012
+ }
1936
2013
  },
1937
- [handleStopSync]
2014
+ [stopSyncFromState, variables]
1938
2015
  );
1939
- const handleShowStopSyncDialog = useCallback5(
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(
1940
2027
  (itemId) => {
1941
2028
  if (!isStopSyncSuppressed) {
1942
2029
  setStopSyncConfirmation(itemId);
1943
2030
  } else {
1944
- handleStopSync(itemId);
2031
+ commitStopSync(itemId);
1945
2032
  }
1946
2033
  },
1947
- [isStopSyncSuppressed, handleStopSync]
2034
+ [isStopSyncSuppressed, commitStopSync]
1948
2035
  );
1949
- const buildMenuActions = useCallback5(
2036
+ const buildMenuActions = useCallback6(
1950
2037
  (variableId) => {
1951
2038
  const variable = variables[variableId];
1952
2039
  if (!variable) {
@@ -1957,7 +2044,7 @@ function VariablesManagerPanel() {
1957
2044
  variableId,
1958
2045
  handlers: {
1959
2046
  onStartSync: handleStartSync,
1960
- onStopSync: handleShowStopSyncDialog
2047
+ onStopSync: handleStopSync
1961
2048
  }
1962
2049
  });
1963
2050
  const deleteAction = {
@@ -1975,7 +2062,7 @@ function VariablesManagerPanel() {
1975
2062
  };
1976
2063
  return [...typeActions, deleteAction];
1977
2064
  },
1978
- [variables, handleStartSync, handleShowStopSyncDialog]
2065
+ [variables, handleStartSync, handleStopSync]
1979
2066
  );
1980
2067
  const hasVariables = Object.keys(variables).length > 0;
1981
2068
  return /* @__PURE__ */ React14.createElement(ThemeProvider, null, /* @__PURE__ */ React14.createElement(Panel, null, /* @__PURE__ */ React14.createElement(
@@ -2110,7 +2197,10 @@ function VariablesManagerPanel() {
2110
2197
  {
2111
2198
  open: true,
2112
2199
  onClose: () => setStopSyncConfirmation(null),
2113
- onConfirm: () => handleStopSyncWithConfirmation(stopSyncConfirmation)
2200
+ onConfirm: () => {
2201
+ commitStopSync(stopSyncConfirmation);
2202
+ setStopSyncConfirmation(null);
2203
+ }
2114
2204
  }
2115
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(
2116
2206
  SaveChangesDialog.Actions,
@@ -2138,7 +2228,7 @@ function VariablesManagerPanel() {
2138
2228
  )));
2139
2229
  }
2140
2230
  var usePreventUnload = (isDirty) => {
2141
- useEffect3(() => {
2231
+ useEffect4(() => {
2142
2232
  const handleBeforeUnload = (event) => {
2143
2233
  if (isDirty) {
2144
2234
  event.preventDefault();
@@ -2153,7 +2243,7 @@ var usePreventUnload = (isDirty) => {
2153
2243
  var StopSyncConfirmationDialog = ({ open, onClose, onConfirm }) => {
2154
2244
  const [, suppressStopSyncMessage] = useSuppressedMessage(STOP_SYNC_MESSAGE_KEY);
2155
2245
  return /* @__PURE__ */ React14.createElement(ConfirmationDialog2, { open, onClose }, /* @__PURE__ */ React14.createElement(ConfirmationDialog2.Title, { icon: ColorFilterIcon, iconColor: "primary" }, __10("Stop syncing variable color", "elementor")), /* @__PURE__ */ React14.createElement(ConfirmationDialog2.Content, null, /* @__PURE__ */ React14.createElement(ConfirmationDialog2.ContentText, null, __10(
2156
- "This will disconnect the variable color from version 3. Existing uses on your site will automatically switch to a default color.",
2246
+ "This will disconnect the variable color from Global Colors. Existing uses on your site will automatically switch to a default color.",
2157
2247
  "elementor"
2158
2248
  ))), /* @__PURE__ */ React14.createElement(
2159
2249
  ConfirmationDialog2.Actions,
@@ -2169,20 +2259,54 @@ var StopSyncConfirmationDialog = ({ open, onClose, onConfirm }) => {
2169
2259
  ));
2170
2260
  };
2171
2261
 
2262
+ // src/components/open-panel-from-event.tsx
2263
+ var EVENT_NAME = "elementor/open-variables-manager";
2264
+ var DEFAULT_PANEL_ROUTE = "panel/elements/categories";
2265
+ function OpenPanelFromEvent() {
2266
+ const { open } = usePanelActions();
2267
+ const pendingRef = useRef7(false);
2268
+ const [readyToOpen, setReadyToOpen] = useState7(false);
2269
+ useEffect5(() => {
2270
+ if (readyToOpen) {
2271
+ setReadyToOpen(false);
2272
+ open();
2273
+ }
2274
+ }, [readyToOpen, open]);
2275
+ useEffect5(() => {
2276
+ return listenTo(routeOpenEvent(DEFAULT_PANEL_ROUTE), () => {
2277
+ if (pendingRef.current) {
2278
+ pendingRef.current = false;
2279
+ setReadyToOpen(true);
2280
+ }
2281
+ });
2282
+ }, []);
2283
+ useEffect5(() => {
2284
+ const handler = () => {
2285
+ pendingRef.current = true;
2286
+ openRoute(DEFAULT_PANEL_ROUTE);
2287
+ };
2288
+ window.addEventListener(EVENT_NAME, handler);
2289
+ return () => window.removeEventListener(EVENT_NAME, handler);
2290
+ }, []);
2291
+ return null;
2292
+ }
2293
+
2172
2294
  // src/components/open-panel-from-url.tsx
2295
+ import { useEffect as useEffect6, useRef as useRef8 } from "react";
2296
+ import { __privateListenTo as listenTo2, routeOpenEvent as routeOpenEvent2 } from "@elementor/editor-v1-adapters";
2173
2297
  var ACTIVE_PANEL_PARAM = "active-panel";
2174
2298
  var PANEL_ID = "variables-manager";
2175
- var DEFAULT_PANEL_ROUTE = "panel/elements";
2299
+ var DEFAULT_PANEL_ROUTE2 = "panel/elements";
2176
2300
  function OpenPanelFromUrl() {
2177
2301
  const { open } = usePanelActions();
2178
- const hasOpened = useRef7(false);
2179
- useEffect4(() => {
2302
+ const hasOpened = useRef8(false);
2303
+ useEffect6(() => {
2180
2304
  const urlParams = new URLSearchParams(window.location.search);
2181
2305
  const activePanel = urlParams.get(ACTIVE_PANEL_PARAM);
2182
2306
  if (activePanel !== PANEL_ID) {
2183
2307
  return;
2184
2308
  }
2185
- const cleanup = listenTo(routeOpenEvent(DEFAULT_PANEL_ROUTE), () => {
2309
+ const cleanup = listenTo2(routeOpenEvent2(DEFAULT_PANEL_ROUTE2), () => {
2186
2310
  if (hasOpened.current) {
2187
2311
  return;
2188
2312
  }
@@ -2201,7 +2325,7 @@ import * as React33 from "react";
2201
2325
  import { useBoundProp as useBoundProp11 } from "@elementor/editor-controls";
2202
2326
 
2203
2327
  // src/components/ui/variable/assigned-variable.tsx
2204
- import { useId, useRef as useRef8 } from "react";
2328
+ import { useId, useRef as useRef9 } from "react";
2205
2329
  import * as React24 from "react";
2206
2330
  import { useBoundProp as useBoundProp6 } from "@elementor/editor-controls";
2207
2331
  import { ColorFilterIcon as ColorFilterIcon3 } from "@elementor/icons";
@@ -2225,16 +2349,16 @@ function createUnlinkHandler(variable, propTypeKey, setValue) {
2225
2349
 
2226
2350
  // src/components/variable-selection-popover.tsx
2227
2351
  import * as React22 from "react";
2228
- import { useState as useState12 } from "react";
2352
+ import { useState as useState13 } from "react";
2229
2353
  import { isExperimentActive } from "@elementor/editor-v1-adapters";
2230
2354
 
2231
2355
  // src/context/variable-selection-popover.context.tsx
2232
2356
  import * as React15 from "react";
2233
- import { createContext as createContext2, useContext as useContext2, useState as useState7 } from "react";
2357
+ import { createContext as createContext2, useContext as useContext2, useState as useState8 } from "react";
2234
2358
  import { Box as Box2 } from "@elementor/ui";
2235
2359
  var PopoverContentRefContext = createContext2(null);
2236
2360
  var PopoverContentRefContextProvider = ({ children }) => {
2237
- const [anchorRef, setAnchorRef] = useState7(null);
2361
+ const [anchorRef, setAnchorRef] = useState8(null);
2238
2362
  return /* @__PURE__ */ React15.createElement(PopoverContentRefContext.Provider, { value: anchorRef }, /* @__PURE__ */ React15.createElement(Box2, { ref: setAnchorRef }, children));
2239
2363
  };
2240
2364
  var usePopoverContentRef = () => {
@@ -2243,7 +2367,7 @@ var usePopoverContentRef = () => {
2243
2367
 
2244
2368
  // src/components/variable-creation.tsx
2245
2369
  import * as React17 from "react";
2246
- import { useState as useState8 } from "react";
2370
+ import { useState as useState9 } from "react";
2247
2371
  import { PopoverContent, useBoundProp as useBoundProp4 } from "@elementor/editor-controls";
2248
2372
  import { PopoverHeader, SectionPopoverBody } from "@elementor/editor-ui";
2249
2373
  import { ArrowLeftIcon } from "@elementor/icons";
@@ -2304,11 +2428,11 @@ var VariableCreation = ({ onGoBack, onClose }) => {
2304
2428
  const { setVariableValue: setVariable, path } = useVariableBoundProp();
2305
2429
  const { propType } = useBoundProp4();
2306
2430
  const initialValue = useInitialValue();
2307
- const [value, setValue] = useState8(initialValue);
2308
- const [label, setLabel] = useState8("");
2309
- const [errorMessage, setErrorMessage] = useState8("");
2310
- const [valueFieldError, setValueFieldError] = useState8("");
2311
- const [propTypeKey, setPropTypeKey] = useState8(propTypeUtil.key);
2431
+ const [value, setValue] = useState9(initialValue);
2432
+ const [label, setLabel] = useState9("");
2433
+ const [errorMessage, setErrorMessage] = useState9("");
2434
+ const [valueFieldError, setValueFieldError] = useState9("");
2435
+ const [propTypeKey, setPropTypeKey] = useState9(propTypeUtil.key);
2312
2436
  const { labelFieldError, setLabelFieldError } = useLabelError();
2313
2437
  const resetFields = () => {
2314
2438
  setValue("");
@@ -2392,11 +2516,12 @@ var VariableCreation = ({ onGoBack, onClose }) => {
2392
2516
  },
2393
2517
  onErrorChange: (errorMsg) => {
2394
2518
  setLabelFieldError({
2395
- value: label,
2519
+ value: "",
2396
2520
  message: errorMsg
2397
2521
  });
2398
2522
  },
2399
- onKeyDown: handleKeyDown
2523
+ onKeyDown: handleKeyDown,
2524
+ focusOnShow: true
2400
2525
  }
2401
2526
  )
2402
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(
@@ -2428,7 +2553,7 @@ var VariableCreation = ({ onGoBack, onClose }) => {
2428
2553
 
2429
2554
  // src/components/variable-edit.tsx
2430
2555
  import * as React19 from "react";
2431
- import { useEffect as useEffect5, useState as useState10 } from "react";
2556
+ import { useEffect as useEffect7, useState as useState11 } from "react";
2432
2557
  import { PopoverContent as PopoverContent2, useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
2433
2558
  import { useSuppressedMessage as useSuppressedMessage2 } from "@elementor/editor-current-user";
2434
2559
  import { PopoverHeader as PopoverHeader2, SectionPopoverBody as SectionPopoverBody2 } from "@elementor/editor-ui";
@@ -2438,7 +2563,7 @@ import { __ as __13 } from "@wordpress/i18n";
2438
2563
 
2439
2564
  // src/components/ui/edit-confirmation-dialog.tsx
2440
2565
  import * as React18 from "react";
2441
- import { useState as useState9 } from "react";
2566
+ import { useState as useState10 } from "react";
2442
2567
  import { AlertTriangleFilledIcon as AlertTriangleFilledIcon3 } from "@elementor/icons";
2443
2568
  import {
2444
2569
  Button as Button4,
@@ -2458,7 +2583,7 @@ var EditConfirmationDialog = ({
2458
2583
  onConfirm,
2459
2584
  onSuppressMessage
2460
2585
  }) => {
2461
- const [dontShowAgain, setDontShowAgain] = useState9(false);
2586
+ const [dontShowAgain, setDontShowAgain] = useState10(false);
2462
2587
  const handleSave = () => {
2463
2588
  if (dontShowAgain) {
2464
2589
  onSuppressMessage?.();
@@ -2492,20 +2617,20 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2492
2617
  const { setVariableValue: notifyBoundPropChange, variableId } = useVariableBoundProp();
2493
2618
  const { propType } = useBoundProp5();
2494
2619
  const [isMessageSuppressed, suppressMessage] = useSuppressedMessage2(EDIT_CONFIRMATION_DIALOG_ID);
2495
- const [deleteConfirmation, setDeleteConfirmation] = useState10(false);
2496
- const [editConfirmation, setEditConfirmation] = useState10(false);
2497
- const [errorMessage, setErrorMessage] = useState10("");
2498
- const [valueFieldError, setValueFieldError] = useState10("");
2620
+ const [deleteConfirmation, setDeleteConfirmation] = useState11(false);
2621
+ const [editConfirmation, setEditConfirmation] = useState11(false);
2622
+ const [errorMessage, setErrorMessage] = useState11("");
2623
+ const [valueFieldError, setValueFieldError] = useState11("");
2499
2624
  const { labelFieldError, setLabelFieldError } = useLabelError();
2500
2625
  const variable = useVariable(editId);
2501
- const [propTypeKey, setPropTypeKey] = useState10(variable?.type ?? propTypeUtil.key);
2626
+ const [propTypeKey, setPropTypeKey] = useState11(variable?.type ?? propTypeUtil.key);
2502
2627
  if (!variable) {
2503
2628
  throw new Error(`Global ${variableType} variable not found`);
2504
2629
  }
2505
2630
  const userPermissions = usePermissions();
2506
- const [value, setValue] = useState10(() => variable.value);
2507
- const [label, setLabel] = useState10(() => variable.label);
2508
- useEffect5(() => {
2631
+ const [value, setValue] = useState11(() => variable.value);
2632
+ const [label, setLabel] = useState11(() => variable.label);
2633
+ useEffect7(() => {
2509
2634
  styleVariablesRepository.update({
2510
2635
  [editId]: {
2511
2636
  ...variable,
@@ -2628,11 +2753,12 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2628
2753
  },
2629
2754
  onErrorChange: (errorMsg) => {
2630
2755
  setLabelFieldError({
2631
- value: label,
2756
+ value: "",
2632
2757
  message: errorMsg
2633
2758
  });
2634
2759
  },
2635
- onKeyDown: handleKeyDown
2760
+ onKeyDown: handleKeyDown,
2761
+ focusOnShow: true
2636
2762
  }
2637
2763
  )
2638
2764
  ), ValueField && /* @__PURE__ */ React19.createElement(FormField, { errorMsg: valueFieldError, label: __13("Value", "elementor") }, /* @__PURE__ */ React19.createElement(Typography8, { variant: "h5" }, /* @__PURE__ */ React19.createElement(
@@ -2669,8 +2795,9 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
2669
2795
  };
2670
2796
 
2671
2797
  // src/components/variables-selection.tsx
2672
- import { useState as useState11 } from "react";
2798
+ import { useEffect as useEffect8, useState as useState12 } from "react";
2673
2799
  import * as React21 from "react";
2800
+ import { trackUpgradePromotionClick as trackUpgradePromotionClick2, trackViewPromotion as trackViewPromotion2 } from "@elementor/editor-controls";
2674
2801
  import {
2675
2802
  PopoverHeader as PopoverHeader3,
2676
2803
  PopoverMenuList,
@@ -2781,7 +2908,7 @@ var getProUpgradeUrl = (variableType) => `https://go.elementor.com/renew-license
2781
2908
  var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings, disabled = false }) => {
2782
2909
  const { icon: VariableIcon, startIcon, variableType, propTypeUtil, emptyState } = useVariableType();
2783
2910
  const { value: variable, setValue: setVariable, path } = useVariableBoundProp();
2784
- const [searchValue, setSearchValue] = useState11("");
2911
+ const [searchValue, setSearchValue] = useState12("");
2785
2912
  const {
2786
2913
  list: variables,
2787
2914
  hasMatches: hasSearchResults,
@@ -2858,6 +2985,15 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings, disabled =
2858
2985
  const handleClearSearch = () => {
2859
2986
  setSearchValue("");
2860
2987
  };
2988
+ useEffect8(() => {
2989
+ if (disabled) {
2990
+ trackViewPromotion2({
2991
+ target_name: "variables_popover",
2992
+ target_location: "widget_panel",
2993
+ location_l1: "variables_list"
2994
+ });
2995
+ }
2996
+ }, [disabled]);
2861
2997
  return /* @__PURE__ */ React21.createElement(SectionPopoverBody3, null, /* @__PURE__ */ React21.createElement(
2862
2998
  PopoverHeader3,
2863
2999
  {
@@ -2894,7 +3030,11 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings, disabled =
2894
3030
  __15("Upgrade to continue creating and editing %s variables.", "elementor"),
2895
3031
  variableType
2896
3032
  ),
2897
- upgradeUrl: getProUpgradeUrl(variableType)
3033
+ upgradeUrl: getProUpgradeUrl(variableType),
3034
+ onCtaClick: () => trackUpgradePromotionClick2({
3035
+ target_name: "variables_popover",
3036
+ location_l1: "variables_list"
3037
+ })
2898
3038
  }
2899
3039
  )), !hasSearchResults && hasVariables && /* @__PURE__ */ React21.createElement(
2900
3040
  NoSearchResults,
@@ -2953,8 +3093,8 @@ var VIEW_LIST = "list";
2953
3093
  var VIEW_ADD = "add";
2954
3094
  var VIEW_EDIT = "edit";
2955
3095
  var VariableSelectionPopover = ({ closePopover, propTypeKey, selectedVariable }) => {
2956
- const [currentView, setCurrentView] = useState12(VIEW_LIST);
2957
- const [editId, setEditId] = useState12("");
3096
+ const [currentView, setCurrentView] = useState13(VIEW_LIST);
3097
+ const [editId, setEditId] = useState13("");
2958
3098
  const { open } = usePanelActions();
2959
3099
  const onSettingsAvailable = isExperimentActive("e_variables_manager") ? () => {
2960
3100
  open();
@@ -3065,7 +3205,7 @@ var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
3065
3205
  var AssignedVariable = ({ variable, propTypeKey }) => {
3066
3206
  const { startIcon, propTypeUtil } = getVariableType(propTypeKey);
3067
3207
  const { setValue } = useBoundProp6();
3068
- const anchorRef = useRef8(null);
3208
+ const anchorRef = useRef9(null);
3069
3209
  const popupId = useId();
3070
3210
  const popupState = usePopupState3({
3071
3211
  variant: "popover",
@@ -3106,14 +3246,14 @@ var AssignedVariable = ({ variable, propTypeKey }) => {
3106
3246
 
3107
3247
  // src/components/ui/variable/deleted-variable.tsx
3108
3248
  import * as React28 from "react";
3109
- import { useId as useId2, useRef as useRef9, useState as useState14 } from "react";
3249
+ import { useId as useId2, useRef as useRef10, useState as useState15 } from "react";
3110
3250
  import { useBoundProp as useBoundProp8 } from "@elementor/editor-controls";
3111
3251
  import { Backdrop, bindPopover as bindPopover2, Box as Box7, Infotip as Infotip2, Popover as Popover2, usePopupState as usePopupState4 } from "@elementor/ui";
3112
3252
  import { __ as __19 } from "@wordpress/i18n";
3113
3253
 
3114
3254
  // src/components/variable-restore.tsx
3115
3255
  import * as React25 from "react";
3116
- import { useState as useState13 } from "react";
3256
+ import { useState as useState14 } from "react";
3117
3257
  import { PopoverContent as PopoverContent3, useBoundProp as useBoundProp7 } from "@elementor/editor-controls";
3118
3258
  import { PopoverHeader as PopoverHeader4, SectionPopoverBody as SectionPopoverBody4 } from "@elementor/editor-ui";
3119
3259
  import { Button as Button6, CardActions as CardActions3, Divider as Divider5, FormHelperText as FormHelperText4, Typography as Typography11 } from "@elementor/ui";
@@ -3127,11 +3267,11 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
3127
3267
  if (!variable) {
3128
3268
  throw new Error(`Global ${variableType} variable not found`);
3129
3269
  }
3130
- const [errorMessage, setErrorMessage] = useState13("");
3131
- const [valueFieldError, setValueFieldError] = useState13("");
3132
- const [label, setLabel] = useState13(variable.label);
3133
- const [value, setValue] = useState13(variable.value);
3134
- const [propTypeKey, setPropTypeKey] = useState13(variable?.type ?? propTypeUtil.key);
3270
+ const [errorMessage, setErrorMessage] = useState14("");
3271
+ const [valueFieldError, setValueFieldError] = useState14("");
3272
+ const [label, setLabel] = useState14(variable.label);
3273
+ const [value, setValue] = useState14(variable.value);
3274
+ const [propTypeKey, setPropTypeKey] = useState14(variable?.type ?? propTypeUtil.key);
3135
3275
  const { labelFieldError, setLabelFieldError } = useLabelError({
3136
3276
  value: variable.label,
3137
3277
  message: ERROR_MESSAGES.DUPLICATED_LABEL
@@ -3204,11 +3344,12 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
3204
3344
  },
3205
3345
  onErrorChange: (errorMsg) => {
3206
3346
  setLabelFieldError({
3207
- value: label,
3347
+ value: "",
3208
3348
  message: errorMsg
3209
3349
  });
3210
3350
  },
3211
- onKeyDown: handleKeyDown
3351
+ onKeyDown: handleKeyDown,
3352
+ focusOnShow: true
3212
3353
  }
3213
3354
  )
3214
3355
  ), ValueField && /* @__PURE__ */ React25.createElement(FormField, { errorMsg: valueFieldError, label: __17("Value", "elementor") }, /* @__PURE__ */ React25.createElement(Typography11, { variant: "h5" }, /* @__PURE__ */ React25.createElement(
@@ -3287,10 +3428,10 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
3287
3428
  const { propTypeUtil } = getVariableType(propTypeKey);
3288
3429
  const boundProp = useBoundProp8();
3289
3430
  const userPermissions = usePermissions();
3290
- const [showInfotip, setShowInfotip] = useState14(false);
3431
+ const [showInfotip, setShowInfotip] = useState15(false);
3291
3432
  const toggleInfotip = () => setShowInfotip((prev) => !prev);
3292
3433
  const closeInfotip = () => setShowInfotip(false);
3293
- const deletedChipAnchorRef = useRef9(null);
3434
+ const deletedChipAnchorRef = useRef10(null);
3294
3435
  const popupId = useId2();
3295
3436
  const popupState = usePopupState4({
3296
3437
  variant: "popover",
@@ -3378,7 +3519,7 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
3378
3519
 
3379
3520
  // src/components/ui/variable/mismatch-variable.tsx
3380
3521
  import * as React30 from "react";
3381
- import { useId as useId3, useRef as useRef10, useState as useState15 } from "react";
3522
+ import { useId as useId3, useRef as useRef11, useState as useState16 } from "react";
3382
3523
  import { useBoundProp as useBoundProp9 } from "@elementor/editor-controls";
3383
3524
  import { Backdrop as Backdrop2, bindPopover as bindPopover3, Box as Box8, Infotip as Infotip3, Popover as Popover3, usePopupState as usePopupState5 } from "@elementor/ui";
3384
3525
  import { __ as __21 } from "@wordpress/i18n";
@@ -3416,13 +3557,13 @@ var MismatchVariableAlert = ({ onClose, onClear, triggerSelect }) => {
3416
3557
  // src/components/ui/variable/mismatch-variable.tsx
3417
3558
  var MismatchVariable = ({ variable }) => {
3418
3559
  const { setValue, value } = useBoundProp9();
3419
- const anchorRef = useRef10(null);
3560
+ const anchorRef = useRef11(null);
3420
3561
  const popupId = useId3();
3421
3562
  const popupState = usePopupState5({
3422
3563
  variant: "popover",
3423
3564
  popupId: `elementor-variables-list-${popupId}`
3424
3565
  });
3425
- const [infotipVisible, setInfotipVisible] = useState15(false);
3566
+ const [infotipVisible, setInfotipVisible] = useState16(false);
3426
3567
  const toggleInfotip = () => setInfotipVisible((prev) => !prev);
3427
3568
  const closeInfotip = () => setInfotipVisible(false);
3428
3569
  const triggerSelect = () => {
@@ -3495,7 +3636,7 @@ var MismatchVariable = ({ variable }) => {
3495
3636
 
3496
3637
  // src/components/ui/variable/missing-variable.tsx
3497
3638
  import * as React32 from "react";
3498
- import { useState as useState16 } from "react";
3639
+ import { useState as useState17 } from "react";
3499
3640
  import { useBoundProp as useBoundProp10 } from "@elementor/editor-controls";
3500
3641
  import { Backdrop as Backdrop3, Infotip as Infotip4 } from "@elementor/ui";
3501
3642
  import { __ as __23 } from "@wordpress/i18n";
@@ -3525,7 +3666,7 @@ var MissingVariableAlert = ({ onClose, onClear }) => {
3525
3666
  // src/components/ui/variable/missing-variable.tsx
3526
3667
  var MissingVariable = () => {
3527
3668
  const { setValue } = useBoundProp10();
3528
- const [infotipVisible, setInfotipVisible] = useState16(false);
3669
+ const [infotipVisible, setInfotipVisible] = useState17(false);
3529
3670
  const toggleInfotip = () => setInfotipVisible((prev) => !prev);
3530
3671
  const closeInfotip = () => setInfotipVisible(false);
3531
3672
  const clearValue = () => setValue(null);
@@ -3613,22 +3754,15 @@ var trackOpenVariablePopover = (path, variableType) => {
3613
3754
  });
3614
3755
  };
3615
3756
 
3616
- // src/mcp/index.ts
3617
- import { isAngieAvailable } from "@elementor/editor-mcp";
3618
-
3619
3757
  // src/mcp/manage-variable-tool.ts
3620
- import { getMCPByDomain as getMCPByDomain2 } from "@elementor/editor-mcp";
3621
3758
  import { z as z3 } from "@elementor/schema";
3622
3759
 
3623
3760
  // src/mcp/variables-resource.ts
3624
- import { getMCPByDomain } from "@elementor/editor-mcp";
3625
3761
  var GLOBAL_VARIABLES_URI = "elementor://global-variables";
3626
- var initVariablesResource = () => {
3627
- const canvasMcpEntry = getMCPByDomain("canvas");
3628
- const variablesMcpEntry = getMCPByDomain("variables");
3762
+ var initVariablesResource = (variablesMcpEntry, canvasMcpEntry) => {
3629
3763
  [canvasMcpEntry, variablesMcpEntry].forEach((entry) => {
3630
- const { mcpServer } = entry;
3631
- mcpServer.resource(
3764
+ const { resource, sendResourceUpdated } = entry;
3765
+ resource(
3632
3766
  "global-variables",
3633
3767
  GLOBAL_VARIABLES_URI,
3634
3768
  {
@@ -3647,7 +3781,7 @@ var initVariablesResource = () => {
3647
3781
  }
3648
3782
  );
3649
3783
  window.addEventListener("variables:updated", () => {
3650
- mcpServer.server.sendResourceUpdated({
3784
+ sendResourceUpdated({
3651
3785
  uri: GLOBAL_VARIABLES_URI
3652
3786
  });
3653
3787
  });
@@ -3655,8 +3789,9 @@ var initVariablesResource = () => {
3655
3789
  };
3656
3790
 
3657
3791
  // src/mcp/manage-variable-tool.ts
3658
- var initManageVariableTool = () => {
3659
- getMCPByDomain2("variables").addTool({
3792
+ var initManageVariableTool = (reg) => {
3793
+ const { addTool } = reg;
3794
+ addTool({
3660
3795
  name: "manage-global-variable",
3661
3796
  schema: {
3662
3797
  action: z3.enum(["create", "update", "delete"]).describe("Operation to perform"),
@@ -3726,30 +3861,36 @@ function getServiceActions(svc) {
3726
3861
  }
3727
3862
 
3728
3863
  // src/mcp/index.ts
3729
- function initMcp() {
3730
- if (!isAngieAvailable()) {
3731
- return;
3732
- }
3733
- initManageVariableTool();
3734
- 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);
3735
3876
  }
3736
3877
 
3737
3878
  // src/register-variable-types.tsx
3738
3879
  import * as React37 from "react";
3880
+ import { trackUpgradePromotionClick as trackUpgradePromotionClick3 } from "@elementor/editor-controls";
3739
3881
  import { colorPropTypeUtil, sizePropTypeUtil, stringPropTypeUtil } from "@elementor/editor-props";
3740
3882
  import { CtaButton } from "@elementor/editor-ui";
3741
- import { isExperimentActive as isExperimentActive2 } from "@elementor/editor-v1-adapters";
3742
- import { BrushIcon, ExpandDiagonalIcon, ResetIcon, TextIcon as TextIcon2 } from "@elementor/icons";
3883
+ import { BrushIcon, ExpandDiagonalIcon, RefreshIcon, RefreshOffIcon, TextIcon as TextIcon2 } from "@elementor/icons";
3743
3884
  import { __ as __26 } from "@wordpress/i18n";
3744
3885
 
3745
3886
  // src/components/fields/color-field.tsx
3746
3887
  import * as React35 from "react";
3747
- import { useRef as useRef11, useState as useState17 } from "react";
3888
+ import { useRef as useRef12, useState as useState18 } from "react";
3748
3889
  import { UnstableColorField } from "@elementor/ui";
3749
3890
  var ColorField = ({ value, onChange, onValidationChange }) => {
3750
- const [color, setColor] = useState17(value);
3751
- const [errorMessage, setErrorMessage] = useState17("");
3752
- const defaultRef = useRef11(null);
3891
+ const [color, setColor] = useState18(value);
3892
+ const [errorMessage, setErrorMessage] = useState18("");
3893
+ const defaultRef = useRef12(null);
3753
3894
  const anchorRef = usePopoverContentRef() ?? defaultRef.current;
3754
3895
  const handleChange = (newValue) => {
3755
3896
  setColor(newValue);
@@ -3788,15 +3929,15 @@ var ColorField = ({ value, onChange, onValidationChange }) => {
3788
3929
 
3789
3930
  // src/components/fields/font-field.tsx
3790
3931
  import * as React36 from "react";
3791
- import { useId as useId4, useRef as useRef12, useState as useState18 } from "react";
3932
+ import { useId as useId4, useRef as useRef13, useState as useState19 } from "react";
3792
3933
  import { enqueueFont as enqueueFont2, ItemSelector, useFontFamilies } from "@elementor/editor-controls";
3793
3934
  import { useSectionWidth } from "@elementor/editor-ui";
3794
3935
  import { ChevronDownIcon, TextIcon } from "@elementor/icons";
3795
3936
  import { bindPopover as bindPopover4, bindTrigger as bindTrigger4, Popover as Popover4, UnstableTag, usePopupState as usePopupState6 } from "@elementor/ui";
3796
3937
  import { __ as __25 } from "@wordpress/i18n";
3797
3938
  var FontField = ({ value, onChange, onValidationChange }) => {
3798
- const [fontFamily, setFontFamily] = useState18(value);
3799
- const defaultRef = useRef12(null);
3939
+ const [fontFamily, setFontFamily] = useState19(value);
3940
+ const defaultRef = useRef13(null);
3800
3941
  const anchorRef = usePopoverContentRef() ?? defaultRef.current;
3801
3942
  const fontPopoverState = usePopupState6({ variant: "popover" });
3802
3943
  const fontFamilies = useFontFamilies();
@@ -3880,20 +4021,17 @@ function registerVariableTypes() {
3880
4021
  defaultValue: "#ffffff",
3881
4022
  menuActionsFactory: ({ variable, variableId, handlers }) => {
3882
4023
  const actions = [];
3883
- if (!isExperimentActive2("e_design_system_sync")) {
3884
- return [];
3885
- }
3886
4024
  if (variable.sync_to_v3) {
3887
4025
  actions.push({
3888
- name: __26("Stop syncing to Version 3", "elementor"),
3889
- icon: ResetIcon,
4026
+ name: __26("Stop syncing to Global Colors", "elementor"),
4027
+ icon: RefreshOffIcon,
3890
4028
  color: "text.primary",
3891
4029
  onClick: () => handlers.onStopSync(variableId)
3892
4030
  });
3893
4031
  } else {
3894
4032
  actions.push({
3895
- name: __26("Sync to Version 3", "elementor"),
3896
- icon: ResetIcon,
4033
+ name: __26("Sync to Global Colors", "elementor"),
4034
+ icon: RefreshIcon,
3897
4035
  color: "text.primary",
3898
4036
  onClick: () => handlers.onStartSync(variableId)
3899
4037
  });
@@ -3918,7 +4056,14 @@ function registerVariableTypes() {
3918
4056
  styleTransformer: EmptyTransformer,
3919
4057
  variableType: "size",
3920
4058
  selectionFilter: () => [],
3921
- emptyState: /* @__PURE__ */ React37.createElement(CtaButton, { size: "small", href: "https://go.elementor.com/go-pro-panel-size-variable/" })
4059
+ emptyState: /* @__PURE__ */ React37.createElement(
4060
+ CtaButton,
4061
+ {
4062
+ size: "small",
4063
+ href: "https://go.elementor.com/go-pro-panel-size-variable/",
4064
+ onClick: () => trackUpgradePromotionClick3({ target_name: "variables_popover", location_l1: "variables_list" })
4065
+ }
4066
+ )
3922
4067
  };
3923
4068
  registerVariableType({
3924
4069
  ...sizePromotions,
@@ -3933,14 +4078,14 @@ function registerVariableTypes() {
3933
4078
 
3934
4079
  // src/renderers/style-variables-renderer.tsx
3935
4080
  import * as React38 from "react";
3936
- import { useEffect as useEffect6, useState as useState19 } from "react";
4081
+ import { useEffect as useEffect9, useState as useState20 } from "react";
3937
4082
  import {
3938
4083
  __privateUseListenTo as useListenTo,
3939
4084
  commandEndEvent,
3940
4085
  getCanvasIframeDocument
3941
4086
  } from "@elementor/editor-v1-adapters";
3942
4087
  import { Portal } from "@elementor/ui";
3943
- var VARIABLES_WRAPPER = "body";
4088
+ var VARIABLES_WRAPPER = ":root";
3944
4089
  function StyleVariablesRenderer() {
3945
4090
  const container = usePortalContainer();
3946
4091
  const styleVariables = useStyleVariables();
@@ -3956,8 +4101,8 @@ function usePortalContainer() {
3956
4101
  return useListenTo(commandEndEvent("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
3957
4102
  }
3958
4103
  function useStyleVariables() {
3959
- const [variables, setVariables] = useState19({});
3960
- useEffect6(() => {
4104
+ const [variables, setVariables] = useState20({});
4105
+ useEffect9(() => {
3961
4106
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
3962
4107
  return () => {
3963
4108
  unsubscribe();
@@ -4049,16 +4194,24 @@ function init() {
4049
4194
  useProps: usePropVariableAction
4050
4195
  });
4051
4196
  service.init().then(() => {
4052
- initMcp();
4197
+ initMcp(getMCPByDomain("variables"), getMCPByDomain("canvas"));
4053
4198
  });
4054
4199
  injectIntoTop({
4055
4200
  id: "canvas-style-variables-render",
4056
4201
  component: StyleVariablesRenderer
4057
4202
  });
4203
+ injectIntoLogic({
4204
+ id: "variables-import-listener",
4205
+ component: GlobalStylesImportListener
4206
+ });
4058
4207
  injectIntoLogic({
4059
4208
  id: "variables-open-panel-from-url",
4060
4209
  component: OpenPanelFromUrl
4061
4210
  });
4211
+ injectIntoLogic({
4212
+ id: "variables-open-panel-from-event",
4213
+ component: OpenPanelFromEvent
4214
+ });
4062
4215
  registerPanel(panel);
4063
4216
  }
4064
4217
  function hasVariableAssigned(value) {