Skip to content
Draft
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
30 changes: 30 additions & 0 deletions packages/main/cypress/specs/ExpandableText.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<div style={{ height: "200px", overflow: "auto" }}>
<button id="before">before</button>
<ExpandableText text={longText} maxCharacters={maxCharacters}></ExpandableText>
</div>
);

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";

Expand Down
22 changes: 22 additions & 0 deletions packages/main/src/ExpandableText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Button, "click">) {
Expand Down
Loading