diff --git a/packages/block-editor/src/components/block-list/block-popover.js b/packages/block-editor/src/components/block-list/block-popover.js
index 2a70b80c2dafa..1b7b42289ed4c 100644
--- a/packages/block-editor/src/components/block-list/block-popover.js
+++ b/packages/block-editor/src/components/block-list/block-popover.js
@@ -160,6 +160,7 @@ function BlockPopover( {
className="block-editor-block-list__block-popover"
__unstableSticky={ ! showEmptyBlockSideInserter }
__unstableSlotName="block-toolbar"
+ __unstableBoundaryParent
// Allow subpixel positioning for the block movement animation.
__unstableAllowVerticalSubpixelPosition={
moverDirection !== 'horizontal' && node
@@ -169,6 +170,9 @@ function BlockPopover( {
}
onBlur={ () => setIsToolbarForced( false ) }
shouldAnchorIncludePadding
+ // Popover calculates the width once. Trigger a reset by remounting
+ // the component.
+ key={ shouldShowContextualToolbar }
>
{ ( shouldShowContextualToolbar || isToolbarForced ) && (
{
@@ -471,6 +472,7 @@ const Popover = ( {
__unstableSticky,
__unstableAllowVerticalSubpixelPosition,
__unstableAllowHorizontalSubpixelPosition,
+ __unstableBoundaryParent,
] );
useFocusContentOnMount( focusOnMount, contentRef );
@@ -626,7 +628,7 @@ const Popover = ( {
const PopoverContainer = Popover;
PopoverContainer.Slot = ( { name = SLOT_NAME } ) => (
-
+
);
export default PopoverContainer;
diff --git a/packages/components/src/popover/utils.js b/packages/components/src/popover/utils.js
index a5a927a0b433e..d62d784273570 100644
--- a/packages/components/src/popover/utils.js
+++ b/packages/components/src/popover/utils.js
@@ -19,6 +19,7 @@ const HEIGHT_OFFSET = 10; // used by the arrow and a bit of empty space
* scroll container edge when part of the anchor
* leaves view.
* @param {string} chosenYAxis yAxis to be used.
+ * @param {Element} boundaryElement
*
* @return {Object} Popover xAxis position and constraints.
*/
@@ -28,7 +29,8 @@ export function computePopoverXAxisPosition(
xAxis,
corner,
sticky,
- chosenYAxis
+ chosenYAxis,
+ boundaryElement
) {
const { width } = contentSize;
const isRTL = document.documentElement.dir === 'rtl';
@@ -121,6 +123,11 @@ export function computePopoverXAxisPosition(
popoverLeft = rightAlignment.popoverLeft;
}
+ if ( boundaryElement ) {
+ const boundaryRect = boundaryElement.getBoundingClientRect();
+ popoverLeft = Math.min( popoverLeft, boundaryRect.right - width );
+ }
+
return {
xAxis: chosenXAxis,
popoverLeft,