@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.mjs CHANGED
@@ -42,98 +42,21 @@ import {
42
42
  import { useState } from "react";
43
43
  import { getElementInteractions } from "@elementor/editor-elements";
44
44
  import { __privateUseListenTo as useListenTo, windowEvent } from "@elementor/editor-v1-adapters";
45
- var useElementInteractions = (elementId) => {
46
- const [interactions, setInteractions] = useState(() => {
47
- const initial = getElementInteractions(elementId);
48
- return initial ?? { version: 1, items: [] };
49
- });
50
- useListenTo(
51
- windowEvent("elementor/element/update_interactions"),
52
- () => {
53
- const newInteractions = getElementInteractions(elementId);
54
- setInteractions(newInteractions ?? { version: 1, items: [] });
55
- },
56
- [elementId]
57
- );
58
- return interactions;
59
- };
60
45
 
61
- // src/contexts/interactions-context.tsx
62
- var InteractionsContext = createContext(null);
63
- var DEFAULT_INTERACTIONS = {
64
- version: 1,
65
- items: []
66
- };
67
- var InteractionsProvider = ({ children, elementId }) => {
68
- const rawInteractions = useElementInteractions(elementId);
69
- useEffect(() => {
70
- window.dispatchEvent(new CustomEvent("elementor/element/update_interactions"));
71
- }, []);
72
- const interactions = rawInteractions ?? DEFAULT_INTERACTIONS;
73
- const setInteractions = (value) => {
74
- const normalizedValue = value && value.items?.length === 0 ? void 0 : value;
75
- updateElementInteractions({
76
- elementId,
77
- interactions: normalizedValue
78
- });
79
- };
80
- const playInteractions = (interactionId) => {
81
- playElementInteractions(elementId, interactionId);
82
- };
83
- const contextValue = {
84
- interactions,
85
- setInteractions,
86
- playInteractions
87
- };
88
- return /* @__PURE__ */ React2.createElement(InteractionsContext.Provider, { value: contextValue }, children);
89
- };
90
- var useInteractionsContext = () => {
91
- const context = useContext(InteractionsContext);
92
- if (!context) {
93
- throw new Error("useInteractionsContext must be used within InteractionsProvider");
94
- }
95
- return context;
96
- };
97
-
98
- // src/contexts/popup-state-context.tsx
99
- import * as React3 from "react";
100
- import { createContext as createContext2, useCallback, useContext as useContext2, useState as useState2 } from "react";
101
- var PopupStateContext = createContext2(void 0);
102
- var PopupStateProvider = ({ children }) => {
103
- const [openByDefault, setOpenByDefault] = useState2(false);
104
- const triggerDefaultOpen = useCallback(() => {
105
- setOpenByDefault(true);
106
- }, []);
107
- const resetDefaultOpen = useCallback(() => {
108
- setOpenByDefault(false);
109
- }, []);
110
- return /* @__PURE__ */ React3.createElement(PopupStateContext.Provider, { value: { openByDefault, triggerDefaultOpen, resetDefaultOpen } }, children);
111
- };
112
-
113
- // src/components/interactions-list.tsx
114
- import * as React10 from "react";
115
- import { useCallback as useCallback5, useEffect as useEffect2, useMemo as useMemo3, useRef as useRef3 } from "react";
116
- import { Repeater } from "@elementor/editor-controls";
117
- import { InfoCircleFilledIcon, PlayerPlayIcon } from "@elementor/icons";
118
- import { Alert, AlertTitle, Box as Box2, IconButton, Tooltip } from "@elementor/ui";
119
- import { __ as __5 } from "@wordpress/i18n";
120
-
121
- // src/contexts/interactions-item-context.tsx
122
- import * as React4 from "react";
123
- import { createContext as createContext3, useContext as useContext3 } from "react";
124
- var InteractionItemContext = createContext3(null);
125
- function InteractionItemContextProvider({
126
- value,
127
- children
46
+ // src/interactions-controls-registry.ts
47
+ var controlsRegistry = /* @__PURE__ */ new Map();
48
+ function registerInteractionsControl({
49
+ type,
50
+ component,
51
+ options
128
52
  }) {
129
- return /* @__PURE__ */ React4.createElement(InteractionItemContext.Provider, { value }, children);
53
+ controlsRegistry.set(type, { type, component, options });
130
54
  }
131
- function useInteractionItemContext() {
132
- const context = useContext3(InteractionItemContext);
133
- if (!context) {
134
- throw new Error("useInteractionItemContext must be used within InteractionItemContextProvider");
135
- }
136
- return context;
55
+ function getInteractionsControl(type) {
56
+ return controlsRegistry.get(type);
57
+ }
58
+ function getInteractionsControlOptions(type) {
59
+ return controlsRegistry.get(type)?.options ?? [];
137
60
  }
138
61
 
139
62
  // src/utils/prop-value-utils.ts
@@ -389,6 +312,176 @@ var buildDisplayLabel = (item) => {
389
312
  return `${triggerLabel}: ${effectLabel} ${typeLabel}`;
390
313
  };
391
314
 
315
+ // src/utils/is-supported-interaction-item.ts
316
+ function isSupportedInteractionItem(interaction) {
317
+ const value = interaction.value;
318
+ const replay = extractBoolean(value.animation.value.config?.value.replay);
319
+ if (true === replay) {
320
+ return hasSupport("replay", "yes");
321
+ }
322
+ const trigger = extractString(value.trigger);
323
+ const easing = extractString(value.animation.value.config?.value.easing);
324
+ const effect = extractString(value.animation.value.effect);
325
+ const checks = [
326
+ ["trigger", trigger],
327
+ ["easing", easing],
328
+ ["effect", effect]
329
+ ];
330
+ return checks.every(([controlType, controlValue]) => {
331
+ if (controlValue === "" || controlValue === null) {
332
+ return true;
333
+ }
334
+ return hasSupport(controlType, controlValue);
335
+ });
336
+ }
337
+ function hasSupport(controlType, controlValue) {
338
+ const supportedOptions = getInteractionsControlOptions(controlType);
339
+ if (1 > supportedOptions.length) {
340
+ return true;
341
+ }
342
+ return supportedOptions.includes(controlValue);
343
+ }
344
+
345
+ // src/utils/filter-interactions.ts
346
+ var filterInteractions = (interactions) => {
347
+ return interactions.filter((interaction) => {
348
+ return isSupportedInteractionItem(interaction);
349
+ });
350
+ };
351
+
352
+ // src/hooks/use-element-interactions.ts
353
+ var useElementInteractions = (elementId) => {
354
+ const [interactions, setInteractions] = useState(() => {
355
+ const initial = getElementInteractions(elementId);
356
+ const filteredInteractions = filterInteractions(initial?.items ?? []);
357
+ return { version: initial?.version ?? 1, items: filteredInteractions };
358
+ });
359
+ useListenTo(
360
+ windowEvent("elementor/element/update_interactions"),
361
+ () => {
362
+ const newInteractions = getElementInteractions(elementId);
363
+ const filteredInteractions = filterInteractions(newInteractions?.items ?? []);
364
+ setInteractions({ version: newInteractions?.version ?? 1, items: filteredInteractions });
365
+ },
366
+ [elementId]
367
+ );
368
+ return interactions;
369
+ };
370
+
371
+ // src/contexts/interactions-context.tsx
372
+ var InteractionsContext = createContext(null);
373
+ var DEFAULT_INTERACTIONS = {
374
+ version: 1,
375
+ items: []
376
+ };
377
+ var InteractionsProvider = ({ children, elementId }) => {
378
+ const rawInteractions = useElementInteractions(elementId);
379
+ useEffect(() => {
380
+ window.dispatchEvent(new CustomEvent("elementor/element/update_interactions"));
381
+ }, []);
382
+ const interactions = rawInteractions ?? DEFAULT_INTERACTIONS;
383
+ const setInteractions = (value) => {
384
+ const normalizedValue = value && value.items?.length === 0 ? void 0 : value;
385
+ updateElementInteractions({
386
+ elementId,
387
+ interactions: normalizedValue
388
+ });
389
+ };
390
+ const playInteractions = (interactionId) => {
391
+ playElementInteractions(elementId, interactionId);
392
+ };
393
+ const contextValue = {
394
+ elementId,
395
+ interactions,
396
+ setInteractions,
397
+ playInteractions
398
+ };
399
+ return /* @__PURE__ */ React2.createElement(InteractionsContext.Provider, { value: contextValue }, children);
400
+ };
401
+ var useInteractionsContext = () => {
402
+ const context = useContext(InteractionsContext);
403
+ if (!context) {
404
+ throw new Error("useInteractionsContext must be used within InteractionsProvider");
405
+ }
406
+ return context;
407
+ };
408
+
409
+ // src/contexts/popup-state-context.tsx
410
+ import * as React3 from "react";
411
+ import { createContext as createContext2, useCallback, useContext as useContext2, useState as useState2 } from "react";
412
+ var PopupStateContext = createContext2(void 0);
413
+ var PopupStateProvider = ({ children }) => {
414
+ const [openByDefault, setOpenByDefault] = useState2(false);
415
+ const triggerDefaultOpen = useCallback(() => {
416
+ setOpenByDefault(true);
417
+ }, []);
418
+ const resetDefaultOpen = useCallback(() => {
419
+ setOpenByDefault(false);
420
+ }, []);
421
+ return /* @__PURE__ */ React3.createElement(PopupStateContext.Provider, { value: { openByDefault, triggerDefaultOpen, resetDefaultOpen } }, children);
422
+ };
423
+
424
+ // src/utils/tracking.ts
425
+ import { getElementLabel } from "@elementor/editor-elements";
426
+ import { getMixpanel } from "@elementor/events";
427
+ var TRIGGER_LABELS2 = {
428
+ load: "On page load",
429
+ scrollIn: "Scroll into view",
430
+ scrollOut: "Scroll out of view",
431
+ scrollOn: "While scrolling",
432
+ hover: "Hover",
433
+ click: "Click"
434
+ };
435
+ var capitalize2 = (s) => s.charAt(0).toUpperCase() + s.slice(1);
436
+ var trackInteractionCreated = (elementId, item) => {
437
+ const { dispatchEvent, config } = getMixpanel();
438
+ if (!config?.names?.interactions?.created) {
439
+ return;
440
+ }
441
+ const trigger = extractString(item.value.trigger);
442
+ const effect = extractString(item.value.animation.value.effect);
443
+ const type = extractString(item.value.animation.value.type);
444
+ dispatchEvent?.(config.names.interactions.created, {
445
+ app_type: config?.appTypes?.editor,
446
+ window_name: config?.appTypes?.editor,
447
+ interaction_type: config?.triggers?.click,
448
+ target_name: getElementLabel(elementId),
449
+ interaction_result: "interaction_created",
450
+ target_location: config?.locations?.widgetPanel,
451
+ location_l1: getElementLabel(elementId),
452
+ location_l2: "interactions",
453
+ interaction_description: "interaction_created",
454
+ interaction_trigger: TRIGGER_LABELS2[trigger] ?? capitalize2(trigger),
455
+ interaction_effect: effect === "custom" ? capitalize2(effect) : `${capitalize2(effect)} ${capitalize2(type)}`
456
+ });
457
+ };
458
+
459
+ // src/components/interactions-list.tsx
460
+ import * as React10 from "react";
461
+ import { useCallback as useCallback5, useEffect as useEffect2, useMemo as useMemo3, useRef as useRef3 } from "react";
462
+ import { Repeater } from "@elementor/editor-controls";
463
+ import { InfoCircleFilledIcon, PlayerPlayIcon } from "@elementor/icons";
464
+ import { Alert, AlertTitle, Box as Box2, IconButton, Tooltip } from "@elementor/ui";
465
+ import { __ as __5 } from "@wordpress/i18n";
466
+
467
+ // src/contexts/interactions-item-context.tsx
468
+ import * as React4 from "react";
469
+ import { createContext as createContext3, useContext as useContext3 } from "react";
470
+ var InteractionItemContext = createContext3(null);
471
+ function InteractionItemContextProvider({
472
+ value,
473
+ children
474
+ }) {
475
+ return /* @__PURE__ */ React4.createElement(InteractionItemContext.Provider, { value }, children);
476
+ }
477
+ function useInteractionItemContext() {
478
+ const context = useContext3(InteractionItemContext);
479
+ if (!context) {
480
+ throw new Error("useInteractionItemContext must be used within InteractionItemContextProvider");
481
+ }
482
+ return context;
483
+ }
484
+
392
485
  // src/components/interactions-list-item.tsx
393
486
  import * as React9 from "react";
394
487
  import { useCallback as useCallback4 } from "react";
@@ -402,19 +495,6 @@ import { PopoverContent } from "@elementor/editor-controls";
402
495
  import { Box, Divider, Grid as Grid2 } from "@elementor/ui";
403
496
  import { __ as __2 } from "@wordpress/i18n";
404
497
 
405
- // src/interactions-controls-registry.ts
406
- var controlsRegistry = /* @__PURE__ */ new Map();
407
- function registerInteractionsControl({
408
- type,
409
- component,
410
- options
411
- }) {
412
- controlsRegistry.set(type, { type, component, options });
413
- }
414
- function getInteractionsControl(type) {
415
- return controlsRegistry.get(type);
416
- }
417
-
418
498
  // src/utils/resolve-direction.ts
419
499
  var resolveDirection = (hasDirection, newEffect, newDirection, currentDirection, currentEffect) => {
420
500
  if (newEffect === "slide" && !newDirection) {
@@ -830,6 +910,7 @@ var InteractionsListItem = ({
830
910
  var MAX_NUMBER_OF_INTERACTIONS = 5;
831
911
  function InteractionsList(props) {
832
912
  const { interactions, onSelectInteractions, onPlayInteraction, triggerCreateOnShowEmpty } = props;
913
+ const { elementId } = useInteractionsContext();
833
914
  const hasInitializedRef = useRef3(false);
834
915
  const handleUpdateInteractions = useCallback5(
835
916
  (newInteractions) => {
@@ -855,13 +936,19 @@ function InteractionsList(props) {
855
936
  "elementor"
856
937
  ))) : void 0;
857
938
  const handleRepeaterChange = useCallback5(
858
- (newItems) => {
939
+ (newItems, _, meta) => {
859
940
  handleUpdateInteractions({
860
941
  ...interactions,
861
942
  items: newItems
862
943
  });
944
+ if (meta?.action?.type === "add") {
945
+ const addedItem = meta.action.payload[0]?.item;
946
+ if (addedItem) {
947
+ trackInteractionCreated(elementId, addedItem);
948
+ }
949
+ }
863
950
  },
864
- [interactions, handleUpdateInteractions]
951
+ [interactions, handleUpdateInteractions, elementId]
865
952
  );
866
953
  const handleInteractionChange = useCallback5(
867
954
  (index, newInteractionValue) => {
@@ -929,6 +1016,7 @@ function InteractionsTabContent({ elementId }) {
929
1016
  {
930
1017
  onCreateInteraction: () => {
931
1018
  firstInteractionState[1](true);
1019
+ trackInteractionCreated(elementId, createDefaultInteractionItem());
932
1020
  }
933
1021
  }
934
1022
  ));
@@ -1062,7 +1150,7 @@ var documentElementsInteractionsProvider = createInteractionsProvider({
1062
1150
  import {
1063
1151
  getContainer,
1064
1152
  getElementInteractions as getElementInteractions3,
1065
- getElementLabel,
1153
+ getElementLabel as getElementLabel2,
1066
1154
  getWidgetsCache,
1067
1155
  updateElementInteractions as updateElementInteractions2
1068
1156
  } from "@elementor/editor-elements";
@@ -1091,7 +1179,7 @@ function isAtomicContainer(container) {
1091
1179
  return Boolean(elementConfig?.atomic_props_schema);
1092
1180
  }
1093
1181
  function getTitleForContainers(containers) {
1094
- return containers.length > 1 ? __6("Elements", "elementor") : getElementLabel(containers[0].id);
1182
+ return containers.length > 1 ? __6("Elements", "elementor") : getElementLabel2(containers[0].id);
1095
1183
  }
1096
1184
  function normalizeClipboardInteractions(raw) {
1097
1185
  if (!raw) {
@@ -1848,7 +1936,7 @@ function init() {
1848
1936
  registerInteractionsControl({
1849
1937
  type: "replay",
1850
1938
  component: Replay,
1851
- options: ["true", "false"]
1939
+ options: ["no"]
1852
1940
  });
1853
1941
  registerInteractionsControl({
1854
1942
  type: "effectType",