Skip to content

Commit a7784f5

Browse files
刘欢claude
andcommitted
feat: add recommendPage to onChange when pageSize changes
- Add third parameter recommendPage to onChange callback - calculatePage logic to preserve user's data position when changing pageSize - Related issue: ant-design/ant-design#30610 Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 5541381 commit a7784f5

6 files changed

Lines changed: 40 additions & 36 deletions

File tree

README.md

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -49,35 +49,36 @@ ReactDOM.render(<Pagination />, container);
4949
## API
5050

5151
// prettier-ignore
52-
| Parameter | Description | Type | Default |
53-
| --- | --- | --- | --- |
54-
| disabled | disable pagination | Bool | - |
55-
| align | align of pagination | start \| center \| end | undefined |
56-
| defaultCurrent | uncontrolled current page | Number | 1 |
57-
| current | current page | Number | undefined |
58-
| total | items total count | Number | 0 |
59-
| defaultPageSize | default items per page | Number | 10 |
60-
| pageSize | items per page | Number | 10 |
61-
| onChange | page change callback | Function(current, pageSize) | - |
62-
| showSizeChanger | show pageSize changer | boolean \| [SelectProps](https://github.com/react-component/select/blob/561f8b7d69fd5dd2cd7d917c88976cca4e539a9d/src/Select.tsx#L112) | `false` when total less than `totalBoundaryShowSizeChanger`, `true` when otherwise |
63-
| totalBoundaryShowSizeChanger | when total larger than it, `showSizeChanger` will be true | number | 50 |
64-
| pageSizeOptions | specify the sizeChanger selections | Array<String> | ['10', '20', '50', '100'] |
65-
| onShowSizeChange | pageSize change callback | Function(current, size) | - |
66-
| hideOnSinglePage | hide on single page | Bool | false |
67-
| showPrevNextJumpers | show jump-prev, jump-next | Bool | true |
68-
| showQuickJumper | show quick goto jumper | Bool / Object | false / {goButton: true} |
69-
| showTotal | show total records and range | Function(total, [from, to]) | - |
70-
| className | className of pagination | String | - |
71-
| simple | when set, show simple pager | Bool / { readOnly?: boolean; } | - |
72-
| locale | to set l10n config | Object | [zh_CN](https://github.com/react-component/pagination/blob/master/src/locale/zh_CN.js) |
73-
| style | the style of pagination | Object | {} |
74-
| showLessItems | show less page items | Bool | false |
75-
| showTitle | show page items title | Bool | true |
76-
| itemRender | custom page item renderer | Function(current, type: 'page' \| 'prev' \| 'next' \| 'jump-prev' \| 'jump-next', element): React.ReactNode \| `(current, type, element) => element` | |
77-
| prevIcon | specify the default previous icon | ReactNode \| (props: PaginationProps) => ReactNode | |
78-
| nextIcon | specify the default next icon | ReactNode \| (props: PaginationProps) => ReactNode | |
79-
| jumpPrevIcon | specify the default previous icon | ReactNode \| (props: PaginationProps) => ReactNode | |
80-
| jumpNextIcon | specify the default next icon | ReactNode \| (props: PaginationProps) => ReactNode | |
52+
53+
| Parameter | Description | Type | Default |
54+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
55+
| disabled | disable pagination | Bool | - |
56+
| align | align of pagination | start \| center \| end | undefined |
57+
| defaultCurrent | uncontrolled current page | Number | 1 |
58+
| current | current page | Number | undefined |
59+
| total | items total count | Number | 0 |
60+
| defaultPageSize | default items per page | Number | 10 |
61+
| pageSize | items per page | Number | 10 |
62+
| onChange | page change callback, the third parameter `recommendPage` is only provided when pageSize changes, useful for keeping the user's data position | Function(current, pageSize, recommendPage?) | - |
63+
| showSizeChanger | show pageSize changer | boolean \| [SelectProps](https://github.com/react-component/select/blob/561f8b7d69fd5dd2cd7d917c88976cca4e539a9d/src/Select.tsx#L112) | `false` when total less than `totalBoundaryShowSizeChanger`, `true` when otherwise |
64+
| totalBoundaryShowSizeChanger | when total larger than it, `showSizeChanger` will be true | number | 50 |
65+
| pageSizeOptions | specify the sizeChanger selections | Array<String> | ['10', '20', '50', '100'] |
66+
| onShowSizeChange | pageSize change callback | Function(current, size) | - |
67+
| hideOnSinglePage | hide on single page | Bool | false |
68+
| showPrevNextJumpers | show jump-prev, jump-next | Bool | true |
69+
| showQuickJumper | show quick goto jumper | Bool / Object | false / {goButton: true} |
70+
| showTotal | show total records and range | Function(total, [from, to]) | - |
71+
| className | className of pagination | String | - |
72+
| simple | when set, show simple pager | Bool / { readOnly?: boolean; } | - |
73+
| locale | to set l10n config | Object | [zh_CN](https://github.com/react-component/pagination/blob/master/src/locale/zh_CN.js) |
74+
| style | the style of pagination | Object | {} |
75+
| showLessItems | show less page items | Bool | false |
76+
| showTitle | show page items title | Bool | true |
77+
| itemRender | custom page item renderer | Function(current, type: 'page' \| 'prev' \| 'next' \| 'jump-prev' \| 'jump-next', element): React.ReactNode \| `(current, type, element) => element` | |
78+
| prevIcon | specify the default previous icon | ReactNode \| (props: PaginationProps) => ReactNode | |
79+
| nextIcon | specify the default next icon | ReactNode \| (props: PaginationProps) => ReactNode | |
80+
| jumpPrevIcon | specify the default previous icon | ReactNode \| (props: PaginationProps) => ReactNode | |
81+
| jumpNextIcon | specify the default next icon | ReactNode \| (props: PaginationProps) => ReactNode | |
8182

8283
## License
8384

src/Pagination.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,19 @@ const Pagination: React.FC<PaginationProps> = (props) => {
197197
}
198198

199199
function changePageSize(size: number) {
200+
const preservedPage = Math.ceil((current * pageSize) / size);
200201
const newCurrent = calculatePage(size, pageSize, total);
202+
const recommendPage =
203+
newCurrent === 0 ? 1 : Math.min(preservedPage, newCurrent);
204+
201205
const nextCurrent =
202206
current > newCurrent && newCurrent !== 0 ? newCurrent : current;
203207

204208
setPageSize(size);
205209
setInternalInputVal(nextCurrent);
206210
onShowSizeChange?.(current, size);
207211
setCurrent(nextCurrent);
208-
onChange?.(nextCurrent, size);
212+
onChange?.(nextCurrent, size, recommendPage);
209213
}
210214

211215
function handleChange(page: number) {

src/interface.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,8 @@ export interface PaginationData {
5757
}
5858

5959
export interface PaginationProps
60-
extends Partial<PaginationData>,
61-
React.AriaAttributes {
62-
onChange?: (page: number, pageSize: number) => void;
60+
extends Partial<PaginationData>, React.AriaAttributes {
61+
onChange?: (page: number, pageSize: number, recommendPage?: number) => void;
6362
onShowSizeChange?: (current: number, size: number) => void;
6463
itemRender?: (
6564
page: number,

tests/index.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ describe('current value on onShowSizeChange when total is 0', () => {
483483
fireEvent.keyDown(input, { key: 'Down', keyCode: 40, which: 40 });
484484
fireEvent.keyDown(input, { key: 'Enter', keyCode: 13, which: 13 });
485485
expect(onShowSizeChange).toHaveBeenLastCalledWith(1, 20);
486-
expect(onChange).toHaveBeenLastCalledWith(1, 20);
486+
expect(onChange).toHaveBeenLastCalledWith(1, 20, 1);
487487
});
488488

489489
it('when total is 0, pager should show `1` and being disabled', () => {

tests/simple.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ describe('simple Pagination', () => {
131131
const pageSize1 = container.querySelectorAll('.rc-select-item')[0];
132132
fireEvent.click(pageSize1);
133133
expect(onChange).toHaveBeenCalled();
134-
expect(onChange).toHaveBeenLastCalledWith(1, 10);
134+
expect(onChange).toHaveBeenLastCalledWith(1, 10, 2);
135135
});
136136

137137
it('should support keyboard event', () => {

tests/sizer.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ describe('Pagination with sizer', () => {
6767
const pageSize1 = container.querySelectorAll('.rc-select-item')[0];
6868
fireEvent.click(pageSize1);
6969
expect(onChange).toHaveBeenCalled();
70-
expect(onChange).toHaveBeenLastCalledWith(1, 10);
70+
expect(onChange).toHaveBeenLastCalledWith(1, 10, 2);
7171
});
7272

7373
// https://github.com/ant-design/ant-design/issues/26580

0 commit comments

Comments
 (0)