Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ui5-popup): position arrows correctly #2917

Merged
merged 3 commits into from
Mar 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 40 additions & 8 deletions packages/main/src/Popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -529,9 +529,7 @@ class Popover extends Popup {

let maxContentHeight = Math.round(maxHeight);

const hasHeader = this.header.length || this.headerText;

if (hasHeader) {
if (this._displayHeader) {
const headerDomRef = this.shadowRoot.querySelector(".ui5-popup-header-root")
|| this.shadowRoot.querySelector(".ui5-popup-header-text");

Expand All @@ -542,9 +540,7 @@ class Popover extends Popup {

this._maxContentHeight = maxContentHeight;

const arrowXCentered = this.horizontalAlign === PopoverHorizontalAlign.Center || this.horizontalAlign === PopoverHorizontalAlign.Stretch;
const arrowTranslateX = isVertical && arrowXCentered ? targetRect.left + targetRect.width / 2 - left - popoverSize.width / 2 : 0;
const arrowTranslateY = !isVertical ? targetRect.top + targetRect.height / 2 - top - popoverSize.height / 2 : 0;
let arrowPos = this.getArrowPosition(targetRect, popoverSize, left, isVertical);

if (this._left === undefined || Math.abs(this._left - left) > 1.5) {
this._left = Math.round(left);
Expand All @@ -555,14 +551,50 @@ class Popover extends Popup {
}

return {
arrowX: Math.round(arrowTranslateX),
arrowY: Math.round(arrowTranslateY),
arrowX: arrowPos.x,
arrowY: arrowPos.y,
top: this._top,
left: this._left,
placementType,
};
}

/**
* Calculates the position for the arrow.
* @private
* @param targetRect BoundingClientRect of the target element
* @param popoverSize Width and height of the popover
* @param left Left offset of the popover
* @param isVertical if the popover is positioned vertically to the target element
* @returns {{x: number, y: number}} Arrow's coordinates
*/
getArrowPosition(targetRect, popoverSize, left, isVertical) {
let arrowXCentered = this.horizontalAlign === PopoverHorizontalAlign.Center || this.horizontalAlign === PopoverHorizontalAlign.Stretch;

if (this.horizontalAlign === PopoverHorizontalAlign.Right && left <= targetRect.left) {
arrowXCentered = true;
}

if (this.horizontalAlign === PopoverHorizontalAlign.Left && left + popoverSize.width >= targetRect.left + targetRect.width) {
arrowXCentered = true;
}

let arrowTranslateX = 0;
if (isVertical && arrowXCentered) {
arrowTranslateX = targetRect.left + targetRect.width / 2 - left - popoverSize.width / 2;
}

let arrowTranslateY = 0;
if (!isVertical) {
arrowTranslateY = targetRect.top + targetRect.height / 2 - top - popoverSize.height / 2;
}

return {
x: Math.round(arrowTranslateX),
y: Math.round(arrowTranslateY),
};
}

/**
* Fallbacks to new placement, prioritizing <code>Left</code> and <code>Right</code> placements.
* @private
Expand Down
13 changes: 13 additions & 0 deletions packages/main/test/pages/Popover.html
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,15 @@
</div>
</ui5-popover>

<div style="text-align: right;">
<p>Right-aligned Popover, wider than button, arrow should be centered on the button</p>
<ui5-button id="btnOpenXRightWide">Open</ui5-button>
</div>

<ui5-popover id="popXRightWide" placement-type="Bottom" horizontal-align="Right">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Magni architecto tenetur quia nam reprehenderit quas eveniet possimus similique quisquam culpa distinctio ex doloremque molestiae maxime sed harum, in exercitationem! Incidunt?
</ui5-popover>

<br>
<br>

Expand Down Expand Up @@ -502,6 +511,10 @@
popWithDiv.openBy(event.target);
});

btnOpenXRightWide.addEventListener("click", function () {
popXRightWide.openBy(btnOpenXRightWide);
});

</script>
</body>

Expand Down