From 26ea8409e1958ef2bb6f1da06f14c5d063e041db Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Thu, 28 Mar 2019 20:56:06 +0800 Subject: [PATCH] feat: update transfer --- components/transfer/index.en-US.md | 2 +- components/transfer/index.jsx | 22 +++- components/transfer/index.zh-CN.md | 4 +- components/transfer/list.jsx | 19 ++-- components/transfer/search.jsx | 1 - components/transfer/style/index.js | 1 + components/transfer/style/index.less | 59 +++++----- components/upload/style/index.less | 159 ++++++++++++++------------- 8 files changed, 145 insertions(+), 122 deletions(-) diff --git a/components/transfer/index.en-US.md b/components/transfer/index.en-US.md index 8be0fa733..d58b03728 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 top to bottom. | 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 | diff --git a/components/transfer/index.jsx b/components/transfer/index.jsx index 927648b70..404a0b764 100644 --- a/components/transfer/index.jsx +++ b/components/transfer/index.jsx @@ -11,6 +11,7 @@ import List from './list'; import Operation from './operation'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; import defaultLocale from '../locale-provider/default'; +import { ConfigConsumerProps } from '../config-provider'; import warning from '../_util/warning'; export const TransferDirection = 'left' | 'right'; @@ -57,6 +58,9 @@ const Transfer = { locale: {}, showSearch: false, }), + inject: { + configProvider: { default: () => ({}) }, + }, data() { // vue 中 通过slot,不方便传递,保留notFoundContent及searchPlaceholder // warning( @@ -312,9 +316,12 @@ const Transfer = { return direction === 'left' ? 'sourceSelectedKeys' : 'targetSelectedKeys'; }, - getLocale(transferLocale) { + getLocale(transferLocale, renderEmpty) { + const h = this.$createElement; // Keep old locale props still working. - const oldLocale = {}; + const oldLocale = { + notFoundContent: renderEmpty(h, 'Transfer'), + }; const notFoundContent = getComponentFromProp(this, 'notFoundContent'); if (notFoundContent) { oldLocale.notFoundContent = notFoundContent; @@ -329,7 +336,7 @@ const Transfer = { renderTransfer(transferLocale) { const props = getOptionProps(this); const { - prefixCls = 'ant-transfer', + prefixCls: customizePrefixCls, disabled, operations = [], showSearch, @@ -338,7 +345,14 @@ const Transfer = { filterOption, lazy, } = props; - const locale = this.getLocale(transferLocale); + const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls; + const prefixCls = getPrefixCls('transfer', customizePrefixCls); + + const renderEmpty = ( + this.configProvider.renderEmpty && + this.configProvider.renderEmpty() + ) || ConfigConsumerProps.renderEmpty; + const locale = this.getLocale(transferLocale, renderEmpty); const { leftFilter, rightFilter, diff --git a/components/transfer/index.zh-CN.md b/components/transfer/index.zh-CN.md index 97699ac2b..43d2848f8 100644 --- a/components/transfer/index.zh-CN.md +++ b/components/transfer/index.zh-CN.md @@ -9,12 +9,12 @@ | 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 | | targetKeys | 显示在右侧框数据的key集合 | string\[] | \[] | -| titles | 标题集合,顺序从左至右 | string\[] | ['', ''] | +| titles | 标题集合,顺序从左至右 | string\[] | \['', ''] | ### 事件 | 事件名称 | 说明 | 回调参数 | diff --git a/components/transfer/list.jsx b/components/transfer/list.jsx index f97ed380a..0c4653e67 100644 --- a/components/transfer/list.jsx +++ b/components/transfer/list.jsx @@ -243,14 +243,17 @@ export default { )} > {search} - - {showItems} - + { + !searchNotFound && + + {showItems} + + } {searchNotFound} ); diff --git a/components/transfer/search.jsx b/components/transfer/search.jsx index d453112fb..7ee509ac4 100644 --- a/components/transfer/search.jsx +++ b/components/transfer/search.jsx @@ -47,7 +47,6 @@ export default { placeholder={placeholder} class={prefixCls} value={value} - ref="input" onChange={this.handleChange} disabled={disabled} /> diff --git a/components/transfer/style/index.js b/components/transfer/style/index.js index bd8cd93d5..b7eb1d789 100644 --- a/components/transfer/style/index.js +++ b/components/transfer/style/index.js @@ -2,6 +2,7 @@ import '../../style/index.less'; import './index.less'; // style dependencies +import '../../empty/style'; import '../../checkbox/style'; import '../../button/style'; import '../../input/style'; diff --git a/components/transfer/style/index.less b/components/transfer/style/index.less index b0f285afe..e0caae4d3 100644 --- a/components/transfer/style/index.less +++ b/components/transfer/style/index.less @@ -15,14 +15,14 @@ } &-list { - border: @border-width-base @border-style-base @border-color-base; - display: inline-block; - border-radius: @border-radius-base; - vertical-align: middle; position: relative; + display: inline-block; width: 180px; height: 200px; padding-top: 34px; + vertical-align: middle; + border: @border-width-base @border-style-base @border-color-base; + border-radius: @border-radius-base; &-with-footer { padding-bottom: 34px; @@ -31,17 +31,17 @@ &-search { padding: 0 @control-padding-horizontal-sm; &-action { - color: @disabled-color; position: absolute; top: 4px; right: 4px; bottom: 4px; width: 28px; + color: @disabled-color; line-height: @input-height-base; text-align: center; .@{iconfont-css-prefix} { - transition: all 0.3s; color: @disabled-color; + transition: all 0.3s; &:hover { color: @text-color-secondary; } @@ -53,16 +53,16 @@ } &-header { - padding: 6px @control-padding-horizontal; - border-radius: @border-radius-base @border-radius-base 0 0; - background: @component-background; - color: @text-color; - border-bottom: @border-width-base @border-style-base @border-color-split; - overflow: hidden; position: absolute; top: 0; left: 0; width: 100%; + padding: 6px @control-padding-horizontal; + overflow: hidden; + color: @text-color; + background: @component-background; + border-bottom: @border-width-base @border-style-base @border-color-split; + border-radius: @border-radius-base @border-radius-base 0 0; &-title { position: absolute; @@ -71,16 +71,16 @@ } &-body { - font-size: @font-size-base; position: relative; height: 100%; + font-size: @font-size-base; &-search-wrapper { position: absolute; top: 0; left: 0; - padding: 4px; width: 100%; + padding: 4px; } } @@ -90,20 +90,20 @@ &-content { height: 100%; + margin: 0; + padding: 0; overflow: auto; list-style: none; - padding: 0; - margin: 0; > .LazyLoad { animation: transferHighlightIn 1s; } &-item { + min-height: 32px; + padding: 6px @control-padding-horizontal; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; - padding: 6px @control-padding-horizontal; - min-height: 32px; transition: all 0.3s; > span { padding-right: 0; @@ -111,40 +111,45 @@ } &-item:not(&-item-disabled):hover { - cursor: pointer; background-color: @item-hover-bg; + cursor: pointer; } &-item-disabled { - cursor: not-allowed; color: @btn-disable-color; + cursor: not-allowed; } } &-body-not-found { - padding-top: 0; - color: @disabled-color; - text-align: center; position: absolute; top: 50%; width: 100%; - margin-top: -10px; + padding-top: 0; + color: @disabled-color; + text-align: center; + transform: translateY(-50%); + + // with filter should offset the search box height + .@{transfer-prefix-cls}-list-body-with-search & { + margin-top: @input-height-base / 2; + } } &-footer { - border-top: @border-width-base @border-style-base @border-color-split; - border-radius: 0 0 @border-radius-base @border-radius-base; position: absolute; bottom: 0; left: 0; width: 100%; + border-top: @border-width-base @border-style-base @border-color-split; + border-radius: 0 0 @border-radius-base @border-radius-base; } } &-operation { display: inline-block; - overflow: hidden; margin: 0 8px; + overflow: hidden; vertical-align: middle; .@{ant-prefix}-btn { diff --git a/components/upload/style/index.less b/components/upload/style/index.less index 181ee0f6f..de4a6a3b5 100644 --- a/components/upload/style/index.less +++ b/components/upload/style/index.less @@ -3,7 +3,8 @@ @upload-prefix-cls: ~'@{ant-prefix}-upload'; @upload-item: ~'@{ant-prefix}-upload-list-item'; -@upload-pictrue-card-size: 104px; +@upload-picture-card-size: 104px; +@upload-picture-card-border-style: @border-style-base; .@{upload-prefix-cls} { .reset-component; @@ -28,26 +29,26 @@ } &&-select-picture-card { + display: table; + width: @upload-picture-card-size; + height: @upload-picture-card-size; + margin-right: 8px; + margin-bottom: 8px; + text-align: center; + vertical-align: top; + background-color: @background-color-light; border: @border-width-base dashed @border-color-base; - width: @upload-pictrue-card-size; - height: @upload-pictrue-card-size; border-radius: @border-radius-base; - background-color: @background-color-light; - text-align: center; cursor: pointer; transition: border-color 0.3s ease; - vertical-align: top; - margin-right: 8px; - margin-bottom: 8px; - display: table; > .@{upload-prefix-cls} { + display: table-cell; width: 100%; height: 100%; - display: table-cell; + padding: 8px; text-align: center; vertical-align: middle; - padding: 8px; } &:hover { @@ -56,15 +57,15 @@ } &&-drag { - border: @border-width-base dashed @border-color-base; - transition: border-color 0.3s; - cursor: pointer; - border-radius: @border-radius-base; - text-align: center; + position: relative; width: 100%; height: 100%; - position: relative; + text-align: center; background: @background-color-light; + border: @border-width-base dashed @border-color-base; + border-radius: @border-radius-base; + cursor: pointer; + transition: border-color 0.3s; .@{upload-prefix-cls} { padding: 16px 0; @@ -94,24 +95,24 @@ p.@{upload-prefix-cls}-drag-icon { .@{iconfont-css-prefix} { - font-size: 48px; color: @primary-5; + font-size: 48px; } margin-bottom: 20px; } p.@{upload-prefix-cls}-text { - font-size: @font-size-lg; margin: 0 0 4px; color: @heading-color; + font-size: @font-size-lg; } p.@{upload-prefix-cls}-hint { - font-size: @font-size-base; color: @text-color-secondary; + font-size: @font-size-base; } .@{iconfont-css-prefix}-plus { + color: @disabled-color; font-size: 30px; transition: all 0.3s; - color: @disabled-color; &:hover { color: @text-color-secondary; } @@ -126,17 +127,17 @@ .reset-component; .clearfix; &-item { - margin-top: 8px; - font-size: @font-size-base; position: relative; height: 22px; + margin-top: 8px; + font-size: @font-size-base; &-name { + display: inline-block; + width: 100%; + padding-left: @font-size-base + 8px; overflow: hidden; - text-overflow: ellipsis; white-space: nowrap; - padding-left: @font-size-base + 8px; - width: 100%; - display: inline-block; + text-overflow: ellipsis; } &-info { @@ -150,23 +151,23 @@ .@{iconfont-css-prefix}-loading, .@{iconfont-css-prefix}-paper-clip { - font-size: @font-size-base; - color: @text-color-secondary; position: absolute; top: @font-size-base / 2 - 2px; + color: @text-color-secondary; + font-size: @font-size-base; } } .@{iconfont-css-prefix}-close { .iconfont-size-under-12px(10px); - transition: all 0.3s; - opacity: 0; - cursor: pointer; position: absolute; top: 6px; right: 4px; color: @text-color-secondary; line-height: 0; + cursor: pointer; + opacity: 0; + transition: all 0.3s; &:hover { color: @text-color; } @@ -187,28 +188,28 @@ } &-error .@{iconfont-css-prefix}-close { - opacity: 1; color: @error-color !important; + opacity: 1; } &-progress { - line-height: 0; - font-size: @font-size-base; position: absolute; - width: 100%; bottom: -12px; + width: 100%; padding-left: @font-size-base + 12px; + font-size: @font-size-base; + line-height: 0; } } &-picture, &-picture-card { .@{upload-item} { + position: relative; + height: 66px; padding: 8px; + border: @border-width-base @upload-picture-card-border-style @border-color-base; border-radius: @border-radius-base; - border: @border-width-base @border-style-base @border-color-base; - height: 66px; - position: relative; &:hover { background: transparent; } @@ -230,44 +231,44 @@ } .@{upload-item}-thumbnail { - width: 48px; - height: 48px; position: absolute; top: 8px; left: 8px; - text-align: center; - line-height: 54px; + width: 48px; + height: 48px; font-size: 26px; + line-height: 54px; + text-align: center; opacity: 0.8; } .@{upload-item}-icon { - font-size: 26px; position: absolute; top: 50%; left: 50%; + font-size: 26px; transform: translate(-50%, -50%); } .@{upload-item}-thumbnail img { + display: block; width: 48px; height: 48px; - display: block; overflow: hidden; } .@{upload-item}-name { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; + display: inline-block; + box-sizing: border-box; + max-width: 100%; margin: 0 0 0 8px; + padding-right: 8px; + padding-left: 48px; + overflow: hidden; line-height: 44px; + white-space: nowrap; + text-overflow: ellipsis; transition: all 0.3s; - padding-left: 48px; - padding-right: 8px; - max-width: 100%; - display: inline-block; - box-sizing: border-box; } .@{upload-item}-uploading .@{upload-item}-name { @@ -275,16 +276,16 @@ } .@{upload-item}-progress { - padding-left: 56px; - margin-top: 0; bottom: 14px; width: ~'calc(100% - 24px)'; + margin-top: 0; + padding-left: 56px; } .@{iconfont-css-prefix}-close { position: absolute; - right: 8px; top: 8px; + right: 8px; line-height: 1; opacity: 1; } @@ -294,58 +295,58 @@ // https://github.com/ant-design/ant-design/issues/11183 float: left; - &.@{upload-prefix-cls}-list:after { + &.@{upload-prefix-cls}-list::after { display: none; } .@{upload-item} { float: left; - width: @upload-pictrue-card-size; - height: @upload-pictrue-card-size; + width: @upload-picture-card-size; + height: @upload-picture-card-size; margin: 0 8px 8px 0; } .@{upload-item}-info { - height: 100%; position: relative; + height: 100%; overflow: hidden; - &:before { - content: ' '; + &::before { position: absolute; z-index: 1; - background-color: rgba(0, 0, 0, 0.5); - transition: all 0.3s; width: 100%; height: 100%; + background-color: fade(@black, 50%); opacity: 0; + transition: all 0.3s; + content: ' '; } } - .@{upload-item}:hover .@{upload-item}-info:before { + .@{upload-item}:hover .@{upload-item}-info::before { opacity: 1; } .@{upload-item}-actions { position: absolute; - left: 50%; top: 50%; - transform: translate(-50%, -50%); + left: 50%; z-index: 10; white-space: nowrap; + transform: translate(-50%, -50%); opacity: 0; transition: all 0.3s; .@{iconfont-css-prefix}-eye-o, .@{iconfont-css-prefix}-delete { z-index: 10; - transition: all 0.3s; - cursor: pointer; - font-size: 16px; width: 16px; - color: @text-color-dark; margin: 0 4px; + color: @text-color-dark; + font-size: 16px; + cursor: pointer; + transition: all 0.3s; &:hover { - color: #fff; + color: @text-color-inverse; } } } @@ -357,18 +358,18 @@ .@{upload-item}-thumbnail, .@{upload-item}-thumbnail img { + position: static; display: block; width: 100%; height: 100%; - position: static; } .@{upload-item}-name { + display: none; margin: 8px 0 0; padding: 0; - text-align: center; line-height: @line-height-base; - display: none; + text-align: center; } .anticon-picture + .@{upload-item}-name { @@ -382,7 +383,7 @@ .@{upload-item}-info { height: auto; - &:before, + &::before, .@{iconfont-css-prefix}-eye-o, .@{iconfont-css-prefix}-delete { display: none; @@ -396,8 +397,8 @@ } .@{upload-item}-progress { - padding-left: 0; bottom: 32px; + padding-left: 0; } } @@ -435,8 +436,8 @@ from { height: 0; margin: 0; - opacity: 0; padding: 0; + opacity: 0; } } @@ -454,8 +455,8 @@ width: 0; height: 0; margin: 0; - opacity: 0; padding: 0; + opacity: 0; } }