@ixo/editor 2.12.0 → 2.13.0

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.
@@ -17426,9 +17426,18 @@ import React168, { useCallback as useCallback42, useEffect as useEffect47, useRe
17426
17426
  import { Box as Box30 } from "@mantine/core";
17427
17427
  var SCROLL_ZONE_SIZE = 80;
17428
17428
  var SCROLL_SPEED = 12;
17429
- var ExternalDropZone = ({ editor, onDrop, acceptedType = "application/x-artifact", dropIndicator, children }) => {
17429
+ var ExternalDropZone = ({
17430
+ editor,
17431
+ onDrop,
17432
+ acceptedType = "application/x-artifact",
17433
+ dropIndicator,
17434
+ isPlacementMode = false,
17435
+ onPlacementCancel,
17436
+ children
17437
+ }) => {
17430
17438
  const containerRef = useRef13(null);
17431
17439
  const [isValidDrag, setIsValidDrag] = useState63(false);
17440
+ const [isHoveringInPlacementMode, setIsHoveringInPlacementMode] = useState63(false);
17432
17441
  const [indicatorStyle, setIndicatorStyle] = useState63({});
17433
17442
  const dropPositionRef = useRef13(null);
17434
17443
  const scrollAnimationRef = useRef13(null);
@@ -17598,8 +17607,87 @@ var ExternalDropZone = ({ editor, onDrop, acceptedType = "application/x-artifact
17598
17607
  window.addEventListener("dragend", handleGlobalDragEnd);
17599
17608
  return () => window.removeEventListener("dragend", handleGlobalDragEnd);
17600
17609
  }, [stopAutoScroll]);
17610
+ const handleOverlayMouseMove = useCallback42(
17611
+ (e) => {
17612
+ setIsHoveringInPlacementMode(true);
17613
+ checkAutoScroll(e.clientY);
17614
+ const result = findDropPosition(e.clientY);
17615
+ if (result) {
17616
+ dropPositionRef.current = result.position;
17617
+ setIndicatorStyle({
17618
+ position: "absolute",
17619
+ top: result.indicatorTop,
17620
+ left: 0,
17621
+ right: 0,
17622
+ zIndex: 9999,
17623
+ pointerEvents: "none"
17624
+ });
17625
+ }
17626
+ },
17627
+ [findDropPosition, checkAutoScroll]
17628
+ );
17629
+ const handleOverlayMouseLeave = useCallback42(() => {
17630
+ setIsHoveringInPlacementMode(false);
17631
+ dropPositionRef.current = null;
17632
+ stopAutoScroll();
17633
+ }, [stopAutoScroll]);
17634
+ const handleOverlayClick = useCallback42(
17635
+ (e) => {
17636
+ e.preventDefault();
17637
+ e.stopPropagation();
17638
+ const position = dropPositionRef.current;
17639
+ if (position) {
17640
+ onDrop(position);
17641
+ }
17642
+ setIsHoveringInPlacementMode(false);
17643
+ dropPositionRef.current = null;
17644
+ stopAutoScroll();
17645
+ },
17646
+ [onDrop, stopAutoScroll]
17647
+ );
17648
+ const handleOverlayWheel = useCallback42(
17649
+ (e) => {
17650
+ const container = getScrollContainer();
17651
+ if (container === window) {
17652
+ window.scrollBy(0, e.deltaY);
17653
+ } else {
17654
+ container.scrollBy(0, e.deltaY);
17655
+ }
17656
+ },
17657
+ [getScrollContainer]
17658
+ );
17659
+ useEffect47(() => {
17660
+ if (!isPlacementMode) return;
17661
+ const handleKeyDown = (e) => {
17662
+ if (e.key === "Escape") {
17663
+ onPlacementCancel?.();
17664
+ }
17665
+ };
17666
+ const handleGlobalClick = (e) => {
17667
+ const target = e.target;
17668
+ if (target.closest("[data-placement-toggle]")) {
17669
+ return;
17670
+ }
17671
+ if (containerRef.current && !containerRef.current.contains(target)) {
17672
+ onPlacementCancel?.();
17673
+ }
17674
+ };
17675
+ document.addEventListener("keydown", handleKeyDown);
17676
+ document.addEventListener("click", handleGlobalClick, true);
17677
+ return () => {
17678
+ document.removeEventListener("keydown", handleKeyDown);
17679
+ document.removeEventListener("click", handleGlobalClick, true);
17680
+ };
17681
+ }, [isPlacementMode, onPlacementCancel]);
17682
+ useEffect47(() => {
17683
+ if (!isPlacementMode) {
17684
+ setIsHoveringInPlacementMode(false);
17685
+ dropPositionRef.current = null;
17686
+ }
17687
+ }, [isPlacementMode]);
17601
17688
  useEffect47(() => {
17602
- if (isValidDrag) {
17689
+ const isActive = isValidDrag || isPlacementMode && isHoveringInPlacementMode;
17690
+ if (isActive) {
17603
17691
  document.body.classList.add("external-artifact-drag-active");
17604
17692
  } else {
17605
17693
  document.body.classList.remove("external-artifact-drag-active");
@@ -17607,7 +17695,7 @@ var ExternalDropZone = ({ editor, onDrop, acceptedType = "application/x-artifact
17607
17695
  return () => {
17608
17696
  document.body.classList.remove("external-artifact-drag-active");
17609
17697
  };
17610
- }, [isValidDrag]);
17698
+ }, [isValidDrag, isPlacementMode, isHoveringInPlacementMode]);
17611
17699
  useEffect47(() => {
17612
17700
  return () => {
17613
17701
  if (scrollAnimationRef.current) {
@@ -17618,18 +17706,44 @@ var ExternalDropZone = ({ editor, onDrop, acceptedType = "application/x-artifact
17618
17706
  const indicatorWithPosition = dropIndicator && React168.isValidElement(dropIndicator) ? React168.cloneElement(dropIndicator, {
17619
17707
  indicatorTop: typeof indicatorStyle.top === "number" ? indicatorStyle.top : void 0
17620
17708
  }) : dropIndicator;
17709
+ const shouldShowIndicator = isValidDrag || isPlacementMode && isHoveringInPlacementMode;
17621
17710
  return /* @__PURE__ */ React168.createElement(
17622
17711
  Box30,
17623
17712
  {
17624
17713
  ref: containerRef,
17625
- style: { position: "relative", width: "100%", height: "100%" },
17714
+ style: {
17715
+ position: "relative",
17716
+ width: "100%",
17717
+ height: "100%"
17718
+ },
17626
17719
  onDragOver: handleDragOver,
17627
17720
  onDragLeave: handleDragLeave,
17628
17721
  onDrop: handleDrop,
17629
- "data-external-drag": isValidDrag ? "true" : void 0
17722
+ "data-external-drag": isValidDrag ? "true" : void 0,
17723
+ "data-placement-mode": isPlacementMode ? "true" : void 0
17630
17724
  },
17631
17725
  children,
17632
- isValidDrag && indicatorWithPosition && /* @__PURE__ */ React168.createElement(Box30, { style: { ...indicatorStyle, background: "none", border: "none", boxShadow: "none" } }, indicatorWithPosition)
17726
+ isPlacementMode && /* @__PURE__ */ React168.createElement(
17727
+ Box30,
17728
+ {
17729
+ style: {
17730
+ position: "absolute",
17731
+ top: 0,
17732
+ left: 0,
17733
+ right: 0,
17734
+ bottom: 0,
17735
+ cursor: "crosshair",
17736
+ zIndex: 9998,
17737
+ // Below the indicator (9999) but above content
17738
+ background: "transparent"
17739
+ },
17740
+ onMouseMove: handleOverlayMouseMove,
17741
+ onMouseLeave: handleOverlayMouseLeave,
17742
+ onClick: handleOverlayClick,
17743
+ onWheel: handleOverlayWheel
17744
+ }
17745
+ ),
17746
+ shouldShowIndicator && indicatorWithPosition && /* @__PURE__ */ React168.createElement(Box30, { style: { ...indicatorStyle, background: "none", border: "none", boxShadow: "none" } }, indicatorWithPosition)
17633
17747
  );
17634
17748
  };
17635
17749
 
@@ -17706,7 +17820,9 @@ function IxoEditorContent({
17706
17820
  pageHeaderProps,
17707
17821
  onExternalDrop,
17708
17822
  externalDropType,
17709
- dropIndicator
17823
+ dropIndicator,
17824
+ isPlacementMode,
17825
+ onPlacementCancel
17710
17826
  }) {
17711
17827
  const { activePanel } = usePanelStore();
17712
17828
  const isPanelOpen = activePanel !== null;
@@ -17749,7 +17865,19 @@ function IxoEditorContent({
17749
17865
  },
17750
17866
  selfNav && /* @__PURE__ */ React170.createElement(PageHeader, { ...pageHeaderProps }),
17751
17867
  /* @__PURE__ */ React170.createElement(CoverImage, { coverImageUrl, logoUrl }),
17752
- onExternalDrop ? /* @__PURE__ */ React170.createElement(ExternalDropZone, { editor, onDrop: onExternalDrop, acceptedType: externalDropType, dropIndicator }, editorContent) : editorContent
17868
+ (onExternalDrop || isPlacementMode) && isEditable ? /* @__PURE__ */ React170.createElement(
17869
+ ExternalDropZone,
17870
+ {
17871
+ editor,
17872
+ onDrop: onExternalDrop || (() => {
17873
+ }),
17874
+ acceptedType: externalDropType,
17875
+ dropIndicator,
17876
+ isPlacementMode,
17877
+ onPlacementCancel
17878
+ },
17879
+ editorContent
17880
+ ) : editorContent
17753
17881
  ), isPanelVisible && /* @__PURE__ */ React170.createElement(PanelContent, { theme: config.theme }));
17754
17882
  }
17755
17883
  function IxoEditor({
@@ -17772,7 +17900,9 @@ function IxoEditor({
17772
17900
  dynamicListPanelRenderer,
17773
17901
  onExternalDrop,
17774
17902
  externalDropType,
17775
- dropIndicator
17903
+ dropIndicator,
17904
+ isPlacementMode,
17905
+ onPlacementCancel
17776
17906
  }) {
17777
17907
  if (!editor) {
17778
17908
  return null;
@@ -17814,7 +17944,9 @@ function IxoEditor({
17814
17944
  pageHeaderProps,
17815
17945
  onExternalDrop,
17816
17946
  externalDropType,
17817
- dropIndicator
17947
+ dropIndicator,
17948
+ isPlacementMode,
17949
+ onPlacementCancel
17818
17950
  },
17819
17951
  children
17820
17952
  )
@@ -18354,4 +18486,4 @@ export {
18354
18486
  ixoGraphQLClient,
18355
18487
  getEntity
18356
18488
  };
18357
- //# sourceMappingURL=chunk-5QJ4XXRA.mjs.map
18489
+ //# sourceMappingURL=chunk-JRIF7FLP.mjs.map