@elementor/editor-variables 3.33.0-98 → 3.34.2

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 (59) hide show
  1. package/dist/index.d.mts +11 -3
  2. package/dist/index.d.ts +11 -3
  3. package/dist/index.js +1874 -801
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +1819 -737
  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 +10 -3
  25. package/src/components/variable-edit.tsx +11 -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 +116 -0
  32. package/src/components/variables-manager/variables-manager-panel.tsx +290 -59
  33. package/src/components/variables-manager/variables-manager-table.tsx +111 -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 +11 -8
  37. package/src/hooks/use-variable-bound-prop.ts +42 -0
  38. package/src/index.ts +1 -0
  39. package/src/init.ts +19 -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 +2 -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/validations.ts +72 -3
  53. package/src/variables-registry/create-variable-type-registry.ts +10 -1
  54. package/src/variables-registry/variable-type-registry.ts +2 -1
  55. package/src/components/ui/tags/deleted-tag.tsx +0 -37
  56. package/src/components/ui/tags/mismatch-tag.tsx +0 -37
  57. package/src/components/ui/tags/missing-tag.tsx +0 -25
  58. /package/src/components/variables-manager/{variable-edit-menu.tsx → ui/variable-edit-menu.tsx} +0 -0
  59. /package/src/components/variables-manager/{variable-table-cell.tsx → ui/variable-table-cell.tsx} +0 -0
package/dist/index.mjs CHANGED
@@ -2,10 +2,11 @@
2
2
  import { injectIntoTop } from "@elementor/editor";
3
3
  import { controlActionsMenu, registerControlReplacement } from "@elementor/editor-editing-panel";
4
4
  import { __registerPanel as registerPanel } from "@elementor/editor-panels";
5
+ import { isTransformable as isTransformable2 } from "@elementor/editor-props";
5
6
 
6
7
  // src/components/variables-manager/variables-manager-panel.tsx
7
- import * as React8 from "react";
8
- import { useEffect, useState as useState4 } from "react";
8
+ import * as React12 from "react";
9
+ import { useCallback as useCallback5, useEffect as useEffect3, useState as useState5 } from "react";
9
10
  import {
10
11
  __createPanel as createPanel,
11
12
  Panel,
@@ -14,19 +15,154 @@ import {
14
15
  PanelHeader,
15
16
  PanelHeaderTitle
16
17
  } from "@elementor/editor-panels";
17
- import { ThemeProvider } from "@elementor/editor-ui";
18
+ import { SaveChangesDialog, SearchField, ThemeProvider, useDialog } from "@elementor/editor-ui";
18
19
  import { changeEditMode } from "@elementor/editor-v1-adapters";
19
- import { ColorFilterIcon, TrashIcon, XIcon } from "@elementor/icons";
20
- import { Alert, Box, Button, Divider, ErrorBoundary, IconButton as IconButton3, Stack as Stack4 } from "@elementor/ui";
21
- import { __ as __5 } from "@wordpress/i18n";
20
+ import { AlertTriangleFilledIcon as AlertTriangleFilledIcon2, ColorFilterIcon, TrashIcon } from "@elementor/icons";
21
+ import {
22
+ Alert,
23
+ AlertAction,
24
+ AlertTitle,
25
+ Button as Button3,
26
+ CloseButton,
27
+ Divider,
28
+ Infotip,
29
+ Stack as Stack6,
30
+ usePopupState as usePopupState2
31
+ } from "@elementor/ui";
32
+ import { __ as __9 } from "@wordpress/i18n";
22
33
 
23
- // src/hooks/use-prop-variables.ts
24
- import { useMemo } from "react";
25
- import { useBoundProp } from "@elementor/editor-controls";
34
+ // src/utils/tracking.ts
35
+ import { getMixpanel } from "@elementor/mixpanel";
36
+ var trackVariableEvent = ({ varType, controlPath, action }) => {
37
+ const { dispatchEvent, config } = getMixpanel();
38
+ if (!config?.names?.variables?.[action]) {
39
+ return;
40
+ }
41
+ const name = config.names.variables[action];
42
+ dispatchEvent?.(name, {
43
+ location: config?.locations?.variables || "",
44
+ secondaryLocation: config?.secondaryLocations?.variablesPopover || "",
45
+ trigger: config?.triggers?.click || "",
46
+ var_type: varType,
47
+ control_path: controlPath,
48
+ action_type: name
49
+ });
50
+ };
51
+ var trackVariablesManagerEvent = ({ action, varType, controlPath }) => {
52
+ const { dispatchEvent, config } = getMixpanel();
53
+ if (!config?.names?.variables?.[action]) {
54
+ return;
55
+ }
56
+ const name = config.names.variables[action];
57
+ const eventData = {
58
+ location: config?.locations?.variablesManager || "",
59
+ trigger: config?.triggers?.click || "",
60
+ action_type: name
61
+ };
62
+ if (varType) {
63
+ eventData.var_type = varType;
64
+ }
65
+ if (controlPath) {
66
+ eventData.style_control_path = controlPath;
67
+ }
68
+ dispatchEvent?.(name, eventData);
69
+ };
26
70
 
27
- // src/context/variable-type-context.tsx
28
- import * as React2 from "react";
29
- import { createContext, useContext } from "react";
71
+ // src/utils/validations.ts
72
+ import { AlertTriangleFilledIcon, InfoCircleFilledIcon } from "@elementor/icons";
73
+ import { __, sprintf } from "@wordpress/i18n";
74
+ var ERROR_MESSAGES = {
75
+ MISSING_VARIABLE_NAME: __("Give your variable a name.", "elementor"),
76
+ MISSING_VARIABLE_VALUE: __("Add a value to complete your variable.", "elementor"),
77
+ INVALID_CHARACTERS: __("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor"),
78
+ NO_NON_SPECIAL_CHARACTER: __("Names have to include at least one non-special character.", "elementor"),
79
+ VARIABLE_LABEL_MAX_LENGTH: __("Keep names up to 50 characters.", "elementor"),
80
+ DUPLICATED_LABEL: __("This variable name already exists. Please choose a unique name.", "elementor"),
81
+ UNEXPECTED_ERROR: __("There was a glitch. Try saving your variable again.", "elementor"),
82
+ BATCH: {
83
+ DUPLICATED_LABELS: (count, name) => (
84
+ // eslint-disable-next-line @wordpress/i18n-translator-comments
85
+ sprintf(__("We found %1$d duplicated %2$s.", "elementor"), count, name)
86
+ ),
87
+ UNEXPECTED_ERROR: __("There was a glitch.", "elementor"),
88
+ DUPLICATED_LABEL_ACTION: __("Take me there", "elementor"),
89
+ DUPLICATED_LABEL_ACTION_MESSAGE: __("Please rename the variables.", "elementor"),
90
+ UNEXPECTED_ERROR_ACTION_MESSAGE: __("Try saving your variables again.", "elementor")
91
+ }
92
+ };
93
+ var VARIABLE_LABEL_MAX_LENGTH = 50;
94
+ var mapServerError = (error) => {
95
+ if (error?.response?.data?.code === "duplicated_label") {
96
+ return {
97
+ field: "label",
98
+ message: ERROR_MESSAGES.DUPLICATED_LABEL
99
+ };
100
+ }
101
+ if (error?.response?.data?.code === "batch_duplicated_label") {
102
+ const errorData = error?.response?.data?.data ?? {};
103
+ const count = Object.keys(errorData).length;
104
+ const name = count === 1 ? "name" : "names";
105
+ const duplicatedIds = Object.keys(errorData);
106
+ return {
107
+ field: "label",
108
+ message: ERROR_MESSAGES.BATCH.DUPLICATED_LABELS(count, name),
109
+ severity: "error",
110
+ IconComponent: AlertTriangleFilledIcon,
111
+ action: {
112
+ label: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION,
113
+ message: ERROR_MESSAGES.BATCH.DUPLICATED_LABEL_ACTION_MESSAGE,
114
+ data: {
115
+ duplicatedIds
116
+ }
117
+ }
118
+ };
119
+ }
120
+ if (error?.response?.data?.code === "batch_operation_failed") {
121
+ return {
122
+ field: "label",
123
+ message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR,
124
+ severity: "secondary",
125
+ IconComponent: InfoCircleFilledIcon,
126
+ action: {
127
+ message: ERROR_MESSAGES.BATCH.UNEXPECTED_ERROR_ACTION_MESSAGE
128
+ }
129
+ };
130
+ }
131
+ return void 0;
132
+ };
133
+ var validateLabel = (name, variables) => {
134
+ if (!name.trim()) {
135
+ return ERROR_MESSAGES.MISSING_VARIABLE_NAME;
136
+ }
137
+ const allowedChars = /^[a-zA-Z0-9_-]+$/;
138
+ if (!allowedChars.test(name)) {
139
+ return ERROR_MESSAGES.INVALID_CHARACTERS;
140
+ }
141
+ const hasAlphanumeric = /[a-zA-Z0-9]/;
142
+ if (!hasAlphanumeric.test(name)) {
143
+ return ERROR_MESSAGES.NO_NON_SPECIAL_CHARACTER;
144
+ }
145
+ if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
146
+ return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
147
+ }
148
+ if (Object.values(variables ?? {}).some((variable) => variable.label === name)) {
149
+ return ERROR_MESSAGES.DUPLICATED_LABEL;
150
+ }
151
+ return "";
152
+ };
153
+ var labelHint = (name) => {
154
+ const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
155
+ if (hintThreshold < name.length) {
156
+ return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
157
+ }
158
+ return "";
159
+ };
160
+ var validateValue = (value) => {
161
+ if (!value.trim()) {
162
+ return ERROR_MESSAGES.MISSING_VARIABLE_VALUE;
163
+ }
164
+ return "";
165
+ };
30
166
 
31
167
  // src/variables-registry/create-variable-type-registry.ts
32
168
  import { styleTransformersRegistry } from "@elementor/editor-canvas";
@@ -36,7 +172,7 @@ import { stylesInheritanceTransformersRegistry } from "@elementor/editor-editing
36
172
  import * as React from "react";
37
173
  import { createTransformer } from "@elementor/editor-canvas";
38
174
  import { Stack, Typography } from "@elementor/ui";
39
- import { __ as __2 } from "@wordpress/i18n";
175
+ import { __ as __3 } from "@wordpress/i18n";
40
176
 
41
177
  // src/components/ui/color-indicator.tsx
42
178
  import { styled, UnstableColorIndicator } from "@elementor/ui";
@@ -51,7 +187,7 @@ import { z } from "@elementor/schema";
51
187
  var colorVariablePropTypeUtil = createPropUtils("global-color-variable", z.string());
52
188
 
53
189
  // src/service.ts
54
- import { __ } from "@wordpress/i18n";
190
+ import { __ as __2 } from "@wordpress/i18n";
55
191
 
56
192
  // src/api.ts
57
193
  import { httpService } from "@elementor/http-client";
@@ -86,9 +222,72 @@ var apiClient = {
86
222
  payload.value = value;
87
223
  }
88
224
  return httpService().post(BASE_PATH + "/restore", payload);
225
+ },
226
+ batch: (payload) => {
227
+ return httpService().post(BASE_PATH + "/batch", payload);
89
228
  }
90
229
  };
91
230
 
231
+ // src/batch-operations.ts
232
+ var generateTempId = () => {
233
+ const timestamp = Date.now().toString(36);
234
+ const random = Math.random().toString(36).substring(2, 8);
235
+ return `tmp-${timestamp}-${random}`;
236
+ };
237
+ var isTempId = (id2) => {
238
+ return id2.startsWith("tmp-");
239
+ };
240
+ var buildOperationsArray = (originalVariables, currentVariables) => {
241
+ const operations = [];
242
+ Object.entries(currentVariables).forEach(([id2, variable]) => {
243
+ if (isTempId(id2)) {
244
+ operations.push({
245
+ type: "create",
246
+ variable: {
247
+ ...variable,
248
+ id: id2
249
+ }
250
+ });
251
+ } else if (originalVariables[id2]) {
252
+ const original = originalVariables[id2];
253
+ if (original.deleted && !variable.deleted) {
254
+ operations.push({
255
+ type: "restore",
256
+ id: id2,
257
+ ...original.label !== variable.label && { label: variable.label },
258
+ ...original.value !== variable.value && { value: variable.value }
259
+ });
260
+ } else if (!variable.deleted && (original.label !== variable.label || original.value !== variable.value || original.order !== variable.order)) {
261
+ operations.push({
262
+ type: "update",
263
+ id: id2,
264
+ variable: {
265
+ ...original.label !== variable.label && { label: variable.label },
266
+ ...original.value !== variable.value && { value: variable.value },
267
+ ...original.order !== variable.order && { order: variable.order }
268
+ }
269
+ });
270
+ }
271
+ }
272
+ });
273
+ Object.entries(originalVariables).forEach(([id2, variable]) => {
274
+ if (isTempId(id2) || variable.deleted) {
275
+ return;
276
+ }
277
+ const currentVariable = currentVariables[id2];
278
+ if (!currentVariable || currentVariable.deleted) {
279
+ operations.push({
280
+ type: "delete",
281
+ id: id2
282
+ });
283
+ }
284
+ });
285
+ return operations.filter((op) => {
286
+ const id2 = op.id || op.variable?.id;
287
+ return id2 && !(isTempId(id2) && currentVariables[id2]?.deleted);
288
+ });
289
+ };
290
+
92
291
  // src/storage.ts
93
292
  var STORAGE_KEY = "elementor-global-variables";
94
293
  var STORAGE_WATERMARK_KEY = "elementor-global-variables-watermark";
@@ -96,6 +295,9 @@ var OP_RW = "RW";
96
295
  var OP_RO = "RO";
