@alfalab/core-components-pagination 2.0.21 → 2.1.0

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 (45) 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/index.js +1 -1
  14. package/esm/Component.js +2 -2
  15. package/esm/components/default-view/index.css +2 -2
  16. package/esm/components/default-view/index.js +2 -2
  17. package/esm/components/per-page-view/index.css +2 -2
  18. package/esm/components/per-page-view/index.js +1 -1
  19. package/esm/components/tag/index.css +8 -8
  20. package/esm/components/tag/index.d.ts +83 -2
  21. package/esm/components/tag/index.js +3 -3
  22. package/esm/index.css +4 -5
  23. package/esm/index.js +1 -1
  24. package/index.css +4 -5
  25. package/index.js +1 -1
  26. package/modern/Component.js +2 -2
  27. package/modern/components/default-view/index.css +2 -2
  28. package/modern/components/default-view/index.js +2 -2
  29. package/modern/components/per-page-view/index.css +2 -2
  30. package/modern/components/per-page-view/index.js +1 -1
  31. package/modern/components/tag/index.css +8 -8
  32. package/modern/components/tag/index.d.ts +83 -2
  33. package/modern/components/tag/index.js +3 -3
  34. package/modern/index.css +4 -5
  35. package/modern/index.js +1 -1
  36. package/package.json +2 -2
  37. package/src/Component.tsx +127 -0
  38. package/src/components/default-view/index.module.css +12 -0
  39. package/src/components/default-view/index.tsx +88 -0
  40. package/src/components/per-page-view/index.module.css +6 -0
  41. package/src/components/per-page-view/index.tsx +13 -0
  42. package/src/components/tag/index.module.css +40 -0
  43. package/src/components/tag/index.tsx +18 -0
  44. package/src/index.module.css +20 -0
  45. package/src/index.ts +1 -0
package/index.css CHANGED
@@ -1,4 +1,4 @@
1
- /* hash: sk2y7 */
1
+ /* hash: rsb7b */
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_2lk2l {
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_2lk2l > * {
30
29
  margin-right: var(--gap-xs)
31
- } .pagination__defaultView_gdi2e > *:last-child {
30
+ } .pagination__defaultView_2lk2l > *: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_2lk2l","defaultView":"pagination__defaultView_2lk2l"};
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: vt6rd */
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_bvjrq {
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_bvjrq"};
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: js9yd */
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_bdgze {
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_bdgze"};
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: stdqr */
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
+ } .pagination__tag_1s9at.pagination__tag_1s9at {
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
+ } .pagination__tag_1s9at.pagination__tag_1s9at:disabled:not(.pagination__checked_1s9at) {
35
35
  opacity: 0.3;
36
- } .pagination__tag_e3qeb.pagination__tag_e3qeb:hover:not(:disabled) {
36
+ } .pagination__tag_1s9at.pagination__tag_1s9at: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
+ } .pagination__tag_1s9at.pagination__tag_1s9at:active:not(:disabled) {
40
40
  background-color: var(--color-light-bg-quaternary);
41
- } .pagination__tag_e3qeb.pagination__tag_e3qeb.pagination__checked_e3qeb {
41
+ } .pagination__tag_1s9at.pagination__tag_1s9at.pagination__checked_1s9at {
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
+ } .pagination__tag_1s9at.pagination__tag_1s9at.pagination__checked_1s9at: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
+ } .pagination__tag_1s9at.pagination__tag_1s9at.pagination__checked_1s9at: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_1s9at","checked":"pagination__checked_1s9at"};
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: rsb7b */
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_2lk2l {
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_2lk2l > * {
30
29
  margin-right: var(--gap-xs)
31
- } .pagination__defaultView_gdi2e > *:last-child {
30
+ } .pagination__defaultView_2lk2l > *: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.0",
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
+ .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
+ );
@@ -0,0 +1,20 @@
1
+ @import '@alfalab/core-components-themes/src/default.css';
2
+
3
+ .component {
4
+ @mixin paragraph_primary_small;
5
+
6
+ display: flex;
7
+ align-items: center;
8
+ color: var(--color-light-text-primary);
9
+ font-variant-numeric: tabular-nums;
10
+ }
11
+
12
+ .defaultView {
13
+ & > * {
14
+ margin-right: var(--gap-xs);
15
+
16
+ &:last-child {
17
+ margin-right: 0;
18
+ }
19
+ }
20
+ }
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './Component';