diff --git a/src/components/MainTable/MainTable.stories.tsx b/src/components/MainTable/MainTable.stories.tsx index 8e89c5a73..67ba5bb9a 100644 --- a/src/components/MainTable/MainTable.stories.tsx +++ b/src/components/MainTable/MainTable.stories.tsx @@ -844,6 +844,47 @@ export const Paginated: Story = { name: "Paginated", }; +/** + * Set `scrollToTop` to scroll to the top of the page when the page of a + * paginated table is changed. Scroll down to the pagination and change the + * page to see this. + */ +export const PaginatedWithScrollToTop: Story = { + args: { + headers: [ + { + content: "Machine", + }, + { + content: "Status", + }, + { + content: "Cores", + className: "u-align--right", + }, + ], + paginate: 25, + rows: Array.from({ length: 100 }, (_, index) => ({ + columns: [ + { + content: `machine-${index + 1}`, + role: "rowheader", + }, + { + content: ["Ready", "Deploying", "Allocated"][index % 3], + }, + { + content: (index % 8) + 1, + className: "u-align--right", + }, + ], + })), + scrollToTop: true, + }, + + name: "Paginated with scroll to top", +}; + export const Empty: Story = { render: () => ( { expect(screen.getAllByRole("rowheader")[0].textContent).toEqual("Idle"); }); + it("can scroll to the top when changing the page", async () => { + const scrollTo = jest + .spyOn(window, "scrollTo") + .mockImplementation(() => undefined); + render(); + await userEvent.click( + screen.getByRole("button", { name: PaginationButtonLabel.Next }), + ); + expect(scrollTo).toHaveBeenCalledWith(0, 0); + scrollTo.mockRestore(); + }); + + it("does not scroll to the top when changing the page by default", async () => { + const scrollTo = jest + .spyOn(window, "scrollTo") + .mockImplementation(() => undefined); + render(); + await userEvent.click( + screen.getByRole("button", { name: PaginationButtonLabel.Next }), + ); + expect(scrollTo).not.toHaveBeenCalled(); + scrollTo.mockRestore(); + }); + describe("sorting", () => { beforeEach(() => { headers[0].sortKey = "status"; diff --git a/src/components/MainTable/MainTable.tsx b/src/components/MainTable/MainTable.tsx index a4f417f66..4963a5b3e 100644 --- a/src/components/MainTable/MainTable.tsx +++ b/src/components/MainTable/MainTable.tsx @@ -106,6 +106,11 @@ export type Props = PropsWithSpread< * The rows to display in the table. */ rows?: MainTableRow[]; + /** + * Whether to scroll to the top of the page when the page of a paginated + * table is changed. + */ + scrollToTop?: boolean; /** * Whether this table should be sortable. */ @@ -298,6 +303,7 @@ const MainTable = ({ paginate, rows, responsive, + scrollToTop, sortable, sortFunction, hiddenCaption, @@ -392,6 +398,7 @@ const MainTable = ({ currentPage={currentPage} itemsPerPage={paginate} paginate={setCurrentPage} + scrollToTop={scrollToTop} style={{ marginTop: "1rem" }} totalItems={rows.length} />