Skip to content

Commit

Permalink
feat: optionally scroll to the top after paginating
Browse files Browse the repository at this point in the history
  • Loading branch information
haideralsh committed Nov 16, 2023
1 parent 2be7378 commit 78e9eee
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 5 deletions.
31 changes: 30 additions & 1 deletion src/Pagination/Pagination.story.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React from "react";
import React, { useRef, useState } from "react";
import { action } from "@storybook/addon-actions";
import { Flex } from "../Flex";
import { Heading1 } from "../Type";
import { Box } from "../Box";
import { Pagination } from ".";

export default {
Expand All @@ -24,6 +27,32 @@ export const _Pagination = () => (
</>
);

export const WithScrollTop = () => {
const [currentPage, setCurrentPage] = useState(1);
const ref = useRef(null);

return (
<Flex gap="x2" flexDirection="column" alignItems="flex-end">
<Box ref={ref} p="x4" height="20vh" width="100%" bg="whiteGrey">
<Heading1>After paginating, this section should not be in the viewport</Heading1>
</Box>
<Box ref={ref} p="x4" height="2000px" width="100%" bg="lightBlue">
<Heading1>After paginating, the page should scroll to the top of this section</Heading1>
</Box>
<Pagination
currentPage={currentPage}
totalPages={7}
onNext={() => setCurrentPage((p) => p + 1)}
onPrevious={() => setCurrentPage((p) => p - 1)}
onSelectPage={(page) => {
setCurrentPage(Number(page));
}}
paginationScrollTargetRef={ref}
/>
</Flex>
);
};

export const OnTheFirstPage = () => <Pagination currentPage={1} totalPages={10} />;

OnTheFirstPage.story = {
Expand Down
43 changes: 39 additions & 4 deletions src/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type PaginationProps = FlexProps & {
nextAriaLabel?: string;
previousLabel?: ReactNode;
previousAriaLabel?: string;
paginationScrollTargetRef?: RefObject<HTMLElement>;
};

function Pagination({
Expand All @@ -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 (
<Flex as="nav" aria-label={ariaLabel || t("pagination navigation")} {...restProps}>
<PreviousButton
disabled={currentPage === 1}
onClick={onPrevious}
onClick={() => {
flushSync(() => {
onPrevious();
});

scrollToTop();
}}
ariaLabel={previousAriaLabel}
label={previousLabel}
/>
Expand All @@ -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}
</PageNumber>
);
})}
<NextButton disabled={currentPage === totalPages} onClick={onNext} ariaLabel={nextAriaLabel} label={nextLabel} />
<NextButton
disabled={currentPage === totalPages}
onClick={() => {
flushSync(() => {
onNext();
});

scrollToTop();
}}
ariaLabel={nextAriaLabel}
label={nextLabel}
/>
</Flex>
);
}
Expand Down

0 comments on commit 78e9eee

Please sign in to comment.