@alfalab/core-components-pagination 2.0.21 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/Component.js +2 -2
  2. package/components/default-view/index.css +2 -2
  3. package/components/default-view/index.js +2 -2
  4. package/components/per-page-view/index.css +2 -2
  5. package/components/per-page-view/index.js +1 -1
  6. package/components/tag/index.css +8 -8
  7. package/components/tag/index.d.ts +83 -2
  8. package/components/tag/index.js +3 -3
  9. package/cssm/Component.js +1 -1
  10. package/cssm/components/default-view/index.js +1 -1
  11. package/cssm/components/tag/index.d.ts +83 -2
  12. package/cssm/components/tag/index.js +2 -2
  13. package/cssm/components/tag/index.module.css +7 -7
  14. package/cssm/index.js +1 -1
  15. package/esm/Component.js +2 -2
  16. package/esm/components/default-view/index.css +2 -2
  17. package/esm/components/default-view/index.js +2 -2
  18. package/esm/components/per-page-view/index.css +2 -2
  19. package/esm/components/per-page-view/index.js +1 -1
  20. package/esm/components/tag/index.css +8 -8
  21. package/esm/components/tag/index.d.ts +83 -2
  22. package/esm/components/tag/index.js +3 -3
  23. package/esm/index.css +4 -5
  24. package/esm/index.js +1 -1
  25. package/index.css +4 -5
  26. package/index.js +1 -1
  27. package/modern/Component.js +2 -2
  28. package/modern/components/default-view/index.css +2 -2
  29. package/modern/components/default-view/index.js +2 -2
  30. package/modern/components/per-page-view/index.css +2 -2
  31. package/modern/components/per-page-view/index.js +1 -1
  32. package/modern/components/tag/index.css +8 -8
  33. package/modern/components/tag/index.d.ts +83 -2
  34. package/modern/components/tag/index.js +3 -3
  35. package/modern/index.css +4 -5
  36. package/modern/index.js +1 -1
  37. package/package.json +2 -2
  38. package/src/Component.tsx +127 -0
  39. package/src/components/default-view/index.module.css +12 -0
  40. package/src/components/default-view/index.tsx +88 -0
  41. package/src/components/per-page-view/index.module.css +6 -0
  42. package/src/components/per-page-view/index.tsx +13 -0
  43. package/src/components/tag/index.module.css +40 -0
  44. package/src/components/tag/index.tsx +18 -0
  45. package/src/index.module.css +20 -0
  46. package/src/index.ts +1 -0
package/esm/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* hash: sk2y7 */
1
+ /* hash: 1gpcn */
2
2
  :root {
3
3
  } /* deprecated */ :root {
4
4
  --color-light-text-primary: #0e0e0e; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
@@ -16,7 +16,7 @@
16
16
  --gap-xs: 8px;
17
17
  } :root {
18
18
  } :root {
19
- } .pagination__component_gdi2e {
19
+ } .pagination__component_ynqhf {
20
20
  font-size: 14px;
21
21
  line-height: 20px;
22
22
  font-weight: 400;
@@ -24,10 +24,9 @@
24
24
  display: flex;
25
25
  align-items: center;
26
26
  color: var(--color-light-text-primary);
27
- font-feature-settings: "tnum";
28
27
  font-variant-numeric: tabular-nums;
29
- } .pagination__defaultView_gdi2e > * {
28
+ } .pagination__defaultView_ynqhf > * {
30
29
  margin-right: var(--gap-xs)
31
- } .pagination__defaultView_gdi2e > *:last-child {
30
+ } .pagination__defaultView_ynqhf > *:last-child {
32
31
  margin-right: 0;
33
32
  }
package/esm/index.js CHANGED
@@ -6,5 +6,5 @@ import '@alfalab/icons-glyph/ChevronForwardMIcon';
6
6
  import './components/default-view/index.js';
7
7
  import './components/tag/index.js';
8
8
  import 'tslib';
9
- import '@alfalab/core-components-tag/esm';
9
+ import '@alfalab/core-components-tag/esm/desktop';
10
10
  import './components/per-page-view/index.js';