97
296
  var Storage = class {
98
297
  state;
298
+ notifyChange() {
299
+ window.dispatchEvent(new Event("variables:updated"));
300
+ }
99
301
  constructor() {
100
302
  this.state = {
101
303
  watermark: -1,
@@ -115,16 +317,19 @@ var Storage = class {
115
317
  this.state.watermark = watermark;
116
318
  localStorage.setItem(STORAGE_WATERMARK_KEY, this.state.watermark.toString());
117
319
  localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
320
+ this.notifyChange();
118
321
  }
119
322
  add(id2, variable) {
120
323
  this.load();
121
324
  this.state.variables[id2] = variable;
122
325
  localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
326
+ this.notifyChange();
123
327
  }
124
328
  update(id2, variable) {
125
329
  this.load();
126
330
  this.state.variables[id2] = variable;
127
331
  localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state.variables));
332
+ this.notifyChange();
128
333
  }
129
334
  watermark(watermark) {
130
335
  this.state.watermark = watermark;
@@ -229,8 +434,11 @@ var service = {
229
434
  variables: () => {
230
435
  return storage.load();
231
436
  },
437
+ getWatermark: () => {
438
+ return storage.state.watermark;
439
+ },
232
440
  init: () => {
233
- service.load();
441
+ return service.load();
234
442
  },
235
443
  load: () => {
236
444
  return apiClient.list().then((response) => {
@@ -250,7 +458,7 @@ var service = {
250
458
  return apiClient.create(type, label, value).then((response) => {
251
459
  const { success, data: payload } = response.data;
252
460
  if (!success) {
253
- const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
461
+ const errorMessage = payload?.message || __2("Unexpected response from server", "elementor");
254
462
  throw new Error(errorMessage);
255
463
  }
256
464
  return payload;
@@ -272,7 +480,7 @@ var service = {
272
480
  return apiClient.update(id2, label, value).then((response) => {
273
481
  const { success, data: payload } = response.data;
274
482
  if (!success) {
275
- const errorMessage = payload?.message || __("Unexpected response from server", "elementor");
483
+ const errorMessage = payload?.message || __2("Unexpected response from server", "elementor");
276
484
  throw new Error(errorMessage);
277
485
  }
278
486
  return payload;
@@ -331,6 +539,47 @@ var service = {
331
539
  variable: restoredVariable
332
540
  };
333
541
  });
542
+ },
543
+ batchSave: (originalVariables, currentVariables) => {
544
+ const operations = buildOperationsArray(originalVariables, currentVariables);
545
+ const batchPayload = { operations, watermark: storage.state.watermark };
546
+ if (operations.length === 0) {
547
+ return Promise.resolve({
548
+ success: true,
549
+ watermark: storage.state.watermark,
550
+ operations: 0
551
+ });
552
+ }
553
+ return apiClient.batch(batchPayload).then((response) => {
554
+ const { success, data: payload } = response.data;
555
+ if (!success) {
556
+ throw new Error("Unexpected response from server");
557
+ }
558
+ return payload;
559
+ }).then((data) => {
560
+ const { results, watermark } = data;
561
+ handleWatermark(OP_RW, watermark);
562
+ if (results) {
563
+ results.forEach((result) => {
564
+ if (result.variable) {
565
+ const { id: variableId, ...variableData } = result.variable;
566
+ if (result.type === "create") {
567
+ storage.add(variableId, variableData);
568
+ } else {
569
+ storage.update(variableId, variableData);
570
+ }
571
+ styleVariablesRepository.update({
572
+ [variableId]: variableData
573
+ });
574
+ }
575
+ });
576
+ }
577
+ return {
578
+ success: true,
579
+ watermark,
580
+ operations: operations.length
581
+ };
582
+ });
334
583
  }
335
584
  };
336
585
  var handleWatermark = (operation, newWatermark) => {
@@ -364,7 +613,7 @@ var inheritanceTransformer = createTransformer((id2) => {
364
613
  const variables = service.variables();
365
614
  const variable = variables[id2];
366
615
  if (!variable) {
367
- return /* @__PURE__ */ React.createElement("span", null, __2("Missing variable", "elementor"));
616
+ return /* @__PURE__ */ React.createElement("span", null, __3("Missing variable", "elementor"));
368
617
  }
369
618
  const showColorIndicator = variable.type === colorVariablePropTypeUtil.key;
370
619
  const css = resolveCssVariable(id2, variable);
@@ -390,6 +639,7 @@ function createVariableTypeRegistry() {
390
639
  valueField,
391
640
  propTypeUtil,
392
641
  variableType,
642
+ defaultValue,
393
643
  selectionFilter,
394
644
  valueTransformer,
395
645
  fallbackPropTypeUtil,
@@ -414,6 +664,7 @@ function createVariableTypeRegistry() {
414
664
  valueField,
415
665
  propTypeUtil,
416
666
  variableType,
667
+ defaultValue,
417
668
  selectionFilter,
418
669
  valueTransformer,
419
670
  fallbackPropTypeUtil,
@@ -431,23 +682,181 @@ function createVariableTypeRegistry() {
431
682
  const getVariableType2 = (key) => {
432
683
  return variableTypes[key];
433
684
  };
685
+ const getVariableTypes2 = () => {
686
+ return variableTypes;
687
+ };
434
688
  const hasVariableType2 = (key) => {
435
689
  return key in variableTypes;
436
690
  };
437
691
  return {
438
692
  registerVariableType: registerVariableType2,
439
693
  getVariableType: getVariableType2,
694
+ getVariableTypes: getVariableTypes2,
440
695
  hasVariableType: hasVariableType2
441
696
  };
442
697
  }
443
698
 
444
699
  // src/variables-registry/variable-type-registry.ts
445
- var { registerVariableType, getVariableType, hasVariableType } = createVariableTypeRegistry();
700
+ var { registerVariableType, getVariableType, getVariableTypes, hasVariableType } = createVariableTypeRegistry();
701
+
702
+ // src/components/ui/delete-confirmation-dialog.tsx
703
+ import * as React2 from "react";
704
+ import { AlertOctagonFilledIcon } from "@elementor/icons";
705
+ import {
706
+ Button,
707
+ Dialog,
708
+ DialogActions,
709
+ DialogContent,
710
+ DialogContentText,
711
+ DialogTitle,
712
+ Typography as Typography2
713
+ } from "@elementor/ui";
714
+ import { __ as __4 } from "@wordpress/i18n";
715
+ var TITLE_ID = "delete-variable-dialog";
716
+ var DeleteConfirmationDialog = ({
717
+ open,
718
+ label,
719
+ closeDialog,
720
+ onConfirm
721
+ }) => {
722
+ return /* @__PURE__ */ React2.createElement(Dialog, { open, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React2.createElement(DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React2.createElement(AlertOctagonFilledIcon, { color: "error" }), __4("Delete this variable?", "elementor")), /* @__PURE__ */ React2.createElement(DialogContent, null, /* @__PURE__ */ React2.createElement(DialogContentText, { variant: "body2", color: "textPrimary" }, __4("All elements using", "elementor"), "\xA0", /* @__PURE__ */ React2.createElement(Typography2, { variant: "subtitle2", component: "span", sx: { lineBreak: "anywhere" } }, label), "\xA0", __4("will keep their current values, but the variable itself will be removed.", "elementor"))), /* @__PURE__ */ React2.createElement(DialogActions, null, /* @__PURE__ */ React2.createElement(Button, { color: "secondary", onClick: closeDialog }, __4("Not now", "elementor")), /* @__PURE__ */ React2.createElement(Button, { variant: "contained", color: "error", onClick: onConfirm }, __4("Delete", "elementor"))));
723
+ };
724
+
725
+ // src/components/ui/empty-state.tsx
726
+ import * as React3 from "react";
727
+ import { Button as Button2, Stack as Stack2, Typography as Typography3 } from "@elementor/ui";
728
+ import { __ as __5 } from "@wordpress/i18n";
729
+
730
+ // src/hooks/use-permissions.ts
731
+ import { useCurrentUserCapabilities } from "@elementor/editor-current-user";
732
+ var usePermissions = () => {
733
+ const { canUser } = useCurrentUserCapabilities();
734
+ return {
735
+ canAssign: () => canUser("edit_posts"),
736
+ canUnlink: () => canUser("edit_posts"),
737
+ canAdd: () => canUser("manage_options"),
738
+ canDelete: () => canUser("manage_options"),
739
+ canEdit: () => canUser("manage_options"),
740
+ canRestore: () => canUser("manage_options"),
741
+ canManageSettings: () => canUser("manage_options")
742
+ };
743
+ };
744
+
745
+ // src/components/ui/empty-state.tsx
746
+ var EmptyState = ({ icon, title, message, onAdd }) => {
747
+ const canAdd = usePermissions().canAdd();
748
+ return /* @__PURE__ */ React3.createElement(
749
+ Stack2,
750
+ {
751
+ gap: 1,
752
+ alignItems: "center",
753
+ justifyContent: "flex-start",
754
+ height: "100%",
755
+ color: "text.secondary",
756
+ sx: { p: 2.5, pt: 8, pb: 5.5 }
757
+ },
758
+ icon,
759
+ canAdd ? /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(Content, { title, message }), onAdd && /* @__PURE__ */ React3.createElement(Button2, { variant: "outlined", color: "secondary", size: "small", onClick: onAdd }, __5("Create a variable", "elementor"))) : /* @__PURE__ */ React3.createElement(
760
+ Content,
761
+ {
762
+ title: __5("There are no variables", "elementor"),
763
+ message: __5("With your current role, you can only connect and detach variables.", "elementor")
764
+ }
765
+ )
766
+ );
767
+ };
768
+ function Content({ title, message }) {
769
+ return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(Typography3, { align: "center", variant: "subtitle2" }, title), /* @__PURE__ */ React3.createElement(Typography3, { align: "center", variant: "caption", maxWidth: "180px" }, message));
770
+ }
771
+
772
+ // src/components/ui/no-search-results.tsx
773
+ import * as React4 from "react";
774
+ import { Link, Stack as Stack3, Typography as Typography4 } from "@elementor/ui";
775
+ import { __ as __6 } from "@wordpress/i18n";
776
+ var NoSearchResults = ({ searchValue, onClear, icon }) => {
777
+ return /* @__PURE__ */ React4.createElement(
778
+ Stack3,
779
+ {
780
+ gap: 1,
781
+ alignItems: "center",
782
+ justifyContent: "center",
783
+ p: 2.5,
784
+ color: "text.secondary",
785
+ sx: { pb: 3.5, pt: 8 }
786
+ },
787
+ icon,
788
+ /* @__PURE__ */ React4.createElement(Typography4, { align: "center", variant: "subtitle2" }, __6("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React4.createElement("br", null), "\u201C", searchValue, "\u201D."),
789
+ /* @__PURE__ */ React4.createElement(Typography4, { align: "center", variant: "caption", sx: { display: "flex", flexDirection: "column" } }, __6("Try something else.", "elementor"), /* @__PURE__ */ React4.createElement(Link, { color: "text.secondary", variant: "caption", component: "button", onClick: onClear }, __6("Clear & try again", "elementor")))
790
+ );
791
+ };
792
+
793
+ // src/components/variables-manager/hooks/use-auto-edit.ts
794
+ import { useCallback, useState } from "react";
795
+ var useAutoEdit = () => {
796
+ const [autoEditVariableId, setAutoEditVariableId] = useState(void 0);
797
+ const startAutoEdit = useCallback((variableId) => {
798
+ setAutoEditVariableId(variableId);
799
+ }, []);
800
+ const handleAutoEditComplete = useCallback(() => {
801
+ setTimeout(() => {
802
+ setAutoEditVariableId(void 0);
803
+ }, 100);
804
+ }, []);
805
+ return {
806
+ autoEditVariableId,
807
+ startAutoEdit,
808
+ handleAutoEditComplete
809
+ };
810
+ };
811
+
812
+ // src/components/variables-manager/hooks/use-error-navigation.ts
813
+ import { useCallback as useCallback2, useRef } from "react";
814
+ var useErrorNavigation = () => {
815
+ const currentIndexRef = useRef(0);
816
+ const createNavigationCallback = useCallback2(
817
+ (ids, onNavigate, onComplete) => {
818
+ return () => {
819
+ if (!ids?.length) {
820
+ return;
821
+ }
822
+ const currentIndex = currentIndexRef.current;
823
+ const currentId = ids[currentIndex];
824
+ if (currentId) {
825
+ onNavigate(currentId);
826
+ const nextIndex = currentIndex + 1;
827
+ if (nextIndex >= ids.length) {
828
+ onComplete();
829
+ currentIndexRef.current = 0;
830
+ } else {
831
+ currentIndexRef.current = nextIndex;
832
+ }
833
+ }
834
+ };
835
+ },
836
+ []
837
+ );
838
+ const resetNavigation = useCallback2(() => {
839
+ currentIndexRef.current = 0;
840
+ }, []);
841
+ return {
842
+ createNavigationCallback,
843
+ resetNavigation
844
+ };
845
+ };
846
+
847
+ // src/components/variables-manager/hooks/use-variables-manager-state.ts
848
+ import { useCallback as useCallback3, useState as useState2 } from "react";
849
+
850
+ // src/hooks/use-prop-variables.ts
851
+ import { useMemo } from "react";
852
+ import { useBoundProp } from "@elementor/editor-controls";
446
853
 
447
854
  // src/context/variable-type-context.tsx
855
+ import * as React5 from "react";
856
+ import { createContext, useContext } from "react";
448
857
  var VariableTypeContext = createContext(null);
449
858
  function VariableTypeProvider({ children, propTypeKey }) {
450
- return /* @__PURE__ */ React2.createElement(VariableTypeContext.Provider, { value: propTypeKey }, children);
859
+ return /* @__PURE__ */ React5.createElement(VariableTypeContext.Provider, { value: propTypeKey }, children);
451
860
  }
452
861
  function useVariableType() {
453
862
  const context = useContext(VariableTypeContext);
@@ -457,6 +866,12 @@ function useVariableType() {
457
866
  return getVariableType(context);
458
867
  }
459
868
 
869
+ // src/utils/filter-by-search.ts
870
+ function filterBySearch(variables, searchValue) {
871
+ const lowerSearchValue = searchValue.toLowerCase();
872
+ return variables.filter((variable) => variable.label.toLowerCase().includes(lowerSearchValue));
873
+ }
874
+
460
875
  // src/hooks/use-prop-variables.ts
461
876
  var getVariables = (includeDeleted = true) => {
462
877
  const variables = service.variables();
@@ -478,11 +893,17 @@ var useVariable = (key) => {
478
893
  var useFilteredVariables = (searchValue, propTypeKey) => {
479
894
  const baseVariables = usePropVariables(propTypeKey);
480
895
  const typeFilteredVariables = useVariableSelectionFilter(baseVariables);
481
- const searchFilteredVariables = filterVariablesBySearchValue(typeFilteredVariables, searchValue);
896
+ const searchFilteredVariables = filterBySearch(typeFilteredVariables, searchValue);
897
+ const sortedVariables = searchFilteredVariables.sort((a, b) => {
898
+ const orderA = a.order ?? Number.MAX_SAFE_INTEGER;
899
+ const orderB = b.order ?? Number.MAX_SAFE_INTEGER;
900
+ return orderA - orderB;
901
+ });
482
902
  return {
483
- list: searchFilteredVariables,
903
+ list: sortedVariables,
484
904
  hasMatches: searchFilteredVariables.length > 0,
485
- isSourceNotEmpty: typeFilteredVariables.length > 0
905
+ isSourceNotEmpty: typeFilteredVariables.length > 0,
906
+ hasNoCompatibleVariables: baseVariables.length > 0 && typeFilteredVariables.length === 0
486
907
  };
487
908
  };
488
909
  var useVariableSelectionFilter = (variables) => {
@@ -490,19 +911,16 @@ var useVariableSelectionFilter = (variables) => {
490
911
  const { propType } = useBoundProp();
491
912
  return selectionFilter ? selectionFilter(variables, propType) : variables;
492
913
  };
493
- var filterVariablesBySearchValue = (variables, searchValue) => {
494
- const lowerSearchValue = searchValue.toLowerCase();
495
- return variables.filter(({ label }) => label.toLowerCase().includes(lowerSearchValue));
496
- };
497
914
  var usePropVariables = (propKey) => {
498
915
  return useMemo(() => normalizeVariables(propKey), [propKey]);
499
916
  };
500
917
  var normalizeVariables = (propKey) => {
501
918
  const variables = getVariables(false);
502
- return Object.entries(variables).filter(([, variable]) => variable.type === propKey).map(([key, { label, value }]) => ({
919
+ return Object.entries(variables).filter(([, variable]) => variable.type === propKey).map(([key, { label, value, order }]) => ({
503
920
  key,
504
921
  label,
505
- value
922
+ value,
923
+ order
506
924
  }));
507
925
  };
508
926
  var extractId = ({ id: id2 }) => id2;
@@ -519,87 +937,195 @@ var restoreVariable = (restoreId, label, value) => {
519
937
  return service.restore(restoreId, label, value).then(extractId);
520
938
  };
521
939
 
522
- // src/components/variables-manager/variables-manager-table.tsx
523
- import * as React7 from "react";
524
- import { createElement as createElement9, useState as useState3 } from "react";
525
- import { EllipsisWithTooltip } from "@elementor/editor-ui";
526
- import { GripVerticalIcon } from "@elementor/icons";
527
- import {
528
- IconButton as IconButton2,
529
- Stack as Stack3,
530
- Table,
531
- TableBody,
532
- TableContainer,
533
- TableHead,
534
- TableRow,
535
- UnstableSortableItem,
536
- UnstableSortableProvider
537
- } from "@elementor/ui";
538
- import { __ as __4 } from "@wordpress/i18n";
940
+ // src/components/variables-manager/hooks/use-variables-manager-state.ts
941
+ var useVariablesManagerState = () => {
942
+ const [variables, setVariables] = useState2(() => getVariables(false));
943
+ const [deletedVariables, setDeletedVariables] = useState2([]);
944
+ const [isSaveDisabled, setIsSaveDisabled] = useState2(false);
945
+ const [isDirty, setIsDirty] = useState2(false);
946
+ const [isSaving, setIsSaving] = useState2(false);
947
+ const [searchValue, setSearchValue] = useState2("");
948
+ const handleOnChange = useCallback3(
949
+ (newVariables) => {
950
+ setVariables({ ...variables, ...newVariables });
951
+ setIsDirty(true);
952
+ },
953
+ [variables]
954
+ );
955
+ const createVariable2 = useCallback3((type, defaultName, defaultValue) => {
956
+ const newId = generateTempId();
957
+ const newVariable = {
958
+ id: newId,
959
+ label: defaultName.trim(),
960
+ value: defaultValue.trim(),
961
+ type
962
+ };
963
+ setVariables((prev) => ({ ...prev, [newId]: newVariable }));
964
+ setIsDirty(true);
965
+ return newId;
966
+ }, []);
967
+ const handleDeleteVariable = useCallback3((itemId) => {
968
+ setDeletedVariables((prev) => [...prev, itemId]);
969
+ setVariables((prev) => ({ ...prev, [itemId]: { ...prev[itemId], deleted: true } }));
970
+ setIsDirty(true);
971
+ }, []);
972
+ const handleSearch = (searchTerm) => {
973
+ setSearchValue(searchTerm);
974
+ };
975
+ const handleSave = useCallback3(async () => {
976
+ const originalVariables = getVariables(false);
977
+ setIsSaving(true);
978
+ const result = await service.batchSave(originalVariables, variables);
979
+ if (result.success) {
980
+ await service.load();
981
+ const updatedVariables = service.variables();
982
+ setVariables(updatedVariables);
983
+ setDeletedVariables([]);
984
+ setIsDirty(false);
985
+ }
986
+ return { success: result.success };
987
+ }, [variables]);
988
+ const filteredVariables = () => {
989
+ const list = Object.entries(variables).map(([id2, value]) => ({ ...value, id: id2 }));
990
+ const filtered = filterBySearch(list, searchValue);
991
+ return Object.fromEntries(filtered.map(({ id: id2, ...rest }) => [id2, rest]));
992
+ };
993
+ return {
994
+ variables: filteredVariables(),
995
+ deletedVariables,
996
+ isDirty,
997
+ isSaveDisabled,
998
+ handleOnChange,
999
+ createVariable: createVariable2,
1000
+ handleDeleteVariable,
1001
+ handleSave,
1002
+ isSaving,
1003
+ handleSearch,
1004
+ searchValue,
1005
+ setIsSaving,
1006
+ setIsSaveDisabled
1007
+ };
1008
+ };
539
1009
 
540
- // src/components/fields/label-field.tsx
541
- import * as React3 from "react";
542
- import { useState } from "react";
543
- import { TextField } from "@elementor/ui";
544
-
545
- // src/utils/validations.ts
546
- import { __ as __3 } from "@wordpress/i18n";
547
- var ERROR_MESSAGES = {
548
- MISSING_VARIABLE_NAME: __3("Give your variable a name.", "elementor"),
549
- MISSING_VARIABLE_VALUE: __3("Add a value to complete your variable.", "elementor"),
550
- INVALID_CHARACTERS: __3("Use letters, numbers, dashes (-), or underscores (_) for the name.", "elementor"),
551
- NO_NON_SPECIAL_CHARACTER: __3("Names have to include at least one non-special character.", "elementor"),
552
- VARIABLE_LABEL_MAX_LENGTH: __3("Keep names up to 50 characters.", "elementor"),
553
- DUPLICATED_LABEL: __3("This variable name already exists. Please choose a unique name.", "elementor"),
554
- UNEXPECTED_ERROR: __3("There was a glitch. Try saving your variable again.", "elementor")
555
- };
556
- var VARIABLE_LABEL_MAX_LENGTH = 50;
557
- var mapServerError = (error) => {
558
- if (error?.response?.data?.code === "duplicated_label") {
1010
+ // src/components/variables-manager/variables-manager-create-menu.tsx
1011
+ import * as React6 from "react";
1012
+ import { createElement as createElement7, useRef as useRef2 } from "react";
1013
+ import { PlusIcon } from "@elementor/icons";
1014
+ import { bindMenu, bindTrigger, IconButton, Menu, MenuItem, Typography as Typography5 } from "@elementor/ui";
1015
+ import { __ as __7 } from "@wordpress/i18n";
1016
+ var SIZE = "tiny";
1017
+ var VariableManagerCreateMenu = ({
1018
+ variables,
1019
+ onCreate,
1020
+ disabled,
1021
+ menuState
1022
+ }) => {
1023
+ const buttonRef = useRef2(null);
1024
+ const variableTypes = getVariableTypes();
1025
+ const menuOptions = Object.entries(variableTypes).map(([key, variable]) => {
1026
+ const displayName = variable.variableType.charAt(0).toUpperCase() + variable.variableType.slice(1);
559
1027
  return {
560
- field: "label",
561
- message: ERROR_MESSAGES.DUPLICATED_LABEL
1028
+ key,
1029
+ name: displayName,
1030
+ icon: variable.icon,
1031
+ onClick: () => {
1032
+ const defaultName = getDefaultName(variables, key, variable.variableType);
1033
+ onCreate(key, defaultName, variable.defaultValue || "");
1034
+ trackVariablesManagerEvent({ action: "add", varType: variable.variableType });
1035
+ }
562
1036
  };
563
- }
564
- return void 0;
565
- };
566
- var validateLabel = (name) => {
567
- if (!name.trim()) {
568
- return ERROR_MESSAGES.MISSING_VARIABLE_NAME;
569
- }
570
- const allowedChars = /^[a-zA-Z0-9_-]+$/;
571
- if (!allowedChars.test(name)) {
572
- return ERROR_MESSAGES.INVALID_CHARACTERS;
573
- }
574
- const hasAlphanumeric = /[a-zA-Z0-9]/;
575
- if (!hasAlphanumeric.test(name)) {
576
- return ERROR_MESSAGES.NO_NON_SPECIAL_CHARACTER;
577
- }
578
- if (VARIABLE_LABEL_MAX_LENGTH < name.length) {
579
- return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
580
- }
581
- return "";
582
- };
583
- var labelHint = (name) => {
584
- const hintThreshold = VARIABLE_LABEL_MAX_LENGTH * 0.8 - 1;
585
- if (hintThreshold < name.length) {
586
- return ERROR_MESSAGES.VARIABLE_LABEL_MAX_LENGTH;
587
- }
588
- return "";
1037
+ });
1038
+ return /* @__PURE__ */ React6.createElement(React6.Fragment, null, /* @__PURE__ */ React6.createElement(
1039
+ IconButton,
1040
+ {
1041
+ ...bindTrigger(menuState),
1042
+ ref: buttonRef,
1043
+ disabled,
1044
+ size: SIZE,
1045
+ "aria-label": __7("Add variable", "elementor")
1046
+ },
1047
+ /* @__PURE__ */ React6.createElement(PlusIcon, { fontSize: SIZE })
1048
+ ), /* @__PURE__ */ React6.createElement(
1049
+ Menu,
1050
+ {
1051
+ disablePortal: true,
1052
+ MenuListProps: {
1053
+ dense: true
1054
+ },
1055
+ PaperProps: {
1056
+ elevation: 6
1057
+ },
1058
+ ...bindMenu(menuState),
1059
+ anchorEl: buttonRef.current,
1060
+ anchorOrigin: {
1061
+ vertical: "bottom",
1062
+ horizontal: "right"
1063
+ },
1064
+ transformOrigin: {
1065
+ vertical: "top",
1066
+ horizontal: "right"
1067
+ },
1068
+ "data-testid": "variable-manager-create-menu"
1069
+ },
1070
+ menuOptions.map((option) => /* @__PURE__ */ React6.createElement(
1071
+ MenuItem,
1072
+ {
1073
+ key: option.key,
1074
+ onClick: () => {
1075
+ option.onClick?.();
1076
+ menuState.close();
1077
+ },
1078
+ sx: {
1079
+ gap: 1.5
1080
+ }
1081
+ },
1082
+ createElement7(option.icon, {
1083
+ fontSize: SIZE,
1084
+ color: "action"
1085
+ }),
1086
+ /* @__PURE__ */ React6.createElement(Typography5, { variant: "caption", color: "text.primary" }, option.name)
1087
+ ))
1088
+ ));
589
1089
  };
590
- var validateValue = (value) => {
591
- if (!value.trim()) {
592
- return ERROR_MESSAGES.MISSING_VARIABLE_VALUE;
1090
+ var getDefaultName = (variables, type, baseName) => {
1091
+ const existingNames = Object.values(variables).filter((variable) => variable.type === type).map((variable) => variable.label);
1092
+ let counter = 1;
1093
+ let name = `${baseName}-${counter}`;
1094
+ while (existingNames.includes(name)) {
1095
+ counter++;
1096
+ name = `${baseName}-${counter}`;
593
1097
  }
594
- return "";
1098
+ return name;
595
1099
  };
596
1100
 
1101
+ // src/components/variables-manager/variables-manager-table.tsx
1102
+ import * as React11 from "react";
1103
+ import { createElement as createElement14, useEffect as useEffect2, useRef as useRef5 } from "react";
1104
+ import { EllipsisWithTooltip } from "@elementor/editor-ui";
1105
+ import { GripVerticalIcon } from "@elementor/icons";
1106
+ import {
1107
+ IconButton as IconButton3,
1108
+ Stack as Stack5,
1109
+ Table,
1110
+ TableBody,
1111
+ TableContainer,
1112
+ TableHead,
1113
+ TableRow,
1114
+ UnstableSortableItem,
1115
+ UnstableSortableProvider
1116
+ } from "@elementor/ui";
1117
+ import { __ as __8 } from "@wordpress/i18n";
1118
+
597
1119
  // src/components/fields/label-field.tsx
1120
+ import * as React7 from "react";
1121
+ import { useRef as useRef3, useState as useState3 } from "react";
1122
+ import { WarningInfotip } from "@elementor/editor-ui";
1123
+ import { TextField } from "@elementor/ui";
598
1124
  function isLabelEqual(a, b) {
599
1125
  return a.trim().toLowerCase() === b.trim().toLowerCase();
600
1126
  }
601
1127
  var useLabelError = (initialError) => {
602
- const [error, setError] = useState(initialError ?? { value: "", message: "" });
1128
+ const [error, setError] = useState3(initialError ?? { value: "", message: "" });
603
1129
  return {
604
1130
  labelFieldError: error,
605
1131
  setLabelFieldError: setError
@@ -612,13 +1138,17 @@ var LabelField = ({
612
1138
  id: id2,
613
1139
  onErrorChange,
614
1140
  size = "tiny",
615
- focusOnShow = false
1141
+ focusOnShow = false,
1142
+ selectOnShow = false,
1143
+ showWarningInfotip = false,
1144
+ variables
616
1145
  }) => {
617
- const [label, setLabel] = useState(value);
618
- const [errorMessage, setErrorMessage] = useState("");
1146
+ const [label, setLabel] = useState3(value);
1147
+ const [errorMessage, setErrorMessage] = useState3("");
1148
+ const fieldRef = useRef3(null);
619
1149
  const handleChange = (newValue) => {
620
1150
  setLabel(newValue);
621
- const errorMsg2 = validateLabel(newValue);
1151
+ const errorMsg2 = validateLabel(newValue, variables);
622
1152
  setErrorMessage(errorMsg2);
623
1153
  onErrorChange?.(errorMsg2);
624
1154
  onChange(isLabelEqual(newValue, error?.value ?? "") || errorMsg2 ? "" : newValue);
@@ -627,32 +1157,54 @@ var LabelField = ({
627
1157
  if (isLabelEqual(label, error?.value ?? "") && error?.message) {
628
1158
  errorMsg = error.message;
629
1159
  }
630
- return /* @__PURE__ */ React3.createElement(
1160
+ const hintMsg = !errorMsg ? labelHint(label) : "";
1161
+ const textField = /* @__PURE__ */ React7.createElement(
631
1162
  TextField,
632
1163
  {
1164
+ ref: fieldRef,
633
1165
  id: id2,
634
1166
  size,
635
1167
  fullWidth: true,
636
1168
  value: label,
637
1169
  error: !!errorMsg,
638
1170
  onChange: (e) => handleChange(e.target.value),
639
- inputProps: { maxLength: VARIABLE_LABEL_MAX_LENGTH },
1171
+ inputProps: {
1172
+ maxLength: VARIABLE_LABEL_MAX_LENGTH,
1173
+ ...selectOnShow && { onFocus: (e) => e.target.select() },
1174
+ "aria-label": "Name"
1175
+ },
640
1176
  autoFocus: focusOnShow
641
1177
  }
642
1178
  );
1179
+ if (showWarningInfotip) {
1180
+ const tooltipWidth = Math.max(240, fieldRef.current?.getBoundingClientRect().width ?? 240);
1181
+ return /* @__PURE__ */ React7.createElement(
1182
+ WarningInfotip,
1183
+ {
1184
+ open: Boolean(errorMsg || hintMsg),
1185
+ text: errorMsg || hintMsg,
1186
+ placement: "bottom-start",
1187
+ width: tooltipWidth,
1188
+ offset: [0, -15],
1189
+ ...hintMsg && { hasError: false }
1190
+ },
1191
+ textField
1192
+ );
1193
+ }
1194
+ return textField;
643
1195
  };
644
1196
 
645
- // src/components/variables-manager/variable-edit-menu.tsx
646
- import * as React4 from "react";
647
- import { createElement as createElement5 } from "react";
1197
+ // src/components/variables-manager/ui/variable-edit-menu.tsx
1198
+ import * as React8 from "react";
1199
+ import { createElement as createElement10 } from "react";
648
1200
  import { DotsVerticalIcon } from "@elementor/icons";
649
- import { bindMenu, bindTrigger, IconButton, Menu, MenuItem, usePopupState } from "@elementor/ui";
1201
+ import { bindMenu as bindMenu2, bindTrigger as bindTrigger2, IconButton as IconButton2, Menu as Menu2, MenuItem as MenuItem2, usePopupState } from "@elementor/ui";
650
1202
  var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
651
1203
  const menuState = usePopupState({
652
1204
  variant: "popover"
653
1205
  });
654
- return /* @__PURE__ */ React4.createElement(React4.Fragment, null, /* @__PURE__ */ React4.createElement(IconButton, { ...bindTrigger(menuState), disabled, size: "tiny" }, /* @__PURE__ */ React4.createElement(DotsVerticalIcon, { fontSize: "tiny" })), /* @__PURE__ */ React4.createElement(
655
- Menu,
1206
+ return /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(IconButton2, { ...bindTrigger2(menuState), disabled, size: "tiny" }, /* @__PURE__ */ React8.createElement(DotsVerticalIcon, { fontSize: "tiny" })), /* @__PURE__ */ React8.createElement(
1207
+ Menu2,
656
1208
  {
657
1209
  disablePortal: true,
658
1210
  MenuListProps: {
@@ -661,7 +1213,7 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
661
1213
  PaperProps: {
662
1214
  elevation: 6
663
1215
  },
664
- ...bindMenu(menuState),
1216
+ ...bindMenu2(menuState),
665
1217
  anchorEl: menuState.anchorEl,
666
1218
  anchorOrigin: {
667
1219
  vertical: "bottom",
@@ -674,8 +1226,8 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
674
1226
  open: menuState.isOpen,
675
1227
  onClose: menuState.close
676
1228
  },
677
- menuActions.map((action) => /* @__PURE__ */ React4.createElement(
678
- MenuItem,
1229
+ menuActions.map((action) => /* @__PURE__ */ React8.createElement(
1230
+ MenuItem2,
679
1231
  {
680
1232
  key: action.name,
681
1233
  onClick: () => {
@@ -687,7 +1239,7 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
687
1239
  gap: 1
688
1240
  }
689
1241
  },
690
- action.icon && createElement5(action.icon, {
1242
+ action.icon && createElement10(action.icon, {
691
1243
  fontSize: "inherit"
692
1244
  }),
693
1245
  " ",
@@ -696,77 +1248,8 @@ var VariableEditMenu = ({ menuActions, disabled, itemId }) => {
696
1248
  ));
697
1249
  };
698
1250
 
699
- // src/components/variables-manager/variable-editable-cell.tsx
700
- import * as React5 from "react";
701
- import { useState as useState2 } from "react";
702
- import { ClickAwayListener, Stack as Stack2 } from "@elementor/ui";
703
- var VariableEditableCell = ({
704
- initialValue,
705
- children,
706
- editableElement,
707
- onChange,
708
- prefixElement
709
- }) => {
710
- const [value, setValue] = useState2(initialValue);
711
- const [isEditing, setIsEditing] = useState2(false);
712
- const handleDoubleClick = () => {
713
- setIsEditing(true);
714
- };
715
- const handleSave = () => {
716
- onChange(value);
717
- setIsEditing(false);
718
- };
719
- const handleKeyDown = (event) => {
720
- if (event.key === "Enter") {
721
- handleSave();
722
- } else if (event.key === "Escape") {
723
- setIsEditing(false);
724
- }
725
- if (event.key === " " && !isEditing) {
726
- event.preventDefault();
727
- setIsEditing(true);
728
- }
729
- };
730
- const handleChange = (newValue) => {
731
- setValue(newValue);
732
- };
733
- const editableContent = editableElement({ value, onChange: handleChange });
734
- if (isEditing) {
735
- return /* @__PURE__ */ React5.createElement(ClickAwayListener, { onClickAway: handleSave }, /* @__PURE__ */ React5.createElement(
736
- Stack2,
737
- {
738
- direction: "row",
739
- alignItems: "center",
740
- gap: 1,
741
- onDoubleClick: handleDoubleClick,
742
- onKeyDown: handleKeyDown,
743
- tabIndex: 0,
744
- role: "button",
745
- "aria-label": "Double click or press Space to edit"
746
- },
747
- prefixElement,
748
- editableContent
749
- ));
750
- }
751
- return /* @__PURE__ */ React5.createElement(
752
- Stack2,
753
- {
754
- direction: "row",
755
- alignItems: "center",
756
- gap: 1,
757
- onDoubleClick: handleDoubleClick,
758
- onKeyDown: handleKeyDown,
759
- tabIndex: 0,
760
- role: "button",
761
- "aria-label": "Double click or press Space to edit"
762
- },
763
- prefixElement,
764
- children
765
- );
766
- };
767
-
768
- // src/components/variables-manager/variable-table-cell.tsx
769
- import * as React6 from "react";
1251
+ // src/components/variables-manager/ui/variable-table-cell.tsx
1252
+ import * as React9 from "react";
770
1253
  import { TableCell } from "@elementor/ui";
771
1254
  var VariableTableCell = ({
772
1255
  children,
@@ -786,20 +1269,167 @@ var VariableTableCell = ({
786
1269
  ...width && { width },
787
1270
  ...sx
788
1271
  };
789
- return /* @__PURE__ */ React6.createElement(TableCell, { size: "small", padding: noPadding ? "none" : void 0, align, sx: baseSx }, children);
1272
+ return /* @__PURE__ */ React9.createElement(TableCell, { size: "small", padding: noPadding ? "none" : void 0, align, sx: baseSx }, children);
790
1273
  };
791
1274
 
1275
+ // src/components/variables-manager/variable-editable-cell.tsx
1276
+ import * as React10 from "react";
1277
+ import { useCallback as useCallback4, useEffect, useRef as useRef4, useState as useState4 } from "react";
1278
+ import { ClickAwayListener, Stack as Stack4 } from "@elementor/ui";
1279
+ var VariableEditableCell = React10.memo(
1280
+ ({
1281
+ initialValue,
1282
+ children,
1283
+ editableElement,
1284
+ onChange,
1285
+ prefixElement,
1286
+ autoEdit = false,
1287
+ onRowRef,
1288
+ onAutoEditComplete,
1289
+ gap = 1,
1290
+ fieldType
1291
+ }) => {
1292
+ const [value, setValue] = useState4(initialValue);
1293
+ const [isEditing, setIsEditing] = useState4(false);
1294
+ const { labelFieldError, setLabelFieldError } = useLabelError();
1295
+ const [valueFieldError, setValueFieldError] = useState4("");
1296
+ const rowRef = useRef4(null);
1297
+ const handleSave = useCallback4(() => {
1298
+ const hasError = fieldType === "label" && labelFieldError?.message || fieldType === "value" && valueFieldError;
1299
+ if (!hasError) {
1300
+ onChange(value);
1301
+ }
1302
+ setIsEditing(false);
1303
+ }, [value, onChange, fieldType, labelFieldError, valueFieldError]);
1304
+ useEffect(() => {
1305
+ onRowRef?.(rowRef?.current);
1306
+ }, [onRowRef]);
1307
+ useEffect(() => {
1308
+ if (autoEdit && !isEditing) {
1309
+ setIsEditing(true);
1310
+ onAutoEditComplete?.();
1311
+ }
1312
+ }, [autoEdit, isEditing, onAutoEditComplete]);
1313
+ const handleDoubleClick = () => {
1314
+ setIsEditing(true);
1315
+ };
1316
+ const handleKeyDown = (event) => {
1317
+ if (event.key === "Enter") {
1318
+ handleSave();
1319
+ } else if (event.key === "Escape") {
1320
+ setIsEditing(false);
1321
+ }
1322
+ if (event.key === " " && !isEditing) {
1323
+ event.preventDefault();
1324
+ setIsEditing(true);
1325
+ }
1326
+ };
1327
+ const handleChange = useCallback4((newValue) => {
1328
+ setValue(newValue);
1329
+ }, []);
1330
+ const handleValidationChange = useCallback4(
1331
+ (errorMsg) => {
1332
+ if (fieldType === "label") {
1333
+ setLabelFieldError({
1334
+ value,
1335
+ message: errorMsg
1336
+ });
1337
+ } else {
1338
+ setValueFieldError(errorMsg);
1339
+ }
1340
+ },
1341
+ [fieldType, value, setLabelFieldError, setValueFieldError]
1342
+ );
1343
+ let currentError;
1344
+ if (fieldType === "label") {
1345
+ currentError = labelFieldError;
1346
+ } else if (fieldType === "value") {
1347
+ currentError = { value, message: valueFieldError };
1348
+ }
1349
+ const editableContent = editableElement({
1350
+ value,
1351
+ onChange: handleChange,
1352
+ onValidationChange: handleValidationChange,
1353
+ error: currentError
1354
+ });
1355
+ if (isEditing) {
1356
+ return /* @__PURE__ */ React10.createElement(ClickAwayListener, { onClickAway: handleSave }, /* @__PURE__ */ React10.createElement(
1357
+ Stack4,
1358
+ {
1359
+ ref: rowRef,
1360
+ direction: "row",
1361
+ alignItems: "center",
1362
+ gap,
1363
+ onDoubleClick: handleDoubleClick,
1364
+ onKeyDown: handleKeyDown,
1365
+ tabIndex: 0,
1366
+ role: "button",
1367
+ "aria-label": "Double click or press Space to edit"
1368
+ },
1369
+ prefixElement,
1370
+ editableContent
1371
+ ));
1372
+ }
1373
+ return /* @__PURE__ */ React10.createElement(
1374
+ Stack4,
1375
+ {
1376
+ ref: rowRef,
1377
+ direction: "row",
1378
+ alignItems: "center",
1379
+ gap,
1380
+ onDoubleClick: handleDoubleClick,
1381
+ onKeyDown: handleKeyDown,
1382
+ tabIndex: 0,
1383
+ role: "button",
1384
+ "aria-label": "Double click or press Space to edit"
1385
+ },
1386
+ prefixElement,
1387
+ children
1388
+ );
1389
+ }
1390
+ );
1391
+
792
1392
  // src/components/variables-manager/variables-manager-table.tsx
793
- var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange }) => {
794
- const [ids, setIds] = useState3(Object.keys(variables));
1393
+ var VariablesManagerTable = ({
1394
+ menuActions,
1395
+ variables,
1396
+ onChange: handleOnChange,
1397
+ autoEditVariableId,
1398
+ onAutoEditComplete,
1399
+ onFieldError
1400
+ }) => {
1401
+ const tableContainerRef = useRef5(null);
1402
+ const variableRowRefs = useRef5(/* @__PURE__ */ new Map());
1403
+ useEffect2(() => {
1404
+ if (autoEditVariableId && tableContainerRef.current) {
1405
+ const rowElement = variableRowRefs.current.get(autoEditVariableId);
1406
+ if (rowElement) {
1407
+ setTimeout(() => {
1408
+ rowElement.scrollIntoView({
1409
+ behavior: "smooth",
1410
+ block: "center",
1411
+ inline: "nearest"
1412
+ });
1413
+ }, 100);
1414
+ }
1415
+ }
1416
+ }, [autoEditVariableId]);
1417
+ const handleRowRef = (id2) => (ref) => {
1418
+ if (ref) {
1419
+ variableRowRefs.current.set(id2, ref);
1420
+ } else {
1421
+ variableRowRefs.current.delete(id2);
1422
+ }
1423
+ };
1424
+ const ids = Object.keys(variables).sort(sortVariablesOrder(variables));
795
1425
  const rows = ids.filter((id2) => !variables[id2].deleted).map((id2) => {
796
1426
  const variable = variables[id2];
797
1427
  const variableType = getVariableType(variable.type);
798
1428
  return {
799
1429
  id: id2,
1430
+ type: variable.type,
800
1431
  name: variable.label,
801
1432
  value: variable.value,
802
- type: variable.type,
803
1433
  ...variableType
804
1434
  };
805
1435
  });
@@ -807,16 +1437,27 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
807
1437
  minWidth: 250,
808
1438
  tableLayout: "fixed"
809
1439
  };
810
- return /* @__PURE__ */ React7.createElement(TableContainer, { sx: { overflow: "initial" } }, /* @__PURE__ */ React7.createElement(Table, { sx: tableSX, "aria-label": "Variables manager list with drag and drop reordering", stickyHeader: true }, /* @__PURE__ */ React7.createElement(TableHead, null, /* @__PURE__ */ React7.createElement(TableRow, null, /* @__PURE__ */ React7.createElement(VariableTableCell, { isHeader: true, noPadding: true, width: 10, maxWidth: 10 }), /* @__PURE__ */ React7.createElement(VariableTableCell, { isHeader: true }, __4("Name", "elementor")), /* @__PURE__ */ React7.createElement(VariableTableCell, { isHeader: true }, __4("Value", "elementor")), /* @__PURE__ */ React7.createElement(VariableTableCell, { isHeader: true, noPadding: true, width: 16, maxWidth: 16 }))), /* @__PURE__ */ React7.createElement(TableBody, null, /* @__PURE__ */ React7.createElement(
1440
+ const handleReorder = (newIds) => {
1441
+ const updatedVariables = { ...variables };
1442
+ newIds.forEach((id2, index) => {
1443
+ const current = updatedVariables[id2];
1444
+ if (!current) {
1445
+ return;
1446
+ }
1447
+ updatedVariables[id2] = Object.assign({}, current, { order: index + 1 });
1448
+ });
1449
+ handleOnChange(updatedVariables);
1450
+ };
1451
+ return /* @__PURE__ */ React11.createElement(TableContainer, { ref: tableContainerRef, sx: { overflow: "initial" } }, /* @__PURE__ */ React11.createElement(Table, { sx: tableSX, "aria-label": "Variables manager list with drag and drop reordering", stickyHeader: true }, /* @__PURE__ */ React11.createElement(TableHead, null, /* @__PURE__ */ React11.createElement(TableRow, null, /* @__PURE__ */ React11.createElement(VariableTableCell, { isHeader: true, noPadding: true, width: 10, maxWidth: 10 }), /* @__PURE__ */ React11.createElement(VariableTableCell, { isHeader: true }, __8("Name", "elementor")), /* @__PURE__ */ React11.createElement(VariableTableCell, { isHeader: true }, __8("Value", "elementor")), /* @__PURE__ */ React11.createElement(VariableTableCell, { isHeader: true, noPadding: true, width: 16, maxWidth: 16 }))), /* @__PURE__ */ React11.createElement(TableBody, null, /* @__PURE__ */ React11.createElement(
811
1452
  UnstableSortableProvider,
812
1453
  {
813
1454
  value: ids,
814
- onChange: setIds,
1455
+ onChange: handleReorder,
815
1456
  variant: "static",
816
1457
  restrictAxis: true,
817
- dragOverlay: ({ children: dragOverlayChildren, ...dragOverlayProps }) => /* @__PURE__ */ React7.createElement(Table, { sx: tableSX, ...dragOverlayProps }, /* @__PURE__ */ React7.createElement(TableBody, null, dragOverlayChildren))
1458
+ dragOverlay: ({ children: dragOverlayChildren, ...dragOverlayProps }) => /* @__PURE__ */ React11.createElement(Table, { sx: tableSX, ...dragOverlayProps }, /* @__PURE__ */ React11.createElement(TableBody, null, dragOverlayChildren))
818
1459
  },
819
- rows.map((row) => /* @__PURE__ */ React7.createElement(
1460
+ rows.map((row) => /* @__PURE__ */ React11.createElement(
820
1461
  UnstableSortableItem,
821
1462
  {
822
1463
  key: row.id,
@@ -830,13 +1471,11 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
830
1471
  isDragged,
831
1472
  dropPosition,
832
1473
  setTriggerRef,
833
- isDragOverlay,
834
- isSorting,
835
- index
1474
+ isSorting
836
1475
  }) => {
837
1476
  const showIndicationBefore = showDropIndication && dropPosition === "before";
838
1477
  const showIndicationAfter = showDropIndication && dropPosition === "after";
839
- return /* @__PURE__ */ React7.createElement(
1478
+ return /* @__PURE__ */ React11.createElement(
840
1479
  TableRow,
841
1480
  {
842
1481
  ...itemProps,
@@ -864,11 +1503,10 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
864
1503
  }
865
1504
  }
866
1505
  },
867
- style: { ...itemStyle, ...triggerStyle },
868
- disableDivider: isDragOverlay || index === rows.length - 1
1506
+ style: { ...itemStyle, ...triggerStyle }
869
1507
  },
870
- /* @__PURE__ */ React7.createElement(VariableTableCell, { noPadding: true, width: 10, maxWidth: 10 }, /* @__PURE__ */ React7.createElement(
871
- IconButton2,
1508
+ /* @__PURE__ */ React11.createElement(VariableTableCell, { noPadding: true, width: 10, maxWidth: 10 }, /* @__PURE__ */ React11.createElement(
1509
+ IconButton3,
872
1510
  {
873
1511
  size: "small",
874
1512
  ref: setTriggerRef,
@@ -876,9 +1514,9 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
876
1514
  disabled: isSorting,
877
1515
  draggable: true
878
1516
  },
879
- /* @__PURE__ */ React7.createElement(GripVerticalIcon, { fontSize: "inherit" })
1517
+ /* @__PURE__ */ React11.createElement(GripVerticalIcon, { fontSize: "inherit" })
880
1518
  )),
881
- /* @__PURE__ */ React7.createElement(VariableTableCell, null, /* @__PURE__ */ React7.createElement(
1519
+ /* @__PURE__ */ React11.createElement(VariableTableCell, null, /* @__PURE__ */ React11.createElement(
882
1520
  VariableEditableCell,
883
1521
  {
884
1522
  initialValue: row.name,
@@ -890,19 +1528,36 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
890
1528
  });
891
1529
  }
892
1530
  },
893
- prefixElement: createElement9(row.icon, { fontSize: "inherit" }),
894
- editableElement: ({ value, onChange }) => /* @__PURE__ */ React7.createElement(
1531
+ prefixElement: createElement14(row.icon, { fontSize: "inherit" }),
1532
+ editableElement: ({
1533
+ value,
1534
+ onChange,
1535
+ onValidationChange,
1536
+ error
1537
+ }) => /* @__PURE__ */ React11.createElement(
895
1538
  LabelField,
896
1539
  {
897
1540
  id: "variable-label-" + row.id,
898
1541
  size: "tiny",
899
1542
  value,
900
1543
  onChange,
901
- focusOnShow: true
1544
+ onErrorChange: (errorMsg) => {
1545
+ onValidationChange?.(errorMsg);
1546
+ onFieldError?.(!!errorMsg);
1547
+ },
1548
+ error,
1549
+ focusOnShow: true,
1550
+ selectOnShow: autoEditVariableId === row.id,
1551
+ showWarningInfotip: true,
1552
+ variables
902
1553
  }
903
- )
1554
+ ),
1555
+ autoEdit: autoEditVariableId === row.id,
1556
+ onRowRef: handleRowRef(row.id),
1557
+ onAutoEditComplete: autoEditVariableId === row.id ? onAutoEditComplete : void 0,
1558
+ fieldType: "label"
904
1559
  },
905
- /* @__PURE__ */ React7.createElement(
1560
+ /* @__PURE__ */ React11.createElement(
906
1561
  EllipsisWithTooltip,
907
1562
  {
908
1563
  title: row.name,
@@ -911,7 +1566,7 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
911
1566
  row.name
912
1567
  )
913
1568
  )),
914
- /* @__PURE__ */ React7.createElement(VariableTableCell, null, /* @__PURE__ */ React7.createElement(
1569
+ /* @__PURE__ */ React11.createElement(VariableTableCell, null, /* @__PURE__ */ React11.createElement(
915
1570
  VariableEditableCell,
916
1571
  {
917
1572
  initialValue: row.value,
@@ -923,19 +1578,39 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
923
1578
  });
924
1579
  }
925
1580
  },
926
- editableElement: row.valueField
1581
+ editableElement: ({
1582
+ value,
1583
+ onChange,
1584
+ onValidationChange,
1585
+ error
1586
+ }) => row.valueField({
1587
+ value,
1588
+ onChange,
1589
+ onValidationChange: (errorMsg) => {
1590
+ onValidationChange?.(errorMsg);
1591
+ onFieldError?.(!!errorMsg);
1592
+ },
1593
+ error
1594
+ }),
1595
+ onRowRef: handleRowRef(row.id),
1596
+ gap: 0.25,
1597
+ fieldType: "value"
927
1598
  },
928
1599
  row.startIcon && row.startIcon({ value: row.value }),
929
- /* @__PURE__ */ React7.createElement(
1600
+ /* @__PURE__ */ React11.createElement(
930
1601
  EllipsisWithTooltip,
931
1602
  {
932
1603
  title: row.value,
933
- sx: { border: "4px solid transparent" }
1604
+ sx: {
1605
+ border: "4px solid transparent",
1606
+ lineHeight: "1",
1607
+ pt: 0.25
1608
+ }
934
1609
  },
935
1610
  row.value
936
1611
  )
937
1612
  )),
938
- /* @__PURE__ */ React7.createElement(
1613
+ /* @__PURE__ */ React11.createElement(
939
1614
  VariableTableCell,
940
1615
  {
941
1616
  align: "right",
@@ -944,7 +1619,7 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
944
1619
  maxWidth: 16,
945
1620
  sx: { paddingInlineEnd: 1 }
946
1621
  },
947
- /* @__PURE__ */ React7.createElement(Stack3, { role: "toolbar", direction: "row", justifyContent: "flex-end" }, /* @__PURE__ */ React7.createElement(
1622
+ /* @__PURE__ */ React11.createElement(Stack5, { role: "toolbar", direction: "row", justifyContent: "flex-end" }, /* @__PURE__ */ React11.createElement(
948
1623
  VariableEditMenu,
949
1624
  {
950
1625
  menuActions,
@@ -959,6 +1634,13 @@ var VariablesManagerTable = ({ menuActions, variables, onChange: handleOnChange
959
1634
  ))
960
1635
  ))));
961
1636
  };
1637
+ function sortVariablesOrder(variables) {
1638
+ return (a, b) => {
1639
+ const orderA = variables[a]?.order ?? Number.MAX_SAFE_INTEGER;
1640
+ const orderB = variables[b]?.order ?? Number.MAX_SAFE_INTEGER;
1641
+ return orderA - orderB;
1642
+ };
1643
+ }
962
1644
 
963
1645
  // src/components/variables-manager/variables-manager-panel.tsx
964
1646
  var id = "variables-manager";
@@ -971,39 +1653,134 @@ var { panel, usePanelActions } = createPanel({
971
1653
  },
972
1654
  onClose: () => {
973
1655
  changeEditMode("edit");
974
- }
1656
+ },
1657
+ isOpenPreviousElement: true
975
1658
  });
976
1659
  function VariablesManagerPanel() {
977
1660
  const { close: closePanel } = usePanelActions();
978
- const [isDirty, setIsDirty] = useState4(false);
979
- const [variables, setVariables] = useState4(getVariables(false));
980
- const [deletedVariables, setDeletedVariables] = useState4([]);
1661
+ const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
1662
+ const createMenuState = usePopupState2({
1663
+ variant: "popover"
1664
+ });
1665
+ const {
1666
+ variables,
1667
+ isDirty,
1668
+ searchValue,
1669
+ isSaveDisabled,
1670
+ handleOnChange,
1671
+ createVariable: createVariable2,
1672
+ handleDeleteVariable,
1673
+ handleSave,
1674
+ isSaving,
1675
+ handleSearch,
1676
+ setIsSaving,
1677
+ setIsSaveDisabled
1678
+ } = useVariablesManagerState();
1679
+ const { autoEditVariableId, startAutoEdit, handleAutoEditComplete } = useAutoEdit();
1680
+ const { createNavigationCallback, resetNavigation } = useErrorNavigation();
1681
+ const [deleteConfirmation, setDeleteConfirmation] = useState5(null);
1682
+ const [serverError, setServerError] = useState5(null);
981
1683
  usePreventUnload(isDirty);
1684
+ const handleClosePanel = () => {
1685
+ if (isDirty) {
1686
+ openSaveChangesDialog();
1687
+ return;
1688
+ }
1689
+ closePanel();
1690
+ };
1691
+ const handleCreateVariable = useCallback5(
1692
+ (type, defaultName, defaultValue) => {
1693
+ const newId = createVariable2(type, defaultName, defaultValue);
1694
+ if (newId) {
1695
+ startAutoEdit(newId);
1696
+ }
1697
+ },
1698
+ [createVariable2, startAutoEdit]
1699
+ );
1700
+ const handleSaveClick = async () => {
1701
+ try {
1702
+ setServerError(null);
1703
+ resetNavigation();
1704
+ const result = await handleSave();
1705
+ trackVariablesManagerEvent({ action: "saveChanges" });
1706
+ return result;
1707
+ } catch (error) {
1708
+ const mappedError = mapServerError(error);
1709
+ const duplicatedIds = mappedError?.action?.data?.duplicatedIds;
1710
+ if (mappedError && "label" === mappedError.field) {
1711
+ if (duplicatedIds && mappedError.action) {
1712
+ mappedError.action.callback = createNavigationCallback(duplicatedIds, startAutoEdit, () => {
1713
+ setIsSaveDisabled(false);
1714
+ });
1715
+ }
1716
+ setServerError(mappedError);
1717
+ setIsSaveDisabled(true);
1718
+ resetNavigation();
1719
+ }
1720
+ return { success: false, error: mappedError };
1721
+ } finally {
1722
+ setIsSaving(false);
1723
+ }
1724
+ };
1725
+ const handleDeleteVariableWithConfirmation = useCallback5(
1726
+ (itemId) => {
1727
+ handleDeleteVariable(itemId);
1728
+ setDeleteConfirmation(null);
1729
+ },
1730
+ [handleDeleteVariable]
1731
+ );
982
1732
  const menuActions = [
983
1733
  {
984
- name: __5("Delete", "elementor"),
1734
+ name: __9("Delete", "elementor"),
985
1735
  icon: TrashIcon,
986
1736
  color: "error.main",
987
1737
  onClick: (itemId) => {
988
- setDeletedVariables([...deletedVariables, itemId]);
989
- setVariables({ ...variables, [itemId]: { ...variables[itemId], deleted: true } });
990
- setIsDirty(true);
1738
+ const variable = variables[itemId];
1739
+ if (variable) {
1740
+ setDeleteConfirmation({ id: itemId, label: variable.label });
1741
+ const variableTypeOptions = getVariableType(variable.type);
1742
+ trackVariablesManagerEvent({ action: "delete", varType: variableTypeOptions?.variableType });
1743
+ }
991
1744
  }
992
1745
  }
993
1746
  ];
994
- const handleOnChange = (newVariables) => {
995
- setVariables(newVariables);
996
- setIsDirty(true);
997
- };
998
- return /* @__PURE__ */ React8.createElement(ThemeProvider, null, /* @__PURE__ */ React8.createElement(ErrorBoundary, { fallback: /* @__PURE__ */ React8.createElement(ErrorBoundaryFallback, null) }, /* @__PURE__ */ React8.createElement(Panel, null, /* @__PURE__ */ React8.createElement(PanelHeader, null, /* @__PURE__ */ React8.createElement(Stack4, { width: "100%", direction: "column", alignItems: "center" }, /* @__PURE__ */ React8.createElement(Stack4, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React8.createElement(Stack4, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React8.createElement(PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React8.createElement(ColorFilterIcon, { fontSize: "inherit" }), __5("Variable Manager", "elementor"))), /* @__PURE__ */ React8.createElement(
999
- CloseButton,
1747
+ const hasVariables = Object.values(variables).some((variable) => !variable.deleted);
1748
+ return /* @__PURE__ */ React12.createElement(ThemeProvider, null, /* @__PURE__ */ React12.createElement(Panel, null, /* @__PURE__ */ React12.createElement(
1749
+ PanelHeader,
1000
1750
  {
1001
- sx: { marginLeft: "auto" },
1002
- onClose: () => {
1003
- closePanel();
1751
+ sx: {
1752
+ height: "unset"
1004
1753
  }
1005
- }
1006
- )), /* @__PURE__ */ React8.createElement(Divider, { sx: { width: "100%" } }))), /* @__PURE__ */ React8.createElement(
1754
+ },
1755
+ /* @__PURE__ */ React12.createElement(Stack6, { width: "100%", direction: "column", alignItems: "center" }, /* @__PURE__ */ React12.createElement(Stack6, { p: 1, pl: 2, width: "100%", direction: "row", alignItems: "center" }, /* @__PURE__ */ React12.createElement(Stack6, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React12.createElement(PanelHeaderTitle, { sx: { display: "flex", alignItems: "center", gap: 0.5 } }, /* @__PURE__ */ React12.createElement(ColorFilterIcon, { fontSize: "inherit" }), __9("Variables Manager", "elementor"))), /* @__PURE__ */ React12.createElement(Stack6, { direction: "row", gap: 0.5, alignItems: "center" }, /* @__PURE__ */ React12.createElement(
1756
+ VariableManagerCreateMenu,
1757
+ {
1758
+ onCreate: handleCreateVariable,
1759
+ variables,
1760
+ menuState: createMenuState
1761
+ }
1762
+ ), /* @__PURE__ */ React12.createElement(
1763
+ CloseButton,
1764
+ {
1765
+ "aria-label": "Close",
1766
+ slotProps: { icon: { fontSize: SIZE } },
1767
+ onClick: () => {
1768
+ handleClosePanel();
1769
+ }
1770
+ }
1771
+ ))), /* @__PURE__ */ React12.createElement(Stack6, { width: "100%", direction: "row", gap: 1 }, /* @__PURE__ */ React12.createElement(
1772
+ SearchField,
1773
+ {
1774
+ sx: {
1775
+ display: "flex",
1776
+ flex: 1
1777
+ },
1778
+ placeholder: __9("Search", "elementor"),
1779
+ value: searchValue,
1780
+ onSearch: handleSearch
1781
+ }
1782
+ )), /* @__PURE__ */ React12.createElement(Divider, { sx: { width: "100%" } }))
1783
+ ), /* @__PURE__ */ React12.createElement(
1007
1784
  PanelBody,
1008
1785
  {
1009
1786
  sx: {
@@ -1012,20 +1789,116 @@ function VariablesManagerPanel() {
1012
1789
  height: "100%"
1013
1790
  }
1014
1791
  },
1015
- /* @__PURE__ */ React8.createElement(
1792
+ hasVariables && /* @__PURE__ */ React12.createElement(
1016
1793
  VariablesManagerTable,
1017
1794
  {
1018
1795
  menuActions,
1019
1796
  variables,
1020
- onChange: handleOnChange
1797
+ onChange: handleOnChange,
1798
+ autoEditVariableId,
1799
+ onAutoEditComplete: handleAutoEditComplete,
1800
+ onFieldError: setIsSaveDisabled
1021
1801
  }
1802
+ ),
1803
+ !hasVariables && searchValue && /* @__PURE__ */ React12.createElement(
1804
+ NoSearchResults,
1805
+ {
1806
+ searchValue,
1807
+ onClear: () => handleSearch(""),
1808
+ icon: /* @__PURE__ */ React12.createElement(ColorFilterIcon, { fontSize: "large" })
1809
+ }
1810
+ ),
1811
+ !hasVariables && !searchValue && /* @__PURE__ */ React12.createElement(
1812
+ EmptyState,
1813
+ {
1814
+ title: __9("Create your first variable", "elementor"),
1815
+ message: __9(
1816
+ "Variables are saved attributes that you can apply anywhere on your site.",
1817
+ "elementor"
1818
+ ),
1819
+ icon: /* @__PURE__ */ React12.createElement(ColorFilterIcon, { fontSize: "large" }),
1820
+ onAdd: createMenuState.open
1821
+ }
1822
+ )
1823
+ ), /* @__PURE__ */ React12.createElement(PanelFooter, null, /* @__PURE__ */ React12.createElement(
1824
+ Infotip,
1825
+ {
1826
+ placement: "right",
1827
+ open: !!serverError,
1828
+ content: serverError ? /* @__PURE__ */ React12.createElement(
1829
+ Alert,
1830
+ {
1831
+ severity: serverError.severity ?? "error",
1832
+ action: serverError.action?.label ? /* @__PURE__ */ React12.createElement(AlertAction, { onClick: serverError.action.callback }, serverError.action.label) : void 0,
1833
+ onClose: !serverError.action?.label ? () => {
1834
+ setServerError(null);
1835
+ setIsSaveDisabled(false);
1836
+ } : void 0,
1837
+ icon: serverError.IconComponent ? /* @__PURE__ */ React12.createElement(serverError.IconComponent, null) : /* @__PURE__ */ React12.createElement(AlertTriangleFilledIcon2, null)
1838
+ },
1839
+ /* @__PURE__ */ React12.createElement(AlertTitle, null, serverError.message),
1840
+ serverError.action?.message
1841
+ ) : null,
1842
+ arrow: false,
1843
+ slotProps: {
1844
+ popper: {
1845
+ modifiers: [
1846
+ {
1847
+ name: "offset",
1848
+ options: { offset: [-10, 10] }
1849
+ }
1850
+ ]
1851
+ }
1852
+ }
1853
+ },
1854
+ /* @__PURE__ */ React12.createElement(
1855
+ Button3,
1856
+ {
1857
+ fullWidth: true,
1858
+ size: "small",
1859
+ color: "global",
1860
+ variant: "contained",
1861
+ disabled: isSaveDisabled || !isDirty || isSaving,
1862
+ onClick: handleSaveClick,
1863
+ loading: isSaving
1864
+ },
1865
+ __9("Save changes", "elementor")
1022
1866
  )
1023
- ), /* @__PURE__ */ React8.createElement(PanelFooter, null, /* @__PURE__ */ React8.createElement(Button, { fullWidth: true, size: "small", color: "global", variant: "contained", disabled: !isDirty }, __5("Save changes", "elementor"))))));
1867
+ ))), deleteConfirmation && /* @__PURE__ */ React12.createElement(
1868
+ DeleteConfirmationDialog,
1869
+ {
1870
+ open: true,
1871
+ label: deleteConfirmation.label,
1872
+ onConfirm: () => handleDeleteVariableWithConfirmation(deleteConfirmation.id),
1873
+ closeDialog: () => setDeleteConfirmation(null)
1874
+ }
1875
+ ), isSaveChangesDialogOpen && /* @__PURE__ */ React12.createElement(SaveChangesDialog, null, /* @__PURE__ */ React12.createElement(SaveChangesDialog.Title, { onClose: closeSaveChangesDialog }, __9("You have unsaved changes", "elementor")), /* @__PURE__ */ React12.createElement(SaveChangesDialog.Content, null, /* @__PURE__ */ React12.createElement(SaveChangesDialog.ContentText, null, __9("To avoid losing your updates, save your changes before leaving.", "elementor"))), /* @__PURE__ */ React12.createElement(
1876
+ SaveChangesDialog.Actions,
1877
+ {
1878
+ actions: {
1879
+ discard: {
1880
+ label: __9("Discard", "elementor"),
1881
+ action: () => {
1882
+ closeSaveChangesDialog();
1883
+ closePanel();
1884
+ }
1885
+ },
1886
+ confirm: {
1887
+ label: __9("Save", "elementor"),
1888
+ action: async () => {
1889
+ const result = await handleSaveClick();
1890
+ closeSaveChangesDialog();
1891
+ if (result?.success) {
1892
+ closePanel();
1893
+ }
1894
+ }
1895
+ }
1896
+ }
1897
+ }
1898
+ )));
1024
1899
  }
1025
- var CloseButton = ({ onClose, ...props }) => /* @__PURE__ */ React8.createElement(IconButton3, { size: "small", color: "secondary", onClick: onClose, "aria-label": "Close", ...props }, /* @__PURE__ */ React8.createElement(XIcon, { fontSize: "small" }));
1026
- var ErrorBoundaryFallback = () => /* @__PURE__ */ React8.createElement(Box, { role: "alert", sx: { minHeight: "100%", p: 2 } }, /* @__PURE__ */ React8.createElement(Alert, { severity: "error", sx: { mb: 2, maxWidth: 400, textAlign: "center" } }, /* @__PURE__ */ React8.createElement("strong", null, __5("Something went wrong", "elementor"))));
1027
1900
  var usePreventUnload = (isDirty) => {
1028
- useEffect(() => {
1901
+ useEffect3(() => {
1029
1902
  const handleBeforeUnload = (event) => {
1030
1903
  if (isDirty) {
1031
1904
  event.preventDefault();
@@ -1039,15 +1912,15 @@ var usePreventUnload = (isDirty) => {
1039
1912
  };
1040
1913
 
1041
1914
  // src/controls/variable-control.tsx
1042
- import * as React32 from "react";
1915
+ import * as React31 from "react";
1043
1916
  import { useBoundProp as useBoundProp11 } from "@elementor/editor-controls";
1044
1917
 
1045
1918
  // src/components/ui/variable/assigned-variable.tsx
1046
- import { useId, useRef } from "react";
1047
- import * as React21 from "react";
1919
+ import { useId, useRef as useRef6 } from "react";
1920
+ import * as React22 from "react";
1048
1921
  import { useBoundProp as useBoundProp6 } from "@elementor/editor-controls";
1049
1922
  import { ColorFilterIcon as ColorFilterIcon3 } from "@elementor/icons";
1050
- import { bindPopover, bindTrigger as bindTrigger2, Box as Box5, Popover, usePopupState as usePopupState2 } from "@elementor/ui";
1923
+ import { bindPopover, bindTrigger as bindTrigger3, Box as Box4, Popover, usePopupState as usePopupState3 } from "@elementor/ui";
1051
1924
 
1052
1925
  // src/utils/unlink-variable.ts
1053
1926
  function transformValueBeforeUnlink(variable, propTypeKey) {
@@ -1066,96 +1939,91 @@ function createUnlinkHandler(variable, propTypeKey, setValue) {
1066
1939
  }
1067
1940
 
1068
1941
  // src/components/variable-selection-popover.tsx
1069
- import * as React19 from "react";
1070
- import { useState as useState10 } from "react";
1942
+ import * as React20 from "react";
1943
+ import { useState as useState11 } from "react";
1071
1944
  import { isExperimentActive } from "@elementor/editor-v1-adapters";
1072
1945
 
1073
1946
  // src/context/variable-selection-popover.context.tsx
1074
- import * as React9 from "react";
1075
- import { createContext as createContext2, useContext as useContext2, useState as useState5 } from "react";
1076
- import { Box as Box2 } from "@elementor/ui";
1947
+ import * as React13 from "react";
1948
+ import { createContext as createContext2, useContext as useContext2, useState as useState6 } from "react";
1949
+ import { Box } from "@elementor/ui";
1077
1950
  var PopoverContentRefContext = createContext2(null);
1078
1951
  var PopoverContentRefContextProvider = ({ children }) => {
1079
- const [anchorRef, setAnchorRef] = useState5(null);
1080
- return /* @__PURE__ */ React9.createElement(PopoverContentRefContext.Provider, { value: anchorRef }, /* @__PURE__ */ React9.createElement(Box2, { ref: setAnchorRef }, children));
1952
+ const [anchorRef, setAnchorRef] = useState6(null);
1953
+ return /* @__PURE__ */ React13.createElement(PopoverContentRefContext.Provider, { value: anchorRef }, /* @__PURE__ */ React13.createElement(Box, { ref: setAnchorRef }, children));
1081
1954
  };
1082
1955
  var usePopoverContentRef = () => {
1083
1956
  return useContext2(PopoverContentRefContext);
1084
1957
  };
1085
1958
 
1086
- // src/hooks/use-permissions.ts
1087
- import { useCurrentUserCapabilities } from "@elementor/editor-current-user";
1088
- var usePermissions = () => {
1089
- const { canUser } = useCurrentUserCapabilities();
1090
- return {
1091
- canAssign: () => canUser("edit_posts"),
1092
- canUnlink: () => canUser("edit_posts"),
1093
- canAdd: () => canUser("manage_options"),
1094
- canDelete: () => canUser("manage_options"),
1095
- canEdit: () => canUser("manage_options"),
1096
- canRestore: () => canUser("manage_options"),
1097
- canManageSettings: () => canUser("manage_options")
1098
- };
1099
- };
1100
-
1101
1959
  // src/components/variable-creation.tsx
1102
- import * as React11 from "react";
1103
- import { useState as useState6 } from "react";
1104
- import { PopoverContent, useBoundProp as useBoundProp3 } from "@elementor/editor-controls";
1960
+ import * as React15 from "react";
1961
+ import { useState as useState7 } from "react";
1962
+ import { PopoverContent, useBoundProp as useBoundProp4 } from "@elementor/editor-controls";
1105
1963
  import { PopoverBody } from "@elementor/editor-editing-panel";
1106
1964
  import { PopoverHeader } from "@elementor/editor-ui";
1107
1965
  import { ArrowLeftIcon } from "@elementor/icons";
1108
- import { Button as Button2, CardActions, Divider as Divider2, FormHelperText as FormHelperText2, IconButton as IconButton4, Typography as Typography2 } from "@elementor/ui";
1109
- import { __ as __6 } from "@wordpress/i18n";
1966
+ import { Button as Button4, CardActions, Divider as Divider2, FormHelperText as FormHelperText2, IconButton as IconButton4, Typography as Typography6 } from "@elementor/ui";
1967
+ import { __ as __10 } from "@wordpress/i18n";
1110
1968
 
1111
1969
  // src/hooks/use-initial-value.ts
1112
1970
  import { useBoundProp as useBoundProp2 } from "@elementor/editor-controls";
1113
1971
  var useInitialValue = () => {
1114
1972
  const { value: initial } = useBoundProp2();
1115
- const hasAssignedVariable2 = hasVariableType(initial?.$$type) && Boolean(initial?.value);
1116
- const variable = useVariable(hasAssignedVariable2 ? initial.value : "");
1117
- if (hasAssignedVariable2) {
1973
+ const hasAssignedVariable = hasVariableType(initial?.$$type) && Boolean(initial?.value);
1974
+ const variable = useVariable(hasAssignedVariable ? initial.value : "");
1975
+ if (hasAssignedVariable) {
1118
1976
  return variable ? variable.value : "";
1119
1977
  }
1120
1978
  return initial?.value ?? "";
1121
1979
  };
1122
1980
 
1123
- // src/utils/tracking.ts
1124
- var trackVariableEvent = ({ varType, controlPath, action }) => {
1125
- const extendedWindow = window;
1126
- const config = extendedWindow?.elementorCommon?.eventsManager?.config;
1127
- if (!config?.names?.variables?.[action]) {
1128
- return;
1981
+ // src/hooks/use-variable-bound-prop.ts
1982
+ import { useBoundProp as useBoundProp3 } from "@elementor/editor-controls";
1983
+ import { isTransformable } from "@elementor/editor-props";
1984
+ var useVariableBoundProp = () => {
1985
+ const { propTypeUtil } = useVariableType();
1986
+ const boundProp = useBoundProp3(propTypeUtil);
1987
+ return {
1988
+ ...boundProp,
1989
+ setVariableValue: (value) => resolveBoundPropAndSetValue(value, boundProp),
1990
+ variableId: boundProp.value ?? boundProp.placeholder
1991
+ };
1992
+ };
1993
+ var resolveBoundPropAndSetValue = (value, boundProp) => {
1994
+ const propValue = unwrapValue(boundProp.value);
1995
+ const placeholder = unwrapValue(boundProp.placeholder);
1996
+ const newValue = unwrapValue(value);
1997
+ if (!propValue && placeholder === newValue) {
1998
+ return boundProp.setValue(null);
1129
1999
  }
1130
- const name = config.names.variables[action];
1131
- extendedWindow.elementorCommon?.eventsManager?.dispatchEvent(name, {
1132
- location: config.locations.variables,
1133
- secondaryLocation: config.secondaryLocations.variablesPopover,
1134
- trigger: config.triggers.click,
1135
- var_type: varType,
1136
- control_path: controlPath,
1137
- action_type: name
1138
- });
2000
+ return boundProp.setValue(value);
2001
+ };
2002
+ var unwrapValue = (input) => {
2003
+ if (isTransformable(input)) {
2004
+ return input.value;
2005
+ }
2006
+ return input;
1139
2007
  };
1140
2008
 
1141
2009
  // src/components/ui/form-field.tsx
1142
- import * as React10 from "react";
2010
+ import * as React14 from "react";
1143
2011
  import { FormHelperText, FormLabel, Grid } from "@elementor/ui";
1144
2012
  var FormField = ({ id: id2, label, errorMsg, noticeMsg, children }) => {
1145
- return /* @__PURE__ */ React10.createElement(Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React10.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React10.createElement(FormLabel, { htmlFor: id2, size: "tiny" }, label)), /* @__PURE__ */ React10.createElement(Grid, { item: true, xs: 12 }, children, errorMsg && /* @__PURE__ */ React10.createElement(FormHelperText, { error: true }, errorMsg), noticeMsg && /* @__PURE__ */ React10.createElement(FormHelperText, null, noticeMsg)));
2013
+ return /* @__PURE__ */ React14.createElement(Grid, { container: true, gap: 0.75, alignItems: "center" }, /* @__PURE__ */ React14.createElement(Grid, { item: true, xs: 12 }, /* @__PURE__ */ React14.createElement(FormLabel, { htmlFor: id2, size: "tiny" }, label)), /* @__PURE__ */ React14.createElement(Grid, { item: true, xs: 12 }, children, errorMsg && /* @__PURE__ */ React14.createElement(FormHelperText, { error: true }, errorMsg), noticeMsg && /* @__PURE__ */ React14.createElement(FormHelperText, null, noticeMsg)));
1146
2014
  };
1147
2015
 
1148
2016
  // src/components/variable-creation.tsx
1149
- var SIZE = "tiny";
2017
+ var SIZE2 = "tiny";
1150
2018
  var VariableCreation = ({ onGoBack, onClose }) => {
1151
2019
  const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
1152
- const { setValue: setVariable, path } = useBoundProp3(propTypeUtil);
1153
- const { propType } = useBoundProp3();
2020
+ const { setVariableValue: setVariable, path } = useVariableBoundProp();
2021
+ const { propType } = useBoundProp4();
1154
2022
  const initialValue = useInitialValue();
1155
- const [value, setValue] = useState6(initialValue);
1156
- const [label, setLabel] = useState6("");
1157
- const [errorMessage, setErrorMessage] = useState6("");
1158
- const [valueFieldError, setValueFieldError] = useState6("");
2023
+ const [value, setValue] = useState7(initialValue);
2024
+ const [label, setLabel] = useState7("");
2025
+ const [errorMessage, setErrorMessage] = useState7("");
2026
+ const [valueFieldError, setValueFieldError] = useState7("");
1159
2027
  const { labelFieldError, setLabelFieldError } = useLabelError();
1160
2028
  const resetFields = () => {
1161
2029
  setValue("");
@@ -1206,22 +2074,22 @@ var VariableCreation = ({ onGoBack, onClose }) => {
1206
2074
  return !!errorMessage;
1207
2075
  };
1208
2076
  const isSubmitDisabled = hasEmptyFields() || hasErrors();
1209
- return /* @__PURE__ */ React11.createElement(PopoverBody, { height: "auto" }, /* @__PURE__ */ React11.createElement(
2077
+ return /* @__PURE__ */ React15.createElement(PopoverBody, { height: "auto" }, /* @__PURE__ */ React15.createElement(
1210
2078
  PopoverHeader,
1211
2079
  {
1212
- icon: /* @__PURE__ */ React11.createElement(React11.Fragment, null, onGoBack && /* @__PURE__ */ React11.createElement(IconButton4, { size: SIZE, "aria-label": __6("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React11.createElement(ArrowLeftIcon, { fontSize: SIZE })), /* @__PURE__ */ React11.createElement(VariableIcon, { fontSize: SIZE })),
1213
- title: __6("Create variable", "elementor"),
2080
+ icon: /* @__PURE__ */ React15.createElement(React15.Fragment, null, onGoBack && /* @__PURE__ */ React15.createElement(IconButton4, { size: SIZE2, "aria-label": __10("Go Back", "elementor"), onClick: onGoBack }, /* @__PURE__ */ React15.createElement(ArrowLeftIcon, { fontSize: SIZE2 })), /* @__PURE__ */ React15.createElement(VariableIcon, { fontSize: SIZE2 })),
2081
+ title: __10("Create variable", "elementor"),
1214
2082
  onClose: closePopover
1215
2083
  }
1216
- ), /* @__PURE__ */ React11.createElement(Divider2, null), /* @__PURE__ */ React11.createElement(PopoverContent, { p: 2 }, /* @__PURE__ */ React11.createElement(
2084
+ ), /* @__PURE__ */ React15.createElement(Divider2, null), /* @__PURE__ */ React15.createElement(PopoverContent, { p: 2 }, /* @__PURE__ */ React15.createElement(
1217
2085
  FormField,
1218
2086
  {
1219
2087
  id: "variable-label",
1220
- label: __6("Name", "elementor"),
2088
+ label: __10("Name", "elementor"),
1221
2089
  errorMsg: labelFieldError?.message,
1222
2090
  noticeMsg: labelHint(label)
1223
2091
  },
1224
- /* @__PURE__ */ React11.createElement(
2092
+ /* @__PURE__ */ React15.createElement(
1225
2093
  LabelField,
1226
2094
  {
1227
2095
  id: "variable-label",
@@ -1239,7 +2107,7 @@ var VariableCreation = ({ onGoBack, onClose }) => {
1239
2107
  }
1240
2108
  }
1241
2109
  )
1242
- ), /* @__PURE__ */ React11.createElement(FormField, { errorMsg: valueFieldError, label: __6("Value", "elementor") }, /* @__PURE__ */ React11.createElement(Typography2, { variant: "h5" }, /* @__PURE__ */ React11.createElement(
2110
+ ), /* @__PURE__ */ React15.createElement(FormField, { errorMsg: valueFieldError, label: __10("Value", "elementor") }, /* @__PURE__ */ React15.createElement(Typography6, { variant: "h5", id: "variable-value-wrapper" }, /* @__PURE__ */ React15.createElement(
1243
2111
  ValueField,
1244
2112
  {
1245
2113
  value,
@@ -1251,49 +2119,36 @@ var VariableCreation = ({ onGoBack, onClose }) => {
1251
2119
  onValidationChange: setValueFieldError,
1252
2120
  propType
1253
2121
  }
1254
- ))), errorMessage && /* @__PURE__ */ React11.createElement(FormHelperText2, { error: true }, errorMessage)), /* @__PURE__ */ React11.createElement(CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React11.createElement(Button2, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleCreateAndTrack }, __6("Create", "elementor"))));
1255
- };
1256
-
1257
- // src/components/variable-edit.tsx
1258
- import * as React14 from "react";
1259
- import { useEffect as useEffect2, useState as useState8 } from "react";
1260
- import { PopoverContent as PopoverContent2, useBoundProp as useBoundProp4 } from "@elementor/editor-controls";
1261
- import { useSuppressedMessage } from "@elementor/editor-current-user";
1262
- import { PopoverBody as PopoverBody2 } from "@elementor/editor-editing-panel";
1263
- import { PopoverHeader as PopoverHeader2 } from "@elementor/editor-ui";
1264
- import { ArrowLeftIcon as ArrowLeftIcon2, TrashIcon as TrashIcon2 } from "@elementor/icons";
1265
- import { Button as Button5, CardActions as CardActions2, Divider as Divider3, FormHelperText as FormHelperText3, IconButton as IconButton5, Typography as Typography5 } from "@elementor/ui";
1266
- import { __ as __9 } from "@wordpress/i18n";
1267
-
1268
- // src/components/ui/delete-confirmation-dialog.tsx
1269
- import * as React12 from "react";
1270
- import { AlertOctagonFilledIcon } from "@elementor/icons";
1271
- import {
1272
- Button as Button3,
1273
- Dialog,
1274
- DialogActions,
1275
- DialogContent,
1276
- DialogContentText,
1277
- DialogTitle,
1278
- Typography as Typography3
1279
- } from "@elementor/ui";
1280
- import { __ as __7 } from "@wordpress/i18n";
1281
- var TITLE_ID = "delete-variable-dialog";
1282
- var DeleteConfirmationDialog = ({
1283
- open,
1284
- label,
1285
- closeDialog,
1286
- onConfirm
1287
- }) => {
1288
- return /* @__PURE__ */ React12.createElement(Dialog, { open, onClose: closeDialog, "aria-labelledby": TITLE_ID, maxWidth: "xs" }, /* @__PURE__ */ React12.createElement(DialogTitle, { id: TITLE_ID, display: "flex", alignItems: "center", gap: 1, sx: { lineHeight: 1 } }, /* @__PURE__ */ React12.createElement(AlertOctagonFilledIcon, { color: "error" }), __7("Delete this variable?", "elementor")), /* @__PURE__ */ React12.createElement(DialogContent, null, /* @__PURE__ */ React12.createElement(DialogContentText, { variant: "body2", color: "textPrimary" }, __7("All elements using", "elementor"), "\xA0", /* @__PURE__ */ React12.createElement(Typography3, { variant: "subtitle2", component: "span", sx: { lineBreak: "anywhere" } }, label), "\xA0", __7("will keep their current values, but the variable itself will be removed.", "elementor"))), /* @__PURE__ */ React12.createElement(DialogActions, null, /* @__PURE__ */ React12.createElement(Button3, { color: "secondary", onClick: closeDialog }, __7("Not now", "elementor")), /* @__PURE__ */ React12.createElement(Button3, { variant: "contained", color: "error", onClick: onConfirm }, __7("Delete", "elementor"))));
2122
+ ))), errorMessage && /* @__PURE__ */ React15.createElement(FormHelperText2, { error: true }, errorMessage)), /* @__PURE__ */ React15.createElement(CardActions, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React15.createElement(
2123
+ Button4,
2124
+ {
2125
+ id: "create-variable-button",
2126
+ size: "small",
2127
+ variant: "contained",
2128
+ disabled: isSubmitDisabled,
2129
+ onClick: handleCreateAndTrack
2130
+ },
2131
+ __10("Create", "elementor")
2132
+ )));
1289
2133
  };
1290
2134
 
2135
+ // src/components/variable-edit.tsx
2136
+ import * as React17 from "react";
2137
+ import { useEffect as useEffect4, useState as useState9 } from "react";
2138
+ import { PopoverContent as PopoverContent2, useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
2139
+ import { useSuppressedMessage } from "@elementor/editor-current-user";
2140
+ import { PopoverBody as PopoverBody2 } from "@elementor/editor-editing-panel";
2141
+ import { PopoverHeader as PopoverHeader2 } from "@elementor/editor-ui";
2142
+ import { ArrowLeftIcon as ArrowLeftIcon2, TrashIcon as TrashIcon2 } from "@elementor/icons";
2143
+ import { Button as Button6, CardActions as CardActions2, Divider as Divider3, FormHelperText as FormHelperText3, IconButton as IconButton5, Tooltip, Typography as Typography8 } from "@elementor/ui";
2144
+ import { __ as __12 } from "@wordpress/i18n";
2145
+
1291
2146
  // src/components/ui/edit-confirmation-dialog.tsx
1292
- import * as React13 from "react";
1293
- import { useState as useState7 } from "react";
1294
- import { AlertTriangleFilledIcon } from "@elementor/icons";
2147
+ import * as React16 from "react";
2148
+ import { useState as useState8 } from "react";
2149
+ import { AlertTriangleFilledIcon as AlertTriangleFilledIcon3 } from "@elementor/icons";
1295
2150
  import {
1296
- Button as Button4,
2151
+ Button as Button5,
1297
2152
  Checkbox,
1298
2153
  Dialog as Dialog2,
1299
2154
  DialogActions as DialogActions2,
@@ -1301,29 +2156,29 @@ import {
1301
2156
  DialogContentText as DialogContentText2,
1302
2157
  DialogTitle as DialogTitle2,
1303
2158
  FormControlLabel,
1304
- Typography as Typography4
2159
+ Typography as Typography7
1305
2160
  } from "@elementor/ui";
1306
- import { __ as __8 } from "@wordpress/i18n";
2161
+ import { __ as __11 } from "@wordpress/i18n";
1307
2162
  var EDIT_CONFIRMATION_DIALOG_ID = "edit-confirmation-dialog";
1308
2163
  var EditConfirmationDialog = ({
1309
2164
  closeDialog,
1310
2165
  onConfirm,
1311
2166
  onSuppressMessage
1312
2167
  }) => {
1313
- const [dontShowAgain, setDontShowAgain] = useState7(false);
2168
+ const [dontShowAgain, setDontShowAgain] = useState8(false);
1314
2169
  const handleSave = () => {
1315
2170
  if (dontShowAgain) {
1316
2171
  onSuppressMessage?.();
1317
2172
  }
1318
2173
  onConfirm?.();
1319
2174
  };
1320
- return /* @__PURE__ */ React13.createElement(Dialog2, { open: true, onClose: closeDialog, maxWidth: "xs" }, /* @__PURE__ */ React13.createElement(DialogTitle2, { display: "flex", alignItems: "center", gap: 1 }, /* @__PURE__ */ React13.createElement(AlertTriangleFilledIcon, { color: "secondary" }), __8("Changes to variables go live right away.", "elementor")), /* @__PURE__ */ React13.createElement(DialogContent2, null, /* @__PURE__ */ React13.createElement(DialogContentText2, { variant: "body2", color: "textPrimary" }, __8(
2175
+ return /* @__PURE__ */ React16.createElement(Dialog2, { open: true, onClose: closeDialog, maxWidth: "xs" }, /* @__PURE__ */ React16.createElement(DialogTitle2, { display: "flex", alignItems: "center", gap: 1 }, /* @__PURE__ */ React16.createElement(AlertTriangleFilledIcon3, { color: "secondary" }), __11("Changes to variables go live right away.", "elementor")), /* @__PURE__ */ React16.createElement(DialogContent2, null, /* @__PURE__ */ React16.createElement(DialogContentText2, { variant: "body2", color: "textPrimary" }, __11(
1321
2176
  "Don't worry - all other changes you make will wait until you publish your site.",
1322
2177
  "elementor"
1323
- ))), /* @__PURE__ */ React13.createElement(DialogActions2, { sx: { justifyContent: "space-between", alignItems: "center" } }, /* @__PURE__ */ React13.createElement(
2178
+ ))), /* @__PURE__ */ React16.createElement(DialogActions2, { sx: { justifyContent: "space-between", alignItems: "center" } }, /* @__PURE__ */ React16.createElement(
1324
2179
  FormControlLabel,
1325
2180
  {
1326
- control: /* @__PURE__ */ React13.createElement(
2181
+ control: /* @__PURE__ */ React16.createElement(
1327
2182
  Checkbox,
1328
2183
  {
1329
2184
  checked: dontShowAgain,
@@ -1331,31 +2186,32 @@ var EditConfirmationDialog = ({
1331
2186
  size: "small"
1332
2187
  }
1333
2188
  ),
1334
- label: /* @__PURE__ */ React13.createElement(Typography4, { variant: "body2" }, __8("Don't show me again", "elementor"))
2189
+ label: /* @__PURE__ */ React16.createElement(Typography7, { variant: "body2" }, __11("Don't show me again", "elementor"))
1335
2190
  }
1336
- ), /* @__PURE__ */ React13.createElement("div", null, /* @__PURE__ */ React13.createElement(Button4, { color: "secondary", onClick: closeDialog }, __8("Keep editing", "elementor")), /* @__PURE__ */ React13.createElement(Button4, { variant: "contained", color: "secondary", onClick: handleSave, sx: { ml: 1 } }, __8("Save", "elementor")))));
2191
+ ), /* @__PURE__ */ React16.createElement("div", null, /* @__PURE__ */ React16.createElement(Button5, { color: "secondary", onClick: closeDialog }, __11("Keep editing", "elementor")), /* @__PURE__ */ React16.createElement(Button5, { variant: "contained", color: "secondary", onClick: handleSave, sx: { ml: 1 } }, __11("Save", "elementor")))));
1337
2192
  };
1338
2193
 
1339
2194
  // src/components/variable-edit.tsx
1340
- var SIZE2 = "tiny";
2195
+ var SIZE3 = "tiny";
2196
+ var DELETE_LABEL = __12("Delete variable", "elementor");
1341
2197
  var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1342
- const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
1343
- const { setValue: notifyBoundPropChange, value: assignedValue } = useBoundProp4(propTypeUtil);
1344
- const { propType } = useBoundProp4();
2198
+ const { icon: VariableIcon, valueField: ValueField, variableType } = useVariableType();
2199
+ const { setVariableValue: notifyBoundPropChange, variableId } = useVariableBoundProp();
2200
+ const { propType } = useBoundProp5();
1345
2201
  const [isMessageSuppressed, suppressMessage] = useSuppressedMessage(EDIT_CONFIRMATION_DIALOG_ID);
1346
- const [deleteConfirmation, setDeleteConfirmation] = useState8(false);
1347
- const [editConfirmation, setEditConfirmation] = useState8(false);
1348
- const [errorMessage, setErrorMessage] = useState8("");
1349
- const [valueFieldError, setValueFieldError] = useState8("");
2202
+ const [deleteConfirmation, setDeleteConfirmation] = useState9(false);
2203
+ const [editConfirmation, setEditConfirmation] = useState9(false);
2204
+ const [errorMessage, setErrorMessage] = useState9("");
2205
+ const [valueFieldError, setValueFieldError] = useState9("");
1350
2206
  const { labelFieldError, setLabelFieldError } = useLabelError();
1351
2207
  const variable = useVariable(editId);
1352
2208
  if (!variable) {
1353
2209
  throw new Error(`Global ${variableType} variable not found`);
1354
2210
  }
1355
2211
  const userPermissions = usePermissions();
1356
- const [value, setValue] = useState8(() => variable.value);
1357
- const [label, setLabel] = useState8(() => variable.label);
1358
- useEffect2(() => {
2212
+ const [value, setValue] = useState9(() => variable.value);
2213
+ const [label, setLabel] = useState9(() => variable.label);
2214
+ useEffect4(() => {
1359
2215
  styleVariablesRepository.update({
1360
2216
  [editId]: {
1361
2217
  ...variable,
@@ -1402,7 +2258,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1402
2258
  });
1403
2259
  };
1404
2260
  const maybeTriggerBoundPropChange = () => {
1405
- if (editId === assignedValue) {
2261
+ if (editId === variableId) {
1406
2262
  notifyBoundPropChange(editId);
1407
2263
  }
1408
2264
  };
@@ -1418,16 +2274,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1418
2274
  const actions = [];
1419
2275
  if (userPermissions.canDelete()) {
1420
2276
  actions.push(
1421
- /* @__PURE__ */ React14.createElement(
1422
- IconButton5,
1423
- {
1424
- key: "delete",
1425
- size: SIZE2,
1426
- "aria-label": __9("Delete", "elementor"),
1427
- onClick: handleDeleteConfirmation
1428
- },
1429
- /* @__PURE__ */ React14.createElement(TrashIcon2, { fontSize: SIZE2 })
1430
- )
2277
+ /* @__PURE__ */ React17.createElement(Tooltip, { key: "delete", placement: "top", title: DELETE_LABEL }, /* @__PURE__ */ React17.createElement(IconButton5, { size: SIZE3, onClick: handleDeleteConfirmation, "aria-label": DELETE_LABEL }, /* @__PURE__ */ React17.createElement(TrashIcon2, { fontSize: SIZE3 })))
1431
2278
  );
1432
2279
  }
1433
2280
  const hasEmptyFields = () => {
@@ -1446,31 +2293,31 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1446
2293
  return !!errorMessage;
1447
2294
  };
1448
2295
  const isSubmitDisabled = noValueChanged() || hasEmptyFields() || hasErrors();
1449
- return /* @__PURE__ */ React14.createElement(React14.Fragment, null, /* @__PURE__ */ React14.createElement(PopoverBody2, { height: "auto" }, /* @__PURE__ */ React14.createElement(
2296
+ return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(PopoverBody2, { height: "auto" }, /* @__PURE__ */ React17.createElement(
1450
2297
  PopoverHeader2,
1451
2298
  {
1452
- title: __9("Edit variable", "elementor"),
2299
+ title: __12("Edit variable", "elementor"),
1453
2300
  onClose,
1454
- icon: /* @__PURE__ */ React14.createElement(React14.Fragment, null, onGoBack && /* @__PURE__ */ React14.createElement(
2301
+ icon: /* @__PURE__ */ React17.createElement(React17.Fragment, null, onGoBack && /* @__PURE__ */ React17.createElement(
1455
2302
  IconButton5,
1456
2303
  {
1457
- size: SIZE2,
1458
- "aria-label": __9("Go Back", "elementor"),
2304
+ size: SIZE3,
2305
+ "aria-label": __12("Go Back", "elementor"),
1459
2306
  onClick: onGoBack
1460
2307
  },
1461
- /* @__PURE__ */ React14.createElement(ArrowLeftIcon2, { fontSize: SIZE2 })
1462
- ), /* @__PURE__ */ React14.createElement(VariableIcon, { fontSize: SIZE2 })),
2308
+ /* @__PURE__ */ React17.createElement(ArrowLeftIcon2, { fontSize: SIZE3 })
2309
+ ), /* @__PURE__ */ React17.createElement(VariableIcon, { fontSize: SIZE3 })),
1463
2310
  actions
1464
2311
  }
1465
- ), /* @__PURE__ */ React14.createElement(Divider3, null), /* @__PURE__ */ React14.createElement(PopoverContent2, { p: 2 }, /* @__PURE__ */ React14.createElement(
2312
+ ), /* @__PURE__ */ React17.createElement(Divider3, null), /* @__PURE__ */ React17.createElement(PopoverContent2, { p: 2 }, /* @__PURE__ */ React17.createElement(
1466
2313
  FormField,
1467
2314
  {
1468
2315
  id: "variable-label",
1469
- label: __9("Name", "elementor"),
2316
+ label: __12("Name", "elementor"),
1470
2317
  errorMsg: labelFieldError?.message,
1471
2318
  noticeMsg: labelHint(label)
1472
2319
  },
1473
- /* @__PURE__ */ React14.createElement(
2320
+ /* @__PURE__ */ React17.createElement(
1474
2321
  LabelField,
1475
2322
  {
1476
2323
  id: "variable-label",
@@ -1488,7 +2335,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1488
2335
  }
1489
2336
  }
1490
2337
  )
1491
- ), /* @__PURE__ */ React14.createElement(FormField, { errorMsg: valueFieldError, label: __9("Value", "elementor") }, /* @__PURE__ */ React14.createElement(Typography5, { variant: "h5" }, /* @__PURE__ */ React14.createElement(
2338
+ ), /* @__PURE__ */ React17.createElement(FormField, { errorMsg: valueFieldError, label: __12("Value", "elementor") }, /* @__PURE__ */ React17.createElement(Typography8, { variant: "h5" }, /* @__PURE__ */ React17.createElement(
1492
2339
  ValueField,
1493
2340
  {
1494
2341
  value,
@@ -1500,7 +2347,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1500
2347
  onValidationChange: setValueFieldError,
1501
2348
  propType
1502
2349
  }
1503
- ))), errorMessage && /* @__PURE__ */ React14.createElement(FormHelperText3, { error: true }, errorMessage)), /* @__PURE__ */ React14.createElement(CardActions2, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React14.createElement(Button5, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleUpdate }, __9("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ React14.createElement(
2350
+ ))), errorMessage && /* @__PURE__ */ React17.createElement(FormHelperText3, { error: true }, errorMessage)), /* @__PURE__ */ React17.createElement(CardActions2, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React17.createElement(Button6, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleUpdate }, __12("Save", "elementor")))), deleteConfirmation && /* @__PURE__ */ React17.createElement(
1504
2351
  DeleteConfirmationDialog,
1505
2352
  {
1506
2353
  open: true,
@@ -1508,7 +2355,7 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1508
2355
  onConfirm: handleDelete,
1509
2356
  closeDialog: closeDeleteDialog()
1510
2357
  }
1511
- ), editConfirmation && !isMessageSuppressed && /* @__PURE__ */ React14.createElement(
2358
+ ), editConfirmation && !isMessageSuppressed && /* @__PURE__ */ React17.createElement(
1512
2359
  EditConfirmationDialog,
1513
2360
  {
1514
2361
  closeDialog: closeEditDialog(),
@@ -1519,26 +2366,26 @@ var VariableEdit = ({ onClose, onGoBack, onSubmit, editId }) => {
1519
2366
  };
1520
2367
 
1521
2368
  // src/components/variables-selection.tsx
1522
- import * as React18 from "react";
1523
- import { useState as useState9 } from "react";
1524
- import { useBoundProp as useBoundProp5 } from "@elementor/editor-controls";
2369
+ import * as React19 from "react";
2370
+ import { useState as useState10 } from "react";
1525
2371
  import { PopoverBody as PopoverBody3 } from "@elementor/editor-editing-panel";
1526
- import { PopoverHeader as PopoverHeader3, PopoverMenuList, PopoverSearch } from "@elementor/editor-ui";
1527
- import { ColorFilterIcon as ColorFilterIcon2, PlusIcon, SettingsIcon } from "@elementor/icons";
1528
- import { Divider as Divider4, IconButton as IconButton7 } from "@elementor/ui";
1529
- import { __ as __13, sprintf } from "@wordpress/i18n";
2372
+ import { PopoverHeader as PopoverHeader3, PopoverMenuList, SearchField as SearchField2 } from "@elementor/editor-ui";
2373
+ import { ColorFilterIcon as ColorFilterIcon2, PlusIcon as PlusIcon2, SettingsIcon } from "@elementor/icons";
2374
+ import { Divider as Divider4, IconButton as IconButton7, Tooltip as Tooltip3 } from "@elementor/ui";
2375
+ import { __ as __14, sprintf as sprintf2 } from "@wordpress/i18n";
1530
2376
 
1531
2377
  // src/components/ui/menu-item-content.tsx
1532
- import * as React15 from "react";
2378
+ import * as React18 from "react";
1533
2379
  import { EllipsisWithTooltip as EllipsisWithTooltip2 } from "@elementor/editor-ui";
1534
2380
  import { EditIcon } from "@elementor/icons";
1535
- import { Box as Box3, IconButton as IconButton6, ListItemIcon, Typography as Typography6 } from "@elementor/ui";
1536
- import { __ as __10 } from "@wordpress/i18n";
1537
- var SIZE3 = "tiny";
2381
+ import { Box as Box2, IconButton as IconButton6, ListItemIcon, Tooltip as Tooltip2, Typography as Typography9 } from "@elementor/ui";
2382
+ import { __ as __13 } from "@wordpress/i18n";
2383
+ var SIZE4 = "tiny";
2384
+ var EDIT_LABEL = __13("Edit variable", "elementor");
1538
2385
  var MenuItemContent = ({ item }) => {
1539
2386
  const onEdit = item.onEdit;
1540
- return /* @__PURE__ */ React15.createElement(React15.Fragment, null, /* @__PURE__ */ React15.createElement(ListItemIcon, null, item.icon), /* @__PURE__ */ React15.createElement(
1541
- Box3,
2387
+ return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement(ListItemIcon, null, item.icon), /* @__PURE__ */ React18.createElement(
2388
+ Box2,
1542
2389
  {
1543
2390
  sx: {
1544
2391
  flex: 1,
@@ -1548,29 +2395,29 @@ var MenuItemContent = ({ item }) => {
1548
2395
  gap: 1
1549
2396
  }
1550
2397
  },
1551
- /* @__PURE__ */ React15.createElement(
2398
+ /* @__PURE__ */ React18.createElement(
1552
2399
  EllipsisWithTooltip2,
1553
2400
  {
1554
2401
  title: item.label || item.value,
1555
- as: Typography6,
2402
+ as: Typography9,
1556
2403
  variant: "caption",
1557
2404
  color: "text.primary",
1558
2405
  sx: { marginTop: "1px", lineHeight: "2" },
1559
2406
  maxWidth: "50%"
1560
2407
  }
1561
2408
  ),
1562
- item.secondaryText && /* @__PURE__ */ React15.createElement(
2409
+ item.secondaryText && /* @__PURE__ */ React18.createElement(
1563
2410
  EllipsisWithTooltip2,
1564
2411
  {
1565
2412
  title: item.secondaryText,
1566
- as: Typography6,
2413
+ as: Typography9,
1567
2414
  variant: "caption",
1568
2415
  color: "text.tertiary",
1569
2416
  sx: { marginTop: "1px", lineHeight: "1" },
1570
2417
  maxWidth: "50%"
1571
2418
  }
1572
2419
  )
1573
- ), !!onEdit && /* @__PURE__ */ React15.createElement(
2420
+ ), !!onEdit && /* @__PURE__ */ React18.createElement(Tooltip2, { placement: "top", title: EDIT_LABEL }, /* @__PURE__ */ React18.createElement(
1574
2421
  IconButton6,
1575
2422
  {
1576
2423
  sx: { mx: 1, opacity: "0" },
@@ -1578,72 +2425,11 @@ var MenuItemContent = ({ item }) => {
1578
2425
  e.stopPropagation();
1579
2426
  onEdit(item.value);
1580
2427
  },
1581
- "aria-label": __10("Edit", "elementor")
1582
- },
1583
- /* @__PURE__ */ React15.createElement(EditIcon, { color: "action", fontSize: SIZE3 })
1584
- ));
1585
- };
1586
-
1587
- // src/components/ui/no-search-results.tsx
1588
- import * as React16 from "react";
1589
- import { Link, Stack as Stack5, Typography as Typography7 } from "@elementor/ui";
1590
- import { __ as __11 } from "@wordpress/i18n";
1591
- var NoSearchResults = ({ searchValue, onClear, icon }) => {
1592
- return /* @__PURE__ */ React16.createElement(
1593
- Stack5,
1594
- {
1595
- gap: 1,
1596
- alignItems: "center",
1597
- justifyContent: "center",
1598
- height: "100%",
1599
- p: 2.5,
1600
- color: "text.secondary",
1601
- sx: { pb: 3.5 }
1602
- },
1603
- icon,
1604
- /* @__PURE__ */ React16.createElement(Typography7, { align: "center", variant: "subtitle2" }, __11("Sorry, nothing matched", "elementor"), /* @__PURE__ */ React16.createElement("br", null), "\u201C", searchValue, "\u201D."),
1605
- /* @__PURE__ */ React16.createElement(Typography7, { align: "center", variant: "caption", sx: { display: "flex", flexDirection: "column" } }, __11("Try something else.", "elementor"), /* @__PURE__ */ React16.createElement(Link, { color: "text.secondary", variant: "caption", component: "button", onClick: onClear }, __11("Clear & try again", "elementor")))
1606
- );
1607
- };
1608
-
1609
- // src/components/ui/no-variables.tsx
1610
- import * as React17 from "react";
1611
- import { Button as Button6, Stack as Stack6, Typography as Typography8 } from "@elementor/ui";
1612
- import { __ as __12 } from "@wordpress/i18n";
1613
- var NoVariables = ({ icon, title, onAdd }) => {
1614
- const canAdd = usePermissions().canAdd();
1615
- return /* @__PURE__ */ React17.createElement(
1616
- Stack6,
1617
- {
1618
- gap: 1,
1619
- alignItems: "center",
1620
- justifyContent: "center",
1621
- height: "100%",
1622
- color: "text.secondary",
1623
- sx: { p: 2.5, pb: 5.5 }
2428
+ "aria-label": EDIT_LABEL
1624
2429
  },
1625
- icon,
1626
- canAdd ? /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(
1627
- NoVariablesContent,
1628
- {
1629
- title: title || __12("Create your first variable", "elementor"),
1630
- message: __12(
1631
- "Variables are saved attributes that you can apply anywhere on your site.",
1632
- "elementor"
1633
- )
1634
- }
1635
- ), onAdd && /* @__PURE__ */ React17.createElement(Button6, { variant: "outlined", color: "secondary", size: "small", onClick: onAdd }, __12("Create a variable", "elementor"))) : /* @__PURE__ */ React17.createElement(
1636
- NoVariablesContent,
1637
- {
1638
- title: __12("There are no variables", "elementor"),
1639
- message: __12("With your current role, you can only connect and detach variables.", "elementor")
1640
- }
1641
- )
1642
- );
2430
+ /* @__PURE__ */ React18.createElement(EditIcon, { color: "action", fontSize: SIZE4 })
2431
+ )));
1643
2432
  };
1644
- function NoVariablesContent({ title, message }) {
1645
- return /* @__PURE__ */ React17.createElement(React17.Fragment, null, /* @__PURE__ */ React17.createElement(Typography8, { align: "center", variant: "subtitle2" }, title), /* @__PURE__ */ React17.createElement(Typography8, { align: "center", variant: "caption", maxWidth: "180px" }, message));
1646
- }
1647
2433
 
1648
2434
  // src/components/ui/styled-menu-list.tsx
1649
2435
  import { MenuList, styled as styled2 } from "@elementor/ui";
@@ -1678,15 +2464,18 @@ var VariablesStyledMenuList = styled2(MenuList)(({ theme }) => ({
1678
2464
  }));
1679
2465
 
1680
2466
  // src/components/variables-selection.tsx
1681
- var SIZE4 = "tiny";
2467
+ var SIZE5 = "tiny";
2468
+ var CREATE_LABEL = __14("Create variable", "elementor");
2469
+ var MANAGER_LABEL = __14("Variables Manager", "elementor");
1682
2470
  var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1683
2471
  const { icon: VariableIcon, startIcon, variableType, propTypeUtil } = useVariableType();
1684
- const { value: variable, setValue: setVariable, path } = useBoundProp5(propTypeUtil);
1685
- const [searchValue, setSearchValue] = useState9("");
2472
+ const { value: variable, setValue: setVariable, path } = useVariableBoundProp();
2473
+ const [searchValue, setSearchValue] = useState10("");
1686
2474
  const {
1687
2475
  list: variables,
1688
2476
  hasMatches: hasSearchResults,
1689
- isSourceNotEmpty: hasVariables
2477
+ isSourceNotEmpty: hasVariables,
2478
+ hasNoCompatibleVariables
1690
2479
  } = useFilteredVariables(searchValue, propTypeUtil.key);
1691
2480
  const handleSetVariable = (key) => {
1692
2481
  setVariable(key);
@@ -1708,20 +2497,46 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1708
2497
  const actions = [];
1709
2498
  if (onAdd) {
1710
2499
  actions.push(
1711
- /* @__PURE__ */ React18.createElement(IconButton7, { key: "add", size: SIZE4, onClick: onAddAndTrack }, /* @__PURE__ */ React18.createElement(PlusIcon, { fontSize: SIZE4 }))
2500
+ /* @__PURE__ */ React19.createElement(Tooltip3, { key: "add", placement: "top", title: CREATE_LABEL }, /* @__PURE__ */ React19.createElement(
2501
+ IconButton7,
2502
+ {
2503
+ id: "add-variable-button",
2504
+ size: SIZE5,
2505
+ onClick: onAddAndTrack,
2506
+ "aria-label": CREATE_LABEL
2507
+ },
2508
+ /* @__PURE__ */ React19.createElement(PlusIcon2, { fontSize: SIZE5 })
2509
+ ))
1712
2510
  );
1713
2511
  }
1714
2512
  if (onSettings) {
2513
+ const handleOpenManager = () => {
2514
+ onSettings();
2515
+ trackVariablesManagerEvent({
2516
+ action: "openManager",
2517
+ varType: variableType,
2518
+ controlPath: path.join(".")
2519
+ });
2520
+ };
1715
2521
  actions.push(
1716
- /* @__PURE__ */ React18.createElement(IconButton7, { key: "settings", size: SIZE4, onClick: onSettings }, /* @__PURE__ */ React18.createElement(SettingsIcon, { fontSize: SIZE4 }))
2522
+ /* @__PURE__ */ React19.createElement(Tooltip3, { key: "settings", placement: "top", title: MANAGER_LABEL }, /* @__PURE__ */ React19.createElement(
2523
+ IconButton7,
2524
+ {
2525
+ id: "variables-manager-button",
2526
+ size: SIZE5,
2527
+ onClick: handleOpenManager,
2528
+ "aria-label": MANAGER_LABEL
2529
+ },
2530
+ /* @__PURE__ */ React19.createElement(SettingsIcon, { fontSize: SIZE5 })
2531
+ ))
1717
2532
  );
1718
2533
  }
1719
- const StartIcon = startIcon || (() => /* @__PURE__ */ React18.createElement(VariableIcon, { fontSize: SIZE4 }));
2534
+ const StartIcon = startIcon || (() => /* @__PURE__ */ React19.createElement(VariableIcon, { fontSize: SIZE5 }));
1720
2535
  const items = variables.map(({ value, label, key }) => ({
1721
2536
  type: "item",
1722
2537
  value: key,
1723
2538
  label,
1724
- icon: /* @__PURE__ */ React18.createElement(StartIcon, { value }),
2539
+ icon: /* @__PURE__ */ React19.createElement(StartIcon, { value }),
1725
2540
  secondaryText: value,
1726
2541
  onEdit: onEdit ? () => onEdit?.(key) : void 0
1727
2542
  }));
@@ -1731,27 +2546,27 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1731
2546
  const handleClearSearch = () => {
1732
2547
  setSearchValue("");
1733
2548
  };
1734
- const noVariableTitle = sprintf(
2549
+ const noVariableTitle = sprintf2(
1735
2550
  /* translators: %s: Variable Type. */
1736
- __13("Create your first %s variable", "elementor"),
2551
+ __14("Create your first %s variable", "elementor"),
1737
2552
  variableType
1738
2553
  );
1739
- return /* @__PURE__ */ React18.createElement(PopoverBody3, null, /* @__PURE__ */ React18.createElement(
2554
+ return /* @__PURE__ */ React19.createElement(PopoverBody3, null, /* @__PURE__ */ React19.createElement(
1740
2555
  PopoverHeader3,
1741
2556
  {
1742
- title: __13("Variables", "elementor"),
1743
- icon: /* @__PURE__ */ React18.createElement(ColorFilterIcon2, { fontSize: SIZE4 }),
2557
+ title: __14("Variables", "elementor"),
2558
+ icon: /* @__PURE__ */ React19.createElement(ColorFilterIcon2, { fontSize: SIZE5 }),
1744
2559
  onClose: closePopover,
1745
2560
  actions
1746
2561
  }
1747
- ), hasVariables && /* @__PURE__ */ React18.createElement(
1748
- PopoverSearch,
2562
+ ), hasVariables && /* @__PURE__ */ React19.createElement(
2563
+ SearchField2,
1749
2564
  {
1750
2565
  value: searchValue,
1751
2566
  onSearch: handleSearch,
1752
- placeholder: __13("Search", "elementor")
2567
+ placeholder: __14("Search", "elementor")
1753
2568
  }
1754
- ), /* @__PURE__ */ React18.createElement(Divider4, null), hasVariables && hasSearchResults && /* @__PURE__ */ React18.createElement(
2569
+ ), /* @__PURE__ */ React19.createElement(Divider4, null), hasVariables && hasSearchResults && /* @__PURE__ */ React19.createElement(
1755
2570
  PopoverMenuList,
1756
2571
  {
1757
2572
  items,
@@ -1761,16 +2576,38 @@ var VariablesSelection = ({ closePopover, onAdd, onEdit, onSettings }) => {
1761
2576
  selectedValue: variable,
1762
2577
  "data-testid": `${variableType}-variables-list`,
1763
2578
  menuListTemplate: VariablesStyledMenuList,
1764
- menuItemContentTemplate: (item) => /* @__PURE__ */ React18.createElement(MenuItemContent, { item })
2579
+ menuItemContentTemplate: (item) => /* @__PURE__ */ React19.createElement(MenuItemContent, { item })
1765
2580
  }
1766
- ), !hasSearchResults && hasVariables && /* @__PURE__ */ React18.createElement(
2581
+ ), !hasSearchResults && hasVariables && /* @__PURE__ */ React19.createElement(
1767
2582
  NoSearchResults,
1768
2583
  {
1769
2584
  searchValue,
1770
2585
  onClear: handleClearSearch,
1771
- icon: /* @__PURE__ */ React18.createElement(VariableIcon, { fontSize: "large" })
2586
+ icon: /* @__PURE__ */ React19.createElement(VariableIcon, { fontSize: "large" })
2587
+ }
2588
+ ), !hasVariables && !hasNoCompatibleVariables && /* @__PURE__ */ React19.createElement(
2589
+ EmptyState,
2590
+ {
2591
+ title: noVariableTitle,
2592
+ message: __14(
2593
+ "Variables are saved attributes that you can apply anywhere on your site.",
2594
+ "elementor"
2595
+ ),
2596
+ icon: /* @__PURE__ */ React19.createElement(VariableIcon, { fontSize: "large" }),
2597
+ onAdd
2598
+ }
2599
+ ), hasNoCompatibleVariables && /* @__PURE__ */ React19.createElement(
2600
+ EmptyState,
2601
+ {
2602
+ title: __14("No compatible variables", "elementor"),
2603
+ message: __14(
2604
+ "Looks like none of your variables work with this control. Create a new variable to use it here.",
2605
+ "elementor"
2606
+ ),
2607
+ icon: /* @__PURE__ */ React19.createElement(VariableIcon, { fontSize: "large" }),
2608
+ onAdd
1772
2609
  }
1773
- ), !hasVariables && /* @__PURE__ */ React18.createElement(NoVariables, { title: noVariableTitle, icon: /* @__PURE__ */ React18.createElement(VariableIcon, { fontSize: "large" }), onAdd }));
2610
+ ));
1774
2611
  };
1775
2612
 
1776
2613
  // src/components/variable-selection-popover.tsx
@@ -1778,13 +2615,13 @@ var VIEW_LIST = "list";
1778
2615
  var VIEW_ADD = "add";
1779
2616
  var VIEW_EDIT = "edit";
1780
2617
  var VariableSelectionPopover = ({ closePopover, propTypeKey, selectedVariable }) => {
1781
- const [currentView, setCurrentView] = useState10(VIEW_LIST);
1782
- const [editId, setEditId] = useState10("");
2618
+ const [currentView, setCurrentView] = useState11(VIEW_LIST);
2619
+ const [editId, setEditId] = useState11("");
1783
2620
  const { open } = usePanelActions();
1784
2621
  const onSettingsAvailable = isExperimentActive("e_variables_manager") ? () => {
1785
2622
  open();
1786
2623
  } : void 0;
1787
- return /* @__PURE__ */ React19.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ React19.createElement(PopoverContentRefContextProvider, null, RenderView({
2624
+ return /* @__PURE__ */ React20.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ React20.createElement(PopoverContentRefContextProvider, null, RenderView({
1788
2625
  propTypeKey,
1789
2626
  currentView,
1790
2627
  selectedVariable,
@@ -1830,7 +2667,7 @@ function RenderView(props) {
1830
2667
  }
1831
2668
  };
1832
2669
  if (VIEW_LIST === props.currentView) {
1833
- return /* @__PURE__ */ React19.createElement(
2670
+ return /* @__PURE__ */ React20.createElement(
1834
2671
  VariablesSelection,
1835
2672
  {
1836
2673
  closePopover: handlers.onClose,
@@ -1841,10 +2678,10 @@ function RenderView(props) {
1841
2678
  );
1842
2679
  }
1843
2680
  if (VIEW_ADD === props.currentView) {
1844
- return /* @__PURE__ */ React19.createElement(VariableCreation, { onGoBack: handlers.onGoBack, onClose: handlers.onClose });
2681
+ return /* @__PURE__ */ React20.createElement(VariableCreation, { onGoBack: handlers.onGoBack, onClose: handlers.onClose });
1845
2682
  }
1846
2683
  if (VIEW_EDIT === props.currentView) {
1847
- return /* @__PURE__ */ React19.createElement(
2684
+ return /* @__PURE__ */ React20.createElement(
1848
2685
  VariableEdit,
1849
2686
  {
1850
2687
  editId: props.editId,
@@ -1858,25 +2695,26 @@ function RenderView(props) {
1858
2695
  }
1859
2696
 
1860
2697
  // src/components/ui/tags/assigned-tag.tsx
1861
- import * as React20 from "react";
2698
+ import * as React21 from "react";
1862
2699
  import { DetachIcon } from "@elementor/icons";
1863
- import { Box as Box4, IconButton as IconButton8, Stack as Stack7, Tooltip, Typography as Typography9, UnstableTag as Tag } from "@elementor/ui";
1864
- import { __ as __14 } from "@wordpress/i18n";
1865
- var SIZE5 = "tiny";
2700
+ import { Box as Box3, IconButton as IconButton8, Stack as Stack7, Tooltip as Tooltip4, Typography as Typography10, UnstableTag as Tag } from "@elementor/ui";
2701
+ import { __ as __15 } from "@wordpress/i18n";
2702
+ var SIZE6 = "tiny";
2703
+ var UNLINK_LABEL = __15("Unlink variable", "elementor");
1866
2704
  var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
1867
2705
  const actions = [];
1868
2706
  if (onUnlink) {
1869
2707
  actions.push(
1870
- /* @__PURE__ */ React20.createElement(IconButton8, { key: "unlink", size: SIZE5, onClick: onUnlink, "aria-label": __14("Unlink", "elementor") }, /* @__PURE__ */ React20.createElement(DetachIcon, { fontSize: SIZE5 }))
2708
+ /* @__PURE__ */ React21.createElement(Tooltip4, { key: "unlink", title: UNLINK_LABEL, placement: "bottom" }, /* @__PURE__ */ React21.createElement(IconButton8, { size: SIZE6, onClick: onUnlink, "aria-label": UNLINK_LABEL }, /* @__PURE__ */ React21.createElement(DetachIcon, { fontSize: SIZE6 })))
1871
2709
  );
1872
2710
  }
1873
- return /* @__PURE__ */ React20.createElement(Tooltip, { title: label, placement: "top" }, /* @__PURE__ */ React20.createElement(
2711
+ return /* @__PURE__ */ React21.createElement(Tooltip4, { title: label, placement: "top" }, /* @__PURE__ */ React21.createElement(
1874
2712
  Tag,
1875
2713
  {
1876
2714
  fullWidth: true,
1877
2715
  showActionsOnHover: true,
1878
- startIcon: /* @__PURE__ */ React20.createElement(Stack7, { gap: 0.5, direction: "row", alignItems: "center" }, startIcon),
1879
- label: /* @__PURE__ */ React20.createElement(Box4, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React20.createElement(Typography9, { sx: { lineHeight: 1.34 }, variant: "caption", noWrap: true }, label)),
2716
+ startIcon: /* @__PURE__ */ React21.createElement(Stack7, { gap: 0.5, direction: "row", alignItems: "center" }, startIcon),
2717
+ label: /* @__PURE__ */ React21.createElement(Box3, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React21.createElement(Typography10, { sx: { lineHeight: 1.34 }, variant: "caption", noWrap: true }, label)),
1880
2718
  actions,
1881
2719
  ...props
1882
2720
  }
@@ -1887,23 +2725,23 @@ var AssignedTag = ({ startIcon, label, onUnlink, ...props }) => {
1887
2725
  var AssignedVariable = ({ variable, propTypeKey }) => {
1888
2726
  const { startIcon, propTypeUtil } = getVariableType(propTypeKey);
1889
2727
  const { setValue } = useBoundProp6();
1890
- const anchorRef = useRef(null);
2728
+ const anchorRef = useRef6(null);
1891
2729
  const popupId = useId();
1892
- const popupState = usePopupState2({
2730
+ const popupState = usePopupState3({
1893
2731
  variant: "popover",
1894
2732
  popupId: `elementor-variables-list-${popupId}`
1895
2733
  });
1896
2734
  const unlinkVariable = createUnlinkHandler(variable, propTypeKey, setValue);
1897
2735
  const StartIcon = startIcon || (() => null);
1898
- return /* @__PURE__ */ React21.createElement(Box5, { ref: anchorRef }, /* @__PURE__ */ React21.createElement(
2736
+ return /* @__PURE__ */ React22.createElement(Box4, { ref: anchorRef }, /* @__PURE__ */ React22.createElement(
1899
2737
  AssignedTag,
1900
2738
  {
1901
2739
  label: variable.label,
1902
- startIcon: /* @__PURE__ */ React21.createElement(React21.Fragment, null, /* @__PURE__ */ React21.createElement(ColorFilterIcon3, { fontSize: SIZE5 }), /* @__PURE__ */ React21.createElement(StartIcon, { value: variable.value })),
2740
+ startIcon: /* @__PURE__ */ React22.createElement(React22.Fragment, null, /* @__PURE__ */ React22.createElement(ColorFilterIcon3, { fontSize: SIZE6 }), /* @__PURE__ */ React22.createElement(StartIcon, { value: variable.value })),
1903
2741
  onUnlink: unlinkVariable,
1904
- ...bindTrigger2(popupState)
2742
+ ...bindTrigger3(popupState)
1905
2743
  }
1906
- ), /* @__PURE__ */ React21.createElement(
2744
+ ), /* @__PURE__ */ React22.createElement(
1907
2745
  Popover,
1908
2746
  {
1909
2747
  disableScrollLock: true,
@@ -1915,7 +2753,7 @@ var AssignedVariable = ({ variable, propTypeKey }) => {
1915
2753
  },
1916
2754
  ...bindPopover(popupState)
1917
2755
  },
1918
- /* @__PURE__ */ React21.createElement(
2756
+ /* @__PURE__ */ React22.createElement(
1919
2757
  VariableSelectionPopover,
1920
2758
  {
1921
2759
  selectedVariable: variable,
@@ -1927,32 +2765,33 @@ var AssignedVariable = ({ variable, propTypeKey }) => {
1927
2765
  };
1928
2766
 
1929
2767
  // src/components/ui/variable/deleted-variable.tsx
1930
- import * as React25 from "react";
1931
- import { useId as useId2, useRef as useRef2, useState as useState12 } from "react";
2768
+ import * as React26 from "react";
2769
+ import { useId as useId2, useRef as useRef7, useState as useState13 } from "react";
1932
2770
  import { useBoundProp as useBoundProp8 } from "@elementor/editor-controls";
1933
- import { Backdrop, bindPopover as bindPopover2, Box as Box7, Infotip, Popover as Popover2, usePopupState as usePopupState3 } from "@elementor/ui";
2771
+ import { Backdrop, bindPopover as bindPopover2, Box as Box6, Infotip as Infotip2, Popover as Popover2, usePopupState as usePopupState4 } from "@elementor/ui";
2772
+ import { __ as __18 } from "@wordpress/i18n";
1934
2773
 
1935
2774
  // src/components/variable-restore.tsx
1936
- import * as React22 from "react";
1937
- import { useState as useState11 } from "react";
2775
+ import * as React23 from "react";
2776
+ import { useState as useState12 } from "react";
1938
2777
  import { PopoverContent as PopoverContent3, useBoundProp as useBoundProp7 } from "@elementor/editor-controls";
1939
2778
  import { PopoverBody as PopoverBody4 } from "@elementor/editor-editing-panel";
1940
2779
  import { PopoverHeader as PopoverHeader4 } from "@elementor/editor-ui";
1941
- import { Button as Button7, CardActions as CardActions3, Divider as Divider5, FormHelperText as FormHelperText4, Typography as Typography10 } from "@elementor/ui";
1942
- import { __ as __15 } from "@wordpress/i18n";
1943
- var SIZE6 = "tiny";
2780
+ import { Button as Button7, CardActions as CardActions3, Divider as Divider5, FormHelperText as FormHelperText4, Typography as Typography11 } from "@elementor/ui";
2781
+ import { __ as __16 } from "@wordpress/i18n";
2782
+ var SIZE7 = "tiny";
1944
2783
  var VariableRestore = ({ variableId, onClose, onSubmit }) => {
1945
- const { icon: VariableIcon, valueField: ValueField, variableType, propTypeUtil } = useVariableType();
1946
- const { setValue: notifyBoundPropChange } = useBoundProp7(propTypeUtil);
2784
+ const { icon: VariableIcon, valueField: ValueField, variableType } = useVariableType();
2785
+ const { setVariableValue: notifyBoundPropChange } = useVariableBoundProp();
1947
2786
  const { propType } = useBoundProp7();
1948
2787
  const variable = useVariable(variableId);
1949
2788
  if (!variable) {
1950
2789
  throw new Error(`Global ${variableType} variable not found`);
1951
2790
  }
1952
- const [errorMessage, setErrorMessage] = useState11("");
1953
- const [valueFieldError, setValueFieldError] = useState11("");
1954
- const [label, setLabel] = useState11(variable.label);
1955
- const [value, setValue] = useState11(variable.value);
2791
+ const [errorMessage, setErrorMessage] = useState12("");
2792
+ const [valueFieldError, setValueFieldError] = useState12("");
2793
+ const [label, setLabel] = useState12(variable.label);
2794
+ const [value, setValue] = useState12(variable.value);
1956
2795
  const { labelFieldError, setLabelFieldError } = useLabelError({
1957
2796
  value: variable.label,
1958
2797
  message: ERROR_MESSAGES.DUPLICATED_LABEL
@@ -1990,22 +2829,22 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
1990
2829
  return !!errorMessage;
1991
2830
  };
1992
2831
  const isSubmitDisabled = noValueChanged() || hasEmptyFields() || hasErrors();
1993
- return /* @__PURE__ */ React22.createElement(PopoverContentRefContextProvider, null, /* @__PURE__ */ React22.createElement(PopoverBody4, { height: "auto" }, /* @__PURE__ */ React22.createElement(
2832
+ return /* @__PURE__ */ React23.createElement(PopoverContentRefContextProvider, null, /* @__PURE__ */ React23.createElement(PopoverBody4, { height: "auto" }, /* @__PURE__ */ React23.createElement(
1994
2833
  PopoverHeader4,
1995
2834
  {
1996
- icon: /* @__PURE__ */ React22.createElement(VariableIcon, { fontSize: SIZE6 }),
1997
- title: __15("Restore variable", "elementor"),
2835
+ icon: /* @__PURE__ */ React23.createElement(VariableIcon, { fontSize: SIZE7 }),
2836
+ title: __16("Restore variable", "elementor"),
1998
2837
  onClose
1999
2838
  }
2000
- ), /* @__PURE__ */ React22.createElement(Divider5, null), /* @__PURE__ */ React22.createElement(PopoverContent3, { p: 2 }, /* @__PURE__ */ React22.createElement(
2839
+ ), /* @__PURE__ */ React23.createElement(Divider5, null), /* @__PURE__ */ React23.createElement(PopoverContent3, { p: 2 }, /* @__PURE__ */ React23.createElement(
2001
2840
  FormField,
2002
2841
  {
2003
2842
  id: "variable-label",
2004
- label: __15("Name", "elementor"),
2843
+ label: __16("Name", "elementor"),
2005
2844
  errorMsg: labelFieldError?.message,
2006
2845
  noticeMsg: labelHint(label)
2007
2846
  },
2008
- /* @__PURE__ */ React22.createElement(
2847
+ /* @__PURE__ */ React23.createElement(
2009
2848
  LabelField,
2010
2849
  {
2011
2850
  id: "variable-label",
@@ -2023,7 +2862,7 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
2023
2862
  }
2024
2863
  }
2025
2864
  )
2026
- ), /* @__PURE__ */ React22.createElement(FormField, { errorMsg: valueFieldError, label: __15("Value", "elementor") }, /* @__PURE__ */ React22.createElement(Typography10, { variant: "h5" }, /* @__PURE__ */ React22.createElement(
2865
+ ), /* @__PURE__ */ React23.createElement(FormField, { errorMsg: valueFieldError, label: __16("Value", "elementor") }, /* @__PURE__ */ React23.createElement(Typography11, { variant: "h5" }, /* @__PURE__ */ React23.createElement(
2027
2866
  ValueField,
2028
2867
  {
2029
2868
  value,
@@ -2035,91 +2874,87 @@ var VariableRestore = ({ variableId, onClose, onSubmit }) => {
2035
2874
  onValidationChange: setValueFieldError,
2036
2875
  propType
2037
2876
  }
2038
- ))), errorMessage && /* @__PURE__ */ React22.createElement(FormHelperText4, { error: true }, errorMessage)), /* @__PURE__ */ React22.createElement(CardActions3, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React22.createElement(Button7, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleRestore }, __15("Restore", "elementor")))));
2877
+ ))), errorMessage && /* @__PURE__ */ React23.createElement(FormHelperText4, { error: true }, errorMessage)), /* @__PURE__ */ React23.createElement(CardActions3, { sx: { pt: 0.5, pb: 1 } }, /* @__PURE__ */ React23.createElement(Button7, { size: "small", variant: "contained", disabled: isSubmitDisabled, onClick: handleRestore }, __16("Restore", "elementor")))));
2039
2878
  };
2040
2879
 
2041
2880
  // src/components/ui/deleted-variable-alert.tsx
2042
- import * as React23 from "react";
2043
- import { useSectionWidth } from "@elementor/editor-editing-panel";
2044
- import { Alert as Alert2, AlertAction, AlertTitle, ClickAwayListener as ClickAwayListener2 } from "@elementor/ui";
2045
- import { __ as __16 } from "@wordpress/i18n";
2881
+ import * as React24 from "react";
2882
+ import { Alert as Alert2, AlertAction as AlertAction2, AlertTitle as AlertTitle2, ClickAwayListener as ClickAwayListener2, Typography as Typography12 } from "@elementor/ui";
2883
+ import { __ as __17 } from "@wordpress/i18n";
2046
2884
  var DeletedVariableAlert = ({ onClose, onUnlink, onRestore, label }) => {
2047
- const sectionWidth = useSectionWidth();
2048
- return /* @__PURE__ */ React23.createElement(ClickAwayListener2, { onClickAway: onClose }, /* @__PURE__ */ React23.createElement(
2885
+ return /* @__PURE__ */ React24.createElement(ClickAwayListener2, { onClickAway: onClose }, /* @__PURE__ */ React24.createElement(
2049
2886
  Alert2,
2050
2887
  {
2051
2888
  variant: "standard",
2052
2889
  severity: "warning",
2053
2890
  onClose,
2054
- action: /* @__PURE__ */ React23.createElement(React23.Fragment, null, onUnlink && /* @__PURE__ */ React23.createElement(AlertAction, { variant: "contained", onClick: onUnlink }, __16("Unlink", "elementor")), onRestore && /* @__PURE__ */ React23.createElement(AlertAction, { variant: "outlined", onClick: onRestore }, __16("Restore", "elementor"))),
2055
- sx: { width: sectionWidth }
2891
+ action: /* @__PURE__ */ React24.createElement(React24.Fragment, null, onUnlink && /* @__PURE__ */ React24.createElement(AlertAction2, { variant: "contained", onClick: onUnlink }, __17("Unlink", "elementor")), onRestore && /* @__PURE__ */ React24.createElement(AlertAction2, { variant: "outlined", onClick: onRestore }, __17("Restore", "elementor"))),
2892
+ sx: { maxWidth: 300 }
2056
2893
  },
2057
- /* @__PURE__ */ React23.createElement(AlertTitle, null, __16("Deleted variable", "elementor")),
2058
- __16("The variable", "elementor"),
2059
- " '",
2060
- label,
2061
- "'",
2062
- " ",
2063
- __16(
2894
+ /* @__PURE__ */ React24.createElement(AlertTitle2, null, __17("Deleted variable", "elementor")),
2895
+ /* @__PURE__ */ React24.createElement(Typography12, { variant: "body2", color: "textPrimary" }, __17("The variable", "elementor"), "\xA0'", /* @__PURE__ */ React24.createElement(Typography12, { variant: "body2", component: "span", sx: { lineBreak: "anywhere" } }, label), "'\xA0", __17(
2064
2896
  "has been deleted, but it is still referenced in this location. You may restore the variable or unlink it to assign a different value.",
2065
2897
  "elementor"
2066
- )
2898
+ ))
2067
2899
  ));
2068
2900
  };
2069
2901
 
2070
- // src/components/ui/tags/deleted-tag.tsx
2071
- import * as React24 from "react";
2072
- import { AlertTriangleFilledIcon as AlertTriangleFilledIcon2 } from "@elementor/icons";
2073
- import { Box as Box6, Chip, Tooltip as Tooltip2, Typography as Typography11 } from "@elementor/ui";
2074
- import { __ as __17 } from "@wordpress/i18n";
2075
- var DeletedTag = React24.forwardRef(({ label, onClick, ...props }, ref) => {
2076
- return /* @__PURE__ */ React24.createElement(
2077
- Chip,
2078
- {
2079
- ref,
2080
- size: "tiny",
2081
- color: "warning",
2082
- shape: "rounded",
2083
- variant: "standard",
2084
- onClick,
2085
- icon: /* @__PURE__ */ React24.createElement(AlertTriangleFilledIcon2, null),
2086
- label: /* @__PURE__ */ React24.createElement(Tooltip2, { title: label, placement: "top" }, /* @__PURE__ */ React24.createElement(Box6, { sx: { display: "flex", gap: 0.5, alignItems: "center" } }, /* @__PURE__ */ React24.createElement(Typography11, { variant: "caption", noWrap: true }, label), /* @__PURE__ */ React24.createElement(Typography11, { variant: "caption", noWrap: true, sx: { textOverflow: "initial", overflow: "visible" } }, "(", __17("deleted", "elementor"), ")"))),
2087
- sx: {
2088
- height: (theme) => theme.spacing(3.5),
2089
- borderRadius: (theme) => theme.spacing(1),
2090
- justifyContent: "flex-start",
2091
- width: "100%"
2092
- },
2093
- ...props
2094
- }
2095
- );
2096
- });
2902
+ // src/components/ui/tags/warning-variable-tag.tsx
2903
+ import * as React25 from "react";
2904
+ import { AlertTriangleFilledIcon as AlertTriangleFilledIcon4 } from "@elementor/icons";
2905
+ import { Box as Box5, Chip, Tooltip as Tooltip5, Typography as Typography13 } from "@elementor/ui";
2906
+ var WarningVariableTag = React25.forwardRef(
2907
+ ({ label, suffix, onClick, icon, ...props }, ref) => {
2908
+ const displayText = suffix ? `${label} (${suffix})` : label;
2909
+ return /* @__PURE__ */ React25.createElement(
2910
+ Chip,
2911
+ {
2912
+ ref,
2913
+ size: "tiny",
2914
+ color: "warning",
2915
+ shape: "rounded",
2916
+ variant: "standard",
2917
+ onClick,
2918
+ icon: /* @__PURE__ */ React25.createElement(AlertTriangleFilledIcon4, null),
2919
+ label: /* @__PURE__ */ React25.createElement(Tooltip5, { title: displayText, placement: "top" }, /* @__PURE__ */ React25.createElement(Box5, { sx: { display: "inline-grid", minWidth: 0 } }, /* @__PURE__ */ React25.createElement(Typography13, { variant: "caption", noWrap: true, sx: { lineHeight: 1.34 } }, displayText))),
2920
+ sx: {
2921
+ height: (theme) => theme.spacing(3.5),
2922
+ borderRadius: (theme) => theme.spacing(1),
2923
+ justifyContent: "flex-start",
2924
+ width: "100%"
2925
+ },
2926
+ ...props
2927
+ }
2928
+ );
2929
+ }
2930
+ );
2931
+ WarningVariableTag.displayName = "WarningVariableTag";
2097
2932
 
2098
2933
  // src/components/ui/variable/deleted-variable.tsx
2099
2934
  var DeletedVariable = ({ variable, propTypeKey }) => {
2100
2935
  const { propTypeUtil } = getVariableType(propTypeKey);
2101
- const { setValue } = useBoundProp8();
2936
+ const boundProp = useBoundProp8();
2102
2937
  const userPermissions = usePermissions();
2103
- const [showInfotip, setShowInfotip] = useState12(false);
2938
+ const [showInfotip, setShowInfotip] = useState13(false);
2104
2939
  const toggleInfotip = () => setShowInfotip((prev) => !prev);
2105
2940
  const closeInfotip = () => setShowInfotip(false);
2106
- const deletedChipAnchorRef = useRef2(null);
2941
+ const deletedChipAnchorRef = useRef7(null);
2107
2942
  const popupId = useId2();
2108
- const popupState = usePopupState3({
2943
+ const popupState = usePopupState4({
2109
2944
  variant: "popover",
2110
2945
  popupId: `elementor-variables-restore-${popupId}`
2111
2946
  });
2112
2947
  const handlers = {};
2113
2948
  if (userPermissions.canUnlink()) {
2114
- handlers.onUnlink = createUnlinkHandler(variable, propTypeKey, setValue);
2949
+ handlers.onUnlink = createUnlinkHandler(variable, propTypeKey, boundProp.setValue);
2115
2950
  }
2116
2951
  if (userPermissions.canRestore()) {
2117
2952
  handlers.onRestore = () => {
2118
2953
  if (!variable.key) {
2119
2954
  return;
2120
2955
  }
2121
- restoreVariable(variable.key).then((key) => {
2122
- setValue(propTypeUtil.create(key));
2956
+ restoreVariable(variable.key).then((id2) => {
2957
+ resolveBoundPropAndSetValue(propTypeUtil.create(id2), boundProp);
2123
2958
  closeInfotip();
2124
2959
  }).catch(() => {
2125
2960
  closeInfotip();
@@ -2131,15 +2966,15 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
2131
2966
  const handleRestoreWithOverrides = () => {
2132
2967
  popupState.close();
2133
2968
  };
2134
- return /* @__PURE__ */ React25.createElement(React25.Fragment, null, /* @__PURE__ */ React25.createElement(Box7, { ref: deletedChipAnchorRef }, showInfotip && /* @__PURE__ */ React25.createElement(Backdrop, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React25.createElement(
2135
- Infotip,
2969
+ return /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement(Box6, { ref: deletedChipAnchorRef }, showInfotip && /* @__PURE__ */ React26.createElement(Backdrop, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React26.createElement(
2970
+ Infotip2,
2136
2971
  {
2137
2972
  color: "warning",
2138
2973
  placement: "right-start",
2139
2974
  open: showInfotip,
2140
2975
  disableHoverListener: true,
2141
2976
  onClose: closeInfotip,
2142
- content: /* @__PURE__ */ React25.createElement(
2977
+ content: /* @__PURE__ */ React26.createElement(
2143
2978
  DeletedVariableAlert,
2144
2979
  {
2145
2980
  onClose: closeInfotip,
@@ -2159,8 +2994,15 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
2159
2994
  }
2160
2995
  }
2161
2996
  },
2162
- /* @__PURE__ */ React25.createElement(DeletedTag, { label: variable.label, onClick: toggleInfotip })
2163
- ), /* @__PURE__ */ React25.createElement(
2997
+ /* @__PURE__ */ React26.createElement(
2998
+ WarningVariableTag,
2999
+ {
3000
+ label: variable.label,
3001
+ onClick: toggleInfotip,
3002
+ suffix: __18("deleted", "elementor")
3003
+ }
3004
+ )
3005
+ ), /* @__PURE__ */ React26.createElement(
2164
3006
  Popover2,
2165
3007
  {
2166
3008
  disableScrollLock: true,
@@ -2171,7 +3013,7 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
2171
3013
  },
2172
3014
  ...bindPopover2(popupState)
2173
3015
  },
2174
- /* @__PURE__ */ React25.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ React25.createElement(
3016
+ /* @__PURE__ */ React26.createElement(VariableTypeProvider, { propTypeKey }, /* @__PURE__ */ React26.createElement(
2175
3017
  VariableRestore,
2176
3018
  {
2177
3019
  variableId: variable.key ?? "",
@@ -2184,83 +3026,51 @@ var DeletedVariable = ({ variable, propTypeKey }) => {
2184
3026
 
2185
3027
  // src/components/ui/variable/mismatch-variable.tsx
2186
3028
  import * as React28 from "react";
2187
- import { useId as useId3, useRef as useRef3, useState as useState13 } from "react";
3029
+ import { useId as useId3, useRef as useRef8, useState as useState14 } from "react";
2188
3030
  import { useBoundProp as useBoundProp9 } from "@elementor/editor-controls";
2189
- import { Backdrop as Backdrop2, bindPopover as bindPopover3, Box as Box9, Infotip as Infotip2, Popover as Popover3, usePopupState as usePopupState4 } from "@elementor/ui";
3031
+ import { Backdrop as Backdrop2, bindPopover as bindPopover3, Box as Box7, Infotip as Infotip3, Popover as Popover3, usePopupState as usePopupState5 } from "@elementor/ui";
3032
+ import { __ as __20 } from "@wordpress/i18n";
2190
3033
 
2191
3034
  // src/components/ui/mismatch-variable-alert.tsx
2192
- import * as React26 from "react";
2193
- import { useSectionWidth as useSectionWidth2 } from "@elementor/editor-editing-panel";
2194
- import { Alert as Alert3, AlertAction as AlertAction2, AlertTitle as AlertTitle2, ClickAwayListener as ClickAwayListener3 } from "@elementor/ui";
2195
- import { __ as __18 } from "@wordpress/i18n";
3035
+ import * as React27 from "react";
3036
+ import { Alert as Alert3, AlertAction as AlertAction3, AlertTitle as AlertTitle3, ClickAwayListener as ClickAwayListener3, Typography as Typography14 } from "@elementor/ui";
3037
+ import { __ as __19 } from "@wordpress/i18n";
2196
3038
  var i18n = {
2197
- title: __18("Variable has changed", "elementor"),
2198
- message: __18(
3039
+ title: __19("Variable has changed", "elementor"),
3040
+ message: __19(
2199
3041
  `This variable is no longer compatible with this property. You can clear it or select a different one.`,
2200
3042
  "elementor"
2201
3043
  ),
2202
3044
  buttons: {
2203
- clear: __18("Clear", "elementor"),
2204
- select: __18("Select variable", "elementor")
3045
+ clear: __19("Clear", "elementor"),
3046
+ select: __19("Select variable", "elementor")
2205
3047
  }
2206
3048
  };
2207
3049
  var MismatchVariableAlert = ({ onClose, onClear, triggerSelect }) => {
2208
- const sectionWidth = useSectionWidth2();
2209
- return /* @__PURE__ */ React26.createElement(ClickAwayListener3, { onClickAway: onClose }, /* @__PURE__ */ React26.createElement(
3050
+ return /* @__PURE__ */ React27.createElement(ClickAwayListener3, { onClickAway: onClose }, /* @__PURE__ */ React27.createElement(
2210
3051
  Alert3,
2211
3052
  {
2212
3053
  variant: "standard",
2213
3054
  severity: "warning",
2214
3055
  onClose,
2215
- action: /* @__PURE__ */ React26.createElement(React26.Fragment, null, onClear && /* @__PURE__ */ React26.createElement(AlertAction2, { variant: "contained", onClick: onClear }, i18n.buttons.clear), triggerSelect && /* @__PURE__ */ React26.createElement(AlertAction2, { variant: "outlined", onClick: triggerSelect }, i18n.buttons.select)),
2216
- sx: {
2217
- width: sectionWidth,
2218
- minWidth: 300
2219
- }
3056
+ action: /* @__PURE__ */ React27.createElement(React27.Fragment, null, onClear && /* @__PURE__ */ React27.createElement(AlertAction3, { variant: "contained", onClick: onClear }, i18n.buttons.clear), triggerSelect && /* @__PURE__ */ React27.createElement(AlertAction3, { variant: "outlined", onClick: triggerSelect }, i18n.buttons.select)),
3057
+ sx: { maxWidth: 300 }
2220
3058
  },
2221
- /* @__PURE__ */ React26.createElement(AlertTitle2, null, i18n.title),
2222
- i18n.message
3059
+ /* @__PURE__ */ React27.createElement(AlertTitle3, null, i18n.title),
3060
+ /* @__PURE__ */ React27.createElement(Typography14, { variant: "body2", color: "textPrimary" }, i18n.message)
2223
3061
  ));
2224
3062
  };
2225
3063
 
2226
- // src/components/ui/tags/mismatch-tag.tsx
2227
- import * as React27 from "react";
2228
- import { AlertTriangleFilledIcon as AlertTriangleFilledIcon3 } from "@elementor/icons";
2229
- import { Box as Box8, Chip as Chip2, Tooltip as Tooltip3, Typography as Typography12 } from "@elementor/ui";
2230
- import { __ as __19 } from "@wordpress/i18n";
2231
- var MismatchTag = React27.forwardRef(({ label, onClick, ...props }, ref) => {
2232
- return /* @__PURE__ */ React27.createElement(
2233
- Chip2,
2234
- {
2235
- ref,
2236
- size: "tiny",
2237
- color: "warning",
2238
- shape: "rounded",
2239
- variant: "standard",
2240
- onClick,
2241
- icon: /* @__PURE__ */ React27.createElement(AlertTriangleFilledIcon3, null),
2242
- label: /* @__PURE__ */ React27.createElement(Tooltip3, { title: label, placement: "top" }, /* @__PURE__ */ React27.createElement(Box8, { sx: { display: "flex", gap: 0.5, alignItems: "center" } }, /* @__PURE__ */ React27.createElement(Typography12, { variant: "caption", noWrap: true }, label), /* @__PURE__ */ React27.createElement(Typography12, { variant: "caption", noWrap: true, sx: { textOverflow: "initial", overflow: "visible" } }, "(", __19("changed", "elementor"), ")"))),
2243
- sx: {
2244
- height: (theme) => theme.spacing(3.5),
2245
- borderRadius: (theme) => theme.spacing(1),
2246
- justifyContent: "flex-start",
2247
- width: "100%"
2248
- },
2249
- ...props
2250
- }
2251
- );
2252
- });
2253
-
2254
3064
  // src/components/ui/variable/mismatch-variable.tsx
2255
3065
  var MismatchVariable = ({ variable }) => {
2256
- const { setValue } = useBoundProp9();
2257
- const anchorRef = useRef3(null);
3066
+ const { setValue, value } = useBoundProp9();
3067
+ const anchorRef = useRef8(null);
2258
3068
  const popupId = useId3();
2259
- const popupState = usePopupState4({
3069
+ const popupState = usePopupState5({
2260
3070
  variant: "popover",
2261
3071
  popupId: `elementor-variables-list-${popupId}`
2262
3072
  });
2263
- const [infotipVisible, setInfotipVisible] = useState13(false);
3073
+ const [infotipVisible, setInfotipVisible] = useState14(false);
2264
3074
  const toggleInfotip = () => setInfotipVisible((prev) => !prev);
2265
3075
  const closeInfotip = () => setInfotipVisible(false);
2266
3076
  const triggerSelect = () => {
@@ -2272,8 +3082,9 @@ var MismatchVariable = ({ variable }) => {
2272
3082
  closeInfotip();
2273
3083
  setValue(null);
2274
3084
  };
2275
- return /* @__PURE__ */ React28.createElement(Box9, { ref: anchorRef }, infotipVisible && /* @__PURE__ */ React28.createElement(Backdrop2, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React28.createElement(
2276
- Infotip2,
3085
+ const showClearButton = !!value;
3086
+ return /* @__PURE__ */ React28.createElement(Box7, { ref: anchorRef }, infotipVisible && /* @__PURE__ */ React28.createElement(Backdrop2, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React28.createElement(
3087
+ Infotip3,
2277
3088
  {
2278
3089
  color: "warning",
2279
3090
  placement: "right-start",
@@ -2284,7 +3095,7 @@ var MismatchVariable = ({ variable }) => {
2284
3095
  MismatchVariableAlert,
2285
3096
  {
2286
3097
  onClose: closeInfotip,
2287
- onClear: clearValue,
3098
+ onClear: showClearButton ? clearValue : void 0,
2288
3099
  triggerSelect
2289
3100
  }
2290
3101
  ),
@@ -2299,7 +3110,14 @@ var MismatchVariable = ({ variable }) => {
2299
3110
  }
2300
3111
  }
2301
3112
  },
2302
- /* @__PURE__ */ React28.createElement(MismatchTag, { label: variable.label, onClick: toggleInfotip })
3113
+ /* @__PURE__ */ React28.createElement(
3114
+ WarningVariableTag,
3115
+ {
3116
+ label: variable.label,
3117
+ onClick: toggleInfotip,
3118
+ suffix: __20("changed", "elementor")
3119
+ }
3120
+ )
2303
3121
  ), /* @__PURE__ */ React28.createElement(
2304
3122
  Popover3,
2305
3123
  {
@@ -2324,79 +3142,50 @@ var MismatchVariable = ({ variable }) => {
2324
3142
  };
2325
3143
 
2326
3144
  // src/components/ui/variable/missing-variable.tsx
2327
- import * as React31 from "react";
2328
- import { useState as useState14 } from "react";
3145
+ import * as React30 from "react";
3146
+ import { useState as useState15 } from "react";
2329
3147
  import { useBoundProp as useBoundProp10 } from "@elementor/editor-controls";
2330
- import { Backdrop as Backdrop3, Infotip as Infotip3 } from "@elementor/ui";
2331
- import { __ as __21 } from "@wordpress/i18n";
3148
+ import { Backdrop as Backdrop3, Infotip as Infotip4 } from "@elementor/ui";
3149
+ import { __ as __22 } from "@wordpress/i18n";
2332
3150
 
2333
3151
  // src/components/ui/missing-variable-alert.tsx
2334
3152
  import * as React29 from "react";
2335
- import { useSectionWidth as useSectionWidth3 } from "@elementor/editor-editing-panel";
2336
- import { Alert as Alert4, AlertAction as AlertAction3, AlertTitle as AlertTitle3, ClickAwayListener as ClickAwayListener4 } from "@elementor/ui";
2337
- import { __ as __20 } from "@wordpress/i18n";
3153
+ import { Alert as Alert4, AlertAction as AlertAction4, AlertTitle as AlertTitle4, ClickAwayListener as ClickAwayListener4, Typography as Typography15 } from "@elementor/ui";
3154
+ import { __ as __21 } from "@wordpress/i18n";
2338
3155
  var MissingVariableAlert = ({ onClose, onClear }) => {
2339
- const sectionWidth = useSectionWidth3();
2340
3156
  return /* @__PURE__ */ React29.createElement(ClickAwayListener4, { onClickAway: onClose }, /* @__PURE__ */ React29.createElement(
2341
3157
  Alert4,
2342
3158
  {
2343
3159
  variant: "standard",
2344
3160
  severity: "warning",
2345
3161
  onClose,
2346
- action: /* @__PURE__ */ React29.createElement(React29.Fragment, null, onClear && /* @__PURE__ */ React29.createElement(AlertAction3, { variant: "contained", onClick: onClear }, __20("Clear", "elementor"))),
2347
- sx: { width: sectionWidth }
3162
+ action: /* @__PURE__ */ React29.createElement(React29.Fragment, null, onClear && /* @__PURE__ */ React29.createElement(AlertAction4, { variant: "contained", onClick: onClear }, __21("Clear", "elementor"))),
3163
+ sx: { maxWidth: 300 }
2348
3164
  },
2349
- /* @__PURE__ */ React29.createElement(AlertTitle3, null, __20("This variable is missing", "elementor")),
2350
- __20(
3165
+ /* @__PURE__ */ React29.createElement(AlertTitle4, null, __21("This variable is missing", "elementor")),
3166
+ /* @__PURE__ */ React29.createElement(Typography15, { variant: "body2", color: "textPrimary" }, __21(
2351
3167
  "It may have been deleted. Try clearing this field and select a different value or variable.",
2352
3168
  "elementor"
2353
- )
3169
+ ))
2354
3170
  ));
2355
3171
  };
2356
3172
 
2357
- // src/components/ui/tags/missing-tag.tsx
2358
- import * as React30 from "react";
2359
- import { AlertTriangleFilledIcon as AlertTriangleFilledIcon4 } from "@elementor/icons";
2360
- import { Chip as Chip3 } from "@elementor/ui";
2361
- var MissingTag = React30.forwardRef(({ label, onClick, ...props }, ref) => {
2362
- return /* @__PURE__ */ React30.createElement(
2363
- Chip3,
2364
- {
2365
- ref,
2366
- size: "tiny",
2367
- color: "warning",
2368
- shape: "rounded",
2369
- variant: "standard",
2370
- onClick,
2371
- icon: /* @__PURE__ */ React30.createElement(AlertTriangleFilledIcon4, null),
2372
- label,
2373
- sx: {
2374
- height: (theme) => theme.spacing(3.5),
2375
- borderRadius: (theme) => theme.spacing(1),
2376
- justifyContent: "flex-start",
2377
- width: "100%"
2378
- },
2379
- ...props
2380
- }
2381
- );
2382
- });
2383
-
2384
3173
  // src/components/ui/variable/missing-variable.tsx
2385
3174
  var MissingVariable = () => {
2386
3175
  const { setValue } = useBoundProp10();
2387
- const [infotipVisible, setInfotipVisible] = useState14(false);
3176
+ const [infotipVisible, setInfotipVisible] = useState15(false);
2388
3177
  const toggleInfotip = () => setInfotipVisible((prev) => !prev);
2389
3178
  const closeInfotip = () => setInfotipVisible(false);
2390
3179
  const clearValue = () => setValue(null);
2391
- return /* @__PURE__ */ React31.createElement(React31.Fragment, null, infotipVisible && /* @__PURE__ */ React31.createElement(Backdrop3, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React31.createElement(
2392
- Infotip3,
3180
+ return /* @__PURE__ */ React30.createElement(React30.Fragment, null, infotipVisible && /* @__PURE__ */ React30.createElement(Backdrop3, { open: true, onClick: closeInfotip, invisible: true }), /* @__PURE__ */ React30.createElement(
3181
+ Infotip4,
2393
3182
  {
2394
3183
  color: "warning",
2395
3184
  placement: "right-start",
2396
3185
  open: infotipVisible,
2397
3186
  disableHoverListener: true,
2398
3187
  onClose: closeInfotip,
2399
- content: /* @__PURE__ */ React31.createElement(MissingVariableAlert, { onClose: closeInfotip, onClear: clearValue }),
3188
+ content: /* @__PURE__ */ React30.createElement(MissingVariableAlert, { onClose: closeInfotip, onClear: clearValue }),
2400
3189
  slotProps: {
2401
3190
  popper: {
2402
3191
  modifiers: [
@@ -2408,47 +3197,47 @@ var MissingVariable = () => {
2408
3197
  }
2409
3198
  }
2410
3199
  },
2411
- /* @__PURE__ */ React31.createElement(MissingTag, { label: __21("Missing variable", "elementor"), onClick: toggleInfotip })
3200
+ /* @__PURE__ */ React30.createElement(WarningVariableTag, { label: __22("Missing variable", "elementor"), onClick: toggleInfotip })
2412
3201
  ));
2413
3202
  };
2414
3203
 
2415
3204
  // src/controls/variable-control.tsx
2416
3205
  var VariableControl = () => {
2417
3206
  const boundProp = useBoundProp11();
2418
- const boundPropValue = boundProp.value;
3207
+ const boundPropValue = boundProp.value ?? boundProp.placeholder;
2419
3208
  const assignedVariable = useVariable(boundPropValue?.value);
2420
3209
  if (!assignedVariable) {
2421
- return /* @__PURE__ */ React32.createElement(MissingVariable, null);
3210
+ return /* @__PURE__ */ React31.createElement(MissingVariable, null);
2422
3211
  }
2423
3212
  const { $$type: propTypeKey } = boundPropValue;
2424
3213
  if (assignedVariable?.deleted) {
2425
- return /* @__PURE__ */ React32.createElement(DeletedVariable, { variable: assignedVariable, propTypeKey });
3214
+ return /* @__PURE__ */ React31.createElement(DeletedVariable, { variable: assignedVariable, propTypeKey });
2426
3215
  }
2427
3216
  const { isCompatible } = getVariableType(assignedVariable.type);
2428
3217
  if (isCompatible && !isCompatible(boundProp?.propType, assignedVariable)) {
2429
- return /* @__PURE__ */ React32.createElement(MismatchVariable, { variable: assignedVariable });
3218
+ return /* @__PURE__ */ React31.createElement(MismatchVariable, { variable: assignedVariable });
2430
3219
  }
2431
- return /* @__PURE__ */ React32.createElement(AssignedVariable, { variable: assignedVariable, propTypeKey });
3220
+ return /* @__PURE__ */ React31.createElement(AssignedVariable, { variable: assignedVariable, propTypeKey });
2432
3221
  };
2433
3222
 
2434
3223
  // src/hooks/use-prop-variable-action.tsx
2435
- import * as React33 from "react";
3224
+ import * as React32 from "react";
2436
3225
  import { useBoundProp as useBoundProp12 } from "@elementor/editor-editing-panel";
2437
3226
  import { ColorFilterIcon as ColorFilterIcon4 } from "@elementor/icons";
2438
- import { __ as __22 } from "@wordpress/i18n";
3227
+ import { __ as __23 } from "@wordpress/i18n";
2439
3228
  var usePropVariableAction = () => {
2440
3229
  const { propType, path } = useBoundProp12();
2441
3230
  const variable = resolveVariableFromPropType(propType);
2442
3231
  return {
2443
3232
  visible: Boolean(variable),
2444
3233
  icon: ColorFilterIcon4,
2445
- title: __22("Variables", "elementor"),
3234
+ title: __23("Variables", "elementor"),
2446
3235
  content: ({ close: closePopover }) => {
2447
3236
  if (!variable) {
2448
3237
  return null;
2449
3238
  }
2450
3239
  trackOpenVariablePopover(path, variable.variableType);
2451
- return /* @__PURE__ */ React33.createElement(VariableSelectionPopover, { closePopover, propTypeKey: variable.propTypeUtil.key });
3240
+ return /* @__PURE__ */ React32.createElement(VariableSelectionPopover, { closePopover, propTypeKey: variable.propTypeUtil.key });
2452
3241
  }
2453
3242
  };
2454
3243
  };
@@ -2472,19 +3261,297 @@ var trackOpenVariablePopover = (path, variableType) => {
2472
3261
  });
2473
3262
  };
2474
3263
 
3264
+ // src/mcp/index.ts
3265
+ import { getMCPByDomain as getMCPByDomain6 } from "@elementor/editor-mcp";
3266
+
3267
+ // src/mcp/create-variable-tool.ts
3268
+ import { getMCPByDomain } from "@elementor/editor-mcp";
3269
+ import { z as z3 } from "@elementor/schema";
3270
+ var InputSchema = {
3271
+ type: z3.string().describe('The type of the variable. Example values: "global-color-variable" or "global-font-variable".'),
3272
+ label: z3.string().describe("The label of the variable, displayed to the user"),
3273
+ value: z3.string().describe("The value of the variable, should correspond to the type")
3274
+ };
3275
+ var OutputSchema = {
3276
+ status: z3.enum(["ok", "error"]).describe("The status of the operation"),
3277
+ message: z3.string().optional().describe("Optional message providing additional information about the operation")
3278
+ };
3279
+ var initCreateVariableTool = () => {
3280
+ getMCPByDomain("variables").addTool({
3281
+ name: "create-global-variable",
3282
+ schema: InputSchema,
3283
+ outputSchema: OutputSchema,
3284
+ description: `Create a new global variable
3285
+ ## When to use this tool:
3286
+ - When a user requests to create a new global variable in the Elementor editor.
3287
+ - When you need to add a new variable to be used in the editor.
3288
+
3289
+ ## Prequisites:
3290
+ - 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.
3291
+ - Make sure when creating a new variable, the label is unique and not already in use.
3292
+ - If the user does not provide a label, ask them to provide one before proceeding.
3293
+ - If the user does not provide a type, ask them to provide one before proceeding.
3294
+ - If the user does not provide a value, ask them to provide one before proceeding.
3295
+
3296
+ ## Required parameters:
3297
+ - type: The type of the variable. Possible values are 'global-color-variable' or 'global-font-variable'.
3298
+ - label: The label of the variable, displayed to the user. Must be unique and not already in use.
3299
+ - 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').
3300
+
3301
+ ## Example tool call (JSON format):
3302
+ \`\`\`json
3303
+ { "type": "global-color-variable", "label": "My Cool Color", "value": "rgb(1,2,3)" }
3304
+ \`\`\`
3305
+
3306
+ ## Example tool response (JSON format):
3307
+ \`\`\`json
3308
+ { "status": "ok" }
3309
+ \`\`\`
3310
+
3311
+ ## 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.
3312
+ { "status": "error", "message": "Unsupported type 'global-kuku-variable'" }
3313
+
3314
+ In that case, inform the user the type is unsupported and they should try another type, perhaps consult to online documentation.
3315
+ `,
3316
+ handler: async (params) => {
3317
+ const { type, label, value } = params;
3318
+ try {
3319
+ await service.create({ type, label, value });
3320
+ } catch (error) {
3321
+ const message = error.message || "Unknown server error";
3322
+ return {
3323
+ status: "error",
3324
+ message: `There was an error creating the variable: ${message}`
3325
+ };
3326
+ }
3327
+ return { status: "ok" };
3328
+ }
3329
+ });
3330
+ };
3331
+
3332
+ // src/mcp/delete-variable-tool.ts
3333
+ import { getMCPByDomain as getMCPByDomain2 } from "@elementor/editor-mcp";
3334
+ import { z as z4 } from "@elementor/schema";
3335
+ var initDeleteVariableTool = () => {
3336
+ getMCPByDomain2("variables").addTool({
3337
+ name: "delete-global-variable",
3338
+ schema: {
3339
+ id: z4.string().describe("The unique identifier of the variable to be deleted.")
3340
+ },
3341
+ outputSchema: {
3342
+ status: z4.enum(["ok", "error"]).describe("The status of the operation")
3343
+ },
3344
+ description: `Delete an existing global variable
3345
+
3346
+ ## When to use this tool:
3347
+ - When a user requests to delete an existing global variable in the Elementor editor.
3348
+ - When you need to remove a variable that is no longer needed or relevant, with the user's confirmation.
3349
+
3350
+ ## Prerequisites:
3351
+ - 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.
3352
+ - Reference the variable by the "id" property, given from the "list-global-variables" tool.
3353
+ - Make sure you have the unique identifier of the variable to be deleted before using this tool.
3354
+ - Confirm with the user that they want to proceed with the deletion, as this action is irreversible.
3355
+
3356
+ <notice>
3357
+ A use might reference a variable by it's label, but you must always use the unique identifier (id) to delete it.
3358
+ If you only have the label, use the "list-global-variables" tool to find the corresponding id.
3359
+ </notice>
3360
+
3361
+ <important>
3362
+ This operation is destructive and cannot be undone. Ensure that the user is fully aware of the consequences before proceeding.
3363
+ When a variable is deleted, all references to it in all pages accross the website will lose their effect.
3364
+ </important>`,
3365
+ handler: async (params) => {
3366
+ const { id: id2 } = params;
3367
+ try {
3368
+ await service.delete(id2);
3369
+ return { status: "ok" };
3370
+ } catch (err) {
3371
+ return {
3372
+ status: "error"
3373
+ };
3374
+ }
3375
+ },
3376
+ isDestrcutive: true
3377
+ });
3378
+ };
3379
+
3380
+ // src/mcp/list-variables-tool.ts
3381
+ import { getMCPByDomain as getMCPByDomain3 } from "@elementor/editor-mcp";
3382
+ import { z as z5 } from "@elementor/schema";
3383
+ var VariableSchema = {
3384
+ type: z5.string().describe("The type of the variable."),
3385
+ label: z5.string().describe("The label of the variable, displayed to the user"),
3386
+ value: z5.string().describe("The value of the variable."),
3387
+ id: z5.string().describe(
3388
+ "The unique identifier of the variable. Used for internal reference, not to be exposed to end users"
3389
+ )
3390
+ };
3391
+ var VariableListSchema = {
3392
+ variables: z5.array(z5.object(VariableSchema)).describe("List of variables")
3393
+ };
3394
+ var initListVariablesTool = () => {
3395
+ getMCPByDomain3("variables").addTool({
3396
+ name: "list-global-variables",
3397
+ description: `List editor global variables
3398
+
3399
+ ## When to use this tool:
3400
+ - When a user requests to see all available global variables in the Elementor editor.
3401
+ - When you need to be exact on a variable label, to avoid any mistakes.
3402
+ - When you want to see the most up-to-date list of global variables.
3403
+ - 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.
3404
+
3405
+ ## Example tool response (JSON format):
3406
+ \`\`\`json
3407
+ { variables: [
3408
+ { type: 'global-color-variable', label: 'Cool', value: 'rgb(1,2,3)', id: 'some-unique-id' },
3409
+ { type: 'global-font-variable', label: 'Headline', value: 'serif', id: 'some-other-unique-id' },
3410
+ ] }
3411
+ \`\`\`
3412
+
3413
+ Once you get the response, please display the variables in a user-friendly way, unless explicitly requested otherwise.
3414
+ Unless explicitly requested otherwise, response in HTML Format, prefer to use tables or unordered lists.
3415
+
3416
+ Note: **The label is most improtant to be seen as-is without any changes.**
3417
+
3418
+ <important>
3419
+ **Do not omit the label**. This is important for the user to identify the variable.
3420
+ **Do not change the label**, it must be displayed exactly as it is, in it's original characters as received from this tool.
3421
+ </important>
3422
+ `,
3423
+ outputSchema: VariableListSchema,
3424
+ handler: async () => {
3425
+ const variables = service.variables();
3426
+ return {
3427
+ variables: Object.entries(variables).map(([id2, varData]) => ({ id: id2, ...varData }))
3428
+ };
3429
+ }
3430
+ });
3431
+ };
3432
+
3433
+ // src/mcp/update-variable-tool.ts
3434
+ import { getMCPByDomain as getMCPByDomain4 } from "@elementor/editor-mcp";
3435
+ import { z as z6 } from "@elementor/schema";
3436
+ var initUpdateVariableTool = () => {
3437
+ getMCPByDomain4("variables").addTool({
3438
+ schema: {
3439
+ id: z6.string().describe("The unique identifier of the variable to be updated or renamed."),
3440
+ label: z6.string().describe(
3441
+ "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."
3442
+ ),
3443
+ value: z6.string().describe(
3444
+ "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."
3445
+ )
3446
+ },
3447
+ outputSchema: {
3448
+ status: z6.enum(["ok", "error"]).describe("The status of the operation"),
3449
+ message: z6.string().optional().describe("Optional message providing additional information about the operation")
3450
+ },
3451
+ name: "update-global-variable",
3452
+ description: `Update an existing global variable
3453
+
3454
+ ## When to use this tool:
3455
+ - When a user requests to update an existing global variable in the Elementor editor.
3456
+ - When you need to modify the value of an existing variable.
3457
+ - When you want to rename an existing variable (change its label).
3458
+ - When you want to both rename and modify the value of an existing variable.
3459
+
3460
+ ## Prerequisites:
3461
+ - 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.
3462
+ - Make sure when updating a variable, the new label is unique and not already in use by another variable.
3463
+ - Make sure you understand whether you are updating a value, renaming, or both.
3464
+ - Reference the variable by the "id" property, given from the "list-global-variables" tool.
3465
+ - If the user wishes to rename, make sure you have the existing value.
3466
+ - If the user wishes to update the value, make sure you have to **correct label**.
3467
+ - You must have the unique identifier, the current label, the current value, and the new value or label or both, before using this tool.
3468
+
3469
+ ## Required parameters:
3470
+ - id: The unique identifier of the variable to be updated or renamed.
3471
+ - 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.
3472
+ - 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.
3473
+
3474
+ ## Example tool call (JSON format):
3475
+ \`\`\`json
3476
+ { "id": "some-unique-id", "label": "Cool", "value": "rgb(0,140,250)" }
3477
+ \`\`\`
3478
+
3479
+ ## Example responses (JSON format):
3480
+ Successful update:
3481
+ \`\`\`json
3482
+ { "status": "ok" }
3483
+ \`\`\`
3484
+
3485
+ 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.
3486
+ \`\`\`json
3487
+ { "status": "error", "message": "Label 'Cool' is already in use by another variable." }
3488
+ \`\`\`
3489
+ `,
3490
+ handler: async (params) => {
3491
+ const { id: id2, label, value } = params;
3492
+ try {
3493
+ await service.update(id2, { label, value });
3494
+ return { status: "ok" };
3495
+ } catch (error) {
3496
+ const message = error.message || "Unknown server error";
3497
+ return {
3498
+ status: "error",
3499
+ message: `There was an error creating the variable: ${message}`
3500
+ };
3501
+ }
3502
+ }
3503
+ });
3504
+ };
3505
+
3506
+ // src/mcp/variables-resource.ts
3507
+ import { getMCPByDomain as getMCPByDomain5 } from "@elementor/editor-mcp";
3508
+ var GLOBAL_VARIABLES_URI = "elementor://variables";
3509
+ var initVariablesResource = () => {
3510
+ const { mcpServer } = getMCPByDomain5("variables");
3511
+ mcpServer.resource(
3512
+ "global-variables",
3513
+ GLOBAL_VARIABLES_URI,
3514
+ {
3515
+ 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."
3516
+ },
3517
+ async () => {
3518
+ return {
3519
+ contents: [{ uri: GLOBAL_VARIABLES_URI, text: localStorage["elementor-global-variables"] }]
3520
+ };
3521
+ }
3522
+ );
3523
+ window.addEventListener("variables:updated", () => {
3524
+ mcpServer.server.sendResourceUpdated({
3525
+ uri: GLOBAL_VARIABLES_URI,
3526
+ contents: [{ uri: GLOBAL_VARIABLES_URI, text: localStorage["elementor-global-variables"] }]
3527
+ });
3528
+ });
3529
+ };
3530
+
3531
+ // src/mcp/index.ts
3532
+ function initMcp() {
3533
+ const { setMCPDescription } = getMCPByDomain6("variables");
3534
+ setMCPDescription(`Elementor Editor Variables MCP`);
3535
+ initListVariablesTool();
3536
+ initCreateVariableTool();
3537
+ initUpdateVariableTool();
3538
+ initDeleteVariableTool();
3539
+ initVariablesResource();
3540
+ }
3541
+
2475
3542
  // src/register-variable-types.tsx
2476
- import * as React36 from "react";
3543
+ import * as React35 from "react";
2477
3544
  import { colorPropTypeUtil, stringPropTypeUtil } from "@elementor/editor-props";
2478
3545
  import { BrushIcon, TextIcon as TextIcon2 } from "@elementor/icons";
2479
3546
 
2480
3547
  // src/components/fields/color-field.tsx
2481
- import * as React34 from "react";
2482
- import { useRef as useRef4, useState as useState15 } from "react";
3548
+ import * as React33 from "react";
3549
+ import { useRef as useRef9, useState as useState16 } from "react";
2483
3550
  import { UnstableColorField } from "@elementor/ui";
2484
3551
  var ColorField = ({ value, onChange, onValidationChange }) => {
2485
- const [color, setColor] = useState15(value);
2486
- const [errorMessage, setErrorMessage] = useState15("");
2487
- const defaultRef = useRef4(null);
3552
+ const [color, setColor] = useState16(value);
3553
+ const [errorMessage, setErrorMessage] = useState16("");
3554
+ const defaultRef = useRef9(null);
2488
3555
  const anchorRef = usePopoverContentRef() ?? defaultRef.current;
2489
3556
  const handleChange = (newValue) => {
2490
3557
  setColor(newValue);
@@ -2493,9 +3560,10 @@ var ColorField = ({ value, onChange, onValidationChange }) => {
2493
3560
  onValidationChange?.(errorMsg);
2494
3561
  onChange(errorMsg ? "" : newValue);
2495
3562
  };
2496
- return /* @__PURE__ */ React34.createElement(
3563
+ return /* @__PURE__ */ React33.createElement(
2497
3564
  UnstableColorField,
2498
3565
  {
3566
+ id: "color-variable-field",
2499
3567
  size: "tiny",
2500
3568
  fullWidth: true,
2501
3569
  value: color,
@@ -2521,21 +3589,21 @@ var ColorField = ({ value, onChange, onValidationChange }) => {
2521
3589
  };
2522
3590
 
2523
3591
  // src/components/fields/font-field.tsx
2524
- import * as React35 from "react";
2525
- import { useId as useId4, useRef as useRef5, useState as useState16 } from "react";
3592
+ import * as React34 from "react";
3593
+ import { useId as useId4, useRef as useRef10, useState as useState17 } from "react";
2526
3594
  import { enqueueFont as enqueueFont2, ItemSelector } from "@elementor/editor-controls";
2527
- import { useFontFamilies, useSectionWidth as useSectionWidth4 } from "@elementor/editor-editing-panel";
3595
+ import { useFontFamilies, useSectionWidth } from "@elementor/editor-editing-panel";
2528
3596
  import { ChevronDownIcon, TextIcon } from "@elementor/icons";
2529
- import { bindPopover as bindPopover4, bindTrigger as bindTrigger3, Popover as Popover4, UnstableTag, usePopupState as usePopupState5 } from "@elementor/ui";
2530
- import { __ as __23 } from "@wordpress/i18n";
3597
+ import { bindPopover as bindPopover4, bindTrigger as bindTrigger4, Popover as Popover4, UnstableTag, usePopupState as usePopupState6 } from "@elementor/ui";
3598
+ import { __ as __24 } from "@wordpress/i18n";
2531
3599
  var FontField = ({ value, onChange, onValidationChange }) => {
2532
- const [fontFamily, setFontFamily] = useState16(value);
2533
- const defaultRef = useRef5(null);
3600
+ const [fontFamily, setFontFamily] = useState17(value);
3601
+ const defaultRef = useRef10(null);
2534
3602
  const anchorRef = usePopoverContentRef() ?? defaultRef.current;
2535
- const fontPopoverState = usePopupState5({ variant: "popover" });
3603
+ const fontPopoverState = usePopupState6({ variant: "popover" });
2536
3604
  const fontFamilies = useFontFamilies();
2537
- const sectionWidth = useSectionWidth4();
2538
- const mapFontSubs = React35.useMemo(() => {
3605
+ const sectionWidth = useSectionWidth();
3606
+ const mapFontSubs = React34.useMemo(() => {
2539
3607
  return fontFamilies.map(({ label, fonts }) => ({
2540
3608
  label,
2541
3609
  items: fonts
@@ -2552,17 +3620,17 @@ var FontField = ({ value, onChange, onValidationChange }) => {
2552
3620
  fontPopoverState.close();
2553
3621
  };
2554
3622
  const id2 = useId4();
2555
- return /* @__PURE__ */ React35.createElement(React35.Fragment, null, /* @__PURE__ */ React35.createElement(
3623
+ return /* @__PURE__ */ React34.createElement(React34.Fragment, null, /* @__PURE__ */ React34.createElement(
2556
3624
  UnstableTag,
2557
3625
  {
2558
3626
  id: id2,
2559
3627
  variant: "outlined",
2560
3628
  label: fontFamily,
2561
- endIcon: /* @__PURE__ */ React35.createElement(ChevronDownIcon, { fontSize: "tiny" }),
2562
- ...bindTrigger3(fontPopoverState),
3629
+ endIcon: /* @__PURE__ */ React34.createElement(ChevronDownIcon, { fontSize: "tiny" }),
3630
+ ...bindTrigger4(fontPopoverState),
2563
3631
  fullWidth: true
2564
3632
  }
2565
- ), /* @__PURE__ */ React35.createElement(
3633
+ ), /* @__PURE__ */ React34.createElement(
2566
3634
  Popover4,
2567
3635
  {
2568
3636
  disablePortal: true,
@@ -2572,15 +3640,16 @@ var FontField = ({ value, onChange, onValidationChange }) => {
2572
3640
  transformOrigin: { vertical: "top", horizontal: -28 },
2573
3641
  ...bindPopover4(fontPopoverState)
2574
3642
  },
2575
- /* @__PURE__ */ React35.createElement(
3643
+ /* @__PURE__ */ React34.createElement(
2576
3644
  ItemSelector,
2577
3645
  {
3646
+ id: "font-family-variables-selector",
2578
3647
  itemsList: mapFontSubs,
2579
3648
  selectedItem: fontFamily,
2580
3649
  onItemChange: handleFontFamilyChange,
2581
3650
  onClose: fontPopoverState.close,
2582
3651
  sectionWidth,
2583
- title: __23("Font Family", "elementor"),
3652
+ title: __24("Font family", "elementor"),
2584
3653
  itemStyle: (item) => ({ fontFamily: item.value }),
2585
3654
  onDebounce: enqueueFont2,
2586
3655
  icon: TextIcon
@@ -2597,20 +3666,22 @@ function registerVariableTypes() {
2597
3666
  propTypeUtil: colorVariablePropTypeUtil,
2598
3667
  fallbackPropTypeUtil: colorPropTypeUtil,
2599
3668
  variableType: "color",
2600
- startIcon: ({ value }) => /* @__PURE__ */ React36.createElement(ColorIndicator, { size: "inherit", component: "span", value })
3669
+ startIcon: ({ value }) => /* @__PURE__ */ React35.createElement(ColorIndicator, { size: "inherit", component: "span", value }),
3670
+ defaultValue: "#ffffff"
2601
3671
  });
2602
3672
  registerVariableType({
2603
3673
  valueField: FontField,
2604
3674
  icon: TextIcon2,
2605
3675
  propTypeUtil: fontVariablePropTypeUtil,
2606
3676
  fallbackPropTypeUtil: stringPropTypeUtil,
2607
- variableType: "font"
3677
+ variableType: "font",
3678
+ defaultValue: "Roboto"
2608
3679
  });
2609
3680
  }
2610
3681
 
2611
3682
  // src/renderers/style-variables-renderer.tsx
2612
- import * as React37 from "react";
2613
- import { useEffect as useEffect3, useState as useState17 } from "react";
3683
+ import * as React36 from "react";
3684
+ import { useEffect as useEffect5, useState as useState18 } from "react";
2614
3685
  import { __privateUseListenTo as useListenTo, commandEndEvent } from "@elementor/editor-v1-adapters";
2615
3686
  import { Portal } from "@elementor/ui";
2616
3687
 
@@ -2631,14 +3702,14 @@ function StyleVariablesRenderer() {
2631
3702
  }
2632
3703
  const cssVariables = convertToCssVariables(styleVariables);
2633
3704
  const wrappedCss = `${VARIABLES_WRAPPER}{${cssVariables}}`;
2634
- return /* @__PURE__ */ React37.createElement(Portal, { container }, /* @__PURE__ */ React37.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
3705
+ return /* @__PURE__ */ React36.createElement(Portal, { container }, /* @__PURE__ */ React36.createElement("style", { "data-e-style-id": "e-variables", key: wrappedCss }, wrappedCss));
2635
3706
  }
2636
3707
  function usePortalContainer() {
2637
3708
  return useListenTo(commandEndEvent("editor/documents/attach-preview"), () => getCanvasIframeDocument()?.head);
2638
3709
  }
2639
3710
  function useStyleVariables() {
2640
- const [variables, setVariables] = useState17({});
2641
- useEffect3(() => {
3711
+ const [variables, setVariables] = useState18({});
3712
+ useEffect5(() => {
2642
3713
  const unsubscribe = styleVariablesRepository.subscribe(setVariables);
2643
3714
  return () => {
2644
3715
  unsubscribe();
@@ -2661,22 +3732,22 @@ import { injectIntoRepeaterItemIcon, injectIntoRepeaterItemLabel } from "@elemen
2661
3732
  import { backgroundColorOverlayPropTypeUtil, shadowPropTypeUtil } from "@elementor/editor-props";
2662
3733
 
2663
3734
  // src/components/variables-repeater-item-slot.tsx
2664
- import * as React38 from "react";
3735
+ import * as React37 from "react";
2665
3736
  var useColorVariable = (value) => {
2666
3737
  const variableId = value?.value?.color?.value;
2667
3738
  return useVariable(variableId || "");
2668
3739
  };
2669
3740
  var BackgroundRepeaterColorIndicator = ({ value }) => {
2670
3741
  const colorVariable = useColorVariable(value);
2671
- return /* @__PURE__ */ React38.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
3742
+ return /* @__PURE__ */ React37.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
2672
3743
  };
2673
3744
  var BackgroundRepeaterLabel = ({ value }) => {
2674
3745
  const colorVariable = useColorVariable(value);
2675
- return /* @__PURE__ */ React38.createElement("span", null, colorVariable?.label);
3746
+ return /* @__PURE__ */ React37.createElement("span", null, colorVariable?.label);
2676
3747
  };
2677
3748
  var BoxShadowRepeaterColorIndicator = ({ value }) => {
2678
3749
  const colorVariable = useColorVariable(value);
2679
- return /* @__PURE__ */ React38.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
3750
+ return /* @__PURE__ */ React37.createElement(ColorIndicator, { component: "span", size: "inherit", value: colorVariable?.value });
2680
3751
  };
2681
3752
 
2682
3753
  // src/repeater-injections.ts
@@ -2714,27 +3785,38 @@ function init() {
2714
3785
  registerRepeaterInjections();
2715
3786
  registerControlReplacement({
2716
3787
  component: VariableControl,
2717
- condition: ({ value }) => hasAssignedVariable(value)
3788
+ condition: ({ value, placeholder }) => {
3789
+ if (hasVariableAssigned(value)) {
3790
+ return true;
3791
+ }
3792
+ if (value) {
3793
+ return false;
3794
+ }
3795
+ return hasVariableAssigned(placeholder);
3796
+ }
2718
3797
  });
2719
3798
  registerPopoverAction({
2720
3799
  id: "variables",
2721
3800
  useProps: usePropVariableAction
2722
3801
  });
2723
- service.init();
3802
+ service.init().then(() => {
3803
+ initMcp();
3804
+ });
2724
3805
  injectIntoTop({
2725
3806
  id: "canvas-style-variables-render",
2726
3807
  component: StyleVariablesRenderer
2727
3808
  });
2728
3809
  registerPanel(panel);
2729
3810
  }
2730
- function hasAssignedVariable(propValue) {
2731
- if (propValue && typeof propValue === "object" && "$$type" in propValue) {
2732
- return hasVariableType(propValue.$$type);
3811
+ function hasVariableAssigned(value) {
3812
+ if (isTransformable2(value)) {
3813
+ return hasVariableType(value.$$type);
2733
3814
  }
2734
3815
  return false;
2735
3816
  }
2736
3817
  export {
2737
3818
  init,
2738
- registerVariableType
3819
+ registerVariableType,
3820
+ registerVariableTypes
2739
3821
  };
2740
3822
  //# sourceMappingURL=index.mjs.map