@elementor/editor-canvas 4.2.0-913 → 4.2.0-915

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -356,7 +356,7 @@ var renameClass = (oldClassName, newClassName) => {
356
356
  };
357
357
 
358
358
  // src/components/elements-overlays.tsx
359
- import * as React5 from "react";
359
+ import * as React6 from "react";
360
360
  import { getElements, useSelectedElement } from "@elementor/editor-elements";
361
361
  import {
362
362
  __privateUseIsRouteActive as useIsRouteActive,
@@ -366,7 +366,7 @@ import {
366
366
  } from "@elementor/editor-v1-adapters";
367
367
 
368
368
  // src/components/grid-outline/grid-outline-overlay.tsx
369
- import * as React4 from "react";
369
+ import * as React5 from "react";
370
370
  import { useSelectedElementSettings } from "@elementor/editor-elements";
371
371
  import { booleanPropTypeUtil } from "@elementor/editor-props";
372
372
  import { Box as Box2 } from "@elementor/ui";
@@ -477,7 +477,7 @@ function useFloatingOnElement({ element, isSelected }) {
477
477
  }
478
478
 
479
479
  // src/hooks/use-grid-tracks.ts
480
- import { useEffect as useEffect4, useState as useState3 } from "react";
480
+ import { useEffect as useEffect5, useState as useState4 } from "react";
481
481
  import { ELEMENT_STYLE_CHANGE_EVENT } from "@elementor/editor-elements";
482
482
  import { __privateUseListenTo as useListenTo, windowEvent } from "@elementor/editor-v1-adapters";
483
483
 
@@ -514,6 +514,29 @@ function computeCellRects(tracks, width, height) {
514
514
  }
515
515
  return cells;
516
516
  }
