Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Options.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KeyCode } from '@rc-component/util';
import { isReactRenderable, KeyCode } from '@rc-component/util';
import React from 'react';
import type { PaginationLocale } from './interface';

Expand All @@ -21,7 +21,7 @@ interface OptionsProps {
selectPrefixCls?: string;
pageSize: number;
pageSizeOptions?: number[];
goButton?: boolean | string;
goButton?: React.ReactNode;
changeSize?: (size: number) => void;
quickGo?: (value: number) => void;
buildOptionText?: (value: number | string) => string;
Expand Down Expand Up @@ -67,7 +67,7 @@ const Options: React.FC<OptionsProps> = (props) => {
};

const handleBlur = (e: React.FocusEvent<HTMLInputElement, Element>) => {
if (goButton || goInputText === '') {
if (isReactRenderable(goButton) || goInputText === '') {
return;
}
setGoInputText('');
Expand Down Expand Up @@ -137,7 +137,7 @@ const Options: React.FC<OptionsProps> = (props) => {

// >>>>> Quick Go
if (quickGo) {
if (goButton) {
if (isReactRenderable(goButton)) {
gotoButton =
typeof goButton === 'boolean' ? (
<button
Expand Down
3 changes: 2 additions & 1 deletion src/Pager.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint react/prop-types: 0 */
import { clsx } from 'clsx';
import React from 'react';
import { isReactRenderable } from '@rc-component/util';
import type { PaginationProps } from './interface';

export interface PagerProps extends Pick<PaginationProps, 'itemRender'> {
Expand Down Expand Up @@ -61,7 +62,7 @@ const Pager: React.FC<PagerProps> = (props) => {
);
const pagerLabel = `${pageLabel} ${page}`.trim();

return pager ? (
return isReactRenderable(pager) ? (
<li
title={showTitle ? String(page) : null}
className={cls}
Expand Down
6 changes: 3 additions & 3 deletions src/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ const Pagination: React.FC<PaginationProps> = (props) => {

if (simple) {
// ====== Simple quick jump ======
if (goButton) {
if (isReactRenderable(goButton)) {
if (typeof goButton === 'boolean') {
gotoButton = (
<button type="button" onClick={handleGoTO} onKeyUp={handleGoTO}>
Expand All @@ -390,12 +390,12 @@ const Pagination: React.FC<PaginationProps> = (props) => {
}

gotoButton = (
<li
<span
title={showTitle ? `${locale.jump_to}${current}/${allPages}` : null}
className={`${prefixCls}-simple-pager`}
>
{gotoButton}
</li>
</span>
);
}

Expand Down
4 changes: 2 additions & 2 deletions tests/__snapshots__/demo.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2727,7 +2727,7 @@ exports[`Example jumperWithGoButton 1`] = `
/>
页
<span>
<li
<span
class="rc-pagination-simple-pager"
title="跳至1/5"
>
Expand All @@ -2736,7 +2736,7 @@ exports[`Example jumperWithGoButton 1`] = `
>
确定
</button>
</li>
</span>
</span>
</div>
</li>
Expand Down
8 changes: 4 additions & 4 deletions tests/__snapshots__/simple.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ exports[`simple Pagination props: showQuickJumper should render normally quick-j
/>
页
<span>
<li
<span
class="rc-pagination-simple-pager"
title="跳至1/5"
>
Expand All @@ -37,7 +37,7 @@ exports[`simple Pagination props: showQuickJumper should render normally quick-j
go
</button>
</span>
</li>
</span>
</span>
</div>
`;
Expand All @@ -54,7 +54,7 @@ exports[`simple Pagination props: showQuickJumper should render normally quick-j
/>
页
<span>
<li
<span
class="rc-pagination-simple-pager"
title="跳至1/5"
>
Expand All @@ -63,7 +63,7 @@ exports[`simple Pagination props: showQuickJumper should render normally quick-j
>
确定
</button>
</li>
</span>
</span>
</div>
`;
Expand Down
63 changes: 63 additions & 0 deletions tests/hydration.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import { act, fireEvent } from '@testing-library/react';
import { hydrateRoot, type Root } from 'react-dom/client';
import { renderToString } from 'react-dom/server';
import Pagination from '../src';

describe('simple Pagination hydration', () => {
it.each([
0,
true,
<button key="custom" type="button">
Go
</button>,
])(
'hydrates a go button without replacing server nodes: %s',
async (goButton) => {
const onChange = jest.fn();
const onRecoverableError = jest.fn();
const node = (
<Pagination
simple
total={100}
showQuickJumper={{ goButton }}
onChange={onChange}
/>
);
const container = document.createElement('div');
container.innerHTML = renderToString(node);
document.body.appendChild(container);
const serverRoot = container.firstElementChild;
const serverInput = container.querySelector('input');
let root: Root;

try {
await act(async () => {
root = hydrateRoot(container, node, { onRecoverableError });
});

expect(onRecoverableError).not.toHaveBeenCalled();
expect(container.firstElementChild).toBe(serverRoot);
expect(container.querySelector('input')).toBe(serverInput);
expect(container.querySelector('li li')).toBeNull();

const button = container.querySelector(
'.rc-pagination-options .rc-pagination-simple-pager',
).firstElementChild;
fireEvent.change(serverInput, { target: { value: '3' } });
fireEvent.click(button);
expect(onChange).toHaveBeenLastCalledWith(3, 10);

const quickInput = container.querySelector(
'.rc-pagination-options-quick-jumper input',
);
fireEvent.change(quickInput, { target: { value: '4' } });
fireEvent.keyUp(button, { key: 'Enter', keyCode: 13, which: 13 });
expect(onChange).toHaveBeenLastCalledWith(4, 10);
} finally {
await act(async () => root?.unmount());
container.remove();
}
},
);
});
47 changes: 47 additions & 0 deletions tests/renderability.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { fireEvent, render } from '@testing-library/react';
import Pagination from '../src';

describe('ReactNode renderability', () => {
it('keeps zero page content clickable', () => {
const onChange = jest.fn();
const { container } = render(
<Pagination
total={30}
onChange={onChange}
itemRender={(_, type, node) => (type === 'page' ? 0 : node)}
/>,
);
const page = container.querySelector('.rc-pagination-item-2');
expect(page.textContent).toBe('0');
fireEvent.click(page);
expect(onChange).toHaveBeenCalledWith(2, 10);
});

it.each([false, true])(
'keeps a zero go button interactive in simple=%s',
(simple) => {
const onChange = jest.fn();
const { container } = render(
<Pagination
simple={simple}
total={100}
onChange={onChange}
showQuickJumper={{ goButton: 0 }}
/>,
);
const input = container.querySelector('input');
fireEvent.change(input, { target: { value: '3' } });
const button = Array.from(container.querySelectorAll('span')).find(
(node) => node.textContent === '0' && node.childElementCount === 0,
);
expect(button).toBeTruthy();
if (!simple) {
fireEvent.blur(input);
expect(onChange).not.toHaveBeenCalled();
}
fireEvent.click(button);
expect(onChange).toHaveBeenCalledWith(3, 10);
},
);
});
Loading