Skip to content

Commit

Permalink
feat(pagination): add separators
Browse files Browse the repository at this point in the history
  • Loading branch information
typeofweb committed Jan 2, 2023
1 parent 1cc7765 commit 9f010ea
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { describe, expect, it } from "vitest";
import { getPages } from "./QuestionsPagination";
import { getPages, QUESTIONS_PAGINATION_SEPARATOR } from "./QuestionsPagination";

describe("QuestionsPagination", () => {
// prettier-ignore
it.each([
{ first: 1, last: 6, current: 1, expected: [1, 2, 3, 4, 6] },
{ first: 1, last: 6, current: 2, expected: [1, 2, 3, 4, 6] },
{ first: 1, last: 6, current: 3, expected: [1, 2, 3, 4, 6] },
{ first: 1, last: 6, current: 4, expected: [1, 3, 4, 5, 6] },
{ first: 1, last: 7, current: 5, expected: [1, 4, 5, 6, 7] },
{ first: 1, last: 6, current: 1, expected: [1, 2, 3, 4, QUESTIONS_PAGINATION_SEPARATOR, 6] },
{ first: 1, last: 6, current: 2, expected: [1, 2, 3, 4, QUESTIONS_PAGINATION_SEPARATOR, 6] },
{ first: 1, last: 6, current: 3, expected: [1, 2, 3, 4, QUESTIONS_PAGINATION_SEPARATOR, 6] },
{ first: 1, last: 6, current: 4, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 3, 4, 5, 6] },
{ first: 1, last: 7, current: 5, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 4, 5, 6, 7] },
{ first: 1, last: 5, current: 3, expected: [1, 2, 3, 4, 5] },
{ first: 1, last: 5, current: 4, expected: [1, 2, 3, 4, 5] },
{ first: 1, last: 5, current: 5, expected: [1, 2, 3, 4, 5] },
{ first: 1, last: 871, current: 412, expected: [1, 411, 412, 413, 871] },
{ first: 1, last: 872, current: 313, expected: [1, 312, 313, 314, 872] },
{ first: 1, last: 872, current: 2, expected: [1, 2, 3, 4, 872] },
{ first: 1, last: 872, current: 871, expected: [1, 869, 870, 871, 872] },
{ first: 1, last: 871, current: 412, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 411, 412, 413, QUESTIONS_PAGINATION_SEPARATOR, 871] },
{ first: 1, last: 872, current: 313, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 312, 313, 314, QUESTIONS_PAGINATION_SEPARATOR, 872] },
{ first: 1, last: 872, current: 2, expected: [1, 2, 3, 4, QUESTIONS_PAGINATION_SEPARATOR, 872] },
{ first: 1, last: 872, current: 871, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 869, 870, 871, 872] },
{ first: 1, last: 1, current: 1, expected: [1] },
{ first: 1, last: 2, current: 1, expected: [1, 2] },
{ first: 1, last: 2, current: 2, expected: [1, 2] },
Expand Down
57 changes: 36 additions & 21 deletions apps/app/src/components/QuestionsPagination/QuestionsPagination.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { LinkProps } from "next/link";
import { e } from "vitest/dist/index-c3f83a58";
import { PAGE_SIZE } from "../../lib/constants";
import { ActiveLink } from "../ActiveLink";

Expand All @@ -8,6 +9,8 @@ type QuestionsPaginationProps = Readonly<{
getHref: (i: number) => LinkProps["href"];
}>;

export const QUESTIONS_PAGINATION_SEPARATOR = Symbol("QUESTIONS_PAGINATION_SEPARATOR");

export const getPages = ({
first,
last,
Expand All @@ -16,7 +19,7 @@ export const getPages = ({
first: number;
last: number;
current: number;
}) => {
}): ReadonlyArray<number | typeof QUESTIONS_PAGINATION_SEPARATOR> => {
if (first === last) {
return [1];
}
Expand All @@ -27,7 +30,13 @@ export const getPages = ({
const lastMiddle = Math.min(last - 1, next);
const middle = Array.from({ length: lastMiddle - firstMiddle + 1 }, (_, i) => firstMiddle + i);

return [first, ...middle, last];
return [
first,
firstMiddle === first + 1 ? undefined : QUESTIONS_PAGINATION_SEPARATOR,
...middle,
lastMiddle === last - 1 ? undefined : QUESTIONS_PAGINATION_SEPARATOR,
last,
].filter((el): el is number | typeof QUESTIONS_PAGINATION_SEPARATOR => el !== undefined);
};

export const QuestionsPagination = ({ current, total, getHref }: QuestionsPaginationProps) => {
Expand All @@ -40,25 +49,31 @@ export const QuestionsPagination = ({ current, total, getHref }: QuestionsPagina
return (
<nav aria-label="Paginacja" role="navigation">
<ul className="flex justify-center gap-x-3">
{pages.map((i) => (
<li key={i}>
<ActiveLink
href={getHref(i)}
className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border-2 border-primary text-primary transition-colors duration-300 hover:bg-violet-100 dark:text-white dark:hover:bg-violet-800"
activeClassName="bg-primary text-white hover:bg-primary"
aria-label={`Strona ${i}${
current - 1 === i ? ", poprzednia" : current + 1 === i ? ", kolejna" : ""
}`}
activeAttributes={{
"aria-current": "page",
"aria-label": `Strona ${i}, bieżąca`,
}}
mergeQuery
>
{i}
</ActiveLink>
</li>
))}
{pages.map((page, idx) =>
page === QUESTIONS_PAGINATION_SEPARATOR ? (
<li key={`${page.toString()}_${idx}`} aria-hidden="true">
<span className="-mx-2 flex h-7 w-7 cursor-default items-center justify-center text-primary after:content-['…'] dark:text-white"></span>
</li>
) : (
<li key={page}>
<ActiveLink
href={getHref(page)}
className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-full border-2 border-primary text-primary transition-colors duration-300 hover:bg-violet-100 dark:text-white dark:hover:bg-violet-800"
activeClassName="bg-primary text-white hover:bg-primary"
aria-label={`Strona ${page}${
current - 1 === page ? ", poprzednia" : current + 1 === page ? ", kolejna" : ""
}`}
activeAttributes={{
"aria-current": "page",
"aria-label": `Strona ${page}, bieżąca`,
}}
mergeQuery
>
{page}
</ActiveLink>
</li>
),
)}
</ul>
</nav>
);
Expand Down

0 comments on commit 9f010ea

Please sign in to comment.