@elementor/editor-variables 3.33.0-99 → 3.35.0-324

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/index.d.mts +17 -4
  2. package/dist/index.d.ts +17 -4
  3. package/dist/index.js +1903 -809
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +1850 -747
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +16 -14
  8. package/src/api.ts +24 -0
  9. package/src/batch-operations.ts +86 -0
  10. package/src/components/fields/color-field.tsx +1 -0
  11. package/src/components/fields/font-field.tsx +2 -1
  12. package/src/components/fields/label-field.tsx +42 -6
  13. package/src/components/ui/deleted-variable-alert.tsx +14 -10
  14. package/src/components/ui/{no-variables.tsx → empty-state.tsx} +8 -13
  15. package/src/components/ui/menu-item-content.tsx +14 -11
  16. package/src/components/ui/mismatch-variable-alert.tsx +5 -9
  17. package/src/components/ui/missing-variable-alert.tsx +8 -9
  18. package/src/components/ui/no-search-results.tsx +1 -2
  19. package/src/components/ui/tags/assigned-tag.tsx +6 -3
  20. package/src/components/ui/tags/warning-variable-tag.tsx +44 -0
  21. package/src/components/ui/variable/deleted-variable.tsx +13 -6
  22. package/src/components/ui/variable/mismatch-variable.tsx +11 -4
  23. package/src/components/ui/variable/missing-variable.tsx +2 -2
  24. package/src/components/variable-creation.tsx +13 -4
  25. package/src/components/variable-edit.tsx +12 -12
  26. package/src/components/variable-restore.tsx +3 -2
  27. package/src/components/variables-manager/hooks/use-auto-edit.ts +21 -0
  28. package/src/components/variables-manager/hooks/use-error-navigation.ts +49 -0
  29. package/src/components/variables-manager/hooks/use-variables-manager-state.ts +89 -0
  30. package/src/components/variables-manager/variable-editable-cell.tsx +131 -67
  31. package/src/components/variables-manager/variables-manager-create-menu.tsx +118 -0
  32. package/src/components/variables-manager/variables-manager-panel.tsx +290 -59
  33. package/src/components/variables-manager/variables-manager-table.tsx +124 -14
  34. package/src/components/variables-selection.tsx +61 -15
  35. package/src/controls/variable-control.tsx +1 -1
  36. package/src/hooks/use-prop-variables.ts +28 -9
  37. package/src/hooks/use-variable-bound-prop.ts +42 -0
  38. package/src/index.ts +1 -0
  39. package/src/init.ts +9 -6
  40. package/src/mcp/create-variable-tool.ts +70 -0
  41. package/src/mcp/delete-variable-tool.ts +50 -0
  42. package/src/mcp/index.ts +17 -0
  43. package/src/mcp/list-variables-tool.ts +58 -0
  44. package/src/mcp/update-variable-tool.ts +81 -0
  45. package/src/mcp/variables-resource.ts +28 -0
  46. package/src/register-variable-types.tsx +4 -0
  47. package/src/service.ts +60 -1
  48. package/src/storage.ts +8 -0
  49. package/src/types.ts +1 -0
  50. package/src/utils/filter-by-search.ts +5 -0
  51. package/src/utils/tracking.ts +37 -22
  52. package/src/utils/unlink-variable.ts +1 -1
  53. package/src/utils/validations.ts +72 -3
  54. package/src/variables-registry/create-variable-type-registry.ts +20 -8
  55. package/src/variables-registry/variable-type-registry.ts +2 -1
  56. package/src/components/ui/tags/deleted-tag.tsx +0 -37
  57. package/src/components/ui/tags/mismatch-tag.tsx +0 -37
  58. package/src/components/ui/tags/missing-tag.tsx +0 -25
  59. /package/src/components/variables-manager/{variable-edit-menu.tsx → ui/variable-edit-menu.tsx} +0 -0
  60. /package/src/components/variables-manager/{variable-table-cell.tsx → ui/variable-table-cell.tsx} +0 -0
package/dist/index.js CHANGED
@@ -31,32 +31,159 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
33
  init: () => init,
34
- registerVariableType: () => registerVariableType
34
+ registerVariableType: () => registerVariableType,
35
+ registerVariableTypes: () => registerVariableTypes
35
36
  });
36
37
  module.exports = __toCommonJS(index_exports);
37
38
 
38
39
  // src/init.ts
39
40
  var import_editor = require("@elementor/editor");
40
- var import_editor_editing_panel11 = require("@elementor/editor-editing-panel");
41
+ var import_editor_editing_panel8 = require("@elementor/editor-editing-panel");
41
42
  var import_editor_panels2 = require("@elementor/editor-panels");
43
+ var import_editor_props6 = require("@elementor/editor-props");
42
44
 
43
45
  // src/components/variables-manager/variables-manager-panel.tsx
44
- var React8 = __toESM(require("react"));
45
- var import_react7 = require("react");
46
+ var React12 = __toESM(require("react"));
47
+ var import_react11 = require("react");
46
48
  var import_editor_panels = require("@elementor/editor-panels");
47
- var import_editor_ui2 = require("@elementor/editor-ui");
49
+ var import_editor_ui3 = require("@elementor/editor-ui");
48
50
  var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
49
- var import_icons3 = require("@elementor/icons");
50
- var import_ui8 = require("@elementor/ui");
51
- var import_i18n5 = require("@wordpress/i18n");
51
+ var import_icons6 = require("@elementor/icons");
52
+ var import_ui12 = require("@elementor/ui");
53
+ var import_i18n9 = require("@wordpress/i18n");
52
54
 
53
- // src/hooks/use-prop-variables.ts
54
- var import_react2 = require("react");
55
- var import_editor_controls = require("@elementor/editor-controls");
55
+ // src/utils/tracking.ts
56
+ var import_mixpanel = require("@elementor/mixpanel");
57
+ var trackVariableEvent = ({ varType, controlPath, action }) => {
58
+ const { dispatchEvent, config } = (0, import_mixpanel.getMixpanel)();
59
+ if (!config?.names?.variables?.[action]) {
60
+ return;
61
+ }
62
+ const name = config.names.variables[action];
63
+ dispatchEvent?.(name, {
64
+ location: config?.locations?.variables || "",
65
+ secondaryLocation: config?.secondaryLocations?.variablesPopover || "",
66
+ trigger: config?.triggers?.click || "",
67
+ var_type: varType,
68
+ control_path: controlPath,
69
+ action_type: name
70
+ });
71
+ };
72
+ var trackVariablesManagerEvent = ({ action, varType, controlPath }) => {
73
+ const { dispatchEvent, config } = (0, import_mixpanel.getMixpanel)();
74
+ if (!config?.names?.variables?.[action]) {
75
+ return;
76
+ }
77
+ const name = config.names.variables[action];
78
+ const eventData = {
79
+ location: config?.locations?.variablesManager || "",
80
+ trigger: config?.triggers?.click || "",
81
+ action_type: name
82
+ };
83
+ if (varType) {
84
+ eventData.var_type = varType;
85
+ }
86
+ if (controlPath) {
87
+ eventData.style_control_path = controlPath;
88
+ }
89
+ dispatchEvent?.(name, eventData);
90
+ };
56
91
 
57
- // src/context/variable-type-context.tsx
58
- var React2 = __toESM(require("react"));
59
- var import_react = require("react");
92
+ // src/utils/validations.ts
93
+ var import_icons = require("@elementor/icons");
94
+ var import_i18n = require("@wordpress/i18n");
95
+ var ERROR_MESSAGES = {
96
+ MISSING_VARIABLE_NAME: (0, import_i18n.__)("Give your variable a name.", "elementor"),
97
+ MISSING_VARIABLE_VALUE: (0, import_i18n.__)("Add a value to complete your variable.", "elementor"),
98
+ INVALID_CHARACTERS: (0, import_i18n.__)("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor"),
99
+ NO_NON_SPECIAL_CHARACTER: (0, import_i18n.__)("Names have to include at least one non-special character.", "elementor"),
100
+ VARIABLE_LABEL_MAX_LENGTH: (0, import_i18n.__)("Keep names up to 50 characters.", "elementor"),
101
+ DUPLICATED_LABEL: (0, import_i18n.__)("This variable name already exists. Please choose a unique name.", "elementor"),
102
+ UNEXPECTED_ERROR: (0, import_i18n.__)("There was a glitch. Try saving your variable again.", "elementor"),
103
+ BATCH: {
104
+ DUPLICATED_LABELS: (count, name) => (
105
+ // eslint-disable-next-line @wordpress/i18n-translator-comments
106
+ (0, import_i18n.sprintf)((0, import_i18n.__)("We found %1$d duplicated %2$s.", "elementor"), count, name)
107
+ ),
108
+ UNEXPECTED_ERROR: (0, import_i18n.__)("There was a glitch.", "elementor"),
109
+ DUPLICATED_LABEL_ACTION: (0, import_i18n.__)("Take me there", "elementor"),
110
+ DUPLICATED_LABEL_ACTION_MESSAGE: (0, import_i18n.__)("Please rename the variables.", "elementor"),
111
+ UNEXPECTED_ERROR_ACTION_MESSAGE: (0, import_i18n.__)("Try saving your variables again.", "elementor")
112
+ }
113
+ };
114
+ var VARIABLE_LABEL_MAX_LENGTH = 50;
115
+ var mapServerError = (error) => {
116
+ if (error?.response?.data?.code === "duplicated_label") {
117
+ return {
118
+ field: "label",
119
+ message: ERROR_MESSAGES.DUPLICATED_LABEL
120
+ };
121
+ }
122
+ if (error?.response?.data?.code === "batch_duplicated_label") {
123
+ const errorData = error?.response?.data?.data ?? {};
124
+ const count = Object.keys(errorData).length;
125
+ const name = count === 1 ? "name" : "names";
126
+ const duplicatedIds = Object.keys(errorData);
127
+ return {
128
+ field: "label",
129
+ message: ERROR_MESSAGES.BATCH.DUPLICATED_LABELS(count, name),
130
+ severity: "error",
131
+ IconComponent: import_icons.AlertTriangleFilledIcon,
132
+ action: {
133
+ label: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION,
134
+ message: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION_MESSAGE,
135
+ data: {
136
+ duplicatedIds
137
+ }
138
+ }
139
+ };
140
+ }
141
+ if (error?.response?.data?.code === "batch_operation_failed") {
142
+ return {
143
+ field: "label",
144
+ message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR,
145
+ severity: "secondary",
146
+ IconComponent: import_icons.InfoCircleFilledIcon,
147
+ action: {
148
+ message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR_ACTION_MESSAGE
149
+ }
150
+ };
151
+ }
152
+ return void 0;
153
+ };
154
+ var validateLabel = (name, variables) => {
155
+ if (!name.trim()) {
156
+ return ERROR_MESSAGES.MISSING_VARIABLE_NAME;
157
+ }
158
+ const allowedChars = /^[a-zA-Z0-9_-]+$/;
159
+ if (!allowedChars.test(name)) {
160
+ return ERROR_MESSAGES.INVALID_CHARACTERS;
161
+ }
162
+ const hasAlphanumeric = /[a-zA-Z0-9]/;
163
+ if (!hasAlphanumeric.test(name)) {
164
+ return ERROR_MESSAGES.NO_NON_SPECIAL_CHARACTER;
165
+ }
166
+ if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
167
+ return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
168
+ }
169
+ if (Object.values(variables ?? {}).some((variable) => variable.label === name)) {
170
+ return ERROR_MESSAGES.DUPLICATED_LABEL;
171
+ }
172
+ return "";
173
+ };
174
+ var labelHint = (name) => {
175
+ const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
176
+ if (hintThreshold < name.length) {
177
+ return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
178
+ }
179
+ return "";
180
+ };
181
+ var validateValue = (value) => {
182
+ if (!value.trim()) {
183
+ return ERROR_MESSAGES.MISSING_VARIABLE_VALUE;
184
+ }
185
+ return "";
186
+ };
60
187
 
61
188
  // src/variables-registry/create-variable-type-registry.ts
62
189
  var import_editor_canvas3 = require("@elementor/editor-canvas");
@@ -66,7 +193,7 @@ var import_editor_editing_panel = require("@elementor/editor-editing-panel");
66
193
  var React = __toESM(require("react"));
67
194
  var import_editor_canvas = require("@elementor/editor-canvas");
68
195
  var import_ui2 = require("@elementor/ui");
69
- var import_i18n2 = require("@wordpress/i18n");
196
+ var import_i18n3 = require("@wordpress/i18n");
70
197
 
71
198
  // src/components/ui/color-indicator.tsx
72
199
  var import_ui = require("@elementor/ui");
@@ -81,7 +208,7 @@ var import_schema = require("@elementor/schema");
81
208
  var colorVariablePropTypeUtil = (0, import_editor_props.createPropUtils)("global-color-variable", import_schema.z.string());
82
209
 
83
210
  // src/service.ts
84
- var import_i18n = require("@wordpress/i18n");
211
+ var import_i18n2 = require("@wordpress/i18n");
85
212
 
86
213
  // src/api.ts
87
214
  var import_http_client = require("@elementor/http-client");
@@ -116,9 +243,72 @@ var apiClient = {
116
243
  payload.value = value;
117
244
  }
118
245
  return (0, import_http_client.httpService)().post(BASE_PATH + "/restore", payload);
246
+ },
247
+ batch: (payload) => {
248
+ return (0, import_http_client.httpService)().post(BASE_PATH + "/batch", payload);
119
249
  }
120
250
  };
121
251
 
252
+ // src/batch-operations.ts
253
+ var generateTempId = () => {
254
+ const timestamp = Date.now().toString(36);
255
+ const random = Math.random().toString(36).substring(2, 8);
256
+ return `tmp-${timestamp}-${random}`;
257
+ };
258
+ var isTempId = (id2) => {
259
+ return id2.startsWith("tmp-");
260
+ };
261
+ var buildOperationsArray = (originalVariables, currentVariables) => {
262
+ const operations = [];
263
+ Object.entries(currentVariables).forEach(([id2, variable]) => {
264
+ if (isTempId(id2)) {
265
+ operations.push({
266
+ type: "create",
267
+ variable: {
268
+ ...variable,
269
+ id: id2
270
+ }
271
+ });
272
+ } else if (originalVariables[id2]) {
273
+ const original = originalVariables[id2];
274
+ if (original.deleted && !variable.deleted) {
275
+ operations.push({
276
+ type: "restore",
277
+ id: id2,
278
+ ...original.label !== variable.label && { label: variable.label },
279
+ ...original.value !== variable.value && { value: variable.value }
280
+ });
281
+ } else if (!variable.deleted && (original.label !== variable.label || original.value !== variable.value || original.order !== variable.order)) {
282
+ operations.push({
283
+ type: "update",
284
+ id: id2,
285
+ variable: {
286
+ ...original.label !== variable.label && { label: variable.label },
287
+ ...original.value !== variable.value && { value: variable.value },
288
+ ...original.order !== variable.order && { order: variable.order }
289
+ }
290
+ });
291
+ }
292
+ }
293
+ });
294
+ Object.entries(originalVariables).forEach(([id2, variable]) => {
295
+ if (isTempId(id2) || variable.deleted) {
296
+ return;
297
+ }
298
+ const currentVariable = currentVariables[id2];
299
+ if (!currentVariable || currentVariable.deleted) {
300
+ operations.push({
301
+ type: "delete",
302
+ id: id2
303
+ });
304
+ }
305
+ });
306
+ return operations.filter((op) => {
307
+ const id2 = op.id || op.variable?.id;
308
+ return id2 && !(isTempId(id2) && currentVariables[id2]?.deleted);
309
+ });
310
+ };
311
+
122
312
  // src/storage.ts
123
313
  var STORAGE_KEY = "elementor-global-variables";
124
314
  var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
@@ -126,6 +316,9 @@ var OP_RW = "RW";
126
316
  var OP_RO = "RO";
