Skip to content

Commit

Permalink
add pagination component
Browse files Browse the repository at this point in the history
  • Loading branch information
lilyanB committed Jun 7, 2023
1 parent be1358d commit 5833418
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 0 deletions.
52 changes: 52 additions & 0 deletions src/components/Pagination/Pagination.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Pagination } from './Pagination';

export default { title: 'Components/Pagination', component: Pagination };

export const _Pagination = {
render: () => (
<>
<Pagination
pages={4}
currentPage={2}
onPageChange={(newPage: number) =>
console.log('move to page ' + newPage)
}
/>

<br />
<br />
<Pagination
pages={40}
currentPage={1}
onPageChange={(newPage: number) =>
console.log('move to page ' + newPage)
}
/>

<br />
<br />

<Pagination
pages={40}
currentPage={25}
onPageChange={(newPage: number) =>
console.log('move to page ' + newPage)
}
/>

<br />
<br />

<Pagination
pages={40}
currentPage={38}
onPageChange={(newPage: number) =>
console.log('move to page ' + newPage)
}
/>

<br />
<br />
</>
),
};
20 changes: 20 additions & 0 deletions src/components/Pagination/Pagination.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { render, screen } from '@testing-library/react';
import { Pagination } from './Pagination';

describe('Components | Pagination', () => {
test('it should render', () => {
render(
<Pagination
pages={40}
currentPage={1}
onPageChange={(newPage: number) =>
console.log('move to page ' + newPage)
}
/>,
);

let pagination = screen.getByTestId('pagination');

expect(pagination).toBeTruthy();
});
});
146 changes: 146 additions & 0 deletions src/components/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import React from 'react';

import { MdArrowForwardIos } from 'react-icons/md';

function renderPagination(
pages: number,
currentPage: number,
onPageChange: (newPage: number) => void,
pageClass: string,
currentpageClass: string,
): React.ReactNode[] {
const pagination: React.ReactNode[] = [];

const isFirstPage = currentPage === 1;
const isLastPage = currentPage === pages;

const addPageLink = (pageNumber: number, className: string): void => {
pagination.push(
<a
onClick={() => onPageChange(pageNumber)}
className={className}
key={pageNumber}
>
{pageNumber}
</a>,
);
};

const addEllipsis = (key: string): void => {
pagination.push(
<span className={pageClass} key={key}>
...
</span>,
);
};

addPageLink(1, currentPage === 1 ? currentpageClass : pageClass);

if (pages > 7) {
if (currentPage > 2 && !isFirstPage) {
addEllipsis('startEllipsis');
}

if (isFirstPage) {
for (let i = currentPage + 1; i < Math.min(currentPage + 4, 4); i++) {
addPageLink(i, i === currentPage ? currentpageClass : pageClass);
}
} else if (isLastPage) {
for (let i = currentPage - 4; i < pages; i++) {
addPageLink(i, i === currentPage ? currentpageClass : pageClass);
}
} else if (currentPage < 3) {
for (
let i = currentPage;
i <= Math.min(currentPage + 1, pages - 1);
i++
) {
addPageLink(i, i === currentPage ? currentpageClass : pageClass);
}
} else if (currentPage < pages - 4) {
for (let i = currentPage; i < currentPage + 3; i++) {
addPageLink(i, i === currentPage ? currentpageClass : pageClass);
}
} else if (currentPage >= pages - 4) {
for (let i = pages - 4; i < pages; i++) {
addPageLink(i, i === currentPage ? currentpageClass : pageClass);
}
}

if (currentPage + 2 < pages - 1 && !isLastPage && currentPage < pages - 4) {
addEllipsis('endEllipsis');
}

if (isFirstPage) {
for (let i = pages - 2; i < pages; i++) {
const className = i === currentPage ? currentpageClass : pageClass;
addPageLink(i, className);
}
} else if (currentPage < 3) {
for (let i = pages - 2; i < pages; i++) {
const className = i === currentPage ? currentpageClass : pageClass;
addPageLink(i, className);
}
}
}
if (pages > 1 && pages <= 7) {
for (let i = 2; i < pages; i++) {
const className = i === currentPage ? currentpageClass : pageClass;
addPageLink(i, className);
}
}

addPageLink(pages, pages === currentPage ? currentpageClass : pageClass);

return pagination;
}

export interface PaginationProps {
pages: number;
currentPage: number;
customClass?: string;
onPageChange: (newPage: number) => void;
}

export function Pagination(props: PaginationProps) {
const { pages, currentPage, customClass, onPageChange } = props;
const pageClass = 'px-3 py-1 rounded-lg cursor-pointer';
const currentpageClass = `${pageClass} bg-f-primary text-f-secondary`;

const pagination = renderPagination(
pages,
currentPage,
onPageChange,
pageClass,
currentpageClass,
);

return (
<div
data-testid="pagination"
className={`bg-primary flex items-center text-f-primary ${customClass}`}
>
<a
onClick={() =>
currentPage !== 1 ? onPageChange(currentPage - 1) : undefined
}
className={currentPage !== 1 ? pageClass : 'px-3 py-1 rounded-lg'}
>
<MdArrowForwardIos className="rotate-180" />
</a>

{pagination}

<a
onClick={() =>
currentPage !== pages ? onPageChange(currentPage + 1) : undefined
}
className={currentPage !== pages ? pageClass : 'px-3 py-1 rounded-lg'}
>
<MdArrowForwardIos />
</a>
</div>
);
}
1 change: 1 addition & 0 deletions src/components/Pagination/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Pagination';
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ export * from './Identicon';
export * from './Transaction';
export * from './Plugin';
export * from './Description';
export * from './Pagination';

0 comments on commit 5833418

Please sign in to comment.