Skip to content

Commit 1cb9dcd

Browse files
committed
fix(ui5-list): growing with scroll improved
1 parent b392d46 commit 1cb9dcd

File tree

3 files changed

+215
-107
lines changed

3 files changed

+215
-107
lines changed

packages/main/cypress/specs/List.cy.tsx

Lines changed: 154 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,17 @@ import Select from "../../src/Select.js";
1313
import Option from "../../src/Option.js";
1414
import CheckBox from "../../src/CheckBox.js";
1515

16-
describe("List Tests", () => {
17-
it("tests 'loadMore' event fired upon infinite scroll", () => {
18-
cy.mount(
19-
<List style="height: 300px;" growing="Scroll">
20-
<ListItemStandard>Laptop Lenovo</ListItemStandard>
21-
<ListItemStandard>IPhone 3</ListItemStandard>
22-
<ListItemStandard>HP Monitor 24</ListItemStandard>
23-
<ListItemStandard>Audio cabel</ListItemStandard>
24-
<ListItemStandard>DVD set</ListItemStandard>
25-
<ListItemStandard>HP Monitor 24</ListItemStandard>
26-
<ListItemStandard>Audio cabel</ListItemStandard>
27-
<ListItemStandard id="lastItem">Last Item</ListItemStandard>
28-
</List>);
29-
30-
cy.get("[ui5-list]")
31-
.as("list");
32-
33-
cy.get<List>("@list")
34-
.then(list => {
35-
list.get(0)?.addEventListener("ui5-load-more", cy.stub().as("loadMore"));
36-
})
37-
.shadow()
38-
.find(".ui5-list-scroll-container")
39-
.as("scrollContainer")
40-
.scrollTo("bottom", { duration: 100 });
41-
42-
cy.get("@loadMore")
43-
.should("have.been.calledOnce");
44-
});
16+
function getGrowingWithScrollList(length: number, height: string = "100px") {
17+
return (
18+
<List growing="Scroll" style={{ height }}>
19+
{Array.from({ length }, (_, index) => (
20+
<ListItemStandard key={index}>Item {index + 1}</ListItemStandard>
21+
))}
22+
</List>
23+
);
24+
}
4525

26+
describe("List Tests", () => {
4627
it("Arrow down and up navigation between last item and growing button", () => {
4728
cy.mount(
4829
<List growing="Button">
@@ -193,6 +174,150 @@ describe("List Tests", () => {
193174
});
194175
});
195176

177+
describe("List - Growing with scroll", () => {
178+
it("tests 'loadMore' event not fired initially when the list did not overflow", () => {
179+
cy.mount(
180+
<div>
181+
<input value="0" />
182+
<List growing="Scroll">
183+
<ListItemGroup headerText="New Items" />
184+
</List>
185+
</div>
186+
);
187+
188+
cy.get("input").should("have.value", "0");
189+
});
190+
it("tests start marker is present in DOM", () => {
191+
cy.mount(getGrowingWithScrollList(5));
192+
cy.get("[ui5-list]")
193+
.shadow()
194+
.find(".ui5-list-start-marker")
195+
.should("exist")
196+
.should("have.attr", "tabindex", "-1")
197+
.should("have.attr", "aria-hidden", "true");
198+
});
199+
200+
it("tests end marker is present in DOM", () => {
201+
cy.mount(getGrowingWithScrollList(5));
202+
cy.get("[ui5-list]")
203+
.shadow()
204+
.find(".ui5-list-end-marker")
205+
.should("exist")
206+
.should("have.attr", "tabindex", "-1")
207+
.should("have.attr", "aria-hidden", "true");
208+
});
209+
210+
it("End marker has correct CSS properties", () => {
211+
cy.mount(getGrowingWithScrollList(5));
212+
cy.get("[ui5-list]")
213+
.shadow()
214+
.find(".ui5-list-end-marker")
215+
.should("have.css", "display", "inline-block");
216+
});
217+
218+
it("tests start marker observation works when scrolled", () => {
219+
cy.mount(getGrowingWithScrollList(5));
220+
cy.get("[ui5-list]").as("list");
221+
222+
// Initially, start marker should be in view, so _startMarkerOutOfView should be false
223+
cy.get<List>("@list")
224+
.should(($el) => {
225+
const list = $el.get(0);
226+
expect(list._startMarkerOutOfView).to.be.false;
227+
});
228+
229+
// Scroll down so start marker goes out of view
230+
cy.get("@list")
231+
.shadow()
232+
.find(".ui5-list-scroll-container")
233+
.scrollTo(0, 200, { duration: 100 });
234+
235+
cy.get<List>("@list")
236+
.should(($el) => {
237+
const list = $el.get(0);
238+
expect(list._startMarkerOutOfView).to.be.true;
239+
});
240+
});
241+
242+
it("tests end marker observation works when scrolled to bottom as load-more is being fired", () => {
243+
cy.mount(getGrowingWithScrollList(5));
244+
cy.get("[ui5-list]").as("list");
245+
246+
cy.get<List>("@list")
247+
.then(list => {
248+
list.get(0)?.addEventListener("ui5-load-more", cy.stub().as("loadMore"));
249+
});
250+
251+
// Scroll to bottom so end marker becomes visible
252+
cy.get("@list")
253+
.shadow()
254+
.find(".ui5-list-scroll-container")
255+
.scrollTo("bottom", { duration: 100 });
256+
257+
// The load-more event should be fired when end marker becomes visible
258+
// (assuming start marker is also out of view due to scrolling)
259+
cy.get("@loadMore")
260+
.should("have.been.called");
261+
});
262+
263+
it("tests rerender/content change does not fire load-more event if conditions are met", () => {
264+
cy.mount(
265+
<div style="height: 6rem; overflow: auto; border: 1px solid black">
266+
{getGrowingWithScrollList(5, "")}
267+
</div>
268+
);
269+
270+
cy.get("[ui5-list]").as("list");
271+
272+
cy.get<List>("@list")
273+
.then(list => {
274+
list.get(0)?.addEventListener("ui5-load-more", cy.stub().as("loadMore"));
275+
});
276+
277+
// Scroll the container to bottom to meet the conditions
278+
cy.get("@list")
279+
.parent()
280+
.scrollTo("bottom", { duration: 100 });
281+
282+
cy.get("@loadMore").invoke("resetHistory");
283+
284+
// Simulate rerender by replacing content
285+
cy.get<List>("@list")
286+
.then(($list) => {
287+
$list[0].innerHTML = '<ui5-li>New Item</ui5-li>';
288+
});
289+
290+
cy.get("@loadMore")
291+
.should("not.have.been.called");
292+
});
293+
294+
it("tests load-more event fires when the scrollable container is a parent element", () => {
295+
cy.mount(
296+
<div id="scrollable-container" style="height: 150px; overflow-y: auto;">
297+
<List growing="Scroll">
298+
{getGrowingWithScrollList(5, "")}
299+
</List>
300+
</div>
301+
);
302+
303+
cy.get("[ui5-list]").as("list");
304+
305+
// Set up load-more event listener
306+
cy.get<List>("@list")
307+
.then(list => {
308+
list.get(0)?.addEventListener("ui5-load-more", cy.stub().as("loadMore"));
309+
});
310+
311+
// Scroll the parent container (not the list itself) to bottom
312+
cy.get("#scrollable-container")
313+
.scrollTo("bottom", { duration: 100 });
314+
315+
// The load-more event should still fire because intersection observers use viewport
316+
cy.get("@loadMore")
317+
.should("have.been.called");
318+
});
319+
});
320+
196321
describe("List - Accessibility", () => {
197322
it("tests active state announcement", () => {
198323
cy.mount(
@@ -1180,19 +1305,6 @@ describe("List Tests", () => {
11801305
cy.get("[ui5-li]").first().should("be.focused");
11811306
});
11821307

1183-
it("tests 'loadMore' event not fired initially when the list did not overflow", () => {
1184-
cy.mount(
1185-
<div>
1186-
<input value="0" />
1187-
<List growing="Scroll">
1188-
<ListItemGroup headerText="New Items" />
1189-
</List>
1190-
</div>
1191-
);
1192-
1193-
cy.get("input").should("have.value", "0");
1194-
});
1195-
11961308
it("detailPress event is fired", () => {
11971309
cy.mount(
11981310
<div>
@@ -1638,26 +1750,6 @@ describe("List Tests", () => {
16381750
.should("have.attr", "tabindex", "0");
16391751
});
16401752

1641-
it("End marker has correct CSS properties", () => {
1642-
cy.mount(
1643-
<List growing="Scroll">
1644-
<ListItemStandard>Laptop Lenovo</ListItemStandard>
1645-
<ListItemStandard>IPhone 3</ListItemStandard>
1646-
<ListItemStandard>HP Monitor 24</ListItemStandard>
1647-
<ListItemStandard>Audio cabel</ListItemStandard>
1648-
<ListItemStandard>DVD set</ListItemStandard>
1649-
<ListItemStandard>HP Monitor 24</ListItemStandard>
1650-
<ListItemStandard>Audio cabel</ListItemStandard>
1651-
<ListItemStandard>Last Item</ListItemStandard>
1652-
</List>
1653-
);
1654-
1655-
cy.get("[ui5-list]")
1656-
.shadow()
1657-
.find(".ui5-list-end-marker")
1658-
.should("have.css", "display", "inline-block");
1659-
});
1660-
16611753
it("Checks if tooltip property value equals the title of li element", () => {
16621754
cy.mount(
16631755
<List headerText="API: ListItem tooltip">

0 commit comments

Comments
 (0)