From 41ee8ea046f1413c6c5e67bbb5d58579e3d14ec8 Mon Sep 17 00:00:00 2001
From: tangjinzhou <415800467@qq.com>
Date: Mon, 7 Jan 2019 20:58:18 +0800
Subject: [PATCH] feat: transfer change `searchChange` to `search`
---
.../__tests__/__snapshots__/demo.test.js.snap | 10 +-
.../__snapshots__/index.test.js.snap | 16 +---
.../__tests__/__snapshots__/list.test.js.snap | 4 +-
.../__snapshots__/search.test.js.snap | 3 +-
components/transfer/__tests__/index.test.js | 10 +-
components/transfer/__tests__/search.test.js | 91 +++++++++++++++++++
components/transfer/demo/basic.md | 8 +-
components/transfer/demo/index.vue | 26 ++++--
components/transfer/demo/search.md | 4 +
components/transfer/index.en-US.md | 4 +-
components/transfer/index.jsx | 11 ++-
components/transfer/index.zh-CN.md | 4 +-
components/transfer/list.jsx | 30 ++----
components/transfer/search.jsx | 11 ++-
14 files changed, 156 insertions(+), 76 deletions(-)
diff --git a/components/transfer/__tests__/__snapshots__/demo.test.js.snap b/components/transfer/__tests__/__snapshots__/demo.test.js.snap
index 31106cf8b..413ff2593 100644
--- a/components/transfer/__tests__/__snapshots__/demo.test.js.snap
+++ b/components/transfer/__tests__/__snapshots__/demo.test.js.snap
@@ -30,9 +30,6 @@ exports[`renders ./components/transfer/demo/advanced.md correctly 1`] = `
-
- 没数据
-
@@ -79,7 +76,6 @@ exports[`renders ./components/transfer/demo/basic.md correctly 1`] = `
- Not Found
-
+
`;
@@ -132,7 +127,6 @@ exports[`renders ./components/transfer/demo/custom-item.md correctly 1`] = `
- Not Found
`;
@@ -28,9 +24,7 @@ exports[`Transfer should show sorted targetkey 1`] = `
`;
diff --git a/components/transfer/__tests__/__snapshots__/list.test.js.snap b/components/transfer/__tests__/__snapshots__/list.test.js.snap
index bd3aac36d..4f5da4fa6 100644
--- a/components/transfer/__tests__/__snapshots__/list.test.js.snap
+++ b/components/transfer/__tests__/__snapshots__/list.test.js.snap
@@ -6,8 +6,6 @@ exports[`List should render correctly 1`] = `
+
`;
diff --git a/components/transfer/__tests__/__snapshots__/search.test.js.snap b/components/transfer/__tests__/__snapshots__/search.test.js.snap
index 8a5504fe9..345f13b20 100644
--- a/components/transfer/__tests__/__snapshots__/search.test.js.snap
+++ b/components/transfer/__tests__/__snapshots__/search.test.js.snap
@@ -4,7 +4,6 @@ exports[`Search should show cross icon when input value exists 1`] = `
`;
diff --git a/components/transfer/__tests__/index.test.js b/components/transfer/__tests__/index.test.js
index 51b483d47..5ad9ebf3a 100644
--- a/components/transfer/__tests__/index.test.js
+++ b/components/transfer/__tests__/index.test.js
@@ -222,7 +222,7 @@ describe('Transfer', () => {
Vue.nextTick(() => {
const input = wrapper.findAll('.ant-transfer-list-body-search-wrapper input').at(0)
input.element.value = 'a'
- input.trigger('change')
+ input.trigger('input')
Vue.nextTick(() => {
expect(wrapper.findAll('.ant-transfer-list-content')
.at(0)
@@ -248,7 +248,7 @@ describe('Transfer', () => {
Vue.nextTick(() => {
const input = wrapper.findAll('.ant-transfer-list-body-search-wrapper input').at(0)
input.element.value = 'content2'
- input.trigger('change')
+ input.trigger('input')
Vue.nextTick(() => {
expect(wrapper.findAll('.ant-transfer-list')
.at(0)
@@ -280,7 +280,7 @@ describe('Transfer', () => {
Vue.nextTick(() => {
const input = wrapper.findAll('.ant-transfer-list-body-search-wrapper input').at(0)
input.element.value = 'content2'
- input.trigger('change')
+ input.trigger('input')
Vue.nextTick(() => {
wrapper.findAll('.ant-transfer-list')
.at(0)
@@ -318,7 +318,7 @@ describe('Transfer', () => {
Vue.nextTick(() => {
const input = wrapper.findAll('.ant-transfer-list-body-search-wrapper input').at(0)
input.element.value = 'content2'
- input.trigger('change')
+ input.trigger('input')
Vue.nextTick(() => {
wrapper.findAll('.ant-transfer-list')
.at(0)
@@ -358,7 +358,7 @@ describe('Transfer', () => {
const input = wrapper.findAll('.ant-transfer-list-body-search-wrapper input').at(0)
input.element.value = 'a'
- input.trigger('change')
+ input.trigger('input')
Vue.nextTick(() => {
wrapper.findAll('.ant-transfer-list')
.at(0)
diff --git a/components/transfer/__tests__/search.test.js b/components/transfer/__tests__/search.test.js
index bcbed8c23..3e0b81d7b 100644
--- a/components/transfer/__tests__/search.test.js
+++ b/components/transfer/__tests__/search.test.js
@@ -1,7 +1,19 @@
import { mount } from '@vue/test-utils'
+import { asyncExpect } from '@/tests/utils'
import Search from '../search'
+import Transfer from '../index'
describe('Search', () => {
+ const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {})
+
+ afterEach(() => {
+ errorSpy.mockReset()
+ })
+
+ afterAll(() => {
+ errorSpy.mockRestore()
+ })
+
it('should show cross icon when input value exists', () => {
const props = {
propsData: {
@@ -16,4 +28,83 @@ describe('Search', () => {
expect(wrapper.html()).toMatchSnapshot()
})
+
+ it('onSearch', async () => {
+ const dataSource = [
+ {
+ key: 'a',
+ title: 'a',
+ description: 'a',
+ },
+ {
+ key: 'b',
+ title: 'b',
+ description: 'b',
+ },
+ {
+ key: 'c',
+ title: 'c',
+ description: 'c',
+ },
+ ]
+
+ const onSearch = jest.fn()
+ const wrapper = mount({
+ render () {
+ return item.title}
+ onSearch={onSearch}
+ showSearch
+ />
+ },
+ }, {
+ sync: false,
+ })
+ await asyncExpect(() => {
+ const input = wrapper
+ .findAll('.ant-input')
+ .at(0)
+ input.element.value = 'a'
+ input.trigger('input')
+ })
+
+ await asyncExpect(() => {
+ expect(onSearch).toBeCalledWith('left', 'a')
+ })
+
+ onSearch.mockReset()
+
+ wrapper
+ .findAll('.ant-transfer-list-search-action')
+ .at(0)
+ .trigger('click')
+ expect(onSearch).toBeCalledWith('left', '')
+ })
+
+ it('legacy onSearchChange', () => {
+ const onSearchChange = jest.fn()
+
+ const wrapper = mount({
+ render () {
+ return item.title} onSearchChange={onSearchChange} showSearch />
+ },
+ }, {
+ sync: false,
+ })
+
+ const input = wrapper
+ .findAll('.ant-input')
+ .at(0)
+ input.element.value = 'a'
+ input.trigger('input')
+
+ expect(errorSpy.mock.calls[0][0]).toMatch(
+ 'Warning: `searchChange` in Transfer is deprecated. Please use `search` instead.',
+ )
+ expect(onSearchChange.mock.calls[0][0]).toEqual('left')
+ expect(onSearchChange.mock.calls[0][1].target.value).toEqual('a')
+ })
})
diff --git a/components/transfer/demo/basic.md b/components/transfer/demo/basic.md
index 61d371988..b1f8bfd69 100644
--- a/components/transfer/demo/basic.md
+++ b/components/transfer/demo/basic.md
@@ -22,7 +22,13 @@ The most basic usage of `Transfer` involves providing the source data and target
:render="item=>item.title"
:disabled="disabled"
/>
-
+
diff --git a/components/transfer/index.en-US.md b/components/transfer/index.en-US.md
index 36f0160e1..8be0fa733 100644
--- a/components/transfer/index.en-US.md
+++ b/components/transfer/index.en-US.md
@@ -9,7 +9,7 @@
| lazy | property of vc-lazy-load for lazy rendering items. Turn off it by set to `false`. | object\|boolean | `{ height: 32, offset: 32 }` |
| listStyle | A custom CSS style used for rendering the transfer columns. | object | |
| locale | i18n text including filter, empty text, item unit, etc | object | `{ itemUnit: 'item', itemsUnit: 'items', notFoundContent: 'The list is empty', searchPlaceholder: 'Search here' }` |
-| operations | A set of operations that are sorted from bottom to top. | string\[] | ['>', '<'] |
+| operations | A set of operations that are sorted from top to bottom. | string\[] | ['>', '<'] |
| render | The function to generate the item shown on a column. Based on an record (element of the dataSource array), this function should return a element which is generated from that record. Also, it can return a plain object with `value` and `label`, `label` is a element and `value` is for title | Function(record) | |
| selectedKeys | A set of keys of selected items. | string\[] | \[] |
| showSearch | If included, a search box is shown on each column. | boolean | false |
@@ -21,7 +21,7 @@
| --- | --- | --- |
| change | A callback function that is executed when the transfer between columns is complete. | (targetKeys, direction, moveKeys): void | |
| scroll | A callback function which is executed when scroll options list | (direction, event): void | |
-| searchChange | A callback function which is executed when search field are changed | (direction: 'left'\|'right', event: Event): void | - |
+| search | A callback function which is executed when search field are changed | (direction: 'left'\|'right', value: string): void | - |
| selectChange | A callback function which is executed when selected items are changed. | (sourceSelectedKeys, targetSelectedKeys): void | |
## Warning
diff --git a/components/transfer/index.jsx b/components/transfer/index.jsx
index c38159189..9953522b6 100644
--- a/components/transfer/index.jsx
+++ b/components/transfer/index.jsx
@@ -6,6 +6,7 @@ import List from './list'
import Operation from './operation'
import LocaleReceiver from '../locale-provider/LocaleReceiver'
import defaultLocale from '../locale-provider/default'
+import warning from '../_util/warning'
export const TransferDirection = 'left' | 'right'
@@ -225,11 +226,16 @@ const Transfer = {
},
handleFilter (direction, e) {
+ const value = e.target.value
this.setState({
// add filter
- [`${direction}Filter`]: e.target.value,
+ [`${direction}Filter`]: value,
})
- this.$emit('searchChange', direction, e)
+ if (this.$listeners.searchChange) {
+ warning(false, '`searchChange` in Transfer is deprecated. Please use `search` instead.')
+ this.$emit('searchChange', direction, e)
+ }
+ this.$emit('search', direction, value)
},
handleLeftFilter (e) {
@@ -243,6 +249,7 @@ const Transfer = {
this.setState({
[`${direction}Filter`]: '',
})
+ this.$emit('search', direction, '')
},
handleLeftClear () {
diff --git a/components/transfer/index.zh-CN.md b/components/transfer/index.zh-CN.md
index 4fcc227fc..97699ac2b 100644
--- a/components/transfer/index.zh-CN.md
+++ b/components/transfer/index.zh-CN.md
@@ -9,7 +9,7 @@
| lazy | Transfer 使用了 [vc-lazy-load]优化性能,这里可以设置相关参数。设为 `false` 可以关闭懒加载。 | object\|boolean | `{ height: 32, offset: 32 }` |
| listStyle | 两个穿梭框的自定义样式 | object | |
| locale | 各种语言 | object | `{ itemUnit: '项', itemsUnit: '项', notFoundContent: '列表为空', searchPlaceholder: '请输入搜索内容' }` |
-| operations | 操作文案集合,顺序从下至上 | string\[] | ['>', '<'] |
+| operations | 操作文案集合,顺序从上至下 | string\[] | ['>', '<'] |
| render | 每行数据渲染函数,该函数的入参为 `dataSource` 中的项,返回值为 element。或者返回一个普通对象,其中 `label` 字段为 element,`value` 字段为 title | Function(record) | |
| selectedKeys | 设置哪些项应该被选中 | string\[] | \[] |
| showSearch | 是否显示搜索框 | boolean | false |
@@ -21,7 +21,7 @@
| --- | --- | --- |
| change | 选项在两栏之间转移时的回调函数 | (targetKeys, direction, moveKeys): void | |
| scroll | 选项列表滚动时的回调函数 | (direction, event): void | |
-| searchChange | 搜索框内容时改变时的回调函数 | (direction: 'left'\|'right', event: Event): void | - |
+| search | 搜索框内容时改变时的回调函数 | (direction: 'left'\|'right', value: string): void | - |
| selectChange | 选中项发生改变时的回调函数 | (sourceSelectedKeys, targetSelectedKeys): void | |
## 注意
diff --git a/components/transfer/list.jsx b/components/transfer/list.jsx
index 5f7adc89c..3256206ba 100644
--- a/components/transfer/list.jsx
+++ b/components/transfer/list.jsx
@@ -9,10 +9,6 @@ import Item from './item'
import triggerEvent from '../_util/triggerEvent'
import addEventListener from '../_util/Dom/addEventListener'
-function isIEorEDGE () {
- return document.documentMode || /Edge/.test(navigator.userAgent)
-}
-
function noop () {
}
@@ -87,7 +83,6 @@ export default {
beforeDestroy () {
clearTimeout(this.timer)
clearTimeout(this.triggerScrollTimer)
- clearTimeout(this.fixIERepaintTimer)
if (this.scrollEvent) {
this.scrollEvent.remove()
}
@@ -135,11 +130,9 @@ export default {
triggerEvent(listNode, 'scroll')
}
}, 0)
- this.fixIERepaint()
},
_handleClear (e) {
this.handleClear(e)
- this.fixIERepaint()
},
matchFilter (text, item) {
const { filter, filterOption } = this.$props
@@ -157,20 +150,6 @@ export default {
renderedEl: isRenderResultPlain ? renderResult.label : renderResult,
}
},
-
- // Fix IE/Edge repaint
- // https://github.com/ant-design/ant-design/issues/9697
- // https://stackoverflow.com/q/27947912/3040605
- fixIERepaint () {
- if (!isIEorEDGE()) {
- return
- }
- this.fixIERepaintTimer = window.setTimeout(() => {
- if (this.$refs.notFoundNode) {
- this.$refs.notFoundNode.className = this.$refs.notFoundNode.className
- }
- }, 0)
- },
filterNull (arr) {
return arr.filter((item) => {
return item !== null
@@ -235,6 +214,7 @@ export default {
handleClear={this.handleClear}
placeholder={searchPlaceholder}
value={filter}
+ disabled={disabled}
/>
) : null
@@ -242,6 +222,10 @@ export default {
const transitionProps = getTransitionProps(transitionName, {
leave: noop,
})
+
+ const searchNotFound = showItems.every(item => item === null) && (
+ {notFoundContent}
+ )
const listBody = bodyDom || (
{showItems}
-
- {notFoundContent}
-
+ {searchNotFound}
)
diff --git a/components/transfer/search.jsx b/components/transfer/search.jsx
index dca35f726..d09a2b534 100644
--- a/components/transfer/search.jsx
+++ b/components/transfer/search.jsx
@@ -8,6 +8,7 @@ export const TransferSearchProps = {
placeholder: PropTypes.string,
value: PropTypes.any,
handleClear: PropTypes.func,
+ disabled: PropTypes.bool,
}
export default {
@@ -21,16 +22,17 @@ export default {
},
handleClear2 (e) {
e.preventDefault()
- if (this.handleClear) {
- this.handleClear(e)
+ const { handleClear, disabled } = this.$props
+ if (!disabled && handleClear) {
+ handleClear(e)
}
},
},
render () {
- const { placeholder, value, prefixCls } = getOptionProps(this)
+ const { placeholder, value, prefixCls, disabled } = getOptionProps(this)
const icon = (value && value.length > 0) ? (
-
+
) : (
@@ -44,6 +46,7 @@ export default {
value={value}
ref='input'
onChange={this.handleChange}
+ disabled={disabled}
/>
{icon}