517
+ function computeGridLines(tracks, width, height) {
518
+ const { columns, rows, columnGap, rowGap, padding } = tracks;
519
+ const hasColumns = columns.length > 0;
520
+ const hasRows = rows.length > 0;
521
+ if (!hasColumns && !hasRows) {
522
+ return { vertical: [], horizontal: [] };
523
+ }
524
+ const columnSegments = hasColumns ? computeTrackSegments(columns, columnGap, padding.left) : [{ start: padding.left, size: width - padding.left - padding.right }];
525
+ const rowSegments = hasRows ? computeTrackSegments(rows, rowGap, padding.top) : [{ start: padding.top, size: height - padding.top - padding.bottom }];
526
+ const xs = uniqueSorted(columnSegments.flatMap((s) => [s.start, s.start + s.size]));
527
+ const ys = uniqueSorted(rowSegments.flatMap((s) => [s.start, s.start + s.size]));
528
+ const yTop = ys[0];
529
+ const yBottom = ys[ys.length - 1];
530
+ const xLeft = xs[0];
531
+ const xRight = xs[xs.length - 1];
532
+ return {
533
+ vertical: xs.map((x) => ({ x1: x, y1: yTop, x2: x, y2: yBottom })),
534
+ horizontal: ys.map((y) => ({ x1: xLeft, y1: y, x2: xRight, y2: y }))
535
+ };
536
+ }
537
+ function uniqueSorted(values) {
538
+ return Array.from(new Set(values)).sort((a, b) => a - b);
539
+ }
517
540
  function computeTrackSegments(sizes, gap, offset2) {
518
541
  const segments = [];
519
542
  let cursor = offset2;
@@ -540,6 +563,46 @@ function toPx(value) {
540
563
  return Number.isFinite(parsed) ? parsed : 0;
541
564
  }
542
565
 
566
+ // src/hooks/use-grid-children.ts
567
+ import { useEffect as useEffect4, useState as useState3 } from "react";
568
+ function useGridChildren(element) {
569
+ const [signal, setSignal] = useState3(0);
570
+ useEffect4(() => {
571
+ if (!element) {
572
+ return;
573
+ }
574
+ const bump = () => setSignal((previous) => previous + 1);
575
+ const resizeObserver = new ResizeObserver(bump);
576
+ const observed = /* @__PURE__ */ new Set();
577
+ const syncChildren = () => {
578
+ for (const child of Array.from(element.children)) {
579
+ if (!observed.has(child)) {
580
+ resizeObserver.observe(child);
581
+ observed.add(child);
582
+ }
583
+ }
584
+ for (const child of observed) {
585
+ if (child.parentElement !== element) {
586
+ resizeObserver.unobserve(child);
587
+ observed.delete(child);
588
+ }
589
+ }
590
+ };
591
+ syncChildren();
592
+ const mutationObserver = new MutationObserver(() => {
593
+ syncChildren();
594
+ bump();
595
+ });
596
+ mutationObserver.observe(element, { childList: true });
597
+ return () => {
598
+ mutationObserver.disconnect();
599
+ resizeObserver.disconnect();
600
+ observed.clear();
601
+ };
602
+ }, [element]);
603
+ return signal;
604
+ }
605
+
543
606
  // src/hooks/use-grid-tracks.ts
544
607
  var EMPTY = {
545
608
  columns: [],
@@ -551,12 +614,13 @@ var EMPTY = {
551
614
  };
552
615
  var DEVICE_MODE_CHANGE_EVENT = "elementor/device-mode/change";
553
616
  function useGridTracks(element, rect) {
554
- const [tracks, setTracks] = useState3(EMPTY);
617
+ const [tracks, setTracks] = useState4(EMPTY);
555
618
  const trigger = useListenTo(
556
619
  [windowEvent(ELEMENT_STYLE_CHANGE_EVENT), windowEvent(DEVICE_MODE_CHANGE_EVENT)],
557
620
  () => ({})
558
621
  );
559
- useEffect4(() => {
622
+ const childrenTrigger = useGridChildren(element);
623
+ useEffect5(() => {
560
624
  const previewWindow = element?.ownerDocument?.defaultView;
561
625
  if (!element || !previewWindow) {
562
626
  setTracks(EMPTY);
@@ -568,7 +632,7 @@ function useGridTracks(element, rect) {
568
632
  return () => {
569
633
  previewWindow.cancelAnimationFrame(frame);
570
634
  };
571
- }, [element, rect.width, rect.height, trigger]);
635
+ }, [element, rect.width, rect.height, trigger, childrenTrigger]);
572
636
  return tracks;
573
637
  }
574
638
 
@@ -578,9 +642,9 @@ import { Box, styled } from "@elementor/ui";
578
642
  import { FloatingPortal, useHover, useInteractions } from "@floating-ui/react";
579
643
 
580
644
  // src/hooks/use-bind-react-props-to-element.ts
581
- import { useEffect as useEffect5 } from "react";
645
+ import { useEffect as useEffect6 } from "react";
582
646
  function useBindReactPropsToElement(element, getProps) {
583
- useEffect5(() => {
647
+ useEffect6(() => {
584
648
  const el = element;
585
649
  const { events, attrs } = groupProps(getProps());
586
650
  events.forEach(([eventName, listener]) => el.addEventListener(eventName, listener));
@@ -661,13 +725,12 @@ var OutlineOverlay = ({ element, isSelected, id, isGlobal = false }) => {
661
725
  };
662
726
 
663
727
  // src/components/grid-outline/grid-outline.tsx
664
- import * as React3 from "react";
728
+ import * as React4 from "react";
665
729
 
666
- // src/components/grid-outline/grid-outline-cell.tsx
730
+ // src/components/grid-outline/cell.tsx
667
731
  import * as React2 from "react";
668
732
  var FALLBACK_COLOR = "rgba(0, 0, 0, 0.12)";
669
- var DASH = "2 2";
670
- function GridOutlineCell({ x, y, width, height, color }) {
733
+ function Cell({ x, y, width, height, color }) {
671
734
  return /* @__PURE__ */ React2.createElement(
672
735
  "rect",
673
736
  {
@@ -678,16 +741,73 @@ function GridOutlineCell({ x, y, width, height, color }) {
678
741
  fill: "none",
679
742
  stroke: color || FALLBACK_COLOR,
680
743
  strokeWidth: 1,
681
- strokeDasharray: DASH,
744
+ strokeDasharray: "2 2",
745
+ vectorEffect: "non-scaling-stroke"
746
+ }
747
+ );
748
+ }
749
+
750
+ // src/components/grid-outline/line.tsx
751
+ import * as React3 from "react";
752
+ var FALLBACK_COLOR2 = "rgba(0, 0, 0, 0.12)";
753
+ function Line({ x1, y1, x2, y2, color }) {
754
+ return /* @__PURE__ */ React3.createElement(
755
+ "line",
756
+ {
757
+ x1,
758
+ y1,
759
+ x2,
760
+ y2,
761
+ stroke: color || FALLBACK_COLOR2,
762
+ strokeWidth: 1,
763
+ strokeDasharray: "2 2",
682
764
  vectorEffect: "non-scaling-stroke"
683
765
  }
684
766
  );
685
767
  }
686
768
 
687
769
  // src/components/grid-outline/grid-outline.tsx
770
+ var renderCells = (tracks, width, height) => computeCellRects(tracks, width, height).map((cell, i) => /* @__PURE__ */ React4.createElement(
771
+ Cell,
772
+ {
773
+ key: i,
774
+ x: snapToHalfPixel(cell.x),
775
+ y: snapToHalfPixel(cell.y),
776
+ width: Math.round(cell.width),
777
+ height: Math.round(cell.height),
778
+ color: tracks.borderColor
779
+ }
780
+ ));
781
+ var renderLines = (tracks, width, height) => {
782
+ const { vertical, horizontal } = computeGridLines(tracks, width, height);
783
+ return [
784
+ ...vertical.map((line, i) => /* @__PURE__ */ React4.createElement(
785
+ Line,
786
+ {
787
+ key: `v${i}`,
788
+ x1: snapToHalfPixel(line.x1),
789
+ y1: Math.round(line.y1),
790
+ x2: snapToHalfPixel(line.x2),
791
+ y2: Math.round(line.y2),
792
+ color: tracks.borderColor
793
+ }
794
+ )),
795
+ ...horizontal.map((line, i) => /* @__PURE__ */ React4.createElement(
796
+ Line,
797
+ {
798
+ key: `h${i}`,
799
+ x1: Math.round(line.x1),
800
+ y1: snapToHalfPixel(line.y1),
801
+ x2: Math.round(line.x2),
802
+ y2: snapToHalfPixel(line.y2),
803
+ color: tracks.borderColor
804
+ }
805
+ ))
806
+ ];
807
+ };
688
808
  function GridOutline({ tracks, width, height }) {
689
- const cells = computeCellRects(tracks, width, height);
690
- return /* @__PURE__ */ React3.createElement(
809
+ const hasGap = tracks.columnGap > 0 || tracks.rowGap > 0;
810
+ return /* @__PURE__ */ React4.createElement(
691
811
  "svg",
692
812
  {
693
813
  width,
@@ -695,17 +815,7 @@ function GridOutline({ tracks, width, height }) {
695
815
  style: { position: "absolute", inset: 0, overflow: "visible" },
696
816
  xmlns: "http://www.w3.org/2000/svg"
697
817
  },
698
- cells.map((cell, i) => /* @__PURE__ */ React3.createElement(
699
- GridOutlineCell,
700
- {
701
- key: i,
702
- x: snapToHalfPixel(cell.x),
703
- y: snapToHalfPixel(cell.y),
704
- width: Math.round(cell.width),
705
- height: Math.round(cell.height),
706
- color: tracks.borderColor
707
- }
708
- ))
818
+ hasGap ? renderCells(tracks, width, height) : renderLines(tracks, width, height)
709
819
  );
710
820
  }
711
821
 
@@ -722,7 +832,7 @@ var GridOutlineOverlay = ({ element, id, isSelected }) => {
722
832
  if (tracks.columns.length === 0 && tracks.rows.length === 0) {
723
833
  return null;
724
834
  }
725
- return /* @__PURE__ */ React4.createElement(FloatingPortal2, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React4.createElement(
835
+ return /* @__PURE__ */ React5.createElement(FloatingPortal2, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
726
836
  Box2,
727
837
  {
728
838
  ref: floating.setRef,
@@ -730,7 +840,7 @@ var GridOutlineOverlay = ({ element, id, isSelected }) => {
730
840
  "data-grid-outline": id,
731
841
  role: "presentation"
732
842
  },
733
- /* @__PURE__ */ React4.createElement(GridOutline, { tracks, width: rect.width, height: rect.height })
843
+ /* @__PURE__ */ React5.createElement(GridOutline, { tracks, width: rect.width, height: rect.height })
734
844
  ));
735
845
  };
736
846
 
@@ -759,7 +869,7 @@ function ElementsOverlays() {
759
869
  return elements.map(({ id, domElement, isGlobal }) => {
760
870
  const isSelected = selected.element?.id === id;
761
871
  return overlayRegistry.map(
762
- ({ shouldRender, component: Overlay }, index) => shouldRender({ id, element: domElement, isSelected }) && /* @__PURE__ */ React5.createElement(
872
+ ({ shouldRender, component: Overlay }, index) => shouldRender({ id, element: domElement, isSelected }) && /* @__PURE__ */ React6.createElement(
763
873
  Overlay,
764
874
  {
765
875
  key: `${id}-${index}`,
@@ -792,7 +902,7 @@ function isV4Element(dataset) {
792
902
  }
793
903
 
794
904
  // src/components/interactions-renderer.tsx
795
- import * as React6 from "react";
905
+ import * as React7 from "react";
796
906
  import {
797
907
  __privateUseListenTo as useListenTo3,
798
908
  commandEndEvent,
@@ -801,15 +911,15 @@ import {
801
911
  import { Portal } from "@elementor/ui";
802
912
 
803
913
  // src/hooks/use-interactions-items.ts
804
- import { useEffect as useEffect7, useMemo, useState as useState4 } from "react";
914
+ import { useEffect as useEffect8, useMemo, useState as useState5 } from "react";
805
915
  import { interactionsRepository } from "@elementor/editor-interactions";
806
916
  import { registerDataHook } from "@elementor/editor-v1-adapters";
807
917
 
808
918
  // src/hooks/use-on-mount.ts
809
- import { useEffect as useEffect6, useRef } from "react";
919
+ import { useEffect as useEffect7, useRef } from "react";
810
920
  function useOnMount(cb) {
811
921
  const mounted = useRef(false);
812
- useEffect6(() => {
922
+ useEffect7(() => {
813
923
  if (!mounted.current) {
814
924
  mounted.current = true;
815
925
  cb();
@@ -819,7 +929,7 @@ function useOnMount(cb) {
819
929
 
820
930
  // src/hooks/use-interactions-items.ts
821
931
  function useInteractionsItems() {
822
- const [interactionItems, setInteractionItems] = useState4({});
932
+ const [interactionItems, setInteractionItems] = useState5({});
823
933
  const providerAndSubscribers = useMemo(() => {
824
934
  try {
825
935
  const providers = interactionsRepository.getProviders();
@@ -837,7 +947,7 @@ function useInteractionsItems() {
837
947
  return [];
838
948
  }
839
949
  }, []);
840
- useEffect7(() => {
950
+ useEffect8(() => {
841
951
  if (providerAndSubscribers.length === 0) {
842
952
  return;
843
953
  }
@@ -898,7 +1008,7 @@ function InteractionsRenderer() {
898
1008
  return null;
899
1009
  }
900
1010
  const interactionsData = JSON.stringify(Array.isArray(interactionItems) ? interactionItems : []);
901
- return /* @__PURE__ */ React6.createElement(Portal, { container }, /* @__PURE__ */ React6.createElement(
1011
+ return /* @__PURE__ */ React7.createElement(Portal, { container }, /* @__PURE__ */ React7.createElement(
902
1012
  "script",
903
1013
  {
904
1014
  type: "application/json",
@@ -914,7 +1024,7 @@ function usePortalContainer() {
914
1024
  }
915
1025
 
916
1026
  // src/components/style-renderer.tsx
917
- import * as React7 from "react";
1027
+ import * as React8 from "react";
918
1028
  import {
919
1029
  __privateUseListenTo as useListenTo5,
920
1030
  commandEndEvent as commandEndEvent3,
@@ -974,7 +1084,7 @@ function getLinkAttrs(el) {
974
1084
  }
975
1085
 
976
1086
  // src/hooks/use-style-items.ts
977
- import { useEffect as useEffect8, useMemo as useMemo4, useRef as useRef2, useState as useState5 } from "react";
1087
+ import { useEffect as useEffect9, useMemo as useMemo4, useRef as useRef2, useState as useState6 } from "react";
978
1088
  import { useBreakpoints } from "@elementor/editor-responsive";
979
1089
  import { isClassState } from "@elementor/editor-styles";
980
1090
  import { stylesRepository as stylesRepository2 } from "@elementor/editor-styles-repository";
@@ -1306,7 +1416,7 @@ function useStyleItems() {
1306
1416
  const resolve = useStylePropResolver();
1307
1417
  const renderStyles = useStyleRenderer(resolve);
1308
1418
  const breakpoints = useBreakpoints();
1309
- const [styleItems, setStyleItems] = useState5({});
1419
+ const [styleItems, setStyleItems] = useState6({});
1310
1420
  const styleItemsCacheRef = useRef2(/* @__PURE__ */ new Map());
1311
1421
  const providerAndSubscribers = useMemo4(() => {
1312
1422
  const createEmptyCache = () => {
@@ -1334,7 +1444,7 @@ function useStyleItems() {
1334
1444
  })
1335
1445
  );
1336
1446
  }, [renderStyles]);
1337
- useEffect8(() => {
1447
+ useEffect9(() => {
1338
1448
  const unsubscribes = providerAndSubscribers.map(
1339
1449
  ({ provider, subscriber }) => provider.subscribe(subscriber)
1340
1450
  );
@@ -1495,7 +1605,7 @@ function StyleRenderer() {
1495
1605
  if (!container) {
1496
1606
  return null;
1497
1607
  }
1498
- return /* @__PURE__ */ React7.createElement(Portal2, { container }, filterUniqueStyleDefinitions(styleItems).map((item) => /* @__PURE__ */ React7.createElement("style", { key: `${item.id}-${item.breakpoint}-${item.state ?? "normal"}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React7.createElement("link", { ...attrs, key: attrs.id })));
1608
+ return /* @__PURE__ */ React8.createElement(Portal2, { container }, filterUniqueStyleDefinitions(styleItems).map((item) => /* @__PURE__ */ React8.createElement("style", { key: `${item.id}-${item.breakpoint}-${item.state ?? "normal"}` }, item.value)), linksAttrs.map((attrs) => /* @__PURE__ */ React8.createElement("link", { ...attrs, key: attrs.id })));
1499
1609
  }
1500
1610
  function usePortalContainer2() {
1501
1611
  return useListenTo5(commandEndEvent3("editor/documents/attach-preview"), () => getCanvasIframeDocument4()?.head);
@@ -2968,7 +3078,7 @@ function createPromotionView(BaseView) {
2968
3078
  import { createRoot } from "react-dom/client";
2969
3079
 
2970
3080
  // src/legacy/replacements/inline-editing/inline-editing-elements.tsx
2971
- import * as React9 from "react";
3081
+ import * as React10 from "react";
2972
3082
  import { getContainer as getContainer2, getElementLabel, getElementType as getElementType2 } from "@elementor/editor-elements";
2973
3083
  import {
2974
3084
  htmlV3PropTypeUtil as htmlV3PropTypeUtil2,
@@ -3021,14 +3131,14 @@ var ReplacementBase = class {
3021
3131
  };
3022
3132
 
3023
3133
  // src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
3024
- import * as React8 from "react";
3025
- import { useCallback as useCallback2, useEffect as useEffect10, useLayoutEffect, useState as useState7 } from "react";
3134
+ import * as React9 from "react";
3135
+ import { useCallback as useCallback2, useEffect as useEffect11, useLayoutEffect, useState as useState8 } from "react";
3026
3136
  import { InlineEditor, InlineEditorToolbar } from "@elementor/editor-controls";
3027
3137
  import { Box as Box3, ThemeProvider } from "@elementor/ui";
3028
3138
  import { autoUpdate as autoUpdate2, flip, FloatingPortal as FloatingPortal3, useFloating as useFloating2 } from "@floating-ui/react";
3029
3139
 
3030
3140
  // src/legacy/replacements/inline-editing/inline-editing-utils.ts
3031
- import { useCallback, useEffect as useEffect9, useState as useState6 } from "react";
3141
+ import { useCallback, useEffect as useEffect10, useState as useState7 } from "react";
3032
3142
  var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
3033
3143
  var NAVIGATOR_SELECTOR = "#elementor-navigator";
3034
3144
  var EDITING_PANEL = "#elementor-panel";
@@ -3060,7 +3170,7 @@ var getInlineEditorElement = (elementWrapper, expectedTag) => {
3060
3170
  };
3061
3171
  var useOnClickOutsideIframe = (handleUnmount) => {
3062
3172
  const asyncUnmountInlineEditor = useCallback(() => queueMicrotask(handleUnmount), [handleUnmount]);
3063
- useEffect9(() => {
3173
+ useEffect10(() => {
3064
3174
  EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
3065
3175
  (selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
3066
3176
  );
@@ -3070,8 +3180,8 @@ var useOnClickOutsideIframe = (handleUnmount) => {
3070
3180
  }, []);
3071
3181
  };
3072
3182
  var useRenderToolbar = (ownerDocument, id) => {
3073
- const [anchor, setAnchor] = useState6(null);
3074
- useEffect9(() => {
3183
+ const [anchor, setAnchor] = useState7(null);
3184
+ useEffect10(() => {
3075
3185
  if (!anchor) {
3076
3186
  removeToolbarAnchor(ownerDocument, id);
3077
3187
  }
@@ -3165,10 +3275,10 @@ var CanvasInlineEditor = ({
3165
3275
  setValue,
3166
3276
  requestDestroy
3167
3277
  }) => {
3168
- const [active, setActive] = useState7(true);
3169
- const [editor, setEditor] = useState7(null);
3278
+ const [active, setActive] = useState8(true);
3279
+ const [editor, setEditor] = useState8(null);
3170
3280
  const { onSelectionEnd, anchor: toolbarAnchor, clearAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
3171
- useEffect10(() => {
3281
+ useEffect11(() => {
3172
3282
  if (!active) {
3173
3283
  clearAnchor();
3174
3284
  requestDestroy();
@@ -3179,7 +3289,7 @@ var CanvasInlineEditor = ({
3179
3289
  setActive(false);
3180
3290
  }, []);
3181
3291
  useOnClickOutsideIframe(dismiss);
3182
- useEffect10(() => {
3292
+ useEffect11(() => {
3183
3293
  const ownerDocument = contentElement.ownerDocument;
3184
3294
  const handleClickAway = (event) => {
3185
3295
  if (contentElement.contains(event.target)) {
@@ -3193,7 +3303,7 @@ var CanvasInlineEditor = ({
3193
3303
  if (!active) {
3194
3304
  return null;
3195
3305
  }
3196
- return /* @__PURE__ */ React8.createElement(ThemeProvider, null, /* @__PURE__ */ React8.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React8.createElement(
3306
+ return /* @__PURE__ */ React9.createElement(ThemeProvider, null, /* @__PURE__ */ React9.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React9.createElement(
3197
3307
  InlineEditor,
3198
3308
  {
3199
3309
  onEditorCreate: setEditor,
@@ -3210,7 +3320,7 @@ var CanvasInlineEditor = ({
3210
3320
  autofocus: true,
3211
3321
  onSelectionEnd
3212
3322
  }
3213
- ), toolbarAnchor && editor && /* @__PURE__ */ React8.createElement(InlineEditingToolbar, { anchor: toolbarAnchor, editor, id }));
3323
+ ), toolbarAnchor && editor && /* @__PURE__ */ React9.createElement(InlineEditingToolbar, { anchor: toolbarAnchor, editor, id }));
3214
3324
  };
3215
3325
  var InlineEditingOverlay = ({
3216
3326
  expectedTag,
@@ -3218,11 +3328,11 @@ var InlineEditingOverlay = ({
3218
3328
  id
3219
3329
  }) => {
3220
3330
  const inlineEditedElement = getInlineEditorElement(rootElement, expectedTag);
3221
- const [overlayRefElement, setOverlayElement] = useState7(inlineEditedElement);
3222
- useEffect10(() => {
3331
+ const [overlayRefElement, setOverlayElement] = useState8(inlineEditedElement);
3332
+ useEffect11(() => {
3223
3333
  setOverlayElement(getInlineEditorElement(rootElement, expectedTag));
3224
3334
  }, [expectedTag, rootElement]);
3225
- return overlayRefElement ? /* @__PURE__ */ React8.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
3335
+ return overlayRefElement ? /* @__PURE__ */ React9.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
3226
3336
  };
3227
3337
  var InlineEditingToolbar = ({ anchor, editor, id }) => {
3228
3338
  const { refs, floatingStyles } = useFloating2({
@@ -3236,7 +3346,7 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
3236
3346
  refs.setReference(anchor);
3237
3347
  return () => refs.setReference(null);
3238
3348
  }, [anchor, refs]);
3239
- return /* @__PURE__ */ React8.createElement(FloatingPortal3, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React8.createElement(
3349
+ return /* @__PURE__ */ React9.createElement(FloatingPortal3, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React9.createElement(
3240
3350
  Box3,
3241
3351
  {
3242
3352
  ref: refs.setFloating,
@@ -3246,7 +3356,7 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
3246
3356
  pointerEvents: "none"
3247
3357
  }
3248
3358
  },
3249
- /* @__PURE__ */ React8.createElement(InlineEditorToolbar, { editor, elementId: id })
3359
+ /* @__PURE__ */ React9.createElement(InlineEditorToolbar, { editor, elementId: id })
3250
3360
  ));
3251
3361
  };
3252
3362
 
@@ -3455,7 +3565,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
3455
3565
  contentElement.innerHTML = "";
3456
3566
  this.editing = true;
3457
3567
  this.reactRoot.render(
3458
- /* @__PURE__ */ React9.createElement(
3568
+ /* @__PURE__ */ React10.createElement(
3459
3569
  CanvasInlineEditor,
3460
3570
  {
3461
3571
  elementClasses,
@@ -4149,7 +4259,7 @@ function getElementDisplayName(container) {
4149
4259
  // src/mcp/tools/build-composition/tool.ts
4150
4260
  import { getCurrentDocument } from "@elementor/editor-documents";
4151
4261
  import {
4152
- createElement as createElement11,
4262
+ createElement as createElement12,
4153
4263
  deleteElement as deleteElement2,
4154
4264
  getContainer as getContainer5,
4155
4265
  getWidgetsCache as getWidgetsCache9
@@ -4157,7 +4267,7 @@ import {
4157
4267
 
4158
4268
  // src/composition-builder/composition-builder.ts
4159
4269
  import {
4160
- createElement as createElement10,
4270
+ createElement as createElement11,
4161
4271
  deleteElement,
4162
4272
  generateElementId as generateElementId2,
4163
4273
  getContainer as getContainer4,
@@ -4428,7 +4538,7 @@ var CompositionBuilder = class _CompositionBuilder {
4428
4538
  elementCustomCSS = {};
4429
4539
  rootContainers = [];
4430
4540
  api = {
4431
- createElement: createElement10,
4541
+ createElement: createElement11,
4432
4542
  deleteElement,
4433
4543
  getWidgetsCache: getWidgetsCache8,
4434
4544
  generateElementId: generateElementId2,
@@ -4955,7 +5065,7 @@ var initBuildCompositionsTool = (reg) => {
4955
5065
  const targetContainer = getCompositionTargetContainer(documentContainer, currentDocument?.type.value);
4956
5066
  try {
4957
5067
  const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
4958
- createElement: createElement11,
5068
+ createElement: createElement12,
4959
5069
  deleteElement: deleteElement2,
4960
5070
  getWidgetsCache: getWidgetsCache9
4961
5071
  });
@@ -5991,7 +6101,7 @@ var getLegacyPanelElementView = ({ settings, ...rest }) => {
5991
6101
  var GLOBAL_STYLES_IMPORTED_EVENT = "elementor/global-styles/imported";
5992
6102
 
5993
6103
  // src/components/spotlight-backdrop.tsx
5994
- import * as React10 from "react";
6104
+ import * as React11 from "react";
5995
6105
  function SpotlightBackdrop({ canvas, element, onExit, ariaLabel }) {
5996
6106
  const rect = useElementRect(element);
5997
6107
  const clipPath = element ? getRectClipPath(rect, canvas.defaultView) : void 0;
@@ -6013,7 +6123,7 @@ function SpotlightBackdrop({ canvas, element, onExit, ariaLabel }) {
6013
6123
  onExit();
6014
6124
  }
6015
6125
  };
6016
- return /* @__PURE__ */ React10.createElement(
6126
+ return /* @__PURE__ */ React11.createElement(
6017
6127
  "div",
6018
6128
  {
6019
6129
  style: backdropStyle,
@@ -6042,9 +6152,9 @@ function useCanvasDocument() {
6042
6152
  }
6043
6153
 
6044
6154
  // src/hooks/use-escape-on-canvas.ts
6045
- import { useEffect as useEffect11 } from "react";
6155
+ import { useEffect as useEffect12 } from "react";
6046
6156
  function useEscapeOnCanvas(canvasDocument, onEscape) {
6047
- useEffect11(() => {
6157
+ useEffect12(() => {
6048
6158
  if (!canvasDocument) {
6049
6159
  return;
6050
6160
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-canvas",
3
3
  "description": "Elementor Editor Canvas",
4
- "version": "4.2.0-913",
4
+ "version": "4.2.0-915",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -37,25 +37,25 @@
37
37
  "react-dom": "^18.3.1"
38
38
  },
39
39
  "dependencies": {
40
- "@elementor/editor": "4.2.0-913",
40
+ "@elementor/editor": "4.2.0-915",
41
41
  "dompurify": "^3.2.6",
42
- "@elementor/editor-controls": "4.2.0-913",
43
- "@elementor/editor-documents": "4.2.0-913",
44
- "@elementor/editor-elements": "4.2.0-913",
45
- "@elementor/editor-interactions": "4.2.0-913",
46
- "@elementor/editor-mcp": "4.2.0-913",
47
- "@elementor/editor-notifications": "4.2.0-913",
48
- "@elementor/editor-props": "4.2.0-913",
49
- "@elementor/editor-responsive": "4.2.0-913",
50
- "@elementor/editor-styles": "4.2.0-913",
51
- "@elementor/editor-styles-repository": "4.2.0-913",
52
- "@elementor/editor-ui": "4.2.0-913",
53
- "@elementor/editor-v1-adapters": "4.2.0-913",
54
- "@elementor/schema": "4.2.0-913",
55
- "@elementor/twing": "4.2.0-913",
42
+ "@elementor/editor-controls": "4.2.0-915",
43
+ "@elementor/editor-documents": "4.2.0-915",
44
+ "@elementor/editor-elements": "4.2.0-915",
45
+ "@elementor/editor-interactions": "4.2.0-915",
46
+ "@elementor/editor-mcp": "4.2.0-915",
47
+ "@elementor/editor-notifications": "4.2.0-915",
48
+ "@elementor/editor-props": "4.2.0-915",
49
+ "@elementor/editor-responsive": "4.2.0-915",
50
+ "@elementor/editor-styles": "4.2.0-915",
51
+ "@elementor/editor-styles-repository": "4.2.0-915",
52
+ "@elementor/editor-ui": "4.2.0-915",
53
+ "@elementor/editor-v1-adapters": "4.2.0-915",
54
+ "@elementor/schema": "4.2.0-915",
55
+ "@elementor/twing": "4.2.0-915",
56
56
  "@elementor/ui": "1.37.5",
57
- "@elementor/utils": "4.2.0-913",
58
- "@elementor/wp-media": "4.2.0-913",
57
+ "@elementor/utils": "4.2.0-915",
58
+ "@elementor/wp-media": "4.2.0-915",
59
59
  "@floating-ui/react": "^0.27.5",
60
60
  "@wordpress/i18n": "^5.13.0"
61
61
  },
@@ -122,7 +122,7 @@ describe( '<GridOutlineOverlay />', () => {
122
122
  expect( screen.queryByRole( 'presentation' ) ).not.toBeInTheDocument();
123
123
  } );
124
124
 
125
- it( 'renders one <rect> per grid cell', () => {
125
+ it( 'renders one rect per cell when the grid has a gap', () => {
126
126
  mockGridOutlineSetting( null );
127
127
  jest.mocked( useGridTracks ).mockReturnValue( {
128
128
  ...NON_EMPTY_TRACKS,
@@ -139,6 +139,23 @@ describe( '<GridOutlineOverlay />', () => {
139
139
  expect( overlay.querySelectorAll( 'rect' ) ).toHaveLength( 3 * 2 );
140
140
  } );
141
141
 
142
+ it( 'renders boundary lines when the grid has no gap', () => {
143
+ mockGridOutlineSetting( null );
144
+ jest.mocked( useGridTracks ).mockReturnValue( {
145
+ ...NON_EMPTY_TRACKS,
146
+ columns: [ 100, 100, 100 ],
147
+ rows: [ 80, 80 ],
148
+ columnGap: 0,
149
+ rowGap: 0,
150
+ } );
151
+
152
+ renderOverlay();
153
+
154
+ const overlay = screen.getByRole( 'presentation' );
155
+ // eslint-disable-next-line testing-library/no-node-access
156
+ expect( overlay.querySelectorAll( 'line' ).length ).toBeGreaterThan( 0 );
157
+ } );
158
+
142
159
  it( 'mounts inside the canvas wrapper portal', () => {
143
160
  mockGridOutlineSetting( null );
144
161