package/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* hash: sk2y7 */
1
+ /* hash: 1gpcn */
2
2
  :root {
3
3
  } /* deprecated */ :root {
4
4
  --color-light-text-primary: #0e0e0e; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
@@ -16,7 +16,7 @@
16
16
  --gap-xs: 8px;
17
17
  } :root {
18
18
  } :root {
19
- } .pagination__component_gdi2e {
19
+ } .pagination__component_ynqhf {
20
20
  font-size: 14px;
21
21
  line-height: 20px;
22
22
  font-weight: 400;
@@ -24,10 +24,9 @@
24
24
  display: flex;
25
25
  align-items: center;
26
26
  color: var(--color-light-text-primary);
27
- font-feature-settings: "tnum";
28
27
  font-variant-numeric: tabular-nums;
29
- } .pagination__defaultView_gdi2e > * {
28
+ } .pagination__defaultView_ynqhf > * {
30
29
  margin-right: var(--gap-xs)
31
- } .pagination__defaultView_gdi2e > *:last-child {
30
+ } .pagination__defaultView_ynqhf > *:last-child {
32
31
  margin-right: 0;
33
32
  }
package/index.js CHANGED
@@ -10,7 +10,7 @@ require('@alfalab/icons-glyph/ChevronForwardMIcon');
10
10
  require('./components/default-view/index.js');
11
11
  require('./components/tag/index.js');
12
12
  require('tslib');
13
- require('@alfalab/core-components-tag');
13
+ require('@alfalab/core-components-tag/desktop');
14
14
  require('./components/per-page-view/index.js');
15
15
 
16
16
 
@@ -5,9 +5,9 @@ import { ChevronForwardMIcon } from '@alfalab/icons-glyph/ChevronForwardMIcon';
5
5
  import { DefaultView } from './components/default-view/index.js';
6
6
  import { PerPageView } from './components/per-page-view/index.js';
7
7
  import { Tag } from './components/tag/index.js';
8
- import '@alfalab/core-components-tag/modern';
8
+ import '@alfalab/core-components-tag/modern/desktop';
9
9
 
10
- const styles = {"component":"pagination__component_gdi2e","defaultView":"pagination__defaultView_gdi2e"};
10
+ const styles = {"component":"pagination__component_ynqhf","defaultView":"pagination__defaultView_ynqhf"};
11
11
  require('./index.css')
12
12
 
