From 2ce740f37f1fce2661dc4e4e9bd4f9321f4cf410 Mon Sep 17 00:00:00 2001 From: mark <44559440+mark-ck@users.noreply.github.com> Date: Thu, 10 Feb 2022 10:33:21 +0800 Subject: [PATCH] feat(Transfer): transfer support different search config between panels (#3724), close #3664 --- docs/transfer/demo/search.md | 4 ++-- docs/transfer/index.en-us.md | 6 +++--- docs/transfer/index.md | 6 +++--- src/transfer/view/transfer.jsx | 26 ++++++++++++++---------- test/transfer/index-spec.js | 36 ++++++++++++++++++++++++++++++++++ types/transfer/index.d.ts | 16 ++++++++++++--- 6 files changed, 73 insertions(+), 21 deletions(-) diff --git a/docs/transfer/demo/search.md b/docs/transfer/demo/search.md index 57406bc5a4..5bbc55c08c 100644 --- a/docs/transfer/demo/search.md +++ b/docs/transfer/demo/search.md @@ -43,9 +43,9 @@ class Demo extends React.Component { } render() { - return (); + }} defaultValue={['3']} dataSource={dataSource} defaultLeftChecked={['1']} onChange={this.handleChange} titles={['Searchable', 'Searchable']} notFoundContent={['left not found', 'right not found']} />); } } diff --git a/docs/transfer/index.en-us.md b/docs/transfer/index.en-us.md index fcd09c4681..eb6e779ec0 100644 --- a/docs/transfer/index.en-us.md +++ b/docs/transfer/index.en-us.md @@ -26,12 +26,12 @@ Move the items in two panels in an intuitive way to select. | onChange | callback function triggered when value change

**signatures**:
Function(value: Array, data: Array, extra: Object) => void
**params**:
_value_: {Array} value of right panel
_data_: {Array} data of right panel
_extra_: {Object} extra parmas
_extra.leftValue_: {Array} value of left panel
_extra.leftData_: {Array} data of left panel
_extra.movedValue_: {Array} moved value
_extra.movedData_: {Object} moved data
_extra.direction_: {String} move direction, 'left' or 'right' | Function | - | | onSelect | callback function triggered when item checked

**signatures**:
Function(sourceSelectedValue: Array, targetSelectedValue: Array, trigger: String) => void
**params**:
_sourceSelectedValue_: {Array} value of checked items in source panel
_targetSelectedValue_: {Array} value of checked items in target panel
_trigger_: {String} trigger panel `source|target`
| Function | - | | itemRender | item render function

**signatures**:
Function(data: Object) => ReactNode
**params**:
_data_: {Object} data
**returns**:
{ReactNode} content of item
| Function | data => data.label | -| showSearch | whether to show the search box | Boolean | false | -| searchProps | props passed to Search when showSearch is true | Object | - | +| showSearch | whether to show the search box | Boolean/Array<Boolean> | false | +| searchProps | props passed to Search when showSearch is true | Object/Array<Object> | - | | filter | custom search function

**signatures**:
Function(searchedValue: String, data: Object) => Boolean
**params**:
_searchedValue_: {String} search keyword
_data_: {Object} data
**returns**:
{Boolean} whether is matched
| Function | filter by label | | onSearch | callback function triggered when search

**signatures**:
Function(searchedValue: String, position: String) => void
**params**:
_searchedValue_: {String} search keyword
_position_: {String} position of the search box | Function | () => {} | | searchPlaceholder | placeholder of the search box | String | - | -| notFoundContent | content when list is empty | ReactNode | 'Not Found' | +| notFoundContent | content when list is empty | ReactNode/Array<ReactNode> | 'Not Found' | | titles | titles of left and right panel | Array<ReactNode> | \[] | | operations | text of move buttons | Array<ReactNode> | [<Icon type="arrow-right" />, <Icon type="arrow-left" />] | | defaultLeftChecked | default checked value of left panel | Array<String> | \[] | diff --git a/docs/transfer/index.md b/docs/transfer/index.md index 8b50d9cc32..54acca1c6e 100644 --- a/docs/transfer/index.md +++ b/docs/transfer/index.md @@ -31,12 +31,12 @@ | leftDisabled | 是否禁用左侧面板 | Boolean | false | | rightDisabled | 是否禁用右侧面板 | Boolean | false | | itemRender | 列表项渲染函数

**签名**:
Function(data: Object) => ReactNode
**参数**:
_data_: {Object} 数据
**返回值**:
{ReactNode} 列表项内容
| Function | data => data.label | -| showSearch | 是否显示搜索框 | Boolean | false | -| searchProps | 搜索框配置项,同 Search 组件 props | Object | - | +| showSearch | 是否显示搜索框 | Boolean/Array<Boolean> | false | +| searchProps | 搜索框配置项,同 Search 组件 props | Object/Array<Object> | - | | filter | 自定义搜索函数

**签名**:
Function(searchedValue: String, data: Object) => Boolean
**参数**:
_searchedValue_: {String} 搜索的内容
_data_: {Object} 数据
**返回值**:
{Boolean} 是否匹配到
| Function | 根据 label 属性匹配 | | onSearch | 搜索框输入时触发的回调函数

**签名**:
Function(searchedValue: String, position: String) => void
**参数**:
_searchedValue_: {String} 搜索的内容
_position_: {String} 搜索面板的位置 | Function | () => {} | | searchPlaceholder | 搜索框占位符 | String | - | -| notFoundContent | 列表为空显示内容 | ReactNode | 'Not Found' | +| notFoundContent | 列表为空显示内容 | ReactNode/Array<ReactNode> | 'Not Found' | | titles | 左右面板标题 | Array<ReactNode> | \[] | | operations | 向右向左移动按钮显示内容 | Array<ReactNode> | [<Icon type="arrow-right" />, <Icon type="arrow-left" />] | | defaultLeftChecked | 左面板默认选中值 | Array<String> | \[] | diff --git a/src/transfer/view/transfer.jsx b/src/transfer/view/transfer.jsx index 6fefa78aa1..ed7b12fa4a 100644 --- a/src/transfer/view/transfer.jsx +++ b/src/transfer/view/transfer.jsx @@ -110,13 +110,13 @@ class Transfer extends Component { */ itemRender: PropTypes.func, /** - * 是否显示搜索框 + * 左右面板是否显示搜索框 */ - showSearch: PropTypes.bool, + showSearch: PropTypes.bool | PropTypes.arrayOf(PropTypes.bool), /** - * 搜索框配置项,同 Search 组件 props + * 左右面板搜索框配置项,同 Search 组件 props */ - searchProps: PropTypes.object, + searchProps: PropTypes.object | PropTypes.arrayOf(PropTypes.object), /** * 自定义搜索函数 * @param {String} searchedValue 搜索的内容 @@ -138,7 +138,7 @@ class Transfer extends Component { /** * 列表为空显示内容 */ - notFoundContent: PropTypes.node, + notFoundContent: PropTypes.node | PropTypes.arrayOf(PropTypes.node), /** * 左右面板标题 */ @@ -506,8 +506,8 @@ class Transfer extends Component { className, dataSource, locale, - showSearch, - searchProps, + showSearch = false, + searchProps = {}, filter, onSearch, leftDisabled, @@ -533,12 +533,9 @@ class Transfer extends Component { prefix, mode, locale, - showSearch, - searchProps, filter, onSearch, searchPlaceholder, - notFoundContent, listClassName, listStyle, itemRender, @@ -557,6 +554,9 @@ class Transfer extends Component { if (rtl) { others.dir = 'rtl'; } + const _showSearch = Array.isArray(showSearch) ? showSearch : [showSearch, showSearch]; + const _searchProps = Array.isArray(searchProps) ? searchProps : [searchProps, searchProps]; + const _notFoundContent = Array.isArray(notFoundContent) ? notFoundContent : [notFoundContent, notFoundContent]; return (
{this.renderCenter()} @@ -574,6 +577,9 @@ class Transfer extends Component { dataSource={rightDatasource} disabled={rightDisabled || disabled} value={rightCheckedValue} + showSearch={_showSearch[1]} + searchProps={_searchProps[1]} + notFoundContent={_notFoundContent[1]} title={titles[1]} />
diff --git a/test/transfer/index-spec.js b/test/transfer/index-spec.js index b7ca4061e2..7a96c9b75a 100644 --- a/test/transfer/index-spec.js +++ b/test/transfer/index-spec.js @@ -153,6 +153,42 @@ describe('Transfer', () => { assert(findItemText(wrapper, 0, 1) === 'abc'); }); + it('should render search box when set showSearch(array)', () => { + const dataSource = [ + { label: 'a', value: '0' }, + { label: 'b', value: '1' }, + { label: abc, value: '2' }, + ]; + + wrapper = mount( + + ); + + assert(wrapper.find('span.next-search').length === 1); + const search = findPanel(wrapper, 0).find('span.next-search'); + const input = search.find('input'); + if (input.instance().placeholder) { + assert(input.instance().placeholder === 'input something...'); + } + input.simulate('change', { target: { value: 'a' } }); + + assert(findItems(wrapper, 0).length === 2); + assert(findItemText(wrapper, 0, 0) === 'a'); + assert(findItemText(wrapper, 0, 1) === 'abc'); + }); + it('should custom style and text', () => { const dataSource = [ { diff --git a/types/transfer/index.d.ts b/types/transfer/index.d.ts index cfea34f4cd..b0c8b0bf4a 100644 --- a/types/transfer/index.d.ts +++ b/types/transfer/index.d.ts @@ -55,9 +55,14 @@ export interface TransferProps extends HTMLAttributesWeak, CommonProps { itemRender?: (data: any) => React.ReactNode; /** - * 是否显示搜索框 + * 左右面板是否显示搜索框 */ - showSearch?: boolean; + showSearch?: boolean | boolean[]; + + /** + * 左右面板搜索框配置 + */ + searchProps?: Record | Record[]; /** * 自定义搜索函数 @@ -69,6 +74,11 @@ export interface TransferProps extends HTMLAttributesWeak, CommonProps { */ onSearch?: (searchedValue: string, position: string) => void; + /** + * 是否开启虚拟滚动 + */ + useVirtual?: boolean, + /** * 搜索框占位符 */ @@ -77,7 +87,7 @@ export interface TransferProps extends HTMLAttributesWeak, CommonProps { /** * 列表为空显示内容 */ - notFoundContent?: React.ReactNode; + notFoundContent?: React.ReactNode | React.ReactNode[]; /** * 左右面板标题