diff --git a/src/Pagination/Pagination.story.tsx b/src/Pagination/Pagination.story.tsx index cf2f2dfd5..aee4b6b12 100644 --- a/src/Pagination/Pagination.story.tsx +++ b/src/Pagination/Pagination.story.tsx @@ -1,6 +1,10 @@ -import React from "react"; +import React, { useRef, useState } from "react"; import { action } from "@storybook/addon-actions"; import { Pagination } from "."; +import { Flex } from "../Flex"; +import { flushSync } from "react-dom"; +import { Heading1, Text } from "../Type"; +import { Box } from "../Box"; export default { title: "Components/Pagination", @@ -24,6 +28,32 @@ export const _Pagination = () => ( ); +export const WithScrollTop = () => { + const [currentPage, setCurrentPage] = useState(1); + const ref = useRef(null); + + return ( + + + After paginating, this section should not be in the viewport + + + After paginating, the page should scroll to the top of this section + + setCurrentPage((p) => p + 1)} + onPrevious={() => setCurrentPage((p) => p - 1)} + onSelectPage={(page) => { + setCurrentPage(Number(page)); + }} + paginationScrollTargetRef={ref} + /> + + ); +}; + export const OnTheFirstPage = () => ; OnTheFirstPage.story = { diff --git a/src/Pagination/Pagination.tsx b/src/Pagination/Pagination.tsx index f67ba3290..49fe35f55 100644 --- a/src/Pagination/Pagination.tsx +++ b/src/Pagination/Pagination.tsx @@ -36,6 +36,7 @@ type PaginationProps = FlexProps & { nextAriaLabel?: string; previousLabel?: ReactNode; previousAriaLabel?: string; + paginationScrollTargetRef?: RefObject; }; function Pagination({ @@ -48,17 +49,34 @@ function Pagination({ nextLabel, previousAriaLabel, previousLabel, - previousLabel, + paginationScrollTargetRef, "aria-label": ariaLabel, ...restProps }: PaginationProps) { const { t } = useTranslation(); + const scrollToTop = () => { + if (paginationScrollTargetRef && paginationScrollTargetRef.current) { + const { top } = paginationScrollTargetRef.current.getBoundingClientRect(); + + window.scrollTo({ + top: window.scrollY + top, + behavior: "smooth", + }); + } + }; + return ( { + flushSync(() => { + onPrevious(); + }); + + scrollToTop(); + }} ariaLabel={previousAriaLabel} label={previousLabel} /> @@ -80,13 +98,30 @@ function Pagination({ disabled={isCurrentPage} aria-label={isCurrentPage ? null : t("go to page", { count: Number(page) })} key={page} - onClick={() => onSelectPage(page)} + onClick={() => { + flushSync(() => { + onSelectPage(page); + }); + + scrollToTop(); + }} > {page} ); })} - + { + flushSync(() => { + onNext(); + }); + + scrollToTop(); + }} + ariaLabel={nextAriaLabel} + label={nextLabel} + /> ); }