13
13
  const Pagination = ({ currentPageIndex = 0, pagesCount, className, sidePadding = 1, activePadding = 2, hideArrows = true, view = 'default', onPageChange = () => null, dataTestId, }) => {
@@ -1,4 +1,4 @@
1
- /* hash: 1lgn5 */
1
+ /* hash: 16zr9 */
2
2
  :root {
3
3
  } /* deprecated */ :root {
4
4
  --color-light-text-secondary: rgba(60, 60, 67, 0.66); /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
@@ -15,7 +15,7 @@
15
15
  } :root {
16
16
  } :root {
17
17
  } :root {
18
- } .pagination__dots_1x6os {
18
+ } .pagination__dots_hcm4n {
19
19
  width: 32px;
20
20
  height: 32px;
21
21
  text-align: center;
@@ -1,9 +1,9 @@
1
1
  import React, { useCallback } from 'react';
2
2
  import { Tag } from '../tag/index.js';
3
3
  import 'classnames';
4
- import '@alfalab/core-components-tag/modern';
4
+ import '@alfalab/core-components-tag/modern/desktop';
5
5
 
6
- const styles = {"dots":"pagination__dots_1x6os"};
6
+ const styles = {"dots":"pagination__dots_hcm4n"};
7
7
  require('./index.css')
8
8
 
9
9
  /* eslint-disable react/no-array-index-key */
@@ -1,4 +1,4 @@
1
- /* hash: 19fqc */
1
+ /* hash: dfv3v */
2
2
  :root {
3
3
  } /* deprecated */ :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
4
4
  } :root { /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
@@ -15,7 +15,7 @@
15
15
  --gap-m: 16px;
16
16
  } :root {
17
17
  } :root {
18
- } .pagination__component_1f89s {
18
+ } .pagination__component_12vfs {
19
19
  display: block;
20
20
  margin: 0 var(--gap-m);
21
21
  }
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
 
3
- const styles = {"component":"pagination__component_1f89s"};
3
+ const styles = {"component":"pagination__component_12vfs"};
4
4
  require('./index.css')
5
5
 
6
6
  const PerPageView = ({ pagesCount, currentPageIndex }) => (React.createElement("span", { className: styles.component },
@@ -1,4 +1,4 @@
1
- /* hash: 13vx4 */
1
+ /* hash: 1whx5 */
2
2
  :root {
3
3
  } /* deprecated */ :root {
4
4
  --color-light-bg-quaternary: #dcdcdd;
@@ -21,7 +21,7 @@
21
21
  } :root {
22
22
  } :root {
23
23
  } :root {
24
- } .pagination__tag_e3qeb.pagination__tag_e3qeb {
24
+ } button.pagination__tag_11495.pagination__tag_11495 {
25
25
  color: var(--color-light-text-secondary);
26
26
  border-radius: var(--border-radius-m);
27
27
  border: none;
@@ -31,19 +31,19 @@
31
31
  width: 32px;
32
32
  height: 32px;
33
33
  padding: 0
34
- } .pagination__tag_e3qeb.pagination__tag_e3qeb:disabled:not(.pagination__checked_e3qeb) {
34
+ } button.pagination__tag_11495.pagination__tag_11495:disabled:not(.pagination__checked_11495) {
35
35
  opacity: 0.3;
36
- } .pagination__tag_e3qeb.pagination__tag_e3qeb:hover:not(:disabled) {
36
+ } button.pagination__tag_11495.pagination__tag_11495:hover:not(:disabled) {
37
37
  background-color: var(--color-light-bg-tertiary);
38
38
  color: var(--color-light-text-primary);
39
- } .pagination__tag_e3qeb.pagination__tag_e3qeb:active:not(:disabled) {
39
+ } button.pagination__tag_11495.pagination__tag_11495:active:not(:disabled) {
40
40
  background-color: var(--color-light-bg-quaternary);
41
- } .pagination__tag_e3qeb.pagination__tag_e3qeb.pagination__checked_e3qeb {
41
+ } button.pagination__tag_11495.pagination__tag_11495.pagination__checked_11495 {
42
42
  cursor: default;
43
43
  background-color: var(--color-light-bg-secondary-inverted);
44
44
  color: var(--color-light-text-primary-inverted);
45
- } .pagination__tag_e3qeb.pagination__tag_e3qeb.pagination__checked_e3qeb:hover:not(:disabled) {
45
+ } button.pagination__tag_11495.pagination__tag_11495.pagination__checked_11495:hover:not(:disabled) {
46
46
  color: var(--color-light-text-primary-inverted);
47
- } .pagination__tag_e3qeb.pagination__tag_e3qeb.pagination__checked_e3qeb:active:not(:disabled) {
47
+ } button.pagination__tag_11495.pagination__tag_11495.pagination__checked_11495:active:not(:disabled) {
48
48
  color: var(--color-light-text-primary);
49
49
  }
@@ -1,4 +1,85 @@
1
- import { FC } from 'react';
2
- import { TagProps } from "@alfalab/core-components-tag";
1
+ /// <reference types="react" />
2
+ import React from 'react';
3
+ import { FC, ButtonHTMLAttributes, ReactNode, RefObject } from "react";
4
+ type StyleColors = {
5
+ default: {
6
+ [key: string]: string;
7
+ };
8
+ inverted: {
9
+ [key: string]: string;
10
+ };
11
+ };
12
+ type NativeProps = ButtonHTMLAttributes<HTMLButtonElement>;
13
+ type BaseTagProps = Omit<NativeProps, "onClick"> & {
14
+ /**
15
+ * Отображение кнопки в отмеченном (зажатом) состоянии
16
+ */
17
+ checked?: boolean;
18
+ /**
19
+ * Размер компонента
20
+ */
21
+ size?: "xxs" | "xs" | "s" | "m" | "l" | "xl";
22
+ /**
23
+ * Дочерние элементы.
24
+ */
25
+ children?: ReactNode;
26
+ /**
27
+ * Дополнительный класс для обёртки children
28
+ */
29
+ childrenClassName?: string;
30
+ /**
31
+ * Слот слева
32
+ */
33
+ leftAddons?: ReactNode;
34
+ /**
35
+ * Слот справа
36
+ */
37
+ rightAddons?: ReactNode;
38
+ /**
39
+ * Идентификатор для систем автоматизированного тестирования
40
+ */
41
+ dataTestId?: string;
42
+ /**
43
+ * Обработчик нажатия
44
+ */
45
+ onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>, payload: {
46
+ checked: boolean;
47
+ name?: string;
48
+ }) => void;
49
+ /**
50
+ * ref на children
51
+ */
52
+ childrenRef?: RefObject<HTMLSpanElement>;
53
+ /**
54
+ * Набор цветов для компонента
55
+ */
56
+ colors?: "default" | "inverted";
57
+ /**
58
+ * @deprecated данный проп больше не используется, временно оставлен для обратной совместимости
59
+ * Используйте props shape и view
60
+ * Вариант тега
61
+ */
62
+ variant?: "default" | "alt";
63
+ /**
64
+ * Форма тега
65
+ */
66
+ shape?: "rounded" | "rectangular";
67
+ /**
68
+ * Стиль тега
69
+ */
70
+ view?: "outlined" | "filled";
71
+ /**
72
+ * Основные стили компонента.
73
+ */
74
+ styles?: {
75
+ [key: string]: string;
76
+ };
77
+ /**
78
+ * Стили компонента для default и inverted режима.
79
+ */
80
+ colorStylesMap?: StyleColors;
81
+ };
82
+ type TagDesktopProps = Omit<BaseTagProps, "styles">;
83
+ type TagProps = TagDesktopProps;
3
84
  declare const Tag: FC<TagProps>;
4
85
  export { Tag };
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
2
  import cn from 'classnames';
3
- import { Tag as Tag$1 } from '@alfalab/core-components-tag/modern';
3
+ import { TagDesktop } from '@alfalab/core-components-tag/modern/desktop';
4
4
 
5
- const styles = {"tag":"pagination__tag_e3qeb","checked":"pagination__checked_e3qeb"};
5
+ const styles = {"tag":"pagination__tag_11495","checked":"pagination__checked_11495"};
6
6
  require('./index.css')
7
7
 
8
- const Tag = ({ className, checked, ...restProps }) => (React.createElement(Tag$1, { ...restProps, checked: checked, size: 'xxs', className: cn(className, styles.tag, { [styles.checked]: checked }) }));
8
+ const Tag = ({ className, checked, ...restProps }) => (React.createElement(TagDesktop, { ...restProps, checked: checked, size: 'xxs', className: cn(className, styles.tag, { [styles.checked]: checked }) }));
9
9
 
10
10
  export { Tag };
package/modern/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* hash: sk2y7 */
1
+ /* hash: 1gpcn */
2
2
  :root {
3
3
  } /* deprecated */ :root {
4
4
  --color-light-text-primary: #0e0e0e; /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */ /* deprecated */
@@ -16,7 +16,7 @@
16
16
  --gap-xs: 8px;
17
17
  } :root {
18
18
  } :root {
19
- } .pagination__component_gdi2e {
19
+ } .pagination__component_ynqhf {
20
20
  font-size: 14px;
21
21
  line-height: 20px;
22
22
  font-weight: 400;
@@ -24,10 +24,9 @@
24
24
  display: flex;
25
25
  align-items: center;
26
26
  color: var(--color-light-text-primary);
27
- font-feature-settings: "tnum";
28
27
  font-variant-numeric: tabular-nums;
29
- } .pagination__defaultView_gdi2e > * {
28
+ } .pagination__defaultView_ynqhf > * {
30
29
  margin-right: var(--gap-xs)
31
- } .pagination__defaultView_gdi2e > *:last-child {
30
+ } .pagination__defaultView_ynqhf > *:last-child {
32
31
  margin-right: 0;
33
32
  }
package/modern/index.js CHANGED
@@ -5,5 +5,5 @@ import '@alfalab/icons-glyph/ChevronBackMIcon';
5
5
  import '@alfalab/icons-glyph/ChevronForwardMIcon';
6
6
  import './components/default-view/index.js';
7
7
  import './components/tag/index.js';
8
- import '@alfalab/core-components-tag/modern';
8
+ import '@alfalab/core-components-tag/modern/desktop';
9
9
  import './components/per-page-view/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/core-components-pagination",
3
- "version": "2.0.21",
3
+ "version": "2.1.1",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -15,7 +15,7 @@
15
15
  "react-dom": "^16.9.0 || ^17.0.1 || ^18.0.0"
16
16
  },
17
17
  "dependencies": {
18
- "@alfalab/core-components-tag": "^5.4.1",
18
+ "@alfalab/core-components-tag": "^6.0.0",
19
19
  "@alfalab/icons-glyph": "^2.108.0",
20
20
  "classnames": "^2.3.1",
21
21
  "tslib": "^2.4.0"
@@ -0,0 +1,127 @@
1
+ import React, { FC } from 'react';
2
+ import cn from 'classnames';
3
+
4
+ import { ChevronBackMIcon } from '@alfalab/icons-glyph/ChevronBackMIcon';
5
+ import { ChevronForwardMIcon } from '@alfalab/icons-glyph/ChevronForwardMIcon';
6
+
7
+ import { DefaultView } from './components/default-view';
8
+ import { PerPageView } from './components/per-page-view';
9
+ import { Tag } from './components/tag';
10
+
11
+ import styles from './index.module.css';
12
+
13
+ export type PaginationProps = {
14
+ /**
15
+ * Текущая страница (с нуля)
16
+ */
17
+ currentPageIndex: number;
18
+
19
+ /**
20
+ * Количество страниц
21
+ */
22
+ pagesCount: number;
23
+
24
+ /**
25
+ * Дополнительный класс
26
+ */
27
+ className?: string;
28
+
29
+ /**
30
+ * Скрывает стрелки, если выбрана первая или последняя страница
31
+ */
32
+ hideArrows?: boolean;
33
+
34
+ /**
35
+ * Количество видимых страниц по бокам
36
+ */
37
+ sidePadding?: number;
38
+
39
+ /**
40
+ * Количество видимых страниц вокруг выбранной
41
+ */
42
+ activePadding?: number;
43
+
44
+ /**
45
+ * Режим пагинации
46
+ */
47
+ view?: 'default' | 'per-page';
48
+
49
+ /**
50
+ * Обработчик переключения страницы
51
+ */
52
+ onPageChange?: (pageIndex: number) => void;
53
+
54
+ /**
55
+ * Идентификатор для систем автоматизированного тестирования
56
+ */
57
+ dataTestId?: string;
58
+ };
59
+
60
+ export const Pagination: FC<PaginationProps> = ({
61
+ currentPageIndex = 0,
62
+ pagesCount,
63
+ className,
64
+ sidePadding = 1,
65
+ activePadding = 2,
66
+ hideArrows = true,
67
+ view = 'default',
68
+ onPageChange = () => null,
69
+ dataTestId,
70
+ }) => {
71
+ const handlePageClick = (pageIndex: number) => {
72
+ onPageChange(pageIndex);
73
+ };
74
+
75
+ const handleNextPageClick = () => {
76
+ handlePageClick(Math.min(pagesCount - 1, currentPageIndex + 1));
77
+ };
78
+
79
+ const handlePrevPageClick = () => {
80
+ handlePageClick(Math.max(0, currentPageIndex - 1));
81
+ };
82
+
83
+ const shouldRenderPrevArrow = view === 'per-page' || !hideArrows || currentPageIndex > 0;
84
+ const shouldRenderNextArrow =
85
+ view === 'per-page' || !hideArrows || currentPageIndex < pagesCount - 1;
86
+
87
+ const viewClassName = view === 'default' ? 'defaultView' : view;
88
+
89
+ return (
90
+ <div
91
+ className={cn(styles.component, className, styles[viewClassName])}
92
+ data-test-id={dataTestId}
93
+ >
94
+ {shouldRenderPrevArrow && (
95
+ <Tag
96
+ className={styles.arrow}
97
+ disabled={currentPageIndex <= 0}
98
+ onClick={handlePrevPageClick}
99
+ rightAddons={<ChevronBackMIcon width={16} height={16} />}
100
+ />
101
+ )}
102
+
103
+ {view === 'default' && (
104
+ <DefaultView
105
+ activePadding={activePadding}
106
+ sidePadding={sidePadding}
107
+ currentPageIndex={currentPageIndex}
108
+ pagesCount={pagesCount}
109
+ onPageChange={handlePageClick}
110
+ />
111
+ )}
112
+
113
+ {view === 'per-page' && (
114
+ <PerPageView currentPageIndex={currentPageIndex} pagesCount={pagesCount} />
115
+ )}
116
+
117
+ {shouldRenderNextArrow && (
118
+ <Tag
119
+ className={styles.arrow}
120
+ disabled={currentPageIndex >= pagesCount - 1}
121
+ onClick={handleNextPageClick}
122
+ rightAddons={<ChevronForwardMIcon width={16} height={16} />}
123
+ />
124
+ )}
125
+ </div>
126
+ );
127
+ };
@@ -0,0 +1,12 @@
1
+ @import '@alfalab/core-components-themes/src/default.css';
2
+
3
+ .dots {
4
+ width: 32px;
5
+ height: 32px;
6
+ text-align: center;
7
+ display: flex;
8
+ align-items: center;
9
+ justify-content: center;
10
+ color: var(--color-light-text-secondary);
11
+ cursor: default;
12
+ }
@@ -0,0 +1,88 @@
1
+ /* eslint-disable react/no-array-index-key */
2
+ import React, { FC, useCallback } from 'react';
3
+
4
+ import { PaginationProps } from '../../Component';
5
+ import { Tag } from '../tag';
6
+
7
+ import styles from './index.module.css';
8
+
9
+ type DefaultViewProps = Pick<
10
+ PaginationProps,
11
+ 'sidePadding' | 'activePadding' | 'pagesCount' | 'currentPageIndex' | 'onPageChange'
12
+ >;
13
+
14
+ export const DefaultView: FC<DefaultViewProps> = ({
15
+ sidePadding = 2,
16
+ activePadding = 1,
17
+ pagesCount,
18
+ currentPageIndex,
19
+ onPageChange = () => null,
20
+ }) => {
21
+ const maxHalfCount = sidePadding + activePadding + 1;
22
+ const maxElementsCount = maxHalfCount * 2 + 1;
23
+ const itemsFit = pagesCount <= maxElementsCount;
24
+ const elementsCount = itemsFit ? pagesCount : maxElementsCount;
25
+
26
+ const getPageIndex = useCallback(
27
+ (elementIndex: number) => {
28
+ const lastIndex = pagesCount - 1;
29
+ const reverseIndex = lastIndex - currentPageIndex;
30
+ const lastElementIndex = elementsCount - 1;
31
+ const reverseElementIndex = lastElementIndex - elementIndex;
32
+
33
+ const hasCollapsedItems = (index: number) => !itemsFit && index >= maxHalfCount;
34
+
35
+ if (elementIndex < sidePadding) {
36
+ return elementIndex;
37
+ }
38
+
39
+ if (elementIndex === sidePadding && hasCollapsedItems(currentPageIndex)) {
40
+ return null;
41
+ }
42
+
43
+ if (reverseElementIndex === sidePadding && hasCollapsedItems(reverseIndex)) {
44
+ return null;
45
+ }
46
+
47
+ if (reverseElementIndex < sidePadding) {
48
+ return lastIndex - reverseElementIndex;
49
+ }
50
+
51
+ const computedIndex = currentPageIndex - maxHalfCount + elementIndex;
52
+
53
+ return Math.min(lastIndex - reverseElementIndex, Math.max(elementIndex, computedIndex));
54
+ },
55
+ [currentPageIndex, elementsCount, itemsFit, maxHalfCount, pagesCount, sidePadding],
56
+ );
57
+
58
+ return (
59
+ <React.Fragment>
60
+ {Array(elementsCount)
61
+ .fill('')
62
+ .map((_, i) => {
63
+ const pageIndex = getPageIndex(i);
64
+
65
+ if (pageIndex === null) {
66
+ return (
67
+ <div key={i.toString()} className={styles.dots}>
68
+ ...
69
+ </div>
70
+ );
71
+ }
72
+
73
+ const active = currentPageIndex === pageIndex;
74
+
75
+ return (
76
+ <Tag
77
+ key={i.toString()}
78
+ checked={active}
79
+ disabled={active}
80
+ onClick={() => onPageChange(pageIndex)}
81
+ >
82
+ {pageIndex + 1}
83
+ </Tag>
84
+ );
85
+ })}
86
+ </React.Fragment>
87
+ );
88
+ };
@@ -0,0 +1,6 @@
1
+ @import '@alfalab/core-components-themes/src/default.css';
2
+
3
+ .component {
4
+ display: block;
5
+ margin: 0 var(--gap-m);
6
+ }
@@ -0,0 +1,13 @@
1
+ import React, { FC } from 'react';
2
+
3
+ import { PaginationProps } from '../../Component';
4
+
5
+ import styles from './index.module.css';
6
+
7
+ type PerPageViewProps = Pick<PaginationProps, 'pagesCount' | 'currentPageIndex'>;
8
+
9
+ export const PerPageView: FC<PerPageViewProps> = ({ pagesCount, currentPageIndex }) => (
10
+ <span className={styles.component}>
11
+ {currentPageIndex + 1} из {pagesCount} страниц
12
+ </span>
13
+ );
@@ -0,0 +1,40 @@
1
+ @import '@alfalab/core-components-themes/src/default.css';
2
+
3
+ button.tag.tag {
4
+ color: var(--color-light-text-secondary);
5
+ border-radius: var(--border-radius-m);
6
+ border: none;
7
+ flex-shrink: 0;
8
+ min-width: auto;
9
+ min-height: auto;
10
+ width: 32px;
11
+ height: 32px;
12
+ padding: 0;
13
+
14
+ &:disabled:not(.checked) {
15
+ opacity: 0.3;
16
+ }
17
+
18
+ &:hover:not(:disabled) {
19
+ background-color: var(--color-light-bg-tertiary);
20
+ color: var(--color-light-text-primary);
21
+ }
22
+
23
+ &:active:not(:disabled) {
24
+ background-color: var(--color-light-bg-quaternary);
25
+ }
26
+
27
+ &.checked {
28
+ cursor: default;
29
+ background-color: var(--color-light-bg-secondary-inverted);
30
+ color: var(--color-light-text-primary-inverted);
31
+ }
32
+
33
+ &.checked:hover:not(:disabled) {
34
+ color: var(--color-light-text-primary-inverted);
35
+ }
36
+
37
+ &.checked:active:not(:disabled) {
38
+ color: var(--color-light-text-primary);
39
+ }
40
+ }
@@ -0,0 +1,18 @@
1
+ import React, { FC } from 'react';
2
+ import cn from 'classnames';
3
+
4
+ import {
5
+ TagDesktop as CoreTag,
6
+ TagDesktopProps as TagProps,
7
+ } from '@alfalab/core-components-tag/desktop';
8
+
9
+ import styles from './index.module.css';
10
+
11
+ export const Tag: FC<TagProps> = ({ className, checked, ...restProps }) => (
12
+ <CoreTag
13
+ {...restProps}
14
+ checked={checked}
15
+ size='xxs'
16
+ className={cn(className, styles.tag, { [styles.checked]: checked })}
17
+ />
18
+ );