// packages/block-editor/src/components/block-tools/use-block-toolbar-popover-props.js
import { useRefEffect } from "@wordpress/compose";
import { useSelect } from "@wordpress/data";
import { getScrollContainer } from "@wordpress/dom";
import {
  useCallback,
  useLayoutEffect,
  useMemo,
  useState
} from "@wordpress/element";
import { store as blockEditorStore } from "../../store";
import { useBlockElement } from "../block-list/use-block-props/use-block-refs";
import { hasStickyOrFixedPositionValue } from "../../hooks/position";
import { getElementBounds } from "../../utils/dom";
var COMMON_PROPS = {
  placement: "top-start"
};
var DEFAULT_PROPS = {
  ...COMMON_PROPS,
  flip: false,
  shift: true
};
var RESTRICTED_HEIGHT_PROPS = {
  ...COMMON_PROPS,
  flip: true,
  shift: false
};
function getProps(contentElement, selectedBlockElement, scrollContainer, toolbarHeight, isSticky) {
  if (!contentElement || !selectedBlockElement) {
    return DEFAULT_PROPS;
  }
  const scrollTop = scrollContainer?.scrollTop || 0;
  const blockRect = getElementBounds(selectedBlockElement);
  const contentRect = contentElement.getBoundingClientRect();
  const topOfContentElementInViewport = scrollTop + contentRect.top;
  const viewportHeight = contentElement.ownerDocument.documentElement.clientHeight;
  const restrictedTopArea = topOfContentElementInViewport + toolbarHeight;
  const hasSpaceForToolbarAbove = blockRect.top > restrictedTopArea;
  const isBlockTallerThanViewport = blockRect.height > viewportHeight - toolbarHeight;
  if (!isSticky && (hasSpaceForToolbarAbove || isBlockTallerThanViewport)) {
    return DEFAULT_PROPS;
  }
  return RESTRICTED_HEIGHT_PROPS;
}
function useBlockToolbarPopoverProps({
  contentElement,
  clientId
}) {
  const selectedBlockElement = useBlockElement(clientId);
  const [toolbarHeight, setToolbarHeight] = useState(0);
  const { blockIndex, isSticky } = useSelect(
    (select) => {
      const { getBlockIndex, getBlockAttributes } = select(blockEditorStore);
      return {
        blockIndex: getBlockIndex(clientId),
        isSticky: hasStickyOrFixedPositionValue(
          getBlockAttributes(clientId)
        )
      };
    },
    [clientId]
  );
  const scrollContainer = useMemo(() => {
    if (!contentElement) {
      return;
    }
    return getScrollContainer(contentElement);
  }, [contentElement]);
  const [props, setProps] = useState(
    () => getProps(
      contentElement,
      selectedBlockElement,
      scrollContainer,
      toolbarHeight,
      isSticky
    )
  );
  const popoverRef = useRefEffect((popoverNode) => {
    setToolbarHeight(popoverNode.offsetHeight);
  }, []);
  const updateProps = useCallback(
    () => setProps(
      getProps(
        contentElement,
        selectedBlockElement,
        scrollContainer,
        toolbarHeight,
        isSticky
      )
    ),
    [contentElement, selectedBlockElement, scrollContainer, toolbarHeight]
  );
  useLayoutEffect(updateProps, [blockIndex, updateProps]);
  useLayoutEffect(() => {
    if (!contentElement || !selectedBlockElement) {
      return;
    }
    const contentView = contentElement?.ownerDocument?.defaultView;
    contentView?.addEventHandler?.("resize", updateProps);
    let resizeObserver;
    const blockView = selectedBlockElement?.ownerDocument?.defaultView;
    if (blockView.ResizeObserver) {
      resizeObserver = new blockView.ResizeObserver(updateProps);
      resizeObserver.observe(selectedBlockElement);
    }
    return () => {
      contentView?.removeEventHandler?.("resize", updateProps);
      if (resizeObserver) {
        resizeObserver.disconnect();
      }
    };
  }, [updateProps, contentElement, selectedBlockElement]);
  return {
    ...props,
    ref: popoverRef
  };
}
export {
  useBlockToolbarPopoverProps as default
};
//# sourceMappingURL=use-block-toolbar-popover-props.js.map
