@wordpress/block-editor
Version:
117 lines (116 loc) • 3.35 kB
JavaScript
// packages/block-editor/src/components/block-popover/index.js
import clsx from "clsx";
import { useMergeRefs } from "@wordpress/compose";
import { Popover } from "@wordpress/components";
import {
forwardRef,
useMemo,
useReducer,
useLayoutEffect
} from "@wordpress/element";
import { useBlockElement } from "../block-list/use-block-props/use-block-refs";
import usePopoverScroll from "./use-popover-scroll";
import { rectUnion, getElementBounds } from "../../utils/dom";
import { jsx } from "react/jsx-runtime";
var MAX_POPOVER_RECOMPUTE_COUNTER = Number.MAX_SAFE_INTEGER;
function BlockPopover({
clientId,
bottomClientId,
children,
__unstablePopoverSlot,
__unstableContentRef,
shift = true,
...props
}, ref) {
const selectedElement = useBlockElement(clientId);
const lastSelectedElement = useBlockElement(bottomClientId ?? clientId);
const mergedRefs = useMergeRefs([
ref,
usePopoverScroll(__unstableContentRef)
]);
const [
popoverDimensionsRecomputeCounter,
forceRecomputePopoverDimensions
] = useReducer(
// Module is there to make sure that the counter doesn't overflow.
(s) => (s + 1) % MAX_POPOVER_RECOMPUTE_COUNTER,
0
);
useLayoutEffect(() => {
if (!selectedElement) {
return;
}
const observer = new window.MutationObserver(
forceRecomputePopoverDimensions
);
observer.observe(selectedElement, { attributes: true });
return () => {
observer.disconnect();
};
}, [selectedElement]);
const popoverAnchor = useMemo(() => {
if (
// popoverDimensionsRecomputeCounter is by definition always equal or greater
// than 0. This check is only there to satisfy the correctness of the
// exhaustive-deps rule for the `useMemo` hook.
popoverDimensionsRecomputeCounter < 0 || !selectedElement || bottomClientId && !lastSelectedElement
) {
return void 0;
}
return {
getBoundingClientRect() {
return lastSelectedElement ? rectUnion(
getElementBounds(selectedElement),
getElementBounds(lastSelectedElement)
) : getElementBounds(selectedElement);
},
contextElement: selectedElement
};
}, [
popoverDimensionsRecomputeCounter,
selectedElement,
bottomClientId,
lastSelectedElement
]);
if (!selectedElement || bottomClientId && !lastSelectedElement) {
return null;
}
return /* @__PURE__ */ jsx(
Popover,
{
ref: mergedRefs,
animate: false,
focusOnMount: false,
anchor: popoverAnchor,
__unstableSlotName: __unstablePopoverSlot,
inline: !__unstablePopoverSlot,
placement: "top-start",
resize: false,
flip: false,
shift,
...props,
className: clsx("block-editor-block-popover", props.className),
variant: "unstyled",
children
}
);
}
var PrivateBlockPopover = forwardRef(BlockPopover);
var PublicBlockPopover = ({ clientId, bottomClientId, children, ...props }, ref) => /* @__PURE__ */ jsx(
PrivateBlockPopover,
{
...props,
bottomClientId,
clientId,
__unstableContentRef: void 0,
__unstablePopoverSlot: void 0,
ref,
children
}
);
var block_popover_default = forwardRef(PublicBlockPopover);
export {
PrivateBlockPopover,
block_popover_default as default
};
//# sourceMappingURL=index.js.map