fix(Transfer): Dropdown is hidden & showSizeChanger not work (#41906)

* fix: Page size dropdown is hidden

* fix: SizeChange not work

* chore: add test case

---------

Co-authored-by: MadCcc <1075746765@qq.com>
This commit is contained in:
JiaQi 2023-06-28 19:23:00 +08:00 committed by GitHub
parent 6cbf3e102b
commit 91be823272
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 30 deletions

View File

@ -1,14 +1,17 @@
import classNames from 'classnames';
import * as React from 'react';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import type { KeyWiseTransferItem } from '.';
import type { PaginationType } from './interface';
import type { RenderedItem, TransferListProps } from './list';
import Pagination from '../pagination';
import ListItem from './ListItem';
import type { PaginationType } from './interface';
import type { RenderedItem, TransferListProps } from './list';
export const OmitProps = ['handleFilter', 'handleClear', 'checkedKeys'] as const;
export type OmitProp = typeof OmitProps[number];
export type OmitProp = (typeof OmitProps)[number];
type PartialTransferListProps<RecordType> = Omit<TransferListProps<RecordType>, OmitProp>;
type ExistPagination = Exclude<PaginationType, boolean>;
export interface TransferListBodyProps<RecordType> extends PartialTransferListProps<RecordType> {
filteredItems: RecordType[];
@ -16,25 +19,15 @@ export interface TransferListBodyProps<RecordType> extends PartialTransferListPr
selectedKeys: string[];
}
const parsePagination = (pagination?: PaginationType) => {
if (!pagination) {
return null;
}
const parsePagination = (pagination?: ExistPagination) => {
const defaultPagination: PaginationType = {
pageSize: 10,
simple: true,
showSizeChanger: false,
showLessItems: false,
};
if (typeof pagination === 'object') {
return { ...defaultPagination, ...pagination };
}
return defaultPagination;
return { ...defaultPagination, ...pagination };
};
export interface ListBodyRef<RecordType extends KeyWiseTransferItem> {
items?: RenderedItem<RecordType>[];
}
@ -57,16 +50,28 @@ const TransferListBody: React.ForwardRefRenderFunction<
onItemSelect,
onItemRemove,
} = props;
const [current, setCurrent] = React.useState<number>(1);
const mergedPagination = React.useMemo(() => {
if (!pagination) {
return null;
}
const convertPagination = typeof pagination === 'object' ? pagination : {};
return parsePagination(convertPagination);
}, [pagination]);
const [pageSize, setPageSize] = useMergedState<number>(10, {
value: mergedPagination?.pageSize,
});
React.useEffect(() => {
const mergedPagination = parsePagination(pagination);
if (mergedPagination) {
const maxPageCount = Math.ceil(filteredRenderItems.length / mergedPagination.pageSize!);
const maxPageCount = Math.ceil(filteredRenderItems.length / pageSize!);
setCurrent(Math.min(current, maxPageCount));
}
}, [filteredRenderItems, pagination]);
}, [filteredRenderItems, mergedPagination, pageSize]);
const onClick = (item: RecordType) => {
onItemSelect?.(item.key, !selectedKeys.includes(item.key));
@ -80,33 +85,33 @@ const TransferListBody: React.ForwardRefRenderFunction<
setCurrent(cur);
};
const onSizeChange = (cur: number, size: number) => {
setCurrent(cur);
setPageSize(size);
};
const memoizedItems = React.useMemo<RenderedItem<RecordType>[]>(() => {
const mergedPagination = parsePagination(pagination);
const displayItems = mergedPagination
? filteredRenderItems.slice(
(current - 1) * mergedPagination.pageSize!,
current * mergedPagination.pageSize!,
)
? filteredRenderItems.slice((current - 1) * pageSize!, current * pageSize!)
: filteredRenderItems;
return displayItems;
}, [current, filteredRenderItems, pagination]);
}, [current, filteredRenderItems, mergedPagination, pageSize]);
React.useImperativeHandle(ref, () => ({ items: memoizedItems }));
const mergedPagination = parsePagination(pagination);
const paginationNode: React.ReactNode = mergedPagination ? (
<Pagination
size="small"
disabled={globalDisabled}
simple={mergedPagination.simple}
pageSize={mergedPagination.pageSize}
pageSize={pageSize}
showLessItems={mergedPagination.showLessItems}
showSizeChanger={mergedPagination.showSizeChanger}
className={`${prefixCls}-pagination`}
total={filteredRenderItems.length}
current={current}
onChange={onPageChange}
onShowSizeChange={onSizeChange}
/>
) : null;

View File

@ -73,6 +73,19 @@ const searchTransferProps = {
targetKeys: ['3', '4'],
};
const generateData = (n = 20) => {
const data = [];
for (let i = 0; i < n; i++) {
data.push({
key: `${i}`,
title: `content${i}`,
description: `description of content${i}`,
chosen: false,
});
}
return data;
};
describe('Transfer', () => {
mountTest(Transfer);
rtlTest(Transfer);
@ -595,6 +608,32 @@ describe('Transfer', () => {
);
await waitFor(() => expect(getAllByTitle('1/1')).toHaveLength(2));
});
it('should support change pageSize', () => {
const dataSource = generateData();
const { container } = render(
<Transfer dataSource={dataSource} pagination={{ showSizeChanger: true, simple: false }} />,
);
fireEvent.mouseDown(container.querySelector('.ant-select-selector')!);
fireEvent.click(container.querySelectorAll('.ant-select-item-option')[1]);
expect(container.querySelectorAll('.ant-transfer-list-content-item').length).toBe(20);
});
it('should be used first when pagination has pagesize', () => {
const dataSource = generateData(30);
const { container } = render(
<Transfer
dataSource={dataSource}
pagination={{ showSizeChanger: true, simple: false, pageSize: 20 }}
/>,
);
fireEvent.mouseDown(container.querySelector('.ant-select-selector')!);
fireEvent.click(container.querySelectorAll('.ant-select-item-option')[2]);
expect(container.querySelectorAll('.ant-transfer-list-content-item').length).toBe(20);
});
});
it('remove by click icon', () => {

View File

@ -110,7 +110,6 @@ const TransferList = <RecordType extends KeyWiseTransferItem>(
} = props;
const [filterValue, setFilterValue] = useState<string>('');
const listBodyRef = useRef<ListBodyRef<RecordType>>({});
const internalHandleFilter = (e: React.ChangeEvent<HTMLInputElement>) => {

View File

@ -101,6 +101,7 @@ const genTransferListStyle: GenerateStyle<TransferToken> = (token: TransferToken
marginXS,
paddingSM,
lineType,
antCls,
iconCls,
motionDurationSlow,
controlItemBgHover,
@ -174,8 +175,9 @@ const genTransferListStyle: GenerateStyle<TransferToken> = (token: TransferToken
display: 'flex',
flex: 'auto',
flexDirection: 'column',
overflow: 'hidden',
fontSize: token.fontSize,
// https://blog.csdn.net/qq449245884/article/details/107373672/
minHeight: 0,
'&-search-wrapper': {
position: 'relative',
@ -262,6 +264,10 @@ const genTransferListStyle: GenerateStyle<TransferToken> = (token: TransferToken
padding: `${token.paddingXS}px 0`,
textAlign: 'end',
borderTop: `${lineWidth}px ${lineType} ${colorSplit}`,
[`${antCls}-pagination-options`]: {
paddingInlineEnd: token.paddingXS,
},
},
'&-body-not-found': {