"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
  if (from && typeof from === "object" || typeof from === "function") {
    for (let key of __getOwnPropNames(from))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  }
  return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
  // If the importer is in node compatibility mode or this is not an ESM
  // file that has been converted to a CommonJS file using a Babel-
  // compatible transform (i.e. "__esModule" has not been set), then set
  // "default" to the CommonJS "module.exports" for node compatibility.
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
  mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

// packages/block-editor/src/components/grid/grid-visualizer.js
var grid_visualizer_exports = {};
__export(grid_visualizer_exports, {
  GridVisualizer: () => GridVisualizer
});
module.exports = __toCommonJS(grid_visualizer_exports);
var import_clsx = __toESM(require("clsx"));
var import_element = require("@wordpress/element");
var import_data = require("@wordpress/data");
var import_compose = require("@wordpress/compose");
var import_use_block_refs = require("../block-list/use-block-props/use-block-refs.cjs");
var import_cover = __toESM(require("../block-popover/cover.cjs"));
var import_utils = require("./utils.cjs");
var import_store = require("../../store/index.cjs");
var import_use_get_number_of_blocks_before_cell = require("./use-get-number-of-blocks-before-cell.cjs");
var import_button_block_appender = __toESM(require("../button-block-appender/index.cjs"));
var import_lock_unlock = require("../../lock-unlock.cjs");
var import_jsx_runtime = require("react/jsx-runtime");
function GridVisualizer({
  clientId,
  contentRef,
  parentLayout,
  childGridClientId
}) {
  const isDistractionFree = (0, import_data.useSelect)(
    (select) => select(import_store.store).getSettings().isDistractionFree,
    []
  );
  const gridElement = (0, import_use_block_refs.useBlockElement)(clientId);
  if (isDistractionFree || !gridElement) {
    return null;
  }
  const isManualGrid = parentLayout?.isManualPlacement && window.__experimentalEnableGridInteractivity;
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    GridVisualizerGrid,
    {
      gridClientId: clientId,
      gridElement,
      isManualGrid,
      ref: contentRef,
      childGridClientId
    }
  );
}
var GridVisualizerGrid = (0, import_element.forwardRef)(
  ({ gridClientId, gridElement, isManualGrid, childGridClientId }, ref) => {
    const [gridInfo, setGridInfo] = (0, import_element.useState)(
      () => (0, import_utils.getGridInfo)(gridElement)
    );
    const [isDroppingAllowed, setIsDroppingAllowed] = (0, import_element.useState)(false);
    const childGridElement = (0, import_use_block_refs.useBlockElement)(childGridClientId);
    const childGridRect = (0, import_element.useMemo)(() => {
      if (!childGridElement) {
        return null;
      }
      return (0, import_utils.getGridItemRect)(childGridElement);
    }, [childGridElement]);
    (0, import_element.useEffect)(() => {
      const resizeCallback = () => setGridInfo((0, import_utils.getGridInfo)(gridElement));
      const borderBoxSpy = new window.ResizeObserver(resizeCallback);
      borderBoxSpy.observe(gridElement, { box: "border-box" });
      const contentBoxSpy = new window.ResizeObserver(resizeCallback);
      contentBoxSpy.observe(gridElement);
      return () => {
        borderBoxSpy.disconnect();
        contentBoxSpy.disconnect();
      };
    }, [gridElement]);
    (0, import_element.useEffect)(() => {
      function onGlobalDrag() {
        setIsDroppingAllowed(true);
      }
      function onGlobalDragEnd() {
        setIsDroppingAllowed(false);
      }
      document.addEventListener("drag", onGlobalDrag);
      document.addEventListener("dragend", onGlobalDragEnd);
      return () => {
        document.removeEventListener("drag", onGlobalDrag);
        document.removeEventListener("dragend", onGlobalDragEnd);
      };
    }, []);
    return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
      import_cover.default,
      {
        className: (0, import_clsx.default)("block-editor-grid-visualizer", {
          "is-dropping-allowed": isDroppingAllowed
        }),
        clientId: gridClientId,
        __unstablePopoverSlot: "__unstable-block-tools-after",
        children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
          "div",
          {
            ref,
            className: "block-editor-grid-visualizer__grid",
            style: gridInfo.style,
            children: isManualGrid ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
              ManualGridVisualizer,
              {
                gridClientId,
                gridInfo,
                childGridRect
              }
            ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
              AutoGridVisualizer,
              {
                gridInfo,
                childGridRect
              }
            )
          }
        )
      }
    );
  }
);
function AutoGridVisualizer({ gridInfo, childGridRect }) {
  return (0, import_utils.range)(1, gridInfo.numRows).map(
    (row) => (0, import_utils.range)(1, gridInfo.numColumns).map((column) => {
      let color = gridInfo.currentColor;
      if (childGridRect?.contains(column, row)) {
        color = "transparent";
      }
      return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        GridVisualizerCell,
        {
          color
        },
        `${row}-${column}`
      );
    })
  );
}
function ManualGridVisualizer({ gridClientId, gridInfo, childGridRect }) {
  const [highlightedRect, setHighlightedRect] = (0, import_element.useState)(null);
  const gridItemStyles = (0, import_data.useSelect)(
    (select) => {
      const { getBlockOrder, getBlockStyles } = (0, import_lock_unlock.unlock)(
        select(import_store.store)
      );
      const blockOrder = getBlockOrder(gridClientId);
      return getBlockStyles(blockOrder);
    },
    [gridClientId]
  );
  const occupiedRects = (0, import_element.useMemo)(() => {
    const rects = [];
    for (const style of Object.values(gridItemStyles)) {
      const {
        columnStart,
        rowStart,
        columnSpan = 1,
        rowSpan = 1
      } = style?.layout ?? {};
      if (!columnStart || !rowStart) {
        continue;
      }
      rects.push(
        new import_utils.GridRect({
          columnStart,
          rowStart,
          columnSpan,
          rowSpan
        })
      );
    }
    return rects;
  }, [gridItemStyles]);
  return (0, import_utils.range)(1, gridInfo.numRows).map(
    (row) => (0, import_utils.range)(1, gridInfo.numColumns).map((column) => {
      const isChildGridCell = childGridRect?.contains(column, row);
      let color = gridInfo.currentColor;
      if (isChildGridCell) {
        color = "transparent";
      }
      const isCellOccupied = occupiedRects.some(
        (rect) => rect.contains(column, row)
      );
      const isHighlighted = highlightedRect?.contains(column, row) ?? false;
      return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
        GridVisualizerCell,
        {
          color,
          className: isHighlighted && "is-highlighted",
          children: isCellOccupied && !isChildGridCell ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            GridVisualizerDropZone,
            {
              column,
              row,
              gridClientId,
              gridInfo,
              setHighlightedRect
            }
          ) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
            GridVisualizerAppender,
            {
              column,
              row,
              gridClientId,
              gridInfo,
              setHighlightedRect
            }
          )
        },
        `${row}-${column}`
      );
    })
  );
}
function GridVisualizerCell({ color, children, className }) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "div",
    {
      className: (0, import_clsx.default)(
        "block-editor-grid-visualizer__cell",
        className
      ),
      style: {
        boxShadow: `inset 0 0 0 1px color-mix(in srgb, ${color} 20%, #0000)`,
        color
      },
      children
    }
  );
}
function useGridVisualizerDropZone(column, row, gridClientId, gridInfo, setHighlightedRect) {
  const {
    getBlockAttributes,
    getBlockRootClientId,
    canInsertBlockType,
    getBlockName
  } = (0, import_data.useSelect)(import_store.store);
  const {
    updateBlockAttributes,
    moveBlocksToPosition,
    __unstableMarkNextChangeAsNotPersistent
  } = (0, import_data.useDispatch)(import_store.store);
  const getNumberOfBlocksBeforeCell = (0, import_use_get_number_of_blocks_before_cell.useGetNumberOfBlocksBeforeCell)(
    gridClientId,
    gridInfo.numColumns
  );
  return useDropZoneWithValidation({
    validateDrag(srcClientId) {
      const blockName = getBlockName(srcClientId);
      if (!canInsertBlockType(blockName, gridClientId)) {
        return false;
      }
      const attributes = getBlockAttributes(srcClientId);
      const rect = new import_utils.GridRect({
        columnStart: column,
        rowStart: row,
        columnSpan: attributes.style?.layout?.columnSpan,
        rowSpan: attributes.style?.layout?.rowSpan
      });
      const isInBounds = new import_utils.GridRect({
        columnSpan: gridInfo.numColumns,
        rowSpan: gridInfo.numRows
      }).containsRect(rect);
      return isInBounds;
    },
    onDragEnter(srcClientId) {
      const attributes = getBlockAttributes(srcClientId);
      setHighlightedRect(
        new import_utils.GridRect({
          columnStart: column,
          rowStart: row,
          columnSpan: attributes.style?.layout?.columnSpan,
          rowSpan: attributes.style?.layout?.rowSpan
        })
      );
    },
    onDragLeave() {
      setHighlightedRect(
        (prevHighlightedRect) => prevHighlightedRect?.columnStart === column && prevHighlightedRect?.rowStart === row ? null : prevHighlightedRect
      );
    },
    onDrop(srcClientId) {
      setHighlightedRect(null);
      const attributes = getBlockAttributes(srcClientId);
      updateBlockAttributes(srcClientId, {
        style: {
          ...attributes.style,
          layout: {
            ...attributes.style?.layout,
            columnStart: column,
            rowStart: row
          }
        }
      });
      __unstableMarkNextChangeAsNotPersistent();
      moveBlocksToPosition(
        [srcClientId],
        getBlockRootClientId(srcClientId),
        gridClientId,
        getNumberOfBlocksBeforeCell(column, row)
      );
    }
  });
}
function GridVisualizerDropZone({
  column,
  row,
  gridClientId,
  gridInfo,
  setHighlightedRect
}) {
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    "div",
    {
      className: "block-editor-grid-visualizer__drop-zone",
      ref: useGridVisualizerDropZone(
        column,
        row,
        gridClientId,
        gridInfo,
        setHighlightedRect
      )
    }
  );
}
function GridVisualizerAppender({
  column,
  row,
  gridClientId,
  gridInfo,
  setHighlightedRect
}) {
  const {
    updateBlockAttributes,
    moveBlocksToPosition,
    __unstableMarkNextChangeAsNotPersistent
  } = (0, import_data.useDispatch)(import_store.store);
  const getNumberOfBlocksBeforeCell = (0, import_use_get_number_of_blocks_before_cell.useGetNumberOfBlocksBeforeCell)(
    gridClientId,
    gridInfo.numColumns
  );
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
    import_button_block_appender.default,
    {
      rootClientId: gridClientId,
      className: "block-editor-grid-visualizer__appender",
      ref: useGridVisualizerDropZone(
        column,
        row,
        gridClientId,
        gridInfo,
        setHighlightedRect
      ),
      style: {
        color: gridInfo.currentColor
      },
      onSelect: (block) => {
        if (!block) {
          return;
        }
        updateBlockAttributes(block.clientId, {
          style: {
            layout: {
              columnStart: column,
              rowStart: row
            }
          }
        });
        __unstableMarkNextChangeAsNotPersistent();
        moveBlocksToPosition(
          [block.clientId],
          gridClientId,
          gridClientId,
          getNumberOfBlocksBeforeCell(column, row)
        );
      }
    }
  );
}
function useDropZoneWithValidation({
  validateDrag,
  onDragEnter,
  onDragLeave,
  onDrop
}) {
  const { getDraggedBlockClientIds } = (0, import_data.useSelect)(import_store.store);
  return (0, import_compose.__experimentalUseDropZone)({
    onDragEnter() {
      const [srcClientId] = getDraggedBlockClientIds();
      if (srcClientId && validateDrag(srcClientId)) {
        onDragEnter(srcClientId);
      }
    },
    onDragLeave() {
      onDragLeave();
    },
    onDrop() {
      const [srcClientId] = getDraggedBlockClientIds();
      if (srcClientId && validateDrag(srcClientId)) {
        onDrop(srcClientId);
      }
    }
  });
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
  GridVisualizer
});
//# sourceMappingURL=grid-visualizer.cjs.map
