@elementor/editor-interactions 4.0.0-678 → 4.0.0-680

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.js CHANGED
@@ -113,98 +113,21 @@ var import_editor_elements2 = require("@elementor/editor-elements");
113
113
  var import_react = require("react");
114
114
  var import_editor_elements = require("@elementor/editor-elements");
115
115
  var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
116
- var useElementInteractions = (elementId) => {
117
- const [interactions, setInteractions] = (0, import_react.useState)(() => {
118
- const initial = (0, import_editor_elements.getElementInteractions)(elementId);
119
- return initial ?? { version: 1, items: [] };
120
- });
121
- (0, import_editor_v1_adapters.__privateUseListenTo)(
122
- (0, import_editor_v1_adapters.windowEvent)("elementor/element/update_interactions"),
123
- () => {
124
- const newInteractions = (0, import_editor_elements.getElementInteractions)(elementId);
125
- setInteractions(newInteractions ?? { version: 1, items: [] });
126
- },
127
- [elementId]
128
- );
129
- return interactions;
130
- };
131
116
 
132
- // src/contexts/interactions-context.tsx
133
- var InteractionsContext = (0, import_react2.createContext)(null);
134
- var DEFAULT_INTERACTIONS = {
135
- version: 1,
136
- items: []
137
- };
138
- var InteractionsProvider = ({ children, elementId }) => {
139
- const rawInteractions = useElementInteractions(elementId);
140
- (0, import_react2.useEffect)(() => {
141
- window.dispatchEvent(new CustomEvent("elementor/element/update_interactions"));
142
- }, []);
143
- const interactions = rawInteractions ?? DEFAULT_INTERACTIONS;
144
- const setInteractions = (value) => {
145
- const normalizedValue = value && value.items?.length === 0 ? void 0 : value;
146
- (0, import_editor_elements2.updateElementInteractions)({
147
- elementId,
148
- interactions: normalizedValue
149
- });
150
- };
151
- const playInteractions = (interactionId) => {
152
- (0, import_editor_elements2.playElementInteractions)(elementId, interactionId);
153
- };
154
- const contextValue = {
155
- interactions,
156
- setInteractions,
157
- playInteractions
158
- };
159
- return /* @__PURE__ */ React2.createElement(InteractionsContext.Provider, { value: contextValue }, children);
160
- };
161
- var useInteractionsContext = () => {
162
- const context = (0, import_react2.useContext)(InteractionsContext);
163
- if (!context) {
164
- throw new Error("useInteractionsContext must be used within InteractionsProvider");
165
- }
166
- return context;
167
- };
168
-
169
- // src/contexts/popup-state-context.tsx
170
- var React3 = __toESM(require("react"));
171
- var import_react3 = require("react");
172
- var PopupStateContext = (0, import_react3.createContext)(void 0);
173
- var PopupStateProvider = ({ children }) => {
174
- const [openByDefault, setOpenByDefault] = (0, import_react3.useState)(false);
175
- const triggerDefaultOpen = (0, import_react3.useCallback)(() => {
176
- setOpenByDefault(true);
177
- }, []);
178
- const resetDefaultOpen = (0, import_react3.useCallback)(() => {
179
- setOpenByDefault(false);
180
- }, []);
181
- return /* @__PURE__ */ React3.createElement(PopupStateContext.Provider, { value: { openByDefault, triggerDefaultOpen, resetDefaultOpen } }, children);
182
- };
183
-
184
- // src/components/interactions-list.tsx
185
- var React10 = __toESM(require("react"));
186
- var import_react9 = require("react");
187
- var import_editor_controls5 = require("@elementor/editor-controls");
188
- var import_icons2 = require("@elementor/icons");
189
- var import_ui6 = require("@elementor/ui");
190
- var import_i18n5 = require("@wordpress/i18n");
191
-
192
- // src/contexts/interactions-item-context.tsx
193
- var React4 = __toESM(require("react"));
194
- var import_react4 = require("react");
195
- var InteractionItemContext = (0, import_react4.createContext)(null);
196
- function InteractionItemContextProvider({
197
- value,
198
- children
117
+ // src/interactions-controls-registry.ts
118
+ var controlsRegistry = /* @__PURE__ */ new Map();
119
+ function registerInteractionsControl({
120
+ type,
121
+ component,
122
+ options
199
123
  }) {
200
- return /* @__PURE__ */ React4.createElement(InteractionItemContext.Provider, { value }, children);
124
+ controlsRegistry.set(type, { type, component, options });
201
125
  }
202
- function useInteractionItemContext() {
203
- const context = (0, import_react4.useContext)(InteractionItemContext);
204
- if (!context) {
205
- throw new Error("useInteractionItemContext must be used within InteractionItemContextProvider");
206
- }
207
- return context;
126
+ function getInteractionsControl(type) {
127
+ return controlsRegistry.get(type);
128
+ }
129
+ function getInteractionsControlOptions(type) {
130
+ return controlsRegistry.get(type)?.options ?? [];
208
131
  }
209
132
 
210
133
  // src/utils/prop-value-utils.ts
@@ -460,6 +383,176 @@ var buildDisplayLabel = (item) => {
460
383
  return `${triggerLabel}: ${effectLabel} ${typeLabel}`;
461
384
  };
462
385
 
386
+ // src/utils/is-supported-interaction-item.ts
387
+ function isSupportedInteractionItem(interaction) {
388
+ const value = interaction.value;
389
+ const replay = extractBoolean(value.animation.value.config?.value.replay);
390
+ if (true === replay) {
391
+ return hasSupport("replay", "yes");
392
+ }
393
+ const trigger = extractString(value.trigger);
394
+ const easing = extractString(value.animation.value.config?.value.easing);
395
+ const effect = extractString(value.animation.value.effect);
396
+ const checks = [
397
+ ["trigger", trigger],
398
+ ["easing", easing],
399
+ ["effect", effect]
400
+ ];
401
+ return checks.every(([controlType, controlValue]) => {
402
+ if (controlValue === "" || controlValue === null) {
403
+ return true;
404
+ }
405
+ return hasSupport(controlType, controlValue);
406
+ });
407
+ }
408
+ function hasSupport(controlType, controlValue) {
409
+ const supportedOptions = getInteractionsControlOptions(controlType);
410
+ if (1 > supportedOptions.length) {
411
+ return true;
412
+ }
413
+ return supportedOptions.includes(controlValue);
414
+ }
415
+
416
+ // src/utils/filter-interactions.ts
417
+ var filterInteractions = (interactions) => {
418
+ return interactions.filter((interaction) => {
419
+ return isSupportedInteractionItem(interaction);
420
+ });
421
+ };
422
+
423
+ // src/hooks/use-element-interactions.ts
424
+ var useElementInteractions = (elementId) => {
425
+ const [interactions, setInteractions] = (0, import_react.useState)(() => {
426
+ const initial = (0, import_editor_elements.getElementInteractions)(elementId);
427
+ const filteredInteractions = filterInteractions(initial?.items ?? []);
428
+ return { version: initial?.version ?? 1, items: filteredInteractions };
429
+ });
430
+ (0, import_editor_v1_adapters.__privateUseListenTo)(
431
+ (0, import_editor_v1_adapters.windowEvent)("elementor/element/update_interactions"),
432
+ () => {
433
+ const newInteractions = (0, import_editor_elements.getElementInteractions)(elementId);
434
+ const filteredInteractions = filterInteractions(newInteractions?.items ?? []);
435
+ setInteractions({ version: newInteractions?.version ?? 1, items: filteredInteractions });
436
+ },
437
+ [elementId]
438
+ );
439
+ return interactions;
440
+ };
441
+
442
+ // src/contexts/interactions-context.tsx
443
+ var InteractionsContext = (0, import_react2.createContext)(null);
444
+ var DEFAULT_INTERACTIONS = {
445
+ version: 1,
446
+ items: []
447
+ };
448
+ var InteractionsProvider = ({ children, elementId }) => {
449
+ const rawInteractions = useElementInteractions(elementId);
450
+ (0, import_react2.useEffect)(() => {
451
+ window.dispatchEvent(new CustomEvent("elementor/element/update_interactions"));
452
+ }, []);
453
+ const interactions = rawInteractions ?? DEFAULT_INTERACTIONS;
454
+ const setInteractions = (value) => {
455
+ const normalizedValue = value && value.items?.length === 0 ? void 0 : value;
456
+ (0, import_editor_elements2.updateElementInteractions)({
457
+ elementId,
458
+ interactions: normalizedValue
459
+ });
460
+ };
461
+ const playInteractions = (interactionId) => {
462
+ (0, import_editor_elements2.playElementInteractions)(elementId, interactionId);
463
+ };
464
+ const contextValue = {
465
+ elementId,
466
+ interactions,
467
+ setInteractions,
468
+ playInteractions
469
+ };
470
+ return /* @__PURE__ */ React2.createElement(InteractionsContext.Provider, { value: contextValue }, children);
471
+ };
472
+ var useInteractionsContext = () => {
473
+ const context = (0, import_react2.useContext)(InteractionsContext);
474
+ if (!context) {
475
+ throw new Error("useInteractionsContext must be used within InteractionsProvider");
476
+ }
477
+ return context;
478
+ };
479
+
480
+ // src/contexts/popup-state-context.tsx
481
+ var React3 = __toESM(require("react"));
482
+ var import_react3 = require("react");
483
+ var PopupStateContext = (0, import_react3.createContext)(void 0);
484
+ var PopupStateProvider = ({ children }) => {
485
+ const [openByDefault, setOpenByDefault] = (0, import_react3.useState)(false);
486
+ const triggerDefaultOpen = (0, import_react3.useCallback)(() => {
487
+ setOpenByDefault(true);
488
+ }, []);
489
+ const resetDefaultOpen = (0, import_react3.useCallback)(() => {
490
+ setOpenByDefault(false);
491
+ }, []);
492
+ return /* @__PURE__ */ React3.createElement(PopupStateContext.Provider, { value: { openByDefault, triggerDefaultOpen, resetDefaultOpen } }, children);
493
+ };
494
+
495
+ // src/utils/tracking.ts
496
+ var import_editor_elements3 = require("@elementor/editor-elements");
497
+ var import_events = require("@elementor/events");
498
+ var TRIGGER_LABELS2 = {
499
+ load: "On page load",
500
+ scrollIn: "Scroll into view",
501
+ scrollOut: "Scroll out of view",
502
+ scrollOn: "While scrolling",
503
+ hover: "Hover",
504
+ click: "Click"
505
+ };
506
+ var capitalize2 = (s) => s.charAt(0).toUpperCase() + s.slice(1);
507
+ var trackInteractionCreated = (elementId, item) => {
508
+ const { dispatchEvent, config } = (0, import_events.getMixpanel)();
509
+ if (!config?.names?.interactions?.created) {
510
+ return;
511
+ }
512
+ const trigger = extractString(item.value.trigger);
513
+ const effect = extractString(item.value.animation.value.effect);
514
+ const type = extractString(item.value.animation.value.type);
515
+ dispatchEvent?.(config.names.interactions.created, {
516
+ app_type: config?.appTypes?.editor,
517
+ window_name: config?.appTypes?.editor,
518
+ interaction_type: config?.triggers?.click,
519
+ target_name: (0, import_editor_elements3.getElementLabel)(elementId),
520
+ interaction_result: "interaction_created",
521
+ target_location: config?.locations?.widgetPanel,
522
+ location_l1: (0, import_editor_elements3.getElementLabel)(elementId),
523
+ location_l2: "interactions",
524
+ interaction_description: "interaction_created",
525
+ interaction_trigger: TRIGGER_LABELS2[trigger] ?? capitalize2(trigger),
526
+ interaction_effect: effect === "custom" ? capitalize2(effect) : `${capitalize2(effect)} ${capitalize2(type)}`
527
+ });
528
+ };
529
+
530
+ // src/components/interactions-list.tsx
531
+ var React10 = __toESM(require("react"));
532
+ var import_react9 = require("react");
533
+ var import_editor_controls5 = require("@elementor/editor-controls");
534
+ var import_icons2 = require("@elementor/icons");
535
+ var import_ui6 = require("@elementor/ui");
536
+ var import_i18n5 = require("@wordpress/i18n");
537
+
538
+ // src/contexts/interactions-item-context.tsx
539
+ var React4 = __toESM(require("react"));
540
+ var import_react4 = require("react");
541
+ var InteractionItemContext = (0, import_react4.createContext)(null);
542
+ function InteractionItemContextProvider({
543
+ value,
544
+ children
545
+ }) {
546
+ return /* @__PURE__ */ React4.createElement(InteractionItemContext.Provider, { value }, children);
547
+ }
548
+ function useInteractionItemContext() {
549
+ const context = (0, import_react4.useContext)(InteractionItemContext);
550
+ if (!context) {
551
+ throw new Error("useInteractionItemContext must be used within InteractionItemContextProvider");
552
+ }
553
+ return context;
554
+ }
555
+
463
556
  // src/components/interactions-list-item.tsx
464
557
  var React9 = __toESM(require("react"));
465
558
  var import_react8 = require("react");
@@ -473,19 +566,6 @@ var import_editor_controls3 = require("@elementor/editor-controls");
473
566
  var import_ui3 = require("@elementor/ui");
474
567
  var import_i18n2 = require("@wordpress/i18n");
475
568
 
476
- // src/interactions-controls-registry.ts
477
- var controlsRegistry = /* @__PURE__ */ new Map();
478
- function registerInteractionsControl({
479
- type,
480
- component,
481
- options
482
- }) {
483
- controlsRegistry.set(type, { type, component, options });
484
- }
485
- function getInteractionsControl(type) {
486
- return controlsRegistry.get(type);
487
- }
488
-
489
569
  // src/utils/resolve-direction.ts
490
570
  var resolveDirection = (hasDirection, newEffect, newDirection, currentDirection, currentEffect) => {
491
571
  if (newEffect === "slide" && !newDirection) {
@@ -901,6 +981,7 @@ var InteractionsListItem = ({
901
981
  var MAX_NUMBER_OF_INTERACTIONS = 5;
902
982
  function InteractionsList(props) {
903
983
  const { interactions, onSelectInteractions, onPlayInteraction, triggerCreateOnShowEmpty } = props;
984
+ const { elementId } = useInteractionsContext();
904
985
  const hasInitializedRef = (0, import_react9.useRef)(false);
905
986
  const handleUpdateInteractions = (0, import_react9.useCallback)(
906
987
  (newInteractions) => {
@@ -926,13 +1007,19 @@ function InteractionsList(props) {
926
1007
  "elementor"
927
1008
  ))) : void 0;
928
1009
  const handleRepeaterChange = (0, import_react9.useCallback)(
929
- (newItems) => {
1010
+ (newItems, _, meta) => {
930
1011
  handleUpdateInteractions({
931
1012
  ...interactions,
932
1013
  items: newItems
933
1014
  });
1015
+ if (meta?.action?.type === "add") {
1016
+ const addedItem = meta.action.payload[0]?.item;
1017
+ if (addedItem) {
1018
+ trackInteractionCreated(elementId, addedItem);
1019
+ }
1020
+ }
934
1021
  },
935
- [interactions, handleUpdateInteractions]
1022
+ [interactions, handleUpdateInteractions, elementId]
936
1023
  );
937
1024
  const handleInteractionChange = (0, import_react9.useCallback)(
938
1025
  (index, newInteractionValue) => {
@@ -1000,6 +1087,7 @@ function InteractionsTabContent({ elementId }) {
1000
1087
  {
1001
1088
  onCreateInteraction: () => {
1002
1089
  firstInteractionState[1](true);
1090
+ trackInteractionCreated(elementId, createDefaultInteractionItem());
1003
1091
  }
1004
1092
  }
1005
1093
  ));
@@ -1090,12 +1178,12 @@ function createInteractionsProvider({
1090
1178
  }
1091
1179
 
1092
1180
  // src/providers/document-elements-interactions-provider.ts
1093
- var import_editor_elements3 = require("@elementor/editor-elements");
1181
+ var import_editor_elements4 = require("@elementor/editor-elements");
1094
1182
  var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
1095
1183
  var ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX = "document-elements-interactions-";
1096
1184
  var documentElementsInteractionsProvider = createInteractionsProvider({
1097
1185
  key: () => {
1098
- const documentId = (0, import_editor_elements3.getCurrentDocumentId)();
1186
+ const documentId = (0, import_editor_elements4.getCurrentDocumentId)();
1099
1187
  if (!documentId) {
1100
1188
  const pendingKey = `${ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX}pending`;
1101
1189
  return pendingKey;
@@ -1109,16 +1197,16 @@ var documentElementsInteractionsProvider = createInteractionsProvider({
1109
1197
  },
1110
1198
  actions: {
1111
1199
  all: () => {
1112
- const elements = (0, import_editor_elements3.getElements)();
1200
+ const elements = (0, import_editor_elements4.getElements)();
1113
1201
  const filtered = elements.filter((element) => {
1114
- const interactions = (0, import_editor_elements3.getElementInteractions)(element.id);
1202
+ const interactions = (0, import_editor_elements4.getElementInteractions)(element.id);
1115
1203
  if (!interactions) {
1116
1204
  return false;
1117
1205
  }
1118
1206
  return interactions?.items?.length > 0;
1119
1207
  });
1120
1208
  return filtered.map((element) => {
1121
- const interactions = (0, import_editor_elements3.getElementInteractions)(element.id);
1209
+ const interactions = (0, import_editor_elements4.getElementInteractions)(element.id);
1122
1210
  return {
1123
1211
  elementId: element.id,
1124
1212
  dataId: element.id,
@@ -1130,7 +1218,7 @@ var documentElementsInteractionsProvider = createInteractionsProvider({
1130
1218
  });
1131
1219
 
1132
1220
  // src/commands/paste-interactions.ts
1133
- var import_editor_elements4 = require("@elementor/editor-elements");
1221
+ var import_editor_elements5 = require("@elementor/editor-elements");
1134
1222
  var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
1135
1223
  var import_i18n6 = require("@wordpress/i18n");
1136
1224
 
@@ -1147,12 +1235,12 @@ function getClipboardElements(storageKey = "clipboard") {
1147
1235
  // src/commands/paste-interactions.ts
1148
1236
  function isAtomicContainer(container) {
1149
1237
  const type = container?.model.get("widgetType") || container?.model.get("elType");
1150
- const widgetsCache = (0, import_editor_elements4.getWidgetsCache)();
1238
+ const widgetsCache = (0, import_editor_elements5.getWidgetsCache)();
1151
1239
  const elementConfig = widgetsCache?.[type];
1152
1240
  return Boolean(elementConfig?.atomic_props_schema);
1153
1241
  }
1154
1242
  function getTitleForContainers(containers) {
1155
- return containers.length > 1 ? (0, import_i18n6.__)("Elements", "elementor") : (0, import_editor_elements4.getElementLabel)(containers[0].id);
1243
+ return containers.length > 1 ? (0, import_i18n6.__)("Elements", "elementor") : (0, import_editor_elements5.getElementLabel)(containers[0].id);
1156
1244
  }
1157
1245
  function normalizeClipboardInteractions(raw) {
1158
1246
  if (!raw) {
@@ -1180,8 +1268,8 @@ function initPasteInteractionsCommand() {
1180
1268
  const pasted = regenerateInteractionIds(newInteractions);
1181
1269
  return containers.map((container) => {
1182
1270
  const elementId = container.id;
1183
- const previous = (0, import_editor_elements4.getElementInteractions)(elementId);
1184
- (0, import_editor_elements4.updateElementInteractions)({
1271
+ const previous = (0, import_editor_elements5.getElementInteractions)(elementId);
1272
+ (0, import_editor_elements5.updateElementInteractions)({
1185
1273
  elementId,
1186
1274
  interactions: pasted
1187
1275
  });
@@ -1190,7 +1278,7 @@ function initPasteInteractionsCommand() {
1190
1278
  },
1191
1279
  undo: (_, revertData) => {
1192
1280
  revertData.forEach(({ elementId, previous }) => {
1193
- (0, import_editor_elements4.updateElementInteractions)({
1281
+ (0, import_editor_elements5.updateElementInteractions)({
1194
1282
  elementId,
1195
1283
  interactions: previous.items?.length ? previous : void 0
1196
1284
  });
@@ -1218,7 +1306,7 @@ function initPasteInteractionsCommand() {
1218
1306
  if (!newInteractions) {
1219
1307
  return;
1220
1308
  }
1221
- const existingContainers = containers.filter((c) => (0, import_editor_elements4.getContainer)(c.id));
1309
+ const existingContainers = containers.filter((c) => (0, import_editor_elements5.getContainer)(c.id));
1222
1310
  const validContainers = existingContainers.filter(isAtomicContainer);
1223
1311
  if (!validContainers.length) {
1224
1312
  return;
@@ -1554,7 +1642,7 @@ function Trigger({ value, onChange }) {
1554
1642
  }
1555
1643
 
1556
1644
  // src/hooks/on-duplicate.ts
1557
- var import_editor_elements5 = require("@elementor/editor-elements");
1645
+ var import_editor_elements6 = require("@elementor/editor-elements");
1558
1646
  var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
1559
1647
  function initCleanInteractionIdsOnDuplicate() {
1560
1648
  (0, import_editor_v1_adapters4.registerDataHook)("after", "document/elements/duplicate", (_args, result) => {
@@ -1565,16 +1653,16 @@ function initCleanInteractionIdsOnDuplicate() {
1565
1653
  });
1566
1654
  }
1567
1655
  function cleanInteractionIdsRecursive(elementId) {
1568
- const container = (0, import_editor_elements5.getContainer)(elementId);
1656
+ const container = (0, import_editor_elements6.getContainer)(elementId);
1569
1657
  if (!container) {
1570
1658
  return;
1571
1659
  }
1572
- (0, import_editor_elements5.getAllDescendants)(container).forEach((element) => {
1660
+ (0, import_editor_elements6.getAllDescendants)(container).forEach((element) => {
1573
1661
  cleanInteractionIds(element.id);
1574
1662
  });
1575
1663
  }
1576
1664
  function cleanInteractionIds(elementId) {
1577
- const container = (0, import_editor_elements5.getContainer)(elementId);
1665
+ const container = (0, import_editor_elements6.getContainer)(elementId);
1578
1666
  if (!container) {
1579
1667
  return;
1580
1668
  }
@@ -1673,7 +1761,7 @@ var initInteractionsSchemaResource = (reg) => {
1673
1761
  };
1674
1762
 
1675
1763
  // src/mcp/tools/manage-element-interaction-tool.ts
1676
- var import_editor_elements6 = require("@elementor/editor-elements");
1764
+ var import_editor_elements7 = require("@elementor/editor-elements");
1677
1765
  var import_schema3 = require("@elementor/schema");
1678
1766
  var import_utils2 = require("@elementor/utils");
1679
1767
  var EMPTY_INTERACTIONS = {
@@ -1804,7 +1892,7 @@ var initManageElementInteractionTool = (reg) => {
1804
1892
  items: updatedItems
1805
1893
  };
1806
1894
  try {
1807
- (0, import_editor_elements6.updateElementInteractions)({ elementId, interactions: updatedInteractions });
1895
+ (0, import_editor_elements7.updateElementInteractions)({ elementId, interactions: updatedInteractions });
1808
1896
  } catch (error) {
1809
1897
  throw new Error(
1810
1898
  `Failed to update interactions for element "${elementId}": ${error instanceof Error ? error.message : "Unknown error"}`
@@ -1909,7 +1997,7 @@ function init() {
1909
1997
  registerInteractionsControl({
1910
1998
  type: "replay",
1911
1999
  component: Replay,
1912
- options: ["true", "false"]
2000
+ options: ["no"]
1913
2001
  });
1914
2002
  registerInteractionsControl({
1915
2003
  type: "effectType",