@elementor/editor-canvas 4.3.0-951 → 4.3.0-953
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 +240 -191
- package/dist/index.mjs +211 -162
- package/package.json +20 -20
- package/src/components/elements-overlays.tsx +10 -2
- package/src/components/grid-outline/grid-empty-cell-positioner.tsx +46 -0
- package/src/components/grid-outline/grid-outline.tsx +11 -1
- package/src/components/grid-outline/index.ts +1 -0
package/dist/index.mjs
CHANGED
|
@@ -384,12 +384,8 @@ import {
|
|
|
384
384
|
windowEvent as windowEvent2
|
|
385
385
|
} from "@elementor/editor-v1-adapters";
|
|
386
386
|
|
|
387
|
-
// src/components/grid-outline/grid-
|
|
388
|
-
import
|
|
389
|
-
import { useSelectedElementSettings } from "@elementor/editor-elements";
|
|
390
|
-
import { booleanPropTypeUtil } from "@elementor/editor-props";
|
|
391
|
-
import { Box as Box2 } from "@elementor/ui";
|
|
392
|
-
import { FloatingPortal as FloatingPortal2 } from "@floating-ui/react";
|
|
387
|
+
// src/components/grid-outline/grid-empty-cell-positioner.tsx
|
|
388
|
+
import { useEffect as useEffect5 } from "react";
|
|
393
389
|
|
|
394
390
|
// src/hooks/use-element-rect.ts
|
|
395
391
|
import { useEffect as useEffect2, useState } from "react";
|
|
@@ -454,49 +450,8 @@ function useMutationsListener({ element, onChange }) {
|
|
|
454
450
|
}, [element, onChange]);
|
|
455
451
|
}
|
|
456
452
|
|
|
457
|
-
// src/hooks/use-floating-on-element.ts
|
|
458
|
-
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
459
|
-
import { autoUpdate, offset, size, useFloating } from "@floating-ui/react";
|
|
460
|
-
function useFloatingOnElement({ element, isSelected }) {
|
|
461
|
-
const [isOpen, setIsOpen] = useState2(false);
|
|
462
|
-
const sizeModifier = 2;
|
|
463
|
-
const { refs, floatingStyles, context } = useFloating({
|
|
464
|
-
// Must be controlled for interactions (like hover) to work.
|
|
465
|
-
open: isOpen || isSelected,
|
|
466
|
-
onOpenChange: setIsOpen,
|
|
467
|
-
whileElementsMounted: autoUpdate,
|
|
468
|
-
middleware: [
|
|
469
|
-
// Match the floating element's size to the reference element.
|
|
470
|
-
size(() => {
|
|
471
|
-
return {
|
|
472
|
-
apply({ elements, rects }) {
|
|
473
|
-
Object.assign(elements.floating.style, {
|
|
474
|
-
width: `${rects.reference.width + sizeModifier}px`,
|
|
475
|
-
height: `${rects.reference.height + sizeModifier}px`
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
};
|
|
479
|
-
}),
|
|
480
|
-
// Center the floating element on the reference element.
|
|
481
|
-
offset(({ rects }) => -rects.reference.height / 2 - rects.floating.height / 2)
|
|
482
|
-
]
|
|
483
|
-
});
|
|
484
|
-
useEffect3(() => {
|
|
485
|
-
refs.setReference(element);
|
|
486
|
-
}, [element, refs]);
|
|
487
|
-
return {
|
|
488
|
-
isVisible: isOpen || isSelected,
|
|
489
|
-
context,
|
|
490
|
-
floating: {
|
|
491
|
-
setRef: refs.setFloating,
|
|
492
|
-
ref: refs.floating,
|
|
493
|
-
styles: floatingStyles
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
|
-
|
|
498
453
|
// src/hooks/use-grid-tracks.ts
|
|
499
|
-
import { useEffect as
|
|
454
|
+
import { useEffect as useEffect4, useState as useState3 } from "react";
|
|
500
455
|
import { ELEMENT_STYLE_CHANGE_EVENT } from "@elementor/editor-elements";
|
|
501
456
|
import { __privateUseListenTo as useListenTo, windowEvent } from "@elementor/editor-v1-adapters";
|
|
502
457
|
|
|
@@ -583,10 +538,10 @@ function toPx(value) {
|
|
|
583
538
|
}
|
|
584
539
|
|
|
585
540
|
// src/hooks/use-grid-children.ts
|
|
586
|
-
import { useEffect as
|
|
541
|
+
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
587
542
|
function useGridChildren(element) {
|
|
588
|
-
const [signal, setSignal] =
|
|
589
|
-
|
|
543
|
+
const [signal, setSignal] = useState2(0);
|
|
544
|
+
useEffect3(() => {
|
|
590
545
|
if (!element) {
|
|
591
546
|
return;
|
|
592
547
|
}
|
|
@@ -633,13 +588,13 @@ var EMPTY = {
|
|
|
633
588
|
};
|
|
634
589
|
var DEVICE_MODE_CHANGE_EVENT = "elementor/device-mode/change";
|
|
635
590
|
function useGridTracks(element, rect) {
|
|
636
|
-
const [tracks, setTracks] =
|
|
591
|
+
const [tracks, setTracks] = useState3(EMPTY);
|
|
637
592
|
const trigger = useListenTo(
|
|
638
593
|
[windowEvent(ELEMENT_STYLE_CHANGE_EVENT), windowEvent(DEVICE_MODE_CHANGE_EVENT)],
|
|
639
594
|
() => ({})
|
|
640
595
|
);
|
|
641
596
|
const childrenTrigger = useGridChildren(element);
|
|
642
|
-
|
|
597
|
+
useEffect4(() => {
|
|
643
598
|
const previewWindow = element?.ownerDocument?.defaultView;
|
|
644
599
|
if (!element || !previewWindow) {
|
|
645
600
|
setTracks(EMPTY);
|
|
@@ -655,98 +610,6 @@ function useGridTracks(element, rect) {
|
|
|
655
610
|
return tracks;
|
|
656
611
|
}
|
|
657
612
|
|
|
658
|
-
// src/components/outline-overlay.tsx
|
|
659
|
-
import * as React from "react";
|
|
660
|
-
import { Box, styled } from "@elementor/ui";
|
|
661
|
-
import { FloatingPortal, useHover, useInteractions } from "@floating-ui/react";
|
|
662
|
-
|
|
663
|
-
// src/hooks/use-bind-react-props-to-element.ts
|
|
664
|
-
import { useEffect as useEffect6 } from "react";
|
|
665
|
-
function useBindReactPropsToElement(element, getProps) {
|
|
666
|
-
useEffect6(() => {
|
|
667
|
-
const el = element;
|
|
668
|
-
const { events, attrs } = groupProps(getProps());
|
|
669
|
-
events.forEach(([eventName, listener]) => el.addEventListener(eventName, listener));
|
|
670
|
-
attrs.forEach(([attrName, attrValue]) => el.setAttribute(attrName, attrValue));
|
|
671
|
-
return () => {
|
|
672
|
-
events.forEach(([eventName, listener]) => el.removeEventListener(eventName, listener));
|
|
673
|
-
attrs.forEach(([attrName]) => el.removeAttribute(attrName));
|
|
674
|
-
};
|
|
675
|
-
}, [getProps, element]);
|
|
676
|
-
}
|
|
677
|
-
function groupProps(props) {
|
|
678
|
-
const eventRegex = /^on(?=[A-Z])/;
|
|
679
|
-
return Object.entries(props).reduce(
|
|
680
|
-
(acc, [propName, propValue]) => {
|
|
681
|
-
if (!eventRegex.test(propName)) {
|
|
682
|
-
acc.attrs.push([propName, propValue]);
|
|
683
|
-
return acc;
|
|
684
|
-
}
|
|
685
|
-
const eventName = propName.replace(eventRegex, "").toLowerCase();
|
|
686
|
-
const listener = propValue;
|
|
687
|
-
acc.events.push([eventName, listener]);
|
|
688
|
-
return acc;
|
|
689
|
-
},
|
|
690
|
-
{
|
|
691
|
-
events: [],
|
|
692
|
-
attrs: []
|
|
693
|
-
}
|
|
694
|
-
);
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
// src/hooks/use-has-overlapping.ts
|
|
698
|
-
var possibleOverlappingSelectors = [".e-off-canvas"];
|
|
699
|
-
var useHasOverlapping = () => {
|
|
700
|
-
const preview = window.elementor?.$preview?.[0];
|
|
701
|
-
if (!preview) {
|
|
702
|
-
return false;
|
|
703
|
-
}
|
|
704
|
-
const hasOverlapping = possibleOverlappingSelectors.map((selector) => Array.from(preview?.contentWindow?.document.body.querySelectorAll(selector) ?? [])).flat().some(
|
|
705
|
-
(elem) => elem.checkVisibility({
|
|
706
|
-
opacityProperty: true,
|
|
707
|
-
visibilityProperty: true,
|
|
708
|
-
contentVisibilityAuto: true
|
|
709
|
-
})
|
|
710
|
-
);
|
|
711
|
-
return hasOverlapping;
|
|
712
|
-
};
|
|
713
|
-
|
|
714
|
-
// src/components/outline-overlay.tsx
|
|
715
|
-
var CANVAS_WRAPPER_ID = "elementor-preview-responsive-wrapper";
|
|
716
|
-
var OverlayBox = styled(Box, {
|
|
717
|
-
shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isSmallerOffset" && prop !== "isGlobal"
|
|
718
|
-
})(
|
|
719
|
-
({ theme, isSelected, isSmallerOffset, isGlobal }) => ({
|
|
720
|
-
outline: `${isSelected ? "2px" : "1px"} solid ${isGlobal ? theme.palette.global.main : theme.palette.primary.light}`,
|
|
721
|
-
outlineOffset: isSelected && !isSmallerOffset ? "-2px" : "-1px",
|
|
722
|
-
pointerEvents: "none"
|
|
723
|
-
})
|
|
724
|
-
);
|
|
725
|
-
var OutlineOverlay = ({ element, isSelected, id, isGlobal = false }) => {
|
|
726
|
-
const { context, floating, isVisible } = useFloatingOnElement({ element, isSelected });
|
|
727
|
-
const { getFloatingProps, getReferenceProps } = useInteractions([useHover(context)]);
|
|
728
|
-
const hasOverlapping = useHasOverlapping();
|
|
729
|
-
useBindReactPropsToElement(element, getReferenceProps);
|
|
730
|
-
const isSmallerOffset = element.offsetHeight <= 1;
|
|
731
|
-
return isVisible && !hasOverlapping && /* @__PURE__ */ React.createElement(FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React.createElement(
|
|
732
|
-
OverlayBox,
|
|
733
|
-
{
|
|
734
|
-
ref: floating.setRef,
|
|
735
|
-
isSelected,
|
|
736
|
-
isGlobal,
|
|
737
|
-
style: floating.styles,
|
|
738
|
-
"data-element-overlay": id,
|
|
739
|
-
role: "presentation",
|
|
740
|
-
isSmallerOffset,
|
|
741
|
-
...getFloatingProps()
|
|
742
|
-
}
|
|
743
|
-
));
|
|
744
|
-
};
|
|
745
|
-
|
|
746
|
-
// src/components/grid-outline/grid-outline.tsx
|
|
747
|
-
import * as React5 from "react";
|
|
748
|
-
import { useMemo } from "react";
|
|
749
|
-
|
|
750
613
|
// src/utils/find-first-empty-cell.ts
|
|
751
614
|
function findFirstEmptyCell(element, columnCount, rowCount) {
|
|
752
615
|
if (!element || columnCount === 0 || rowCount === 0) {
|
|
@@ -909,6 +772,179 @@ function scanFirstEmpty(matrix, flowsByColumn) {
|
|
|
909
772
|
return null;
|
|
910
773
|
}
|
|
911
774
|
|
|
775
|
+
// src/components/grid-outline/grid-empty-cell-positioner.tsx
|
|
776
|
+
var CSS_VAR_ROW = "--e-grid-empty-cell-row";
|
|
777
|
+
var CSS_VAR_COL = "--e-grid-empty-cell-col";
|
|
778
|
+
var CSS_VAR_VISIBILITY = "--e-grid-empty-cell-visibility";
|
|
779
|
+
var clearGridEmptyCellStyles = (target) => {
|
|
780
|
+
target.style.removeProperty(CSS_VAR_ROW);
|
|
781
|
+
target.style.removeProperty(CSS_VAR_COL);
|
|
782
|
+
target.style.removeProperty(CSS_VAR_VISIBILITY);
|
|
783
|
+
};
|
|
784
|
+
var GridEmptyCellPositioner = ({ element }) => {
|
|
785
|
+
const rect = useElementRect(element);
|
|
786
|
+
const tracks = useGridTracks(element, rect);
|
|
787
|
+
useEffect5(() => {
|
|
788
|
+
if (!element) {
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const firstEmpty = findFirstEmptyCell(element, tracks.columns.length, tracks.rows.length);
|
|
792
|
+
if (!firstEmpty) {
|
|
793
|
+
element.style.removeProperty(CSS_VAR_ROW);
|
|
794
|
+
element.style.removeProperty(CSS_VAR_COL);
|
|
795
|
+
element.style.setProperty(CSS_VAR_VISIBILITY, "hidden");
|
|
796
|
+
return () => clearGridEmptyCellStyles(element);
|
|
797
|
+
}
|
|
798
|
+
element.style.setProperty(CSS_VAR_ROW, String(firstEmpty.row + 1));
|
|
799
|
+
element.style.setProperty(CSS_VAR_COL, String(firstEmpty.col + 1));
|
|
800
|
+
element.style.setProperty(CSS_VAR_VISIBILITY, "visible");
|
|
801
|
+
return () => {
|
|
802
|
+
clearGridEmptyCellStyles(element);
|
|
803
|
+
};
|
|
804
|
+
}, [element, tracks]);
|
|
805
|
+
return null;
|
|
806
|
+
};
|
|
807
|
+
|
|
808
|
+
// src/components/grid-outline/grid-outline-overlay.tsx
|
|
809
|
+
import * as React6 from "react";
|
|
810
|
+
import { useSelectedElementSettings } from "@elementor/editor-elements";
|
|
811
|
+
import { booleanPropTypeUtil } from "@elementor/editor-props";
|
|
812
|
+
import { Box as Box2 } from "@elementor/ui";
|
|
813
|
+
import { FloatingPortal as FloatingPortal2 } from "@floating-ui/react";
|
|
814
|
+
|
|
815
|
+
// src/hooks/use-floating-on-element.ts
|
|
816
|
+
import { useEffect as useEffect6, useState as useState4 } from "react";
|
|
817
|
+
import { autoUpdate, offset, size, useFloating } from "@floating-ui/react";
|
|
818
|
+
function useFloatingOnElement({ element, isSelected }) {
|
|
819
|
+
const [isOpen, setIsOpen] = useState4(false);
|
|
820
|
+
const sizeModifier = 2;
|
|
821
|
+
const { refs, floatingStyles, context } = useFloating({
|
|
822
|
+
// Must be controlled for interactions (like hover) to work.
|
|
823
|
+
open: isOpen || isSelected,
|
|
824
|
+
onOpenChange: setIsOpen,
|
|
825
|
+
whileElementsMounted: autoUpdate,
|
|
826
|
+
middleware: [
|
|
827
|
+
// Match the floating element's size to the reference element.
|
|
828
|
+
size(() => {
|
|
829
|
+
return {
|
|
830
|
+
apply({ elements, rects }) {
|
|
831
|
+
Object.assign(elements.floating.style, {
|
|
832
|
+
width: `${rects.reference.width + sizeModifier}px`,
|
|
833
|
+
height: `${rects.reference.height + sizeModifier}px`
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
}),
|
|
838
|
+
// Center the floating element on the reference element.
|
|
839
|
+
offset(({ rects }) => -rects.reference.height / 2 - rects.floating.height / 2)
|
|
840
|
+
]
|
|
841
|
+
});
|
|
842
|
+
useEffect6(() => {
|
|
843
|
+
refs.setReference(element);
|
|
844
|
+
}, [element, refs]);
|
|
845
|
+
return {
|
|
846
|
+
isVisible: isOpen || isSelected,
|
|
847
|
+
context,
|
|
848
|
+
floating: {
|
|
849
|
+
setRef: refs.setFloating,
|
|
850
|
+
ref: refs.floating,
|
|
851
|
+
styles: floatingStyles
|
|
852
|
+
}
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// src/components/outline-overlay.tsx
|
|
857
|
+
import * as React from "react";
|
|
858
|
+
import { Box, styled } from "@elementor/ui";
|
|
859
|
+
import { FloatingPortal, useHover, useInteractions } from "@floating-ui/react";
|
|
860
|
+
|
|
861
|
+
// src/hooks/use-bind-react-props-to-element.ts
|
|
862
|
+
import { useEffect as useEffect7 } from "react";
|
|
863
|
+
function useBindReactPropsToElement(element, getProps) {
|
|
864
|
+
useEffect7(() => {
|
|
865
|
+
const el = element;
|
|
866
|
+
const { events, attrs } = groupProps(getProps());
|
|
867
|
+
events.forEach(([eventName, listener]) => el.addEventListener(eventName, listener));
|
|
868
|
+
attrs.forEach(([attrName, attrValue]) => el.setAttribute(attrName, attrValue));
|
|
869
|
+
return () => {
|
|
870
|
+
events.forEach(([eventName, listener]) => el.removeEventListener(eventName, listener));
|
|
871
|
+
attrs.forEach(([attrName]) => el.removeAttribute(attrName));
|
|
872
|
+
};
|
|
873
|
+
}, [getProps, element]);
|
|
874
|
+
}
|
|
875
|
+
function groupProps(props) {
|
|
876
|
+
const eventRegex = /^on(?=[A-Z])/;
|
|
877
|
+
return Object.entries(props).reduce(
|
|
878
|
+
(acc, [propName, propValue]) => {
|
|
879
|
+
if (!eventRegex.test(propName)) {
|
|
880
|
+
acc.attrs.push([propName, propValue]);
|
|
881
|
+
return acc;
|
|
882
|
+
}
|
|
883
|
+
const eventName = propName.replace(eventRegex, "").toLowerCase();
|
|
884
|
+
const listener = propValue;
|
|
885
|
+
acc.events.push([eventName, listener]);
|
|
886
|
+
return acc;
|
|
887
|
+
},
|
|
888
|
+
{
|
|
889
|
+
events: [],
|
|
890
|
+
attrs: []
|
|
891
|
+
}
|
|
892
|
+
);
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
// src/hooks/use-has-overlapping.ts
|
|
896
|
+
var possibleOverlappingSelectors = [".e-off-canvas"];
|
|
897
|
+
var useHasOverlapping = () => {
|
|
898
|
+
const preview = window.elementor?.$preview?.[0];
|
|
899
|
+
if (!preview) {
|
|
900
|
+
return false;
|
|
901
|
+
}
|
|
902
|
+
const hasOverlapping = possibleOverlappingSelectors.map((selector) => Array.from(preview?.contentWindow?.document.body.querySelectorAll(selector) ?? [])).flat().some(
|
|
903
|
+
(elem) => elem.checkVisibility({
|
|
904
|
+
opacityProperty: true,
|
|
905
|
+
visibilityProperty: true,
|
|
906
|
+
contentVisibilityAuto: true
|
|
907
|
+
})
|
|
908
|
+
);
|
|
909
|
+
return hasOverlapping;
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
// src/components/outline-overlay.tsx
|
|
913
|
+
var CANVAS_WRAPPER_ID = "elementor-preview-responsive-wrapper";
|
|
914
|
+
var OverlayBox = styled(Box, {
|
|
915
|
+
shouldForwardProp: (prop) => prop !== "isSelected" && prop !== "isSmallerOffset" && prop !== "isGlobal"
|
|
916
|
+
})(
|
|
917
|
+
({ theme, isSelected, isSmallerOffset, isGlobal }) => ({
|
|
918
|
+
outline: `${isSelected ? "2px" : "1px"} solid ${isGlobal ? theme.palette.global.main : theme.palette.primary.light}`,
|
|
919
|
+
outlineOffset: isSelected && !isSmallerOffset ? "-2px" : "-1px",
|
|
920
|
+
pointerEvents: "none"
|
|
921
|
+
})
|
|
922
|
+
);
|
|
923
|
+
var OutlineOverlay = ({ element, isSelected, id, isGlobal = false }) => {
|
|
924
|
+
const { context, floating, isVisible } = useFloatingOnElement({ element, isSelected });
|
|
925
|
+
const { getFloatingProps, getReferenceProps } = useInteractions([useHover(context)]);
|
|
926
|
+
const hasOverlapping = useHasOverlapping();
|
|
927
|
+
useBindReactPropsToElement(element, getReferenceProps);
|
|
928
|
+
const isSmallerOffset = element.offsetHeight <= 1;
|
|
929
|
+
return isVisible && !hasOverlapping && /* @__PURE__ */ React.createElement(FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React.createElement(
|
|
930
|
+
OverlayBox,
|
|
931
|
+
{
|
|
932
|
+
ref: floating.setRef,
|
|
933
|
+
isSelected,
|
|
934
|
+
isGlobal,
|
|
935
|
+
style: floating.styles,
|
|
936
|
+
"data-element-overlay": id,
|
|
937
|
+
role: "presentation",
|
|
938
|
+
isSmallerOffset,
|
|
939
|
+
...getFloatingProps()
|
|
940
|
+
}
|
|
941
|
+
));
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
// src/components/grid-outline/grid-outline.tsx
|
|
945
|
+
import * as React5 from "react";
|
|
946
|
+
import { useMemo } from "react";
|
|
947
|
+
|
|
912
948
|
// src/components/grid-outline/cell.tsx
|
|
913
949
|
import * as React2 from "react";
|
|
914
950
|
var FALLBACK_COLOR = "rgba(0, 0, 0, 0.12)";
|
|
@@ -1016,6 +1052,13 @@ var renderLines = (tracks, width, height) => {
|
|
|
1016
1052
|
))
|
|
1017
1053
|
];
|
|
1018
1054
|
};
|
|
1055
|
+
var isDragActiveFromDom = (element) => {
|
|
1056
|
+
return Boolean(
|
|
1057
|
+
element?.querySelector(
|
|
1058
|
+
".e-dragging-over, .elementor-dragging-on-child, .elementor-draggable-over, .elementor-widget-placeholder, .elementor-sortable-placeholder"
|
|
1059
|
+
)
|
|
1060
|
+
);
|
|
1061
|
+
};
|
|
1019
1062
|
function GridOutline({ element, tracks, width, height }) {
|
|
1020
1063
|
const cells = useMemo(() => computeCellRects(tracks, width, height), [tracks, width, height]);
|
|
1021
1064
|
const hasGap = tracks.columnGap > 0 || tracks.rowGap > 0;
|
|
@@ -1033,7 +1076,7 @@ function GridOutline({ element, tracks, width, height }) {
|
|
|
1033
1076
|
xmlns: "http://www.w3.org/2000/svg"
|
|
1034
1077
|
},
|
|
1035
1078
|
hasGap ? renderCells(cells, tracks.borderColor) : renderLines(tracks, width, height)
|
|
1036
|
-
), emptyCellRect && /* @__PURE__ */ React5.createElement(FirstEmptyCell, { rect: emptyCellRect, color: tracks.borderColor }));
|
|
1079
|
+
), emptyCellRect && !isDragActiveFromDom(element) && /* @__PURE__ */ React5.createElement(FirstEmptyCell, { rect: emptyCellRect, color: tracks.borderColor }));
|
|
1037
1080
|
}
|
|
1038
1081
|
|
|
1039
1082
|
// src/components/grid-outline/grid-outline-overlay.tsx
|
|
@@ -1063,14 +1106,20 @@ var GridOutlineOverlay = ({ element, id, isSelected }) => {
|
|
|
1063
1106
|
|
|
1064
1107
|
// src/components/elements-overlays.tsx
|
|
1065
1108
|
var ELEMENTS_DATA_ATTR = "atomic";
|
|
1109
|
+
var E_GRID_TYPE = "e-grid";
|
|
1110
|
+
var isGridElement = (element) => [element.dataset.eType, element.dataset.element_type].includes(E_GRID_TYPE);
|
|
1066
1111
|
var overlayRegistry = [
|
|
1067
1112
|
{
|
|
1068
1113
|
component: OutlineOverlay,
|
|
1069
1114
|
shouldRender: () => true
|
|
1070
1115
|
},
|
|
1116
|
+
{
|
|
1117
|
+
component: GridEmptyCellPositioner,
|
|
1118
|
+
shouldRender: ({ element }) => isGridElement(element)
|
|
1119
|
+
},
|
|
1071
1120
|
{
|
|
1072
1121
|
component: GridOutlineOverlay,
|
|
1073
|
-
shouldRender: ({ element, isSelected }) => isSelected && element
|
|
1122
|
+
shouldRender: ({ element, isSelected }) => isSelected && isGridElement(element)
|
|
1074
1123
|
}
|
|
1075
1124
|
];
|
|
1076
1125
|
function ElementsOverlays() {
|
|
@@ -1128,15 +1177,15 @@ import {
|
|
|
1128
1177
|
import { Portal } from "@elementor/ui";
|
|
1129
1178
|
|
|
1130
1179
|
// src/hooks/use-interactions-items.ts
|
|
1131
|
-
import { useEffect as
|
|
1180
|
+
import { useEffect as useEffect9, useMemo as useMemo2, useState as useState5 } from "react";
|
|
1132
1181
|
import { interactionsRepository } from "@elementor/editor-interactions";
|
|
1133
1182
|
import { registerDataHook } from "@elementor/editor-v1-adapters";
|
|
1134
1183
|
|
|
1135
1184
|
// src/hooks/use-on-mount.ts
|
|
1136
|
-
import { useEffect as
|
|
1185
|
+
import { useEffect as useEffect8, useRef } from "react";
|
|
1137
1186
|
function useOnMount(cb) {
|
|
1138
1187
|
const mounted = useRef(false);
|
|
1139
|
-
|
|
1188
|
+
useEffect8(() => {
|
|
1140
1189
|
if (!mounted.current) {
|
|
1141
1190
|
mounted.current = true;
|
|
1142
1191
|
cb();
|
|
@@ -1164,7 +1213,7 @@ function useInteractionsItems() {
|
|
|
1164
1213
|
return [];
|
|
1165
1214
|
}
|
|
1166
1215
|
}, []);
|
|
1167
|
-
|
|
1216
|
+
useEffect9(() => {
|
|
1168
1217
|
if (providerAndSubscribers.length === 0) {
|
|
1169
1218
|
return;
|
|
1170
1219
|
}
|
|
@@ -1301,7 +1350,7 @@ function getLinkAttrs(el) {
|
|
|
1301
1350
|
}
|
|
1302
1351
|
|
|
1303
1352
|
// src/hooks/use-style-items.ts
|
|
1304
|
-
import { useEffect as
|
|
1353
|
+
import { useEffect as useEffect10, useMemo as useMemo5, useRef as useRef2, useState as useState6 } from "react";
|
|
1305
1354
|
import { useBreakpoints } from "@elementor/editor-responsive";
|
|
1306
1355
|
import { isClassState } from "@elementor/editor-styles";
|
|
1307
1356
|
import { stylesRepository as stylesRepository2 } from "@elementor/editor-styles-repository";
|
|
@@ -1679,7 +1728,7 @@ function useStyleItems() {
|
|
|
1679
1728
|
})
|
|
1680
1729
|
);
|
|
1681
1730
|
}, [renderStyles]);
|
|
1682
|
-
|
|
1731
|
+
useEffect10(() => {
|
|
1683
1732
|
const unsubscribes = providerAndSubscribers.map(
|
|
1684
1733
|
({ provider, subscriber }) => provider.subscribe(subscriber)
|
|
1685
1734
|
);
|
|
@@ -3387,13 +3436,13 @@ var ReplacementBase = class {
|
|
|
3387
3436
|
|
|
3388
3437
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
3389
3438
|
import * as React10 from "react";
|
|
3390
|
-
import { useCallback as useCallback2, useEffect as
|
|
3439
|
+
import { useCallback as useCallback2, useEffect as useEffect12, useLayoutEffect, useState as useState8 } from "react";
|
|
3391
3440
|
import { InlineEditor, InlineEditorToolbar } from "@elementor/editor-controls";
|
|
3392
3441
|
import { Box as Box3, ThemeProvider } from "@elementor/ui";
|
|
3393
3442
|
import { autoUpdate as autoUpdate2, flip, FloatingPortal as FloatingPortal3, useFloating as useFloating2 } from "@floating-ui/react";
|
|
3394
3443
|
|
|
3395
3444
|
// src/legacy/replacements/inline-editing/inline-editing-utils.ts
|
|
3396
|
-
import { useCallback, useEffect as
|
|
3445
|
+
import { useCallback, useEffect as useEffect11, useState as useState7 } from "react";
|
|
3397
3446
|
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
3398
3447
|
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
3399
3448
|
var EDITING_PANEL = "#elementor-panel";
|
|
@@ -3425,7 +3474,7 @@ var getInlineEditorElement = (elementWrapper, expectedTag) => {
|
|
|
3425
3474
|
};
|
|
3426
3475
|
var useOnClickOutsideIframe = (handleUnmount) => {
|
|
3427
3476
|
const asyncUnmountInlineEditor = useCallback(() => queueMicrotask(handleUnmount), [handleUnmount]);
|
|
3428
|
-
|
|
3477
|
+
useEffect11(() => {
|
|
3429
3478
|
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
3430
3479
|
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
3431
3480
|
);
|
|
@@ -3436,7 +3485,7 @@ var useOnClickOutsideIframe = (handleUnmount) => {
|
|
|
3436
3485
|
};
|
|
3437
3486
|
var useRenderToolbar = (ownerDocument, id) => {
|
|
3438
3487
|
const [anchor, setAnchor] = useState7(null);
|
|
3439
|
-
|
|
3488
|
+
useEffect11(() => {
|
|
3440
3489
|
if (!anchor) {
|
|
3441
3490
|
removeToolbarAnchor(ownerDocument, id);
|
|
3442
3491
|
}
|
|
@@ -3533,7 +3582,7 @@ var CanvasInlineEditor = ({
|
|
|
3533
3582
|
const [active, setActive] = useState8(true);
|
|
3534
3583
|
const [editor, setEditor] = useState8(null);
|
|
3535
3584
|
const { onSelectionEnd, anchor: toolbarAnchor, clearAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
3536
|
-
|
|
3585
|
+
useEffect12(() => {
|
|
3537
3586
|
if (!active) {
|
|
3538
3587
|
clearAnchor();
|
|
3539
3588
|
requestDestroy();
|
|
@@ -3544,7 +3593,7 @@ var CanvasInlineEditor = ({
|
|
|
3544
3593
|
setActive(false);
|
|
3545
3594
|
}, []);
|
|
3546
3595
|
useOnClickOutsideIframe(dismiss);
|
|
3547
|
-
|
|
3596
|
+
useEffect12(() => {
|
|
3548
3597
|
const ownerDocument = contentElement.ownerDocument;
|
|
3549
3598
|
const handleClickAway = (event) => {
|
|
3550
3599
|
if (contentElement.contains(event.target)) {
|
|
@@ -3584,7 +3633,7 @@ var InlineEditingOverlay = ({
|
|
|
3584
3633
|
}) => {
|
|
3585
3634
|
const inlineEditedElement = getInlineEditorElement(rootElement, expectedTag);
|
|
3586
3635
|
const [overlayRefElement, setOverlayElement] = useState8(inlineEditedElement);
|
|
3587
|
-
|
|
3636
|
+
useEffect12(() => {
|
|
3588
3637
|
setOverlayElement(getInlineEditorElement(rootElement, expectedTag));
|
|
3589
3638
|
}, [expectedTag, rootElement]);
|
|
3590
3639
|
return overlayRefElement ? /* @__PURE__ */ React10.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
|
|
@@ -6563,9 +6612,9 @@ function useCanvasDocument() {
|
|
|
6563
6612
|
}
|
|
6564
6613
|
|
|
6565
6614
|
// src/hooks/use-escape-on-canvas.ts
|
|
6566
|
-
import { useEffect as
|
|
6615
|
+
import { useEffect as useEffect13 } from "react";
|
|
6567
6616
|
function useEscapeOnCanvas(canvasDocument, onEscape) {
|
|
6568
|
-
|
|
6617
|
+
useEffect13(() => {
|
|
6569
6618
|
if (!canvasDocument) {
|
|
6570
6619
|
return;
|
|
6571
6620
|
}
|
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.3.0-
|
|
4
|
+
"version": "4.3.0-953",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,26 +37,26 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "4.3.0-
|
|
41
|
-
"@elementor/editor-controls": "4.3.0-
|
|
42
|
-
"@elementor/editor-documents": "4.3.0-
|
|
43
|
-
"@elementor/editor-elements": "4.3.0-
|
|
44
|
-
"@elementor/editor-interactions": "4.3.0-
|
|
45
|
-
"@elementor/editor-mcp": "4.3.0-
|
|
46
|
-
"@elementor/editor-notifications": "4.3.0-
|
|
47
|
-
"@elementor/editor-props": "4.3.0-
|
|
48
|
-
"@elementor/editor-responsive": "4.3.0-
|
|
49
|
-
"@elementor/editor-styles": "4.3.0-
|
|
50
|
-
"@elementor/editor-styles-repository": "4.3.0-
|
|
51
|
-
"@elementor/editor-ui": "4.3.0-
|
|
52
|
-
"@elementor/editor-v1-adapters": "4.3.0-
|
|
53
|
-
"@elementor/events": "4.3.0-
|
|
54
|
-
"@elementor/http-client": "4.3.0-
|
|
55
|
-
"@elementor/schema": "4.3.0-
|
|
56
|
-
"@elementor/twing": "4.3.0-
|
|
40
|
+
"@elementor/editor": "4.3.0-953",
|
|
41
|
+
"@elementor/editor-controls": "4.3.0-953",
|
|
42
|
+
"@elementor/editor-documents": "4.3.0-953",
|
|
43
|
+
"@elementor/editor-elements": "4.3.0-953",
|
|
44
|
+
"@elementor/editor-interactions": "4.3.0-953",
|
|
45
|
+
"@elementor/editor-mcp": "4.3.0-953",
|
|
46
|
+
"@elementor/editor-notifications": "4.3.0-953",
|
|
47
|
+
"@elementor/editor-props": "4.3.0-953",
|
|
48
|
+
"@elementor/editor-responsive": "4.3.0-953",
|
|
49
|
+
"@elementor/editor-styles": "4.3.0-953",
|
|
50
|
+
"@elementor/editor-styles-repository": "4.3.0-953",
|
|
51
|
+
"@elementor/editor-ui": "4.3.0-953",
|
|
52
|
+
"@elementor/editor-v1-adapters": "4.3.0-953",
|
|
53
|
+
"@elementor/events": "4.3.0-953",
|
|
54
|
+
"@elementor/http-client": "4.3.0-953",
|
|
55
|
+
"@elementor/schema": "4.3.0-953",
|
|
56
|
+
"@elementor/twing": "4.3.0-953",
|
|
57
57
|
"@elementor/ui": "1.37.5",
|
|
58
|
-
"@elementor/utils": "4.3.0-
|
|
59
|
-
"@elementor/wp-media": "4.3.0-
|
|
58
|
+
"@elementor/utils": "4.3.0-953",
|
|
59
|
+
"@elementor/wp-media": "4.3.0-953",
|
|
60
60
|
"@floating-ui/react": "^0.27.5",
|
|
61
61
|
"@wordpress/i18n": "^5.13.0",
|
|
62
62
|
"dompurify": "^3.2.6"
|
|
@@ -8,19 +8,27 @@ import {
|
|
|
8
8
|
} from '@elementor/editor-v1-adapters';
|
|
9
9
|
|
|
10
10
|
import type { ElementOverlayConfig } from '../types/element-overlay';
|
|
11
|
-
import { GridOutlineOverlay } from './grid-outline';
|
|
11
|
+
import { GridEmptyCellPositioner, GridOutlineOverlay } from './grid-outline';
|
|
12
12
|
import { OutlineOverlay } from './outline-overlay';
|
|
13
13
|
|
|
14
14
|
const ELEMENTS_DATA_ATTR = 'atomic';
|
|
15
|
+
const E_GRID_TYPE = 'e-grid';
|
|
16
|
+
|
|
17
|
+
const isGridElement = ( element: HTMLElement ): boolean =>
|
|
18
|
+
[ element.dataset.eType, element.dataset.element_type ].includes( E_GRID_TYPE );
|
|
15
19
|
|
|
16
20
|
const overlayRegistry: ElementOverlayConfig[] = [
|
|
17
21
|
{
|
|
18
22
|
component: OutlineOverlay,
|
|
19
23
|
shouldRender: () => true,
|
|
20
24
|
},
|
|
25
|
+
{
|
|
26
|
+
component: GridEmptyCellPositioner,
|
|
27
|
+
shouldRender: ( { element } ) => isGridElement( element ),
|
|
28
|
+
},
|
|
21
29
|
{
|
|
22
30
|
component: GridOutlineOverlay,
|
|
23
|
-
shouldRender: ( { element, isSelected } ) => isSelected && element
|
|
31
|
+
shouldRender: ( { element, isSelected } ) => isSelected && isGridElement( element ),
|
|
24
32
|
},
|
|
25
33
|
];
|
|
26
34
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useElementRect } from '../../hooks/use-element-rect';
|
|
4
|
+
import { useGridTracks } from '../../hooks/use-grid-tracks';
|
|
5
|
+
import type { ElementOverlayProps } from '../../types/element-overlay';
|
|
6
|
+
import { findFirstEmptyCell } from '../../utils/find-first-empty-cell';
|
|
7
|
+
|
|
8
|
+
const CSS_VAR_ROW = '--e-grid-empty-cell-row';
|
|
9
|
+
const CSS_VAR_COL = '--e-grid-empty-cell-col';
|
|
10
|
+
const CSS_VAR_VISIBILITY = '--e-grid-empty-cell-visibility';
|
|
11
|
+
|
|
12
|
+
const clearGridEmptyCellStyles = ( target: HTMLElement ): void => {
|
|
13
|
+
target.style.removeProperty( CSS_VAR_ROW );
|
|
14
|
+
target.style.removeProperty( CSS_VAR_COL );
|
|
15
|
+
target.style.removeProperty( CSS_VAR_VISIBILITY );
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const GridEmptyCellPositioner = ( { element }: ElementOverlayProps ): null => {
|
|
19
|
+
const rect = useElementRect( element );
|
|
20
|
+
const tracks = useGridTracks( element, rect );
|
|
21
|
+
|
|
22
|
+
useEffect( () => {
|
|
23
|
+
if ( ! element ) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const firstEmpty = findFirstEmptyCell( element, tracks.columns.length, tracks.rows.length );
|
|
28
|
+
|
|
29
|
+
if ( ! firstEmpty ) {
|
|
30
|
+
element.style.removeProperty( CSS_VAR_ROW );
|
|
31
|
+
element.style.removeProperty( CSS_VAR_COL );
|
|
32
|
+
element.style.setProperty( CSS_VAR_VISIBILITY, 'hidden' );
|
|
33
|
+
return () => clearGridEmptyCellStyles( element );
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
element.style.setProperty( CSS_VAR_ROW, String( firstEmpty.row + 1 ) );
|
|
37
|
+
element.style.setProperty( CSS_VAR_COL, String( firstEmpty.col + 1 ) );
|
|
38
|
+
element.style.setProperty( CSS_VAR_VISIBILITY, 'visible' );
|
|
39
|
+
|
|
40
|
+
return () => {
|
|
41
|
+
clearGridEmptyCellStyles( element );
|
|
42
|
+
};
|
|
43
|
+
}, [ element, tracks ] );
|
|
44
|
+
|
|
45
|
+
return null;
|
|
46
|
+
};
|