mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 11:10:01 +08:00
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:
parent
6cbf3e102b
commit
91be823272
@ -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;
|
||||
|
||||
|
@ -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', () => {
|
||||
|
@ -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>) => {
|
||||
|
@ -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': {
|
||||
|
Loading…
Reference in New Issue
Block a user