Skip to content

Commit f77e551

Browse files
committed
feat: add wrapper to buttons
1 parent 48059d9 commit f77e551

File tree

9 files changed

+283
-161
lines changed

9 files changed

+283
-161
lines changed

src/components/Pagination/Pagination.tsx

+8-10
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export const Pagination = ({
2525
total,
2626
size: propSize,
2727
onUpdate,
28-
pageHrefBuilder,
28+
buttonWrapper,
2929
compact: propCompact = true,
3030
pageSizeOptions,
3131
showPages = true,
@@ -52,7 +52,7 @@ export const Pagination = ({
5252
mobile,
5353
});
5454

55-
const onUpdateInner = pageHrefBuilder ? undefined : onUpdate;
55+
const handleOnUpdateForButtonControl = buttonWrapper ? undefined : onUpdate;
5656

5757
const pagination = items
5858
.map((item) => {
@@ -65,8 +65,8 @@ export const Pagination = ({
6565
size={size}
6666
pageSize={pageSize}
6767
item={item}
68-
pageHrefBuilder={pageHrefBuilder}
69-
onUpdate={onUpdateInner}
68+
buttonWrapper={buttonWrapper}
69+
onUpdate={handleOnUpdateForButtonControl}
7070
className={b('pagination-item')}
7171
/>
7272
)
@@ -99,8 +99,8 @@ export const Pagination = ({
9999
item={item}
100100
page={resultPage}
101101
pageSize={pageSize}
102-
pageHrefBuilder={pageHrefBuilder}
103-
onUpdate={onUpdateInner}
102+
buttonWrapper={buttonWrapper}
103+
onUpdate={handleOnUpdateForButtonControl}
104104
compact={compact}
105105
className={b('pagination-item')}
106106
/>
@@ -119,15 +119,13 @@ export const Pagination = ({
119119
numberOfPages={numberOfPages}
120120
pageSize={pageSize}
121121
size={size}
122-
pageHrefBuilder={pageHrefBuilder}
123-
onUpdate={onUpdateInner}
122+
onUpdate={onUpdate}
124123
className={b('input')}
125124
/>
126125
)}
127126
{pageSizeOptions && (
128127
<PaginationPageSizer
129-
pageHrefBuilder={pageHrefBuilder}
130-
onUpdate={onUpdateInner}
128+
onUpdate={onUpdate}
131129
page={resultPage}
132130
pageSize={pageSize}
133131
pageSizeOptions={pageSizeOptions}

src/components/Pagination/README-ru.md

+99-32
Original file line numberDiff line numberDiff line change
@@ -12,60 +12,127 @@ import {Pagination} from '@gravity-ui/uikit';
1212

1313
## Использование
1414

15-
Возможны 2 способа использвания пагинации: как [ссылки](#ссылки) и как [кнопки](#кнопки).
15+
Возможны 2 способа взаимодействия с пагинацией: как [с кнопками](#кнопки) и как [с произвольными компонентами](#произвольные-компоненты).
1616

17-
### Ссылки
17+
### Кнопки
1818

19-
При использовании этого способа пользователь будет взаимодействовать с компонентами пагинации (кроме поля ввода), как со ссылками. Появляется возможность откртывать страницы (например, из контекстного меню) в новой квладке, в новом окне и т.д.
20-
Для этого необходимо указать свойство `pageHrefBuilder`.
19+
При использовании этого способа пользователь будет взаимодействовать с компонентами пагинации, как с кнопками.
20+
Для этого необходимо указать свойство `onUpdate` (свойство `buttonWrapper` должно быть `undefined`)
2121

2222
```jsx
2323
import {Pagination, PaginationProps} from '@gravity-ui/uikit';
2424

2525
const [state, setState] = React.useState({page: 1, pageSize: 100});
2626

27+
const handleUpdate: PaginationProps['onUpdate'] = (page, pageSize) =>
28+
setState((prevState) => ({page, pageSize}));
29+
30+
const pagination = <Pagination page={1} pageSize={100} total={1000} onUpdate={handleUpdate} />;
31+
```
32+
33+
### Произвольные компоненты
34+
35+
При использовании этого способа пользователь будет взаимодействовать кнопками пагинации, как с произвольными компонентами.
36+
37+
Для этого необходимо указать свойство `buttonWraper`. В этом случае `onUpdate` будет вызываться только при изменении компонентов input и select.
38+
39+
> Например, можно обернуть кнопки в тег `<a/>` и взаимодействовать с ними, как с ссылками. Это позволит открывать страницы (например, из контекстного меню) в новой владке, в новом окне и т.д.
40+
41+
#### Links example
42+
43+
```jsx
44+
import {Pagination, PaginationProps} from '@gravity-ui/uikit';
45+
2746
const PAGE_PARAM = 'page_number';
2847
const PAGE_SIZE_PARAM = 'page_size';
2948

30-
const pageHrefBuilder: PaginationProps['pageHrefBuilder'] = (page, pageSize) => {
31-
const queryParams = new URLSearchParams(window.location.search);
32-
queryParams.set(PAGE_PARAM, String(page));
33-
queryParams.set(PAGE_SIZE_PARAM, String(pageSize));
34-
return window.location.href.replace(window.location.search, `?${queryParams.toString()}`);
49+
function pageHrefBuilder(page: number, pageSize: number) {
50+
const queryParams = new URLSearchParams(window.location.search);
51+
queryParams.set(PAGE_PARAM, String(page));
52+
queryParams.set(PAGE_SIZE_PARAM, String(pageSize));
53+
return window.location.href.replace(window.location.search, `?${queryParams.toString()}`);
54+
}
55+
56+
const [state, setState] = React.useState({page: 1, pageSize: 100});
57+
58+
const renderWrapper = ({page, pageSize, button}) => {
59+
return button.props.disabled ? (
60+
button
61+
) : (
62+
<a href={pageHrefBuilder(page, pageSize)} key={button.key}>
63+
{button}
64+
</a>
65+
);
3566
},
3667

37-
const pagination = <Pagination page={1} pageSize={100} total={1000} pageHrefBuilder={pageHrefBuilder} />;
68+
const handleUpdate = (page, pageSize)=>{
69+
window.location.href = pageHrefBuilder(page, pageSize);
70+
}
71+
72+
const pagination = <Pagination
73+
page={1}
74+
pageSize={100}
75+
total={1000}
76+
buttonWrapper={renderWrapper}
77+
onUpdate={(page, pageSize)=>setState({page, pageSize})}
78+
>;
3879
```
3980

40-
### Кнопки
41-
42-
При использовании этого способа пользователь будет взаимодействовать с компонентами пагинации (кроме поля ввода), как с кнопками.
43-
Для этого необходимо указать свойство `onUpdate` (свойство `pageHrefBuilder` должно быть `undefined`)
81+
#### Links for react-router SPA way
4482

4583
```jsx
4684
import {Pagination, PaginationProps} from '@gravity-ui/uikit';
85+
import {useNavigate, Link} from 'react-router-dom';
4786

48-
const [state, setState] = React.useState({page: 1, pageSize: 100});
87+
const PAGE_PARAM = 'page_number';
88+
const PAGE_SIZE_PARAM = 'page_size';
4989

50-
const handleUpdate: PaginationProps['onUpdate'] = (page, pageSize) =>
51-
setState((prevState) => ({...prevState, page, pageSize}));
90+
function pageHrefBuilder(page: number, pageSize: number) {
91+
const queryParams = new URLSearchParams(window.location.search);
92+
queryParams.set(PAGE_PARAM, String(page));
93+
queryParams.set(PAGE_SIZE_PARAM, String(pageSize));
94+
return window.location.href.replace(window.location.search, `?${queryParams.toString()}`);
95+
}
5296

53-
const pagination = <Pagination page={1} pageSize={100} total={1000} onUpdate={handleUpdate} />;
97+
const [state, setState] = React.useState({page: 1, pageSize: 100});
98+
const navigate = useNavigate();
99+
100+
const renderWrapper = ({page, pageSize, button}) => {
101+
return button.props.disabled ? (
102+
button
103+
) : (
104+
<Link to={pageHrefBuilder(page, pageSize)} key={button.key}>
105+
{button}
106+
</a>
107+
);
108+
},
109+
110+
const handleUpdate = (page, pageSize)=>{
111+
navigate(pageHrefBuilder(page, pageSize));
112+
}
113+
114+
const pagination = <Pagination
115+
page={1}
116+
pageSize={100}
117+
total={1000}
118+
buttonWrapper={renderWrapper}
119+
onUpdate={(page, pageSize)=>setState({page, pageSize})}
120+
>;
54121
```
55122

56123
## Свойства
57124

58-
| Имя | Описание | Тип | Значение по умолчанию |
59-
| :-------------- | :----------------------------------------------------------------------------------------------------------------------------- | :--------: | :-------------------: |
60-
| className | HTML-атрибут `class`. | `string` | |
61-
| compact | Скрывает заголовки для кнопок `First`, `Previous` и `Next`. В мобильной версии всегда имеет значение `true`. | `boolean` | `true` |
62-
| pageHrefBuilder | Функция для генерации ссылок пагинации | `Function` | |
63-
| onUpdate | Вызывается при изменении номера страницы или свойства `pageSize` (вызывается только если не задан параметр `pageHrefBuilder`). | `Function` | |
64-
| size | Размер элементов пагинации. По умолчанию `l` для мобильных и `m` для десктопных версий. | `string` | |
65-
| page | Номер текущей страницы. | `number` | |
66-
| pageSize | Количество элементов данных на одной странице. | `number` | |
67-
| pageSizeOptions | Позволяет указать опции для `sizeChanger`. | `number[]` | |
68-
| total | Общее количество элементов данных. | `number` | |
69-
| showInput | Отображает элемент ввода для перехода к конкретной странице | `boolean` | `false` |
70-
| showPages | Отображает нумерацию страниц. | `boolean` | `true` |
71-
| qa | HTML-атрибут `data-qa`, используется для тестирования. | `string` | |
125+
| Имя | Описание | Тип | Значение по умолчанию |
126+
| :-------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------: | :-------------------: |
127+
| className | HTML-атрибут `class`. | `string` | |
128+
| compact | Скрывает заголовки для кнопок `First`, `Previous` и `Next`. В мобильной версии всегда имеет значение `true`. | `boolean` | `true` |
129+
| buttonWrapper | Компонент-обертка над кнопками пагинации | `Function` | |
130+
| onUpdate | Вызывается при изменении номера страницы или свойства `pageSize` (ели задан параметр `buttonWrapper`, то `onUpdate` вызывается только в `input` и `select`). | `Function` | |
131+
| size | Размер элементов пагинации. По умолчанию `l` для мобильных и `m` для десктопных версий. | `string` | |
132+
| page | Номер текущей страницы. | `number` | |
133+
| pageSize | Количество элементов данных на одной странице. | `number` | |
134+
| pageSizeOptions | Позволяет указать опции для `sizeChanger`. | `number[]` | |
135+
| total | Общее количество элементов данных. | `number` | |
136+
| showInput | Отображает элемент ввода для перехода к конкретной странице | `boolean` | `false` |
137+
| showPages | Отображает нумерацию страниц. | `boolean` | `true` |
138+
| qa | HTML-атрибут `data-qa`, используется для тестирования. | `string` | |

0 commit comments

Comments
 (0)