@elementor/editor-canvas 4.2.0-946 → 4.2.0-beta1

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
@@ -33,6 +33,7 @@ __export(index_exports, {
33
33
  BREAKPOINTS_SCHEMA_FULL_URI: () => BREAKPOINTS_SCHEMA_FULL_URI,
34
34
  BREAKPOINTS_SCHEMA_URI: () => BREAKPOINTS_SCHEMA_URI,
35
35
  DOCUMENT_STRUCTURE_URI: () => DOCUMENT_STRUCTURE_URI,
36
+ ELEMENT_ADDED_EVENT: () => ELEMENT_ADDED_EVENT,
36
37
  GLOBAL_STYLES_IMPORTED_EVENT: () => GLOBAL_STYLES_IMPORTED_EVENT,
37
38
  SpotlightBackdrop: () => SpotlightBackdrop,
38
39
  UnknownStyleStateError: () => UnknownStyleStateError,
@@ -396,7 +397,7 @@ var convertCssToAtomic = async (style) => {
396
397
 
397
398
  // src/init.tsx
398
399
  var import_editor = require("@elementor/editor");
399
- var import_editor_mcp4 = require("@elementor/editor-mcp");
400
+ var import_editor_mcp6 = require("@elementor/editor-mcp");
400
401
 
401
402
  // src/components/classes-rename.tsx
402
403
  var import_react = require("react");
@@ -445,12 +446,8 @@ var React7 = __toESM(require("react"));
445
446
  var import_editor_elements5 = require("@elementor/editor-elements");
446
447
  var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
447
448
 
448
- // src/components/grid-outline/grid-outline-overlay.tsx
449
- var React6 = __toESM(require("react"));
450
- var import_editor_elements4 = require("@elementor/editor-elements");
451
- var import_editor_props2 = require("@elementor/editor-props");
452
- var import_ui2 = require("@elementor/ui");
453
- var import_react10 = require("@floating-ui/react");
449
+ // src/components/grid-outline/grid-empty-cell-positioner.tsx
450
+ var import_react5 = require("react");
454
451
 
455
452
  // src/hooks/use-element-rect.ts
456
453
  var import_react2 = require("react");
@@ -515,49 +512,8 @@ function useMutationsListener({ element, onChange }) {
515
512
  }, [element, onChange]);
516
513
  }
517
514
 
518
- // src/hooks/use-floating-on-element.ts
519
- var import_react3 = require("react");
520
- var import_react4 = require("@floating-ui/react");
521
- function useFloatingOnElement({ element, isSelected }) {
522
- const [isOpen, setIsOpen] = (0, import_react3.useState)(false);
523
- const sizeModifier = 2;
524
- const { refs, floatingStyles, context } = (0, import_react4.useFloating)({
525
- // Must be controlled for interactions (like hover) to work.
526
- open: isOpen || isSelected,
527
- onOpenChange: setIsOpen,
528
- whileElementsMounted: import_react4.autoUpdate,
529
- middleware: [
530
- // Match the floating element's size to the reference element.
531
- (0, import_react4.size)(() => {
532
- return {
533
- apply({ elements, rects }) {
534
- Object.assign(elements.floating.style, {
535
- width: `${rects.reference.width + sizeModifier}px`,
536
- height: `${rects.reference.height + sizeModifier}px`
537
- });
538
- }
539
- };
540
- }),
541
- // Center the floating element on the reference element.
542
- (0, import_react4.offset)(({ rects }) => -rects.reference.height / 2 - rects.floating.height / 2)
543
- ]
544
- });
545
- (0, import_react3.useEffect)(() => {
546
- refs.setReference(element);
547
- }, [element, refs]);
548
- return {
549
- isVisible: isOpen || isSelected,
550
- context,
551
- floating: {
552
- setRef: refs.setFloating,
553
- ref: refs.floating,
554
- styles: floatingStyles
555
- }
556
- };
557
- }
558
-
559
515
  // src/hooks/use-grid-tracks.ts
560
- var import_react6 = require("react");
516
+ var import_react4 = require("react");
561
517
  var import_editor_elements3 = require("@elementor/editor-elements");
562
518
  var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
563
519
 
@@ -644,10 +600,10 @@ function toPx(value) {
644
600
  }
645
601
 
646
602
  // src/hooks/use-grid-children.ts
647
- var import_react5 = require("react");
603
+ var import_react3 = require("react");
648
604
  function useGridChildren(element) {
649
- const [signal, setSignal] = (0, import_react5.useState)(0);
650
- (0, import_react5.useEffect)(() => {
605
+ const [signal, setSignal] = (0, import_react3.useState)(0);
606
+ (0, import_react3.useEffect)(() => {
651
607
  if (!element) {
652
608
  return;
653
609
  }
@@ -694,13 +650,13 @@ var EMPTY = {
694
650
  };
695
651
  var DEVICE_MODE_CHANGE_EVENT = "elementor/device-mode/change";
696
652
  function useGridTracks(element, rect) {
697
- const [tracks, setTracks] = (0, import_react6.useState)(EMPTY);
653
+ const [tracks, setTracks] = (0, import_react4.useState)(EMPTY);
698
654
  const trigger = (0, import_editor_v1_adapters2.__privateUseListenTo)(
699
655
  [(0, import_editor_v1_adapters2.windowEvent)(import_editor_elements3.ELEMENT_STYLE_CHANGE_EVENT), (0, import_editor_v1_adapters2.windowEvent)(DEVICE_MODE_CHANGE_EVENT)],
700
656
  () => ({})
701
657
  );
702
658
  const childrenTrigger = useGridChildren(element);
703
- (0, import_react6.useEffect)(() => {
659
+ (0, import_react4.useEffect)(() => {
704
660
  const previewWindow = element?.ownerDocument?.defaultView;
705
661
  if (!element || !previewWindow) {
706
662
  setTracks(EMPTY);
@@ -716,98 +672,6 @@ function useGridTracks(element, rect) {
716
672
  return tracks;
717
673
  }
718
674
 
719
- // src/components/outline-overlay.tsx
720
- var React = __toESM(require("react"));
721
- var import_ui = require("@elementor/ui");
722
- var import_react8 = require("@floating-ui/react");
723
-
724
- // src/hooks/use-bind-react-props-to-element.ts
725
- var import_react7 = require("react");
726
- function useBindReactPropsToElement(element, getProps) {
727
- (0, import_react7.useEffect)(() => {
728
- const el = element;
729
- const { events, attrs } = groupProps(getProps());
730
- events.forEach(([eventName, listener]) => el.addEventListener(eventName, listener));
731
- attrs.forEach(([attrName, attrValue]) => el.setAttribute(attrName, attrValue));
732
- return () => {
733
- events.forEach(([eventName, listener]) => el.removeEventListener(eventName, listener));
734
- attrs.forEach(([attrName]) => el.removeAttribute(attrName));
735
- };
736
- }, [getProps, element]);
737
- }
738
- function groupProps(props) {
739
- const eventRegex = /^on(?=[A-Z])/;
740
- return Object.entries(props).reduce(
741
- (acc, [propName, propValue]) => {
742
- if (!eventRegex.test(propName)) {
743
- acc.attrs.push([propName, propValue]);
744
- return acc;
745
- }
746
- const eventName = propName.replace(eventRegex, "").toLowerCase();
747
- const listener = propValue;
748
- acc.events.push([eventName, listener]);
749
- return acc;
750
- },
751
- {
752
- events: [],
753
- attrs: []
754
- }
755
- );
756
- }
757
-
758
- // src/hooks/use-has-overlapping.ts
759
- var possibleOverlappingSelectors = [".e-off-canvas"];
760
- var useHasOverlapping = () => {
761
- const preview = window.elementor?.$preview?.[0];
762
- if (!preview) {
763
- return false;
764
- }
765
- const hasOverlapping = possibleOverlappingSelectors.map((selector) => Array.from(preview?.contentWindow?.document.body.querySelectorAll(selector) ?? [])).flat().some(
766
- (elem) => elem.checkVisibility({
767
- opacityProperty: true,
768
- visibilityProperty: true,
769
- contentVisibilityAuto: true
770
- })
771
- );
772
- return hasOverlapping;
773
- };
774
-
775
- // src/components/outline-overlay.tsx
776
- var CANVAS_WRAPPER_ID = "elementor-preview-responsive-wrapper";
777
- var OverlayBox = (0, import_ui.styled)(import_ui.Box, {
778
- shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isSmallerOffset" && prop !== "isGlobal"
779
- })(
780
- ({ theme, isSelected, isSmallerOffset, isGlobal }) => ({
781
- outline: `${isSelected ? "2px" : "1px"} solid ${isGlobal ? theme.palette.global.main : theme.palette.primary.light}`,
782
- outlineOffset: isSelected && !isSmallerOffset ? "-2px" : "-1px",
783
- pointerEvents: "none"
784
- })
785
- );
786
- var OutlineOverlay = ({ element, isSelected, id, isGlobal = false }) => {
787
- const { context, floating, isVisible } = useFloatingOnElement({ element, isSelected });
788
- const { getFloatingProps, getReferenceProps } = (0, import_react8.useInteractions)([(0, import_react8.useHover)(context)]);
789
- const hasOverlapping = useHasOverlapping();
790
- useBindReactPropsToElement(element, getReferenceProps);
791
- const isSmallerOffset = element.offsetHeight <= 1;
792
- return isVisible && !hasOverlapping && /* @__PURE__ */ React.createElement(import_react8.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React.createElement(
793
- OverlayBox,
794
- {
795
- ref: floating.setRef,
796
- isSelected,
797
- isGlobal,
798
- style: floating.styles,
799
- "data-element-overlay": id,
800
- role: "presentation",
801
- isSmallerOffset,
802
- ...getFloatingProps()
803
- }
804
- ));
805
- };
806
-
807
- // src/components/grid-outline/grid-outline.tsx
808
- var React5 = __toESM(require("react"));
809
- var import_react9 = require("react");
810
-
811
675
  // src/utils/find-first-empty-cell.ts
812
676
  function findFirstEmptyCell(element, columnCount, rowCount) {
813
677
  if (!element || columnCount === 0 || rowCount === 0) {
@@ -970,6 +834,179 @@ function scanFirstEmpty(matrix, flowsByColumn) {
970
834
  return null;
971
835
  }
972
836
 
837
+ // src/components/grid-outline/grid-empty-cell-positioner.tsx
838
+ var CSS_VAR_ROW = "--e-grid-empty-cell-row";
839
+ var CSS_VAR_COL = "--e-grid-empty-cell-col";
840
+ var CSS_VAR_VISIBILITY = "--e-grid-empty-cell-visibility";
841
+ var clearGridEmptyCellStyles = (target) => {
842
+ target.style.removeProperty(CSS_VAR_ROW);
843
+ target.style.removeProperty(CSS_VAR_COL);
844
+ target.style.removeProperty(CSS_VAR_VISIBILITY);
845
+ };
846
+ var GridEmptyCellPositioner = ({ element }) => {
847
+ const rect = useElementRect(element);
848
+ const tracks = useGridTracks(element, rect);
849
+ (0, import_react5.useEffect)(() => {
850
+ if (!element) {
851
+ return;
852
+ }
853
+ const firstEmpty = findFirstEmptyCell(element, tracks.columns.length, tracks.rows.length);
854
+ if (!firstEmpty) {
855
+ element.style.removeProperty(CSS_VAR_ROW);
856
+ element.style.removeProperty(CSS_VAR_COL);
857
+ element.style.setProperty(CSS_VAR_VISIBILITY, "hidden");
858
+ return () => clearGridEmptyCellStyles(element);
859
+ }
860
+ element.style.setProperty(CSS_VAR_ROW, String(firstEmpty.row + 1));
861
+ element.style.setProperty(CSS_VAR_COL, String(firstEmpty.col + 1));
862
+ element.style.setProperty(CSS_VAR_VISIBILITY, "visible");
863
+ return () => {
864
+ clearGridEmptyCellStyles(element);
865
+ };
866
+ }, [element, tracks]);
867
+ return null;
868
+ };
869
+
870
+ // src/components/grid-outline/grid-outline-overlay.tsx
871
+ var React6 = __toESM(require("react"));
872
+ var import_editor_elements4 = require("@elementor/editor-elements");
873
+ var import_editor_props2 = require("@elementor/editor-props");
874
+ var import_ui2 = require("@elementor/ui");
875
+ var import_react11 = require("@floating-ui/react");
876
+
877
+ // src/hooks/use-floating-on-element.ts
878
+ var import_react6 = require("react");
879
+ var import_react7 = require("@floating-ui/react");
880
+ function useFloatingOnElement({ element, isSelected }) {
881
+ const [isOpen, setIsOpen] = (0, import_react6.useState)(false);
882
+ const sizeModifier = 2;
883
+ const { refs, floatingStyles, context } = (0, import_react7.useFloating)({
884
+ // Must be controlled for interactions (like hover) to work.
885
+ open: isOpen || isSelected,
886
+ onOpenChange: setIsOpen,
887
+ whileElementsMounted: import_react7.autoUpdate,
888
+ middleware: [
889
+ // Match the floating element's size to the reference element.
890
+ (0, import_react7.size)(() => {
891
+ return {
892
+ apply({ elements, rects }) {
893
+ Object.assign(elements.floating.style, {
894
+ width: `${rects.reference.width + sizeModifier}px`,
895
+ height: `${rects.reference.height + sizeModifier}px`
896
+ });
897
+ }
898
+ };
899
+ }),
900
+ // Center the floating element on the reference element.
901
+ (0, import_react7.offset)(({ rects }) => -rects.reference.height / 2 - rects.floating.height / 2)
902
+ ]
903
+ });
904
+ (0, import_react6.useEffect)(() => {
905
+ refs.setReference(element);
906
+ }, [element, refs]);
907
+ return {
908
+ isVisible: isOpen || isSelected,
909
+ context,
910
+ floating: {
911
+ setRef: refs.setFloating,
912
+ ref: refs.floating,
913
+ styles: floatingStyles
914
+ }
915
+ };
916
+ }
917
+
918
+ // src/components/outline-overlay.tsx
919
+ var React = __toESM(require("react"));
920
+ var import_ui = require("@elementor/ui");
921
+ var import_react9 = require("@floating-ui/react");
922
+
923
+ // src/hooks/use-bind-react-props-to-element.ts
924
+ var import_react8 = require("react");
925
+ function useBindReactPropsToElement(element, getProps) {
926
+ (0, import_react8.useEffect)(() => {
927
+ const el = element;
928
+ const { events, attrs } = groupProps(getProps());
929
+ events.forEach(([eventName, listener]) => el.addEventListener(eventName, listener));
930
+ attrs.forEach(([attrName, attrValue]) => el.setAttribute(attrName, attrValue));
931
+ return () => {
932
+ events.forEach(([eventName, listener]) => el.removeEventListener(eventName, listener));
933
+ attrs.forEach(([attrName]) => el.removeAttribute(attrName));
934
+ };
935
+ }, [getProps, element]);
936
+ }
937
+ function groupProps(props) {
938
+ const eventRegex = /^on(?=[A-Z])/;
939
+ return Object.entries(props).reduce(
940
+ (acc, [propName, propValue]) => {
941
+ if (!eventRegex.test(propName)) {
942
+ acc.attrs.push([propName, propValue]);
943
+ return acc;
944
+ }
945
+ const eventName = propName.replace(eventRegex, "").toLowerCase();
946
+ const listener = propValue;
947
+ acc.events.push([eventName, listener]);
948
+ return acc;
949
+ },
950
+ {
951
+ events: [],
952
+ attrs: []
953
+ }
954
+ );
955
+ }
956
+
957
+ // src/hooks/use-has-overlapping.ts
958
+ var possibleOverlappingSelectors = [".e-off-canvas"];
959
+ var useHasOverlapping = () => {
960
+ const preview = window.elementor?.$preview?.[0];
961
+ if (!preview) {
962
+ return false;
963
+ }
964
+ const hasOverlapping = possibleOverlappingSelectors.map((selector) => Array.from(preview?.contentWindow?.document.body.querySelectorAll(selector) ?? [])).flat().some(
965
+ (elem) => elem.checkVisibility({
966
+ opacityProperty: true,
967
+ visibilityProperty: true,
968
+ contentVisibilityAuto: true
969
+ })
970
+ );
971
+ return hasOverlapping;
972
+ };
973
+
974
+ // src/components/outline-overlay.tsx
975
+ var CANVAS_WRAPPER_ID = "elementor-preview-responsive-wrapper";
976
+ var OverlayBox = (0, import_ui.styled)(import_ui.Box, {
977
+ shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isSmallerOffset" && prop !== "isGlobal"
978
+ })(
979
+ ({ theme, isSelected, isSmallerOffset, isGlobal }) => ({
980
+ outline: `${isSelected ? "2px" : "1px"} solid ${isGlobal ? theme.palette.global.main : theme.palette.primary.light}`,
981
+ outlineOffset: isSelected && !isSmallerOffset ? "-2px" : "-1px",
982
+ pointerEvents: "none"
983
+ })
984
+ );
985
+ var OutlineOverlay = ({ element, isSelected, id, isGlobal = false }) => {
986
+ const { context, floating, isVisible } = useFloatingOnElement({ element, isSelected });
987
+ const { getFloatingProps, getReferenceProps } = (0, import_react9.useInteractions)([(0, import_react9.useHover)(context)]);
988
+ const hasOverlapping = useHasOverlapping();
989
+ useBindReactPropsToElement(element, getReferenceProps);
990
+ const isSmallerOffset = element.offsetHeight <= 1;
991
+ return isVisible && !hasOverlapping && /* @__PURE__ */ React.createElement(import_react9.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React.createElement(
992
+ OverlayBox,
993
+ {
994
+ ref: floating.setRef,
995
+ isSelected,
996
+ isGlobal,
997
+ style: floating.styles,
998
+ "data-element-overlay": id,
999
+ role: "presentation",
1000
+ isSmallerOffset,
1001
+ ...getFloatingProps()
1002
+ }
1003
+ ));
1004
+ };
1005
+
1006
+ // src/components/grid-outline/grid-outline.tsx
1007
+ var React5 = __toESM(require("react"));
1008
+ var import_react10 = require("react");
1009
+
973
1010
  // src/components/grid-outline/cell.tsx
974
1011
  var React2 = __toESM(require("react"));
975
1012
  var FALLBACK_COLOR = "rgba(0, 0, 0, 0.12)";
@@ -1077,10 +1114,17 @@ var renderLines = (tracks, width, height) => {
1077
1114
  ))
1078
1115
  ];
1079
1116
  };
1117
+ var isDragActiveFromDom = (element) => {
1118
+ return Boolean(
1119
+ element?.querySelector(
1120
+ ".e-dragging-over, .elementor-dragging-on-child, .elementor-draggable-over, .elementor-widget-placeholder, .elementor-sortable-placeholder"
1121
+ )
1122
+ );
1123
+ };
1080
1124
  function GridOutline({ element, tracks, width, height }) {
1081
- const cells = (0, import_react9.useMemo)(() => computeCellRects(tracks, width, height), [tracks, width, height]);
1125
+ const cells = (0, import_react10.useMemo)(() => computeCellRects(tracks, width, height), [tracks, width, height]);
1082
1126
  const hasGap = tracks.columnGap > 0 || tracks.rowGap > 0;
1083
- const firstEmpty = (0, import_react9.useMemo)(
1127
+ const firstEmpty = (0, import_react10.useMemo)(
1084
1128
  () => findFirstEmptyCell(element, tracks.columns.length, tracks.rows.length),
1085
1129
  [element, tracks]
1086
1130
  );
@@ -1094,7 +1138,7 @@ function GridOutline({ element, tracks, width, height }) {
1094
1138
  xmlns: "http://www.w3.org/2000/svg"
1095
1139
  },
1096
1140
  hasGap ? renderCells(cells, tracks.borderColor) : renderLines(tracks, width, height)
1097
- ), emptyCellRect && /* @__PURE__ */ React5.createElement(FirstEmptyCell, { rect: emptyCellRect, color: tracks.borderColor }));
1141
+ ), emptyCellRect && !isDragActiveFromDom(element) && /* @__PURE__ */ React5.createElement(FirstEmptyCell, { rect: emptyCellRect, color: tracks.borderColor }));
1098
1142
  }
1099
1143
 
1100
1144
  // src/components/grid-outline/grid-outline-overlay.tsx
@@ -1110,7 +1154,7 @@ var GridOutlineOverlay = ({ element, id, isSelected }) => {
1110
1154
  if (tracks.columns.length === 0 && tracks.rows.length === 0) {
1111
1155
  return null;
1112
1156
  }
1113
- return /* @__PURE__ */ React6.createElement(import_react10.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React6.createElement(
1157
+ return /* @__PURE__ */ React6.createElement(import_react11.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React6.createElement(
1114
1158
  import_ui2.Box,
1115
1159
  {
1116
1160
  ref: floating.setRef,
@@ -1124,14 +1168,20 @@ var GridOutlineOverlay = ({ element, id, isSelected }) => {
1124
1168
 
1125
1169
  // src/components/elements-overlays.tsx
1126
1170
  var ELEMENTS_DATA_ATTR = "atomic";
1171
+ var E_GRID_TYPE = "e-grid";
1172
+ var isGridElement = (element) => [element.dataset.eType, element.dataset.element_type].includes(E_GRID_TYPE);
1127
1173
  var overlayRegistry = [
1128
1174
  {
1129
1175
  component: OutlineOverlay,
1130
1176
  shouldRender: () => true
1131
1177
  },
1178
+ {
1179
+ component: GridEmptyCellPositioner,
1180
+ shouldRender: ({ element }) => isGridElement(element)
1181
+ },
1132
1182
  {
1133
1183
  component: GridOutlineOverlay,
1134
- shouldRender: ({ element, isSelected }) => isSelected && element.dataset.eType === "e-grid"
1184
+ shouldRender: ({ element, isSelected }) => isSelected && isGridElement(element)
1135
1185
  }
1136
1186
  ];
1137
1187
  function ElementsOverlays() {
@@ -1185,15 +1235,15 @@ var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
1185
1235
  var import_ui3 = require("@elementor/ui");
1186
1236
 
1187
1237
  // src/hooks/use-interactions-items.ts
1188
- var import_react12 = require("react");
1238
+ var import_react13 = require("react");
1189
1239
  var import_editor_interactions = require("@elementor/editor-interactions");
1190
1240
  var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
1191
1241
 
1192
1242
  // src/hooks/use-on-mount.ts
1193
- var import_react11 = require("react");
1243
+ var import_react12 = require("react");
1194
1244
  function useOnMount(cb) {
1195
- const mounted = (0, import_react11.useRef)(false);
1196
- (0, import_react11.useEffect)(() => {
1245
+ const mounted = (0, import_react12.useRef)(false);
1246
+ (0, import_react12.useEffect)(() => {
1197
1247
  if (!mounted.current) {
1198
1248
  mounted.current = true;
1199
1249
  cb();
@@ -1203,8 +1253,8 @@ function useOnMount(cb) {
1203
1253
 
1204
1254
  // src/hooks/use-interactions-items.ts
1205
1255
  function useInteractionsItems() {
1206
- const [interactionItems, setInteractionItems] = (0, import_react12.useState)({});
1207
- const providerAndSubscribers = (0, import_react12.useMemo)(() => {
1256
+ const [interactionItems, setInteractionItems] = (0, import_react13.useState)({});
1257
+ const providerAndSubscribers = (0, import_react13.useMemo)(() => {
1208
1258
  try {
1209
1259
  const providers = import_editor_interactions.interactionsRepository.getProviders();
1210
1260
  const mapped = providers.map((provider) => {
@@ -1221,7 +1271,7 @@ function useInteractionsItems() {
1221
1271
  return [];
1222
1272
  }
1223
1273
  }, []);
1224
- (0, import_react12.useEffect)(() => {
1274
+ (0, import_react13.useEffect)(() => {
1225
1275
  if (providerAndSubscribers.length === 0) {
1226
1276
  return;
1227
1277
  }
@@ -1252,7 +1302,7 @@ function useInteractionsItems() {
1252
1302
  });
1253
1303
  });
1254
1304
  });
1255
- return (0, import_react12.useMemo)(() => {
1305
+ return (0, import_react13.useMemo)(() => {
1256
1306
  const result = Object.values(interactionItems).sort(sortByProviderPriority).flatMap(({ items }) => items);
1257
1307
  return result;
1258
1308
  }, [interactionItems]);
@@ -1350,7 +1400,7 @@ function getLinkAttrs(el) {
1350
1400
  }
1351
1401
 
1352
1402
  // src/hooks/use-style-items.ts
1353
- var import_react15 = require("react");
1403
+ var import_react16 = require("react");
1354
1404
  var import_editor_responsive2 = require("@elementor/editor-responsive");
1355
1405
  var import_editor_styles3 = require("@elementor/editor-styles");
1356
1406
  var import_editor_styles_repository2 = require("@elementor/editor-styles-repository");
@@ -1412,7 +1462,7 @@ function signalizedProcess(signal, steps = []) {
1412
1462
  }
1413
1463
 
1414
1464
  // src/hooks/use-style-prop-resolver.ts
1415
- var import_react13 = require("react");
1465
+ var import_react14 = require("react");
1416
1466
  var import_editor_styles = require("@elementor/editor-styles");
1417
1467
  var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
1418
1468
 
@@ -1561,7 +1611,7 @@ var styleTransformersRegistry = createTransformersRegistry();
1561
1611
 
1562
1612
  // src/hooks/use-style-prop-resolver.ts
1563
1613
  function useStylePropResolver() {
1564
- return (0, import_react13.useMemo)(() => {
1614
+ return (0, import_react14.useMemo)(() => {
1565
1615
  return createPropsResolver({
1566
1616
  transformers: styleTransformersRegistry,
1567
1617
  schema: (0, import_editor_styles.getStylesSchema)(),
@@ -1573,7 +1623,7 @@ function useStylePropResolver() {
1573
1623
  }
1574
1624
 
1575
1625
  // src/hooks/use-style-renderer.ts
1576
- var import_react14 = require("react");
1626
+ var import_react15 = require("react");
1577
1627
  var import_editor_responsive = require("@elementor/editor-responsive");
1578
1628
 
1579
1629
  // src/renderers/create-styles-renderer.ts
@@ -1682,7 +1732,7 @@ function customCssToString(customCss) {
1682
1732
  var SELECTOR_PREFIX = ".elementor";
1683
1733
  function useStyleRenderer(resolve) {
1684
1734
  const breakpoints = (0, import_editor_responsive.useBreakpointsMap)();
1685
- return (0, import_react14.useMemo)(() => {
1735
+ return (0, import_react15.useMemo)(() => {
1686
1736
  return createStylesRenderer({
1687
1737
  selectorPrefix: SELECTOR_PREFIX,
1688
1738
  breakpoints,
@@ -1696,9 +1746,9 @@ function useStyleItems() {
1696
1746
  const resolve = useStylePropResolver();
1697
1747
  const renderStyles = useStyleRenderer(resolve);
1698
1748
  const breakpoints = (0, import_editor_responsive2.useBreakpoints)();
1699
- const [styleItems, setStyleItems] = (0, import_react15.useState)({});
1700
- const styleItemsCacheRef = (0, import_react15.useRef)(/* @__PURE__ */ new Map());
1701
- const providerAndSubscribers = (0, import_react15.useMemo)(() => {
1749
+ const [styleItems, setStyleItems] = (0, import_react16.useState)({});
1750
+ const styleItemsCacheRef = (0, import_react16.useRef)(/* @__PURE__ */ new Map());
1751
+ const providerAndSubscribers = (0, import_react16.useMemo)(() => {
1702
1752
  const createEmptyCache = () => {
1703
1753
  return { orderedIds: [], itemsById: /* @__PURE__ */ new Map() };
1704
1754
  };
@@ -1724,7 +1774,7 @@ function useStyleItems() {
1724
1774
  })
1725
1775
  );
1726
1776
  }, [renderStyles]);
1727
- (0, import_react15.useEffect)(() => {
1777
+ (0, import_react16.useEffect)(() => {
1728
1778
  const unsubscribes = providerAndSubscribers.map(
1729
1779
  ({ provider, subscriber }) => provider.subscribe(subscriber)
1730
1780
  );
@@ -1739,11 +1789,11 @@ function useStyleItems() {
1739
1789
  await Promise.all(promises);
1740
1790
  });
1741
1791
  });
1742
- const breakpointSorter = (0, import_react15.useMemo)(
1792
+ const breakpointSorter = (0, import_react16.useMemo)(
1743
1793
  () => createBreakpointSorter(breakpoints.map((breakpoint) => breakpoint.id)),
1744
1794
  [breakpoints]
1745
1795
  );
1746
- return (0, import_react15.useMemo)(
1796
+ return (0, import_react16.useMemo)(
1747
1797
  () => Object.values(styleItems).sort(prioritySorter).flatMap(({ items }) => items).sort(stateSorter).sort(breakpointSorter),
1748
1798
  [styleItems, breakpointSorter]
1749
1799
  );
@@ -3423,13 +3473,13 @@ var ReplacementBase = class {
3423
3473
 
3424
3474
  // src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
3425
3475
  var React10 = __toESM(require("react"));
3426
- var import_react17 = require("react");
3476
+ var import_react18 = require("react");
3427
3477
  var import_editor_controls2 = require("@elementor/editor-controls");
3428
3478
  var import_ui5 = require("@elementor/ui");
3429
- var import_react18 = require("@floating-ui/react");
3479
+ var import_react19 = require("@floating-ui/react");
3430
3480
 
3431
3481
  // src/legacy/replacements/inline-editing/inline-editing-utils.ts
3432
- var import_react16 = require("react");
3482
+ var import_react17 = require("react");
3433
3483
  var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
3434
3484
  var NAVIGATOR_SELECTOR = "#elementor-navigator";
3435
3485
  var EDITING_PANEL = "#elementor-panel";
@@ -3460,8 +3510,8 @@ var getInlineEditorElement = (elementWrapper, expectedTag) => {
3460
3510
  return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
3461
3511
  };
3462
3512
  var useOnClickOutsideIframe = (handleUnmount) => {
3463
- const asyncUnmountInlineEditor = (0, import_react16.useCallback)(() => queueMicrotask(handleUnmount), [handleUnmount]);
3464
- (0, import_react16.useEffect)(() => {
3513
+ const asyncUnmountInlineEditor = (0, import_react17.useCallback)(() => queueMicrotask(handleUnmount), [handleUnmount]);
3514
+ (0, import_react17.useEffect)(() => {
3465
3515
  EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
3466
3516
  (selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
3467
3517
  );
@@ -3471,8 +3521,8 @@ var useOnClickOutsideIframe = (handleUnmount) => {
3471
3521
  }, []);
3472
3522
  };
3473
3523
  var useRenderToolbar = (ownerDocument, id) => {
3474
- const [anchor, setAnchor] = (0, import_react16.useState)(null);
3475
- (0, import_react16.useEffect)(() => {
3524
+ const [anchor, setAnchor] = (0, import_react17.useState)(null);
3525
+ (0, import_react17.useEffect)(() => {
3476
3526
  if (!anchor) {
3477
3527
  removeToolbarAnchor(ownerDocument, id);
3478
3528
  }
@@ -3486,7 +3536,7 @@ var useRenderToolbar = (ownerDocument, id) => {
3486
3536
  setAnchor(null);
3487
3537
  }
3488
3538
  };
3489
- const clearAnchor = (0, import_react16.useCallback)(() => {
3539
+ const clearAnchor = (0, import_react17.useCallback)(() => {
3490
3540
  setAnchor(null);
3491
3541
  }, []);
3492
3542
  return { onSelectionEnd, anchor, clearAnchor };
@@ -3566,21 +3616,21 @@ var CanvasInlineEditor = ({
3566
3616
  setValue,
3567
3617
  requestDestroy
3568
3618
  }) => {
3569
- const [active, setActive] = (0, import_react17.useState)(true);
3570
- const [editor, setEditor] = (0, import_react17.useState)(null);
3619
+ const [active, setActive] = (0, import_react18.useState)(true);
3620
+ const [editor, setEditor] = (0, import_react18.useState)(null);
3571
3621
  const { onSelectionEnd, anchor: toolbarAnchor, clearAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
3572
- (0, import_react17.useEffect)(() => {
3622
+ (0, import_react18.useEffect)(() => {
3573
3623
  if (!active) {
3574
3624
  clearAnchor();
3575
3625
  requestDestroy();
3576
3626
  }
3577
3627
  }, [active, clearAnchor, requestDestroy]);
3578
- const dismiss = (0, import_react17.useCallback)(() => {
3628
+ const dismiss = (0, import_react18.useCallback)(() => {
3579
3629
  setEditor(null);
3580
3630
  setActive(false);
3581
3631
  }, []);
3582
3632
  useOnClickOutsideIframe(dismiss);
3583
- (0, import_react17.useEffect)(() => {
3633
+ (0, import_react18.useEffect)(() => {
3584
3634
  const ownerDocument = contentElement.ownerDocument;
3585
3635
  const handleClickAway = (event) => {
3586
3636
  if (contentElement.contains(event.target)) {
@@ -3619,25 +3669,25 @@ var InlineEditingOverlay = ({
3619
3669
  id
3620
3670
  }) => {
3621
3671
  const inlineEditedElement = getInlineEditorElement(rootElement, expectedTag);
3622
- const [overlayRefElement, setOverlayElement] = (0, import_react17.useState)(inlineEditedElement);
3623
- (0, import_react17.useEffect)(() => {
3672
+ const [overlayRefElement, setOverlayElement] = (0, import_react18.useState)(inlineEditedElement);
3673
+ (0, import_react18.useEffect)(() => {
3624
3674
  setOverlayElement(getInlineEditorElement(rootElement, expectedTag));
3625
3675
  }, [expectedTag, rootElement]);
3626
3676
  return overlayRefElement ? /* @__PURE__ */ React10.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
3627
3677
  };
3628
3678
  var InlineEditingToolbar = ({ anchor, editor, id }) => {
3629
- const { refs, floatingStyles } = (0, import_react18.useFloating)({
3679
+ const { refs, floatingStyles } = (0, import_react19.useFloating)({
3630
3680
  placement: "top",
3631
3681
  strategy: "fixed",
3632
3682
  transform: false,
3633
- whileElementsMounted: import_react18.autoUpdate,
3634
- middleware: [horizontalShifterMiddleware, (0, import_react18.flip)()]
3683
+ whileElementsMounted: import_react19.autoUpdate,
3684
+ middleware: [horizontalShifterMiddleware, (0, import_react19.flip)()]
3635
3685
  });
3636
- (0, import_react17.useLayoutEffect)(() => {
3686
+ (0, import_react18.useLayoutEffect)(() => {
3637
3687
  refs.setReference(anchor);
3638
3688
  return () => refs.setReference(null);
3639
3689
  }, [anchor, refs]);
3640
- return /* @__PURE__ */ React10.createElement(import_react18.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React10.createElement(
3690
+ return /* @__PURE__ */ React10.createElement(import_react19.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React10.createElement(
3641
3691
  import_ui5.Box,
3642
3692
  {
3643
3693
  ref: refs.setFloating,
@@ -4656,6 +4706,7 @@ function getElementDisplayName(container) {
4656
4706
  // src/mcp/tools/build-composition/tool.ts
4657
4707
  var import_editor_documents3 = require("@elementor/editor-documents");
4658
4708
  var import_editor_elements16 = require("@elementor/editor-elements");
4709
+ var import_editor_mcp3 = require("@elementor/editor-mcp");
4659
4710
 
4660
4711
  // src/composition-builder/composition-builder.ts
4661
4712
  var import_editor_elements15 = require("@elementor/editor-elements");
@@ -5161,6 +5212,12 @@ ${childTypeErrors.join("\n")}`);
5161
5212
  }
5162
5213
  };
5163
5214
 
5215
+ // src/utils/tracking.ts
5216
+ var import_events = require("@elementor/events");
5217
+ var trackCanvasEvent = (data) => {
5218
+ (0, import_events.trackEvent)(data);
5219
+ };
5220
+
5164
5221
  // src/mcp/utils/get-composition-target-container.ts
5165
5222
  var import_editor_documents2 = require("@elementor/editor-documents");
5166
5223
  function getCompositionTargetContainer(documentContainer, documentType) {
@@ -5408,6 +5465,7 @@ function serializeWrapped(doc, rootElement, wrapperConfigId) {
5408
5465
  }
5409
5466
 
5410
5467
  // src/mcp/tools/build-composition/tool.ts
5468
+ var ELEMENT_ADDED_EVENT = "elementor/canvas/element-added";
5411
5469
  var initBuildCompositionsTool = (reg) => {
5412
5470
  const { addTool, resource } = reg;
5413
5471
  resource(
@@ -5462,6 +5520,15 @@ var initBuildCompositionsTool = (reg) => {
5462
5520
  const { configErrors, rootContainers: generatedRootContainers } = await compositionBuilder.build(targetContainer);
5463
5521
  rootContainers.push(...generatedRootContainers);
5464
5522
  generatedXML = new XMLSerializer().serializeToString(compositionBuilder.getXML());
5523
+ rootContainers.forEach((container) => {
5524
+ const elementData = container.model?.toJSON();
5525
+ if (elementData) {
5526
+ onElementAdded(elementData);
5527
+ }
5528
+ });
5529
+ Object.values(stylesConfig).forEach((styleValue) => {
5530
+ (0, import_editor_mcp3.dispatchMcpStylesAppliedEvent)({ styleValue });
5531
+ });
5465
5532
  if (configErrors.length) {
5466
5533
  errors.push(...configErrors.map((msg) => new Error(msg)));
5467
5534
  }
@@ -5554,16 +5621,39 @@ function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
5554
5621
  }
5555
5622
  }
5556
5623
  }
5624
+ function onElementAdded(element) {
5625
+ const elType = element.elType ?? "";
5626
+ const widgetType = element.widgetType ?? "";
5627
+ const elementName = elType === "widget" ? widgetType : elType;
5628
+ trackCanvasEvent({
5629
+ eventName: "add_element",
5630
+ executed_by: "mcp_tool",
5631
+ element_name: elementName,
5632
+ element_type: elType,
5633
+ widget_type: widgetType
5634
+ });
5635
+ const event = {
5636
+ element,
5637
+ executedBy: "mcp_tool"
5638
+ };
5639
+ window.dispatchEvent(new CustomEvent(ELEMENT_ADDED_EVENT, { detail: event }));
5640
+ if (element.elements?.length) {
5641
+ element.elements?.forEach((childElement) => {
5642
+ onElementAdded(childElement);
5643
+ });
5644
+ }
5645
+ }
5557
5646
 
5558
5647
  // src/mcp/tools/configure-element/tool.ts
5559
5648
  var import_editor_elements17 = require("@elementor/editor-elements");
5649
+ var import_editor_mcp5 = require("@elementor/editor-mcp");
5560
5650
  var import_editor_props10 = require("@elementor/editor-props");
5561
5651
 
5562
5652
  // src/mcp/tools/configure-element/prompt.ts
5563
- var import_editor_mcp3 = require("@elementor/editor-mcp");
5653
+ var import_editor_mcp4 = require("@elementor/editor-mcp");
5564
5654
  var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
5565
5655
  var generatePrompt2 = () => {
5566
- const configureElementToolPrompt = (0, import_editor_mcp3.toolPrompts)("configure-element");
5656
+ const configureElementToolPrompt = (0, import_editor_mcp4.toolPrompts)("configure-element");
5567
5657
  configureElementToolPrompt.description(`
5568
5658
  Configure an existing element on the page.
5569
5659
 
@@ -5795,6 +5885,7 @@ async function applyStyleFromCss(opts) {
5795
5885
  propertyValue: styleValue,
5796
5886
  customCssWriteMode: "merge-with-stored"
5797
5887
  });
5888
+ (0, import_editor_mcp5.dispatchMcpStylesAppliedEvent)({ styleValue });
5798
5889
  } catch (error) {
5799
5890
  throw new Error(
5800
5891
  createUpdateErrorMessage({
@@ -6406,7 +6497,7 @@ function init() {
6406
6497
  component: ClassesRename
6407
6498
  });
6408
6499
  initCanvasMcp(
6409
- (0, import_editor_mcp4.getMCPByDomain)("canvas", {
6500
+ (0, import_editor_mcp6.getMCPByDomain)("canvas", {
6410
6501
  instructions: `Everything related to V4 ( Atomic ) canvas.
6411
6502
  # Canvas workflow for new compositions
6412
6503
  - Configure elements settings and styles
@@ -6515,9 +6606,9 @@ function useCanvasDocument() {
6515
6606
  }
6516
6607
 
6517
6608
  // src/hooks/use-escape-on-canvas.ts
6518
- var import_react19 = require("react");
6609
+ var import_react20 = require("react");
6519
6610
  function useEscapeOnCanvas(canvasDocument, onEscape) {
6520
- (0, import_react19.useEffect)(() => {
6611
+ (0, import_react20.useEffect)(() => {
6521
6612
  if (!canvasDocument) {
6522
6613
  return;
6523
6614
  }
@@ -6557,6 +6648,7 @@ function hasDoAfterRender(view) {
6557
6648
  BREAKPOINTS_SCHEMA_FULL_URI,
6558
6649
  BREAKPOINTS_SCHEMA_URI,
6559
6650
  DOCUMENT_STRUCTURE_URI,
6651
+ ELEMENT_ADDED_EVENT,
6560
6652
  GLOBAL_STYLES_IMPORTED_EVENT,
6561
6653
  SpotlightBackdrop,
6562
6654
  UnknownStyleStateError,