Skip to content

Commit 6716cac

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

File tree

9 files changed

+352
-158
lines changed

9 files changed

+352
-158
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

+134-31
Original file line numberDiff line numberDiff line change
@@ -12,60 +12,163 @@ 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+
function renderWrapper({page, pageSize, button}) {
57+
return button.props.disabled ? (
58+
button
59+
) : (
60+
<a href={pageHrefBuilder(page, pageSize)} key={button.key}>
61+
{button}
62+
</a>
63+
);
3564
},
3665

37-
const pagination = <Pagination page={1} pageSize={100} total={1000} pageHrefBuilder={pageHrefBuilder} />;
38-
```
66+
const [state, setState] = React.useState({page: 1, pageSize: 100});
3967

40-
### Кнопки
68+
const pagination = <Pagination
69+
page={1}
70+
pageSize={100}
71+
total={1000}
72+
buttonWrapper={renderWrapper}
73+
onUpdate={(page, pageSize)=>setState({page, pageSize})}
74+
/>;
75+
```
4176

42-
При использовании этого способа пользователь будет взаимодействовать с компонентами пагинации (кроме поля ввода), как с кнопками.
43-
Для этого необходимо указать свойство `onUpdate` (свойство `pageHrefBuilder` должно быть `undefined`)
77+
#### Links example
4478

4579
```jsx
4680
import {Pagination, PaginationProps} from '@gravity-ui/uikit';
4781

82+
const PAGE_PARAM = 'page_number';
83+
const PAGE_SIZE_PARAM = 'page_size';
84+
85+
function pageHrefBuilder(page: number, pageSize: number) {
86+
const queryParams = new URLSearchParams(window.location.search);
87+
queryParams.set(PAGE_PARAM, String(page));
88+
queryParams.set(PAGE_SIZE_PARAM, String(pageSize));
89+
return window.location.href.replace(window.location.search, `?${queryParams.toString()}`);
90+
}
91+
4892
const [state, setState] = React.useState({page: 1, pageSize: 100});
4993

50-
const handleUpdate: PaginationProps['onUpdate'] = (page, pageSize) =>
51-
setState((prevState) => ({...prevState, page, pageSize}));
94+
const renderWrapper = ({page, pageSize, button}) => {
95+
return button.props.disabled ? (
96+
button
97+
) : (
98+
<a href={pageHrefBuilder(page, pageSize)} key={button.key}>
99+
{button}
100+
</a>
101+
);
102+
},
52103

53-
const pagination = <Pagination page={1} pageSize={100} total={1000} onUpdate={handleUpdate} />;
104+
const handleUpdate = (page, pageSize)=>{
105+
window.location.href = pageHrefBuilder(page, pageSize);
106+
}
107+
108+
const pagination = <Pagination
109+
page={1}
110+
pageSize={100}
111+
total={1000}
112+
buttonWrapper={renderWrapper}
113+
onUpdate={(page, pageSize)=>setState({page, pageSize})}
114+
>;
115+
```
116+
117+
#### Links for react-router SPA way
118+
119+
```jsx
120+
import {Pagination, PaginationProps} from '@gravity-ui/uikit';
121+
import {useNavigate, Link} from 'react-router-dom';
122+
123+
const PAGE_PARAM = 'page_number';
124+
const PAGE_SIZE_PARAM = 'page_size';
125+
126+
function pageHrefBuilder(page: number, pageSize: number) {
127+
const queryParams = new URLSearchParams(window.location.search);
128+
queryParams.set(PAGE_PARAM, String(page));
129+
queryParams.set(PAGE_SIZE_PARAM, String(pageSize));
130+
return window.location.href.replace(window.location.search, `?${queryParams.toString()}`);
131+
}
132+
133+
const [state, setState] = React.useState({page: 1, pageSize: 100});
134+
const navigate = useNavigate();
135+
136+
const renderWrapper = ({page, pageSize, button}) => {
137+
return button.props.disabled ? (
138+
button
139+
) : (
140+
<Link to={pageHrefBuilder(page, pageSize)} key={button.key}>
141+
{button}
142+
</a>
143+
);
144+
},
145+
146+
const handleUpdate = (page, pageSize)=>{
147+
navigate(pageHrefBuilder(page, pageSize));
148+
}
149+
150+
const pagination = <Pagination
151+
page={1}
152+
pageSize={100}
153+
total={1000}
154+
buttonWrapper={renderWrapper}
155+
onUpdate={(page, pageSize)=>setState({page, pageSize})}
156+
>;
54157
```
55158

56159
## Свойства
57160

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` | |
161+
| Имя | Описание | Тип | Значение по умолчанию |
162+
| :-------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------- | :--------: | :-------------------: |
163+
| className | HTML-атрибут `class`. | `string` | |
164+
| compact | Скрывает заголовки для кнопок `First`, `Previous` и `Next`. В мобильной версии всегда имеет значение `true`. | `boolean` | `true` |
165+
| buttonWrapper | Компонент-обертка над кнопками пагинации | `Function` | |
166+
| onUpdate | Вызывается при изменении номера страницы или свойства `pageSize` (ели задан параметр `buttonWrapper`, то `onUpdate` вызывается только в `input` и `select`). | `Function` | |
167+
| size | Размер элементов пагинации. По умолчанию `l` для мобильных и `m` для десктопных версий. | `string` | |
168+
| page | Номер текущей страницы. | `number` | |
169+
| pageSize | Количество элементов данных на одной странице. | `number` | |
170+
| pageSizeOptions | Позволяет указать опции для `sizeChanger`. | `number[]` | |
171+
| total | Общее количество элементов данных. | `number` | |
172+
| showInput | Отображает элемент ввода для перехода к конкретной странице | `boolean` | `false` |
173+
| showPages | Отображает нумерацию страниц. | `boolean` | `true` |
174+
| qa | HTML-атрибут `data-qa`, используется для тестирования. | `string` | |

0 commit comments

Comments
 (0)