127
317
  var Storage = class {
128
318
  state;
319
+ notifyChange() {
320
+ window.dispatchEvent(new Event("variables:updated"));
321
+ }
129
322
  constructor() {
130
323
  this.state = {
131
324
  watermark: -1,
@@ -145,16 +338,19 @@ var Storage = class {
145
338
  this.state.watermark = watermark;
146
339
  localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
147
340
  localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
341
+ this.notifyChange();
148
342
  }
149
343
  add(id2, variable) {
150
344
  this.load();
151
345
  this.state.variables[id2] = variable;
152
346
  localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
347
+ this.notifyChange();
153
348
  }
154
349
  update(id2, variable) {
155
350
  this.load();
156
351
  this.state.variables[id2] = variable;
157
352
  localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
353
+ this.notifyChange();
158
354
  }
159
355
  watermark(watermark) {
160
356
  this.state.watermark = watermark;
@@ -259,8 +455,11 @@ var service = {
259
455
  variables: () => {
260
456
  return storage.load();
261
457
  },
458
+ getWatermark: () => {
459
+ return storage.state.watermark;
460
+ },
262
461
  init: () => {
263
- service.load();
462
+ return service.load();
264
463
  },
265
464
  load: () => {
266
465
  return apiClient.list().then((response) => {
@@ -280,7 +479,7 @@ var service = {
280
479
  return apiClient.create(type, label, value).then((response) => {
281
480
  const { success, data: payload } = response.data;
282
481
  if (!success) {
283
- const errorMessage = payload?.message || (0, import_i18n.__)("Unexpected response from server", "elementor");
482
+ const errorMessage = payload?.message || (0, import_i18n2.__)("Unexpected response from server", "elementor");
284
483
  throw new Error(errorMessage);
285
484
  }
286
485
  return payload;
@@ -302,7 +501,7 @@ var service = {
302
501
  return apiClient.update(id2, label, value).then((response) => {
303
502
  const { success, data: payload } = response.data;
304
503
  if (!success) {
305
- const errorMessage = payload?.message || (0, import_i18n.__)("Unexpected response from server", "elementor");
504
+ const errorMessage = payload?.message || (0, import_i18n2.__)("Unexpected response from server", "elementor");
306
505
  throw new Error(errorMessage);
307
506
  }
308
507
  return payload;
@@ -361,6 +560,47 @@ var service = {
361
560
  variable: restoredVariable
362
561
  };
363
562
  });
563
+ },
564
+ batchSave: (originalVariables, currentVariables) => {
565
+ const operations = buildOperationsArray(originalVariables, currentVariables);
566
+ const batchPayload = { operations, watermark: storage.state.watermark };
567
+ if (operations.length === 0) {
568
+ return Promise.resolve({
569
+ success: true,
570
+ watermark: storage.state.watermark,
571
+ operations: 0
572
+ });
573
+ }
574
+ return apiClient.batch(batchPayload).then((response) => {
575
+ const { success, data: payload } = response.data;
576
+ if (!success) {
577
+ throw new Error("Unexpected response from server");
578
+ }
579
+ return payload;
580
+ }).then((data) => {
581
+ const { results, watermark } = data;
582
+ handleWatermark(OP_RW, watermark);
583
+ if (results) {
584
+ results.forEach((result) => {
585
+ if (result.variable) {
586
+ const { id: variableId, ...variableData } = result.variable;
587
+ if (result.type === "create") {
588
+ storage.add(variableId, variableData);
589
+ } else {
590
+ storage.update(variableId, variableData);
591
+ }
592
+ styleVariablesRepository.update({
593
+ [variableId]: variableData
594
+ });
595
+ }
596
+ });
597
+ }
598
+ return {
599
+ success: true,
600
+ watermark,
601
+ operations: operations.length
602
+ };
603
+ });
364
604
  }
365
605
  };
366
606
  var handleWatermark = (operation, newWatermark) => {
@@ -394,7 +634,7 @@ var inheritanceTransformer = (0, import_editor_canvas.createTransformer)((id2) =
394
634
  const variables = service.variables();
395
635
  const variable = variables[id2];
396
636
  if (!variable) {
397
- return /* @__PURE__ */ React.createElement("span", null, (0, import_i18n2.__)("Missing variable", "elementor"));
637
+ return /* @__PURE__ */ React.createElement("span", null, (0, import_i18n3.__)("Missing variable", "elementor"));
398
638
  }
399
639
  const showColorIndicator = variable.type === colorVariablePropTypeUtil.key;
400
640
  const css = resolveCssVariable(id2, variable);
@@ -415,19 +655,19 @@ var variableTransformer = (0, import_editor_canvas2.createTransformer)((id2) =>
415
655
  function createVariableTypeRegistry() {
416
656
  const variableTypes = {};
417
657
  const registerVariableType2 = ({
658
+ key,
418
659
  icon,
419
660
  startIcon,
420
661
  valueField,
421
662
  propTypeUtil,
422
663
  variableType,
664
+ defaultValue,
423
665
  selectionFilter,
424
666
  valueTransformer,
425
667
  fallbackPropTypeUtil,
426
668
  isCompatible
427
669
  }) => {
428
- if (variableTypes[propTypeUtil.key]) {
429
- throw new Error(`Variable with key "${propTypeUtil.key}" is already registered.`);
430
- }
670
+ const variableTypeKey = key ?? propTypeUtil.key;
431
671
  if (!isCompatible) {
432
672
  isCompatible = (propType, variable) => {
433
673
  if ("union" === propType.kind) {
@@ -438,12 +678,13 @@ function createVariableTypeRegistry() {
438
678
  return false;
439
679
  };
440
680
  }
441
- variableTypes[propTypeUtil.key] = {
681
+ variableTypes[variableTypeKey] = {
442
682
  icon,
443
683
  startIcon,
444
684
  valueField,
445
685
  propTypeUtil,
446
686
  variableType,
687
+ defaultValue,
447
688
  selectionFilter,
448
689
  valueTransformer,
449
690
  fallbackPropTypeUtil,
@@ -461,32 +702,188 @@ function createVariableTypeRegistry() {
461
702
  const getVariableType2 = (key) => {
462
703
  return variableTypes[key];
463
704
  };
705
+ const getVariableTypes2 = () => {
706
+ return variableTypes;
707
+ };
464
708
  const hasVariableType2 = (key) => {
465
709
  return key in variableTypes;
466
710
  };
467
711
  return {
468
712
  registerVariableType: registerVariableType2,
469
713
  getVariableType: getVariableType2,
714
+ getVariableTypes: getVariableTypes2,
470
715
  hasVariableType: hasVariableType2
471
716
  };
472
717
  }
473
718
 
474
719
  // src/variables-registry/variable-type-registry.ts
475
- var { registerVariableType, getVariableType, hasVariableType } = createVariableTypeRegistry();
720
+ var { registerVariableType, getVariableType, getVariableTypes, hasVariableType } = createVariableTypeRegistry();
721
+
722
+ // src/components/ui/delete-confirmation-dialog.tsx
723
+ var React2 = __toESM(require("react"));
724
+ var import_icons2 = require("@elementor/icons");
725
+ var import_ui3 = require("@elementor/ui");
726
+ var import_i18n4 = require("@wordpress/i18n");
727
+ var TITLE_ID = "delete-variable-dialog";
728
+ var DeleteConfirmationDialog = ({
729
+ open,
730
+ label,
731
+ closeDialog,
732
+ onConfirm
733
+ }) => {
734
+ return /* @__PURE__ */ React2.createElement(import_ui3.Dialog, { open, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React2.createElement(import_ui3.DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React2.createElement(import_icons2.AlertOctagonFilledIcon, { color: "error" }), (0, import_i18n4.__)("Delete this variable?", "elementor")), /* @__PURE__ */ React2.createElement(import_ui3.DialogContent, null, /* @__PURE__ */ React2.createElement(import_ui3.DialogContentText, { variant: "body2", color: "textPrimary" }, (0, import_i18n4.__)("All elements using", "elementor"), "\xA0", /* @__PURE__ */ React2.createElement(import_ui3.Typography, { variant: "subtitle2", component: "span", sx: { lineBreak: "anywhere" } }, label), "\xA0", (0, import_i18n4.__)("will keep their current values, but the variable itself will be removed.", "elementor"))), /* @__PURE__ */ React2.createElement(import_ui3.DialogActions, null, /* @__PURE__ */ React2.createElement(import_ui3.Button, { color: "secondary", onClick: closeDialog }, (0, import_i18n4.__)("Not now", "elementor")), /* @__PURE__ */ React2.createElement(import_ui3.Button, { variant: "contained", color: "error", onClick: onConfirm }, (0, import_i18n4.__)("Delete", "elementor"))));
735
+ };
736
+
737
+ // src/components/ui/empty-state.tsx
738
+ var React3 = __toESM(require("react"));
739
+ var import_ui4 = require("@elementor/ui");
740
+ var import_i18n5 = require("@wordpress/i18n");
741
+
742
+ // src/hooks/use-permissions.ts
743
+ var import_editor_current_user = require("@elementor/editor-current-user");
744
+ var usePermissions = () => {
745
+ const { canUser } = (0, import_editor_current_user.useCurrentUserCapabilities)();
746
+ return {
747
+ canAssign: () => canUser("edit_posts"),
748
+ canUnlink: () => canUser("edit_posts"),
749
+ canAdd: () => canUser("manage_options"),
750
+ canDelete: () => canUser("manage_options"),
751
+ canEdit: () => canUser("manage_options"),
752
+ canRestore: () => canUser("manage_options"),
753
+ canManageSettings: () => canUser("manage_options")
754
+ };
755
+ };
756
+
757
+ // src/components/ui/empty-state.tsx
758
+ var EmptyState = ({ icon, title, message, onAdd }) => {
759
+ const canAdd = usePermissions().canAdd();
760
+ return /* @__PURE__ */ React3.createElement(
761
+ import_ui4.Stack,
762
+ {
763
+ gap: 1,
764
+ alignItems: "center",
765
+ justifyContent: "flex-start",
766
+ height: "100%",
767
+ color: "text.secondary",
768
+ sx: { p: 2.5, pt: 8, pb: 5.5 }
769
+ },
770
+ icon,
771
+ canAdd ? /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(Content, { title, message }), onAdd && /* @__PURE__ */ React3.createElement(import_ui4.Button, { variant: "outlined", color: "secondary", size: "small", onClick: onAdd }, (0, import_i18n5.__)("Create a variable", "elementor"))) : /* @__PURE__ */ React3.createElement(
772
+ Content,
773
+ {
774
+ title: (0, import_i18n5.__)("There are no variables", "elementor"),
775
+ message: (0, import_i18n5.__)("With your current role, you can only connect and detach variables.", "elementor")
776
+ }
777
+ )
778
+ );
779
+ };
780
+ function Content({ title, message }) {
781
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(import_ui4.Typography, { align: "center", variant: "subtitle2" }, title), /* @__PURE__ */ React3.createElement(import_ui4.Typography, { align: "center", variant: "caption", maxWidth: "180px" }, message));
782
+ }
783
+
784
+ // src/components/ui/no-search-results.tsx
785
+ var React4 = __toESM(require("react"));
786
+ var import_ui5 = require("@elementor/ui");
787
+ var import_i18n6 = require("@wordpress/i18n");
788
+ var NoSearchResults = ({ searchValue, onClear, icon }) => {
789
+ return /* @__PURE__ */ React4.createElement(
790
+ import_ui5.Stack,
791
+ {
792
+ gap: 1,
793
+ alignItems: "center",
794
+ justifyContent: "center",
795
+ p: 2.5,
796
+ color: "text.secondary",
797
+ sx: { pb: 3.5, pt: 8 }
798
+ },
799
+ icon,
800
+ /* @__PURE__ */ React4.createElement(import_ui5.Typography, { align: "center", variant: "subtitle2" }, (0, import_i18n6.__)("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React4.createElement("br", null), "\u201C", searchValue, "\u201D."),
801
+ /* @__PURE__ */ React4.createElement(import_ui5.Typography, { align: "center", variant: "caption", sx: { display: "flex", flexDirection: "column" } }, (0, import_i18n6.__)("Try something else.", "elementor"), /* @__PURE__ */ React4.createElement(import_ui5.Link, { color: "text.secondary", variant: "caption", component: "button", onClick: onClear }, (0, import_i18n6.__)("Clear & try again", "elementor")))
802
+ );
803
+ };
804
+
805
+ // src/components/variables-manager/hooks/use-auto-edit.ts
806
+ var import_react = require("react");
807
+ var useAutoEdit = () => {
808
+ const [autoEditVariableId, setAutoEditVariableId] = (0, import_react.useState)(void 0);
809
+ const startAutoEdit = (0, import_react.useCallback)((variableId) => {
810
+ setAutoEditVariableId(variableId);
811
+ }, []);
812
+ const handleAutoEditComplete = (0, import_react.useCallback)(() => {
813
+ setTimeout(() => {
814
+ setAutoEditVariableId(void 0);
815
+ }, 100);
816
+ }, []);
817
+ return {
818
+ autoEditVariableId,
819
+ startAutoEdit,
820
+ handleAutoEditComplete
821
+ };
822
+ };
823
+
824
+ // src/components/variables-manager/hooks/use-error-navigation.ts
825
+ var import_react2 = require("react");
826
+ var useErrorNavigation = () => {
827
+ const currentIndexRef = (0, import_react2.useRef)(0);
828
+ const createNavigationCallback = (0, import_react2.useCallback)(
829
+ (ids, onNavigate, onComplete) => {
830
+ return () => {
831
+ if (!ids?.length) {
832
+ return;
833
+ }
834
+ const currentIndex = currentIndexRef.current;
835
+ const currentId = ids[currentIndex];
836
+ if (currentId) {
837
+ onNavigate(currentId);
838
+ const nextIndex = currentIndex + 1;
839
+ if (nextIndex >= ids.length) {
840
+ onComplete();
841
+ currentIndexRef.current = 0;
842
+ } else {
843
+ currentIndexRef.current = nextIndex;
844
+ }
845
+ }
846
+ };
847
+ },
848
+ []
849
+ );
850
+ const resetNavigation = (0, import_react2.useCallback)(() => {
851
+ currentIndexRef.current = 0;
852
+ }, []);
853
+ return {
854
+ createNavigationCallback,
855
+ resetNavigation
856
+ };
857
+ };
858
+
859
+ // src/components/variables-manager/hooks/use-variables-manager-state.ts
860
+ var import_react5 = require("react");
861
+
862
+ // src/hooks/use-prop-variables.ts
863
+ var import_react4 = require("react");
864
+ var import_editor_controls = require("@elementor/editor-controls");
476
865
 
477
866
  // src/context/variable-type-context.tsx
478
- var VariableTypeContext = (0, import_react.createContext)(null);
867
+ var React5 = __toESM(require("react"));
868
+ var import_react3 = require("react");
869
+ var VariableTypeContext = (0, import_react3.createContext)(null);
479
870
  function VariableTypeProvider({ children, propTypeKey }) {
480
- return /* @__PURE__ */ React2.createElement(VariableTypeContext.Provider, { value: propTypeKey }, children);
871
+ return /* @__PURE__ */ React5.createElement(VariableTypeContext.Provider, { value: propTypeKey }, children);
481
872
  }
482
873
  function useVariableType() {
483
- const context = (0, import_react.useContext)(VariableTypeContext);
874
+ const context = (0, import_react3.useContext)(VariableTypeContext);
484
875
  if (context === null) {
485
876
  throw new Error("useVariableType must be used within a VariableTypeProvider");
486
877
  }
487
878
  return getVariableType(context);
488
879
  }
489
880
 
881
+ // src/utils/filter-by-search.ts
882
+ function filterBySearch(variables, searchValue) {
883
+ const lowerSearchValue = searchValue.toLowerCase();
884
+ return variables.filter((variable) => variable.label.toLowerCase().includes(lowerSearchValue));
885
+ }
886
+
490
887
  // src/hooks/use-prop-variables.ts
491
888
  var getVariables = (includeDeleted = true) => {
492
889
  const variables = service.variables();
@@ -508,11 +905,17 @@ var useVariable = (key) => {
508
905
  var useFilteredVariables = (searchValue, propTypeKey) => {
509
906
  const baseVariables = usePropVariables(propTypeKey);
510
907
  const typeFilteredVariables = useVariableSelectionFilter(baseVariables);
511
- const searchFilteredVariables = filterVariablesBySearchValue(typeFilteredVariables, searchValue);
908
+ const searchFilteredVariables = filterBySearch(typeFilteredVariables, searchValue);
909
+ const sortedVariables = searchFilteredVariables.sort((a, b) => {
910
+ const orderA = a.order ?? Number.MAX_SAFE_INTEGER;
911
+ const orderB = b.order ?? Number.MAX_SAFE_INTEGER;
912
+ return orderA - orderB;
913
+ });
512
914
  return {
513
- list: searchFilteredVariables,
915
+ list: sortedVariables,
514
916
  hasMatches: searchFilteredVariables.length > 0,
515
- isSourceNotEmpty: typeFilteredVariables.length > 0
917
+ isSourceNotEmpty: typeFilteredVariables.length > 0,
918
+ hasNoCompatibleVariables: baseVariables.length > 0 && typeFilteredVariables.length === 0
516
919
  };
517
920
  };
518
921
  var useVariableSelectionFilter = (variables) => {
@@ -520,19 +923,28 @@ var useVariableSelectionFilter = (variables) => {
520
923
  const { propType } = (0, import_editor_controls.useBoundProp)();
521
924
  return selectionFilter ? selectionFilter(variables, propType) : variables;
522
925
  };
523
- var filterVariablesBySearchValue = (variables, searchValue) => {
524
- const lowerSearchValue = searchValue.toLowerCase();
525
- return variables.filter(({ label }) => label.toLowerCase().includes(lowerSearchValue));
526
- };
527
926
  var usePropVariables = (propKey) => {
528
- return (0, import_react2.useMemo)(() => normalizeVariables(propKey), [propKey]);
927
+ return (0, import_react4.useMemo)(() => normalizeVariables(propKey), [propKey]);
928
+ };
929
+ var getMatchingTypes = (propKey) => {
930
+ const matchingTypes = [];
931
+ const allTypes = getVariableTypes();
932
+ const variableType = getVariableType(propKey);
933
+ Object.entries(allTypes).forEach(([key, typeOptions]) => {
934
+ if (variableType.variableType === typeOptions.variableType) {
935
+ matchingTypes.push(key);
936
+ }
937
+ });
938
+ return matchingTypes;
529
939
  };
530
940
  var normalizeVariables = (propKey) => {
531
941
  const variables = getVariables(false);
532
- return Object.entries(variables).filter(([, variable]) => variable.type === propKey).map(([key, { label, value }]) => ({
942
+ const matchingTypes = getMatchingTypes(propKey);
943
+ return Object.entries(variables).filter(([, variable]) => matchingTypes.includes(variable.type)).map(([key, { label, value, order }]) => ({
533
944
  key,
534
945
  label,
535
- value
946
+ value,
947
+ order
536
948
  }));
537
949
  };
538
950
  var extractId = ({ id: id2 }) => id2;
@@ -549,77 +961,185 @@ var restoreVariable = (restoreId, label, value) => {
549
961
  return service.restore(restoreId, label, value).then(extractId);
550
962
  };
551
963
 
552
- // src/components/variables-manager/variables-manager-table.tsx
553
- var React7 = __toESM(require("react"));
554
- var import_react6 = require("react");
555
- var import_editor_ui = require("@elementor/editor-ui");
556
- var import_icons2 = require("@elementor/icons");
557
- var import_ui7 = require("@elementor/ui");
558
- var import_i18n4 = require("@wordpress/i18n");
559
-
560
- // src/components/fields/label-field.tsx
561
- var React3 = __toESM(require("react"));
562
- var import_react3 = require("react");
563
- var import_ui3 = require("@elementor/ui");
564
-
565
- // src/utils/validations.ts
566
- var import_i18n3 = require("@wordpress/i18n");
567
- var ERROR_MESSAGES = {
568
- MISSING_VARIABLE_NAME: (0, import_i18n3.__)("Give your variable a name.", "elementor"),
569
- MISSING_VARIABLE_VALUE: (0, import_i18n3.__)("Add a value to complete your variable.", "elementor"),
570
- INVALID_CHARACTERS: (0, import_i18n3.__)("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor"),
571
- NO_NON_SPECIAL_CHARACTER: (0, import_i18n3.__)("Names have to include at least one non-special character.", "elementor"),
572
- VARIABLE_LABEL_MAX_LENGTH: (0, import_i18n3.__)("Keep names up to 50 characters.", "elementor"),
573
- DUPLICATED_LABEL: (0, import_i18n3.__)("This variable name already exists. Please choose a unique name.", "elementor"),
574
- UNEXPECTED_ERROR: (0, import_i18n3.__)("There was a glitch. Try saving your variable again.", "elementor")
964
+ // src/components/variables-manager/hooks/use-variables-manager-state.ts
965
+ var useVariablesManagerState = () => {
966
+ const [variables, setVariables] = (0, import_react5.useState)(() => getVariables(false));
967
+ const [deletedVariables, setDeletedVariables] = (0, import_react5.useState)([]);
968
+ const [isSaveDisabled, setIsSaveDisabled] = (0, import_react5.useState)(false);
969
+ const [isDirty, setIsDirty] = (0, import_react5.useState)(false);
970
+ const [isSaving, setIsSaving] = (0, import_react5.useState)(false);
971
+ const [searchValue, setSearchValue] = (0, import_react5.useState)("");
972
+ const handleOnChange = (0, import_react5.useCallback)(
973
+ (newVariables) => {
974
+ setVariables({ ...variables, ...newVariables });
975
+ setIsDirty(true);
976
+ },
977
+ [variables]
978
+ );
979
+ const createVariable2 = (0, import_react5.useCallback)((type, defaultName, defaultValue) => {
980
+ const newId = generateTempId();
981
+ const newVariable = {
982
+ id: newId,
983
+ label: defaultName.trim(),
984
+ value: defaultValue.trim(),
985
+ type
986
+ };
987
+ setVariables((prev) => ({ ...prev, [newId]: newVariable }));
988
+ setIsDirty(true);
989
+ return newId;
990
+ }, []);
991
+ const handleDeleteVariable = (0, import_react5.useCallback)((itemId) => {
992
+ setDeletedVariables((prev) => [...prev, itemId]);
993
+ setVariables((prev) => ({ ...prev, [itemId]: { ...prev[itemId], deleted: true } }));
994
+ setIsDirty(true);
995
+ }, []);
996
+ const handleSearch = (searchTerm) => {
997
+ setSearchValue(searchTerm);
998
+ };
999
+ const handleSave = (0, import_react5.useCallback)(async () => {
1000
+ const originalVariables = getVariables(false);
1001
+ setIsSaving(true);
1002
+ const result = await service.batchSave(originalVariables, variables);
1003
+ if (result.success) {
1004
+ await service.load();
1005
+ const updatedVariables = service.variables();
1006
+ setVariables(updatedVariables);
1007
+ setDeletedVariables([]);
1008
+ setIsDirty(false);
1009
+ }
1010
+ return { success: result.success };
1011
+ }, [variables]);
1012
+ const filteredVariables = () => {
1013
+ const list = Object.entries(variables).map(([id2, value]) => ({ ...value, id: id2 }));
1014
+ const filtered = filterBySearch(list, searchValue);
1015
+ return Object.fromEntries(filtered.map(({ id: id2, ...rest }) => [id2, rest]));
1016
+ };
1017
+ return {
1018
+ variables: filteredVariables(),
1019
+ deletedVariables,
1020
+ isDirty,
1021
+ isSaveDisabled,
1022
+ handleOnChange,
1023
+ createVariable: createVariable2,
1024
+ handleDeleteVariable,
1025
+ handleSave,
1026
+ isSaving,
1027
+ handleSearch,
1028
+ searchValue,
1029
+ setIsSaving,
1030
+ setIsSaveDisabled
1031
+ };
575
1032
  };
576
- var VARIABLE_LABEL_MAX_LENGTH = 50;
577
- var mapServerError = (error) => {
578
- if (error?.response?.data?.code === "duplicated_label") {
1033
+
1034
+ // src/components/variables-manager/variables-manager-create-menu.tsx
1035
+ var React6 = __toESM(require("react"));
1036
+ var import_react6 = require("react");
1037
+ var import_icons3 = require("@elementor/icons");
1038
+ var import_ui6 = require("@elementor/ui");
1039
+ var import_i18n7 = require("@wordpress/i18n");
1040
+ var SIZE = "tiny";
1041
+ var VariableManagerCreateMenu = ({
1042
+ variables,
1043
+ onCreate,
1044
+ disabled,
1045
+ menuState
1046
+ }) => {
1047
+ const buttonRef = (0, import_react6.useRef)(null);
1048
+ const variableTypes = getVariableTypes();
1049
+ const menuOptions = Object.entries(variableTypes).filter(([, variable]) => !!variable.defaultValue).map(([key, variable]) => {
1050
+ const displayName = variable.variableType.charAt(0).toUpperCase() + variable.variableType.slice(1);
579
1051
  return {
580
- field: "label",
581
- message: ERROR_MESSAGES.DUPLICATED_LABEL
1052
+ key,
1053
+ name: displayName,
1054
+ icon: variable.icon,
1055
+ onClick: () => {
1056
+ const defaultName = getDefaultName(variables, key, variable.variableType);
1057
+ onCreate(key, defaultName, variable.defaultValue || "");
1058
+ trackVariablesManagerEvent({ action: "add", varType: variable.variableType });
1059
+ }
582
1060
  };
583
- }
584
- return void 0;
585
- };
586
- var validateLabel = (name) => {
587
- if (!name.trim()) {
588
- return ERROR_MESSAGES.MISSING_VARIABLE_NAME;
589
- }
590
- const allowedChars = /^[a-zA-Z0-9_-]+$/;
591
- if (!allowedChars.test(name)) {
592
- return ERROR_MESSAGES.INVALID_CHARACTERS;
593
- }
594
- const hasAlphanumeric = /[a-zA-Z0-9]/;
595
- if (!hasAlphanumeric.test(name)) {
596
- return ERROR_MESSAGES.NO_NON_SPECIAL_CHARACTER;
597
- }
598
- if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
599
- return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
600
- }
601
- return "";
602
- };
603
- var labelHint = (name) => {
604
- const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
605
- if (hintThreshold < name.length) {
606
- return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
607
- }
608
- return "";
1061
+ });
1062
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
1063
+ import_ui6.IconButton,
1064
+ {
1065
+ ...(0, import_ui6.bindTrigger)(menuState),
1066
+ ref: buttonRef,
1067
+ disabled,
1068
+ size: SIZE,
1069
+ "aria-label": (0, import_i18n7.__)("Add variable", "elementor")
1070
+ },
1071
+ /* @__PURE__ */ React6.createElement(import_icons3.PlusIcon, { fontSize: SIZE })
1072
+ ), /* @__PURE__ */ React6.createElement(
1073
+ import_ui6.Menu,
1074
+ {
1075
+ disablePortal: true,
1076
+ MenuListProps: {
1077
+ dense: true
1078
+ },
1079
+ PaperProps: {
1080
+ elevation: 6
1081
+ },
1082
+ ...(0, import_ui6.bindMenu)(menuState),
1083
+ anchorEl: buttonRef.current,
1084
+ anchorOrigin: {
1085
+ vertical: "bottom",
1086
+ horizontal: "right"
1087
+ },
1088
+ transformOrigin: {
1089
+ vertical: "top",
1090
+ horizontal: "right"
1091
+ },
1092
+ "data-testid": "variable-manager-create-menu"
1093
+ },
1094
+ menuOptions.map((option) => /* @__PURE__ */ React6.createElement(
1095
+ import_ui6.MenuItem,
1096
+ {
1097
+ key: option.key,
1098
+ onClick: () => {
1099
+ option.onClick?.();
1100
+ menuState.close();
1101
+ },
1102
+ sx: {
1103
+ gap: 1.5
1104
+ }
1105
+ },
1106
+ (0, import_react6.createElement)(option.icon, {
1107
+ fontSize: SIZE,
1108
+ color: "action"
1109
+ }),
1110
+ /* @__PURE__ */ React6.createElement(import_ui6.Typography, { variant: "caption", color: "text.primary" }, option.name)
1111
+ ))
1112
+ ));
609
1113
  };
610
- var validateValue = (value) => {
611
- if (!value.trim()) {
612
- return ERROR_MESSAGES.MISSING_VARIABLE_VALUE;
1114
+ var getDefaultName = (variables, type, baseName) => {
1115
+ const existingNames = Object.values(variables).filter((variable) => variable.type === type).map((variable) => variable.label);
1116
+ let counter = 1;
1117
+ let name = `${baseName}-${counter}`;
1118
+ while (existingNames.includes(name)) {
1119
+ counter++;
1120
+ name = `${baseName}-${counter}`;
613
1121
  }
614
- return "";
1122
+ return name;
615
1123
  };
616
1124
 
1125
+ // src/components/variables-manager/variables-manager-table.tsx
1126
+ var React11 = __toESM(require("react"));
1127
+ var import_react10 = require("react");
1128
+ var import_editor_ui2 = require("@elementor/editor-ui");
1129
+ var import_icons5 = require("@elementor/icons");
1130
+ var import_ui11 = require("@elementor/ui");
1131
+ var import_i18n8 = require("@wordpress/i18n");
1132
+
617
1133
  // src/components/fields/label-field.tsx
1134
+ var React7 = __toESM(require("react"));
1135
+ var import_react7 = require("react");
1136
+ var import_editor_ui = require("@elementor/editor-ui");
1137
+ var import_ui7 = require("@elementor/ui");
618
1138
  function isLabelEqual(a, b) {
619
1139
  return a.trim().toLowerCase() === b.trim().toLowerCase();
620
1140
  }
621
1141
  var useLabelError = (initialError) => {
622
- const [error, setError] = (0, import_react3.useState)(initialError ?? { value: "", message: "" });
1142
+ const [error, setError] = (0, import_react7.useState)(initialError ?? { value: "", message: "" });
623
1143
  return {
624
1144
  labelFieldError: error,
625
1145
  setLabelFieldError: setError
@@ -632,13 +1152,17 @@ var LabelField = ({
632
1152
  id: id2,
633
1153
  onErrorChange,
634
1154
  size = "tiny",
635
- focusOnShow = false
1155
+ focusOnShow = false,
1156
+ selectOnShow = false,
1157
+ showWarningInfotip = false,
1158
+ variables
636
1159
  }) => {
637
- const [label, setLabel] = (0, import_react3.useState)(value);
638
- const [errorMessage, setErrorMessage] = (0, import_react3.useState)("");
1160
+ const [label, setLabel] = (0, import_react7.useState)(value);
1161
+ const [errorMessage, setErrorMessage] = (0, import_react7.useState)("");
1162
+ const fieldRef = (0, import_react7.useRef)(null);
639
1163
  const handleChange = (newValue) => {
640
1164
  setLabel(newValue);
641
- const errorMsg2 = validateLabel(newValue);
1165
+ const errorMsg2 = validateLabel(newValue, variables);
642
1166
  setErrorMessage(errorMsg2);
643
1167
  onErrorChange?.(errorMsg2);
644
1168
  onChange(isLabelEqual(newValue, error?.value ?? "") || errorMsg2 ? "" : newValue);
@@ -647,32 +1171,54 @@ var LabelField = ({
647
1171
  if (isLabelEqual(label, error?.value ?? "") && error?.message) {
648
1172
  errorMsg = error.message;
649
1173
  }
650
- return /* @__PURE__ */ React3.createElement(
651
- import_ui3.TextField,
1174
+ const hintMsg = !errorMsg ? labelHint(label) : "";
1175
+ const textField = /* @__PURE__ */ React7.createElement(
1176
+ import_ui7.TextField,
652
1177
  {
1178
+ ref: fieldRef,
653
1179
  id: id2,
654
1180
  size,
655
1181
  fullWidth: true,
656
1182
  value: label,
657
1183
  error: !!errorMsg,
658
1184
  onChange: (e) => handleChange(e.target.value),
659
- inputProps: { maxLength: VARIABLE_LABEL_MAX_LENGTH },
1185
+ inputProps: {
1186
+ maxLength: VARIABLE_LABEL_MAX_LENGTH,
1187
+ ...selectOnShow && { onFocus: (e) => e.target.select() },
1188
+ "aria-label": "Name"
1189
+ },
660
1190
  autoFocus: focusOnShow
661
1191
  }
662
1192
  );
1193
+ if (showWarningInfotip) {
1194
+ const tooltipWidth = Math.max(240, fieldRef.current?.getBoundingClientRect().width ?? 240);
1195
+ return /* @__PURE__ */ React7.createElement(
1196
+ import_editor_ui.WarningInfotip,
1197
+ {
1198
+ open: Boolean(errorMsg || hintMsg),
1199
+ text: errorMsg || hintMsg,
1200
+ placement: "bottom-start",
1201
+ width: tooltipWidth,
1202
+ offset: [0, -15],
1203
+ ...hintMsg && { hasError: false }
1204
+ },
1205
+ textField
1206
+ );
1207
+ }
1208
+ return textField;
663
1209
  };
664
1210
 
665
- // src/components/variables-manager/variable-edit-menu.tsx
666
- var React4 = __toESM(require("react"));
667
- var import_react4 = require("react");
668
- var import_icons = require("@elementor/icons");
669
- var import_ui4 = require("@elementor/ui");
1211
+ // src/components/variables-manager/ui/variable-edit-menu.tsx
1212
+ var React8 = __toESM(require("react"));
1213
+ var import_react8 = require("react");
1214
+ var import_icons4 = require("@elementor/icons");
1215
+ var import_ui8 = require("@elementor/ui");
670
1216
  var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
671
- const menuState = (0, import_ui4.usePopupState)({
1217
+ const menuState = (0, import_ui8.usePopupState)({
672
1218
  variant: "popover"
673
1219
  });
674
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(import_ui4.IconButton, { ...(0, import_ui4.bindTrigger)(menuState), disabled, size: "tiny" }, /* @__PURE__ */ React4.createElement(import_icons.DotsVerticalIcon, { fontSize: "tiny" })), /* @__PURE__ */ React4.createElement(
675
- import_ui4.Menu,
1220
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(import_ui8.IconButton, { ...(0, import_ui8.bindTrigger)(menuState), disabled, size: "tiny" }, /* @__PURE__ */ React8.createElement(import_icons4.DotsVerticalIcon, { fontSize: "tiny" })), /* @__PURE__ */ React8.createElement(
1221
+ import_ui8.Menu,
676
1222
  {
677
1223
  disablePortal: true,
678
1224
  MenuListProps: {
@@ -681,7 +1227,7 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
681
1227
  PaperProps: {
682
1228
  elevation: 6
683
1229
  },
684
- ...(0, import_ui4.bindMenu)(menuState),
1230
+ ...(0, import_ui8.bindMenu)(menuState),
685
1231
  anchorEl: menuState.anchorEl,
686
1232
  anchorOrigin: {
687
1233
  vertical: "bottom",
@@ -694,8 +1240,8 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
694
1240
  open: menuState.isOpen,
695
1241
  onClose: menuState.close
696
1242
  },
697
- menuActions.map((action) => /* @__PURE__ */ React4.createElement(
698
- import_ui4.MenuItem,
1243
+ menuActions.map((action) => /* @__PURE__ */ React8.createElement(
1244
+ import_ui8.MenuItem,
699
1245
  {
700
1246
  key: action.name,
701
1247
  onClick: () => {
@@ -707,7 +1253,7 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
707
1253
  gap: 1
708
1254
  }
709
1255
  },
710
- action.icon && (0, import_react4.createElement)(action.icon, {
1256
+ action.icon && (0, import_react8.createElement)(action.icon, {
711
1257
  fontSize: "inherit"
712
1258
  }),
713
1259
  " ",
@@ -716,78 +1262,9 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
716
1262
  ));
717
1263
  };
718
1264
 
719
- // src/components/variables-manager/variable-editable-cell.tsx
720
- var React5 = __toESM(require("react"));
721
- var import_react5 = require("react");
722
- var import_ui5 = require("@elementor/ui");
723
- var VariableEditableCell = ({
724
- initialValue,
725
- children,
726
- editableElement,
727
- onChange,
728
- prefixElement
729
- }) => {
730
- const [value, setValue] = (0, import_react5.useState)(initialValue);
731
- const [isEditing, setIsEditing] = (0, import_react5.useState)(false);
732
- const handleDoubleClick = () => {
733
- setIsEditing(true);
734
- };
735
- const handleSave = () => {
736
- onChange(value);
737
- setIsEditing(false);
738
- };
739
- const handleKeyDown = (event) => {
740
- if (event.key === "Enter") {
741
- handleSave();
742
- } else if (event.key === "Escape") {
743
- setIsEditing(false);
744
- }
745
- if (event.key === " " && !isEditing) {
746
- event.preventDefault();
747
- setIsEditing(true);
748
- }
749
- };
750
- const handleChange = (newValue) => {
751
- setValue(newValue);
752
- };
753
- const editableContent = editableElement({ value, onChange: handleChange });
754
- if (isEditing) {
755
- return /* @__PURE__ */ React5.createElement(import_ui5.ClickAwayListener, { onClickAway: handleSave }, /* @__PURE__ */ React5.createElement(
756
- import_ui5.Stack,
757
- {
758
- direction: "row",
759
- alignItems: "center",
760
- gap: 1,
761
- onDoubleClick: handleDoubleClick,
762
- onKeyDown: handleKeyDown,
763
- tabIndex: 0,
764
- role: "button",
765
- "aria-label": "Double click or press Space to edit"
766
- },
767
- prefixElement,
768
- editableContent
769
- ));
770
- }
771
- return /* @__PURE__ */ React5.createElement(
772
- import_ui5.Stack,
773
- {
774
- direction: "row",
775
- alignItems: "center",
776
- gap: 1,
777
- onDoubleClick: handleDoubleClick,
778
- onKeyDown: handleKeyDown,
779
- tabIndex: 0,
780
- role: "button",
781
- "aria-label": "Double click or press Space to edit"
782
- },
783
- prefixElement,
784
- children
785
- );
786
- };
787
-
788
- // src/components/variables-manager/variable-table-cell.tsx
789
- var React6 = __toESM(require("react"));
790
- var import_ui6 = require("@elementor/ui");
1265
+ // src/components/variables-manager/ui/variable-table-cell.tsx
1266
+ var React9 = __toESM(require("react"));
1267
+ var import_ui9 = require("@elementor/ui");
791
1268
  var VariableTableCell = ({
792
1269
  children,
793
1270
  isHeader,
@@ -806,20 +1283,167 @@ var VariableTableCell = ({
806
1283
  ...width && { width },
807
1284
  ...sx
808
1285
  };
809
- return /* @__PURE__ */ React6.createElement(import_ui6.TableCell, { size: "small", padding: noPadding ? "none" : void 0, align, sx: baseSx }, children);
1286
+ return /* @__PURE__ */ React9.createElement(import_ui9.TableCell, { size: "small", padding: noPadding ? "none" : void 0, align, sx: baseSx }, children);
810
1287
  };
811
1288
 
1289
+ // src/components/variables-manager/variable-editable-cell.tsx
1290
+ var React10 = __toESM(require("react"));
1291
+ var import_react9 = require("react");
1292
+ var import_ui10 = require("@elementor/ui");
1293
+ var VariableEditableCell = React10.memo(
1294
+ ({
1295
+ initialValue,
1296
+ children,
1297
+ editableElement,
1298
+ onChange,
1299
+ prefixElement,
1300
+ autoEdit = false,
1301
+ onRowRef,
1302
+ onAutoEditComplete,
1303
+ gap = 1,
1304
+ fieldType
1305
+ }) => {
1306
+ const [value, setValue] = (0, import_react9.useState)(initialValue);
1307
+ const [isEditing, setIsEditing] = (0, import_react9.useState)(false);
1308
+ const { labelFieldError, setLabelFieldError } = useLabelError();
1309
+ const [valueFieldError, setValueFieldError] = (0, import_react9.useState)("");
1310
+ const rowRef = (0, import_react9.useRef)(null);
1311
+ const handleSave = (0, import_react9.useCallback)(() => {
1312
+ const hasError = fieldType === "label" && labelFieldError?.message || fieldType === "value" && valueFieldError;
1313
+ if (!hasError) {
1314
+ onChange(value);
1315
+ }
1316
+ setIsEditing(false);
1317
+ }, [value, onChange, fieldType, labelFieldError, valueFieldError]);
1318
+ (0, import_react9.useEffect)(() => {
1319
+ onRowRef?.(rowRef?.current);
1320
+ }, [onRowRef]);
1321
+ (0, import_react9.useEffect)(() => {
1322
+ if (autoEdit && !isEditing) {
1323
+ setIsEditing(true);
1324
+ onAutoEditComplete?.();
1325
+ }
1326
+ }, [autoEdit, isEditing, onAutoEditComplete]);
1327
+ const handleDoubleClick = () => {
1328
+ setIsEditing(true);
1329
+ };
1330
+ const handleKeyDown = (event) => {
1331
+ if (event.key === "Enter") {
1332
+ handleSave();
1333
+ } else if (event.key === "Escape") {
1334
+ setIsEditing(false);
1335
+ }
1336
+ if (event.key === " " && !isEditing) {
1337
+ event.preventDefault();
1338
+ setIsEditing(true);
1339
+ }
1340
+ };
1341
+ const handleChange = (0, import_react9.useCallback)((newValue) => {
1342
+ setValue(newValue);
1343
+ }, []);
1344
+ const handleValidationChange = (0, import_react9.useCallback)(
1345
+ (errorMsg) => {
1346
+ if (fieldType === "label") {
1347
+ setLabelFieldError({
1348
+ value,
1349
+ message: errorMsg
1350
+ });
1351
+ } else {
1352
+ setValueFieldError(errorMsg);
1353
+ }
1354
+ },
1355
+ [fieldType, value, setLabelFieldError, setValueFieldError]
1356
+ );
1357
+ let currentError;
1358
+ if (fieldType === "label") {
1359
+ currentError = labelFieldError;
1360
+ } else if (fieldType === "value") {
1361
+ currentError = { value, message: valueFieldError };
1362
+ }
1363
+ const editableContent = editableElement({
1364
+ value,
1365
+ onChange: handleChange,
1366
+ onValidationChange: handleValidationChange,
1367
+ error: currentError
1368
+ });
1369
+ if (isEditing) {
1370
+ return /* @__PURE__ */ React10.createElement(import_ui10.ClickAwayListener, { onClickAway: handleSave }, /* @__PURE__ */ React10.createElement(
1371
+ import_ui10.Stack,
1372
+ {
1373
+ ref: rowRef,
1374
+ direction: "row",
1375
+ alignItems: "center",
1376
+ gap,
1377
+ onDoubleClick: handleDoubleClick,
1378
+ onKeyDown: handleKeyDown,
1379
+ tabIndex: 0,
1380
+ role: "button",
1381
+ "aria-label": "Double click or press Space to edit"
1382
+ },
1383
+ prefixElement,
1384
+ editableContent
1385
+ ));
1386
+ }
1387
+ return /* @__PURE__ */ React10.createElement(
1388
+ import_ui10.Stack,
1389
+ {
1390
+ ref: rowRef,
1391
+ direction: "row",
1392
+ alignItems: "center",
1393
+ gap,
1394
+ onDoubleClick: handleDoubleClick,
1395
+ onKeyDown: handleKeyDown,
1396
+ tabIndex: 0,
1397
+ role: "button",
1398
+ "aria-label": "Double click or press Space to edit"
1399
+ },
1400
+ prefixElement,
1401
+ children
1402
+ );
1403
+ }
1404
+ );
1405
+
812
1406
  // src/components/variables-manager/variables-manager-table.tsx
813
- var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange }) => {
814
- const [ids, setIds] = (0, import_react6.useState)(Object.keys(variables));
1407
+ var VariablesManagerTable = ({
1408
+ menuActions,
1409
+ variables,
1410
+ onChange: handleOnChange,
1411
+ autoEditVariableId,
1412
+ onAutoEditComplete,
1413
+ onFieldError
1414
+ }) => {
1415
+ const tableContainerRef = (0, import_react10.useRef)(null);
1416
+ const variableRowRefs = (0, import_react10.useRef)(/* @__PURE__ */ new Map());
1417
+ (0, import_react10.useEffect)(() => {
1418
+ if (autoEditVariableId && tableContainerRef.current) {
1419
+ const rowElement = variableRowRefs.current.get(autoEditVariableId);
1420
+ if (rowElement) {
1421
+ setTimeout(() => {
1422
+ rowElement.scrollIntoView({
1423
+ behavior: "smooth",
1424
+ block: "center",
1425
+ inline: "nearest"
1426
+ });
1427
+ }, 100);
1428
+ }
1429
+ }
1430
+ }, [autoEditVariableId]);
1431
+ const handleRowRef = (id2) => (ref) => {
1432
+ if (ref) {
1433
+ variableRowRefs.current.set(id2, ref);
1434
+ } else {
1435
+ variableRowRefs.current.delete(id2);
1436
+ }
1437
+ };
1438
+ const ids = Object.keys(variables).sort(sortVariablesOrder(variables));
815
1439
  const rows = ids.filter((id2) => !variables[id2].deleted).map((id2) => {
816
1440
  const variable = variables[id2];
817
1441
  const variableType = getVariableType(variable.type);
818
1442
  return {
819
1443
  id: id2,
1444
+ type: variable.type,
820
1445
  name: variable.label,
821
1446
  value: variable.value,
822
- type: variable.type,
823
1447
  ...variableType
824
1448
  };
825
1449
  });
@@ -827,17 +1451,28 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
827
1451
  minWidth: 250,
828
1452
  tableLayout: "fixed"
829
1453
  };
830
- return /* @__PURE__ */ React7.createElement(import_ui7.TableContainer, { sx: { overflow: "initial" } }, /* @__PURE__ */ React7.createElement(import_ui7.Table, { sx: tableSX, "aria-label": "Variables manager list with drag and drop reordering", stickyHeader: true }, /* @__PURE__ */ React7.createElement(import_ui7.TableHead, null, /* @__PURE__ */ React7.createElement(import_ui7.TableRow, null, /* @__PURE__ */ React7.createElement(VariableTableCell, { isHeader: true, noPadding: true, width: 10, maxWidth: 10 }), /* @__PURE__ */ React7.createElement(VariableTableCell, { isHeader: true }, (0, import_i18n4.__)("Name", "elementor")), /* @__PURE__ */ React7.createElement(VariableTableCell, { isHeader: true }, (0, import_i18n4.__)("Value", "elementor")), /* @__PURE__ */ React7.createElement(VariableTableCell, { isHeader: true, noPadding: true, width: 16, maxWidth: 16 }))), /* @__PURE__ */ React7.createElement(import_ui7.TableBody, null, /* @__PURE__ */ React7.createElement(
831
- import_ui7.UnstableSortableProvider,
1454
+ const handleReorder = (newIds) => {
1455
+ const updatedVariables = { ...variables };
1456
+ newIds.forEach((id2, index) => {
1457
+ const current = updatedVariables[id2];
1458
+ if (!current) {
1459
+ return;
1460
+ }
1461
+ updatedVariables[id2] = Object.assign({}, current, { order: index + 1 });
1462
+ });
1463
+ handleOnChange(updatedVariables);
1464
+ };
1465
+ return /* @__PURE__ */ React11.createElement(import_ui11.TableContainer, { ref: tableContainerRef, sx: { overflow: "initial" } }, /* @__PURE__ */ React11.createElement(import_ui11.Table, { sx: tableSX, "aria-label": "Variables manager list with drag and drop reordering", stickyHeader: true }, /* @__PURE__ */ React11.createElement(import_ui11.TableHead, null, /* @__PURE__ */ React11.createElement(import_ui11.TableRow, null, /* @__PURE__ */ React11.createElement(VariableTableCell, { isHeader: true, noPadding: true, width: 10, maxWidth: 10 }), /* @__PURE__ */ React11.createElement(VariableTableCell, { isHeader: true }, (0, import_i18n8.__)("Name", "elementor")), /* @__PURE__ */ React11.createElement(VariableTableCell, { isHeader: true }, (0, import_i18n8.__)("Value", "elementor")), /* @__PURE__ */ React11.createElement(VariableTableCell, { isHeader: true, noPadding: true, width: 16, maxWidth: 16 }))), /* @__PURE__ */ React11.createElement(import_ui11.TableBody, null, /* @__PURE__ */ React11.createElement(
1466
+ import_ui11.UnstableSortableProvider,
832
1467
  {
833
1468
  value: ids,
834
- onChange: setIds,
1469
+ onChange: handleReorder,
835
1470
  variant: "static",
836
1471
  restrictAxis: true,
837
- dragOverlay: ({ children: dragOverlayChildren, ...dragOverlayProps }) => /* @__PURE__ */ React7.createElement(import_ui7.Table, { sx: tableSX, ...dragOverlayProps }, /* @__PURE__ */ React7.createElement(import_ui7.TableBody, null, dragOverlayChildren))
1472
+ dragOverlay: ({ children: dragOverlayChildren, ...dragOverlayProps }) => /* @__PURE__ */ React11.createElement(import_ui11.Table, { sx: tableSX, ...dragOverlayProps }, /* @__PURE__ */ React11.createElement(import_ui11.TableBody, null, dragOverlayChildren))
838
1473
  },
839
- rows.map((row) => /* @__PURE__ */ React7.createElement(
840
- import_ui7.UnstableSortableItem,
1474
+ rows.map((row) => /* @__PURE__ */ React11.createElement(
1475
+ import_ui11.UnstableSortableItem,
841
1476
  {
842
1477
  key: row.id,
843
1478
  id: row.id,
@@ -850,16 +1485,15 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
850
1485
  isDragged,
851
1486
  dropPosition,
852
1487
  setTriggerRef,
853
- isDragOverlay,
854
- isSorting,
855
- index
1488
+ isSorting
856
1489
  }) => {
857
1490
  const showIndicationBefore = showDropIndication && dropPosition === "before";
858
1491
  const showIndicationAfter = showDropIndication && dropPosition === "after";
859
- return /* @__PURE__ */ React7.createElement(
860
- import_ui7.TableRow,
1492
+ return /* @__PURE__ */ React11.createElement(
1493
+ import_ui11.TableRow,
861
1494
  {
862
1495
  ...itemProps,
1496
+ ref: handleRowRef("table-ref-" + row.id),
863
1497
  selected: isDragged,
864
1498
  sx: {
865
1499
  ...showIndicationBefore && {
@@ -884,11 +1518,10 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
884
1518
  }
885
1519
  }
886
1520
  },
887
- style: { ...itemStyle, ...triggerStyle },
888
- disableDivider: isDragOverlay || index === rows.length - 1
1521
+ style: { ...itemStyle, ...triggerStyle }
889
1522
  },
890
- /* @__PURE__ */ React7.createElement(VariableTableCell, { noPadding: true, width: 10, maxWidth: 10 }, /* @__PURE__ */ React7.createElement(
891
- import_ui7.IconButton,
1523
+ /* @__PURE__ */ React11.createElement(VariableTableCell, { noPadding: true, width: 10, maxWidth: 10 }, /* @__PURE__ */ React11.createElement(
1524
+ import_ui11.IconButton,
892
1525
  {
893
1526
  size: "small",
894
1527
  ref: setTriggerRef,
@@ -896,9 +1529,9 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
896
1529
  disabled: isSorting,
897
1530
  draggable: true
898
1531
  },
899
- /* @__PURE__ */ React7.createElement(import_icons2.GripVerticalIcon, { fontSize: "inherit" })
1532
+ /* @__PURE__ */ React11.createElement(import_icons5.GripVerticalIcon, { fontSize: "inherit" })
900
1533
  )),
901
- /* @__PURE__ */ React7.createElement(VariableTableCell, null, /* @__PURE__ */ React7.createElement(
1534
+ /* @__PURE__ */ React11.createElement(VariableTableCell, null, /* @__PURE__ */ React11.createElement(
902
1535
  VariableEditableCell,
903
1536
  {
904
1537
  initialValue: row.name,
@@ -910,20 +1543,37 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
910
1543
  });
911
1544
  }
912
1545
  },
913
- prefixElement: (0, import_react6.createElement)(row.icon, { fontSize: "inherit" }),
914
- editableElement: ({ value, onChange }) => /* @__PURE__ */ React7.createElement(
1546
+ prefixElement: (0, import_react10.createElement)(row.icon, { fontSize: "inherit" }),
1547
+ editableElement: ({
1548
+ value,
1549
+ onChange,
1550
+ onValidationChange,
1551
+ error
1552
+ }) => /* @__PURE__ */ React11.createElement(
915
1553
  LabelField,
916
1554
  {
917
1555
  id: "variable-label-" + row.id,
918
1556
  size: "tiny",
919
1557
  value,
920
1558
  onChange,
921
- focusOnShow: true
1559
+ onErrorChange: (errorMsg) => {
1560
+ onValidationChange?.(errorMsg);
1561
+ onFieldError?.(!!errorMsg);
1562
+ },
1563
+ error,
1564
+ focusOnShow: true,
1565
+ selectOnShow: autoEditVariableId === row.id,
1566
+ showWarningInfotip: true,
1567
+ variables
922
1568
  }
923
- )
1569
+ ),
1570
+ autoEdit: autoEditVariableId === row.id,
1571
+ onRowRef: handleRowRef(row.id),
1572
+ onAutoEditComplete: autoEditVariableId === row.id ? onAutoEditComplete : void 0,
1573
+ fieldType: "label"
924
1574
  },
925
- /* @__PURE__ */ React7.createElement(
926
- import_editor_ui.EllipsisWithTooltip,
1575
+ /* @__PURE__ */ React11.createElement(
1576
+ import_editor_ui2.EllipsisWithTooltip,
927
1577
  {
928
1578
  title: row.name,
929
1579
  sx: { border: "4px solid transparent" }
@@ -931,7 +1581,7 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
931
1581
  row.name
932
1582
  )
933
1583
  )),
934
- /* @__PURE__ */ React7.createElement(VariableTableCell, null, /* @__PURE__ */ React7.createElement(
1584
+ /* @__PURE__ */ React11.createElement(VariableTableCell, null, /* @__PURE__ */ React11.createElement(
935
1585
  VariableEditableCell,
936
1586
  {
937
1587
  initialValue: row.value,
@@ -943,19 +1593,51 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
943
1593
  });
944
1594
  }
945
1595
  },
946
- editableElement: row.valueField
1596
+ editableElement: ({
1597
+ value,
1598
+ onChange,
1599
+ onValidationChange,
1600
+ error
1601
+ }) => row.valueField({
1602
+ ref: {
1603
+ current: variableRowRefs.current.get(
1604
+ "table-ref-" + row.id
1605
+ )
1606
+ },
1607
+ value,
1608
+ onChange,
1609
+ onPropTypeKeyChange: (type) => {
1610
+ handleOnChange({
1611
+ ...variables,
1612
+ [row.id]: { ...variables[row.id], type }
1613
+ });
1614
+ },
1615
+ propTypeKey: row.type,
1616
+ onValidationChange: (errorMsg) => {
1617
+ onValidationChange?.(errorMsg);
1618
+ onFieldError?.(!!errorMsg);
1619
+ },
1620
+ error
1621
+ }),
1622
+ onRowRef: handleRowRef(row.id),
1623
+ gap: 0.25,
1624
+ fieldType: "value"
947
1625
  },
948
1626
  row.startIcon && row.startIcon({ value: row.value }),
949
- /* @__PURE__ */ React7.createElement(
950
- import_editor_ui.EllipsisWithTooltip,
1627
+ /* @__PURE__ */ React11.createElement(
1628
+ import_editor_ui2.EllipsisWithTooltip,
951
1629
  {
952
1630
  title: row.value,
953
- sx: { border: "4px solid transparent" }
1631
+ sx: {
1632
+ border: "4px solid transparent",
1633
+ lineHeight: "1",
1634
+ pt: 0.25
1635
+ }
954
1636
  },
955
1637
  row.value
956
1638
  )
957
1639
  )),
958
- /* @__PURE__ */ React7.createElement(
1640
+ /* @__PURE__ */ React11.createElement(
959
1641
  VariableTableCell,
960
1642
  {
961
1643
  align: "right",
@@ -964,7 +1646,7 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
964
1646
  maxWidth: 16,
965
1647
  sx: { paddingInlineEnd: 1 }
966
1648
  },
967
- /* @__PURE__ */ React7.createElement(import_ui7.Stack, { role: "toolbar", direction: "row", justifyContent: "flex-end" }, /* @__PURE__ */ React7.createElement(
1649
+ /* @__PURE__ */ React11.createElement(import_ui11.Stack, { role: "toolbar", direction: "row", justifyContent: "flex-end" }, /* @__PURE__ */ React11.createElement(
968
1650
  VariableEditMenu,
969
1651
  {
970
1652
  menuActions,
@@ -979,6 +1661,13 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
979
1661
  ))
980
1662
  ))));
981
1663
  };
1664
+ function sortVariablesOrder(variables) {
1665
+ return (a, b) => {
1666
+ const orderA = variables[a]?.order ?? Number.MAX_SAFE_INTEGER;
1667
+ const orderB = variables[b]?.order ?? Number.MAX_SAFE_INTEGER;
1668
+ return orderA - orderB;
1669
+ };
1670
+ }
982
1671
 
983
1672
  // src/components/variables-manager/variables-manager-panel.tsx
984
1673
  var id = "variables-manager";
@@ -991,39 +1680,134 @@ var { panel, usePanelActions } = (0, import_editor_panels.__createPanel)({
991
1680
  },
992
1681
  onClose: () => {
993
1682
  (0, import_editor_v1_adapters.changeEditMode)("edit");
994
- }
1683
+ },
1684
+ isOpenPreviousElement: true
995
1685
  });
996
1686
  function VariablesManagerPanel() {
997
1687
  const { close: closePanel } = usePanelActions();
998
- const [isDirty, setIsDirty] = (0, import_react7.useState)(false);
999
- const [variables, setVariables] = (0, import_react7.useState)(getVariables(false));
1000
- const [deletedVariables, setDeletedVariables] = (0, import_react7.useState)([]);
1688
+ const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = (0, import_editor_ui3.useDialog)();
1689
+ const createMenuState = (0, import_ui12.usePopupState)({
1690
+ variant: "popover"
1691
+ });
1692
+ const {
1693
+ variables,
1694
+ isDirty,
1695
+ searchValue,
1696
+ isSaveDisabled,
1697
+ handleOnChange,
1698
+ createVariable: createVariable2,
1699
+ handleDeleteVariable,
1700
+ handleSave,
1701
+ isSaving,
1702
+ handleSearch,
1703
+ setIsSaving,
1704
+ setIsSaveDisabled
1705
+ } = useVariablesManagerState();
1706
+ const { autoEditVariableId, startAutoEdit, handleAutoEditComplete } = useAutoEdit();
1707
+ const { createNavigationCallback, resetNavigation } = useErrorNavigation();
1708
+ const [deleteConfirmation, setDeleteConfirmation] = (0, import_react11.useState)(null);
1709
+ const [serverError, setServerError] = (0, import_react11.useState)(null);
1001
1710
  usePreventUnload(isDirty);
1711
+ const handleClosePanel = () => {
1712
+ if (isDirty) {
1713
+ openSaveChangesDialog();
1714
+ return;
1715
+ }
1716
+ closePanel();
1717
+ };
1718
+ const handleCreateVariable = (0, import_react11.useCallback)(
1719
+ (type, defaultName, defaultValue) => {
1720
+ const newId = createVariable2(type, defaultName, defaultValue);
1721
+ if (newId) {
1722
+ startAutoEdit(newId);
1723
+ }
1724
+ },
1725
+ [createVariable2, startAutoEdit]
1726
+ );
1727
+ const handleSaveClick = async () => {
1728
+ try {
1729
+ setServerError(null);
1730
+ resetNavigation();
1731
+ const result = await handleSave();
1732
+ trackVariablesManagerEvent({ action: "saveChanges" });
1733
+ return result;
1734
+ } catch (error) {
1735
+ const mappedError = mapServerError(error);
1736
+ const duplicatedIds = mappedError?.action?.data?.duplicatedIds;
1737
+ if (mappedError && "label" === mappedError.field) {
1738
+ if (duplicatedIds && mappedError.action) {
1739
+ mappedError.action.callback = createNavigationCallback(duplicatedIds, startAutoEdit, () => {
1740
+ setIsSaveDisabled(false);
1741
+ });
1742
+ }
1743
+ setServerError(mappedError);
1744
+ setIsSaveDisabled(true);
1745
+ resetNavigation();
1746
+ }
1747
+ return { success: false, error: mappedError };
1748
+ } finally {
1749
+ setIsSaving(false);
1750
+ }
1751
+ };
1752
+ const handleDeleteVariableWithConfirmation = (0, import_react11.useCallback)(
1753
+ (itemId) => {
1754
+ handleDeleteVariable(itemId);
1755
+ setDeleteConfirmation(null);
1756
+ },
1757
+ [handleDeleteVariable]
1758
+ );
1002
1759
  const menuActions = [
1003
1760
  {
1004
- name: (0, import_i18n5.__)("Delete", "elementor"),
1005
- icon: import_icons3.TrashIcon,
1761
+ name: (0, import_i18n9.__)("Delete", "elementor"),
1762
+ icon: import_icons6.TrashIcon,
1006
1763
  color: "error.main",
1007
1764
  onClick: (itemId) => {
1008
- setDeletedVariables([...deletedVariables, itemId]);
1009
- setVariables({ ...variables, [itemId]: { ...variables[itemId], deleted: true } });
1010
- setIsDirty(true);
1765
+ const variable = variables[itemId];
1766
+ if (variable) {
1767
+ setDeleteConfirmation({ id: itemId, label: variable.label });
1768
+ const variableTypeOptions = getVariableType(variable.type);
1769
+ trackVariablesManagerEvent({ action: "delete", varType: variableTypeOptions?.variableType });
1770
+ }
1011
1771
  }
1012
1772
  }
1013
1773
  ];
1014
- const handleOnChange = (newVariables) => {
1015
- setVariables(newVariables);
1016
- setIsDirty(true);
1017
- };
1018
- return /* @__PURE__ */ React8.createElement(import_editor_ui2.ThemeProvider, null, /* @__PURE__ */ React8.createElement(import_ui8.ErrorBoundary, { fallback: /* @__PURE__ */ React8.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React8.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React8.createElement(import_editor_panels.PanelHeader, null, /* @__PURE__ */ React8.createElement(import_ui8.Stack, { width: "100%", direction: "column", alignItems: "center" }, /* @__PURE__ */ React8.createElement(import_ui8.Stack, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React8.createElement(import_ui8.Stack, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React8.createElement(import_editor_panels.PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React8.createElement(import_icons3.ColorFilterIcon, { fontSize: "inherit" }), (0, import_i18n5.__)("Variable Manager", "elementor"))), /* @__PURE__ */ React8.createElement(
1019
- CloseButton,
1774
+ const hasVariables = Object.values(variables).some((variable) => !variable.deleted);
1775
+ return /* @__PURE__ */ React12.createElement(import_editor_ui3.ThemeProvider, null, /* @__PURE__ */ React12.createElement(import_editor_panels.Panel, null, /* @__PURE__ */ React12.createElement(
1776
+ import_editor_panels.PanelHeader,
1020
1777
  {
1021
- sx: { marginLeft: "auto" },
1022
- onClose: () => {
1023
- closePanel();
1778
+ sx: {
1779
+ height: "unset"
1024
1780
  }
1025
- }
1026
- )), /* @__PURE__ */ React8.createElement(import_ui8.Divider, { sx: { width: "100%" } }))), /* @__PURE__ */ React8.createElement(
1781
+ },
1782
+ /* @__PURE__ */ React12.createElement(import_ui12.Stack, { width: "100%", direction: "column", alignItems: "center" }, /* @__PURE__ */ React12.createElement(import_ui12.Stack, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React12.createElement(import_ui12.Stack, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React12.createElement(import_editor_panels.PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React12.createElement(import_icons6.ColorFilterIcon, { fontSize: "inherit" }), (0, import_i18n9.__)("Variables Manager", "elementor"))), /* @__PURE__ */ React12.createElement(import_ui12.Stack, { direction: "row", gap: 0.5, alignItems: "center" }, /* @__PURE__ */ React12.createElement(
1783
+ VariableManagerCreateMenu,
1784
+ {
1785
+ onCreate: handleCreateVariable,
1786
+ variables,
1787
+ menuState: createMenuState
1788
+ }
1789
+ ), /* @__PURE__ */ React12.createElement(
1790
+ import_ui12.CloseButton,
1791
+ {
1792
+ "aria-label": "Close",
1793
+ slotProps: { icon: { fontSize: SIZE } },
1794
+ onClick: () => {
1795
+ handleClosePanel();
1796
+ }
1797
+ }
1798
+ ))), /* @__PURE__ */ React12.createElement(import_ui12.Stack, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React12.createElement(
1799
+ import_editor_ui3.SearchField,
1800
+ {
1801
+ sx: {
1802
+ display: "flex",
1803
+ flex: 1
1804
+ },
1805
+ placeholder: (0, import_i18n9.__)("Search", "elementor"),
1806
+ value: searchValue,
1807
+ onSearch: handleSearch
1808
+ }
1809
+ )), /* @__PURE__ */ React12.createElement(import_ui12.Divider, { sx: { width: "100%" } }))
1810
+ ), /* @__PURE__ */ React12.createElement(
1027
1811
  import_editor_panels.PanelBody,
1028
1812
  {
1029
1813
  sx: {
@@ -1032,20 +1816,116 @@ function VariablesManagerPanel() {
1032
1816
  height: "100%"
1033
1817
  }
1034
1818
  },
1035
- /* @__PURE__ */ React8.createElement(
1819
+ hasVariables && /* @__PURE__ */ React12.createElement(
1036
1820
  VariablesManagerTable,
1037
1821
  {
1038
1822
  menuActions,
1039
1823
  variables,
1040
- onChange: handleOnChange
1824
+ onChange: handleOnChange,
1825
+ autoEditVariableId,
1826
+ onAutoEditComplete: handleAutoEditComplete,
1827
+ onFieldError: setIsSaveDisabled
1828
+ }
1829
+ ),
1830
+ !hasVariables && searchValue && /* @__PURE__ */ React12.createElement(
1831
+ NoSearchResults,
1832
+ {
1833
+ searchValue,
1834
+ onClear: () => handleSearch(""),
1835
+ icon: /* @__PURE__ */ React12.createElement(import_icons6.ColorFilterIcon, { fontSize: "large" })
1836
+ }
1837
+ ),
1838
+ !hasVariables && !searchValue && /* @__PURE__ */ React12.createElement(
1839
+ EmptyState,
1840
+ {
1841
+ title: (0, import_i18n9.__)("Create your first variable", "elementor"),
1842
+ message: (0, import_i18n9.__)(
1843
+ "Variables are saved attributes that you can apply anywhere on your site.",
1844
+ "elementor"
1845
+ ),
1846
+ icon: /* @__PURE__ */ React12.createElement(import_icons6.ColorFilterIcon, { fontSize: "large" }),
1847
+ onAdd: createMenuState.open
1848
+ }
1849
+ )
1850
+ ), /* @__PURE__ */ React12.createElement(import_editor_panels.PanelFooter, null, /* @__PURE__ */ React12.createElement(
1851
+ import_ui12.Infotip,
1852
+ {
1853
+ placement: "right",
1854
+ open: !!serverError,
1855
+ content: serverError ? /* @__PURE__ */ React12.createElement(
1856
+ import_ui12.Alert,
1857
+ {
1858
+ severity: serverError.severity ?? "error",
1859
+ action: serverError.action?.label ? /* @__PURE__ */ React12.createElement(import_ui12.AlertAction, { onClick: serverError.action.callback }, serverError.action.label) : void 0,
1860
+ onClose: !serverError.action?.label ? () => {
1861
+ setServerError(null);
1862
+ setIsSaveDisabled(false);
1863
+ } : void 0,
1864
+ icon: serverError.IconComponent ? /* @__PURE__ */ React12.createElement(serverError.IconComponent, null) : /* @__PURE__ */ React12.createElement(import_icons6.AlertTriangleFilledIcon, null)
1865
+ },
1866
+ /* @__PURE__ */ React12.createElement(import_ui12.AlertTitle, null, serverError.message),
1867
+ serverError.action?.message
1868
+ ) : null,
1869
+ arrow: false,
1870
+ slotProps: {
1871
+ popper: {
1872
+ modifiers: [
1873
+ {
1874
+ name: "offset",
1875
+ options: { offset: [-10, 10] }
1876
+ }
1877
+ ]
1878
+ }
1041
1879
  }
1880
+ },
1881
+ /* @__PURE__ */ React12.createElement(
1882
+ import_ui12.Button,
1883
+ {
1884
+ fullWidth: true,
1885
+ size: "small",
1886
+ color: "global",
1887
+ variant: "contained",
1888
+ disabled: isSaveDisabled || !isDirty || isSaving,
1889
+ onClick: handleSaveClick,
1890
+ loading: isSaving
1891
+ },
1892
+ (0, import_i18n9.__)("Save changes", "elementor")
1042
1893
  )
1043
- ), /* @__PURE__ */ React8.createElement(import_editor_panels.PanelFooter, null, /* @__PURE__ */ React8.createElement(import_ui8.Button, { fullWidth: true, size: "small", color: "global", variant: "contained", disabled: !isDirty }, (0, import_i18n5.__)("Save changes", "elementor"))))));
1894
+ ))), deleteConfirmation && /* @__PURE__ */ React12.createElement(
1895
+ DeleteConfirmationDialog,
1896
+ {
1897
+ open: true,
1898
+ label: deleteConfirmation.label,
1899
+ onConfirm: () => handleDeleteVariableWithConfirmation(deleteConfirmation.id),
1900
+ closeDialog: () => setDeleteConfirmation(null)
1901
+ }
1902
+ ), isSaveChangesDialogOpen && /* @__PURE__ */ React12.createElement(import_editor_ui3.SaveChangesDialog, null, /* @__PURE__ */ React12.createElement(import_editor_ui3.SaveChangesDialog.Title, { onClose: closeSaveChangesDialog }, (0, import_i18n9.__)("You have unsaved changes", "elementor")), /* @__PURE__ */ React12.createElement(import_editor_ui3.SaveChangesDialog.Content, null, /* @__PURE__ */ React12.createElement(import_editor_ui3.SaveChangesDialog.ContentText, null, (0, import_i18n9.__)("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React12.createElement(
1903
+ import_editor_ui3.SaveChangesDialog.Actions,
1904
+ {
1905
+ actions: {
1906
+ discard: {
1907
+ label: (0, import_i18n9.__)("Discard", "elementor"),
1908
+ action: () => {
1909
+ closeSaveChangesDialog();
1910
+ closePanel();
1911
+ }
1912
+ },
1913
+ confirm: {
1914
+ label: (0, import_i18n9.__)("Save", "elementor"),
1915
+ action: async () => {
1916
+ const result = await handleSaveClick();
1917
+ closeSaveChangesDialog();
1918
+ if (result?.success) {
1919
+ closePanel();
1920
+ }
1921
+ }
1922
+ }
1923
+ }
1924
+ }
1925
+ )));
1044
1926
  }
1045
- var CloseButton = ({ onClose, ...props }) => /* @__PURE__ */ React8.createElement(import_ui8.IconButton, { size: "small", color: "secondary", onClick: onClose, "aria-label": "Close", ...props }, /* @__PURE__ */ React8.createElement(import_icons3.XIcon, { fontSize: "small" }));
1046
- var ErrorBoundaryFallback = () => /* @__PURE__ */ React8.createElement(import_ui8.Box, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React8.createElement(import_ui8.Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React8.createElement("strong", null, (0, import_i18n5.__)("Something went wrong", "elementor"))));
1047
1927
  var usePreventUnload = (isDirty) => {
1048
- (0, import_react7.useEffect)(() => {
1928
+ (0, import_react11.useEffect)(() => {
1049
1929
  const handleBeforeUnload = (event) => {
1050
1930
  if (isDirty) {
1051
1931
  event.preventDefault();
@@ -1059,21 +1939,21 @@ var usePreventUnload = (isDirty) => {
1059
1939
  };
1060
1940
 
1061
1941
  // src/controls/variable-control.tsx
1062
- var React32 = __toESM(require("react"));
1942
+ var React31 = __toESM(require("react"));
1063
1943
  var import_editor_controls11 = require("@elementor/editor-controls");
1064
1944
 
1065
1945
  // src/components/ui/variable/assigned-variable.tsx
1066
- var import_react14 = require("react");
1067
- var React21 = __toESM(require("react"));
1946
+ var import_react18 = require("react");
1947
+ var React22 = __toESM(require("react"));
1068
1948
  var import_editor_controls6 = require("@elementor/editor-controls");
1069
- var import_icons11 = require("@elementor/icons");
1070
- var import_ui21 = require("@elementor/ui");
1949
+ var import_icons13 = require("@elementor/icons");
1950
+ var import_ui22 = require("@elementor/ui");
1071
1951
 
1072
1952
  // src/utils/unlink-variable.ts
1073
1953
  function transformValueBeforeUnlink(variable, propTypeKey) {
1074
1954
  const { valueTransformer } = getVariableType(propTypeKey);
1075
1955
  if (valueTransformer) {
1076
- return valueTransformer(variable.value);
1956
+ return valueTransformer(variable);
1077
1957
  }
1078
1958
  return variable.value;
1079
1959
  }
@@ -1086,96 +1966,92 @@ function createUnlinkHandler(variable, propTypeKey, setValue) {
1086
1966
  }
1087
1967
 
1088
1968
  // src/components/variable-selection-popover.tsx
1089
- var React19 = __toESM(require("react"));
1090
- var import_react13 = require("react");
1969
+ var React20 = __toESM(require("react"));
1970
+ var import_react17 = require("react");
1091
1971
  var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
1092
1972
 
1093
1973
  // src/context/variable-selection-popover.context.tsx
1094
- var React9 = __toESM(require("react"));
1095
- var import_react8 = require("react");
1096
- var import_ui9 = require("@elementor/ui");
1097
- var PopoverContentRefContext = (0, import_react8.createContext)(null);
1974
+ var React13 = __toESM(require("react"));
1975
+ var import_react12 = require("react");
1976
+ var import_ui13 = require("@elementor/ui");
1977
+ var PopoverContentRefContext = (0, import_react12.createContext)(null);
1098
1978
  var PopoverContentRefContextProvider = ({ children }) => {
1099
- const [anchorRef, setAnchorRef] = (0, import_react8.useState)(null);
1100
- return /* @__PURE__ */ React9.createElement(PopoverContentRefContext.Provider, { value: anchorRef }, /* @__PURE__ */ React9.createElement(import_ui9.Box, { ref: setAnchorRef }, children));
1979
+ const [anchorRef, setAnchorRef] = (0, import_react12.useState)(null);
1980
+ return /* @__PURE__ */ React13.createElement(PopoverContentRefContext.Provider, { value: anchorRef }, /* @__PURE__ */ React13.createElement(import_ui13.Box, { ref: setAnchorRef }, children));
1101
1981
  };
1102
1982
  var usePopoverContentRef = () => {
1103
- return (0, import_react8.useContext)(PopoverContentRefContext);
1104
- };
1105
-
1106
- // src/hooks/use-permissions.ts
1107
- var import_editor_current_user = require("@elementor/editor-current-user");
1108
- var usePermissions = () => {
1109
- const { canUser } = (0, import_editor_current_user.useCurrentUserCapabilities)();
1110
- return {
1111
- canAssign: () => canUser("edit_posts"),
1112
- canUnlink: () => canUser("edit_posts"),
1113
- canAdd: () => canUser("manage_options"),
1114
- canDelete: () => canUser("manage_options"),
1115
- canEdit: () => canUser("manage_options"),
1116
- canRestore: () => canUser("manage_options"),
1117
- canManageSettings: () => canUser("manage_options")
1118
- };
1983
+ return (0, import_react12.useContext)(PopoverContentRefContext);
1119
1984
  };
1120
1985
 
1121
1986
  // src/components/variable-creation.tsx
1122
- var React11 = __toESM(require("react"));
1123
- var import_react9 = require("react");
1124
- var import_editor_controls3 = require("@elementor/editor-controls");
1987
+ var React15 = __toESM(require("react"));
1988
+ var import_react13 = require("react");
1989
+ var import_editor_controls4 = require("@elementor/editor-controls");
1125
1990
  var import_editor_editing_panel2 = require("@elementor/editor-editing-panel");
1126
- var import_editor_ui3 = require("@elementor/editor-ui");
1127
- var import_icons4 = require("@elementor/icons");
1128
- var import_ui11 = require("@elementor/ui");
1129
- var import_i18n6 = require("@wordpress/i18n");
1991
+ var import_editor_ui4 = require("@elementor/editor-ui");
1992
+ var import_icons7 = require("@elementor/icons");
1993
+ var import_ui15 = require("@elementor/ui");
1994
+ var import_i18n10 = require("@wordpress/i18n");
1130
1995
 
1131
1996
  // src/hooks/use-initial-value.ts
1132
1997
  var import_editor_controls2 = require("@elementor/editor-controls");
1133
1998
  var useInitialValue = () => {
1134
1999
  const { value: initial } = (0, import_editor_controls2.useBoundProp)();
1135
- const hasAssignedVariable2 = hasVariableType(initial?.$$type) && Boolean(initial?.value);
1136
- const variable = useVariable(hasAssignedVariable2 ? initial.value : "");
1137
- if (hasAssignedVariable2) {
2000
+ const hasAssignedVariable = hasVariableType(initial?.$$type) && Boolean(initial?.value);
2001
+ const variable = useVariable(hasAssignedVariable ? initial.value : "");
2002
+ if (hasAssignedVariable) {
1138
2003
  return variable ? variable.value : "";
1139
2004
  }
1140
2005
  return initial?.value ?? "";
1141
2006
  };
1142
2007
 
1143
- // src/utils/tracking.ts
1144
- var trackVariableEvent = ({ varType, controlPath, action }) => {
1145
- const extendedWindow = window;
1146
- const config = extendedWindow?.elementorCommon?.eventsManager?.config;
1147
- if (!config?.names?.variables?.[action]) {
1148
- return;
2008
+ // src/hooks/use-variable-bound-prop.ts
2009
+ var import_editor_controls3 = require("@elementor/editor-controls");
2010
+ var import_editor_props3 = require("@elementor/editor-props");
2011
+ var useVariableBoundProp = () => {
2012
+ const { propTypeUtil } = useVariableType();
2013
+ const boundProp = (0, import_editor_controls3.useBoundProp)(propTypeUtil);
2014
+ return {
2015
+ ...boundProp,
2016
+ setVariableValue: (value) => resolveBoundPropAndSetValue(value, boundProp),
2017
+ variableId: boundProp.value ?? boundProp.placeholder
2018
+ };
2019
+ };
2020
+ var resolveBoundPropAndSetValue = (value, boundProp) => {
2021
+ const propValue = unwrapValue(boundProp.value);
2022
+ const placeholder = unwrapValue(boundProp.placeholder);
2023
+ const newValue = unwrapValue(value);
2024
+ if (!propValue && placeholder === newValue) {
2025
+ return boundProp.setValue(null);
1149
2026
  }
1150
- const name = config.names.variables[action];
1151
- extendedWindow.elementorCommon?.eventsManager?.dispatchEvent(name, {
1152
- location: config.locations.variables,
1153
- secondaryLocation: config.secondaryLocations.variablesPopover,
1154
- trigger: config.triggers.click,
1155
- var_type: varType,
1156
- control_path: controlPath,
1157
- action_type: name
1158
- });
2027
+ return boundProp.setValue(value);
2028
+ };
2029
+ var unwrapValue = (input) => {
2030
+ if ((0, import_editor_props3.isTransformable)(input)) {
2031
+ return input.value;
2032
+ }
2033
+ return input;
1159
2034
  };
1160
2035
 
1161
2036
  // src/components/ui/form-field.tsx
1162
- var React10 = __toESM(require("react"));
1163
- var import_ui10 = require("@elementor/ui");
2037
+ var React14 = __toESM(require("react"));
2038
+ var import_ui14 = require("@elementor/ui");
1164
2039
  var FormField = ({ id: id2, label, errorMsg, noticeMsg, children }) => {
1165
- return /* @__PURE__ */ React10.createElement(import_ui10.Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React10.createElement(import_ui10.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(import_ui10.FormLabel, { htmlFor: id2, size: "tiny" }, label)), /* @__PURE__ */ React10.createElement(import_ui10.Grid, { item: true, xs: 12 }, children, errorMsg && /* @__PURE__ */ React10.createElement(import_ui10.FormHelperText, { error: true }, errorMsg), noticeMsg && /* @__PURE__ */ React10.createElement(import_ui10.FormHelperText, null, noticeMsg)));
2040
+ return /* @__PURE__ */ React14.createElement(import_ui14.Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React14.createElement(import_ui14.Grid, { item: true, xs: 12 }, /* @__PURE__ */ React14.createElement(import_ui14.FormLabel, { htmlFor: id2, size: "tiny" }, label)), /* @__PURE__ */ React14.createElement(import_ui14.Grid, { item: true, xs: 12 }, children, errorMsg && /* @__PURE__ */ React14.createElement(import_ui14.FormHelperText, { error: true }, errorMsg), noticeMsg && /* @__PURE__ */ React14.createElement(import_ui14.FormHelperText, null, noticeMsg)));
1166
2041
  };
1167
2042
 
1168
2043
  // src/components/variable-creation.tsx
1169
- var SIZE = "tiny";
2044
+ var SIZE2 = "tiny";
1170
2045
  var VariableCreation = ({ onGoBack, onClose }) => {
1171
2046
  const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
1172
- const { setValue: setVariable, path } = (0, import_editor_controls3.useBoundProp)(propTypeUtil);
1173
- const { propType } = (0, import_editor_controls3.useBoundProp)();
2047
+ const { setVariableValue: setVariable, path } = useVariableBoundProp();
2048
+ const { propType } = (0, import_editor_controls4.useBoundProp)();
1174
2049
  const initialValue = useInitialValue();
1175
- const [value, setValue] = (0, import_react9.useState)(initialValue);
1176
- const [label, setLabel] = (0, import_react9.useState)("");
1177
- const [errorMessage, setErrorMessage] = (0, import_react9.useState)("");
1178
- const [valueFieldError, setValueFieldError] = (0, import_react9.useState)("");
2050
+ const [value, setValue] = (0, import_react13.useState)(initialValue);
2051
+ const [label, setLabel] = (0, import_react13.useState)("");
2052
+ const [errorMessage, setErrorMessage] = (0, import_react13.useState)("");
2053
+ const [valueFieldError, setValueFieldError] = (0, import_react13.useState)("");
2054
+ const [propTypeKey, setPropTypeKey] = (0, import_react13.useState)(propTypeUtil.key);
1179
2055
  const { labelFieldError, setLabelFieldError } = useLabelError();
1180
2056
  const resetFields = () => {
1181
2057
  setValue("");
@@ -1191,7 +2067,7 @@ var VariableCreation = ({ onGoBack, onClose }) => {
1191
2067
  createVariable({
1192
2068
  value,
1193
2069
  label,
1194
- type: propTypeUtil.key
2070
+ type: propTypeKey
1195
2071
  }).then((key) => {
1196
2072
  setVariable(key);
1197
2073
  closePopover();
@@ -1226,22 +2102,22 @@ var VariableCreation = ({ onGoBack, onClose }) => {
1226
2102
  return !!errorMessage;
1227
2103
  };
1228
2104
  const isSubmitDisabled = hasEmptyFields() || hasErrors();
1229
- return /* @__PURE__ */ React11.createElement(import_editor_editing_panel2.PopoverBody, { height: "auto" }, /* @__PURE__ */ React11.createElement(
1230
- import_editor_ui3.PopoverHeader,
2105
+ return /* @__PURE__ */ React15.createElement(import_editor_editing_panel2.PopoverBody, { height: "auto" }, /* @__PURE__ */ React15.createElement(
2106
+ import_editor_ui4.PopoverHeader,
1231
2107
  {
1232
- icon: /* @__PURE__ */ React11.createElement(React11.Fragment, null, onGoBack && /* @__PURE__ */ React11.createElement(import_ui11.IconButton, { size: SIZE, "aria-label": (0, import_i18n6.__)("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React11.createElement(import_icons4.ArrowLeftIcon, { fontSize: SIZE })), /* @__PURE__ */ React11.createElement(VariableIcon, { fontSize: SIZE })),
1233
- title: (0, import_i18n6.__)("Create variable", "elementor"),
2108
+ icon: /* @__PURE__ */ React15.createElement(React15.Fragment, null, onGoBack && /* @__PURE__ */ React15.createElement(import_ui15.IconButton, { size: SIZE2, "aria-label": (0, import_i18n10.__)("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React15.createElement(import_icons7.ArrowLeftIcon, { fontSize: SIZE2 })), /* @__PURE__ */ React15.createElement(VariableIcon, { fontSize: SIZE2 })),
2109
+ title: (0, import_i18n10.__)("Create variable", "elementor"),
1234
2110
  onClose: closePopover
1235
2111
  }
1236
- ), /* @__PURE__ */ React11.createElement(import_ui11.Divider, null), /* @__PURE__ */ React11.createElement(import_editor_controls3.PopoverContent, { p: 2 }, /* @__PURE__ */ React11.createElement(
2112
+ ), /* @__PURE__ */ React15.createElement(import_ui15.Divider, null), /* @__PURE__ */ React15.createElement(import_editor_controls4.PopoverContent, { p: 2 }, /* @__PURE__ */ React15.createElement(
1237
2113
  FormField,
1238
2114
  {
1239
2115
  id: "variable-label",
1240
- label: (0, import_i18n6.__)("Name", "elementor"),
2116
+ label: (0, import_i18n10.__)("Name", "elementor"),
1241
2117
  errorMsg: labelFieldError?.message,
1242
2118
  noticeMsg: labelHint(label)
1243
2119
  },
1244
- /* @__PURE__ */ React11.createElement(
2120
+ /* @__PURE__ */ React15.createElement(
1245
2121
  LabelField,
1246
2122
  {
1247
2123
  id: "variable-label",
@@ -1259,10 +2135,11 @@ var VariableCreation = ({ onGoBack, onClose }) => {
1259
2135
  }
1260
2136
  }
1261
2137
  )
1262
- ), /* @__PURE__ */ React11.createElement(FormField, { errorMsg: valueFieldError, label: (0, import_i18n6.__)("Value", "elementor") }, /* @__PURE__ */ React11.createElement(import_ui11.Typography, { variant: "h5" }, /* @__PURE__ */ React11.createElement(
2138
+ ), /* @__PURE__ */ React15.createElement(FormField, { errorMsg: valueFieldError, label: (0, import_i18n10.__)("Value", "elementor") }, /* @__PURE__ */ React15.createElement(import_ui15.Typography, { variant: "h5", id: "variable-value-wrapper" }, /* @__PURE__ */ React15.createElement(
1263
2139
  ValueField,
1264
2140
  {
1265
2141
  value,
2142
+ onPropTypeKeyChange: (key) => setPropTypeKey(key),
1266
2143
  onChange: (newValue) => {
1267
2144
  setValue(newValue);
1268
2145
  setErrorMessage("");
@@ -1271,93 +2148,89 @@ var VariableCreation = ({ onGoBack, onClose }) => {
1271
2148
  onValidationChange: setValueFieldError,
1272
2149
  propType
1273
2150
  }
1274
- ))), errorMessage && /* @__PURE__ */ React11.createElement(import_ui11.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ React11.createElement(import_ui11.CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React11.createElement(import_ui11.Button, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleCreateAndTrack }, (0, import_i18n6.__)("Create", "elementor"))));
2151
+ ))), errorMessage && /* @__PURE__ */ React15.createElement(import_ui15.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ React15.createElement(import_ui15.CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React15.createElement(
2152
+ import_ui15.Button,
2153
+ {
2154
+ id: "create-variable-button",
2155
+ size: "small",
2156
+ variant: "contained",
2157
+ disabled: isSubmitDisabled,
2158
+ onClick: handleCreateAndTrack
2159
+ },
2160
+ (0, import_i18n10.__)("Create", "elementor")
2161
+ )));
1275
2162
  };
1276
2163
 
1277
2164
  // src/components/variable-edit.tsx
1278
- var React14 = __toESM(require("react"));
1279
- var import_react11 = require("react");
1280
- var import_editor_controls4 = require("@elementor/editor-controls");
2165
+ var React17 = __toESM(require("react"));
2166
+ var import_react15 = require("react");
2167
+ var import_editor_controls5 = require("@elementor/editor-controls");
1281
2168
  var import_editor_current_user2 = require("@elementor/editor-current-user");
1282
2169
  var import_editor_editing_panel3 = require("@elementor/editor-editing-panel");
1283
- var import_editor_ui4 = require("@elementor/editor-ui");
1284
- var import_icons7 = require("@elementor/icons");
1285
- var import_ui14 = require("@elementor/ui");
1286
- var import_i18n9 = require("@wordpress/i18n");
1287
-
1288
- // src/components/ui/delete-confirmation-dialog.tsx
1289
- var React12 = __toESM(require("react"));
1290
- var import_icons5 = require("@elementor/icons");
1291
- var import_ui12 = require("@elementor/ui");
1292
- var import_i18n7 = require("@wordpress/i18n");
1293
- var TITLE_ID = "delete-variable-dialog";
1294
- var DeleteConfirmationDialog = ({
1295
- open,
1296
- label,
1297
- closeDialog,
1298
- onConfirm
1299
- }) => {
1300
- return /* @__PURE__ */ React12.createElement(import_ui12.Dialog, { open, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React12.createElement(import_ui12.DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React12.createElement(import_icons5.AlertOctagonFilledIcon, { color: "error" }), (0, import_i18n7.__)("Delete this variable?", "elementor")), /* @__PURE__ */ React12.createElement(import_ui12.DialogContent, null, /* @__PURE__ */ React12.createElement(import_ui12.DialogContentText, { variant: "body2", color: "textPrimary" }, (0, import_i18n7.__)("All elements using", "elementor"), "\xA0", /* @__PURE__ */ React12.createElement(import_ui12.Typography, { variant: "subtitle2", component: "span", sx: { lineBreak: "anywhere" } }, label), "\xA0", (0, import_i18n7.__)("will keep their current values, but the variable itself will be removed.", "elementor"))), /* @__PURE__ */ React12.createElement(import_ui12.DialogActions, null, /* @__PURE__ */ React12.createElement(import_ui12.Button, { color: "secondary", onClick: closeDialog }, (0, import_i18n7.__)("Not now", "elementor")), /* @__PURE__ */ React12.createElement(import_ui12.Button, { variant: "contained", color: "error", onClick: onConfirm }, (0, import_i18n7.__)("Delete", "elementor"))));
1301
- };
2170
+ var import_editor_ui5 = require("@elementor/editor-ui");
2171
+ var import_icons9 = require("@elementor/icons");
2172
+ var import_ui17 = require("@elementor/ui");
2173
+ var import_i18n12 = require("@wordpress/i18n");
1302
2174
 
1303
2175
  // src/components/ui/edit-confirmation-dialog.tsx
1304
- var React13 = __toESM(require("react"));
1305
- var import_react10 = require("react");
1306
- var import_icons6 = require("@elementor/icons");
1307
- var import_ui13 = require("@elementor/ui");
1308
- var import_i18n8 = require("@wordpress/i18n");
2176
+ var React16 = __toESM(require("react"));
2177
+ var import_react14 = require("react");
2178
+ var import_icons8 = require("@elementor/icons");
2179
+ var import_ui16 = require("@elementor/ui");
2180
+ var import_i18n11 = require("@wordpress/i18n");
1309
2181
  var EDIT_CONFIRMATION_DIALOG_ID = "edit-confirmation-dialog";
1310
2182
  var EditConfirmationDialog = ({
1311
2183
  closeDialog,
1312
2184
  onConfirm,
1313
2185
  onSuppressMessage
1314
2186
  }) => {
1315
- const [dontShowAgain, setDontShowAgain] = (0, import_react10.useState)(false);
2187
+ const [dontShowAgain, setDontShowAgain] = (0, import_react14.useState)(false);
1316
2188
  const handleSave = () => {
1317
2189
  if (dontShowAgain) {
1318
2190
  onSuppressMessage?.();
1319
2191
  }
1320
2192
  onConfirm?.();
1321
2193
  };
1322
- return /* @__PURE__ */ React13.createElement(import_ui13.Dialog, { open: true, onClose: closeDialog, maxWidth: "xs" }, /* @__PURE__ */ React13.createElement(import_ui13.DialogTitle, { display: "flex", alignItems: "center", gap: 1 }, /* @__PURE__ */ React13.createElement(import_icons6.AlertTriangleFilledIcon, { color: "secondary" }), (0, import_i18n8.__)("Changes to variables go live right away.", "elementor")), /* @__PURE__ */ React13.createElement(import_ui13.DialogContent, null, /* @__PURE__ */ React13.createElement(import_ui13.DialogContentText, { variant: "body2", color: "textPrimary" }, (0, import_i18n8.__)(
2194
+ return /* @__PURE__ */ React16.createElement(import_ui16.Dialog, { open: true, onClose: closeDialog, maxWidth: "xs" }, /* @__PURE__ */ React16.createElement(import_ui16.DialogTitle, { display: "flex", alignItems: "center", gap: 1 }, /* @__PURE__ */ React16.createElement(import_icons8.AlertTriangleFilledIcon, { color: "secondary" }), (0, import_i18n11.__)("Changes to variables go live right away.", "elementor")), /* @__PURE__ */ React16.createElement(import_ui16.DialogContent, null, /* @__PURE__ */ React16.createElement(import_ui16.DialogContentText, { variant: "body2", color: "textPrimary" }, (0, import_i18n11.__)(
1323
2195
  "Don't worry - all other changes you make will wait until you publish your site.",
1324
2196
  "elementor"
1325
- ))), /* @__PURE__ */ React13.createElement(import_ui13.DialogActions, { sx: { justifyContent: "space-between", alignItems: "center" } }, /* @__PURE__ */ React13.createElement(
1326
- import_ui13.FormControlLabel,
2197
+ ))), /* @__PURE__ */ React16.createElement(import_ui16.DialogActions, { sx: { justifyContent: "space-between", alignItems: "center" } }, /* @__PURE__ */ React16.createElement(
2198
+ import_ui16.FormControlLabel,
1327
2199
  {
1328
- control: /* @__PURE__ */ React13.createElement(
1329
- import_ui13.Checkbox,
2200
+ control: /* @__PURE__ */ React16.createElement(
2201
+ import_ui16.Checkbox,
1330
2202
  {
1331
2203
  checked: dontShowAgain,
1332
2204
  onChange: (event) => setDontShowAgain(event.target.checked),
1333
2205
  size: "small"
1334
2206
  }
1335
2207
  ),
1336
- label: /* @__PURE__ */ React13.createElement(import_ui13.Typography, { variant: "body2" }, (0, import_i18n8.__)("Don't show me again", "elementor"))
2208
+ label: /* @__PURE__ */ React16.createElement(import_ui16.Typography, { variant: "body2" }, (0, import_i18n11.__)("Don't show me again", "elementor"))
1337
2209
  }
1338
- ), /* @__PURE__ */ React13.createElement("div", null, /* @__PURE__ */ React13.createElement(import_ui13.Button, { color: "secondary", onClick: closeDialog }, (0, import_i18n8.__)("Keep editing", "elementor")), /* @__PURE__ */ React13.createElement(import_ui13.Button, { variant: "contained", color: "secondary", onClick: handleSave, sx: { ml: 1 } }, (0, import_i18n8.__)("Save", "elementor")))));
2210
+ ), /* @__PURE__ */ React16.createElement("div", null, /* @__PURE__ */ React16.createElement(import_ui16.Button, { color: "secondary", onClick: closeDialog }, (0, import_i18n11.__)("Keep editing", "elementor")), /* @__PURE__ */ React16.createElement(import_ui16.Button, { variant: "contained", color: "secondary", onClick: handleSave, sx: { ml: 1 } }, (0, import_i18n11.__)("Save", "elementor")))));
1339
2211
  };
1340
2212
 
1341
2213
  // src/components/variable-edit.tsx
1342
- var SIZE2 = "tiny";
2214
+ var SIZE3 = "tiny";
2215
+ var DELETE_LABEL = (0, import_i18n12.__)("Delete variable", "elementor");
1343
2216
  var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1344
- const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
1345
- const { setValue: notifyBoundPropChange, value: assignedValue } = (0, import_editor_controls4.useBoundProp)(propTypeUtil);
1346
- const { propType } = (0, import_editor_controls4.useBoundProp)();
2217
+ const { icon: VariableIcon, valueField: ValueField, variableType } = useVariableType();
2218
+ const { setVariableValue: notifyBoundPropChange, variableId } = useVariableBoundProp();
2219
+ const { propType } = (0, import_editor_controls5.useBoundProp)();
1347
2220
  const [isMessageSuppressed, suppressMessage] = (0, import_editor_current_user2.useSuppressedMessage)(EDIT_CONFIRMATION_DIALOG_ID);
1348
- const [deleteConfirmation, setDeleteConfirmation] = (0, import_react11.useState)(false);
1349
- const [editConfirmation, setEditConfirmation] = (0, import_react11.useState)(false);
1350
- const [errorMessage, setErrorMessage] = (0, import_react11.useState)("");
1351
- const [valueFieldError, setValueFieldError] = (0, import_react11.useState)("");
2221
+ const [deleteConfirmation, setDeleteConfirmation] = (0, import_react15.useState)(false);
2222
+ const [editConfirmation, setEditConfirmation] = (0, import_react15.useState)(false);
2223
+ const [errorMessage, setErrorMessage] = (0, import_react15.useState)("");
2224
+ const [valueFieldError, setValueFieldError] = (0, import_react15.useState)("");
1352
2225
  const { labelFieldError, setLabelFieldError } = useLabelError();
1353
2226
  const variable = useVariable(editId);
1354
2227
  if (!variable) {
1355
2228
  throw new Error(`Global ${variableType} variable not found`);
1356
2229
  }
1357
2230
  const userPermissions = usePermissions();
1358
- const [value, setValue] = (0, import_react11.useState)(() => variable.value);
1359
- const [label, setLabel] = (0, import_react11.useState)(() => variable.label);
1360
- (0, import_react11.useEffect)(() => {
2231
+ const [value, setValue] = (0, import_react15.useState)(() => variable.value);
2232
+ const [label, setLabel] = (0, import_react15.useState)(() => variable.label);
2233
+ (0, import_react15.useEffect)(() => {
1361
2234
  styleVariablesRepository.update({
1362
2235
  [editId]: {
1363
2236
  ...variable,
@@ -1404,7 +2277,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1404
2277
  });
1405
2278
  };
1406
2279
  const maybeTriggerBoundPropChange = () => {
1407
- if (editId === assignedValue) {
2280
+ if (editId === variableId) {
1408
2281
  notifyBoundPropChange(editId);
1409
2282
  }
1410
2283
  };
@@ -1420,16 +2293,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1420
2293
  const actions = [];
1421
2294
  if (userPermissions.canDelete()) {
1422
2295
  actions.push(
1423
- /* @__PURE__ */ React14.createElement(
1424
- import_ui14.IconButton,
1425
- {
1426
- key: "delete",
1427
- size: SIZE2,
1428
- "aria-label": (0, import_i18n9.__)("Delete", "elementor"),
1429
- onClick: handleDeleteConfirmation
1430
- },
1431
- /* @__PURE__ */ React14.createElement(import_icons7.TrashIcon, { fontSize: SIZE2 })
1432
- )
2296
+ /* @__PURE__ */ React17.createElement(import_ui17.Tooltip, { key: "delete", placement: "top", title: DELETE_LABEL }, /* @__PURE__ */ React17.createElement(import_ui17.IconButton, { size: SIZE3, onClick: handleDeleteConfirmation, "aria-label": DELETE_LABEL }, /* @__PURE__ */ React17.createElement(import_icons9.TrashIcon, { fontSize: SIZE3 })))
1433
2297
  );
1434
2298
  }
1435
2299
  const hasEmptyFields = () => {
@@ -1448,31 +2312,31 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1448
2312
  return !!errorMessage;
1449
2313
  };
1450
2314
  const isSubmitDisabled = noValueChanged() || hasEmptyFields() || hasErrors();
1451
- return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(import_editor_editing_panel3.PopoverBody, { height: "auto" }, /* @__PURE__ */ React14.createElement(
1452
- import_editor_ui4.PopoverHeader,
2315
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(import_editor_editing_panel3.PopoverBody, { height: "auto" }, /* @__PURE__ */ React17.createElement(
2316
+ import_editor_ui5.PopoverHeader,
1453
2317
  {
1454
- title: (0, import_i18n9.__)("Edit variable", "elementor"),
2318
+ title: (0, import_i18n12.__)("Edit variable", "elementor"),
1455
2319
  onClose,
1456
- icon: /* @__PURE__ */ React14.createElement(React14.Fragment, null, onGoBack && /* @__PURE__ */ React14.createElement(
1457
- import_ui14.IconButton,
2320
+ icon: /* @__PURE__ */ React17.createElement(React17.Fragment, null, onGoBack && /* @__PURE__ */ React17.createElement(
2321
+ import_ui17.IconButton,
1458
2322
  {
1459
- size: SIZE2,
1460
- "aria-label": (0, import_i18n9.__)("Go Back", "elementor"),
2323
+ size: SIZE3,
2324
+ "aria-label": (0, import_i18n12.__)("Go Back", "elementor"),
1461
2325
  onClick: onGoBack
1462
2326
  },
1463
- /* @__PURE__ */ React14.createElement(import_icons7.ArrowLeftIcon, { fontSize: SIZE2 })
1464
- ), /* @__PURE__ */ React14.createElement(VariableIcon, { fontSize: SIZE2 })),
2327
+ /* @__PURE__ */ React17.createElement(import_icons9.ArrowLeftIcon, { fontSize: SIZE3 })
2328
+ ), /* @__PURE__ */ React17.createElement(VariableIcon, { fontSize: SIZE3 })),
1465
2329
  actions
1466
2330
  }
1467
- ), /* @__PURE__ */ React14.createElement(import_ui14.Divider, null), /* @__PURE__ */ React14.createElement(import_editor_controls4.PopoverContent, { p: 2 }, /* @__PURE__ */ React14.createElement(
2331
+ ), /* @__PURE__ */ React17.createElement(import_ui17.Divider, null), /* @__PURE__ */ React17.createElement(import_editor_controls5.PopoverContent, { p: 2 }, /* @__PURE__ */ React17.createElement(
1468
2332
  FormField,
1469
2333
  {
1470
2334
  id: "variable-label",
1471
- label: (0, import_i18n9.__)("Name", "elementor"),
2335
+ label: (0, import_i18n12.__)("Name", "elementor"),
1472
2336
  errorMsg: labelFieldError?.message,
1473
2337
  noticeMsg: labelHint(label)
1474
2338
  },
1475
- /* @__PURE__ */ React14.createElement(
2339
+ /* @__PURE__ */ React17.createElement(
1476
2340
  LabelField,
1477
2341
  {
1478
2342
  id: "variable-label",
@@ -1490,9 +2354,10 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1490
2354
  }
1491
2355
  }
1492
2356
  )
1493
- ), /* @__PURE__ */ React14.createElement(FormField, { errorMsg: valueFieldError, label: (0, import_i18n9.__)("Value", "elementor") }, /* @__PURE__ */ React14.createElement(import_ui14.Typography, { variant: "h5" }, /* @__PURE__ */ React14.createElement(
2357
+ ), /* @__PURE__ */ React17.createElement(FormField, { errorMsg: valueFieldError, label: (0, import_i18n12.__)("Value", "elementor") }, /* @__PURE__ */ React17.createElement(import_ui17.Typography, { variant: "h5" }, /* @__PURE__ */ React17.createElement(
1494
2358
  ValueField,
1495
2359
  {
2360
+ propTypeKey: variable.type,
1496
2361
  value,
1497
2362
  onChange: (newValue) => {
1498
2363
  setValue(newValue);
@@ -1502,7 +2367,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1502
2367
  onValidationChange: setValueFieldError,
1503
2368
  propType
1504
2369
  }
1505
- ))), errorMessage && /* @__PURE__ */ React14.createElement(import_ui14.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ React14.createElement(import_ui14.CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React14.createElement(import_ui14.Button, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleUpdate }, (0, import_i18n9.__)("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ React14.createElement(
2370
+ ))), errorMessage && /* @__PURE__ */ React17.createElement(import_ui17.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ React17.createElement(import_ui17.CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React17.createElement(import_ui17.Button, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleUpdate }, (0, import_i18n12.__)("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ React17.createElement(
1506
2371
  DeleteConfirmationDialog,
1507
2372
  {
1508
2373
  open: true,
@@ -1510,7 +2375,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1510
2375
  onConfirm: handleDelete,
1511
2376
  closeDialog: closeDeleteDialog()
1512
2377
  }
1513
- ), editConfirmation && !isMessageSuppressed && /* @__PURE__ */ React14.createElement(
2378
+ ), editConfirmation && !isMessageSuppressed && /* @__PURE__ */ React17.createElement(
1514
2379
  EditConfirmationDialog,
1515
2380
  {
1516
2381
  closeDialog: closeEditDialog(),
@@ -1521,135 +2386,74 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1521
2386
  };
1522
2387
 
1523
2388
  // src/components/variables-selection.tsx
1524
- var React18 = __toESM(require("react"));
1525
- var import_react12 = require("react");
1526
- var import_editor_controls5 = require("@elementor/editor-controls");
2389
+ var React19 = __toESM(require("react"));
2390
+ var import_react16 = require("react");
1527
2391
  var import_editor_editing_panel4 = require("@elementor/editor-editing-panel");
1528
- var import_editor_ui6 = require("@elementor/editor-ui");
1529
- var import_icons9 = require("@elementor/icons");
1530
- var import_ui19 = require("@elementor/ui");
1531
- var import_i18n13 = require("@wordpress/i18n");
2392
+ var import_editor_ui7 = require("@elementor/editor-ui");
2393
+ var import_icons11 = require("@elementor/icons");
2394
+ var import_ui20 = require("@elementor/ui");
2395
+ var import_i18n14 = require("@wordpress/i18n");
1532
2396
 
1533
2397
  // src/components/ui/menu-item-content.tsx
1534
- var React15 = __toESM(require("react"));
1535
- var import_editor_ui5 = require("@elementor/editor-ui");
1536
- var import_icons8 = require("@elementor/icons");
1537
- var import_ui15 = require("@elementor/ui");
1538
- var import_i18n10 = require("@wordpress/i18n");
1539
- var SIZE3 = "tiny";
1540
- var MenuItemContent = ({ item }) => {
1541
- const onEdit = item.onEdit;
1542
- return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(import_ui15.ListItemIcon, null, item.icon), /* @__PURE__ */ React15.createElement(
1543
- import_ui15.Box,
1544
- {
1545
- sx: {
1546
- flex: 1,
1547
- minWidth: 0,
1548
- display: "flex",
1549
- alignItems: "center",
1550
- gap: 1
1551
- }
1552
- },
1553
- /* @__PURE__ */ React15.createElement(
1554
- import_editor_ui5.EllipsisWithTooltip,
1555
- {
1556
- title: item.label || item.value,
1557
- as: import_ui15.Typography,
1558
- variant: "caption",
1559
- color: "text.primary",
1560
- sx: { marginTop: "1px", lineHeight: "2" },
1561
- maxWidth: "50%"
1562
- }
1563
- ),
1564
- item.secondaryText && /* @__PURE__ */ React15.createElement(
1565
- import_editor_ui5.EllipsisWithTooltip,
1566
- {
1567
- title: item.secondaryText,
1568
- as: import_ui15.Typography,
1569
- variant: "caption",
1570
- color: "text.tertiary",
1571
- sx: { marginTop: "1px", lineHeight: "1" },
1572
- maxWidth: "50%"
1573
- }
1574
- )
1575
- ), !!onEdit && /* @__PURE__ */ React15.createElement(
1576
- import_ui15.IconButton,
1577
- {
1578
- sx: { mx: 1, opacity: "0" },
1579
- onClick: (e) => {
1580
- e.stopPropagation();
1581
- onEdit(item.value);
1582
- },
1583
- "aria-label": (0, import_i18n10.__)("Edit", "elementor")
1584
- },
1585
- /* @__PURE__ */ React15.createElement(import_icons8.EditIcon, { color: "action", fontSize: SIZE3 })
1586
- ));
1587
- };
1588
-
1589
- // src/components/ui/no-search-results.tsx
1590
- var React16 = __toESM(require("react"));
1591
- var import_ui16 = require("@elementor/ui");
1592
- var import_i18n11 = require("@wordpress/i18n");
1593
- var NoSearchResults = ({ searchValue, onClear, icon }) => {
1594
- return /* @__PURE__ */ React16.createElement(
1595
- import_ui16.Stack,
1596
- {
1597
- gap: 1,
1598
- alignItems: "center",
1599
- justifyContent: "center",
1600
- height: "100%",
1601
- p: 2.5,
1602
- color: "text.secondary",
1603
- sx: { pb: 3.5 }
1604
- },
1605
- icon,
1606
- /* @__PURE__ */ React16.createElement(import_ui16.Typography, { align: "center", variant: "subtitle2" }, (0, import_i18n11.__)("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React16.createElement("br", null), "\u201C", searchValue, "\u201D."),
1607
- /* @__PURE__ */ React16.createElement(import_ui16.Typography, { align: "center", variant: "caption", sx: { display: "flex", flexDirection: "column" } }, (0, import_i18n11.__)("Try something else.", "elementor"), /* @__PURE__ */ React16.createElement(import_ui16.Link, { color: "text.secondary", variant: "caption", component: "button", onClick: onClear }, (0, import_i18n11.__)("Clear & try again", "elementor")))
1608
- );
1609
- };
1610
-
1611
- // src/components/ui/no-variables.tsx
1612
- var React17 = __toESM(require("react"));
1613
- var import_ui17 = require("@elementor/ui");
1614
- var import_i18n12 = require("@wordpress/i18n");
1615
- var NoVariables = ({ icon, title, onAdd }) => {
1616
- const canAdd = usePermissions().canAdd();
1617
- return /* @__PURE__ */ React17.createElement(
1618
- import_ui17.Stack,
2398
+ var React18 = __toESM(require("react"));
2399
+ var import_editor_ui6 = require("@elementor/editor-ui");
2400
+ var import_icons10 = require("@elementor/icons");
2401
+ var import_ui18 = require("@elementor/ui");
2402
+ var import_i18n13 = require("@wordpress/i18n");
2403
+ var SIZE4 = "tiny";
2404
+ var EDIT_LABEL = (0, import_i18n13.__)("Edit variable", "elementor");
2405
+ var MenuItemContent = ({ item }) => {
2406
+ const onEdit = item.onEdit;
2407
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(import_ui18.ListItemIcon, null, item.icon), /* @__PURE__ */ React18.createElement(
2408
+ import_ui18.Box,
1619
2409
  {
1620
- gap: 1,
1621
- alignItems: "center",
1622
- justifyContent: "center",
1623
- height: "100%",
1624
- color: "text.secondary",
1625
- sx: { p: 2.5, pb: 5.5 }
2410
+ sx: {
2411
+ flex: 1,
2412
+ minWidth: 0,
2413
+ display: "flex",
2414
+ alignItems: "center",
2415
+ gap: 1
2416
+ }
1626
2417
  },
1627
- icon,
1628
- canAdd ? /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(
1629
- NoVariablesContent,
2418
+ /* @__PURE__ */ React18.createElement(
2419
+ import_editor_ui6.EllipsisWithTooltip,
1630
2420
  {
1631
- title: title || (0, import_i18n12.__)("Create your first variable", "elementor"),
1632
- message: (0, import_i18n12.__)(
1633
- "Variables are saved attributes that you can apply anywhere on your site.",
1634
- "elementor"
1635
- )
2421
+ title: item.label || item.value,
2422
+ as: import_ui18.Typography,
2423
+ variant: "caption",
2424
+ color: "text.primary",
2425
+ sx: { marginTop: "1px", lineHeight: "2" },
2426
+ maxWidth: "50%"
1636
2427
  }
1637
- ), onAdd && /* @__PURE__ */ React17.createElement(import_ui17.Button, { variant: "outlined", color: "secondary", size: "small", onClick: onAdd }, (0, import_i18n12.__)("Create a variable", "elementor"))) : /* @__PURE__ */ React17.createElement(
1638
- NoVariablesContent,
2428
+ ),
2429
+ item.secondaryText && /* @__PURE__ */ React18.createElement(
2430
+ import_editor_ui6.EllipsisWithTooltip,
1639
2431
  {
1640
- title: (0, import_i18n12.__)("There are no variables", "elementor"),
1641
- message: (0, import_i18n12.__)("With your current role, you can only connect and detach variables.", "elementor")
2432
+ title: item.secondaryText,
2433
+ as: import_ui18.Typography,
2434
+ variant: "caption",
2435
+ color: "text.tertiary",
2436
+ sx: { marginTop: "1px", lineHeight: "1" },
2437
+ maxWidth: "50%"
1642
2438
  }
1643
2439
  )
1644
- );
2440
+ ), !!onEdit && /* @__PURE__ */ React18.createElement(import_ui18.Tooltip, { placement: "top", title: EDIT_LABEL }, /* @__PURE__ */ React18.createElement(
2441
+ import_ui18.IconButton,
2442
+ {
2443
+ sx: { mx: 1, opacity: "0" },
2444
+ onClick: (e) => {
2445
+ e.stopPropagation();
2446
+ onEdit(item.value);
2447
+ },
2448
+ "aria-label": EDIT_LABEL
2449
+ },
2450
+ /* @__PURE__ */ React18.createElement(import_icons10.EditIcon, { color: "action", fontSize: SIZE4 })
2451
+ )));
1645
2452
  };
1646
- function NoVariablesContent({ title, message }) {
1647
- return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(import_ui17.Typography, { align: "center", variant: "subtitle2" }, title), /* @__PURE__ */ React17.createElement(import_ui17.Typography, { align: "center", variant: "caption", maxWidth: "180px" }, message));
1648
- }
1649
2453
 
1650
2454
  // src/components/ui/styled-menu-list.tsx
1651
- var import_ui18 = require("@elementor/ui");
1652
- var VariablesStyledMenuList = (0, import_ui18.styled)(import_ui18.MenuList)(({ theme }) => ({
2455
+ var import_ui19 = require("@elementor/ui");
2456
+ var VariablesStyledMenuList = (0, import_ui19.styled)(import_ui19.MenuList)(({ theme }) => ({
1653
2457
  "& > li": {
1654
2458
  height: 32,
1655
2459
  width: "100%",
@@ -1680,15 +2484,18 @@ var VariablesStyledMenuList = (0, import_ui18.styled)(import_ui18.MenuList)(({ t
1680
2484
  }));
1681
2485
 
1682
2486
  // src/components/variables-selection.tsx
1683
- var SIZE4 = "tiny";
2487
+ var SIZE5 = "tiny";
2488
+ var CREATE_LABEL = (0, import_i18n14.__)("Create variable", "elementor");
2489
+ var MANAGER_LABEL = (0, import_i18n14.__)("Variables Manager", "elementor");
1684
2490
  var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1685
2491
  const { icon: VariableIcon, startIcon, variableType, propTypeUtil } = useVariableType();
1686
- const { value: variable, setValue: setVariable, path } = (0, import_editor_controls5.useBoundProp)(propTypeUtil);
1687
- const [searchValue, setSearchValue] = (0, import_react12.useState)("");
2492
+ const { value: variable, setValue: setVariable, path } = useVariableBoundProp();
2493
+ const [searchValue, setSearchValue] = (0, import_react16.useState)("");
1688
2494
  const {
1689
2495
  list: variables,
1690
2496
  hasMatches: hasSearchResults,
1691
- isSourceNotEmpty: hasVariables
2497
+ isSourceNotEmpty: hasVariables,
2498
+ hasNoCompatibleVariables
1692
2499
  } = useFilteredVariables(searchValue, propTypeUtil.key);
1693
2500
  const handleSetVariable = (key) => {
1694
2501
  setVariable(key);
@@ -1710,20 +2517,46 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1710
2517
  const actions = [];
1711
2518
  if (onAdd) {
1712
2519
  actions.push(
1713
- /* @__PURE__ */ React18.createElement(import_ui19.IconButton, { key: "add", size: SIZE4, onClick: onAddAndTrack }, /* @__PURE__ */ React18.createElement(import_icons9.PlusIcon, { fontSize: SIZE4 }))
2520
+ /* @__PURE__ */ React19.createElement(import_ui20.Tooltip, { key: "add", placement: "top", title: CREATE_LABEL }, /* @__PURE__ */ React19.createElement(
2521
+ import_ui20.IconButton,
2522
+ {
2523
+ id: "add-variable-button",
2524
+ size: SIZE5,
2525
+ onClick: onAddAndTrack,
2526
+ "aria-label": CREATE_LABEL
2527
+ },
2528
+ /* @__PURE__ */ React19.createElement(import_icons11.PlusIcon, { fontSize: SIZE5 })
2529
+ ))
1714
2530
  );
1715
2531
  }
1716
2532
  if (onSettings) {
2533
+ const handleOpenManager = () => {
2534
+ onSettings();
2535
+ trackVariablesManagerEvent({
2536
+ action: "openManager",
2537
+ varType: variableType,
2538
+ controlPath: path.join(".")
2539
+ });
2540
+ };
1717
2541
  actions.push(
1718
- /* @__PURE__ */ React18.createElement(import_ui19.IconButton, { key: "settings", size: SIZE4, onClick: onSettings }, /* @__PURE__ */ React18.createElement(import_icons9.SettingsIcon, { fontSize: SIZE4 }))
2542
+ /* @__PURE__ */ React19.createElement(import_ui20.Tooltip, { key: "settings", placement: "top", title: MANAGER_LABEL }, /* @__PURE__ */ React19.createElement(
2543
+ import_ui20.IconButton,
2544
+ {
2545
+ id: "variables-manager-button",
2546
+ size: SIZE5,
2547
+ onClick: handleOpenManager,
2548
+ "aria-label": MANAGER_LABEL
2549
+ },
2550
+ /* @__PURE__ */ React19.createElement(import_icons11.SettingsIcon, { fontSize: SIZE5 })
2551
+ ))
1719
2552
  );
1720
2553
  }
1721
- const StartIcon = startIcon || (() => /* @__PURE__ */ React18.createElement(VariableIcon, { fontSize: SIZE4 }));
2554
+ const StartIcon = startIcon || (() => /* @__PURE__ */ React19.createElement(VariableIcon, { fontSize: SIZE5 }));
1722
2555
  const items = variables.map(({ value, label, key }) => ({
1723
2556
  type: "item",
1724
2557
  value: key,
1725
2558
  label,
1726
- icon: /* @__PURE__ */ React18.createElement(StartIcon, { value }),
2559
+ icon: /* @__PURE__ */ React19.createElement(StartIcon, { value }),
1727
2560
  secondaryText: value,
1728
2561
  onEdit: onEdit ? () => onEdit?.(key) : void 0
1729
2562
  }));
@@ -1733,28 +2566,28 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1733
2566
  const handleClearSearch = () => {
1734
2567
  setSearchValue("");
1735
2568
  };
1736
- const noVariableTitle = (0, import_i18n13.sprintf)(
2569
+ const noVariableTitle = (0, import_i18n14.sprintf)(
1737
2570
  /* translators: %s: Variable Type. */
1738
- (0, import_i18n13.__)("Create your first %s variable", "elementor"),
2571
+ (0, import_i18n14.__)("Create your first %s variable", "elementor"),
1739
2572
  variableType
1740
2573
  );
1741
- return /* @__PURE__ */ React18.createElement(import_editor_editing_panel4.PopoverBody, null, /* @__PURE__ */ React18.createElement(
1742
- import_editor_ui6.PopoverHeader,
2574
+ return /* @__PURE__ */ React19.createElement(import_editor_editing_panel4.PopoverBody, null, /* @__PURE__ */ React19.createElement(
2575
+ import_editor_ui7.PopoverHeader,
1743
2576
  {
1744
- title: (0, import_i18n13.__)("Variables", "elementor"),
1745
- icon: /* @__PURE__ */ React18.createElement(import_icons9.ColorFilterIcon, { fontSize: SIZE4 }),
2577
+ title: (0, import_i18n14.__)("Variables", "elementor"),
2578
+ icon: /* @__PURE__ */ React19.createElement(import_icons11.ColorFilterIcon, { fontSize: SIZE5 }),
1746
2579
  onClose: closePopover,
1747
2580
  actions
1748
2581
  }
1749
- ), hasVariables && /* @__PURE__ */ React18.createElement(
1750
- import_editor_ui6.PopoverSearch,
2582
+ ), hasVariables && /* @__PURE__ */ React19.createElement(
2583
+ import_editor_ui7.SearchField,
1751
2584
  {
1752
2585
  value: searchValue,
1753
2586
  onSearch: handleSearch,
1754
- placeholder: (0, import_i18n13.__)("Search", "elementor")
2587
+ placeholder: (0, import_i18n14.__)("Search", "elementor")
1755
2588
  }
1756
- ), /* @__PURE__ */ React18.createElement(import_ui19.Divider, null), hasVariables && hasSearchResults && /* @__PURE__ */ React18.createElement(
1757
- import_editor_ui6.PopoverMenuList,
2589
+ ), /* @__PURE__ */ React19.createElement(import_ui20.Divider, null), hasVariables && hasSearchResults && /* @__PURE__ */ React19.createElement(
2590
+ import_editor_ui7.PopoverMenuList,
1758
2591
  {
1759
2592
  items,
1760
2593
  onSelect: handleSetVariable,
@@ -1763,16 +2596,38 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1763
2596
  selectedValue: variable,
1764
2597
  "data-testid": `${variableType}-variables-list`,
1765
2598
  menuListTemplate: VariablesStyledMenuList,
1766
- menuItemContentTemplate: (item) => /* @__PURE__ */ React18.createElement(MenuItemContent, { item })
2599
+ menuItemContentTemplate: (item) => /* @__PURE__ */ React19.createElement(MenuItemContent, { item })
1767
2600
  }
1768
- ), !hasSearchResults && hasVariables && /* @__PURE__ */ React18.createElement(
2601
+ ), !hasSearchResults && hasVariables && /* @__PURE__ */ React19.createElement(
1769
2602
  NoSearchResults,
1770
2603
  {
1771
2604
  searchValue,
1772
2605
  onClear: handleClearSearch,
1773
- icon: /* @__PURE__ */ React18.createElement(VariableIcon, { fontSize: "large" })
2606
+ icon: /* @__PURE__ */ React19.createElement(VariableIcon, { fontSize: "large" })
2607
+ }
2608
+ ), !hasVariables && !hasNoCompatibleVariables && /* @__PURE__ */ React19.createElement(
2609
+ EmptyState,
2610
+ {
2611
+ title: noVariableTitle,
2612
+ message: (0, import_i18n14.__)(
2613
+ "Variables are saved attributes that you can apply anywhere on your site.",
2614
+ "elementor"
2615
+ ),
2616
+ icon: /* @__PURE__ */ React19.createElement(VariableIcon, { fontSize: "large" }),
2617
+ onAdd
2618
+ }
2619
+ ), hasNoCompatibleVariables && /* @__PURE__ */ React19.createElement(
2620
+ EmptyState,
2621
+ {
2622
+ title: (0, import_i18n14.__)("No compatible variables", "elementor"),
2623
+ message: (0, import_i18n14.__)(
2624
+ "Looks like none of your variables work with this control. Create a new variable to use it here.",
2625
+ "elementor"
2626
+ ),
2627
+ icon: /* @__PURE__ */ React19.createElement(VariableIcon, { fontSize: "large" }),
2628
+ onAdd
1774
2629
  }
1775
- ), !hasVariables && /* @__PURE__ */ React18.createElement(NoVariables, { title: noVariableTitle, icon: /* @__PURE__ */ React18.createElement(VariableIcon, { fontSize: "large" }), onAdd }));
2630
+ ));
1776
2631
  };
1777
2632
 
1778
2633
  // src/components/variable-selection-popover.tsx
@@ -1780,13 +2635,13 @@ var VIEW_LIST = "list";
1780
2635
  var VIEW_ADD = "add";
1781
2636
  var VIEW_EDIT = "edit";
1782
2637
  var VariableSelectionPopover = ({ closePopover, propTypeKey, selectedVariable }) => {
1783
- const [currentView, setCurrentView] = (0, import_react13.useState)(VIEW_LIST);
1784
- const [editId, setEditId] = (0, import_react13.useState)("");
2638
+ const [currentView, setCurrentView] = (0, import_react17.useState)(VIEW_LIST);
2639
+ const [editId, setEditId] = (0, import_react17.useState)("");
1785
2640
  const { open } = usePanelActions();
1786
2641
  const onSettingsAvailable = (0, import_editor_v1_adapters2.isExperimentActive)("e_variables_manager") ? () => {
1787
2642
  open();
1788
2643
  } : void 0;
1789
- return /* @__PURE__ */ React19.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ React19.createElement(PopoverContentRefContextProvider, null, RenderView({
2644
+ return /* @__PURE__ */ React20.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ React20.createElement(PopoverContentRefContextProvider, null, RenderView({
1790
2645
  propTypeKey,
1791
2646
  currentView,
1792
2647
  selectedVariable,
@@ -1832,7 +2687,7 @@ function RenderView(props) {
1832
2687
  }
1833
2688
  };
1834
2689
  if (VIEW_LIST === props.currentView) {
1835
- return /* @__PURE__ */ React19.createElement(
2690
+ return /* @__PURE__ */ React20.createElement(
1836
2691
  VariablesSelection,
1837
2692
  {
1838
2693
  closePopover: handlers.onClose,
@@ -1843,10 +2698,10 @@ function RenderView(props) {
1843
2698
  );
1844
2699
  }
1845
2700
  if (VIEW_ADD === props.currentView) {
1846
- return /* @__PURE__ */ React19.createElement(VariableCreation, { onGoBack: handlers.onGoBack, onClose: handlers.onClose });
2701
+ return /* @__PURE__ */ React20.createElement(VariableCreation, { onGoBack: handlers.onGoBack, onClose: handlers.onClose });
1847
2702
  }
1848
2703
  if (VIEW_EDIT === props.currentView) {
1849
- return /* @__PURE__ */ React19.createElement(
2704
+ return /* @__PURE__ */ React20.createElement(
1850
2705
  VariableEdit,
1851
2706
  {
1852
2707
  editId: props.editId,
@@ -1860,25 +2715,26 @@ function RenderView(props) {
1860
2715
  }
1861
2716
 
1862
2717
  // src/components/ui/tags/assigned-tag.tsx
1863
- var React20 = __toESM(require("react"));
1864
- var import_icons10 = require("@elementor/icons");
1865
- var import_ui20 = require("@elementor/ui");
1866
- var import_i18n14 = require("@wordpress/i18n");
1867
- var SIZE5 = "tiny";
2718
+ var React21 = __toESM(require("react"));
2719
+ var import_icons12 = require("@elementor/icons");
2720
+ var import_ui21 = require("@elementor/ui");
2721
+ var import_i18n15 = require("@wordpress/i18n");
2722
+ var SIZE6 = "tiny";
2723
+ var UNLINK_LABEL = (0, import_i18n15.__)("Unlink variable", "elementor");
1868
2724
  var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
1869
2725
  const actions = [];
1870
2726
  if (onUnlink) {
1871
2727
  actions.push(
1872
- /* @__PURE__ */ React20.createElement(import_ui20.IconButton, { key: "unlink", size: SIZE5, onClick: onUnlink, "aria-label": (0, import_i18n14.__)("Unlink", "elementor") }, /* @__PURE__ */ React20.createElement(import_icons10.DetachIcon, { fontSize: SIZE5 }))
2728
+ /* @__PURE__ */ React21.createElement(import_ui21.Tooltip, { key: "unlink", title: UNLINK_LABEL, placement: "bottom" }, /* @__PURE__ */ React21.createElement(import_ui21.IconButton, { size: SIZE6, onClick: onUnlink, "aria-label": UNLINK_LABEL }, /* @__PURE__ */ React21.createElement(import_icons12.DetachIcon, { fontSize: SIZE6 })))
1873
2729
  );
1874
2730
  }
1875
- return /* @__PURE__ */ React20.createElement(import_ui20.Tooltip, { title: label, placement: "top" }, /* @__PURE__ */ React20.createElement(
1876
- import_ui20.UnstableTag,
2731
+ return /* @__PURE__ */ React21.createElement(import_ui21.Tooltip, { title: label, placement: "top" }, /* @__PURE__ */ React21.createElement(
2732
+ import_ui21.UnstableTag,
1877
2733
  {
1878
2734
  fullWidth: true,
1879
2735
  showActionsOnHover: true,
1880
- startIcon: /* @__PURE__ */ React20.createElement(import_ui20.Stack, { gap: 0.5, direction: "row", alignItems: "center" }, startIcon),
1881
- label: /* @__PURE__ */ React20.createElement(import_ui20.Box, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React20.createElement(import_ui20.Typography, { sx: { lineHeight: 1.34 }, variant: "caption", noWrap: true }, label)),
2736
+ startIcon: /* @__PURE__ */ React21.createElement(import_ui21.Stack, { gap: 0.5, direction: "row", alignItems: "center" }, startIcon),
2737
+ label: /* @__PURE__ */ React21.createElement(import_ui21.Box, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React21.createElement(import_ui21.Typography, { sx: { lineHeight: 1.34 }, variant: "caption", noWrap: true }, label)),
1882
2738
  actions,
1883
2739
  ...props
1884
2740
  }
@@ -1889,24 +2745,24 @@ var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
1889
2745
  var AssignedVariable = ({ variable, propTypeKey }) => {
1890
2746
  const { startIcon, propTypeUtil } = getVariableType(propTypeKey);
1891
2747
  const { setValue } = (0, import_editor_controls6.useBoundProp)();
1892
- const anchorRef = (0, import_react14.useRef)(null);
1893
- const popupId = (0, import_react14.useId)();
1894
- const popupState = (0, import_ui21.usePopupState)({
2748
+ const anchorRef = (0, import_react18.useRef)(null);
2749
+ const popupId = (0, import_react18.useId)();
2750
+ const popupState = (0, import_ui22.usePopupState)({
1895
2751
  variant: "popover",
1896
2752
  popupId: `elementor-variables-list-${popupId}`
1897
2753
  });
1898
2754
  const unlinkVariable = createUnlinkHandler(variable, propTypeKey, setValue);
1899
2755
  const StartIcon = startIcon || (() => null);
1900
- return /* @__PURE__ */ React21.createElement(import_ui21.Box, { ref: anchorRef }, /* @__PURE__ */ React21.createElement(
2756
+ return /* @__PURE__ */ React22.createElement(import_ui22.Box, { ref: anchorRef }, /* @__PURE__ */ React22.createElement(
1901
2757
  AssignedTag,
1902
2758
  {
1903
2759
  label: variable.label,
1904
- startIcon: /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(import_icons11.ColorFilterIcon, { fontSize: SIZE5 }), /* @__PURE__ */ React21.createElement(StartIcon, { value: variable.value })),
2760
+ startIcon: /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(import_icons13.ColorFilterIcon, { fontSize: SIZE6 }), /* @__PURE__ */ React22.createElement(StartIcon, { value: variable.value })),
1905
2761
  onUnlink: unlinkVariable,
1906
- ...(0, import_ui21.bindTrigger)(popupState)
2762
+ ...(0, import_ui22.bindTrigger)(popupState)
1907
2763
  }
1908
- ), /* @__PURE__ */ React21.createElement(
1909
- import_ui21.Popover,
2764
+ ), /* @__PURE__ */ React22.createElement(
2765
+ import_ui22.Popover,
1910
2766
  {
1911
2767
  disableScrollLock: true,
1912
2768
  anchorEl: anchorRef.current,
@@ -1915,9 +2771,9 @@ var AssignedVariable = ({ variable, propTypeKey }) => {
1915
2771
  PaperProps: {
1916
2772
  sx: { my: 1 }
1917
2773
  },
1918
- ...(0, import_ui21.bindPopover)(popupState)
2774
+ ...(0, import_ui22.bindPopover)(popupState)
1919
2775
  },
1920
- /* @__PURE__ */ React21.createElement(
2776
+ /* @__PURE__ */ React22.createElement(
1921
2777
  VariableSelectionPopover,
1922
2778
  {
1923
2779
  selectedVariable: variable,
@@ -1929,32 +2785,33 @@ var AssignedVariable = ({ variable, propTypeKey }) => {
1929
2785
  };
1930
2786
 
1931
2787
  // src/components/ui/variable/deleted-variable.tsx
1932
- var React25 = __toESM(require("react"));
1933
- var import_react16 = require("react");
2788
+ var React26 = __toESM(require("react"));
2789
+ var import_react20 = require("react");
1934
2790
  var import_editor_controls8 = require("@elementor/editor-controls");
1935
- var import_ui25 = require("@elementor/ui");
2791
+ var import_ui26 = require("@elementor/ui");
2792
+ var import_i18n18 = require("@wordpress/i18n");
1936
2793
 
1937
2794
  // src/components/variable-restore.tsx
1938
- var React22 = __toESM(require("react"));
1939
- var import_react15 = require("react");
2795
+ var React23 = __toESM(require("react"));
2796
+ var import_react19 = require("react");
1940
2797
  var import_editor_controls7 = require("@elementor/editor-controls");
1941
2798
  var import_editor_editing_panel5 = require("@elementor/editor-editing-panel");
1942
- var import_editor_ui7 = require("@elementor/editor-ui");
1943
- var import_ui22 = require("@elementor/ui");
1944
- var import_i18n15 = require("@wordpress/i18n");
1945
- var SIZE6 = "tiny";
2799
+ var import_editor_ui8 = require("@elementor/editor-ui");
2800
+ var import_ui23 = require("@elementor/ui");
2801
+ var import_i18n16 = require("@wordpress/i18n");
2802
+ var SIZE7 = "tiny";
1946
2803
  var VariableRestore = ({ variableId, onClose, onSubmit }) => {
1947
- const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
1948
- const { setValue: notifyBoundPropChange } = (0, import_editor_controls7.useBoundProp)(propTypeUtil);
2804
+ const { icon: VariableIcon, valueField: ValueField, variableType } = useVariableType();
2805
+ const { setVariableValue: notifyBoundPropChange } = useVariableBoundProp();
1949
2806
  const { propType } = (0, import_editor_controls7.useBoundProp)();
1950
2807
  const variable = useVariable(variableId);
1951
2808
  if (!variable) {
1952
2809
  throw new Error(`Global ${variableType} variable not found`);
1953
2810
  }
1954
- const [errorMessage, setErrorMessage] = (0, import_react15.useState)("");
1955
- const [valueFieldError, setValueFieldError] = (0, import_react15.useState)("");
1956
- const [label, setLabel] = (0, import_react15.useState)(variable.label);
1957
- const [value, setValue] = (0, import_react15.useState)(variable.value);
2811
+ const [errorMessage, setErrorMessage] = (0, import_react19.useState)("");
2812
+ const [valueFieldError, setValueFieldError] = (0, import_react19.useState)("");
2813
+ const [label, setLabel] = (0, import_react19.useState)(variable.label);
2814
+ const [value, setValue] = (0, import_react19.useState)(variable.value);
1958
2815
  const { labelFieldError, setLabelFieldError } = useLabelError({
1959
2816
  value: variable.label,
1960
2817
  message: ERROR_MESSAGES.DUPLICATED_LABEL
@@ -1992,22 +2849,22 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
1992
2849
  return !!errorMessage;
1993
2850
  };
1994
2851
  const isSubmitDisabled = noValueChanged() || hasEmptyFields() || hasErrors();
1995
- return /* @__PURE__ */ React22.createElement(PopoverContentRefContextProvider, null, /* @__PURE__ */ React22.createElement(import_editor_editing_panel5.PopoverBody, { height: "auto" }, /* @__PURE__ */ React22.createElement(
1996
- import_editor_ui7.PopoverHeader,
2852
+ return /* @__PURE__ */ React23.createElement(PopoverContentRefContextProvider, null, /* @__PURE__ */ React23.createElement(import_editor_editing_panel5.PopoverBody, { height: "auto" }, /* @__PURE__ */ React23.createElement(
2853
+ import_editor_ui8.PopoverHeader,
1997
2854
  {
1998
- icon: /* @__PURE__ */ React22.createElement(VariableIcon, { fontSize: SIZE6 }),
1999
- title: (0, import_i18n15.__)("Restore variable", "elementor"),
2855
+ icon: /* @__PURE__ */ React23.createElement(VariableIcon, { fontSize: SIZE7 }),
2856
+ title: (0, import_i18n16.__)("Restore variable", "elementor"),
2000
2857
  onClose
2001
2858
  }
2002
- ), /* @__PURE__ */ React22.createElement(import_ui22.Divider, null), /* @__PURE__ */ React22.createElement(import_editor_controls7.PopoverContent, { p: 2 }, /* @__PURE__ */ React22.createElement(
2859
+ ), /* @__PURE__ */ React23.createElement(import_ui23.Divider, null), /* @__PURE__ */ React23.createElement(import_editor_controls7.PopoverContent, { p: 2 }, /* @__PURE__ */ React23.createElement(
2003
2860
  FormField,
2004
2861
  {
2005
2862
  id: "variable-label",
2006
- label: (0, import_i18n15.__)("Name", "elementor"),
2863
+ label: (0, import_i18n16.__)("Name", "elementor"),
2007
2864
  errorMsg: labelFieldError?.message,
2008
2865
  noticeMsg: labelHint(label)
2009
2866
  },
2010
- /* @__PURE__ */ React22.createElement(
2867
+ /* @__PURE__ */ React23.createElement(
2011
2868
  LabelField,
2012
2869
  {
2013
2870
  id: "variable-label",
@@ -2025,7 +2882,7 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
2025
2882
  }
2026
2883
  }
2027
2884
  )
2028
- ), /* @__PURE__ */ React22.createElement(FormField, { errorMsg: valueFieldError, label: (0, import_i18n15.__)("Value", "elementor") }, /* @__PURE__ */ React22.createElement(import_ui22.Typography, { variant: "h5" }, /* @__PURE__ */ React22.createElement(
2885
+ ), /* @__PURE__ */ React23.createElement(FormField, { errorMsg: valueFieldError, label: (0, import_i18n16.__)("Value", "elementor") }, /* @__PURE__ */ React23.createElement(import_ui23.Typography, { variant: "h5" }, /* @__PURE__ */ React23.createElement(
2029
2886
  ValueField,
2030
2887
  {
2031
2888
  value,
@@ -2037,91 +2894,87 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
2037
2894
  onValidationChange: setValueFieldError,
2038
2895
  propType
2039
2896
  }
2040
- ))), errorMessage && /* @__PURE__ */ React22.createElement(import_ui22.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ React22.createElement(import_ui22.CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React22.createElement(import_ui22.Button, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleRestore }, (0, import_i18n15.__)("Restore", "elementor")))));
2897
+ ))), errorMessage && /* @__PURE__ */ React23.createElement(import_ui23.FormHelperText, { error: true }, errorMessage)), /* @__PURE__ */ React23.createElement(import_ui23.CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React23.createElement(import_ui23.Button, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleRestore }, (0, import_i18n16.__)("Restore", "elementor")))));
2041
2898
  };
2042
2899
 
2043
2900
  // src/components/ui/deleted-variable-alert.tsx
2044
- var React23 = __toESM(require("react"));
2045
- var import_editor_editing_panel6 = require("@elementor/editor-editing-panel");
2046
- var import_ui23 = require("@elementor/ui");
2047
- var import_i18n16 = require("@wordpress/i18n");
2901
+ var React24 = __toESM(require("react"));
2902
+ var import_ui24 = require("@elementor/ui");
2903
+ var import_i18n17 = require("@wordpress/i18n");
2048
2904
  var DeletedVariableAlert = ({ onClose, onUnlink, onRestore, label }) => {
2049
- const sectionWidth = (0, import_editor_editing_panel6.useSectionWidth)();
2050
- return /* @__PURE__ */ React23.createElement(import_ui23.ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ React23.createElement(
2051
- import_ui23.Alert,
2905
+ return /* @__PURE__ */ React24.createElement(import_ui24.ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ React24.createElement(
2906
+ import_ui24.Alert,
2052
2907
  {
2053
2908
  variant: "standard",
2054
2909
  severity: "warning",
2055
2910
  onClose,
2056
- action: /* @__PURE__ */ React23.createElement(React23.Fragment, null, onUnlink && /* @__PURE__ */ React23.createElement(import_ui23.AlertAction, { variant: "contained", onClick: onUnlink }, (0, import_i18n16.__)("Unlink", "elementor")), onRestore && /* @__PURE__ */ React23.createElement(import_ui23.AlertAction, { variant: "outlined", onClick: onRestore }, (0, import_i18n16.__)("Restore", "elementor"))),
2057
- sx: { width: sectionWidth }
2911
+ action: /* @__PURE__ */ React24.createElement(React24.Fragment, null, onUnlink && /* @__PURE__ */ React24.createElement(import_ui24.AlertAction, { variant: "contained", onClick: onUnlink }, (0, import_i18n17.__)("Unlink", "elementor")), onRestore && /* @__PURE__ */ React24.createElement(import_ui24.AlertAction, { variant: "outlined", onClick: onRestore }, (0, import_i18n17.__)("Restore", "elementor"))),
2912
+ sx: { maxWidth: 300 }
2058
2913
  },
2059
- /* @__PURE__ */ React23.createElement(import_ui23.AlertTitle, null, (0, import_i18n16.__)("Deleted variable", "elementor")),
2060
- (0, import_i18n16.__)("The variable", "elementor"),
2061
- " '",
2062
- label,
2063
- "'",
2064
- " ",
2065
- (0, import_i18n16.__)(
2914
+ /* @__PURE__ */ React24.createElement(import_ui24.AlertTitle, null, (0, import_i18n17.__)("Deleted variable", "elementor")),
2915
+ /* @__PURE__ */ React24.createElement(import_ui24.Typography, { variant: "body2", color: "textPrimary" }, (0, import_i18n17.__)("The variable", "elementor"), "\xA0'", /* @__PURE__ */ React24.createElement(import_ui24.Typography, { variant: "body2", component: "span", sx: { lineBreak: "anywhere" } }, label), "'\xA0", (0, import_i18n17.__)(
2066
2916
  "has been deleted, but it is still referenced in this location. You may restore the variable or unlink it to assign a different value.",
2067
2917
  "elementor"
2068
- )
2918
+ ))
2069
2919
  ));
2070
2920
  };
2071
2921
 
2072
- // src/components/ui/tags/deleted-tag.tsx
2073
- var React24 = __toESM(require("react"));
2074
- var import_icons12 = require("@elementor/icons");
2075
- var import_ui24 = require("@elementor/ui");
2076
- var import_i18n17 = require("@wordpress/i18n");
2077
- var DeletedTag = React24.forwardRef(({ label, onClick, ...props }, ref) => {
2078
- return /* @__PURE__ */ React24.createElement(
2079
- import_ui24.Chip,
2080
- {
2081
- ref,
2082
- size: "tiny",
2083
- color: "warning",
2084
- shape: "rounded",
2085
- variant: "standard",
2086
- onClick,
2087
- icon: /* @__PURE__ */ React24.createElement(import_icons12.AlertTriangleFilledIcon, null),
2088
- label: /* @__PURE__ */ React24.createElement(import_ui24.Tooltip, { title: label, placement: "top" }, /* @__PURE__ */ React24.createElement(import_ui24.Box, { sx: { display: "flex", gap: 0.5, alignItems: "center" } }, /* @__PURE__ */ React24.createElement(import_ui24.Typography, { variant: "caption", noWrap: true }, label), /* @__PURE__ */ React24.createElement(import_ui24.Typography, { variant: "caption", noWrap: true, sx: { textOverflow: "initial", overflow: "visible" } }, "(", (0, import_i18n17.__)("deleted", "elementor"), ")"))),
2089
- sx: {
2090
- height: (theme) => theme.spacing(3.5),
2091
- borderRadius: (theme) => theme.spacing(1),
2092
- justifyContent: "flex-start",
2093
- width: "100%"
2094
- },
2095
- ...props
2096
- }
2097
- );
2098
- });
2922
+ // src/components/ui/tags/warning-variable-tag.tsx
2923
+ var React25 = __toESM(require("react"));
2924
+ var import_icons14 = require("@elementor/icons");
2925
+ var import_ui25 = require("@elementor/ui");
2926
+ var WarningVariableTag = React25.forwardRef(
2927
+ ({ label, suffix, onClick, icon, ...props }, ref) => {
2928
+ const displayText = suffix ? `${label} (${suffix})` : label;
2929
+ return /* @__PURE__ */ React25.createElement(
2930
+ import_ui25.Chip,
2931
+ {
2932
+ ref,
2933
+ size: "tiny",
2934
+ color: "warning",
2935
+ shape: "rounded",
2936
+ variant: "standard",
2937
+ onClick,
2938
+ icon: /* @__PURE__ */ React25.createElement(import_icons14.AlertTriangleFilledIcon, null),
2939
+ label: /* @__PURE__ */ React25.createElement(import_ui25.Tooltip, { title: displayText, placement: "top" }, /* @__PURE__ */ React25.createElement(import_ui25.Box, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React25.createElement(import_ui25.Typography, { variant: "caption", noWrap: true, sx: { lineHeight: 1.34 } }, displayText))),
2940
+ sx: {
2941
+ height: (theme) => theme.spacing(3.5),
2942
+ borderRadius: (theme) => theme.spacing(1),
2943
+ justifyContent: "flex-start",
2944
+ width: "100%"
2945
+ },
2946
+ ...props
2947
+ }
2948
+ );
2949
+ }
2950
+ );
2951
+ WarningVariableTag.displayName = "WarningVariableTag";
2099
2952
 
2100
2953
  // src/components/ui/variable/deleted-variable.tsx
2101
2954
  var DeletedVariable = ({ variable, propTypeKey }) => {
2102
2955
  const { propTypeUtil } = getVariableType(propTypeKey);
2103
- const { setValue } = (0, import_editor_controls8.useBoundProp)();
2956
+ const boundProp = (0, import_editor_controls8.useBoundProp)();
2104
2957
  const userPermissions = usePermissions();
2105
- const [showInfotip, setShowInfotip] = (0, import_react16.useState)(false);
2958
+ const [showInfotip, setShowInfotip] = (0, import_react20.useState)(false);
2106
2959
  const toggleInfotip = () => setShowInfotip((prev) => !prev);
2107
2960
  const closeInfotip = () => setShowInfotip(false);
2108
- const deletedChipAnchorRef = (0, import_react16.useRef)(null);
2109
- const popupId = (0, import_react16.useId)();
2110
- const popupState = (0, import_ui25.usePopupState)({
2961
+ const deletedChipAnchorRef = (0, import_react20.useRef)(null);
2962
+ const popupId = (0, import_react20.useId)();
2963
+ const popupState = (0, import_ui26.usePopupState)({
2111
2964
  variant: "popover",
2112
2965
  popupId: `elementor-variables-restore-${popupId}`
2113
2966
  });
2114
2967
  const handlers = {};
2115
2968
  if (userPermissions.canUnlink()) {
2116
- handlers.onUnlink = createUnlinkHandler(variable, propTypeKey, setValue);
2969
+ handlers.onUnlink = createUnlinkHandler(variable, propTypeKey, boundProp.setValue);
2117
2970
  }
2118
2971
  if (userPermissions.canRestore()) {
2119
2972
  handlers.onRestore = () => {
2120
2973
  if (!variable.key) {
2121
2974
  return;
2122
2975
  }
2123
- restoreVariable(variable.key).then((key) => {
2124
- setValue(propTypeUtil.create(key));
2976
+ restoreVariable(variable.key).then((id2) => {
2977
+ resolveBoundPropAndSetValue(propTypeUtil.create(id2), boundProp);
2125
2978
  closeInfotip();
2126
2979
  }).catch(() => {
2127
2980
  closeInfotip();
@@ -2133,15 +2986,15 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
2133
2986
  const handleRestoreWithOverrides = () => {
2134
2987
  popupState.close();
2135
2988
  };
2136
- return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(import_ui25.Box, { ref: deletedChipAnchorRef }, showInfotip && /* @__PURE__ */ React25.createElement(import_ui25.Backdrop, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React25.createElement(
2137
- import_ui25.Infotip,
2989
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(import_ui26.Box, { ref: deletedChipAnchorRef }, showInfotip && /* @__PURE__ */ React26.createElement(import_ui26.Backdrop, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React26.createElement(
2990
+ import_ui26.Infotip,
2138
2991
  {
2139
2992
  color: "warning",
2140
2993
  placement: "right-start",
2141
2994
  open: showInfotip,
2142
2995
  disableHoverListener: true,
2143
2996
  onClose: closeInfotip,
2144
- content: /* @__PURE__ */ React25.createElement(
2997
+ content: /* @__PURE__ */ React26.createElement(
2145
2998
  DeletedVariableAlert,
2146
2999
  {
2147
3000
  onClose: closeInfotip,
@@ -2161,9 +3014,16 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
2161
3014
  }
2162
3015
  }
2163
3016
  },
2164
- /* @__PURE__ */ React25.createElement(DeletedTag, { label: variable.label, onClick: toggleInfotip })
2165
- ), /* @__PURE__ */ React25.createElement(
2166
- import_ui25.Popover,
3017
+ /* @__PURE__ */ React26.createElement(
3018
+ WarningVariableTag,
3019
+ {
3020
+ label: variable.label,
3021
+ onClick: toggleInfotip,
3022
+ suffix: (0, import_i18n18.__)("deleted", "elementor")
3023
+ }
3024
+ )
3025
+ ), /* @__PURE__ */ React26.createElement(
3026
+ import_ui26.Popover,
2167
3027
  {
2168
3028
  disableScrollLock: true,
2169
3029
  anchorOrigin: { vertical: "bottom", horizontal: "right" },
@@ -2171,9 +3031,9 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
2171
3031
  PaperProps: {
2172
3032
  sx: { my: 1 }
2173
3033
  },
2174
- ...(0, import_ui25.bindPopover)(popupState)
3034
+ ...(0, import_ui26.bindPopover)(popupState)
2175
3035
  },
2176
- /* @__PURE__ */ React25.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ React25.createElement(
3036
+ /* @__PURE__ */ React26.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ React26.createElement(
2177
3037
  VariableRestore,
2178
3038
  {
2179
3039
  variableId: variable.key ?? "",
@@ -2186,83 +3046,51 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
2186
3046
 
2187
3047
  // src/components/ui/variable/mismatch-variable.tsx
2188
3048
  var React28 = __toESM(require("react"));
2189
- var import_react17 = require("react");
3049
+ var import_react21 = require("react");
2190
3050
  var import_editor_controls9 = require("@elementor/editor-controls");
2191
3051
  var import_ui28 = require("@elementor/ui");
3052
+ var import_i18n20 = require("@wordpress/i18n");
2192
3053
 
2193
3054
  // src/components/ui/mismatch-variable-alert.tsx
2194
- var React26 = __toESM(require("react"));
2195
- var import_editor_editing_panel7 = require("@elementor/editor-editing-panel");
2196
- var import_ui26 = require("@elementor/ui");
2197
- var import_i18n18 = require("@wordpress/i18n");
3055
+ var React27 = __toESM(require("react"));
3056
+ var import_ui27 = require("@elementor/ui");
3057
+ var import_i18n19 = require("@wordpress/i18n");
2198
3058
  var i18n = {
2199
- title: (0, import_i18n18.__)("Variable has changed", "elementor"),
2200
- message: (0, import_i18n18.__)(
3059
+ title: (0, import_i18n19.__)("Variable has changed", "elementor"),
3060
+ message: (0, import_i18n19.__)(
2201
3061
  `This variable is no longer compatible with this property. You can clear it or select a different one.`,
2202
3062
  "elementor"
2203
3063
  ),
2204
3064
  buttons: {
2205
- clear: (0, import_i18n18.__)("Clear", "elementor"),
2206
- select: (0, import_i18n18.__)("Select variable", "elementor")
3065
+ clear: (0, import_i18n19.__)("Clear", "elementor"),
3066
+ select: (0, import_i18n19.__)("Select variable", "elementor")
2207
3067
  }
2208
3068
  };
2209
3069
  var MismatchVariableAlert = ({ onClose, onClear, triggerSelect }) => {
2210
- const sectionWidth = (0, import_editor_editing_panel7.useSectionWidth)();
2211
- return /* @__PURE__ */ React26.createElement(import_ui26.ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ React26.createElement(
2212
- import_ui26.Alert,
3070
+ return /* @__PURE__ */ React27.createElement(import_ui27.ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ React27.createElement(
3071
+ import_ui27.Alert,
2213
3072
  {
2214
3073
  variant: "standard",
2215
3074
  severity: "warning",
2216
3075
  onClose,
2217
- action: /* @__PURE__ */ React26.createElement(React26.Fragment, null, onClear && /* @__PURE__ */ React26.createElement(import_ui26.AlertAction, { variant: "contained", onClick: onClear }, i18n.buttons.clear), triggerSelect && /* @__PURE__ */ React26.createElement(import_ui26.AlertAction, { variant: "outlined", onClick: triggerSelect }, i18n.buttons.select)),
2218
- sx: {
2219
- width: sectionWidth,
2220
- minWidth: 300
2221
- }
3076
+ action: /* @__PURE__ */ React27.createElement(React27.Fragment, null, onClear && /* @__PURE__ */ React27.createElement(import_ui27.AlertAction, { variant: "contained", onClick: onClear }, i18n.buttons.clear), triggerSelect && /* @__PURE__ */ React27.createElement(import_ui27.AlertAction, { variant: "outlined", onClick: triggerSelect }, i18n.buttons.select)),
3077
+ sx: { maxWidth: 300 }
2222
3078
  },
2223
- /* @__PURE__ */ React26.createElement(import_ui26.AlertTitle, null, i18n.title),
2224
- i18n.message
3079
+ /* @__PURE__ */ React27.createElement(import_ui27.AlertTitle, null, i18n.title),
3080
+ /* @__PURE__ */ React27.createElement(import_ui27.Typography, { variant: "body2", color: "textPrimary" }, i18n.message)
2225
3081
  ));
2226
3082
  };
2227
3083
 
2228
- // src/components/ui/tags/mismatch-tag.tsx
2229
- var React27 = __toESM(require("react"));
2230
- var import_icons13 = require("@elementor/icons");
2231
- var import_ui27 = require("@elementor/ui");
2232
- var import_i18n19 = require("@wordpress/i18n");
2233
- var MismatchTag = React27.forwardRef(({ label, onClick, ...props }, ref) => {
2234
- return /* @__PURE__ */ React27.createElement(
2235
- import_ui27.Chip,
2236
- {
2237
- ref,
2238
- size: "tiny",
2239
- color: "warning",
2240
- shape: "rounded",
2241
- variant: "standard",
2242
- onClick,
2243
- icon: /* @__PURE__ */ React27.createElement(import_icons13.AlertTriangleFilledIcon, null),
2244
- label: /* @__PURE__ */ React27.createElement(import_ui27.Tooltip, { title: label, placement: "top" }, /* @__PURE__ */ React27.createElement(import_ui27.Box, { sx: { display: "flex", gap: 0.5, alignItems: "center" } }, /* @__PURE__ */ React27.createElement(import_ui27.Typography, { variant: "caption", noWrap: true }, label), /* @__PURE__ */ React27.createElement(import_ui27.Typography, { variant: "caption", noWrap: true, sx: { textOverflow: "initial", overflow: "visible" } }, "(", (0, import_i18n19.__)("changed", "elementor"), ")"))),
2245
- sx: {
2246
- height: (theme) => theme.spacing(3.5),
2247
- borderRadius: (theme) => theme.spacing(1),
2248
- justifyContent: "flex-start",
2249
- width: "100%"
2250
- },
2251
- ...props
2252
- }
2253
- );
2254
- });
2255
-
2256
3084
  // src/components/ui/variable/mismatch-variable.tsx
2257
3085
  var MismatchVariable = ({ variable }) => {
2258
- const { setValue } = (0, import_editor_controls9.useBoundProp)();
2259
- const anchorRef = (0, import_react17.useRef)(null);
2260
- const popupId = (0, import_react17.useId)();
3086
+ const { setValue, value } = (0, import_editor_controls9.useBoundProp)();
3087
+ const anchorRef = (0, import_react21.useRef)(null);
3088
+ const popupId = (0, import_react21.useId)();
2261
3089
  const popupState = (0, import_ui28.usePopupState)({
2262
3090
  variant: "popover",
2263
3091
  popupId: `elementor-variables-list-${popupId}`
2264
3092
  });
2265
- const [infotipVisible, setInfotipVisible] = (0, import_react17.useState)(false);
3093
+ const [infotipVisible, setInfotipVisible] = (0, import_react21.useState)(false);
2266
3094
  const toggleInfotip = () => setInfotipVisible((prev) => !prev);
2267
3095
  const closeInfotip = () => setInfotipVisible(false);
2268
3096
  const triggerSelect = () => {
@@ -2274,6 +3102,7 @@ var MismatchVariable = ({ variable }) => {
2274
3102
  closeInfotip();
2275
3103
  setValue(null);
2276
3104
  };
3105
+ const showClearButton = !!value;
2277
3106
  return /* @__PURE__ */ React28.createElement(import_ui28.Box, { ref: anchorRef }, infotipVisible && /* @__PURE__ */ React28.createElement(import_ui28.Backdrop, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React28.createElement(
2278
3107
  import_ui28.Infotip,
2279
3108
  {
@@ -2286,7 +3115,7 @@ var MismatchVariable = ({ variable }) => {
2286
3115
  MismatchVariableAlert,
2287
3116
  {
2288
3117
  onClose: closeInfotip,
2289
- onClear: clearValue,
3118
+ onClear: showClearButton ? clearValue : void 0,
2290
3119
  triggerSelect
2291
3120
  }
2292
3121
  ),
@@ -2301,7 +3130,14 @@ var MismatchVariable = ({ variable }) => {
2301
3130
  }
2302
3131
  }
2303
3132
  },
2304
- /* @__PURE__ */ React28.createElement(MismatchTag, { label: variable.label, onClick: toggleInfotip })
3133
+ /* @__PURE__ */ React28.createElement(
3134
+ WarningVariableTag,
3135
+ {
3136
+ label: variable.label,
3137
+ onClick: toggleInfotip,
3138
+ suffix: (0, import_i18n20.__)("changed", "elementor")
3139
+ }
3140
+ )
2305
3141
  ), /* @__PURE__ */ React28.createElement(
2306
3142
  import_ui28.Popover,
2307
3143
  {
@@ -2326,79 +3162,50 @@ var MismatchVariable = ({ variable }) => {
2326
3162
  };
2327
3163
 
2328
3164
  // src/components/ui/variable/missing-variable.tsx
2329
- var React31 = __toESM(require("react"));
2330
- var import_react18 = require("react");
3165
+ var React30 = __toESM(require("react"));
3166
+ var import_react22 = require("react");
2331
3167
  var import_editor_controls10 = require("@elementor/editor-controls");
2332
- var import_ui31 = require("@elementor/ui");
2333
- var import_i18n21 = require("@wordpress/i18n");
3168
+ var import_ui30 = require("@elementor/ui");
3169
+ var import_i18n22 = require("@wordpress/i18n");
2334
3170
 
2335
3171
  // src/components/ui/missing-variable-alert.tsx
2336
3172
  var React29 = __toESM(require("react"));
2337
- var import_editor_editing_panel8 = require("@elementor/editor-editing-panel");
2338
3173
  var import_ui29 = require("@elementor/ui");
2339
- var import_i18n20 = require("@wordpress/i18n");
3174
+ var import_i18n21 = require("@wordpress/i18n");
2340
3175
  var MissingVariableAlert = ({ onClose, onClear }) => {
2341
- const sectionWidth = (0, import_editor_editing_panel8.useSectionWidth)();
2342
3176
  return /* @__PURE__ */ React29.createElement(import_ui29.ClickAwayListener, { onClickAway: onClose }, /* @__PURE__ */ React29.createElement(
2343
3177
  import_ui29.Alert,
2344
3178
  {
2345
3179
  variant: "standard",
2346
3180
  severity: "warning",
2347
3181
  onClose,
2348
- action: /* @__PURE__ */ React29.createElement(React29.Fragment, null, onClear && /* @__PURE__ */ React29.createElement(import_ui29.AlertAction, { variant: "contained", onClick: onClear }, (0, import_i18n20.__)("Clear", "elementor"))),
2349
- sx: { width: sectionWidth }
3182
+ action: /* @__PURE__ */ React29.createElement(React29.Fragment, null, onClear && /* @__PURE__ */ React29.createElement(import_ui29.AlertAction, { variant: "contained", onClick: onClear }, (0, import_i18n21.__)("Clear", "elementor"))),
3183
+ sx: { maxWidth: 300 }
2350
3184
  },
2351
- /* @__PURE__ */ React29.createElement(import_ui29.AlertTitle, null, (0, import_i18n20.__)("This variable is missing", "elementor")),
2352
- (0, import_i18n20.__)(
3185
+ /* @__PURE__ */ React29.createElement(import_ui29.AlertTitle, null, (0, import_i18n21.__)("This variable is missing", "elementor")),
3186
+ /* @__PURE__ */ React29.createElement(import_ui29.Typography, { variant: "body2", color: "textPrimary" }, (0, import_i18n21.__)(
2353
3187
  "It may have been deleted. Try clearing this field and select a different value or variable.",
2354
3188
  "elementor"
2355
- )
3189
+ ))
2356
3190
  ));
2357
3191
  };
2358
3192
 
2359
- // src/components/ui/tags/missing-tag.tsx
2360
- var React30 = __toESM(require("react"));
2361
- var import_icons14 = require("@elementor/icons");
2362
- var import_ui30 = require("@elementor/ui");
2363
- var MissingTag = React30.forwardRef(({ label, onClick, ...props }, ref) => {
2364
- return /* @__PURE__ */ React30.createElement(
2365
- import_ui30.Chip,
2366
- {
2367
- ref,
2368
- size: "tiny",
2369
- color: "warning",
2370
- shape: "rounded",
2371
- variant: "standard",
2372
- onClick,
2373
- icon: /* @__PURE__ */ React30.createElement(import_icons14.AlertTriangleFilledIcon, null),
2374
- label,
2375
- sx: {
2376
- height: (theme) => theme.spacing(3.5),
2377
- borderRadius: (theme) => theme.spacing(1),
2378
- justifyContent: "flex-start",
2379
- width: "100%"
2380
- },
2381
- ...props
2382
- }
2383
- );
2384
- });
2385
-
2386
3193
  // src/components/ui/variable/missing-variable.tsx
2387
3194
  var MissingVariable = () => {
2388
3195
  const { setValue } = (0, import_editor_controls10.useBoundProp)();
2389
- const [infotipVisible, setInfotipVisible] = (0, import_react18.useState)(false);
3196
+ const [infotipVisible, setInfotipVisible] = (0, import_react22.useState)(false);
2390
3197
  const toggleInfotip = () => setInfotipVisible((prev) => !prev);
2391
3198
  const closeInfotip = () => setInfotipVisible(false);
2392
3199
  const clearValue = () => setValue(null);
2393
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, infotipVisible && /* @__PURE__ */ React31.createElement(import_ui31.Backdrop, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React31.createElement(
2394
- import_ui31.Infotip,
3200
+ return /* @__PURE__ */ React30.createElement(React30.Fragment, null, infotipVisible && /* @__PURE__ */ React30.createElement(import_ui30.Backdrop, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React30.createElement(
3201
+ import_ui30.Infotip,
2395
3202
  {
2396
3203
  color: "warning",
2397
3204
  placement: "right-start",
2398
3205
  open: infotipVisible,
2399
3206
  disableHoverListener: true,
2400
3207
  onClose: closeInfotip,
2401
- content: /* @__PURE__ */ React31.createElement(MissingVariableAlert, { onClose: closeInfotip, onClear: clearValue }),
3208
+ content: /* @__PURE__ */ React30.createElement(MissingVariableAlert, { onClose: closeInfotip, onClear: clearValue }),
2402
3209
  slotProps: {
2403
3210
  popper: {
2404
3211
  modifiers: [
@@ -2410,47 +3217,47 @@ var MissingVariable = () => {
2410
3217
  }
2411
3218
  }
2412
3219
  },
2413
- /* @__PURE__ */ React31.createElement(MissingTag, { label: (0, import_i18n21.__)("Missing variable", "elementor"), onClick: toggleInfotip })
3220
+ /* @__PURE__ */ React30.createElement(WarningVariableTag, { label: (0, import_i18n22.__)("Missing variable", "elementor"), onClick: toggleInfotip })
2414
3221
  ));
2415
3222
  };
2416
3223
 
2417
3224
  // src/controls/variable-control.tsx
2418
3225
  var VariableControl = () => {
2419
3226
  const boundProp = (0, import_editor_controls11.useBoundProp)();
2420
- const boundPropValue = boundProp.value;
3227
+ const boundPropValue = boundProp.value ?? boundProp.placeholder;
2421
3228
  const assignedVariable = useVariable(boundPropValue?.value);
2422
3229
  if (!assignedVariable) {
2423
- return /* @__PURE__ */ React32.createElement(MissingVariable, null);
3230
+ return /* @__PURE__ */ React31.createElement(MissingVariable, null);
2424
3231
  }
2425
3232
  const { $$type: propTypeKey } = boundPropValue;
2426
3233
  if (assignedVariable?.deleted) {
2427
- return /* @__PURE__ */ React32.createElement(DeletedVariable, { variable: assignedVariable, propTypeKey });
3234
+ return /* @__PURE__ */ React31.createElement(DeletedVariable, { variable: assignedVariable, propTypeKey });
2428
3235
  }
2429
3236
  const { isCompatible } = getVariableType(assignedVariable.type);
2430
3237
  if (isCompatible && !isCompatible(boundProp?.propType, assignedVariable)) {
2431
- return /* @__PURE__ */ React32.createElement(MismatchVariable, { variable: assignedVariable });
3238
+ return /* @__PURE__ */ React31.createElement(MismatchVariable, { variable: assignedVariable });
2432
3239
  }
2433
- return /* @__PURE__ */ React32.createElement(AssignedVariable, { variable: assignedVariable, propTypeKey });
3240
+ return /* @__PURE__ */ React31.createElement(AssignedVariable, { variable: assignedVariable, propTypeKey });
2434
3241
  };
2435
3242
 
2436
3243
  // src/hooks/use-prop-variable-action.tsx
2437
- var React33 = __toESM(require("react"));
2438
- var import_editor_editing_panel9 = require("@elementor/editor-editing-panel");
3244
+ var React32 = __toESM(require("react"));
3245
+ var import_editor_editing_panel6 = require("@elementor/editor-editing-panel");
2439
3246
  var import_icons15 = require("@elementor/icons");
2440
- var import_i18n22 = require("@wordpress/i18n");
3247
+ var import_i18n23 = require("@wordpress/i18n");
2441
3248
  var usePropVariableAction = () => {
2442
- const { propType, path } = (0, import_editor_editing_panel9.useBoundProp)();
3249
+ const { propType, path } = (0, import_editor_editing_panel6.useBoundProp)();
2443
3250
  const variable = resolveVariableFromPropType(propType);
2444
3251
  return {
2445
3252
  visible: Boolean(variable),
2446
3253
  icon: import_icons15.ColorFilterIcon,
2447
- title: (0, import_i18n22.__)("Variables", "elementor"),
3254
+ title: (0, import_i18n23.__)("Variables", "elementor"),
2448
3255
  content: ({ close: closePopover }) => {
2449
3256
  if (!variable) {
2450
3257
  return null;
2451
3258
  }
2452
3259
  trackOpenVariablePopover(path, variable.variableType);
2453
- return /* @__PURE__ */ React33.createElement(VariableSelectionPopover, { closePopover, propTypeKey: variable.propTypeUtil.key });
3260
+ return /* @__PURE__ */ React32.createElement(VariableSelectionPopover, { closePopover, propTypeKey: variable.propTypeUtil.key });
2454
3261
  }
2455
3262
  };
2456
3263
  };
@@ -2474,19 +3281,297 @@ var trackOpenVariablePopover = (path, variableType) => {
2474
3281
  });
2475
3282
  };
2476
3283
 
3284
+ // src/mcp/index.ts
3285
+ var import_editor_mcp6 = require("@elementor/editor-mcp");
3286
+
3287
+ // src/mcp/create-variable-tool.ts
3288
+ var import_editor_mcp = require("@elementor/editor-mcp");
3289
+ var import_schema3 = require("@elementor/schema");
3290
+ var InputSchema = {
3291
+ type: import_schema3.z.string().describe('The type of the variable. Example values: "global-color-variable" or "global-font-variable".'),
3292
+ label: import_schema3.z.string().describe("The label of the variable, displayed to the user"),
3293
+ value: import_schema3.z.string().describe("The value of the variable, should correspond to the type")
3294
+ };
3295
+ var OutputSchema = {
3296
+ status: import_schema3.z.enum(["ok", "error"]).describe("The status of the operation"),
3297
+ message: import_schema3.z.string().optional().describe("Optional message providing additional information about the operation")
3298
+ };
3299
+ var initCreateVariableTool = () => {
3300
+ (0, import_editor_mcp.getMCPByDomain)("variables").addTool({
3301
+ name: "create-global-variable",
3302
+ schema: InputSchema,
3303
+ outputSchema: OutputSchema,
3304
+ description: `Create a new global variable
3305
+ ## When to use this tool:
3306
+ - When a user requests to create a new global variable in the Elementor editor.
3307
+ - When you need to add a new variable to be used in the editor.
3308
+
3309
+ ## Prequisites:
3310
+ - Ensure you have the most up-to-date list of existing global variables to avoid label duplication. You can use the "list-global-variables" tool to fetch the current variables.
3311
+ - Make sure when creating a new variable, the label is unique and not already in use.
3312
+ - If the user does not provide a label, ask them to provide one before proceeding.
3313
+ - If the user does not provide a type, ask them to provide one before proceeding.
3314
+ - If the user does not provide a value, ask them to provide one before proceeding.
3315
+
3316
+ ## Required parameters:
3317
+ - type: The type of the variable. Possible values are 'global-color-variable' or 'global-font-variable'.
3318
+ - label: The label of the variable, displayed to the user. Must be unique and not already in use.
3319
+ - value: The value of the variable. For color variables, this should be a valid CSS color (e.g., 'rgb(255,0,0)', '#ff0000', 'red'). For font variables, this should be a valid font family (e.g., 'Arial', 'serif').
3320
+
3321
+ ## Example tool call (JSON format):
3322
+ \`\`\`json
3323
+ { "type": "global-color-variable", "label": "My Cool Color", "value": "rgb(1,2,3)" }
3324
+ \`\`\`
3325
+
3326
+ ## Example tool response (JSON format):
3327
+ \`\`\`json
3328
+ { "status": "ok" }
3329
+ \`\`\`
3330
+
3331
+ ## Example to a failed tool response, which must be displayed to the end user. If the error message is not plain, attempt to find the most useful part of the message and display it.
3332
+ { "status": "error", "message": "Unsupported type 'global-kuku-variable'" }
3333
+
3334
+ In that case, inform the user the type is unsupported and they should try another type, perhaps consult to online documentation.
3335
+ `,
3336
+ handler: async (params) => {
3337
+ const { type, label, value } = params;
3338
+ try {
3339
+ await service.create({ type, label, value });
3340
+ } catch (error) {
3341
+ const message = error.message || "Unknown server error";
3342
+ return {
3343
+ status: "error",
3344
+ message: `There was an error creating the variable: ${message}`
3345
+ };
3346
+ }
3347
+ return { status: "ok" };
3348
+ }
3349
+ });
3350
+ };
3351
+
3352
+ // src/mcp/delete-variable-tool.ts
3353
+ var import_editor_mcp2 = require("@elementor/editor-mcp");
3354
+ var import_schema4 = require("@elementor/schema");
3355
+ var initDeleteVariableTool = () => {
3356
+ (0, import_editor_mcp2.getMCPByDomain)("variables").addTool({
3357
+ name: "delete-global-variable",
3358
+ schema: {
3359
+ id: import_schema4.z.string().describe("The unique identifier of the variable to be deleted.")
3360
+ },
3361
+ outputSchema: {
3362
+ status: import_schema4.z.enum(["ok", "error"]).describe("The status of the operation")
3363
+ },
3364
+ description: `Delete an existing global variable
3365
+
3366
+ ## When to use this tool:
3367
+ - When a user requests to delete an existing global variable in the Elementor editor.
3368
+ - When you need to remove a variable that is no longer needed or relevant, with the user's confirmation.
3369
+
3370
+ ## Prerequisites:
3371
+ - Ensure you have the most up-to-date list of existing global variables. You can use the "list-global-variables" tool to fetch the current variables.
3372
+ - Reference the variable by the "id" property, given from the "list-global-variables" tool.
3373
+ - Make sure you have the unique identifier of the variable to be deleted before using this tool.
3374
+ - Confirm with the user that they want to proceed with the deletion, as this action is irreversible.
3375
+
3376
+ <notice>
3377
+ A use might reference a variable by it's label, but you must always use the unique identifier (id) to delete it.
3378
+ If you only have the label, use the "list-global-variables" tool to find the corresponding id.
3379
+ </notice>
3380
+
3381
+ <important>
3382
+ This operation is destructive and cannot be undone. Ensure that the user is fully aware of the consequences before proceeding.
3383
+ When a variable is deleted, all references to it in all pages accross the website will lose their effect.
3384
+ </important>`,
3385
+ handler: async (params) => {
3386
+ const { id: id2 } = params;
3387
+ try {
3388
+ await service.delete(id2);
3389
+ return { status: "ok" };
3390
+ } catch (err) {
3391
+ return {
3392
+ status: "error"
3393
+ };
3394
+ }
3395
+ },
3396
+ isDestrcutive: true
3397
+ });
3398
+ };
3399
+
3400
+ // src/mcp/list-variables-tool.ts
3401
+ var import_editor_mcp3 = require("@elementor/editor-mcp");
3402
+ var import_schema5 = require("@elementor/schema");
3403
+ var VariableSchema = {
3404
+ type: import_schema5.z.string().describe("The type of the variable."),
3405
+ label: import_schema5.z.string().describe("The label of the variable, displayed to the user"),
3406
+ value: import_schema5.z.string().describe("The value of the variable."),
3407
+ id: import_schema5.z.string().describe(
3408
+ "The unique identifier of the variable. Used for internal reference, not to be exposed to end users"
3409
+ )
3410
+ };
3411
+ var VariableListSchema = {
3412
+ variables: import_schema5.z.array(import_schema5.z.object(VariableSchema)).describe("List of variables")
3413
+ };
3414
+ var initListVariablesTool = () => {
3415
+ (0, import_editor_mcp3.getMCPByDomain)("variables").addTool({
3416
+ name: "list-global-variables",
3417
+ description: `List editor global variables
3418
+
3419
+ ## When to use this tool:
3420
+ - When a user requests to see all available global variables in the Elementor editor.
3421
+ - When you need to be exact on a variable label, to avoid any mistakes.
3422
+ - When you want to see the most up-to-date list of global variables.
3423
+ - Before using any other variables related tools that makes changes, such as deletion, creation, or updates. This ensures you have the latest information and there is no naming collision or mismatching.
3424
+
3425
+ ## Example tool response (JSON format):
3426
+ \`\`\`json
3427
+ { variables: [
3428
+ { type: 'global-color-variable', label: 'Cool', value: 'rgb(1,2,3)', id: 'some-unique-id' },
3429
+ { type: 'global-font-variable', label: 'Headline', value: 'serif', id: 'some-other-unique-id' },
3430
+ ] }
3431
+ \`\`\`
3432
+
3433
+ Once you get the response, please display the variables in a user-friendly way, unless explicitly requested otherwise.
3434
+ Unless explicitly requested otherwise, response in HTML Format, prefer to use tables or unordered lists.
3435
+
3436
+ Note: **The label is most improtant to be seen as-is without any changes.**
3437
+
3438
+ <important>
3439
+ **Do not omit the label**. This is important for the user to identify the variable.
3440
+ **Do not change the label**, it must be displayed exactly as it is, in it's original characters as received from this tool.
3441
+ </important>
3442
+ `,
3443
+ outputSchema: VariableListSchema,
3444
+ handler: async () => {
3445
+ const variables = service.variables();
3446
+ return {
3447
+ variables: Object.entries(variables).map(([id2, varData]) => ({ id: id2, ...varData }))
3448
+ };
3449
+ }
3450
+ });
3451
+ };
3452
+
3453
+ // src/mcp/update-variable-tool.ts
3454
+ var import_editor_mcp4 = require("@elementor/editor-mcp");
3455
+ var import_schema6 = require("@elementor/schema");
3456
+ var initUpdateVariableTool = () => {
3457
+ (0, import_editor_mcp4.getMCPByDomain)("variables").addTool({
3458
+ schema: {
3459
+ id: import_schema6.z.string().describe("The unique identifier of the variable to be updated or renamed."),
3460
+ label: import_schema6.z.string().describe(
3461
+ "The label of the variable to be stored after the change. If the user only wishes to update the value, this must be strictly equal to the current label."
3462
+ ),
3463
+ value: import_schema6.z.string().describe(
3464
+ "The new value for the variable. For color variables, this should be a valid CSS color (e.g., 'rgb(255,0,0)', '#ff0000', 'red'). For font variables, this should be a valid font family (e.g., 'Arial', 'serif'). If the user wishes to rename only, make sure you provide the existing value."
3465
+ )
3466
+ },
3467
+ outputSchema: {
3468
+ status: import_schema6.z.enum(["ok", "error"]).describe("The status of the operation"),
3469
+ message: import_schema6.z.string().optional().describe("Optional message providing additional information about the operation")
3470
+ },
3471
+ name: "update-global-variable",
3472
+ description: `Update an existing global variable
3473
+
3474
+ ## When to use this tool:
3475
+ - When a user requests to update an existing global variable in the Elementor editor.
3476
+ - When you need to modify the value of an existing variable.
3477
+ - When you want to rename an existing variable (change its label).
3478
+ - When you want to both rename and modify the value of an existing variable.
3479
+
3480
+ ## Prerequisites:
3481
+ - Ensure you have the most up-to-date list of existing global variables to avoid label duplication. You can use the "list-global-variables" tool to fetch the current variables.
3482
+ - Make sure when updating a variable, the new label is unique and not already in use by another variable.
3483
+ - Make sure you understand whether you are updating a value, renaming, or both.
3484
+ - Reference the variable by the "id" property, given from the "list-global-variables" tool.
3485
+ - If the user wishes to rename, make sure you have the existing value.
3486
+ - If the user wishes to update the value, make sure you have to **correct label**.
3487
+ - You must have the unique identifier, the current label, the current value, and the new value or label or both, before using this tool.
3488
+
3489
+ ## Required parameters:
3490
+ - id: The unique identifier of the variable to be updated or renamed.
3491
+ - label: The label of the variable to be stored after the change. If the user only wishes to update the value, this must be strictly equal to the current label.
3492
+ - value: The new value for the variable. For color variables, this should be a valid CSS color (e.g., 'rgb(255,0,0)', '#ff0000', 'red'). For font variables, this should be a valid font family (e.g., 'Arial', 'serif'). If the user wishes to rename only, make sure you provide the existing value.
3493
+
3494
+ ## Example tool call (JSON format):
3495
+ \`\`\`json
3496
+ { "id": "some-unique-id", "label": "Cool", "value": "rgb(0,140,250)" }
3497
+ \`\`\`
3498
+
3499
+ ## Example responses (JSON format):
3500
+ Successful update:
3501
+ \`\`\`json
3502
+ { "status": "ok" }
3503
+ \`\`\`
3504
+
3505
+ Failed update, which must be displayed to the end user. If the error message is not plain, attempt to find the most useful part of the message and display it.
3506
+ \`\`\`json
3507
+ { "status": "error", "message": "Label 'Cool' is already in use by another variable." }
3508
+ \`\`\`
3509
+ `,
3510
+ handler: async (params) => {
3511
+ const { id: id2, label, value } = params;
3512
+ try {
3513
+ await service.update(id2, { label, value });
3514
+ return { status: "ok" };
3515
+ } catch (error) {
3516
+ const message = error.message || "Unknown server error";
3517
+ return {
3518
+ status: "error",
3519
+ message: `There was an error creating the variable: ${message}`
3520
+ };
3521
+ }
3522
+ }
3523
+ });
3524
+ };
3525
+
3526
+ // src/mcp/variables-resource.ts
3527
+ var import_editor_mcp5 = require("@elementor/editor-mcp");
3528
+ var GLOBAL_VARIABLES_URI = "elementor://variables";
3529
+ var initVariablesResource = () => {
3530
+ const { mcpServer } = (0, import_editor_mcp5.getMCPByDomain)("variables");
3531
+ mcpServer.resource(
3532
+ "global-variables",
3533
+ GLOBAL_VARIABLES_URI,
3534
+ {
3535
+ description: "Global variables list. Variables are being used in this way: If it is directly in the schema, you need to put the ID which is the key inside the object."
3536
+ },
3537
+ async () => {
3538
+ return {
3539
+ contents: [{ uri: GLOBAL_VARIABLES_URI, text: localStorage["elementor-global-variables"] }]
3540
+ };
3541
+ }
3542
+ );
3543
+ window.addEventListener("variables:updated", () => {
3544
+ mcpServer.server.sendResourceUpdated({
3545
+ uri: GLOBAL_VARIABLES_URI,
3546
+ contents: [{ uri: GLOBAL_VARIABLES_URI, text: localStorage["elementor-global-variables"] }]
3547
+ });
3548
+ });
3549
+ };
3550
+
3551
+ // src/mcp/index.ts
3552
+ function initMcp() {
3553
+ const { setMCPDescription } = (0, import_editor_mcp6.getMCPByDomain)("variables");
3554
+ setMCPDescription(`Elementor Editor Variables MCP`);
3555
+ initListVariablesTool();
3556
+ initCreateVariableTool();
3557
+ initUpdateVariableTool();
3558
+ initDeleteVariableTool();
3559
+ initVariablesResource();
3560
+ }
3561
+
2477
3562
  // src/register-variable-types.tsx
2478
- var React36 = __toESM(require("react"));
2479
- var import_editor_props3 = require("@elementor/editor-props");
3563
+ var React35 = __toESM(require("react"));
3564
+ var import_editor_props4 = require("@elementor/editor-props");
2480
3565
  var import_icons17 = require("@elementor/icons");
2481
3566
 
2482
3567
  // src/components/fields/color-field.tsx
2483
- var React34 = __toESM(require("react"));
2484
- var import_react19 = require("react");
2485
- var import_ui32 = require("@elementor/ui");
3568
+ var React33 = __toESM(require("react"));
3569
+ var import_react23 = require("react");
3570
+ var import_ui31 = require("@elementor/ui");
2486
3571
  var ColorField = ({ value, onChange, onValidationChange }) => {
2487
- const [color, setColor] = (0, import_react19.useState)(value);
2488
- const [errorMessage, setErrorMessage] = (0, import_react19.useState)("");
2489
- const defaultRef = (0, import_react19.useRef)(null);
3572
+ const [color, setColor] = (0, import_react23.useState)(value);
3573
+ const [errorMessage, setErrorMessage] = (0, import_react23.useState)("");
3574
+ const defaultRef = (0, import_react23.useRef)(null);
2490
3575
  const anchorRef = usePopoverContentRef() ?? defaultRef.current;
2491
3576
  const handleChange = (newValue) => {
2492
3577
  setColor(newValue);
@@ -2495,9 +3580,10 @@ var ColorField = ({ value, onChange, onValidationChange }) => {
2495
3580
  onValidationChange?.(errorMsg);
2496
3581
  onChange(errorMsg ? "" : newValue);
2497
3582
  };
2498
- return /* @__PURE__ */ React34.createElement(
2499
- import_ui32.UnstableColorField,
3583
+ return /* @__PURE__ */ React33.createElement(
3584
+ import_ui31.UnstableColorField,
2500
3585
  {
3586
+ id: "color-variable-field",
2501
3587
  size: "tiny",
2502
3588
  fullWidth: true,
2503
3589
  value: color,
@@ -2523,21 +3609,21 @@ var ColorField = ({ value, onChange, onValidationChange }) => {
2523
3609
  };
2524
3610
 
2525
3611
  // src/components/fields/font-field.tsx
2526
- var React35 = __toESM(require("react"));
2527
- var import_react20 = require("react");
3612
+ var React34 = __toESM(require("react"));
3613
+ var import_react24 = require("react");
2528
3614
  var import_editor_controls12 = require("@elementor/editor-controls");
2529
- var import_editor_editing_panel10 = require("@elementor/editor-editing-panel");
3615
+ var import_editor_editing_panel7 = require("@elementor/editor-editing-panel");
2530
3616
  var import_icons16 = require("@elementor/icons");
2531
- var import_ui33 = require("@elementor/ui");
2532
- var import_i18n23 = require("@wordpress/i18n");
3617
+ var import_ui32 = require("@elementor/ui");
3618
+ var import_i18n24 = require("@wordpress/i18n");
2533
3619
  var FontField = ({ value, onChange, onValidationChange }) => {
2534
- const [fontFamily, setFontFamily] = (0, import_react20.useState)(value);
2535
- const defaultRef = (0, import_react20.useRef)(null);
3620
+ const [fontFamily, setFontFamily] = (0, import_react24.useState)(value);
3621
+ const defaultRef = (0, import_react24.useRef)(null);
2536
3622
  const anchorRef = usePopoverContentRef() ?? defaultRef.current;
2537
- const fontPopoverState = (0, import_ui33.usePopupState)({ variant: "popover" });
2538
- const fontFamilies = (0, import_editor_editing_panel10.useFontFamilies)();
2539
- const sectionWidth = (0, import_editor_editing_panel10.useSectionWidth)();
2540
- const mapFontSubs = React35.useMemo(() => {
3623
+ const fontPopoverState = (0, import_ui32.usePopupState)({ variant: "popover" });
3624
+ const fontFamilies = (0, import_editor_editing_panel7.useFontFamilies)();
3625
+ const sectionWidth = (0, import_editor_editing_panel7.useSectionWidth)();
3626
+ const mapFontSubs = React34.useMemo(() => {
2541
3627
  return fontFamilies.map(({ label, fonts }) => ({
2542
3628
  label,
2543
3629
  items: fonts
@@ -2553,36 +3639,37 @@ var FontField = ({ value, onChange, onValidationChange }) => {
2553
3639
  handleChange(newFontFamily);
2554
3640
  fontPopoverState.close();
2555
3641
  };
2556
- const id2 = (0, import_react20.useId)();
2557
- return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(
2558
- import_ui33.UnstableTag,
3642
+ const id2 = (0, import_react24.useId)();
3643
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(
3644
+ import_ui32.UnstableTag,
2559
3645
  {
2560
3646
  id: id2,
2561
3647
  variant: "outlined",
2562
3648
  label: fontFamily,
2563
- endIcon: /* @__PURE__ */ React35.createElement(import_icons16.ChevronDownIcon, { fontSize: "tiny" }),
2564
- ...(0, import_ui33.bindTrigger)(fontPopoverState),
3649
+ endIcon: /* @__PURE__ */ React34.createElement(import_icons16.ChevronDownIcon, { fontSize: "tiny" }),
3650
+ ...(0, import_ui32.bindTrigger)(fontPopoverState),
2565
3651
  fullWidth: true
2566
3652
  }
2567
- ), /* @__PURE__ */ React35.createElement(
2568
- import_ui33.Popover,
3653
+ ), /* @__PURE__ */ React34.createElement(
3654
+ import_ui32.Popover,
2569
3655
  {
2570
3656
  disablePortal: true,
2571
3657
  disableScrollLock: true,
2572
3658
  anchorEl: anchorRef,
2573
3659
  anchorOrigin: { vertical: "top", horizontal: "right" },
2574
3660
  transformOrigin: { vertical: "top", horizontal: -28 },
2575
- ...(0, import_ui33.bindPopover)(fontPopoverState)
3661
+ ...(0, import_ui32.bindPopover)(fontPopoverState)
2576
3662
  },
2577
- /* @__PURE__ */ React35.createElement(
3663
+ /* @__PURE__ */ React34.createElement(
2578
3664
  import_editor_controls12.ItemSelector,
2579
3665
  {
3666
+ id: "font-family-variables-selector",
2580
3667
  itemsList: mapFontSubs,
2581
3668
  selectedItem: fontFamily,
2582
3669
  onItemChange: handleFontFamilyChange,
2583
3670
  onClose: fontPopoverState.close,
2584
3671
  sectionWidth,
2585
- title: (0, import_i18n23.__)("Font Family", "elementor"),
3672
+ title: (0, import_i18n24.__)("Font family", "elementor"),
2586
3673
  itemStyle: (item) => ({ fontFamily: item.value }),
2587
3674
  onDebounce: import_editor_controls12.enqueueFont,
2588
3675
  icon: import_icons16.TextIcon
@@ -2594,27 +3681,31 @@ var FontField = ({ value, onChange, onValidationChange }) => {
2594
3681
  // src/register-variable-types.tsx
2595
3682
  function registerVariableTypes() {
2596
3683
  registerVariableType({
3684
+ key: colorVariablePropTypeUtil.key,
2597
3685
  valueField: ColorField,
2598
3686
  icon: import_icons17.BrushIcon,
2599
3687
  propTypeUtil: colorVariablePropTypeUtil,
2600
- fallbackPropTypeUtil: import_editor_props3.colorPropTypeUtil,
3688
+ fallbackPropTypeUtil: import_editor_props4.colorPropTypeUtil,
2601
3689
  variableType: "color",
2602
- startIcon: ({ value }) => /* @__PURE__ */ React36.createElement(ColorIndicator, { size: "inherit", component: "span", value })
3690
+ startIcon: ({ value }) => /* @__PURE__ */ React35.createElement(ColorIndicator, { size: "inherit", component: "span", value }),
3691
+ defaultValue: "#ffffff"
2603
3692
  });
2604
3693
  registerVariableType({
3694
+ key: fontVariablePropTypeUtil.key,
2605
3695
  valueField: FontField,
2606
3696
  icon: import_icons17.TextIcon,
2607
3697
  propTypeUtil: fontVariablePropTypeUtil,
2608
- fallbackPropTypeUtil: import_editor_props3.stringPropTypeUtil,
2609
- variableType: "font"
3698
+ fallbackPropTypeUtil: import_editor_props4.stringPropTypeUtil,
3699
+ variableType: "font",
3700
+ defaultValue: "Roboto"
2610
3701
  });
2611
3702
  }
2612
3703
 
2613
3704
  // src/renderers/style-variables-renderer.tsx
2614
- var React37 = __toESM(require("react"));
2615
- var import_react21 = require("react");
3705
+ var React36 = __toESM(require("react"));
3706
+ var import_react25 = require("react");
2616
3707
  var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
2617
- var import_ui34 = require("@elementor/ui");
3708
+ var import_ui33 = require("@elementor/ui");
2618
3709
 
2619
3710
  // src/sync/get-canvas-iframe-document.ts
2620
3711
  function getCanvasIframeDocument() {
@@ -2633,14 +3724,14 @@ function StyleVariablesRenderer() {
2633
3724
  }
2634
3725
  const cssVariables = convertToCssVariables(styleVariables);
2635
3726
  const wrappedCss = `${VARIABLES_WRAPPER}{${cssVariables}}`;
2636
- return /* @__PURE__ */ React37.createElement(import_ui34.Portal, { container }, /* @__PURE__ */ React37.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
3727
+ return /* @__PURE__ */ React36.createElement(import_ui33.Portal, { container }, /* @__PURE__ */ React36.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
2637
3728
  }
2638
3729
  function usePortalContainer() {
2639
3730
  return (0, import_editor_v1_adapters3.__privateUseListenTo)((0, import_editor_v1_adapters3.commandEndEvent)("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
2640
3731
  }
2641
3732
  function useStyleVariables() {
2642
- const [variables, setVariables] = (0, import_react21.useState)({});
2643
- (0, import_react21.useEffect)(() => {
3733
+ const [variables, setVariables] = (0, import_react25.useState)({});
3734
+ (0, import_react25.useEffect)(() => {
2644
3735
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
2645
3736
  return () => {
2646
3737
  unsubscribe();
@@ -2660,25 +3751,25 @@ function convertToCssVariables(variables) {
2660
3751
 
2661
3752
  // src/repeater-injections.ts
2662
3753
  var import_editor_controls13 = require("@elementor/editor-controls");
2663
- var import_editor_props4 = require("@elementor/editor-props");
3754
+ var import_editor_props5 = require("@elementor/editor-props");
2664
3755
 
2665
3756
  // src/components/variables-repeater-item-slot.tsx
2666
- var React38 = __toESM(require("react"));
3757
+ var React37 = __toESM(require("react"));
2667
3758
  var useColorVariable = (value) => {
2668
3759
  const variableId = value?.value?.color?.value;
2669
3760
  return useVariable(variableId || "");
2670
3761
  };
2671
3762
  var BackgroundRepeaterColorIndicator = ({ value }) => {
2672
3763
  const colorVariable = useColorVariable(value);
2673
- return /* @__PURE__ */ React38.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
3764
+ return /* @__PURE__ */ React37.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
2674
3765
  };
2675
3766
  var BackgroundRepeaterLabel = ({ value }) => {
2676
3767
  const colorVariable = useColorVariable(value);
2677
- return /* @__PURE__ */ React38.createElement("span", null, colorVariable?.label);
3768
+ return /* @__PURE__ */ React37.createElement("span", null, colorVariable?.label);
2678
3769
  };
2679
3770
  var BoxShadowRepeaterColorIndicator = ({ value }) => {
2680
3771
  const colorVariable = useColorVariable(value);
2681
- return /* @__PURE__ */ React38.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
3772
+ return /* @__PURE__ */ React37.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
2682
3773
  };
2683
3774
 
2684
3775
  // src/repeater-injections.ts
@@ -2687,21 +3778,21 @@ function registerRepeaterInjections() {
2687
3778
  id: "color-variables-background-icon",
2688
3779
  component: BackgroundRepeaterColorIndicator,
2689
3780
  condition: ({ value: prop }) => {
2690
- return hasAssignedColorVariable(import_editor_props4.backgroundColorOverlayPropTypeUtil.extract(prop)?.color);
3781
+ return hasAssignedColorVariable(import_editor_props5.backgroundColorOverlayPropTypeUtil.extract(prop)?.color);
2691
3782
  }
2692
3783
  });
2693
3784
  (0, import_editor_controls13.injectIntoRepeaterItemIcon)({
2694
3785
  id: "color-variables-icon",
2695
3786
  component: BoxShadowRepeaterColorIndicator,
2696
3787
  condition: ({ value: prop }) => {
2697
- return hasAssignedColorVariable(import_editor_props4.shadowPropTypeUtil.extract(prop)?.color);
3788
+ return hasAssignedColorVariable(import_editor_props5.shadowPropTypeUtil.extract(prop)?.color);
2698
3789
  }
2699
3790
  });
2700
3791
  (0, import_editor_controls13.injectIntoRepeaterItemLabel)({
2701
3792
  id: "color-variables-label",
2702
3793
  component: BackgroundRepeaterLabel,
2703
3794
  condition: ({ value: prop }) => {
2704
- return hasAssignedColorVariable(import_editor_props4.backgroundColorOverlayPropTypeUtil.extract(prop)?.color);
3795
+ return hasAssignedColorVariable(import_editor_props5.backgroundColorOverlayPropTypeUtil.extract(prop)?.color);
2705
3796
  }
2706
3797
  });
2707
3798
  }
@@ -2710,34 +3801,37 @@ var hasAssignedColorVariable = (propValue) => {
2710
3801
  };
2711
3802
 
2712
3803
  // src/init.ts
2713
- var { registerPopoverAction } = import_editor_editing_panel11.controlActionsMenu;
3804
+ var { registerPopoverAction } = import_editor_editing_panel8.controlActionsMenu;
2714
3805
  function init() {
2715
3806
  registerVariableTypes();
2716
3807
  registerRepeaterInjections();
2717
- (0, import_editor_editing_panel11.registerControlReplacement)({
3808
+ (0, import_editor_editing_panel8.registerControlReplacement)({
2718
3809
  component: VariableControl,
2719
- condition: ({ value }) => hasAssignedVariable(value)
3810
+ condition: ({ value, placeholder }) => hasVariable(value) || hasVariable(placeholder)
2720
3811
  });
2721
3812
  registerPopoverAction({
2722
3813
  id: "variables",
2723
3814
  useProps: usePropVariableAction
2724
3815
  });
2725
- service.init();
3816
+ service.init().then(() => {
3817
+ initMcp();
3818
+ });
2726
3819
  (0, import_editor.injectIntoTop)({
2727
3820
  id: "canvas-style-variables-render",
2728
3821
  component: StyleVariablesRenderer
2729
3822
  });
2730
3823
  (0, import_editor_panels2.__registerPanel)(panel);
2731
3824
  }
2732
- function hasAssignedVariable(propValue) {
2733
- if (propValue && typeof propValue === "object" && "$$type" in propValue) {
2734
- return hasVariableType(propValue.$$type);
3825
+ function hasVariable(value) {
3826
+ if ((0, import_editor_props6.isTransformable)(value)) {
3827
+ return hasVariableType(value.$$type);
2735
3828
  }
2736
3829
  return false;
2737
3830
  }
2738
3831
  // Annotate the CommonJS export names for ESM import in node:
2739
3832
  0 && (module.exports = {
2740
3833
  init,
2741
- registerVariableType
3834
+ registerVariableType,
3835
+ registerVariableTypes
2742
3836
  });
2743
3837
  //# sourceMappingURL=index.js.map