diff --git a/packages/main/src/Popover.ts b/packages/main/src/Popover.ts index 3bf539c5c7b0..c51c5ce73525 100644 --- a/packages/main/src/Popover.ts +++ b/packages/main/src/Popover.ts @@ -502,7 +502,7 @@ class Popover extends Popup { * @private */ calcPlacement(targetRect: DOMRect, popoverSize: PopoverSize): CalculatedPlacement { - let left = 0; + let left = Popover.VIEWPORT_MARGIN; let top = 0; const allowTargetOverlap = this.allowTargetOverlap; @@ -570,10 +570,10 @@ class Popover extends Popup { // correct popover positions if (isVertical) { - if (popoverSize.width > clientWidth || left < 0) { - left = 0; - } else if (left + popoverSize.width > clientWidth) { - left -= left + popoverSize.width - clientWidth; + if (popoverSize.width > clientWidth || left < Popover.VIEWPORT_MARGIN) { + left = Popover.VIEWPORT_MARGIN; + } else if (left + popoverSize.width > clientWidth - Popover.VIEWPORT_MARGIN) { + left = clientWidth - Popover.VIEWPORT_MARGIN - popoverSize.width; } } else { if (popoverSize.height > clientHeight || top < 0) { // eslint-disable-line @@ -719,7 +719,7 @@ class Popover extends Popup { getVerticalLeft(targetRect: DOMRect, popoverSize: PopoverSize): number { const horizontalAlign = this._actualHorizontalAlign; - let left = 0; + let left = Popover.VIEWPORT_MARGIN; switch (horizontalAlign) { case PopoverHorizontalAlign.Center: diff --git a/packages/main/test/pages/Popover.html b/packages/main/test/pages/Popover.html index 309fe468e07d..c4e9eae4f4cd 100644 --- a/packages/main/test/pages/Popover.html +++ b/packages/main/test/pages/Popover.html @@ -212,20 +212,20 @@
placement-type="Right" (default)

No space on the Right, try Left, Bottom, Top

- Click me ! + Click me ! Click me !

placement-type="Right" (default) and allow-target-overlap=true

No space on the right, try Left, Bottom, Top and if nothing works, the target will be overlapped

- Click me ! + Click me ! Click me !

placement-type="Left"

No space on the Left, try Right, Bottom, Top

- Click me ! + Click me !
Click me !
@@ -233,8 +233,8 @@

placement-type="Left" and allow-target-overlap=true -

No space on the right, try Roght, Bottom, Top and if nothing works, the target will be overlapped

- Click me ! +

No space on the right, try Right, Bottom, Top and if nothing works, the target will be overlapped

+ Click me !
Click me !
@@ -242,12 +242,20 @@

placement-type="Top" - Click me ! + Click me ! +
+ ... + ... +


placement-type="Bottom" - Click me ! + Click me ! +
+ ... + ... +
@@ -575,12 +583,16 @@

Horizontal Align

popFullWidthLeftTargetOverlap.showAt(btnNormalWidthLeftTargetOverlap); }); - btnFullWidthTop.addEventListener("click", function (event) { - popFullWidthTop.showAt(btnFullWidthTop); + [btnFullWidthTop, btnLeftEdgeTop, btnRightEdgeTop].forEach((el) => { + el.addEventListener("click", function (event) { + popFullWidthTop.showAt(el); + }); }); - btnFullWidthBottom.addEventListener("click", function (event) { - popFullWidthBottom.showAt(btnFullWidthBottom); + [btnFullWidthBottom, btnLeftEdgeBottom, btnRightEdgeBottom].forEach((el) => { + el.addEventListener("click", function (event) { + popFullWidthBottom.showAt(el); + }); }); btnQuickViewCardOpener.addEventListener("click", function (event) { diff --git a/packages/main/test/pages/styles/Popover.css b/packages/main/test/pages/styles/Popover.css index 8e8f5905a66a..f6a94b40b1dd 100644 --- a/packages/main/test/pages/styles/Popover.css +++ b/packages/main/test/pages/styles/Popover.css @@ -32,7 +32,7 @@ ui5-date-picker, width: 300px } -.popover7auto { +.fullWidth { width: 100% } @@ -73,3 +73,9 @@ ui5-date-picker, position: relative; z-index: 1; } + +.flexContainerSpaceBetween { + display: flex; + justify-content: space-between; +} + diff --git a/packages/main/test/specs/Popover.spec.js b/packages/main/test/specs/Popover.spec.js index 1bd402356f7e..83459ce293a4 100644 --- a/packages/main/test/specs/Popover.spec.js +++ b/packages/main/test/specs/Popover.spec.js @@ -421,26 +421,22 @@ describe("Acc", () => { }); }); -describe("Horizontal Alignment", () => { - before(async () => { - await browser.url(`test/pages/Popover.html`); - }); - +describe("Alignment", () => { const EPS = 2; // 2px - const isHorizontallyCentered = async (popover, opener) => { - const popoverRect = { - ...await popover.getLocation(), - ...await popover.getSize() + const isHorizontallyCentered = async (element, opener) => { + const elemRect = { + ...await element.getLocation(), + ...await element.getSize() }; const openerRect = { ...await opener.getLocation(), ...await opener.getSize() }; const openerCenter = openerRect.x + openerRect.width / 2; - const expectedPopoverLeft = openerCenter - popoverRect.width / 2; + const expectedElemX = openerCenter - elemRect.width / 2; - return Math.abs(popoverRect.x - expectedPopoverLeft) < EPS; + return Math.abs(elemRect.x - expectedElemX) < EPS; } const isHorizontallyLeftAligned = async (popover, opener) => { @@ -471,59 +467,104 @@ describe("Horizontal Alignment", () => { return Math.abs(openerRight - popoverRight) < EPS; } - it("Center", async () => { - await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Center']").click(); - await browser.$("#horizontalAlignBtn").click(); - const popover = await browser.$("#popoverHorizontalAlign"); - const opener = await browser.$("#targetOpener"); + describe("Horizontal Alignment", () => { + before(async () => { + await browser.url(`test/pages/Popover.html`); + }); - assert.ok(await isHorizontallyCentered(popover, opener), `Popover should be centered`); - }); + it("Center", async () => { + await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Center']").click(); + await browser.$("#horizontalAlignBtn").click(); + const popover = await browser.$("#popoverHorizontalAlign"); + const opener = await browser.$("#targetOpener"); - it("Left", async () => { - await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Left']").click(); - await browser.$("#horizontalAlignBtn").click(); - const popover = await browser.$("#popoverHorizontalAlign"); - const opener = await browser.$("#targetOpener"); + assert.ok(await isHorizontallyCentered(popover, opener), `Popover should be centered`); + }); - assert.ok(await isHorizontallyLeftAligned(popover, opener), `Popover should be left aligned`); - }); + it("Left", async () => { + await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Left']").click(); + await browser.$("#horizontalAlignBtn").click(); + const popover = await browser.$("#popoverHorizontalAlign"); + const opener = await browser.$("#targetOpener"); - it("Right", async () => { - await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Right']").click(); - await browser.$("#horizontalAlignBtn").click(); - const popover = await browser.$("#popoverHorizontalAlign"); - const opener = await browser.$("#targetOpener"); + assert.ok(await isHorizontallyLeftAligned(popover, opener), `Popover should be left aligned`); + }); - assert.ok(await isHorizontallyRightAligned(popover, opener), `Popover should be right aligned`); - }); + it("Right", async () => { + await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Right']").click(); + await browser.$("#horizontalAlignBtn").click(); + const popover = await browser.$("#popoverHorizontalAlign"); + const opener = await browser.$("#targetOpener"); - it("Center, in RTL", async () => { - await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Center']").click(); - await browser.$("#rtlCb").click(); - await browser.$("#horizontalAlignBtn").click(); - const popover = await browser.$("#popoverHorizontalAlign"); - const opener = await browser.$("#targetOpener"); + assert.ok(await isHorizontallyRightAligned(popover, opener), `Popover should be right aligned`); + }); - assert.ok(await isHorizontallyCentered(popover, opener), `Popover should be centered`); - }); + it("Center, in RTL", async () => { + await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Center']").click(); + await browser.$("#rtlCb").click(); + await browser.$("#horizontalAlignBtn").click(); + const popover = await browser.$("#popoverHorizontalAlign"); + const opener = await browser.$("#targetOpener"); + + assert.ok(await isHorizontallyCentered(popover, opener), `Popover should be centered`); + }); - it("Left, in RTL", async () => { - await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Left']").click(); - await browser.$("#horizontalAlignBtn").click(); - const popover = await browser.$("#popoverHorizontalAlign"); - const opener = await browser.$("#targetOpener"); + it("Left, in RTL", async () => { + await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Left']").click(); + await browser.$("#horizontalAlignBtn").click(); + const popover = await browser.$("#popoverHorizontalAlign"); + const opener = await browser.$("#targetOpener"); - assert.ok(isHorizontallyRightAligned(popover, opener), `Popover should be right aligned, flipped by RTL direction`); + assert.ok(isHorizontallyRightAligned(popover, opener), `Popover should be right aligned, flipped by RTL direction`); + }); + + it("Right, in RTL", async () => { + await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Right']").click(); + await browser.$("#horizontalAlignBtn").click(); + const popover = await browser.$("#popoverHorizontalAlign"); + const opener = await browser.$("#targetOpener"); + + assert.ok(await isHorizontallyLeftAligned(popover, opener), `Popover should be left aligned, flipped by RTL direction`); + }); }); - it("Right, in RTL", async () => { - await browser.$("[ui5-radio-button][name='horizontalAlign'][text='Right']").click(); - await browser.$("#horizontalAlignBtn").click(); - const popover = await browser.$("#popoverHorizontalAlign"); - const opener = await browser.$("#targetOpener"); + describe("Arrow Horizontal Alignment", () => { + before(async () => { + await browser.url(`test/pages/Popover.html`); + }); + + it("Arrow centering when opener has big width", async () => { + const opener = await browser.$("#btnFullWidthTop"); + await opener.click(); + const popover = await browser.$("#popFullWidthTop"); + const arrow = await popover.shadow$(".ui5-popover-arrow"); + + assert.ok(await isHorizontallyCentered(arrow, opener), `Arrow should be centered`); + + await browser.keys("Escape"); + }); + + it("Arrow centering when opener is to the left edge", async () => { + const opener = await browser.$("#btnLeftEdgeTop"); + await opener.click(); + const popover = await browser.$("#popFullWidthTop"); + const arrow = await popover.shadow$(".ui5-popover-arrow"); + + assert.ok(await isHorizontallyCentered(arrow, opener), `Arrow should be centered`); + + await browser.keys("Escape"); + }); + + it("Arrow centering when opener is to the right edge", async () => { + const opener = await browser.$("#btnRightEdgeTop"); + await opener.click(); + const popover = await browser.$("#popFullWidthTop"); + const arrow = await popover.shadow$(".ui5-popover-arrow"); - assert.ok(await isHorizontallyLeftAligned(popover, opener), `Popover should be left aligned, flipped by RTL direction`); + assert.ok(await isHorizontallyCentered(arrow, opener), `Arrow should be centered`); + + await browser.keys("Escape"); + }); }); });