Skip to content

Commit

Permalink
fix: Pagination select props order (ant-design#51962)
Browse files Browse the repository at this point in the history
* fix: Pagination select props order

* chore: replace with select

* chore: back of support

* chore: bump rc-pagination

* chore: merge selection

* chore: fix lint
  • Loading branch information
zombieJ authored Dec 11, 2024
1 parent 9b4400b commit 846dc9b
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 33 deletions.
107 changes: 93 additions & 14 deletions components/pagination/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,31 @@ import type { PaginationLocale, PaginationProps as RcPaginationProps } from 'rc-
import RcPagination from 'rc-pagination';
import enUS from 'rc-pagination/lib/locale/en_US';

import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';
import useSize from '../config-provider/hooks/useSize';
import useBreakpoint from '../grid/hooks/useBreakpoint';
import type { SelectProps } from '../select';
import { useLocale } from '../locale';
import type { SelectProps } from '../select';
import Select from '../select';
import { useToken } from '../theme/internal';
import { MiddleSelect, MiniSelect } from './Select';
import useStyle from './style';
import BorderedStyle from './style/bordered';
import useShowSizeChanger from './useShowSizeChanger';

export interface PaginationProps extends RcPaginationProps {
export interface PaginationProps
extends Omit<RcPaginationProps, 'showSizeChanger' | 'pageSizeOptions'> {
showQuickJumper?: boolean | { goButton?: React.ReactNode };
size?: 'default' | 'small';
responsive?: boolean;
role?: string;
totalBoundaryShowSizeChanger?: number;
rootClassName?: string;
showSizeChanger?: boolean | SelectProps;
/** @deprecated Not official support. Will be removed in next major version. */
selectComponentClass?: any;
/** `string` type will be removed in next major version. */
pageSizeOptions?: (string | number)[];
}

export type PaginationPosition = 'top' | 'bottom' | 'both';
Expand All @@ -46,9 +53,10 @@ const Pagination: React.FC<PaginationProps> = (props) => {
style,
size: customizeSize,
locale: customLocale,
selectComponentClass,
responsive,
showSizeChanger,
selectComponentClass,
pageSizeOptions,
...restProps
} = props;
const { xs } = useBreakpoint(responsive);
Expand All @@ -60,8 +68,86 @@ const Pagination: React.FC<PaginationProps> = (props) => {
// Style
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);

const mergedShowSizeChanger = showSizeChanger ?? pagination.showSizeChanger;
// ============================== Size ==============================
const mergedSize = useSize(customizeSize);

const isSmall = mergedSize === 'small' || !!(xs && !mergedSize && responsive);

// ============================= Locale =============================
const [contextLocale] = useLocale('Pagination', enUS);

const locale = { ...contextLocale, ...customLocale };

// ========================== Size Changer ==========================
// Merge the props showSizeChanger
const [propShowSizeChanger, propSizeChangerSelectProps] = useShowSizeChanger(showSizeChanger);
const [contextShowSizeChanger, contextSizeChangerSelectProps] = useShowSizeChanger(
pagination.showSizeChanger,
);

const mergedShowSizeChanger = propShowSizeChanger ?? contextShowSizeChanger;
const mergedShowSizeChangerSelectProps =
propSizeChangerSelectProps ?? contextSizeChangerSelectProps;

const SizeChanger: typeof Select = selectComponentClass || Select;

// Generate options
const mergedPageSizeOptions = React.useMemo(() => {
return pageSizeOptions ? pageSizeOptions.map((option) => Number(option)) : undefined;
}, [pageSizeOptions]);

// Render size changer
const sizeChangerRender: RcPaginationProps['sizeChangerRender'] = (info) => {
const {
disabled,
size: pageSize,
onSizeChange,
'aria-label': ariaLabel,
className: sizeChangerClassName,
options,
} = info;

const { className: propSizeChangerClassName, onChange: propSizeChangerOnChange } =
mergedShowSizeChangerSelectProps || {};

// Origin Select is using Select.Option,
// So it make the option value must be string
// Just for compatible
const selectedValue = options.find(
(option) => String(option.value) === String(pageSize),
)?.value;

return (
<SizeChanger
disabled={disabled}
showSearch
popupMatchSelectWidth={false}
getPopupContainer={(triggerNode) => triggerNode.parentNode}
aria-label={ariaLabel}
options={options}
{...mergedShowSizeChangerSelectProps}
value={selectedValue}
onChange={(nextSize, option) => {
onSizeChange?.(nextSize);
propSizeChangerOnChange?.(nextSize, option);
}}
size={isSmall ? 'small' : 'middle'}
className={classNames(sizeChangerClassName, propSizeChangerClassName)}
/>
);
};

if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('Pagination');

warning(
!selectComponentClass,
'usage',
'`selectComponentClass` is not official api which will be removed.',
);
}

// ============================= Render =============================
const iconsProps = React.useMemo<Record<PropertyKey, React.ReactNode>>(() => {
const ellipsis = <span className={`${prefixCls}-item-ellipsis`}>•••</span>;
const prevIcon = (
Expand Down Expand Up @@ -103,14 +189,6 @@ const Pagination: React.FC<PaginationProps> = (props) => {
return { prevIcon, nextIcon, jumpPrevIcon, jumpNextIcon };
}, [direction, prefixCls]);

const [contextLocale] = useLocale('Pagination', enUS);

const locale = { ...contextLocale, ...customLocale };

const mergedSize = useSize(customizeSize);

const isSmall = mergedSize === 'small' || !!(xs && !mergedSize && responsive);

const selectPrefixCls = getPrefixCls('select', customizeSelectPrefixCls);

const extendedClassName = classNames(
Expand Down Expand Up @@ -139,9 +217,10 @@ const Pagination: React.FC<PaginationProps> = (props) => {
prefixCls={prefixCls}
selectPrefixCls={selectPrefixCls}
className={extendedClassName}
selectComponentClass={selectComponentClass || (isSmall ? MiniSelect : MiddleSelect)}
locale={locale}
pageSizeOptions={mergedPageSizeOptions}
showSizeChanger={mergedShowSizeChanger}
sizeChangerRender={sizeChangerRender}
/>
</>,
);
Expand Down
16 changes: 0 additions & 16 deletions components/pagination/Select.tsx

This file was deleted.

22 changes: 22 additions & 0 deletions components/pagination/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ describe('Pagination', () => {
});

it('should support custom selectComponentClass', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});

const CustomSelect: React.FC<{ className?: string }> & { Option: OptionFC } = ({
className,
...props
Expand All @@ -67,6 +69,11 @@ describe('Pagination', () => {
<Pagination defaultCurrent={1} total={500} selectComponentClass={CustomSelect} />,
);
expect(container.querySelectorAll('.custom-select').length).toBeTruthy();
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Pagination] `selectComponentClass` is not official api which will be removed.',
);

errorSpy.mockRestore();
});

describe('ConfigProvider', () => {
Expand Down Expand Up @@ -104,4 +111,19 @@ describe('Pagination', () => {
expect(container.querySelector('.ant-pagination-end')).toBeTruthy();
});
});

it('showSizeChanger support showSearch=false', () => {
const { container } = render(
<Pagination
defaultCurrent={1}
total={500}
showSizeChanger={{
showSearch: false,
}}
/>,
);

// Expect `input` is `readonly`
expect(container.querySelector('.ant-select input')).toHaveAttribute('readonly');
});
});
2 changes: 1 addition & 1 deletion components/pagination/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Common props ref:[Common props](/docs/react/common-props)
| hideOnSinglePage | Whether to hide pager on single page | boolean | false | |
| itemRender | To customize item's innerHTML | (page, type: 'page' \| 'prev' \| 'next', originalElement) => React.ReactNode | - | |
| pageSize | Number of data items per page | number | - | |
| pageSizeOptions | Specify the sizeChanger options | string\[] \| number\[] | \[`10`, `20`, `50`, `100`] | |
| pageSizeOptions | Specify the sizeChanger options | number\[] | \[`10`, `20`, `50`, `100`] | |
| responsive | If `size` is not specified, `Pagination` would resize according to the width of the window | boolean | - | |
| showLessItems | Show less page items | boolean | false | |
| showQuickJumper | Determine whether you can jump to pages directly | boolean \| { goButton: ReactNode } | false | |
Expand Down
2 changes: 1 addition & 1 deletion components/pagination/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*WM86SrBC8TsAAA
| hideOnSinglePage | 只有一页时是否隐藏分页器 | boolean | false | |
| itemRender | 用于自定义页码的结构,可用于优化 SEO | (page, type: 'page' \| 'prev' \| 'next', originalElement) => React.ReactNode | - | |
| pageSize | 每页条数 | number | - | |
| pageSizeOptions | 指定每页可以显示多少条 | string\[] \| number\[] | \[`10`, `20`, `50`, `100`] | |
| pageSizeOptions | 指定每页可以显示多少条 | number\[] | \[`10`, `20`, `50`, `100`] | |
| responsive | 当 size 未指定时,根据屏幕宽度自动调整尺寸 | boolean | - | |
| showLessItems | 是否显示较少页面内容 | boolean | false | |
| showQuickJumper | 是否可以快速跳转至某页 | boolean \| { goButton: ReactNode } | false | |
Expand Down
18 changes: 18 additions & 0 deletions components/pagination/useShowSizeChanger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useMemo } from 'react';

import type { PaginationProps } from '.';
import type { SelectProps } from '../select';

export default function useShowSizeChanger(showSizeChanger?: PaginationProps['showSizeChanger']) {
return useMemo<[show: boolean | undefined, selectProps: SelectProps | undefined]>(() => {
if (typeof showSizeChanger === 'boolean') {
return [showSizeChanger, {}];
}

if (showSizeChanger && typeof showSizeChanger === 'object') {
return [true, showSizeChanger];
}

return [undefined, undefined];
}, [showSizeChanger]);
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
"rc-menu": "~9.16.0",
"rc-motion": "^2.9.3",
"rc-notification": "~5.6.2",
"rc-pagination": "~4.3.0",
"rc-pagination": "~5.0.0",
"rc-picker": "~4.8.3",
"rc-progress": "~4.0.0",
"rc-rate": "~2.13.0",
Expand Down

0 comments on commit 846dc9b

Please sign in to comment.