diff --git a/packages/main/src/Popover.js b/packages/main/src/Popover.js
index 99b50f6d82d3..30a2b93afb77 100644
--- a/packages/main/src/Popover.js
+++ b/packages/main/src/Popover.js
@@ -1,4 +1,5 @@
import Integer from "@ui5/webcomponents-base/dist/types/Integer.js";
+import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
import Popup from "./Popup.js";
import PopoverPlacementType from "./types/PopoverPlacementType.js";
import PopoverVerticalAlign from "./types/PopoverVerticalAlign.js";
@@ -250,6 +251,12 @@ const metadata = {
* @public
*/
class Popover extends Popup {
+ constructor() {
+ super();
+
+ this._handleResize = this.handleResize.bind(this);
+ }
+
static get metadata() {
return metadata;
}
@@ -266,6 +273,14 @@ class Popover extends Popup {
return 10; // px
}
+ onEnterDOM() {
+ ResizeHandler.register(this, this._handleResize);
+ }
+
+ onExitDOM() {
+ ResizeHandler.deregister(this, this._handleResize);
+ }
+
isOpenerClicked(event) {
const target = event.target;
return target === this._opener || (target.getFocusDomRef && target.getFocusDomRef() === this._opener) || event.composedPath().indexOf(this._opener) > -1;
@@ -277,14 +292,15 @@ class Popover extends Popup {
* @param {boolean} preventInitialFocus prevents applying the focus inside the popover
* @public
*/
- openBy(opener, preventInitialFocus = false) {
+ async openBy(opener, preventInitialFocus = false) {
if (!opener || this.opened) {
return;
}
this._opener = opener;
+ this._openerRect = opener.getBoundingClientRect();
- super.open(preventInitialFocus);
+ await super.open(preventInitialFocus);
}
/**
@@ -332,21 +348,36 @@ class Popover extends Popup {
&& openerRect.right === 0;
}
+ handleResize() {
+ if (this.opened) {
+ this.reposition();
+ }
+ }
+
reposition() {
this.show();
}
show() {
let placement;
- const popoverSize = this.popoverSize;
- const openerRect = this._opener.getBoundingClientRect();
+ const popoverSize = this.getPopoverSize();
+
+ if (popoverSize.width === 0 || popoverSize.height === 0) {
+ // size can not be determined properly at this point, popover will be shown with the next reposition
+ return;
+ }
- if (this.shouldCloseDueToNoOpener(openerRect) && this.isFocusWithin()) {
+ if (this.isOpen()) {
+ // update opener rect if it was changed during the popover being opened
+ this._openerRect = this._opener.getBoundingClientRect();
+ }
+
+ if (this.shouldCloseDueToNoOpener(this._openerRect) && this.isFocusWithin()) {
// reuse the old placement as the opener is not available,
// but keep the popover open as the focus is within
placement = this._oldPlacement;
} else {
- placement = this.calcPlacement(openerRect, popoverSize);
+ placement = this.calcPlacement(this._openerRect, popoverSize);
}
const stretching = this.horizontalAlign === PopoverHorizontalAlign.Stretch;
@@ -379,7 +410,7 @@ class Popover extends Popup {
}
}
- get popoverSize() {
+ getPopoverSize() {
let width,
height;
let rect = this.getBoundingClientRect();
@@ -391,17 +422,15 @@ class Popover extends Popup {
return { width, height };
}
- this.style.visibility = "hidden";
this.style.display = "block";
+ this.style.top = "-10000px";
+ this.style.left = "-10000px";
rect = this.getBoundingClientRect();
width = rect.width;
height = rect.height;
- this.hide();
- this.style.visibility = "visible";
-
return { width, height };
}
@@ -595,6 +624,7 @@ class Popover extends Popup {
switch (this.horizontalAlign) {
case PopoverHorizontalAlign.Center:
case PopoverHorizontalAlign.Stretch:
+
left = targetRect.left - (popoverSize.width - targetRect.width) / 2;
break;
case PopoverHorizontalAlign.Left:
diff --git a/packages/main/src/Popup.js b/packages/main/src/Popup.js
index 1cb5258c2871..419a9a0ad6f5 100644
--- a/packages/main/src/Popup.js
+++ b/packages/main/src/Popup.js
@@ -1,3 +1,4 @@
+import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js";
import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
import { getRTL } from "@ui5/webcomponents-base/dist/config/RTL.js";
import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
@@ -321,7 +322,7 @@ class Popup extends UI5Element {
* @param {boolean} preventInitialFocus prevents applying the focus inside the popup
* @public
*/
- open(preventInitialFocus) {
+ async open(preventInitialFocus) {
const prevented = !this.fireEvent("before-open", {}, true, false);
if (prevented) {
return;
@@ -337,6 +338,7 @@ class Popup extends UI5Element {
this._zIndex = getNextZIndex();
this.style.zIndex = this._zIndex;
this._focusedElementBeforeOpen = getFocusedElement();
+
this.show();
if (!this._disableInitialFocus && !preventInitialFocus) {
@@ -346,6 +348,8 @@ class Popup extends UI5Element {
this._addOpenedPopup();
this.opened = true;
+
+ await renderFinished();
this.fireEvent("after-open", {}, false, false);
}
diff --git a/packages/main/test/pages/Popover.html b/packages/main/test/pages/Popover.html
index 6df3f5c34abb..0d7dd0719d77 100644
--- a/packages/main/test/pages/Popover.html
+++ b/packages/main/test/pages/Popover.html
@@ -137,8 +137,8 @@
@@ -375,6 +375,13 @@
+
+
+