diff --git a/packages/main/cypress/specs/ExpandableText.cy.tsx b/packages/main/cypress/specs/ExpandableText.cy.tsx
index c83050b218a0..5abd96f812e7 100644
--- a/packages/main/cypress/specs/ExpandableText.cy.tsx
+++ b/packages/main/cypress/specs/ExpandableText.cy.tsx
@@ -173,6 +173,36 @@ describe("ExpandableText", () => {
.should("exist");
});
+ it("Scroll toggle link into view after expansion with long text (accessibility)", () => {
+ // Generate long text that will definitely push content below viewport
+ const longText = "This is a very long text. ".repeat(50);
+ const maxCharacters = 10;
+
+ cy.mount(
+
+
+
+
+ );
+
+ cy.get("[ui5-expandable-text]").shadow().as("expTextShadow");
+ cy.get("@expTextShadow").find(".ui5-exp-text-toggle").as("toggle");
+
+ // Focus and expand
+ cy.get("#before").focus();
+ cy.get("#before").realPress("Tab");
+
+ cy.get("@toggle")
+ .should("be.focused")
+ .realPress("Enter");
+
+ // After expansion, the toggle link (now showing "Show Less") should still be visible
+ // by checking that it's within the viewport
+ cy.get("@toggle")
+ .contains(EXPANDABLE_TEXT_SHOW_LESS.defaultText)
+ .should("be.visible");
+ });
+
it("ARIA attributes", () => {
const text = "This is a very long text that should be displayed";
diff --git a/packages/main/src/ExpandableText.ts b/packages/main/src/ExpandableText.ts
index 543b3cacf52e..c07c51e0d8d8 100644
--- a/packages/main/src/ExpandableText.ts
+++ b/packages/main/src/ExpandableText.ts
@@ -96,9 +96,26 @@ class ExpandableText extends UI5Element {
@property({ type: Boolean })
_expanded = false;
+ @property({ type: Boolean })
+ _shouldScrollIntoView = false;
+
@i18n("@ui5/webcomponents")
static i18nBundle: I18nBundle;
+ onAfterRendering() {
+ if (this._shouldScrollIntoView) {
+ this._shouldScrollIntoView = false;
+ const toggleLink = this.shadowRoot?.querySelector("[ui5-link]") as HTMLElement;
+ if (toggleLink) {
+ toggleLink.scrollIntoView({
+ behavior: "smooth",
+ block: "nearest",
+ inline: "nearest",
+ });
+ }
+ }
+ }
+
getFocusDomRef(): HTMLElement | undefined {
if (this._usePopover) {
return this.shadowRoot?.querySelector("[ui5-responsive-popover]") as HTMLElement;
@@ -168,6 +185,11 @@ class ExpandableText extends UI5Element {
_handleToggleClick() {
this._expanded = !this._expanded;
+ // Scroll the toggle link into view after expanding/collapsing, especially important
+ // when expanded content is long and pushes the "Show Less" link out of viewport
+ if (!this._usePopover) {
+ this._shouldScrollIntoView = true;
+ }
}
_handleCloseButtonClick(e: UI5CustomEvent