@elementor/editor-interactions 4.0.0-682 → 4.0.0-beta5

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
@@ -39,6 +39,8 @@ __export(index_exports, {
39
39
  ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX: () => ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX,
40
40
  EmptyState: () => EmptyState,
41
41
  InteractionsTab: () => InteractionsTab,
42
+ REPEAT_OPTIONS: () => REPEAT_OPTIONS,
43
+ REPEAT_TOOLTIPS: () => REPEAT_TOOLTIPS,
42
44
  REPLAY_OPTIONS: () => REPLAY_OPTIONS,
43
45
  TRIGGER_OPTIONS: () => TRIGGER_OPTIONS,
44
46
  buildDisplayLabel: () => buildDisplayLabel,
@@ -186,6 +188,110 @@ var createSizeValue = (size, unit) => {
186
188
  return { size, unit };
187
189
  };
188
190
 
191
+ // src/utils/custom-effect-to-prop-value.ts
192
+ var CUSTOM_EFFECT_TYPE = "custom-effect";
193
+ var KEYFRAMES_TYPE = "keyframes";
194
+ var KEYFRAME_STOP_TYPE = "keyframe-stop";
195
+ var KEYFRAME_STOP_SETTINGS_TYPE = "keyframe-stop-settings";
196
+ var SIZE_TYPE = "size";
197
+ var NUMBER_TYPE = "number";
198
+ var TRANSFORM_SCALE_TYPE = "transform-scale";
199
+ var TRANSFORM_ROTATE_TYPE = "transform-rotate";
200
+ var TRANSFORM_MOVE_TYPE = "transform-move";
201
+ var TRANSFORM_SKEW_TYPE = "transform-skew";
202
+ var UNIT_PERCENT = "%";
203
+ var UNIT_DEG = "deg";
204
+ var UNIT_PX = "px";
205
+ var isPlainCustomEffect = (v) => typeof v === "object" && v !== null && "keyframes" in v && Array.isArray(v.keyframes) && !("$$type" in v);
206
+ var toSizePropValue = (size, unit = UNIT_PERCENT) => ({
207
+ $$type: SIZE_TYPE,
208
+ value: { size, unit }
209
+ });
210
+ var toNumberPropValue = (n) => ({
211
+ $$type: NUMBER_TYPE,
212
+ value: n
213
+ });
214
+ var toDimensionalNumberPropValue = (type, plain, defaults) => ({
215
+ $$type: type,
216
+ value: {
217
+ x: toNumberPropValue(plain.x ?? defaults.x),
218
+ y: toNumberPropValue(plain.y ?? defaults.y),
219
+ z: toNumberPropValue(plain.z ?? defaults.z)
220
+ }
221
+ });
222
+ var toDimensionalSizePropValue = (type, plain, defaults, unit) => ({
223
+ $$type: type,
224
+ value: {
225
+ x: toSizePropValue(plain.x ?? defaults.x, unit),
226
+ y: toSizePropValue(plain.y ?? defaults.y, unit),
227
+ z: toSizePropValue(plain.z ?? defaults.z, unit)
228
+ }
229
+ });
230
+ var toSkewPropValue = (plain) => ({
231
+ $$type: TRANSFORM_SKEW_TYPE,
232
+ value: {
233
+ x: toSizePropValue(plain.x ?? 0, UNIT_DEG),
234
+ y: toSizePropValue(plain.y ?? 0, UNIT_DEG)
235
+ }
236
+ });
237
+ var toKeyframeStopSettingsPropValue = (plain) => {
238
+ const value = {};
239
+ if (plain.opacity !== void 0) {
240
+ const percent = plain.opacity <= 1 ? Math.round(plain.opacity * 100) : plain.opacity;
241
+ value.opacity = toSizePropValue(percent);
242
+ }
243
+ if (plain.scale !== void 0) {
244
+ value.scale = toDimensionalNumberPropValue(TRANSFORM_SCALE_TYPE, plain.scale, { x: 1, y: 1, z: 1 });
245
+ }
246
+ if (plain.rotate !== void 0) {
247
+ value.rotate = toDimensionalSizePropValue(
248
+ TRANSFORM_ROTATE_TYPE,
249
+ plain.rotate,
250
+ { x: 0, y: 0, z: 0 },
251
+ UNIT_DEG
252
+ );
253
+ }
254
+ if (plain.move !== void 0) {
255
+ value.move = toDimensionalSizePropValue(TRANSFORM_MOVE_TYPE, plain.move, { x: 0, y: 0, z: 0 }, UNIT_PX);
256
+ }
257
+ if (plain.skew !== void 0) {
258
+ value.skew = toSkewPropValue(plain.skew);
259
+ }
260
+ return { $$type: KEYFRAME_STOP_SETTINGS_TYPE, value };
261
+ };
262
+ var isPlainKeyframe = (v) => typeof v === "object" && v !== null && "stop" in v && "value" in v && !("$$type" in v);
263
+ var toKeyframeStopPropValue = (item) => {
264
+ if (!isPlainKeyframe(item)) {
265
+ return item;
266
+ }
267
+ return {
268
+ $$type: KEYFRAME_STOP_TYPE,
269
+ value: {
270
+ stop: toSizePropValue(item.stop),
271
+ settings: toKeyframeStopSettingsPropValue(item.value)
272
+ }
273
+ };
274
+ };
275
+ var toKeyframesPropValue = (keyframes) => ({
276
+ $$type: KEYFRAMES_TYPE,
277
+ value: keyframes.map(toKeyframeStopPropValue)
278
+ });
279
+ var plainCustomEffectToPropValue = (plain) => ({
280
+ $$type: CUSTOM_EFFECT_TYPE,
281
+ value: {
282
+ keyframes: toKeyframesPropValue(plain.keyframes)
283
+ }
284
+ });
285
+ var toCustomEffectPropValue = (customEffects) => {
286
+ if (customEffects === void 0) {
287
+ return void 0;
288
+ }
289
+ if (isPlainCustomEffect(customEffects)) {
290
+ return plainCustomEffectToPropValue(customEffects);
291
+ }
292
+ return customEffects;
293
+ };
294
+
189
295
  // src/utils/get-interactions-config.ts
190
296
  function getInteractionsConfig() {
191
297
  return window.ElementorInteractionsConfig ?? {};
@@ -224,7 +330,7 @@ var createBoolean = (value) => ({
224
330
  var createConfig = ({
225
331
  replay,
226
332
  easing = "easeIn",
227
- relativeTo = "",
333
+ relativeTo = "viewport",
228
334
  repeat = "",
229
335
  times = 1,
230
336
  start = 85,
@@ -277,25 +383,28 @@ var createAnimationPreset = ({
277
383
  start,
278
384
  end,
279
385
  customEffects
280
- }) => ({
281
- $$type: "animation-preset-props",
282
- value: {
283
- effect: createString(effect),
284
- custom_effect: customEffects,
285
- type: createString(type),
286
- direction: createString(direction ?? ""),
287
- timing_config: createTimingConfig(duration, delay),
288
- config: createConfig({
289
- replay,
290
- easing,
291
- relativeTo,
292
- repeat,
293
- times,
294
- start,
295
- end
296
- })
297
- }
298
- });
386
+ }) => {
387
+ const customEffectProp = toCustomEffectPropValue(customEffects);
388
+ return {
389
+ $$type: "animation-preset-props",
390
+ value: {
391
+ effect: createString(effect),
392
+ ...customEffectProp !== void 0 && { custom_effect: customEffectProp },
393
+ type: createString(type),
394
+ direction: createString(direction ?? ""),
395
+ timing_config: createTimingConfig(duration, delay),
396
+ config: createConfig({
397
+ replay,
398
+ easing,
399
+ relativeTo,
400
+ repeat,
401
+ times,
402
+ start,
403
+ end
404
+ })
405
+ }
406
+ };
407
+ };
299
408
  var createInteractionItem = ({
300
409
  trigger,
301
410
  effect,
@@ -757,7 +866,6 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
757
866
  controlVisibilityConfig.times(interactionValues)
758
867
  );
759
868
  const EasingControl = useControlComponent("easing");
760
- const containerRef = (0, import_react6.useRef)(null);
761
869
  const updateInteraction = (updates) => {
762
870
  const resolvedDirectionValue = resolveDirection(
763
871
  "direction" in updates,
@@ -792,19 +900,12 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
792
900
  onPlayInteraction(interactionId);
793
901
  }, 0);
794
902
  };
795
- return /* @__PURE__ */ React7.createElement(import_ui3.Box, { ref: containerRef }, /* @__PURE__ */ React7.createElement(import_editor_controls3.PopoverContent, { p: 1.5 }, /* @__PURE__ */ React7.createElement(import_ui3.Grid, { container: true, spacing: 1.5 }, TriggerControl && /* @__PURE__ */ React7.createElement(Field, { label: (0, import_i18n2.__)("Trigger", "elementor") }, /* @__PURE__ */ React7.createElement(
796
- TriggerControl,
797
- {
798
- value: trigger,
799
- onChange: (v) => updateInteraction({ trigger: v })
800
- }
801
- )), ReplayControl && /* @__PURE__ */ React7.createElement(Field, { label: (0, import_i18n2.__)("Replay", "elementor") }, /* @__PURE__ */ React7.createElement(
903
+ return /* @__PURE__ */ React7.createElement(import_editor_controls3.PopoverContent, { p: 1.5 }, /* @__PURE__ */ React7.createElement(import_ui3.Grid, { container: true, spacing: 1.5 }, TriggerControl && /* @__PURE__ */ React7.createElement(Field, { label: (0, import_i18n2.__)("Trigger", "elementor") }, /* @__PURE__ */ React7.createElement(TriggerControl, { value: trigger, onChange: (v) => updateInteraction({ trigger: v }) })), ReplayControl && /* @__PURE__ */ React7.createElement(Field, { label: (0, import_i18n2.__)("Replay", "elementor") }, /* @__PURE__ */ React7.createElement(
802
904
  ReplayControl,
803
905
  {
804
906
  value: replay,
805
907
  onChange: (v) => updateInteraction({ replay: v }),
806
- disabled: true,
807
- anchorRef: containerRef
908
+ disabled: true
808
909
  }
809
910
  ))), /* @__PURE__ */ React7.createElement(import_ui3.Divider, null), /* @__PURE__ */ React7.createElement(import_ui3.Grid, { container: true, spacing: 1.5 }, EffectControl && /* @__PURE__ */ React7.createElement(Field, { label: (0, import_i18n2.__)("Effect", "elementor") }, /* @__PURE__ */ React7.createElement(EffectControl, { value: effect, onChange: (v) => updateInteraction({ effect: v }) })), CustomEffectControl && /* @__PURE__ */ React7.createElement(Field, { label: (0, import_i18n2.__)("Custom Effect", "elementor") }, /* @__PURE__ */ React7.createElement(
810
911
  CustomEffectControl,
@@ -867,7 +968,7 @@ var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
867
968
  updateInteraction({ easing: v });
868
969
  }
869
970
  }
870
- )))));
971
+ ))));
871
972
  };
872
973
 
873
974
  // src/components/interaction-settings.tsx
@@ -1217,6 +1318,9 @@ var documentElementsInteractionsProvider = createInteractionsProvider({
1217
1318
  }
1218
1319
  });
1219
1320
 
1321
+ // src/init.ts
1322
+ var import_editor_mcp = require("@elementor/editor-mcp");
1323
+
1220
1324
  // src/commands/paste-interactions.ts
1221
1325
  var import_editor_elements5 = require("@elementor/editor-elements");
1222
1326
  var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
@@ -1417,7 +1521,6 @@ var InteractionsPromotionChip = (0, import_react12.forwardRef)(
1417
1521
  );
1418
1522
  }
