Skip to content

Commit 9f010ea

Browse files
committed
feat(pagination): add separators
1 parent 1cc7765 commit 9f010ea

File tree

2 files changed

+47
-31
lines changed

2 files changed

+47
-31
lines changed

apps/app/src/components/QuestionsPagination/QuestionsPagination.test.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
import { describe, expect, it } from "vitest";
2-
import { getPages } from "./QuestionsPagination";
2+
import { getPages, QUESTIONS_PAGINATION_SEPARATOR } from "./QuestionsPagination";
33

44
describe("QuestionsPagination", () => {
5+
// prettier-ignore
56
it.each([
6-
{ first: 1, last: 6, current: 1, expected: [1, 2, 3, 4, 6] },
7-
{ first: 1, last: 6, current: 2, expected: [1, 2, 3, 4, 6] },
8-
{ first: 1, last: 6, current: 3, expected: [1, 2, 3, 4, 6] },
9-
{ first: 1, last: 6, current: 4, expected: [1, 3, 4, 5, 6] },
10-
{ first: 1, last: 7, current: 5, expected: [1, 4, 5, 6, 7] },
7+
{ first: 1, last: 6, current: 1, expected: [1, 2, 3, 4, QUESTIONS_PAGINATION_SEPARATOR, 6] },
8+
{ first: 1, last: 6, current: 2, expected: [1, 2, 3, 4, QUESTIONS_PAGINATION_SEPARATOR, 6] },
9+
{ first: 1, last: 6, current: 3, expected: [1, 2, 3, 4, QUESTIONS_PAGINATION_SEPARATOR, 6] },
10+
{ first: 1, last: 6, current: 4, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 3, 4, 5, 6] },
11+
{ first: 1, last: 7, current: 5, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 4, 5, 6, 7] },
1112
{ first: 1, last: 5, current: 3, expected: [1, 2, 3, 4, 5] },
1213
{ first: 1, last: 5, current: 4, expected: [1, 2, 3, 4, 5] },
1314
{ first: 1, last: 5, current: 5, expected: [1, 2, 3, 4, 5] },
14-
{ first: 1, last: 871, current: 412, expected: [1, 411, 412, 413, 871] },
15-
{ first: 1, last: 872, current: 313, expected: [1, 312, 313, 314, 872] },
16-
{ first: 1, last: 872, current: 2, expected: [1, 2, 3, 4, 872] },
17-
{ first: 1, last: 872, current: 871, expected: [1, 869, 870, 871, 872] },
15+
{ first: 1, last: 871, current: 412, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 411, 412, 413, QUESTIONS_PAGINATION_SEPARATOR, 871] },
16+
{ first: 1, last: 872, current: 313, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 312, 313, 314, QUESTIONS_PAGINATION_SEPARATOR, 872] },
17+
{ first: 1, last: 872, current: 2, expected: [1, 2, 3, 4, QUESTIONS_PAGINATION_SEPARATOR, 872] },
18+
{ first: 1, last: 872, current: 871, expected: [1, QUESTIONS_PAGINATION_SEPARATOR, 869, 870, 871, 872] },
1819
{ first: 1, last: 1, current: 1, expected: [1] },
1920
{ first: 1, last: 2, current: 1, expected: [1, 2] },
2021
{ first: 1, last: 2, current: 2, expected: [1, 2] },

apps/app/src/components/QuestionsPagination/QuestionsPagination.tsx

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { LinkProps } from "next/link";
2+
import { e } from "vitest/dist/index-c3f83a58";
23
import { PAGE_SIZE } from "../../lib/constants";
34
import { ActiveLink } from "../ActiveLink";
45

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

12+
export const QUESTIONS_PAGINATION_SEPARATOR = Symbol("QUESTIONS_PAGINATION_SEPARATOR");
13+
1114
export const getPages = ({
1215
first,
1316
last,
@@ -16,7 +19,7 @@ export const getPages = ({
1619
first: number;
1720
last: number;
1821
current: number;
19-
}) => {
22+
}): ReadonlyArray<number | typeof QUESTIONS_PAGINATION_SEPARATOR> => {
2023
if (first === last) {
2124
return [1];
2225
}
@@ -27,7 +30,13 @@ export const getPages = ({
2730
const lastMiddle = Math.min(last - 1, next);
2831
const middle = Array.from({ length: lastMiddle - firstMiddle + 1 }, (_, i) => firstMiddle + i);
2932

30-
return [first, ...middle, last];
33+
return [
34+
first,
35+
firstMiddle === first + 1 ? undefined : QUESTIONS_PAGINATION_SEPARATOR,
36+
...middle,
37+
lastMiddle === last - 1 ? undefined : QUESTIONS_PAGINATION_SEPARATOR,
38+
last,
39+
].filter((el): el is number | typeof QUESTIONS_PAGINATION_SEPARATOR => el !== undefined);
3140
};
3241

3342
export const QuestionsPagination = ({ current, total, getHref }: QuestionsPaginationProps) => {
@@ -40,25 +49,31 @@ export const QuestionsPagination = ({ current, total, getHref }: QuestionsPagina
4049
return (
4150
<nav aria-label="Paginacja" role="navigation">
4251
<ul className="flex justify-center gap-x-3">
43-
{pages.map((i) => (
44-
<li key={i}>
45-
<ActiveLink
46-
href={getHref(i)}
47-
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"
48-
activeClassName="bg-primary text-white hover:bg-primary"
49-
aria-label={`Strona ${i}${
50-
current - 1 === i ? ", poprzednia" : current + 1 === i ? ", kolejna" : ""
51-
}`}
52-
activeAttributes={{
53-
"aria-current": "page",
54-
"aria-label": `Strona ${i}, bieżąca`,
55-
}}
56-
mergeQuery
57-
>
58-
{i}
59-
</ActiveLink>
60-
</li>
61-
))}
52+
{pages.map((page, idx) =>
53+
page === QUESTIONS_PAGINATION_SEPARATOR ? (
54+
<li key={`${page.toString()}_${idx}`} aria-hidden="true">
55+
<span className="-mx-2 flex h-7 w-7 cursor-default items-center justify-center text-primary after:content-['…'] dark:text-white"></span>
56+
</li>
57+
) : (
58+
<li key={page}>
59+
<ActiveLink
60+
href={getHref(page)}
61+
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"
62+
activeClassName="bg-primary text-white hover:bg-primary"
63+
aria-label={`Strona ${page}${
64+
current - 1 === page ? ", poprzednia" : current + 1 === page ? ", kolejna" : ""
65+
}`}
66+
activeAttributes={{
67+
"aria-current": "page",
68+
"aria-label": `Strona ${page}, bieżąca`,
69+
}}
70+
mergeQuery
71+
>
72+
{page}
73+
</ActiveLink>
74+
</li>
75+
),
76+
)}
6277
</ul>
6378
</nav>
6479
);

0 commit comments

Comments
 (0)