diff --git a/packages/fiori/src/ShellBar.ts b/packages/fiori/src/ShellBar.ts
index a4c5e624029c..0107f9dc97e7 100644
--- a/packages/fiori/src/ShellBar.ts
+++ b/packages/fiori/src/ShellBar.ts
@@ -41,7 +41,6 @@ import type {
UI5CustomEvent,
} from "@ui5/webcomponents-base";
import type ListItemBase from "@ui5/webcomponents/dist/ListItemBase.js";
-import type PopoverHorizontalAlign from "@ui5/webcomponents/dist/types/PopoverHorizontalAlign.js";
import throttle from "@ui5/webcomponents-base/dist/util/throttle.js";
import { getScopedVarName } from "@ui5/webcomponents-base/dist/CustomElementsScope.js";
import getActiveElement from "@ui5/webcomponents-base/dist/util/getActiveElement.js";
@@ -1524,10 +1523,6 @@ class ShellBar extends UI5Element {
return this.primaryTitle || this.showLogoInMenuButton;
}
- get popoverHorizontalAlign(): `${PopoverHorizontalAlign}` {
- return this.effectiveDir === "rtl" ? "Start" : "End";
- }
-
get hasAssistant() {
return !!this.assistant.length;
}
diff --git a/packages/fiori/src/ShellBarPopoverTemplate.tsx b/packages/fiori/src/ShellBarPopoverTemplate.tsx
index b32f7491d225..f523ef439460 100644
--- a/packages/fiori/src/ShellBarPopoverTemplate.tsx
+++ b/packages/fiori/src/ShellBarPopoverTemplate.tsx
@@ -1,5 +1,6 @@
import Popover from "@ui5/webcomponents/dist/Popover.js";
import List from "@ui5/webcomponents/dist/List.js";
+import PopoverHorizontalAlign from "@ui5/webcomponents/dist/types/PopoverHorizontalAlign.js";
import ListItemStandard from "@ui5/webcomponents/dist/ListItemStandard.js";
import type ShellBar from "./ShellBar.js";
@@ -21,7 +22,7 @@ export default function PopoversTemplate(this: ShellBar) {
{
);
-
+
cy.get("[ui5-popover]").invoke("removeAttr", "accessible-name");
-
+
cy.get("[ui5-popover]")
.shadow()
.find(".ui5-popup-root")
.should("have.attr", "aria-labelledby");
-
+
cy.get("[ui5-popover]")
.shadow()
.find(".ui5-popup-root")
.should("not.have.attr", "aria-label");
});
-
+
it("should use aria-label when accessible-name attribute is set dynamically", () => {
cy.mount(
);
-
+
cy.get("[ui5-popover]").invoke("attr", "accessible-name", "text");
-
+
cy.get("[ui5-popover]")
.shadow()
.find(".ui5-popup-root")
.should("not.have.attr", "aria-labelledby");
-
+
cy.get("[ui5-popover]")
.shadow()
.find(".ui5-popup-root")
.should("have.attr", "aria-label");
});
-
+
it("tests accessible-name-ref", () => {
cy.mount(
@@ -652,25 +652,25 @@ describe("Popover opener", () => {
>
);
-
+
cy.get("#first-focusable").should("be.focused");
-
+
cy.realPress("Tab");
cy.wait(500);
cy.get("#li1").should("be.focused");
cy.get("#first-focusable").should("not.be.focused");
-
+
cy.realPress("Tab");
-
+
cy.get("#first-focusable").should("be.focused");
-
+
cy.realPress("Tab");
cy.realPress("Tab");
-
+
cy.get("#first-focusable").should("be.focused");
-
+
cy.realPress("Escape");
-
+
cy.get("[ui5-popover]").should("not.be.visible");
});
@@ -967,7 +967,7 @@ describe("Popover opener", () => {
pop.addEventListener("ui5-before-open", async () => {
const applyFocusResult = pop.applyFocus();
- pop.remove();
+ pop.remove();
try {
await applyFocusResult;
@@ -1020,31 +1020,31 @@ describe("Popover opener", () => {
const container = document.createElement("div");
container.id = "container";
root[0].appendChild(container);
-
+
const shadowRoot = container.attachShadow({ mode: "open" });
-
+
const opener = document.createElement("ui5-button");
opener.setAttribute("id", "lnk");
opener.textContent = "Open Popover";
shadowRoot.appendChild(opener);
-
+
const popover = document.createElement("ui5-popover");
popover.setAttribute("id", "pop");
popover.setAttribute("header-text", "Popover in Shadow Root");
popover.setAttribute("opener", "lnk");
-
+
const content = document.createElement("div");
content.textContent = "Popover content";
popover.appendChild(content);
-
+
shadowRoot.appendChild(popover);
});
-
+
cy.get("#container")
.shadow()
.find("#lnk")
.realClick();
-
+
cy.get("#container")
.shadow()
.find("#pop")
@@ -1053,7 +1053,7 @@ describe("Popover opener", () => {
cy.get("#container").then(container => {
container.remove();
});
- });
+ });
it("tests opener set as ID in window.document, while popover is in a shadow root", () => {
cy.mount(
@@ -1421,6 +1421,82 @@ describe("Placement", () => {
expect(top).to.be.lt(100)
});
});
+
+ it("placement=Start in RTL", () => {
+ cy.mount(
+
+
+
+
+ Popover with Start placement in RTL mode
+
+
+
+ );
+
+ cy.get("[ui5-popover]").invoke("prop", "open", true);
+
+ cy.get("[ui5-popover]").should("be.visible");
+
+ // wait for the popover to be positioned
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
+ cy.wait(200);
+
+ let popover;
+ cy.get('[ui5-popover]')
+ .then($popover => {
+ popover = $popover;
+ });
+
+ cy.get('#btnStart').should($opener => {
+ const popoverRect = popover[0].getBoundingClientRect();
+ const openerRect = $opener[0].getBoundingClientRect();
+
+ // In RTL mode, Start placement should position popover to the right of the opener
+ expect(popoverRect.left).to.be.greaterThan(openerRect.right - 5);
+ });
+ });
+
+ it("placement=End in RTL", () => {
+ cy.mount(
+
+
+
+
+ Popover with End placement in RTL mode
+
+
+
+ );
+
+ cy.get("[ui5-popover]").invoke("prop", "open", true);
+
+ cy.get("[ui5-popover]").should("be.visible");
+
+ // wait for the popover to be positioned
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
+ cy.wait(200);
+
+ let popover;
+ cy.get('[ui5-popover]')
+ .then($popover => {
+ popover = $popover;
+ });
+
+ cy.get('#btnEnd').should($opener => {
+ const popoverRect = popover[0].getBoundingClientRect();
+ const openerRect = $opener[0].getBoundingClientRect();
+
+ // In RTL mode, End placement should position popover to the left of the opener
+ expect(popoverRect.right).to.be.lessThan(openerRect.left + 5);
+ });
+ });
});
describe("Alignment", () => {
diff --git a/packages/main/src/ComboBox.ts b/packages/main/src/ComboBox.ts
index 418692326425..22fb72924d70 100644
--- a/packages/main/src/ComboBox.ts
+++ b/packages/main/src/ComboBox.ts
@@ -87,7 +87,6 @@ import "./ComboBoxItemGroup.js";
// eslint-disable-next-line
import { isInstanceOfComboBoxItemGroup } from "./ComboBoxItemGroup.js";
import type ComboBoxFilter from "./types/ComboBoxFilter.js";
-import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js";
import type Input from "./Input.js";
import type { InputEventDetail } from "./Input.js";
import type InputComposition from "./features/InputComposition.js";
@@ -1479,10 +1478,6 @@ class ComboBox extends UI5Element implements IFormInputElement {
return !this.valueStateMessage.length && this.hasValueStateText;
}
- get _valueStatePopoverHorizontalAlign(): `${PopoverHorizontalAlign}` {
- return this.effectiveDir !== "rtl" ? PopoverHorizontalAlign.Start : PopoverHorizontalAlign.End;
- }
-
/**
* This method is relevant for sap_horizon theme only
*/
diff --git a/packages/main/src/ComboBoxPopoverTemplate.tsx b/packages/main/src/ComboBoxPopoverTemplate.tsx
index 30ed7bbdc4ac..77a483304361 100644
--- a/packages/main/src/ComboBoxPopoverTemplate.tsx
+++ b/packages/main/src/ComboBoxPopoverTemplate.tsx
@@ -2,6 +2,7 @@ import Icon from "./Icon.js";
import Button from "./Button.js";
import List from "./List.js";
import Input from "./Input.js";
+import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js";
import Popover from "./Popover.js";
import ResponsivePopover from "./ResponsivePopover.js";
import BusyIndicator from "./BusyIndicator.js";
@@ -116,7 +117,7 @@ export default function ComboBoxPopoverTemplate(this: ComboBox) {
hideArrow={true}
tabindex={-1}
class="ui5-valuestatemessage-popover"
- horizontalAlign={this._valueStatePopoverHorizontalAlign}
+ horizontalAlign={PopoverHorizontalAlign.Start}
placement="Bottom"
opener={this}
open={this.valueStateOpen}
diff --git a/packages/main/src/Input.ts b/packages/main/src/Input.ts
index 08da1a4eaa1b..0b45e9194712 100644
--- a/packages/main/src/Input.ts
+++ b/packages/main/src/Input.ts
@@ -62,7 +62,7 @@ import InputType from "./types/InputType.js";
import type Popover from "./Popover.js";
import type Icon from "./Icon.js";
import type { IIcon } from "./Icon.js";
-import type PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js";
+
// Templates
import InputTemplate from "./InputTemplate.js";
import { StartsWith } from "./Filters.js";
@@ -1969,10 +1969,6 @@ class Input extends UI5Element implements SuggestionComponent, IFormInputElement
return "";
}
- get _valueStatePopoverHorizontalAlign(): `${PopoverHorizontalAlign}` {
- return this.effectiveDir !== "rtl" ? "Start" : "End";
- }
-
/**
* This method is relevant for sap_horizon theme only
*/
diff --git a/packages/main/src/InputPopoverTemplate.tsx b/packages/main/src/InputPopoverTemplate.tsx
index a1f23e7fab64..1b0fc9534dda 100644
--- a/packages/main/src/InputPopoverTemplate.tsx
+++ b/packages/main/src/InputPopoverTemplate.tsx
@@ -6,6 +6,7 @@ import alert from "@ui5/webcomponents-icons/dist/alert.js";
import sysEnter2 from "@ui5/webcomponents-icons/dist/sys-enter-2.js";
import information from "@ui5/webcomponents-icons/dist/information.js";
+import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js";
import Popover from "./Popover.js";
import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js";
@@ -24,7 +25,7 @@ export default function InputPopoverTemplate(this: Input, hooks?: { suggestionsL
class="ui5-valuestatemessage-popover"
placement="Bottom"
tabindex={-1}
- horizontalAlign={this._valueStatePopoverHorizontalAlign}
+ horizontalAlign={PopoverHorizontalAlign.Start}
opener={this}
open={this.valueStateOpen}
onClose={this._handleValueStatePopoverAfterClose}
diff --git a/packages/main/src/MenuItem.ts b/packages/main/src/MenuItem.ts
index 14937aa7de71..a73787cfb80c 100644
--- a/packages/main/src/MenuItem.ts
+++ b/packages/main/src/MenuItem.ts
@@ -30,7 +30,6 @@ import type { ListItemAccessibilityAttributes } from "./ListItem.js";
import type List from "./List.js";
import ListItem from "./ListItem.js";
import type ResponsivePopover from "./ResponsivePopover.js";
-import type PopoverPlacement from "./types/PopoverPlacement.js";
import { isInstanceOfMenuSeparator } from "./MenuSeparator.js";
import { isInstanceOfMenuItemGroup } from "./MenuItemGroup.js";
import MenuItemTemplate from "./MenuItemTemplate.js";
@@ -357,10 +356,6 @@ class MenuItem extends ListItem implements IMenuItem {
}
}
- get placement(): `${PopoverPlacement}` {
- return this.isRtl ? "Start" : "End";
- }
-
get isRtl() {
return this.effectiveDir === "rtl";
}
diff --git a/packages/main/src/MenuItemTemplate.tsx b/packages/main/src/MenuItemTemplate.tsx
index 47046eacdd0f..1d5cd262d070 100644
--- a/packages/main/src/MenuItemTemplate.tsx
+++ b/packages/main/src/MenuItemTemplate.tsx
@@ -1,4 +1,5 @@
import type MenuItem from "./MenuItem.js";
+import PopoverPlacement from "./types/PopoverPlacement.js";
import ResponsivePopover from "./ResponsivePopover.js";
import Button from "./Button.js";
import List from "./List.js";
@@ -91,7 +92,7 @@ function listItemPostContent(this: MenuItem) {
preventFocusRestore={true}
hideArrow={true}
allowTargetOverlap={true}
- placement={this.placement}
+ placement={PopoverPlacement.End}
verticalAlign="Top"
accessibleName={this.accessibleNameText}
onBeforeOpen={this._beforePopoverOpen}
diff --git a/packages/main/src/MultiComboBox.ts b/packages/main/src/MultiComboBox.ts
index 15fb35bf27a7..c941d6eaf633 100644
--- a/packages/main/src/MultiComboBox.ts
+++ b/packages/main/src/MultiComboBox.ts
@@ -112,7 +112,6 @@ import type ComboBoxFilter from "./types/ComboBoxFilter.js";
import CheckBox from "./CheckBox.js";
import Input from "./Input.js";
import type { InputEventDetail } from "./Input.js";
-import type PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js";
import SuggestionItem from "./SuggestionItem.js";
import type InputComposition from "./features/InputComposition.js";
@@ -2199,10 +2198,6 @@ class MultiComboBox extends UI5Element implements IFormInputElement {
return shouldBeExpanded;
}
- get _valueStatePopoverHorizontalAlign(): `${PopoverHorizontalAlign}` {
- return this.effectiveDir !== "rtl" ? "Start" : "End";
- }
-
get iconsCount() {
const slottedIconsCount = this.icon?.length || 0;
const clearIconCount = Number(this._effectiveShowClearIcon) ?? 0;
diff --git a/packages/main/src/MultiComboBoxPopoverTemplate.tsx b/packages/main/src/MultiComboBoxPopoverTemplate.tsx
index 3c0811ddc28f..52d4353fd133 100644
--- a/packages/main/src/MultiComboBoxPopoverTemplate.tsx
+++ b/packages/main/src/MultiComboBoxPopoverTemplate.tsx
@@ -7,6 +7,7 @@ import ToggleButton from "./ToggleButton.js";
import SuggestionItem from "./SuggestionItem.js";
import Icon from "./Icon.js";
import List from "./List.js";
+import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js";
import Popover from "./Popover.js";
import CheckBox from "./CheckBox.js";
@@ -114,7 +115,7 @@ export default function MultiComboBoxPopoverTemplate(this: MultiComboBox) {
hideArrow={true}
class="ui5-valuestatemessage-popover"
placement="Bottom"
- horizontalAlign={this._valueStatePopoverHorizontalAlign}
+ horizontalAlign={PopoverHorizontalAlign.Start}
tabIndex={-1}
open={this.valueStateOpen}
opener={this}
diff --git a/packages/main/src/Popover.ts b/packages/main/src/Popover.ts
index 3f10d1ea4b72..51751a3e44cb 100644
--- a/packages/main/src/Popover.ts
+++ b/packages/main/src/Popover.ts
@@ -32,11 +32,25 @@ type ArrowPosition = {
y: number;
}
+enum PopoverActualHorizontalAlign {
+ Center = "Center",
+ Left = "Left",
+ Right = "Right",
+ Stretch = "Stretch",
+}
+
+enum PopoverActualPlacement {
+ Left = "Left",
+ Right = "Right",
+ Top = "Top",
+ Bottom = "Bottom",
+}
+
type CalculatedPlacement = {
arrow: ArrowPosition,
top: number,
left: number,
- placement: `${PopoverPlacement}`,
+ actualPlacement: `${PopoverActualPlacement}`,
}
/**
@@ -166,7 +180,7 @@ class Popover extends Popup {
* @private
*/
@property()
- actualPlacement: `${PopoverPlacement}` = "End";
+ actualPlacement: `${PopoverActualPlacement}` = "Right";
@property({ type: Number, noAttribute: true })
_maxHeight?: number;
@@ -316,11 +330,11 @@ class Popover extends Popup {
return openerHTMLElement;
}
- shouldCloseDueToOverflow(placement: `${PopoverPlacement}`, openerRect: DOMRect): boolean {
+ shouldCloseDueToOverflow(placement: `${PopoverActualPlacement}`, openerRect: DOMRect): boolean {
const threshold = 32;
const limits = {
- "Start": openerRect.right,
- "End": openerRect.left,
+ "Left": openerRect.right,
+ "Right": openerRect.left,
"Top": openerRect.top,
"Bottom": openerRect.bottom,
};
@@ -416,7 +430,7 @@ class Popover extends Popup {
}
this._oldPlacement = placement;
- this.actualPlacement = placement.placement;
+ this.actualPlacement = placement.actualPlacement;
let left = clamp(
this._left!,
@@ -424,7 +438,7 @@ class Popover extends Popup {
document.documentElement.clientWidth - popoverSize.width - Popover.VIEWPORT_MARGIN,
);
- if (this.actualPlacement === PopoverPlacement.End) {
+ if (this.actualPlacement === PopoverActualPlacement.Right) {
left = Math.max(left, this._left!);
}
@@ -434,7 +448,7 @@ class Popover extends Popup {
document.documentElement.clientHeight - popoverSize.height - Popover.VIEWPORT_MARGIN,
);
- if (this.actualPlacement === PopoverPlacement.Bottom) {
+ if (this.actualPlacement === PopoverActualPlacement.Bottom) {
top = Math.max(top, this._top!);
}
@@ -532,12 +546,12 @@ class Popover extends Popup {
let maxHeight = clientHeight;
let maxWidth = clientWidth;
- const placement = this.getActualPlacement(targetRect);
+ const actualPlacement = this.getActualPlacement(targetRect);
- this._preventRepositionAndClose = this.shouldCloseDueToNoOpener(targetRect) || this.shouldCloseDueToOverflow(placement, targetRect);
+ this._preventRepositionAndClose = this.shouldCloseDueToNoOpener(targetRect) || this.shouldCloseDueToOverflow(actualPlacement, targetRect);
- const isVertical = placement === PopoverPlacement.Top
- || placement === PopoverPlacement.Bottom;
+ const isVertical = actualPlacement === PopoverActualPlacement.Top
+ || actualPlacement === PopoverActualPlacement.Bottom;
if (this.horizontalAlign === PopoverHorizontalAlign.Stretch && isVertical) {
popoverSize.width = targetRect.width;
@@ -550,8 +564,8 @@ class Popover extends Popup {
const arrowOffset = this.hideArrow ? 0 : ARROW_SIZE;
// calc popover positions
- switch (placement) {
- case PopoverPlacement.Top:
+ switch (actualPlacement) {
+ case PopoverActualPlacement.Top:
left = this.getVerticalLeft(targetRect, popoverSize);
top = Math.max(targetRect.top - popoverSize.height - arrowOffset, 0);
@@ -559,7 +573,7 @@ class Popover extends Popup {
maxHeight = targetRect.top - arrowOffset;
}
break;
- case PopoverPlacement.Bottom:
+ case PopoverActualPlacement.Bottom:
left = this.getVerticalLeft(targetRect, popoverSize);
top = targetRect.bottom + arrowOffset;
@@ -569,7 +583,7 @@ class Popover extends Popup {
maxHeight = clientHeight - targetRect.bottom - arrowOffset;
}
break;
- case PopoverPlacement.Start:
+ case PopoverActualPlacement.Left:
left = Math.max(targetRect.left - popoverSize.width - arrowOffset, 0);
top = this.getHorizontalTop(targetRect, popoverSize);
@@ -577,7 +591,7 @@ class Popover extends Popup {
maxWidth = targetRect.left - arrowOffset;
}
break;
- case PopoverPlacement.End:
+ case PopoverActualPlacement.Right:
left = targetRect.left + targetRect.width + arrowOffset;
top = this.getHorizontalTop(targetRect, popoverSize);
@@ -624,7 +638,7 @@ class Popover extends Popup {
arrow: arrowPos,
top: this._top,
left: this._left,
- placement,
+ actualPlacement,
};
}
@@ -644,14 +658,14 @@ class Popover extends Popup {
* @returns Arrow's coordinates
*/
getArrowPosition(targetRect: DOMRect, popoverSize: PopoverSize, left: number, top: number, isVertical: boolean, borderRadius: number): ArrowPosition {
- const horizontalAlign = this._actualHorizontalAlign;
- let arrowXCentered = horizontalAlign === PopoverHorizontalAlign.Center || horizontalAlign === PopoverHorizontalAlign.Stretch;
+ const actualHorizontalAlign = this._actualHorizontalAlign;
+ let arrowXCentered = actualHorizontalAlign === PopoverActualHorizontalAlign.Center || actualHorizontalAlign === PopoverActualHorizontalAlign.Stretch;
- if (horizontalAlign === PopoverHorizontalAlign.End && left <= targetRect.left) {
+ if (actualHorizontalAlign === PopoverActualHorizontalAlign.Right && left <= targetRect.left) {
arrowXCentered = true;
}
- if (horizontalAlign === PopoverHorizontalAlign.Start && left + popoverSize.width >= targetRect.left + targetRect.width) {
+ if (actualHorizontalAlign === PopoverActualHorizontalAlign.Left && left + popoverSize.width >= targetRect.left + targetRect.width) {
arrowXCentered = true;
}
@@ -691,31 +705,46 @@ class Popover extends Popup {
* Fallbacks to new placement, prioritizing `Left` and `Right` placements.
* @private
*/
- fallbackPlacement(clientWidth: number, clientHeight: number, targetRect: DOMRect, popoverSize: PopoverSize): PopoverPlacement | undefined {
+ fallbackPlacement(clientWidth: number, clientHeight: number, targetRect: DOMRect, popoverSize: PopoverSize): PopoverActualPlacement | undefined {
if (targetRect.left > popoverSize.width) {
- return PopoverPlacement.Start;
+ return PopoverActualPlacement.Left;
}
if (clientWidth - targetRect.right > targetRect.left) {
- return PopoverPlacement.End;
+ return PopoverActualPlacement.Right;
}
if (clientHeight - targetRect.bottom > popoverSize.height) {
- return PopoverPlacement.Bottom;
+ return PopoverActualPlacement.Bottom;
}
if (clientHeight - targetRect.bottom < targetRect.top) {
- return PopoverPlacement.Top;
+ return PopoverActualPlacement.Top;
}
}
- getActualPlacement(targetRect: DOMRect): `${PopoverPlacement}` {
+ getActualPlacement(targetRect: DOMRect): `${PopoverActualPlacement}` {
const placement = this.placement;
- let actualPlacement = placement;
- const isVertical = placement === PopoverPlacement.Top
- || placement === PopoverPlacement.Bottom;
+ const isVertical = placement === PopoverPlacement.Top || placement === PopoverPlacement.Bottom;
const popoverSize = this.getPopoverSize(!this.allowTargetOverlap);
+ let actualPlacement: PopoverActualPlacement = PopoverActualPlacement.Right;
+
+ switch (placement) {
+ case PopoverPlacement.Start:
+ actualPlacement = this.isRtl ? PopoverActualPlacement.Right : PopoverActualPlacement.Left;
+ break;
+ case PopoverPlacement.End:
+ actualPlacement = this.isRtl ? PopoverActualPlacement.Left : PopoverActualPlacement.Right;
+ break;
+ case PopoverPlacement.Top:
+ actualPlacement = PopoverActualPlacement.Top;
+ break;
+ case PopoverPlacement.Bottom:
+ actualPlacement = PopoverActualPlacement.Bottom;
+ break;
+ }
+
const clientWidth = document.documentElement.clientWidth;
let clientHeight = document.documentElement.clientHeight;
let popoverHeight = popoverSize.height;
@@ -725,27 +754,27 @@ class Popover extends Popup {
clientHeight -= Popover.VIEWPORT_MARGIN;
}
- switch (placement) {
- case PopoverPlacement.Top:
+ switch (actualPlacement) {
+ case PopoverActualPlacement.Top:
if (targetRect.top < popoverHeight
&& targetRect.top < clientHeight - targetRect.bottom) {
- actualPlacement = PopoverPlacement.Bottom;
+ actualPlacement = PopoverActualPlacement.Bottom;
}
break;
- case PopoverPlacement.Bottom:
+ case PopoverActualPlacement.Bottom:
if (clientHeight - targetRect.bottom < popoverHeight
&& clientHeight - targetRect.bottom < targetRect.top) {
- actualPlacement = PopoverPlacement.Top;
+ actualPlacement = PopoverActualPlacement.Top;
}
break;
- case PopoverPlacement.Start:
+ case PopoverActualPlacement.Left:
if (targetRect.left < popoverSize.width) {
- actualPlacement = this.fallbackPlacement(clientWidth, clientHeight, targetRect, popoverSize) || placement;
+ actualPlacement = this.fallbackPlacement(clientWidth, clientHeight, targetRect, popoverSize) || actualPlacement;
}
break;
- case PopoverPlacement.End:
+ case PopoverActualPlacement.Right:
if (clientWidth - targetRect.right < popoverSize.width) {
- actualPlacement = this.fallbackPlacement(clientWidth, clientHeight, targetRect, popoverSize) || placement;
+ actualPlacement = this.fallbackPlacement(clientWidth, clientHeight, targetRect, popoverSize) || actualPlacement;
}
break;
}
@@ -754,18 +783,18 @@ class Popover extends Popup {
}
getVerticalLeft(targetRect: DOMRect, popoverSize: PopoverSize): number {
- const horizontalAlign = this._actualHorizontalAlign;
+ const actualHorizontalAlign = this._actualHorizontalAlign;
let left = Popover.VIEWPORT_MARGIN;
- switch (horizontalAlign) {
- case PopoverHorizontalAlign.Center:
- case PopoverHorizontalAlign.Stretch:
+ switch (actualHorizontalAlign) {
+ case PopoverActualHorizontalAlign.Center:
+ case PopoverActualHorizontalAlign.Stretch:
left = targetRect.left - (popoverSize.width - targetRect.width) / 2;
break;
- case PopoverHorizontalAlign.Start:
+ case PopoverActualHorizontalAlign.Left:
left = targetRect.left;
break;
- case PopoverHorizontalAlign.End:
+ case PopoverActualHorizontalAlign.Right:
left = targetRect.right - popoverSize.width;
break;
}
@@ -838,18 +867,22 @@ class Popover extends Popup {
return true;
}
- get _actualHorizontalAlign() {
- if (this.effectiveDir === "rtl") {
- if (this.horizontalAlign === PopoverHorizontalAlign.Start) {
- return PopoverHorizontalAlign.End;
- }
+ get isRtl() {
+ return this.effectiveDir === "rtl";
+ }
- if (this.horizontalAlign === PopoverHorizontalAlign.End) {
- return PopoverHorizontalAlign.Start;
- }
+ get _actualHorizontalAlign() : PopoverActualHorizontalAlign {
+ switch (this.horizontalAlign) {
+ case PopoverHorizontalAlign.Start:
+ return this.isRtl ? PopoverActualHorizontalAlign.Right : PopoverActualHorizontalAlign.Left;
+ case PopoverHorizontalAlign.End:
+ return this.isRtl ? PopoverActualHorizontalAlign.Left : PopoverActualHorizontalAlign.Right;
+ case PopoverHorizontalAlign.Stretch:
+ return PopoverActualHorizontalAlign.Stretch;
+ case PopoverHorizontalAlign.Center:
+ default:
+ return PopoverActualHorizontalAlign.Center;
}
-
- return this.horizontalAlign;
}
}
diff --git a/packages/main/src/TextArea.ts b/packages/main/src/TextArea.ts
index c879b7aa0be2..01bdda9214ba 100644
--- a/packages/main/src/TextArea.ts
+++ b/packages/main/src/TextArea.ts
@@ -17,7 +17,6 @@ import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
import { isEscape } from "@ui5/webcomponents-base/dist/Keys.js";
import type { IFormInputElement } from "@ui5/webcomponents-base/dist/features/InputElementsFormSupport.js";
import type Popover from "./Popover.js";
-import type PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js";
import TextAreaTemplate from "./TextAreaTemplate.js";
@@ -658,10 +657,6 @@ class TextArea extends UI5Element implements IFormInputElement {
return this.valueState === ValueState.Negative || this.valueState === ValueState.Critical || this.valueState === ValueState.Information;
}
- get _valueStatePopoverHorizontalAlign(): `${PopoverHorizontalAlign}` {
- return this.effectiveDir !== "rtl" ? "Start" : "End";
- }
-
get valueStateTextMappings() {
return {
"Positive": TextArea.i18nBundle.getText(VALUE_STATE_SUCCESS),
diff --git a/packages/main/src/TextAreaPopoverTemplate.tsx b/packages/main/src/TextAreaPopoverTemplate.tsx
index ea829d1ebb77..a316249eb53f 100644
--- a/packages/main/src/TextAreaPopoverTemplate.tsx
+++ b/packages/main/src/TextAreaPopoverTemplate.tsx
@@ -1,4 +1,5 @@
import Icon from "./Icon.js";
+import PopoverHorizontalAlign from "./types/PopoverHorizontalAlign.js";
import Popover from "./Popover.js";
import type TextArea from "./TextArea.js";
import error from "@ui5/webcomponents-icons/dist/error.js";
@@ -25,7 +26,7 @@ export default function TextAreaPopoverTemplate(this: TextArea) {
class="ui5-valuestatemessage-popover"
style={{ "max-width": `${this._width!}px` }}
placement="Bottom"
- horizontalAlign={this._valueStatePopoverHorizontalAlign}
+ horizontalAlign={PopoverHorizontalAlign.Start}
>
Open
Popover placement End
+
+ Placement Start
+
+
+
+ Placement End
+
+
+
Email
@@ -84,6 +93,28 @@
+
+
+
+
+
+
+
+