@elementor/editor-interactions 4.0.0-manual → 4.1.0-685
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.d.mts +85 -5
- package/dist/index.d.ts +85 -5
- package/dist/index.js +563 -217
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +515 -183
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -11
- package/src/commands/get-clipboard-elements.ts +11 -0
- package/src/commands/paste-interactions.ts +136 -0
- package/src/components/controls/easing.tsx +3 -0
- package/src/components/controls/effect.tsx +3 -0
- package/src/components/controls/replay.tsx +3 -0
- package/src/components/controls/trigger.tsx +3 -0
- package/src/components/interaction-details.tsx +53 -1
- package/src/components/interactions-list.tsx +16 -3
- package/src/components/interactions-tab.tsx +4 -1
- package/src/contexts/interactions-context.tsx +4 -1
- package/src/hooks/use-element-interactions.ts +26 -0
- package/src/index.ts +25 -0
- package/src/init.ts +3 -1
- package/src/interactions-controls-registry.ts +15 -3
- package/src/mcp/tools/manage-element-interaction-tool.ts +40 -5
- package/src/types.ts +6 -1
- package/src/ui/interactions-promotion-chip.tsx +14 -4
- package/src/ui/promotion-select.tsx +4 -0
- package/src/utils/filter-interactions.ts +9 -0
- package/src/utils/get-interactions-config.ts +1 -11
- package/src/utils/is-supported-interaction-item.ts +39 -0
- package/src/utils/prop-value-utils.ts +35 -14
- package/src/utils/tracking.ts +42 -0
package/dist/index.mjs
CHANGED
|
@@ -26,8 +26,7 @@ var EmptyState = ({ onCreateInteraction }) => {
|
|
|
26
26
|
|
|
27
27
|
// src/components/interactions-tab.tsx
|
|
28
28
|
import * as React11 from "react";
|
|
29
|
-
import { useCallback as useCallback6, useState as
|
|
30
|
-
import { useElementInteractions as useElementInteractions2 } from "@elementor/editor-elements";
|
|
29
|
+
import { useCallback as useCallback6, useState as useState4 } from "react";
|
|
31
30
|
import { SessionStorageProvider } from "@elementor/session";
|
|
32
31
|
import { Stack as Stack3 } from "@elementor/ui";
|
|
33
32
|
|
|
@@ -36,84 +35,28 @@ import * as React2 from "react";
|
|
|
36
35
|
import { createContext, useContext, useEffect } from "react";
|
|
37
36
|
import {
|
|
38
37
|
playElementInteractions,
|
|
39
|
-
updateElementInteractions
|
|
40
|
-
useElementInteractions
|
|
38
|
+
updateElementInteractions
|
|
41
39
|
} from "@elementor/editor-elements";
|
|
42
|
-
var InteractionsContext = createContext(null);
|
|
43
|
-
var DEFAULT_INTERACTIONS = {
|
|
44
|
-
version: 1,
|
|
45
|
-
items: []
|
|
46
|
-
};
|
|
47
|
-
var InteractionsProvider = ({ children, elementId }) => {
|
|
48
|
-
const rawInteractions = useElementInteractions(elementId);
|
|
49
|
-
useEffect(() => {
|
|
50
|
-
window.dispatchEvent(new CustomEvent("elementor/element/update_interactions"));
|
|
51
|
-
}, []);
|
|
52
|
-
const interactions = rawInteractions ?? DEFAULT_INTERACTIONS;
|
|
53
|
-
const setInteractions = (value) => {
|
|
54
|
-
const normalizedValue = value && value.items?.length === 0 ? void 0 : value;
|
|
55
|
-
updateElementInteractions({
|
|
56
|
-
elementId,
|
|
57
|
-
interactions: normalizedValue
|
|
58
|
-
});
|
|
59
|
-
};
|
|
60
|
-
const playInteractions = (interactionId) => {
|
|
61
|
-
playElementInteractions(elementId, interactionId);
|
|
62
|
-
};
|
|
63
|
-
const contextValue = {
|
|
64
|
-
interactions,
|
|
65
|
-
setInteractions,
|
|
66
|
-
playInteractions
|
|
67
|
-
};
|
|
68
|
-
return /* @__PURE__ */ React2.createElement(InteractionsContext.Provider, { value: contextValue }, children);
|
|
69
|
-
};
|
|
70
|
-
var useInteractionsContext = () => {
|
|
71
|
-
const context = useContext(InteractionsContext);
|
|
72
|
-
if (!context) {
|
|
73
|
-
throw new Error("useInteractionsContext must be used within InteractionsProvider");
|
|
74
|
-
}
|
|
75
|
-
return context;
|
|
76
|
-
};
|
|
77
40
|
|
|
78
|
-
// src/
|
|
79
|
-
import
|
|
80
|
-
import {
|
|
81
|
-
|
|
82
|
-
var PopupStateProvider = ({ children }) => {
|
|
83
|
-
const [openByDefault, setOpenByDefault] = useState(false);
|
|
84
|
-
const triggerDefaultOpen = useCallback(() => {
|
|
85
|
-
setOpenByDefault(true);
|
|
86
|
-
}, []);
|
|
87
|
-
const resetDefaultOpen = useCallback(() => {
|
|
88
|
-
setOpenByDefault(false);
|
|
89
|
-
}, []);
|
|
90
|
-
return /* @__PURE__ */ React3.createElement(PopupStateContext.Provider, { value: { openByDefault, triggerDefaultOpen, resetDefaultOpen } }, children);
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// src/components/interactions-list.tsx
|
|
94
|
-
import * as React10 from "react";
|
|
95
|
-
import { useCallback as useCallback5, useEffect as useEffect2, useMemo as useMemo3, useRef as useRef3 } from "react";
|
|
96
|
-
import { Repeater } from "@elementor/editor-controls";
|
|
97
|
-
import { InfoCircleFilledIcon, PlayerPlayIcon } from "@elementor/icons";
|
|
98
|
-
import { Alert, AlertTitle, Box as Box2, IconButton, Tooltip } from "@elementor/ui";
|
|
99
|
-
import { __ as __5 } from "@wordpress/i18n";
|
|
41
|
+
// src/hooks/use-element-interactions.ts
|
|
42
|
+
import { useState } from "react";
|
|
43
|
+
import { getElementInteractions } from "@elementor/editor-elements";
|
|
44
|
+
import { __privateUseListenTo as useListenTo, windowEvent } from "@elementor/editor-v1-adapters";
|
|
100
45
|
|
|
101
|
-
// src/
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
children
|
|
46
|
+
// src/interactions-controls-registry.ts
|
|
47
|
+
var controlsRegistry = /* @__PURE__ */ new Map();
|
|
48
|
+
function registerInteractionsControl({
|
|
49
|
+
type,
|
|
50
|
+
component,
|
|
51
|
+
options
|
|
108
52
|
}) {
|
|
109
|
-
|
|
53
|
+
controlsRegistry.set(type, { type, component, options });
|
|
110
54
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return context;
|
|
55
|
+
function getInteractionsControl(type) {
|
|
56
|
+
return controlsRegistry.get(type);
|
|
57
|
+
}
|
|
58
|
+
function getInteractionsControlOptions(type) {
|
|
59
|
+
return controlsRegistry.get(type)?.options ?? [];
|
|
117
60
|
}
|
|
118
61
|
|
|
119
62
|
// src/utils/prop-value-utils.ts
|
|
@@ -172,17 +115,30 @@ var createSizeValue = (size, unit) => {
|
|
|
172
115
|
return { size, unit };
|
|
173
116
|
};
|
|
174
117
|
|
|
118
|
+
// src/utils/get-interactions-config.ts
|
|
119
|
+
function getInteractionsConfig() {
|
|
120
|
+
return window.ElementorInteractionsConfig ?? {};
|
|
121
|
+
}
|
|
122
|
+
|
|
175
123
|
// src/utils/temp-id-utils.ts
|
|
176
124
|
var TEMP_ID_PREFIX = "temp-";
|
|
125
|
+
var TEMP_ID_REGEX = /^temp-[a-z0-9]+$/i;
|
|
177
126
|
function generateTempInteractionId() {
|
|
178
127
|
return `${TEMP_ID_PREFIX}${Math.random().toString(36).substring(2, 11)}`;
|
|
179
128
|
}
|
|
129
|
+
function isTempId(id) {
|
|
130
|
+
return !!id && TEMP_ID_REGEX.test(id);
|
|
131
|
+
}
|
|
180
132
|
|
|
181
133
|
// src/utils/prop-value-utils.ts
|
|
182
134
|
var createString = (value) => ({
|
|
183
135
|
$$type: "string",
|
|
184
136
|
value
|
|
185
137
|
});
|
|
138
|
+
var createNumber = (value) => ({
|
|
139
|
+
$$type: "number",
|
|
140
|
+
value
|
|
141
|
+
});
|
|
186
142
|
var createTimingConfig = (duration, delay) => ({
|
|
187
143
|
$$type: "timing-config",
|
|
188
144
|
value: {
|
|
@@ -198,6 +154,8 @@ var createConfig = ({
|
|
|
198
154
|
replay,
|
|
199
155
|
easing = "easeIn",
|
|
200
156
|
relativeTo = "",
|
|
157
|
+
repeat = "",
|
|
158
|
+
times = 1,
|
|
201
159
|
start = 85,
|
|
202
160
|
end = 15
|
|
203
161
|
}) => ({
|
|
@@ -206,6 +164,8 @@ var createConfig = ({
|
|
|
206
164
|
replay: createBoolean(replay),
|
|
207
165
|
easing: createString(easing),
|
|
208
166
|
relativeTo: createString(relativeTo),
|
|
167
|
+
repeat: createString(repeat),
|
|
168
|
+
times: createNumber(times),
|
|
209
169
|
start: createSize(start, "%"),
|
|
210
170
|
end: createSize(end, "%")
|
|
211
171
|
}
|
|
@@ -241,6 +201,8 @@ var createAnimationPreset = ({
|
|
|
241
201
|
replay = false,
|
|
242
202
|
easing = "easeIn",
|
|
243
203
|
relativeTo,
|
|
204
|
+
repeat,
|
|
205
|
+
times,
|
|
244
206
|
start,
|
|
245
207
|
end,
|
|
246
208
|
customEffects
|
|
@@ -256,6 +218,8 @@ var createAnimationPreset = ({
|
|
|
256
218
|
replay,
|
|
257
219
|
easing,
|
|
258
220
|
relativeTo,
|
|
221
|
+
repeat,
|
|
222
|
+
times,
|
|
259
223
|
start,
|
|
260
224
|
end
|
|
261
225
|
})
|
|
@@ -272,6 +236,8 @@ var createInteractionItem = ({
|
|
|
272
236
|
replay = false,
|
|
273
237
|
easing = "easeIn",
|
|
274
238
|
relativeTo,
|
|
239
|
+
repeat,
|
|
240
|
+
times,
|
|
275
241
|
start,
|
|
276
242
|
end,
|
|
277
243
|
excludedBreakpoints,
|
|
@@ -290,6 +256,8 @@ var createInteractionItem = ({
|
|
|
290
256
|
replay,
|
|
291
257
|
easing,
|
|
292
258
|
relativeTo,
|
|
259
|
+
repeat,
|
|
260
|
+
times,
|
|
293
261
|
start,
|
|
294
262
|
end,
|
|
295
263
|
customEffects
|
|
@@ -300,17 +268,22 @@ var createInteractionItem = ({
|
|
|
300
268
|
}
|
|
301
269
|
});
|
|
302
270
|
var createDefaultInteractionItem = () => {
|
|
271
|
+
const { constants } = getInteractionsConfig();
|
|
303
272
|
return createInteractionItem({
|
|
304
273
|
trigger: "load",
|
|
305
274
|
effect: "fade",
|
|
306
275
|
type: "in",
|
|
307
|
-
duration:
|
|
308
|
-
delay:
|
|
276
|
+
duration: constants.defaultDuration,
|
|
277
|
+
delay: constants.defaultDelay,
|
|
309
278
|
replay: false,
|
|
310
|
-
easing:
|
|
279
|
+
easing: constants.defaultEasing,
|
|
311
280
|
interactionId: generateTempInteractionId()
|
|
312
281
|
});
|
|
313
282
|
};
|
|
283
|
+
var createDefaultInteractions = () => ({
|
|
284
|
+
version: 1,
|
|
285
|
+
items: [createDefaultInteractionItem()]
|
|
286
|
+
});
|
|
314
287
|
var extractString = (prop, fallback = "") => {
|
|
315
288
|
return prop?.value ?? fallback;
|
|
316
289
|
};
|
|
@@ -335,10 +308,180 @@ var buildDisplayLabel = (item) => {
|
|
|
335
308
|
const type = extractString(item.animation.value.type);
|
|
336
309
|
const triggerLabel = TRIGGER_LABELS[trigger] || capitalize(trigger);
|
|
337
310
|
const effectLabel = capitalize(effect);
|
|
338
|
-
const typeLabel = capitalize(type);
|
|
311
|
+
const typeLabel = "custom" === effect ? "" : capitalize(type);
|
|
339
312
|
return `${triggerLabel}: ${effectLabel} ${typeLabel}`;
|
|
340
313
|
};
|
|
341
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
|
+
|
|
342
485
|
// src/components/interactions-list-item.tsx
|
|
343
486
|
import * as React9 from "react";
|
|
344
487
|
import { useCallback as useCallback4 } from "react";
|
|
@@ -352,19 +495,6 @@ import { PopoverContent } from "@elementor/editor-controls";
|
|
|
352
495
|
import { Box, Divider, Grid as Grid2 } from "@elementor/ui";
|
|
353
496
|
import { __ as __2 } from "@wordpress/i18n";
|
|
354
497
|
|
|
355
|
-
// src/interactions-controls-registry.ts
|
|
356
|
-
var controlsRegistry = /* @__PURE__ */ new Map();
|
|
357
|
-
function registerInteractionsControl({
|
|
358
|
-
type,
|
|
359
|
-
component,
|
|
360
|
-
options
|
|
361
|
-
}) {
|
|
362
|
-
controlsRegistry.set(type, { type, component, options });
|
|
363
|
-
}
|
|
364
|
-
function getInteractionsControl(type) {
|
|
365
|
-
return controlsRegistry.get(type);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
498
|
// src/utils/resolve-direction.ts
|
|
369
499
|
var resolveDirection = (hasDirection, newEffect, newDirection, currentDirection, currentEffect) => {
|
|
370
500
|
if (newEffect === "slide" && !newDirection) {
|
|
@@ -457,6 +587,8 @@ var DEFAULT_VALUES = {
|
|
|
457
587
|
replay: false,
|
|
458
588
|
easing: "easeIn",
|
|
459
589
|
relativeTo: "viewport",
|
|
590
|
+
repeat: "",
|
|
591
|
+
times: 1,
|
|
460
592
|
start: 85,
|
|
461
593
|
end: 15
|
|
462
594
|
};
|
|
@@ -469,6 +601,8 @@ var controlVisibilityConfig = {
|
|
|
469
601
|
relativeTo: (values) => values.trigger === "scrollOn",
|
|
470
602
|
start: (values) => values.trigger === "scrollOn",
|
|
471
603
|
end: (values) => values.trigger === "scrollOn",
|
|
604
|
+
repeat: (values) => values.trigger !== "scrollOn",
|
|
605
|
+
times: (values) => values.trigger !== "scrollOn" && values.repeat === "times",
|
|
472
606
|
duration: (values) => {
|
|
473
607
|
const isRelativeToVisible = values.trigger === "scrollOn";
|
|
474
608
|
return !isRelativeToVisible;
|
|
@@ -478,6 +612,13 @@ var controlVisibilityConfig = {
|
|
|
478
612
|
return !isRelativeToVisible;
|
|
479
613
|
}
|
|
480
614
|
};
|
|
615
|
+
function normalizeTimesValue(value, fallback) {
|
|
616
|
+
const numericValue = Number(value);
|
|
617
|
+
if (!Number.isFinite(numericValue)) {
|
|
618
|
+
return fallback;
|
|
619
|
+
}
|
|
620
|
+
return Math.max(1, Math.floor(numericValue));
|
|
621
|
+
}
|
|
481
622
|
function useControlComponent(controlName, isVisible = true) {
|
|
482
623
|
return useMemo(() => {
|
|
483
624
|
if (!isVisible) {
|
|
@@ -497,6 +638,9 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
|
|
|
497
638
|
const replay = extractBoolean(interaction.animation.value.config?.value.replay, DEFAULT_VALUES.replay);
|
|
498
639
|
const easing = extractString(interaction.animation.value.config?.value.easing, DEFAULT_VALUES.easing);
|
|
499
640
|
const relativeTo = extractString(interaction.animation.value.config?.value.relativeTo, DEFAULT_VALUES.relativeTo);
|
|
641
|
+
const configValue = interaction.animation.value.config?.value;
|
|
642
|
+
const repeat = extractString(configValue?.repeat, DEFAULT_VALUES.repeat);
|
|
643
|
+
const times = normalizeTimesValue(configValue?.times?.value, DEFAULT_VALUES.times);
|
|
500
644
|
const start = extractSize(interaction.animation.value.config?.value.start, DEFAULT_VALUES.start);
|
|
501
645
|
const end = extractSize(interaction.animation.value.config?.value.end, DEFAULT_VALUES.end);
|
|
502
646
|
const interactionValues = {
|
|
@@ -509,6 +653,8 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
|
|
|
509
653
|
easing,
|
|
510
654
|
replay,
|
|
511
655
|
relativeTo,
|
|
656
|
+
repeat,
|
|
657
|
+
times,
|
|
512
658
|
start,
|
|
513
659
|
end,
|
|
514
660
|
customEffects
|
|
@@ -531,6 +677,14 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
|
|
|
531
677
|
controlVisibilityConfig.effectType(interactionValues)
|
|
532
678
|
);
|
|
533
679
|
const DirectionControl = useControlComponent("direction", controlVisibilityConfig.direction(interactionValues));
|
|
680
|
+
const RepeatControl = useControlComponent(
|
|
681
|
+
"repeat",
|
|
682
|
+
controlVisibilityConfig.repeat(interactionValues)
|
|
683
|
+
);
|
|
684
|
+
const TimesControl = useControlComponent(
|
|
685
|
+
"times",
|
|
686
|
+
controlVisibilityConfig.times(interactionValues)
|
|
687
|
+
);
|
|
534
688
|
const EasingControl = useControlComponent("easing");
|
|
535
689
|
const containerRef = useRef2(null);
|
|
536
690
|
const updateInteraction = (updates) => {
|
|
@@ -554,6 +708,8 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
|
|
|
554
708
|
replay: updates.replay ?? replay,
|
|
555
709
|
easing: updates.easing ?? easing,
|
|
556
710
|
relativeTo: updates.relativeTo ?? relativeTo,
|
|
711
|
+
repeat: updates.repeat ?? repeat,
|
|
712
|
+
times: updates.times ?? times,
|
|
557
713
|
start: updates.start ?? start,
|
|
558
714
|
end: updates.end ?? end,
|
|
559
715
|
customEffects: updates.customEffects ?? customEffects
|
|
@@ -592,6 +748,14 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
|
|
|
592
748
|
onChange: (v) => updateInteraction({ direction: v }),
|
|
593
749
|
interactionType: type
|
|
594
750
|
}
|
|
751
|
+
)), RepeatControl && /* @__PURE__ */ React7.createElement(Field, { label: __2("Repeat", "elementor") }, /* @__PURE__ */ React7.createElement(RepeatControl, { value: repeat, onChange: (v) => updateInteraction({ repeat: v }) })), TimesControl && /* @__PURE__ */ React7.createElement(Field, { label: __2("Times", "elementor") }, /* @__PURE__ */ React7.createElement(
|
|
752
|
+
TimesControl,
|
|
753
|
+
{
|
|
754
|
+
value: times,
|
|
755
|
+
onChange: (v) => updateInteraction({
|
|
756
|
+
times: normalizeTimesValue(v, DEFAULT_VALUES.times)
|
|
757
|
+
})
|
|
758
|
+
}
|
|
595
759
|
)), controlVisibilityConfig.duration(interactionValues) && /* @__PURE__ */ React7.createElement(Field, { label: __2("Duration", "elementor") }, /* @__PURE__ */ React7.createElement(
|
|
596
760
|
TimeFrameIndicator,
|
|
597
761
|
{
|
|
@@ -637,7 +801,7 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
|
|
|
637
801
|
|
|
638
802
|
// src/components/interaction-settings.tsx
|
|
639
803
|
import * as React8 from "react";
|
|
640
|
-
import { useCallback as useCallback3, useMemo as useMemo2, useState as
|
|
804
|
+
import { useCallback as useCallback3, useMemo as useMemo2, useState as useState3 } from "react";
|
|
641
805
|
import { ControlFormLabel as ControlFormLabel2, PopoverContent as PopoverContent2 } from "@elementor/editor-controls";
|
|
642
806
|
import { useBreakpoints } from "@elementor/editor-responsive";
|
|
643
807
|
import { Autocomplete, Chip, Grid as Grid3, Stack as Stack2, TextField } from "@elementor/ui";
|
|
@@ -649,7 +813,7 @@ var InteractionSettings = ({ interaction, onChange }) => {
|
|
|
649
813
|
() => breakpoints.map((breakpoint) => ({ label: breakpoint.label, value: String(breakpoint.id) })),
|
|
650
814
|
[breakpoints]
|
|
651
815
|
);
|
|
652
|
-
const [selectedBreakpoints, setSelectedBreakpoints] =
|
|
816
|
+
const [selectedBreakpoints, setSelectedBreakpoints] = useState3(() => {
|
|
653
817
|
const excluded = extractExcludedBreakpoints(interaction.breakpoints).filter((excludedBreakpoint) => {
|
|
654
818
|
return availableBreakpoints.some(({ value }) => value === excludedBreakpoint);
|
|
655
819
|
});
|
|
@@ -746,6 +910,7 @@ var InteractionsListItem = ({
|
|
|
746
910
|
var MAX_NUMBER_OF_INTERACTIONS = 5;
|
|
747
911
|
function InteractionsList(props) {
|
|
748
912
|
const { interactions, onSelectInteractions, onPlayInteraction, triggerCreateOnShowEmpty } = props;
|
|
913
|
+
const { elementId } = useInteractionsContext();
|
|
749
914
|
const hasInitializedRef = useRef3(false);
|
|
750
915
|
const handleUpdateInteractions = useCallback5(
|
|
751
916
|
(newInteractions) => {
|
|
@@ -771,13 +936,19 @@ function InteractionsList(props) {
|
|
|
771
936
|
"elementor"
|
|
772
937
|
))) : void 0;
|
|
773
938
|
const handleRepeaterChange = useCallback5(
|
|
774
|
-
(newItems) => {
|
|
939
|
+
(newItems, _, meta) => {
|
|
775
940
|
handleUpdateInteractions({
|
|
776
941
|
...interactions,
|
|
777
942
|
items: newItems
|
|
778
943
|
});
|
|
944
|
+
if (meta?.action?.type === "add") {
|
|
945
|
+
const addedItem = meta.action.payload[0]?.item;
|
|
946
|
+
if (addedItem) {
|
|
947
|
+
trackInteractionCreated(elementId, addedItem);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
779
950
|
},
|
|
780
|
-
[interactions, handleUpdateInteractions]
|
|
951
|
+
[interactions, handleUpdateInteractions, elementId]
|
|
781
952
|
);
|
|
782
953
|
const handleInteractionChange = useCallback5(
|
|
783
954
|
(index, newInteractionValue) => {
|
|
@@ -837,14 +1008,15 @@ var InteractionsTab = ({ elementId }) => {
|
|
|
837
1008
|
return /* @__PURE__ */ React11.createElement(PopupStateProvider, null, /* @__PURE__ */ React11.createElement(InteractionsTabContent, { elementId }));
|
|
838
1009
|
};
|
|
839
1010
|
function InteractionsTabContent({ elementId }) {
|
|
840
|
-
const existingInteractions =
|
|
841
|
-
const firstInteractionState =
|
|
1011
|
+
const existingInteractions = useElementInteractions(elementId);
|
|
1012
|
+
const firstInteractionState = useState4(false);
|
|
842
1013
|
const hasInteractions = existingInteractions?.items?.length || firstInteractionState[0];
|
|
843
1014
|
return /* @__PURE__ */ React11.createElement(SessionStorageProvider, { prefix: elementId }, hasInteractions ? /* @__PURE__ */ React11.createElement(InteractionsProvider, { elementId }, /* @__PURE__ */ React11.createElement(InteractionsContent, { firstInteractionState })) : /* @__PURE__ */ React11.createElement(
|
|
844
1015
|
EmptyState,
|
|
845
1016
|
{
|
|
846
1017
|
onCreateInteraction: () => {
|
|
847
1018
|
firstInteractionState[1](true);
|
|
1019
|
+
trackInteractionCreated(elementId, createDefaultInteractionItem());
|
|
848
1020
|
}
|
|
849
1021
|
}
|
|
850
1022
|
));
|
|
@@ -875,20 +1047,6 @@ function InteractionsContent({
|
|
|
875
1047
|
));
|
|
876
1048
|
}
|
|
877
1049
|
|
|
878
|
-
// src/utils/get-interactions-config.ts
|
|
879
|
-
var DEFAULT_CONFIG = {
|
|
880
|
-
constants: {
|
|
881
|
-
defaultDuration: 300,
|
|
882
|
-
defaultDelay: 0,
|
|
883
|
-
slideDistance: 100,
|
|
884
|
-
scaleStart: 0.5,
|
|
885
|
-
easing: "linear"
|
|
886
|
-
}
|
|
887
|
-
};
|
|
888
|
-
function getInteractionsConfig() {
|
|
889
|
-
return window.ElementorInteractionsConfig || DEFAULT_CONFIG;
|
|
890
|
-
}
|
|
891
|
-
|
|
892
1050
|
// src/utils/create-interactions-repository.ts
|
|
893
1051
|
var createInteractionsRepository = () => {
|
|
894
1052
|
const providers = [];
|
|
@@ -949,8 +1107,8 @@ function createInteractionsProvider({
|
|
|
949
1107
|
}
|
|
950
1108
|
|
|
951
1109
|
// src/providers/document-elements-interactions-provider.ts
|
|
952
|
-
import { getCurrentDocumentId, getElementInteractions, getElements } from "@elementor/editor-elements";
|
|
953
|
-
import { __privateListenTo as listenTo, windowEvent } from "@elementor/editor-v1-adapters";
|
|
1110
|
+
import { getCurrentDocumentId, getElementInteractions as getElementInteractions2, getElements } from "@elementor/editor-elements";
|
|
1111
|
+
import { __privateListenTo as listenTo, windowEvent as windowEvent2 } from "@elementor/editor-v1-adapters";
|
|
954
1112
|
var ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX = "document-elements-interactions-";
|
|
955
1113
|
var documentElementsInteractionsProvider = createInteractionsProvider({
|
|
956
1114
|
key: () => {
|
|
@@ -964,20 +1122,20 @@ var documentElementsInteractionsProvider = createInteractionsProvider({
|
|
|
964
1122
|
},
|
|
965
1123
|
priority: 50,
|
|
966
1124
|
subscribe: (cb) => {
|
|
967
|
-
return listenTo([
|
|
1125
|
+
return listenTo([windowEvent2("elementor/element/update_interactions")], () => cb());
|
|
968
1126
|
},
|
|
969
1127
|
actions: {
|
|
970
1128
|
all: () => {
|
|
971
1129
|
const elements = getElements();
|
|
972
1130
|
const filtered = elements.filter((element) => {
|
|
973
|
-
const interactions =
|
|
1131
|
+
const interactions = getElementInteractions2(element.id);
|
|
974
1132
|
if (!interactions) {
|
|
975
1133
|
return false;
|
|
976
1134
|
}
|
|
977
1135
|
return interactions?.items?.length > 0;
|
|
978
1136
|
});
|
|
979
1137
|
return filtered.map((element) => {
|
|
980
|
-
const interactions =
|
|
1138
|
+
const interactions = getElementInteractions2(element.id);
|
|
981
1139
|
return {
|
|
982
1140
|
elementId: element.id,
|
|
983
1141
|
dataId: element.id,
|
|
@@ -988,37 +1146,145 @@ var documentElementsInteractionsProvider = createInteractionsProvider({
|
|
|
988
1146
|
}
|
|
989
1147
|
});
|
|
990
1148
|
|
|
1149
|
+
// src/commands/paste-interactions.ts
|
|
1150
|
+
import {
|
|
1151
|
+
getContainer,
|
|
1152
|
+
getElementInteractions as getElementInteractions3,
|
|
1153
|
+
getElementLabel as getElementLabel2,
|
|
1154
|
+
getWidgetsCache,
|
|
1155
|
+
updateElementInteractions as updateElementInteractions2
|
|
1156
|
+
} from "@elementor/editor-elements";
|
|
1157
|
+
import {
|
|
1158
|
+
__privateListenTo as listenTo2,
|
|
1159
|
+
commandStartEvent,
|
|
1160
|
+
undoable
|
|
1161
|
+
} from "@elementor/editor-v1-adapters";
|
|
1162
|
+
import { __ as __6 } from "@wordpress/i18n";
|
|
1163
|
+
|
|
1164
|
+
// src/commands/get-clipboard-elements.ts
|
|
1165
|
+
function getClipboardElements(storageKey = "clipboard") {
|
|
1166
|
+
try {
|
|
1167
|
+
const storedData = JSON.parse(localStorage.getItem("elementor") ?? "{}");
|
|
1168
|
+
return storedData[storageKey]?.elements;
|
|
1169
|
+
} catch {
|
|
1170
|
+
return void 0;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
// src/commands/paste-interactions.ts
|
|
1175
|
+
function isAtomicContainer(container) {
|
|
1176
|
+
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
1177
|
+
const widgetsCache = getWidgetsCache();
|
|
1178
|
+
const elementConfig = widgetsCache?.[type];
|
|
1179
|
+
return Boolean(elementConfig?.atomic_props_schema);
|
|
1180
|
+
}
|
|
1181
|
+
function getTitleForContainers(containers) {
|
|
1182
|
+
return containers.length > 1 ? __6("Elements", "elementor") : getElementLabel2(containers[0].id);
|
|
1183
|
+
}
|
|
1184
|
+
function normalizeClipboardInteractions(raw) {
|
|
1185
|
+
if (!raw) {
|
|
1186
|
+
return null;
|
|
1187
|
+
}
|
|
1188
|
+
const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
|
|
1189
|
+
if (!parsed?.items?.length) {
|
|
1190
|
+
return null;
|
|
1191
|
+
}
|
|
1192
|
+
return { version: parsed.version ?? 1, items: parsed.items };
|
|
1193
|
+
}
|
|
1194
|
+
function regenerateInteractionIds(interactions) {
|
|
1195
|
+
const cloned = structuredClone(interactions);
|
|
1196
|
+
cloned.items?.forEach((item) => {
|
|
1197
|
+
if (item.$$type === "interaction-item" && item.value) {
|
|
1198
|
+
item.value.interaction_id = createString(generateTempInteractionId());
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
return cloned;
|
|
1202
|
+
}
|
|
1203
|
+
function initPasteInteractionsCommand() {
|
|
1204
|
+
const undoablePasteInteractions = undoable(
|
|
1205
|
+
{
|
|
1206
|
+
do: ({ containers, newInteractions }) => {
|
|
1207
|
+
const pasted = regenerateInteractionIds(newInteractions);
|
|
1208
|
+
return containers.map((container) => {
|
|
1209
|
+
const elementId = container.id;
|
|
1210
|
+
const previous = getElementInteractions3(elementId);
|
|
1211
|
+
updateElementInteractions2({
|
|
1212
|
+
elementId,
|
|
1213
|
+
interactions: pasted
|
|
1214
|
+
});
|
|
1215
|
+
return { elementId, previous: previous ?? { version: 1, items: [] } };
|
|
1216
|
+
});
|
|
1217
|
+
},
|
|
1218
|
+
undo: (_, revertData) => {
|
|
1219
|
+
revertData.forEach(({ elementId, previous }) => {
|
|
1220
|
+
updateElementInteractions2({
|
|
1221
|
+
elementId,
|
|
1222
|
+
interactions: previous.items?.length ? previous : void 0
|
|
1223
|
+
});
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
},
|
|
1227
|
+
{
|
|
1228
|
+
title: ({ containers }) => getTitleForContainers(containers),
|
|
1229
|
+
subtitle: __6("Interactions Pasted", "elementor")
|
|
1230
|
+
}
|
|
1231
|
+
);
|
|
1232
|
+
listenTo2(commandStartEvent("document/elements/paste-interactions"), (e) => {
|
|
1233
|
+
const args = e.args;
|
|
1234
|
+
const containers = args.containers ?? (args.container ? [args.container] : []);
|
|
1235
|
+
const storageKey = args.storageKey ?? "clipboard";
|
|
1236
|
+
if (!containers.length) {
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
const clipboardElements = getClipboardElements(storageKey);
|
|
1240
|
+
const [clipboardElement] = clipboardElements ?? [];
|
|
1241
|
+
if (!clipboardElement) {
|
|
1242
|
+
return;
|
|
1243
|
+
}
|
|
1244
|
+
const newInteractions = normalizeClipboardInteractions(clipboardElement.interactions);
|
|
1245
|
+
if (!newInteractions) {
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
1248
|
+
const existingContainers = containers.filter((c) => getContainer(c.id));
|
|
1249
|
+
const validContainers = existingContainers.filter(isAtomicContainer);
|
|
1250
|
+
if (!validContainers.length) {
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
undoablePasteInteractions({ containers: validContainers, newInteractions });
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
|
|
991
1257
|
// src/components/controls/direction.tsx
|
|
992
1258
|
import * as React12 from "react";
|
|
993
1259
|
import { useMemo as useMemo4 } from "react";
|
|
994
1260
|
import { ToggleButtonGroupUi } from "@elementor/editor-controls";
|
|
995
1261
|
import { ArrowDownSmallIcon, ArrowLeftIcon, ArrowRightIcon, ArrowUpSmallIcon } from "@elementor/icons";
|
|
996
|
-
import { __ as
|
|
1262
|
+
import { __ as __7 } from "@wordpress/i18n";
|
|
997
1263
|
function Direction({ value, onChange, interactionType }) {
|
|
998
1264
|
const options = useMemo4(() => {
|
|
999
1265
|
const isIn = interactionType === "in";
|
|
1000
1266
|
return [
|
|
1001
1267
|
{
|
|
1002
1268
|
value: "top",
|
|
1003
|
-
label: isIn ?
|
|
1269
|
+
label: isIn ? __7("From top", "elementor") : __7("To top", "elementor"),
|
|
1004
1270
|
renderContent: ({ size }) => isIn ? /* @__PURE__ */ React12.createElement(ArrowDownSmallIcon, { fontSize: size }) : /* @__PURE__ */ React12.createElement(ArrowUpSmallIcon, { fontSize: size }),
|
|
1005
1271
|
showTooltip: true
|
|
1006
1272
|
},
|
|
1007
1273
|
{
|
|
1008
1274
|
value: "bottom",
|
|
1009
|
-
label: interactionType === "in" ?
|
|
1275
|
+
label: interactionType === "in" ? __7("From bottom", "elementor") : __7("To bottom", "elementor"),
|
|
1010
1276
|
renderContent: ({ size }) => isIn ? /* @__PURE__ */ React12.createElement(ArrowUpSmallIcon, { fontSize: size }) : /* @__PURE__ */ React12.createElement(ArrowDownSmallIcon, { fontSize: size }),
|
|
1011
1277
|
showTooltip: true
|
|
1012
1278
|
},
|
|
1013
1279
|
{
|
|
1014
1280
|
value: "left",
|
|
1015
|
-
label: interactionType === "in" ?
|
|
1281
|
+
label: interactionType === "in" ? __7("From left", "elementor") : __7("To left", "elementor"),
|
|
1016
1282
|
renderContent: ({ size }) => isIn ? /* @__PURE__ */ React12.createElement(ArrowRightIcon, { fontSize: size }) : /* @__PURE__ */ React12.createElement(ArrowLeftIcon, { fontSize: size }),
|
|
1017
1283
|
showTooltip: true
|
|
1018
1284
|
},
|
|
1019
1285
|
{
|
|
1020
1286
|
value: "right",
|
|
1021
|
-
label: interactionType === "in" ?
|
|
1287
|
+
label: interactionType === "in" ? __7("From right", "elementor") : __7("To right", "elementor"),
|
|
1022
1288
|
renderContent: ({ size }) => isIn ? /* @__PURE__ */ React12.createElement(ArrowLeftIcon, { fontSize: size }) : /* @__PURE__ */ React12.createElement(ArrowRightIcon, { fontSize: size }),
|
|
1023
1289
|
showTooltip: true
|
|
1024
1290
|
}
|
|
@@ -1029,27 +1295,35 @@ function Direction({ value, onChange, interactionType }) {
|
|
|
1029
1295
|
|
|
1030
1296
|
// src/components/controls/easing.tsx
|
|
1031
1297
|
import * as React15 from "react";
|
|
1032
|
-
import { __ as
|
|
1298
|
+
import { __ as __10 } from "@wordpress/i18n";
|
|
1033
1299
|
|
|
1034
1300
|
// src/ui/promotion-select.tsx
|
|
1035
1301
|
import * as React14 from "react";
|
|
1036
1302
|
import { useRef as useRef4 } from "react";
|
|
1037
1303
|
import { MenuListItem } from "@elementor/editor-ui";
|
|
1038
1304
|
import { MenuSubheader, Select } from "@elementor/ui";
|
|
1039
|
-
import { __ as
|
|
1305
|
+
import { __ as __9 } from "@wordpress/i18n";
|
|
1040
1306
|
|
|
1041
1307
|
// src/ui/interactions-promotion-chip.tsx
|
|
1042
1308
|
import * as React13 from "react";
|
|
1043
|
-
import { forwardRef, useImperativeHandle, useState as
|
|
1309
|
+
import { forwardRef, useCallback as useCallback7, useImperativeHandle, useState as useState5 } from "react";
|
|
1310
|
+
import { trackUpgradePromotionClick, trackViewPromotion } from "@elementor/editor-controls";
|
|
1044
1311
|
import { PromotionChip, PromotionPopover, useCanvasClickHandler } from "@elementor/editor-ui";
|
|
1045
1312
|
import { Box as Box3 } from "@elementor/ui";
|
|
1046
|
-
import { __ as
|
|
1313
|
+
import { __ as __8 } from "@wordpress/i18n";
|
|
1047
1314
|
var InteractionsPromotionChip = forwardRef(
|
|
1048
|
-
({ content, upgradeUrl, anchorRef }, ref) => {
|
|
1049
|
-
const [isOpen, setIsOpen] =
|
|
1315
|
+
({ content, upgradeUrl, anchorRef, trackingData }, ref) => {
|
|
1316
|
+
const [isOpen, setIsOpen] = useState5(false);
|
|
1050
1317
|
useCanvasClickHandler(isOpen, () => setIsOpen(false));
|
|
1051
|
-
const toggle = (
|
|
1052
|
-
|
|
1318
|
+
const toggle = useCallback7(() => {
|
|
1319
|
+
setIsOpen((prev) => {
|
|
1320
|
+
if (!prev) {
|
|
1321
|
+
trackViewPromotion(trackingData);
|
|
1322
|
+
}
|
|
1323
|
+
return !prev;
|
|
1324
|
+
});
|
|
1325
|
+
}, [trackingData]);
|
|
1326
|
+
useImperativeHandle(ref, () => ({ toggle }), [toggle]);
|
|
1053
1327
|
const handleToggle = (e) => {
|
|
1054
1328
|
e.stopPropagation();
|
|
1055
1329
|
toggle();
|
|
@@ -1058,16 +1332,17 @@ var InteractionsPromotionChip = forwardRef(
|
|
|
1058
1332
|
PromotionPopover,
|
|
1059
1333
|
{
|
|
1060
1334
|
open: isOpen,
|
|
1061
|
-
title:
|
|
1335
|
+
title: __8("Interactions", "elementor"),
|
|
1062
1336
|
content,
|
|
1063
|
-
ctaText:
|
|
1337
|
+
ctaText: __8("Upgrade now", "elementor"),
|
|
1064
1338
|
ctaUrl: upgradeUrl,
|
|
1065
1339
|
anchorRef,
|
|
1066
1340
|
placement: anchorRef ? "right-start" : void 0,
|
|
1067
1341
|
onClose: (e) => {
|
|
1068
1342
|
e.stopPropagation();
|
|
1069
1343
|
setIsOpen(false);
|
|
1070
|
-
}
|
|
1344
|
+
},
|
|
1345
|
+
onCtaClick: () => trackUpgradePromotionClick(trackingData)
|
|
1071
1346
|
},
|
|
1072
1347
|
/* @__PURE__ */ React13.createElement(
|
|
1073
1348
|
Box3,
|
|
@@ -1091,7 +1366,8 @@ function PromotionSelect({
|
|
|
1091
1366
|
disabledOptions,
|
|
1092
1367
|
promotionLabel,
|
|
1093
1368
|
promotionContent,
|
|
1094
|
-
upgradeUrl
|
|
1369
|
+
upgradeUrl,
|
|
1370
|
+
trackingData
|
|
1095
1371
|
}) {
|
|
1096
1372
|
const promotionRef = useRef4(null);
|
|
1097
1373
|
const anchorRef = useRef4(null);
|
|
@@ -1122,14 +1398,15 @@ function PromotionSelect({
|
|
|
1122
1398
|
promotionRef.current?.toggle();
|
|
1123
1399
|
}
|
|
1124
1400
|
},
|
|
1125
|
-
promotionLabel ??
|
|
1401
|
+
promotionLabel ?? __9("PRO features", "elementor"),
|
|
1126
1402
|
/* @__PURE__ */ React14.createElement(
|
|
1127
1403
|
InteractionsPromotionChip,
|
|
1128
1404
|
{
|
|
1129
1405
|
content: promotionContent,
|
|
1130
1406
|
upgradeUrl,
|
|
1131
1407
|
ref: promotionRef,
|
|
1132
|
-
anchorRef
|
|
1408
|
+
anchorRef,
|
|
1409
|
+
trackingData
|
|
1133
1410
|
}
|
|
1134
1411
|
)
|
|
1135
1412
|
),
|
|
@@ -1138,14 +1415,15 @@ function PromotionSelect({
|
|
|
1138
1415
|
}
|
|
1139
1416
|
|
|
1140
1417
|
// src/components/controls/easing.tsx
|
|
1418
|
+
var TRACKING_DATA = { target_name: "interactions_easing", location_l2: "interactions" };
|
|
1141
1419
|
var EASING_OPTIONS = {
|
|
1142
|
-
easeIn:
|
|
1143
|
-
easeInOut:
|
|
1144
|
-
easeOut:
|
|
1145
|
-
backIn:
|
|
1146
|
-
backInOut:
|
|
1147
|
-
backOut:
|
|
1148
|
-
linear:
|
|
1420
|
+
easeIn: __10("Ease In", "elementor"),
|
|
1421
|
+
easeInOut: __10("Ease In Out", "elementor"),
|
|
1422
|
+
easeOut: __10("Ease Out", "elementor"),
|
|
1423
|
+
backIn: __10("Back In", "elementor"),
|
|
1424
|
+
backInOut: __10("Back In Out", "elementor"),
|
|
1425
|
+
backOut: __10("Back Out", "elementor"),
|
|
1426
|
+
linear: __10("Linear", "elementor")
|
|
1149
1427
|
};
|
|
1150
1428
|
var BASE_EASINGS = ["easeIn"];
|
|
1151
1429
|
function Easing({}) {
|
|
@@ -1161,20 +1439,22 @@ function Easing({}) {
|
|
|
1161
1439
|
value: DEFAULT_VALUES.easing,
|
|
1162
1440
|
baseOptions,
|
|
1163
1441
|
disabledOptions,
|
|
1164
|
-
promotionContent:
|
|
1165
|
-
upgradeUrl: "https://go.elementor.com/go-pro-interactions-easing-modal/"
|
|
1442
|
+
promotionContent: __10("Upgrade to control the smoothness of the interaction.", "elementor"),
|
|
1443
|
+
upgradeUrl: "https://go.elementor.com/go-pro-interactions-easing-modal/",
|
|
1444
|
+
trackingData: TRACKING_DATA
|
|
1166
1445
|
}
|
|
1167
1446
|
);
|
|
1168
1447
|
}
|
|
1169
1448
|
|
|
1170
1449
|
// src/components/controls/effect.tsx
|
|
1171
1450
|
import * as React16 from "react";
|
|
1172
|
-
import { __ as
|
|
1451
|
+
import { __ as __11 } from "@wordpress/i18n";
|
|
1452
|
+
var TRACKING_DATA2 = { target_name: "interactions_effect", location_l2: "interactions" };
|
|
1173
1453
|
var EFFECT_OPTIONS = {
|
|
1174
|
-
fade:
|
|
1175
|
-
slide:
|
|
1176
|
-
scale:
|
|
1177
|
-
custom:
|
|
1454
|
+
fade: __11("Fade", "elementor"),
|
|
1455
|
+
slide: __11("Slide", "elementor"),
|
|
1456
|
+
scale: __11("Scale", "elementor"),
|
|
1457
|
+
custom: __11("Custom", "elementor")
|
|
1178
1458
|
};
|
|
1179
1459
|
var BASE_EFFECTS = ["fade", "slide", "scale"];
|
|
1180
1460
|
function Effect({ value, onChange }) {
|
|
@@ -1191,12 +1471,13 @@ function Effect({ value, onChange }) {
|
|
|
1191
1471
|
onChange,
|
|
1192
1472
|
baseOptions,
|
|
1193
1473
|
disabledOptions,
|
|
1194
|
-
promotionLabel:
|
|
1195
|
-
promotionContent:
|
|
1474
|
+
promotionLabel: __11("PRO effects", "elementor"),
|
|
1475
|
+
promotionContent: __11(
|
|
1196
1476
|
"Upgrade to further customize your animation with opacity, scale, move, rotate and more.",
|
|
1197
1477
|
"elementor"
|
|
1198
1478
|
),
|
|
1199
|
-
upgradeUrl: "https://go.elementor.com/go-pro-interactions-custom-effect-modal/"
|
|
1479
|
+
upgradeUrl: "https://go.elementor.com/go-pro-interactions-custom-effect-modal/",
|
|
1480
|
+
trackingData: TRACKING_DATA2
|
|
1200
1481
|
}
|
|
1201
1482
|
);
|
|
1202
1483
|
}
|
|
@@ -1204,19 +1485,19 @@ function Effect({ value, onChange }) {
|
|
|
1204
1485
|
// src/components/controls/effect-type.tsx
|
|
1205
1486
|
import * as React17 from "react";
|
|
1206
1487
|
import { ToggleButtonGroupUi as ToggleButtonGroupUi2 } from "@elementor/editor-controls";
|
|
1207
|
-
import { __ as
|
|
1488
|
+
import { __ as __12 } from "@wordpress/i18n";
|
|
1208
1489
|
function EffectType({ value, onChange }) {
|
|
1209
1490
|
const options = [
|
|
1210
1491
|
{
|
|
1211
1492
|
value: "in",
|
|
1212
|
-
label:
|
|
1213
|
-
renderContent: () =>
|
|
1493
|
+
label: __12("In", "elementor"),
|
|
1494
|
+
renderContent: () => __12("In", "elementor"),
|
|
1214
1495
|
showTooltip: true
|
|
1215
1496
|
},
|
|
1216
1497
|
{
|
|
1217
1498
|
value: "out",
|
|
1218
|
-
label:
|
|
1219
|
-
renderContent: () =>
|
|
1499
|
+
label: __12("Out", "elementor"),
|
|
1500
|
+
renderContent: () => __12("Out", "elementor"),
|
|
1220
1501
|
showTooltip: true
|
|
1221
1502
|
}
|
|
1222
1503
|
];
|
|
@@ -1228,10 +1509,11 @@ import * as React18 from "react";
|
|
|
1228
1509
|
import { ToggleButtonGroupUi as ToggleButtonGroupUi3 } from "@elementor/editor-controls";
|
|
1229
1510
|
import { CheckIcon, MinusIcon } from "@elementor/icons";
|
|
1230
1511
|
import { Box as Box4 } from "@elementor/ui";
|
|
1231
|
-
import { __ as
|
|
1512
|
+
import { __ as __13 } from "@wordpress/i18n";
|
|
1513
|
+
var TRACKING_DATA3 = { target_name: "interactions_replay", location_l2: "interactions" };
|
|
1232
1514
|
var REPLAY_OPTIONS = {
|
|
1233
|
-
no:
|
|
1234
|
-
yes:
|
|
1515
|
+
no: __13("No", "elementor"),
|
|
1516
|
+
yes: __13("Yes", "elementor")
|
|
1235
1517
|
};
|
|
1236
1518
|
var BASE_REPLAY = ["no"];
|
|
1237
1519
|
var OVERLAY_GRID = "1 / 1";
|
|
@@ -1256,22 +1538,24 @@ function Replay({ onChange, anchorRef }) {
|
|
|
1256
1538
|
return /* @__PURE__ */ React18.createElement(Box4, { sx: { display: "grid", alignItems: "center" } }, /* @__PURE__ */ React18.createElement(Box4, { sx: { gridArea: OVERLAY_GRID } }, /* @__PURE__ */ React18.createElement(ToggleButtonGroupUi3, { items: options, exclusive: true, onChange, value: false })), /* @__PURE__ */ React18.createElement(Box4, { sx: { gridArea: OVERLAY_GRID, marginInlineEnd: CHIP_OFFSET, justifySelf: "end" } }, /* @__PURE__ */ React18.createElement(
|
|
1257
1539
|
InteractionsPromotionChip,
|
|
1258
1540
|
{
|
|
1259
|
-
content:
|
|
1541
|
+
content: __13("Upgrade to run the animation every time its trigger occurs.", "elementor"),
|
|
1260
1542
|
upgradeUrl: "https://go.elementor.com/go-pro-interactions-replay-modal/",
|
|
1261
|
-
anchorRef
|
|
1543
|
+
anchorRef,
|
|
1544
|
+
trackingData: TRACKING_DATA3
|
|
1262
1545
|
}
|
|
1263
1546
|
)));
|
|
1264
1547
|
}
|
|
1265
1548
|
|
|
1266
1549
|
// src/components/controls/trigger.tsx
|
|
1267
1550
|
import * as React19 from "react";
|
|
1268
|
-
import { __ as
|
|
1551
|
+
import { __ as __14 } from "@wordpress/i18n";
|
|
1552
|
+
var TRACKING_DATA4 = { target_name: "interactions_trigger", location_l2: "interactions" };
|
|
1269
1553
|
var TRIGGER_OPTIONS = {
|
|
1270
|
-
load:
|
|
1271
|
-
scrollIn:
|
|
1272
|
-
scrollOn:
|
|
1273
|
-
hover:
|
|
1274
|
-
click:
|
|
1554
|
+
load: __14("Page load", "elementor"),
|
|
1555
|
+
scrollIn: __14("Scroll into view", "elementor"),
|
|
1556
|
+
scrollOn: __14("While scrolling", "elementor"),
|
|
1557
|
+
hover: __14("On hover", "elementor"),
|
|
1558
|
+
click: __14("On click", "elementor")
|
|
1275
1559
|
};
|
|
1276
1560
|
var BASE_TRIGGERS = ["load", "scrollIn"];
|
|
1277
1561
|
function Trigger({ value, onChange }) {
|
|
@@ -1288,15 +1572,16 @@ function Trigger({ value, onChange }) {
|
|
|
1288
1572
|
onChange,
|
|
1289
1573
|
baseOptions,
|
|
1290
1574
|
disabledOptions,
|
|
1291
|
-
promotionLabel:
|
|
1292
|
-
promotionContent:
|
|
1293
|
-
upgradeUrl: "https://go.elementor.com/go-pro-interactions-triggers-modal/"
|
|
1575
|
+
promotionLabel: __14("PRO triggers", "elementor"),
|
|
1576
|
+
promotionContent: __14("Upgrade to unlock more interactions triggers.", "elementor"),
|
|
1577
|
+
upgradeUrl: "https://go.elementor.com/go-pro-interactions-triggers-modal/",
|
|
1578
|
+
trackingData: TRACKING_DATA4
|
|
1294
1579
|
}
|
|
1295
1580
|
);
|
|
1296
1581
|
}
|
|
1297
1582
|
|
|
1298
1583
|
// src/hooks/on-duplicate.ts
|
|
1299
|
-
import { getAllDescendants, getContainer } from "@elementor/editor-elements";
|
|
1584
|
+
import { getAllDescendants, getContainer as getContainer2 } from "@elementor/editor-elements";
|
|
1300
1585
|
import { registerDataHook } from "@elementor/editor-v1-adapters";
|
|
1301
1586
|
function initCleanInteractionIdsOnDuplicate() {
|
|
1302
1587
|
registerDataHook("after", "document/elements/duplicate", (_args, result) => {
|
|
@@ -1307,7 +1592,7 @@ function initCleanInteractionIdsOnDuplicate() {
|
|
|
1307
1592
|
});
|
|
1308
1593
|
}
|
|
1309
1594
|
function cleanInteractionIdsRecursive(elementId) {
|
|
1310
|
-
const container =
|
|
1595
|
+
const container = getContainer2(elementId);
|
|
1311
1596
|
if (!container) {
|
|
1312
1597
|
return;
|
|
1313
1598
|
}
|
|
@@ -1316,7 +1601,7 @@ function cleanInteractionIdsRecursive(elementId) {
|
|
|
1316
1601
|
});
|
|
1317
1602
|
}
|
|
1318
1603
|
function cleanInteractionIds(elementId) {
|
|
1319
|
-
const container =
|
|
1604
|
+
const container = getContainer2(elementId);
|
|
1320
1605
|
if (!container) {
|
|
1321
1606
|
return;
|
|
1322
1607
|
}
|
|
@@ -1415,13 +1700,14 @@ var initInteractionsSchemaResource = (reg) => {
|
|
|
1415
1700
|
};
|
|
1416
1701
|
|
|
1417
1702
|
// src/mcp/tools/manage-element-interaction-tool.ts
|
|
1418
|
-
import { updateElementInteractions as
|
|
1703
|
+
import { updateElementInteractions as updateElementInteractions3 } from "@elementor/editor-elements";
|
|
1419
1704
|
import { z as z2 } from "@elementor/schema";
|
|
1420
1705
|
import { isProActive as isProActive2 } from "@elementor/utils";
|
|
1421
1706
|
var EMPTY_INTERACTIONS = {
|
|
1422
1707
|
version: 1,
|
|
1423
1708
|
items: []
|
|
1424
1709
|
};
|
|
1710
|
+
var EFFECTS_WITHOUT_TYPE = ["custom"];
|
|
1425
1711
|
var initManageElementInteractionTool = (reg) => {
|
|
1426
1712
|
const { addTool } = reg;
|
|
1427
1713
|
const extendedSchema = isProActive2() ? { ...baseSchema, ...proSchema } : baseSchema;
|
|
@@ -1448,16 +1734,36 @@ var initManageElementInteractionTool = (reg) => {
|
|
|
1448
1734
|
},
|
|
1449
1735
|
handler: (input) => {
|
|
1450
1736
|
const { elementId, action, interactionId, ...animationData } = input;
|
|
1737
|
+
const { effectType, ...restAnimationData } = animationData;
|
|
1738
|
+
const effect = restAnimationData.effect;
|
|
1739
|
+
const resolvedType = effectType ?? (effect && !EFFECTS_WITHOUT_TYPE.includes(effect) ? "in" : void 0);
|
|
1451
1740
|
const allInteractions = interactionsRepository.all();
|
|
1452
1741
|
const elementData = allInteractions.find((data) => data.elementId === elementId);
|
|
1453
1742
|
const currentInteractions = elementData?.interactions ?? EMPTY_INTERACTIONS;
|
|
1454
1743
|
if (action === "get") {
|
|
1744
|
+
const summary = currentInteractions.items.map((item) => {
|
|
1745
|
+
const { value } = item;
|
|
1746
|
+
const animValue = value.animation.value;
|
|
1747
|
+
const timingValue = animValue.timing_config.value;
|
|
1748
|
+
const configValue = animValue.config.value;
|
|
1749
|
+
return {
|
|
1750
|
+
id: extractString(value.interaction_id),
|
|
1751
|
+
trigger: extractString(value.trigger),
|
|
1752
|
+
effect: extractString(animValue.effect),
|
|
1753
|
+
effectType: extractString(animValue.type),
|
|
1754
|
+
direction: extractString(animValue.direction),
|
|
1755
|
+
duration: extractSize(timingValue.duration),
|
|
1756
|
+
delay: extractSize(timingValue.delay),
|
|
1757
|
+
easing: extractString(configValue.easing),
|
|
1758
|
+
excludedBreakpoints: extractExcludedBreakpoints(value.breakpoints)
|
|
1759
|
+
};
|
|
1760
|
+
});
|
|
1455
1761
|
return {
|
|
1456
1762
|
success: true,
|
|
1457
1763
|
elementId,
|
|
1458
1764
|
action,
|
|
1459
|
-
interactions:
|
|
1460
|
-
count:
|
|
1765
|
+
interactions: summary,
|
|
1766
|
+
count: summary.length
|
|
1461
1767
|
};
|
|
1462
1768
|
}
|
|
1463
1769
|
let updatedItems = [...currentInteractions.items];
|
|
@@ -1470,7 +1776,8 @@ var initManageElementInteractionTool = (reg) => {
|
|
|
1470
1776
|
}
|
|
1471
1777
|
const newItem = createInteractionItem({
|
|
1472
1778
|
interactionId: generateTempInteractionId(),
|
|
1473
|
-
...
|
|
1779
|
+
...restAnimationData,
|
|
1780
|
+
type: resolvedType
|
|
1474
1781
|
});
|
|
1475
1782
|
updatedItems = [...updatedItems, newItem];
|
|
1476
1783
|
break;
|
|
@@ -1489,7 +1796,8 @@ var initManageElementInteractionTool = (reg) => {
|
|
|
1489
1796
|
}
|
|
1490
1797
|
const updatedItem = createInteractionItem({
|
|
1491
1798
|
interactionId,
|
|
1492
|
-
...
|
|
1799
|
+
...restAnimationData,
|
|
1800
|
+
type: resolvedType
|
|
1493
1801
|
});
|
|
1494
1802
|
updatedItems = [
|
|
1495
1803
|
...updatedItems.slice(0, itemIndex),
|
|
@@ -1523,7 +1831,7 @@ var initManageElementInteractionTool = (reg) => {
|
|
|
1523
1831
|
items: updatedItems
|
|
1524
1832
|
};
|
|
1525
1833
|
try {
|
|
1526
|
-
|
|
1834
|
+
updateElementInteractions3({ elementId, interactions: updatedInteractions });
|
|
1527
1835
|
} catch (error) {
|
|
1528
1836
|
throw new Error(
|
|
1529
1837
|
`Failed to update interactions for element "${elementId}": ${error instanceof Error ? error.message : "Unknown error"}`
|
|
@@ -1614,6 +1922,7 @@ function init() {
|
|
|
1614
1922
|
try {
|
|
1615
1923
|
interactionsRepository.register(documentElementsInteractionsProvider);
|
|
1616
1924
|
initCleanInteractionIdsOnDuplicate();
|
|
1925
|
+
initPasteInteractionsCommand();
|
|
1617
1926
|
registerInteractionsControl({
|
|
1618
1927
|
type: "trigger",
|
|
1619
1928
|
component: Trigger,
|
|
@@ -1627,7 +1936,7 @@ function init() {
|
|
|
1627
1936
|
registerInteractionsControl({
|
|
1628
1937
|
type: "replay",
|
|
1629
1938
|
component: Replay,
|
|
1630
|
-
options: ["
|
|
1939
|
+
options: ["no"]
|
|
1631
1940
|
});
|
|
1632
1941
|
registerInteractionsControl({
|
|
1633
1942
|
type: "effectType",
|
|
@@ -1661,10 +1970,33 @@ export {
|
|
|
1661
1970
|
InteractionsTab,
|
|
1662
1971
|
REPLAY_OPTIONS,
|
|
1663
1972
|
TRIGGER_OPTIONS,
|
|
1973
|
+
buildDisplayLabel,
|
|
1974
|
+
convertTimeUnit,
|
|
1975
|
+
createAnimationPreset,
|
|
1976
|
+
createBoolean,
|
|
1977
|
+
createConfig,
|
|
1978
|
+
createDefaultInteractionItem,
|
|
1979
|
+
createDefaultInteractions,
|
|
1980
|
+
createExcludedBreakpoints,
|
|
1981
|
+
createInteractionBreakpoints,
|
|
1982
|
+
createInteractionItem,
|
|
1664
1983
|
createInteractionsProvider,
|
|
1984
|
+
createNumber,
|
|
1985
|
+
createString,
|
|
1986
|
+
createTimingConfig,
|
|
1987
|
+
extractBoolean,
|
|
1988
|
+
extractExcludedBreakpoints,
|
|
1989
|
+
extractSize,
|
|
1990
|
+
extractString,
|
|
1991
|
+
formatSizeValue,
|
|
1992
|
+
generateTempInteractionId,
|
|
1665
1993
|
getInteractionsConfig,
|
|
1666
1994
|
init,
|
|
1667
1995
|
interactionsRepository,
|
|
1668
|
-
|
|
1996
|
+
isTempId,
|
|
1997
|
+
parseSizeValue,
|
|
1998
|
+
registerInteractionsControl,
|
|
1999
|
+
resolveDirection,
|
|
2000
|
+
useElementInteractions
|
|
1669
2001
|
};
|
|
1670
2002
|
//# sourceMappingURL=index.mjs.map
|