@elementor/editor-variables 4.1.0-766 → 4.1.0-768

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -466,7 +466,7 @@ import {
466
466
  } from "@elementor/editor-panels";
467
467
  import { ConfirmationDialog as ConfirmationDialog2, SaveChangesDialog, SearchField, ThemeProvider, useDialog } from "@elementor/editor-ui";
468
468
  import { changeEditMode } from "@elementor/editor-v1-adapters";
469
- import { AlertTriangleFilledIcon as AlertTriangleFilledIcon2, ColorFilterIcon, TrashIcon } from "@elementor/icons";
469
+ import { AlertTriangleFilledIcon as AlertTriangleFilledIcon2, ColorFilterIcon, CopyIcon, TrashIcon } from "@elementor/icons";
470
470
  import {
471
471
  Alert,
472
472
  AlertAction,
@@ -1042,6 +1042,30 @@ var restoreVariable = (restoreId, label, value, type) => {
1042
1042
  return service.restore(restoreId, label, value, type).then(extractId);
1043
1043
  };
1044
1044
 
1045
+ // src/utils/duplicate-label.ts
1046
+ var COPY_SUFFIX = "-Copy";
1047
+ var trimToFit = (base, suffix) => {
1048
+ const combined = base + suffix;
1049
+ if (combined.length <= VARIABLE_LABEL_MAX_LENGTH) {
1050
+ return combined;
1051
+ }
1052
+ return base.slice(0, VARIABLE_LABEL_MAX_LENGTH - suffix.length) + suffix;
1053
+ };
1054
+ var generateDuplicateLabel = (originalLabel, existingLabels) => {
1055
+ const labelsSet = new Set(existingLabels);
1056
+ const firstCandidate = trimToFit(originalLabel, COPY_SUFFIX);
1057
+ if (!labelsSet.has(firstCandidate)) {
1058
+ return firstCandidate;
1059
+ }
1060
+ for (let i = 2; i <= labelsSet.size + 1; i++) {
1061
+ const candidate = trimToFit(originalLabel, `${COPY_SUFFIX}-${i}`);
1062
+ if (!labelsSet.has(candidate)) {
1063
+ return candidate;
1064
+ }
1065
+ }
1066
+ return firstCandidate;
1067
+ };
1068
+
1045
1069
  // src/components/variables-manager/hooks/use-variables-manager-state.ts
1046
1070
  var useVariablesManagerState = () => {
1047
1071
  const [variables, setVariables] = useState2(() => getVariables(false));
@@ -1069,6 +1093,26 @@ var useVariablesManagerState = () => {
1069
1093
  setIsDirty(true);
1070
1094
  return newId;
1071
1095
  }, []);
1096
+ const duplicateVariable = useCallback3((sourceId) => {
1097
+ const newId = generateTempId();
1098
+ setVariables((prev) => {
1099
+ const source = prev[sourceId];
1100
+ if (!source || source.deleted) {
1101
+ return prev;
1102
+ }
1103
+ const existingLabels = Object.values(prev).filter((v) => !v.deleted).map((v) => v.label);
1104
+ return {
1105
+ ...prev,
1106
+ [newId]: {
1107
+ label: generateDuplicateLabel(source.label, existingLabels),
1108
+ value: source.value,
1109
+ type: source.type
1110
+ }
1111
+ };
1112
+ });
1113
+ setIsDirty(true);
1114
+ return newId;
1115
+ }, []);
1072
1116
  const handleDeleteVariable = useCallback3((itemId) => {
1073
1117
  setDeletedVariables((prev) => [...prev, itemId]);
1074
1118
  setVariables((prev) => ({ ...prev, [itemId]: { ...prev[itemId], deleted: true } }));
@@ -1117,6 +1161,7 @@ var useVariablesManagerState = () => {
1117
1161
  isSaveDisabled,
1118
1162
  handleOnChange,
1119
1163
  createVariable: createVariable2,
1164
+ duplicateVariable,
1120
1165
  handleDeleteVariable,
1121
1166
  handleStartSync,
1122
1167
  handleStopSync,
@@ -1940,6 +1985,7 @@ function VariablesManagerPanel() {
1940
1985
  isSaveDisabled,
1941
1986
  handleOnChange,
1942
1987
  createVariable: createVariable2,
1988
+ duplicateVariable,
1943
1989
  handleDeleteVariable,
1944
1990
  handleStartSync: startSyncFromState,
1945
1991
  handleStopSync: stopSyncFromState,
@@ -2047,6 +2093,20 @@ function VariablesManagerPanel() {
2047
2093
  onStopSync: handleStopSync
2048
2094
  }
2049
2095
  });
2096
+ const duplicateAction = {
2097
+ name: __10("Duplicate", "elementor"),
2098
+ icon: CopyIcon,
2099
+ color: "text.primary",
2100
+ onClick: (itemId) => {
2101
+ const newId = duplicateVariable(itemId);
2102
+ startAutoEdit(newId);
2103
+ const variableTypeOptions = getVariableType(variable.type);
2104
+ trackVariablesManagerEvent({
2105
+ action: "duplicate",
2106
+ varType: variableTypeOptions?.variableType
2107
+ });
2108
+ }
2109
+ };
2050
2110
  const deleteAction = {
2051
2111
  name: __10("Delete", "elementor"),
2052
2112
  icon: TrashIcon,
@@ -2060,9 +2120,9 @@ function VariablesManagerPanel() {
2060
2120
  }
2061
2121
  }
2062
2122
  };
2063
- return [...typeActions, deleteAction];
2123
+ return [...typeActions, duplicateAction, deleteAction];
2064
2124
  },
2065
- [variables, handleStartSync, handleStopSync]
2125
+ [variables, handleStartSync, handleStopSync, duplicateVariable, startAutoEdit]
2066
2126
  );
2067
2127
  const hasVariables = Object.keys(variables).length > 0;
2068
2128
  return /* @__PURE__ */ React14.createElement(ThemeProvider, null, /* @__PURE__ */ React14.createElement(Panel, null, /* @__PURE__ */ React14.createElement(