From 91be823272207ca8e7708fb37361919637ea4422 Mon Sep 17 00:00:00 2001 From: JiaQi <112228030+Yuiai01@users.noreply.github.com> Date: Wed, 28 Jun 2023 19:23:00 +0800 Subject: [PATCH] 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> --- components/transfer/ListBody.tsx | 61 +++++++++++--------- components/transfer/__tests__/index.test.tsx | 39 +++++++++++++ components/transfer/list.tsx | 1 - components/transfer/style/index.ts | 8 ++- 4 files changed, 79 insertions(+), 30 deletions(-) diff --git a/components/transfer/ListBody.tsx b/components/transfer/ListBody.tsx index e57c60c075..5708422f12 100644 --- a/components/transfer/ListBody.tsx +++ b/components/transfer/ListBody.tsx @@ -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 = Omit, OmitProp>; +type ExistPagination = Exclude; export interface TransferListBodyProps extends PartialTransferListProps { filteredItems: RecordType[]; @@ -16,25 +19,15 @@ export interface TransferListBodyProps 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 { items?: RenderedItem[]; } @@ -57,16 +50,28 @@ const TransferListBody: React.ForwardRefRenderFunction< onItemSelect, onItemRemove, } = props; - const [current, setCurrent] = React.useState(1); + const mergedPagination = React.useMemo(() => { + if (!pagination) { + return null; + } + + const convertPagination = typeof pagination === 'object' ? pagination : {}; + + return parsePagination(convertPagination); + }, [pagination]); + + const [pageSize, setPageSize] = useMergedState(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[]>(() => { - 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 ? ( ) : null; diff --git a/components/transfer/__tests__/index.test.tsx b/components/transfer/__tests__/index.test.tsx index 6920c8bb83..764df524d2 100644 --- a/components/transfer/__tests__/index.test.tsx +++ b/components/transfer/__tests__/index.test.tsx @@ -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( + , + ); + + 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( + , + ); + + 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', () => { diff --git a/components/transfer/list.tsx b/components/transfer/list.tsx index e10facd00b..7661e5b808 100644 --- a/components/transfer/list.tsx +++ b/components/transfer/list.tsx @@ -110,7 +110,6 @@ const TransferList = ( } = props; const [filterValue, setFilterValue] = useState(''); - const listBodyRef = useRef>({}); const internalHandleFilter = (e: React.ChangeEvent) => { diff --git a/components/transfer/style/index.ts b/components/transfer/style/index.ts index 5e050aed1e..96f18573ad 100644 --- a/components/transfer/style/index.ts +++ b/components/transfer/style/index.ts @@ -101,6 +101,7 @@ const genTransferListStyle: GenerateStyle = (token: TransferToken marginXS, paddingSM, lineType, + antCls, iconCls, motionDurationSlow, controlItemBgHover, @@ -174,8 +175,9 @@ const genTransferListStyle: GenerateStyle = (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 = (token: TransferToken padding: `${token.paddingXS}px 0`, textAlign: 'end', borderTop: `${lineWidth}px ${lineType} ${colorSplit}`, + + [`${antCls}-pagination-options`]: { + paddingInlineEnd: token.paddingXS, + }, }, '&-body-not-found': {