1419
1523
  );
1420
- InteractionsPromotionChip.displayName = "InteractionsPromotionChip";
1421
1524
 
1422
1525
  // src/ui/promotion-select.tsx
1423
1526
  function PromotionSelect({
@@ -1565,58 +1668,128 @@ function EffectType({ value, onChange }) {
1565
1668
  return /* @__PURE__ */ React17.createElement(import_editor_controls8.ToggleButtonGroupUi, { items: options, exclusive: true, onChange, value });
1566
1669
  }
1567
1670
 
1568
- // src/components/controls/replay.tsx
1569
- var React18 = __toESM(require("react"));
1671
+ // src/components/controls/repeat.tsx
1672
+ var React19 = __toESM(require("react"));
1673
+ var import_react15 = require("react");
1570
1674
  var import_editor_controls9 = require("@elementor/editor-controls");
1571
1675
  var import_icons4 = require("@elementor/icons");
1572
- var import_ui10 = require("@elementor/ui");
1573
1676
  var import_i18n13 = require("@wordpress/i18n");
1574
- var TRACKING_DATA3 = { target_name: "interactions_replay", location_l2: "interactions" };
1677
+
1678
+ // src/ui/promotion-overlay-layout.tsx
1679
+ var React18 = __toESM(require("react"));
1680
+ var import_react14 = require("react");
1681
+ var import_ui10 = require("@elementor/ui");
1682
+ var OVERLAY_GRID = "1 / 1";
1683
+ var CHIP_OFFSET = "50%";
1684
+ var PromotionOverlayLayout = (0, import_react14.forwardRef)(
1685
+ ({ children, promotionChip }, ref) => /* @__PURE__ */ React18.createElement(import_ui10.Box, { ref, sx: { display: "grid", alignItems: "center" } }, /* @__PURE__ */ React18.createElement(import_ui10.Box, { sx: { gridArea: OVERLAY_GRID } }, children), /* @__PURE__ */ React18.createElement(import_ui10.Box, { sx: { gridArea: OVERLAY_GRID, marginInlineEnd: CHIP_OFFSET, justifySelf: "end" } }, promotionChip))
1686
+ );
1687
+
1688
+ // src/components/controls/repeat.tsx
1689
+ var TRACKING_DATA3 = { target_name: "interactions_repeat", location_l2: "interactions" };
1690
+ var REPEAT_OPTIONS = {
1691
+ times: (0, import_i18n13.__)("times", "elementor"),
1692
+ loop: (0, import_i18n13.__)("loop", "elementor")
1693
+ };
1694
+ var REPEAT_TOOLTIPS = {
1695
+ times: (0, import_i18n13.__)("Enable number", "elementor"),
1696
+ loop: (0, import_i18n13.__)("Infinite repeat", "elementor")
1697
+ };
1698
+ function Repeat() {
1699
+ const repeatContainerRef = (0, import_react15.useRef)(null);
1700
+ const options = [
1701
+ {
1702
+ value: REPEAT_OPTIONS.times,
1703
+ disabled: true,
1704
+ label: REPEAT_TOOLTIPS.times,
1705
+ renderContent: ({ size }) => /* @__PURE__ */ React19.createElement(import_icons4.Number123Icon, { fontSize: size }),
1706
+ showTooltip: true
1707
+ },
1708
+ {
1709
+ value: REPEAT_OPTIONS.loop,
1710
+ disabled: true,
1711
+ label: REPEAT_TOOLTIPS.loop,
1712
+ renderContent: ({ size }) => /* @__PURE__ */ React19.createElement(import_icons4.RepeatIcon, { fontSize: size }),
1713
+ showTooltip: true
1714
+ }
1715
+ ];
1716
+ return /* @__PURE__ */ React19.createElement(
1717
+ PromotionOverlayLayout,
1718
+ {
1719
+ ref: repeatContainerRef,
1720
+ promotionChip: /* @__PURE__ */ React19.createElement(
1721
+ InteractionsPromotionChip,
1722
+ {
1723
+ content: (0, import_i18n13.__)("Upgrade to control how many times the animation repeats.", "elementor"),
1724
+ upgradeUrl: "https://go.elementor.com/go-pro-interactions-repeat-modal/",
1725
+ anchorRef: repeatContainerRef,
1726
+ trackingData: TRACKING_DATA3
1727
+ }
1728
+ )
1729
+ },
1730
+ /* @__PURE__ */ React19.createElement(import_editor_controls9.ToggleButtonGroupUi, { items: options, exclusive: true, onChange: () => {
1731
+ }, value: "" })
1732
+ );
1733
+ }
1734
+
1735
+ // src/components/controls/replay.tsx
1736
+ var React20 = __toESM(require("react"));
1737
+ var import_react16 = require("react");
1738
+ var import_editor_controls10 = require("@elementor/editor-controls");
1739
+ var import_icons5 = require("@elementor/icons");
1740
+ var import_i18n14 = require("@wordpress/i18n");
1741
+ var TRACKING_DATA4 = { target_name: "interactions_replay", location_l2: "interactions" };
1575
1742
  var REPLAY_OPTIONS = {
1576
- no: (0, import_i18n13.__)("No", "elementor"),
1577
- yes: (0, import_i18n13.__)("Yes", "elementor")
1743
+ no: (0, import_i18n14.__)("No", "elementor"),
1744
+ yes: (0, import_i18n14.__)("Yes", "elementor")
1578
1745
  };
1579
1746
  var BASE_REPLAY = ["no"];
1580
- var OVERLAY_GRID = "1 / 1";
1581
- var CHIP_OFFSET = "50%";
1582
- function Replay({ onChange, anchorRef }) {
1747
+ function Replay({ onChange }) {
1748
+ const replayContainerRef = (0, import_react16.useRef)(null);
1583
1749
  const options = [
1584
1750
  {
1585
1751
  value: false,
1586
1752
  disabled: false,
1587
1753
  label: REPLAY_OPTIONS.no,
1588
- renderContent: ({ size }) => /* @__PURE__ */ React18.createElement(import_icons4.MinusIcon, { fontSize: size }),
1754
+ renderContent: ({ size }) => /* @__PURE__ */ React20.createElement(import_icons5.MinusIcon, { fontSize: size }),
1589
1755
  showTooltip: true
1590
1756
  },
1591
1757
  {
1592
1758
  value: true,
1593
1759
  disabled: true,
1594
1760
  label: REPLAY_OPTIONS.yes,
1595
- renderContent: ({ size }) => /* @__PURE__ */ React18.createElement(import_icons4.CheckIcon, { fontSize: size }),
1761
+ renderContent: ({ size }) => /* @__PURE__ */ React20.createElement(import_icons5.CheckIcon, { fontSize: size }),
1596
1762
  showTooltip: true
1597
1763
  }
1598
1764
  ];
1599
- return /* @__PURE__ */ React18.createElement(import_ui10.Box, { sx: { display: "grid", alignItems: "center" } }, /* @__PURE__ */ React18.createElement(import_ui10.Box, { sx: { gridArea: OVERLAY_GRID } }, /* @__PURE__ */ React18.createElement(import_editor_controls9.ToggleButtonGroupUi, { items: options, exclusive: true, onChange, value: false })), /* @__PURE__ */ React18.createElement(import_ui10.Box, { sx: { gridArea: OVERLAY_GRID, marginInlineEnd: CHIP_OFFSET, justifySelf: "end" } }, /* @__PURE__ */ React18.createElement(
1600
- InteractionsPromotionChip,
1765
+ return /* @__PURE__ */ React20.createElement(
1766
+ PromotionOverlayLayout,
1601
1767
  {
1602
- content: (0, import_i18n13.__)("Upgrade to run the animation every time its trigger occurs.", "elementor"),
1603
- upgradeUrl: "https://go.elementor.com/go-pro-interactions-replay-modal/",
1604
- anchorRef,
1605
- trackingData: TRACKING_DATA3
1606
- }
1607
- )));
1768
+ ref: replayContainerRef,
1769
+ promotionChip: /* @__PURE__ */ React20.createElement(
1770
+ InteractionsPromotionChip,
1771
+ {
1772
+ content: (0, import_i18n14.__)("Upgrade to run the animation every time its trigger occurs.", "elementor"),
1773
+ upgradeUrl: "https://go.elementor.com/go-pro-interactions-replay-modal/",
1774
+ anchorRef: replayContainerRef,
1775
+ trackingData: TRACKING_DATA4
1776
+ }
1777
+ )
1778
+ },
1779
+ /* @__PURE__ */ React20.createElement(import_editor_controls10.ToggleButtonGroupUi, { items: options, exclusive: true, onChange, value: false })
1780
+ );
1608
1781
  }
1609
1782
 
1610
1783
  // src/components/controls/trigger.tsx
1611
- var React19 = __toESM(require("react"));
1612
- var import_i18n14 = require("@wordpress/i18n");
1613
- var TRACKING_DATA4 = { target_name: "interactions_trigger", location_l2: "interactions" };
1784
+ var React21 = __toESM(require("react"));
1785
+ var import_i18n15 = require("@wordpress/i18n");
1786
+ var TRACKING_DATA5 = { target_name: "interactions_trigger", location_l2: "interactions" };
1614
1787
  var TRIGGER_OPTIONS = {
1615
- load: (0, import_i18n14.__)("Page load", "elementor"),
1616
- scrollIn: (0, import_i18n14.__)("Scroll into view", "elementor"),
1617
- scrollOn: (0, import_i18n14.__)("While scrolling", "elementor"),
1618
- hover: (0, import_i18n14.__)("On hover", "elementor"),
1619
- click: (0, import_i18n14.__)("On click", "elementor")
1788
+ load: (0, import_i18n15.__)("Page load", "elementor"),
1789
+ scrollIn: (0, import_i18n15.__)("Scroll into view", "elementor"),
1790
+ scrollOn: (0, import_i18n15.__)("While scrolling", "elementor"),
1791
+ hover: (0, import_i18n15.__)("On hover", "elementor"),
1792
+ click: (0, import_i18n15.__)("On click", "elementor")
1620
1793
  };
1621
1794
  var BASE_TRIGGERS = ["load", "scrollIn"];
1622
1795
  function Trigger({ value, onChange }) {
@@ -1626,17 +1799,17 @@ function Trigger({ value, onChange }) {
1626
1799
  const disabledOptions = Object.fromEntries(
1627
1800
  Object.entries(TRIGGER_OPTIONS).filter(([key]) => !BASE_TRIGGERS.includes(key))
1628
1801
  );
1629
- return /* @__PURE__ */ React19.createElement(
1802
+ return /* @__PURE__ */ React21.createElement(
1630
1803
  PromotionSelect,
1631
1804
  {
1632
1805
  value: value in baseOptions ? value : DEFAULT_VALUES.trigger,
1633
1806
  onChange,
1634
1807
  baseOptions,
1635
1808
  disabledOptions,
1636
- promotionLabel: (0, import_i18n14.__)("PRO triggers", "elementor"),
1637
- promotionContent: (0, import_i18n14.__)("Upgrade to unlock more interactions triggers.", "elementor"),
1809
+ promotionLabel: (0, import_i18n15.__)("PRO triggers", "elementor"),
1810
+ promotionContent: (0, import_i18n15.__)("Upgrade to unlock more interactions triggers.", "elementor"),
1638
1811
  upgradeUrl: "https://go.elementor.com/go-pro-interactions-triggers-modal/",
1639
- trackingData: TRACKING_DATA4
1812
+ trackingData: TRACKING_DATA5
1640
1813
  }
1641
1814
  );
1642
1815
  }
@@ -1679,12 +1852,6 @@ function cleanInteractionIds(elementId) {
1679
1852
  container.model.set("interactions", updatedInteractions);
1680
1853
  }
1681
1854
 
1682
- // src/mcp/index.ts
1683
- var import_editor_mcp = require("@elementor/editor-mcp");
1684
-
1685
- // src/mcp/constants.ts
1686
- var MAX_INTERACTIONS_PER_ELEMENT = 5;
1687
-
1688
1855
  // src/mcp/resources/interactions-schema-resource.ts
1689
1856
  var import_utils = require("@elementor/utils");
1690
1857
 
@@ -1705,7 +1872,7 @@ var baseSchema = {
1705
1872
  var proSchema = {
1706
1873
  trigger: import_schema.z.enum(["load", "scrollIn", "scrollOut", "scrollOn", "hover", "click"]).optional().describe("Event that triggers the animation"),
1707
1874
  effect: import_schema.z.enum(["fade", "slide", "scale", "custom"]).optional().describe("Animation effect type"),
1708
- customEffect: import_schema.z.object({
1875
+ customEffects: import_schema.z.object({
1709
1876
  keyframes: import_schema.z.array(
1710
1877
  import_schema.z.object({
1711
1878
  stop: import_schema.z.number().describe("The stop of the keyframe in percent, can be either 0 or 100"),
@@ -1764,6 +1931,69 @@ var initInteractionsSchemaResource = (reg) => {
1764
1931
  var import_editor_elements7 = require("@elementor/editor-elements");
1765
1932
  var import_schema3 = require("@elementor/schema");
1766
1933
  var import_utils2 = require("@elementor/utils");
1934
+
1935
+ // src/mcp/constants.ts
1936
+ var MAX_INTERACTIONS_PER_ELEMENT = 5;
1937
+ var EDITOR_INTERACTIONS_MCP_INSTRUCTIONS = `MCP server for managing element interactions and animations. Use this to add, modify, or remove animations and motion effects triggered by user events such as page load or scroll-into-view.
1938
+ ** IMPORTANT **
1939
+ Use the "interactions-schema" resource to get the schema of the interactions.
1940
+ Actions:
1941
+ - get: Read the current interactions on the element.
1942
+ - add: Add a new interaction (max ${MAX_INTERACTIONS_PER_ELEMENT} per element).
1943
+ - update: Update an existing interaction by its interactionId.
1944
+ - delete: Remove a specific interaction by its interactionId.
1945
+ - clear: Remove all interactions from the element.
1946
+
1947
+ For add/update, provide: trigger, effect, effectType, direction (required for slide effect), duration, delay, easing.
1948
+ Use excludedBreakpoints to disable the animation on specific responsive breakpoints (e.g. ["mobile", "tablet"]).
1949
+ Example Get Request:
1950
+ {
1951
+ "elementId": "123",
1952
+ "action": "get",
1953
+ "interactionId": "123",
1954
+ "animationData": {
1955
+ "trigger": "click",
1956
+ "effect": "fade",
1957
+ }
1958
+ }
1959
+ Example Add Request:
1960
+ {
1961
+ "elementId": "123",
1962
+ "action": "add",
1963
+ "animationData": {
1964
+ "effectType": "in",
1965
+ "direction": "top",
1966
+ "trigger": "click",
1967
+ "effect": "fade",
1968
+ "duration": 1000,
1969
+ "delay": 0,
1970
+ "easing": "easeIn",
1971
+ "excludedBreakpoints": ["mobile", "tablet"],
1972
+ }
1973
+ }
1974
+ Example Update Request:
1975
+ {
1976
+ "elementId": "123",
1977
+ "action": "update",
1978
+ "interactionId": "123",
1979
+ "animationData": {
1980
+ "trigger": "click",
1981
+ "effect": "fade",
1982
+ }
1983
+ }
1984
+ Example Delete Request:
1985
+ {
1986
+ "elementId": "123",
1987
+ "action": "delete",
1988
+ "interactionId": "123",
1989
+ }
1990
+ Example Clear Request:
1991
+ {
1992
+ "elementId": "123",
1993
+ "action": "clear",
1994
+ }`;
1995
+
1996
+ // src/mcp/tools/manage-element-interaction-tool.ts
1767
1997
  var EMPTY_INTERACTIONS = {
1768
1998
  version: 1,
1769
1999
  items: []
@@ -1909,73 +2139,18 @@ var initManageElementInteractionTool = (reg) => {
1909
2139
  };
1910
2140
 
1911
2141
  // src/mcp/index.ts
1912
- var initMcpInteractions = () => {
1913
- const reg = (0, import_editor_mcp.getMCPByDomain)("interactions", {
1914
- instructions: `
1915
- MCP server for managing element interactions and animations. Use this to add, modify, or remove animations and motion effects triggered by user events such as page load or scroll-into-view.
1916
- ** IMPORTANT **
1917
- Use the "interactions-schema" resource to get the schema of the interactions.
1918
- Actions:
1919
- - get: Read the current interactions on the element.
1920
- - add: Add a new interaction (max ${MAX_INTERACTIONS_PER_ELEMENT} per element).
1921
- - update: Update an existing interaction by its interactionId.
1922
- - delete: Remove a specific interaction by its interactionId.
1923
- - clear: Remove all interactions from the element.
1924
-
1925
- For add/update, provide: trigger, effect, effectType, direction (required for slide effect), duration, delay, easing.
1926
- Use excludedBreakpoints to disable the animation on specific responsive breakpoints (e.g. ["mobile", "tablet"]).
1927
- Example Get Request:
1928
- {
1929
- "elementId": "123",
1930
- "action": "get",
1931
- "interactionId": "123",
1932
- "animationData": {
1933
- "trigger": "click",
1934
- "effect": "fade",
1935
- }
1936
- }
1937
- Example Add Request:
1938
- {
1939
- "elementId": "123",
1940
- "action": "add",
1941
- "animationData": {
1942
- "effectType": "in",
1943
- "direction": "top",
1944
- "trigger": "click",
1945
- "effect": "fade",
1946
- "duration": 1000,
1947
- "delay": 0,
1948
- "easing": "easeIn",
1949
- "excludedBreakpoints": ["mobile", "tablet"],
1950
- }
1951
- }
1952
- Example Update Request:
1953
- {
1954
- "elementId": "123",
1955
- "action": "update",
1956
- "interactionId": "123",
1957
- "animationData": {
1958
- "trigger": "click",
1959
- "effect": "fade",
1960
- }
1961
- }
1962
- Example Delete Request:
1963
- {
1964
- "elementId": "123",
1965
- "action": "delete",
1966
- "interactionId": "123",
1967
- }
1968
- Example Clear Request:
1969
- {
1970
- "elementId": "123",
1971
- "action": "clear",
1972
- }
1973
- `
1974
- });
1975
- reg.waitForReady().then(() => {
1976
- initInteractionsSchemaResource(reg);
1977
- initManageElementInteractionTool(reg);
1978
- });
2142
+ var initMcpInteractions = (reg) => {
2143
+ const { setMCPDescription } = reg;
2144
+ setMCPDescription(
2145
+ `Everything related to V4 ( Atomic ) interactions.
2146
+ # Interactions
2147
+ - Create/update/delete interactions
2148
+ - Get list of interactions
2149
+ - Get details of an interaction
2150
+ `
2151
+ );
2152
+ initInteractionsSchemaResource(reg);
2153
+ initManageElementInteractionTool(reg);
1979
2154
  };
1980
2155
 
1981
2156
  // src/init.ts
@@ -2014,7 +2189,11 @@ function init() {
2014
2189
  component: Effect,
2015
2190
  options: ["fade", "slide", "scale"]
2016
2191
  });
2017
- initMcpInteractions();
2192
+ registerInteractionsControl({
2193
+ type: "repeat",
2194
+ component: Repeat
2195
+ });
2196
+ initMcpInteractions((0, import_editor_mcp.getMCPByDomain)("interactions", { instructions: EDITOR_INTERACTIONS_MCP_INSTRUCTIONS }));
2018
2197
  } catch (error) {
2019
2198
  throw error;
2020
2199
  }
@@ -2030,6 +2209,8 @@ function init() {
2030
2209
  ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX,
2031
2210
  EmptyState,
2032
2211
  InteractionsTab,
2212
+ REPEAT_OPTIONS,
2213
+ REPEAT_TOOLTIPS,
2033
2214
  REPLAY_OPTIONS,
2034
2215
  TRIGGER_OPTIONS,
2035
2216
  buildDisplayLabel,