Procházet zdrojové kódy

Transfer: add chalk theme

Leopoldthecoder před 8 roky
rodič
revize
2df521482b

+ 4 - 4
examples/docs/en-US/transfer.md

@@ -1,7 +1,7 @@
 <style>
   .demo-transfer {
     .transfer-footer {
-      margin-left: 20px;
+      margin-left: 15px;
       padding: 6px 5px;
     }
   }
@@ -155,7 +155,7 @@ You can search and filter data items.
 
 You can customize list titles, button texts, render function for data items, checking status texts in list footer and list footer contents.
 
-:::demo Use `titles`, `button-texts`, `render-content` and `footer-format` to respectively customize list titles, button texts, render function for data items, checking status texts in list footer. For list footer contents, two named slots are provided: `left-footer` and `right-footer`. Plus, if you want some items initially checked, you can use `left-default-checked` and `right-default-checked`. Finally, this example demonstrate the `change` event. Note that this demo can't run in jsfiddle because it doesn't support JSX syntax. In a real project, `render-content` will work if relevant dependencies are correctly configured.
+:::demo Use `titles`, `button-texts`, `render-content` and `format` to respectively customize list titles, button texts, render function for data items, checking status texts in list header. For list footer contents, two named slots are provided: `left-footer` and `right-footer`. Plus, if you want some items initially checked, you can use `left-default-checked` and `right-default-checked`. Finally, this example demonstrate the `change` event. Note that this demo can't run in jsfiddle because it doesn't support JSX syntax. In a real project, `render-content` will work if relevant dependencies are correctly configured.
 ```html
 <template>
   <el-transfer
@@ -166,7 +166,7 @@ You can customize list titles, button texts, render function for data items, che
     :render-content="renderFunc"
     :titles="['Source', 'Target']"
     :button-texts="['To left', 'To right']"
-    :footer-format="{
+    :format="{
       noChecked: '${total}',
       hasChecked: '${checked}/${total}'
     }"
@@ -267,7 +267,7 @@ By default, Transfer looks for `key`, `label` and `disabled` in a data item. If
 | titles | custom list titles | array | — | ['List 1', 'List 2'] |
 | button-texts | custom button texts | array | — | [ ] |
 | render-content | custom render function for data items | function(h, option) | — | — |
-| footer-format | texts for checking status in list footer | object{noChecked, hasChecked} | — | { noChecked: '${total} items', hasChecked: '${checked}/${total} checked' } |
+| format | texts for checking status in list header | object{noChecked, hasChecked} | — | { noChecked: '${checked}/${total}', hasChecked: '${checked}/${total}' } |
 | props | prop aliases for data source | object{key, label, disabled} | — | — |
 | left-default-checked | key array of initially checked data items of the left list | array | — | [ ] |
 | right-default-checked | key array of initially checked data items of the right list | array | — | [ ] |

+ 4 - 4
examples/docs/zh-CN/transfer.md

@@ -1,7 +1,7 @@
 <style>
   .demo-transfer {
     .transfer-footer {
-      margin-left: 20px;
+      margin-left: 15px;
       padding: 6px 5px;
     }
   }
@@ -152,7 +152,7 @@
 
 可以对列表标题文案、按钮文案、数据项的渲染函数、列表底部的勾选状态文案、列表底部的内容区等进行自定义。
 
-:::demo 可以使用 `titles`、`button-texts`、`render-content` 和 `footer-format` 属性分别对列表标题文案、按钮文案、数据项的渲染函数和列表部的勾选状态文案进行自定义。对于列表底部的内容区,提供了两个具名 slot:`left-footer` 和 `right-footer`。此外,如果希望某些数据项在初始化时就被勾选,可以使用 `left-default-checked` 和 `right-default-checked` 属性。最后,本例还展示了 `change` 事件的用法。注意:由于 jsfiddle 不支持 JSX 语法,所以本例在 jsfiddle 中无法运行。但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。
+:::demo 可以使用 `titles`、`button-texts`、`render-content` 和 `format` 属性分别对列表标题文案、按钮文案、数据项的渲染函数和列表部的勾选状态文案进行自定义。对于列表底部的内容区,提供了两个具名 slot:`left-footer` 和 `right-footer`。此外,如果希望某些数据项在初始化时就被勾选,可以使用 `left-default-checked` 和 `right-default-checked` 属性。最后,本例还展示了 `change` 事件的用法。注意:由于 jsfiddle 不支持 JSX 语法,所以本例在 jsfiddle 中无法运行。但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。
 ```html
 <template>
   <el-transfer
@@ -163,7 +163,7 @@
     :render-content="renderFunc"
     :titles="['Source', 'Target']"
     :button-texts="['到左边', '到右边']"
-    :footer-format="{
+    :format="{
       noChecked: '${total}',
       hasChecked: '${checked}/${total}'
     }"
@@ -264,7 +264,7 @@
 | titles | 自定义列表标题 | array | — | ['列表 1', '列表 2'] |
 | button-texts | 自定义按钮文案 | array | — | [ ] |
 | render-content | 自定义数据项渲染函数 | function(h, option) | — | — |
-| footer-format | 列表底部勾选状态文案 | object{noChecked, hasChecked} | — | { noChecked: '共 ${total} 项', hasChecked: '已选 ${checked}/${total} 项' } |
+| format | 列表顶部勾选状态文案 | object{noChecked, hasChecked} | — | { noChecked: '${checked}/${total}', hasChecked: '${checked}/${total}' } |
 | props | 数据源的字段别名 | object{key, label, disabled} | — | — |
 | left-default-checked | 初始状态下左侧列表的已勾选项的 key 数组 | array | — | [ ] |
 | right-default-checked | 初始状态下右侧列表的已勾选项的 key 数组 | array | — | [ ] |

+ 11 - 7
packages/theme-chalk/src/common/var.scss

@@ -48,6 +48,10 @@ $--color-text-placeholder: #b4bccc;
 $--link-color: $--color-primary-light-2;
 $--link-hover-color: $--color-primary;
 
+/* Background
+-------------------------- */
+$--background-color-base: #f5f7fa;
+
 /* Border
 -------------------------- */
 $--border-width-base: 1px;
@@ -628,16 +632,16 @@ $--collapse-content-color: $--color-text-primary;
 
 /* Transfer
 --------------------------*/
-$--transfer-border-color: $--color-text-regular;
-$--transfer-box-shadow: $--box-shadow-base;
+$--transfer-border-color: $--border-color-lighter;
+$--transfer-border-radius: $--border-radius-base;
 $--transfer-panel-width: 200px;
-$--transfer-panel-header-height: 36px;
-$--transfer-panel-header-background: $--color-text-primary;
-$--transfer-panel-footer-height: 36px;
+$--transfer-panel-header-height: 40px;
+$--transfer-panel-header-background: $--background-color-base;
+$--transfer-panel-footer-height: 40px;
 $--transfer-panel-body-height: 246px;
-$--transfer-item-height: 32px;
+$--transfer-item-height: 30px;
 $--transfer-item-hover-background: $--color-text-secondary;
-$--transfer-filter-height: 22px;
+$--transfer-filter-height: 32px;
 
 /* Header
   --------------------------*/

+ 81 - 24
packages/theme-chalk/src/transfer.scss

@@ -12,19 +12,47 @@
   @include e(buttons) {
     display: inline-block;
     vertical-align: middle;
-    padding: 0 10px;
+    padding: 0 30px;
+  }
 
-    .el-button {
-      display: block;
-      margin: 0 auto;
-      padding: 8px 12px;
+  @include e(button) {
+    display: block;
+    margin: 0 auto;
+    padding: 10px;
+    border-radius: 50%;
+    color: $--color-white;
+    background-color: $--color-primary;
+    font-size: 0;
+
+    @include when(with-texts) {
+      border-radius: $--border-radius-base;
+    }
+
+    @include when(disabled) {
+      border: $--border-base;
+      background-color: $--background-color-base;
+      color: $--color-text-placeholder;
 
-      &:first-child {
-        margin-bottom: 6px;
+      &:hover {
+        border: $--border-base;
+        background-color: $--background-color-base;
+        color: $--color-text-placeholder;
       }
     }
 
-    .el-button [class*="el-icon-"] + span {
+    &:first-child {
+      margin-bottom: 10px;
+    }
+
+    &:nth-child(2) {
+      margin: 0;
+    }
+
+    i, span {
+      font-size: 14px;
+    }
+
+    & [class*="el-icon-"] + span {
       margin-left: 0;
     }
   }
@@ -32,8 +60,9 @@
 
 @include b(transfer-panel) {
   border: 1px solid $--transfer-border-color;
+  border-radius: $--transfer-border-radius;
+  overflow: hidden;
   background: $--color-white;
-  box-shadow: $--transfer-box-shadow;
   display: inline-block;
   vertical-align: middle;
   width: $--transfer-panel-width;
@@ -41,8 +70,11 @@
   position: relative;
 
   @include e(body) {
-    padding-bottom: $--transfer-panel-footer-height;
     height: $--transfer-panel-body-height;
+
+    @include when(with-footer) {
+      padding-bottom: $--transfer-panel-footer-height;
+    }
   }
 
   @include e(list) {
@@ -54,14 +86,15 @@
     box-sizing: border-box;
 
     @include when(filterable) {
-      height: #{$--transfer-panel-body-height - $--transfer-filter-height - 10px};
+      height: #{$--transfer-panel-body-height - $--transfer-filter-height - 20px};
+      padding-top: 0;
     }
   }
 
   @include e(item) {
     height: $--transfer-item-height;
     line-height: $--transfer-item-height;
-    padding-left: 20px;
+    padding-left: 15px;
     display: block;
 
     & + .el-transfer-panel__item {
@@ -69,11 +102,11 @@
     }
 
     &.el-checkbox {
-      color: $--color-black;
+      color: $--color-text-regular;
     }
 
     &:hover {
-      background: $--transfer-item-hover-background;
+      color: $--color-primary;
     }
 
     &.el-checkbox .el-checkbox__label {
@@ -81,19 +114,20 @@
       @include utils-ellipsis;
       display: block;
       box-sizing: border-box;
-      padding-left: 28px;
+      padding-left: 24px;
     }
 
     .el-checkbox__input {
       position: absolute;
-      top: 9px;
+      top: 8px;
     }
   }
 
   @include e(filter) {
-    margin-top: 10px;
+    margin-top: 15px;
+    margin-bottom: 5px;
     text-align: center;
-    padding: 0 10px;
+    padding: 0 15px;
     width: 100%;
     box-sizing: border-box;
 
@@ -102,10 +136,14 @@
       width: 100%;
       display: inline-block;
       box-sizing: border-box;
+      border-radius: #{$--transfer-filter-height / 2};
+      padding-right: 10px;
+      padding-left: 30px;
     }
 
     .el-input__icon {
-      right: 10px;
+      right: auto;
+      left: 15px;
     }
 
     .el-icon-circle-close {
@@ -118,10 +156,29 @@
     line-height: $--transfer-panel-header-height;
     background: $--transfer-panel-header-background;
     margin: 0;
-    padding-left: 20px;
+    padding-left: 15px;
     border-bottom: 1px solid $--transfer-border-color;
     box-sizing: border-box;
     color: $--color-black;
+
+    .el-checkbox {
+      display: block;
+      line-height: 40px;
+
+      .el-checkbox__label {
+        font-size: 16px;
+        color: $--color-text-primary;
+        font-weight: normal;
+
+        span {
+          float: right;
+          margin-right: 15px;
+          color: $--color-text-secondary;
+          font-size: 12px;
+          font-weight: normal;
+        }
+      }
+    }
   }
 
   .el-transfer-panel__footer {
@@ -139,7 +196,7 @@
 
     .el-checkbox {
       padding-left: 20px;
-      color: $--color-black;
+      color: $--color-text-regular;
     }
   }
 
@@ -147,12 +204,12 @@
     margin: 0;
     height: $--transfer-item-height;
     line-height: $--transfer-item-height;
-    padding: 6px 20px 0;
-    color: $--color-black;
+    padding: 6px 15px 0;
+    color: $--color-text-secondary;
   }
 
   .el-checkbox__label {
-    padding-left: 14px;
+    padding-left: 8px;
   }
 
   .el-checkbox__inner {

+ 7 - 3
packages/transfer/src/main.vue

@@ -12,7 +12,7 @@
     <div class="el-transfer__buttons">
       <el-button
         type="primary"
-        size="small"
+        :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
         @click.native="addToLeft"
         :disabled="rightChecked.length === 0">
         <i class="el-icon-arrow-left"></i>
@@ -20,7 +20,7 @@
       </el-button>
       <el-button
         type="primary"
-        size="small"
+        :class="['el-transfer__button', hasButtonTexts ? 'is-with-texts' : '']"
         @click.native="addToRight"
         :disabled="leftChecked.length === 0">
         <span v-if="buttonTexts[1] !== undefined">{{ buttonTexts[1] }}</span>
@@ -98,7 +98,7 @@
           return [];
         }
       },
-      footerFormat: {
+      format: {
         type: Object,
         default() {
           return {};
@@ -131,6 +131,10 @@
 
       targetData() {
         return this.data.filter(item => this.value.indexOf(item[this.props.key]) > -1);
+      },
+
+      hasButtonTexts() {
+        return this.buttonTexts.length === 2;
       }
     },
 

+ 18 - 13
packages/transfer/src/transfer-panel.vue

@@ -1,8 +1,16 @@
 <template>
   <div class="el-transfer-panel">
-    <p class="el-transfer-panel__header">{{ title }}</p>
+    <p class="el-transfer-panel__header">
+      <el-checkbox
+        v-model="allChecked"
+        @change="handleAllCheckedChange"
+        :indeterminate="isIndeterminate">
+        {{ title }}
+        <span>{{ checkedSummary }}</span>
+      </el-checkbox>
+    </p>
     
-    <div class="el-transfer-panel__body">
+    <div :class="['el-transfer-panel__body', hasFooter ? 'is-with-footer' : '']">
       <el-input
         class="el-transfer-panel__filter"
         v-model="query"
@@ -34,12 +42,7 @@
         class="el-transfer-panel__empty"
         v-show="data.length === 0 && !hasNoMatch">{{ t('el.transfer.noData') }}</p>
     </div>
-    
-    <p class="el-transfer-panel__footer">
-      <el-checkbox
-        v-model="allChecked"
-        @change="handleAllCheckedChange"
-        :indeterminate="isIndeterminate">{{ checkedSummary }}</el-checkbox>
+    <p class="el-transfer-panel__footer" v-if="hasFooter">
       <slot></slot>
     </p>
   </div>
@@ -95,7 +98,7 @@
       placeholder: String,
       title: String,
       filterable: Boolean,
-      footerFormat: Object,
+      format: Object,
       filterMethod: Function,
       defaultChecked: Array,
       props: Object
@@ -167,15 +170,13 @@
       checkedSummary() {
         const checkedLength = this.checked.length;
         const dataLength = this.data.length;
-        const { noChecked, hasChecked } = this.footerFormat;
+        const { noChecked, hasChecked } = this.format;
         if (noChecked && hasChecked) {
           return checkedLength > 0
             ? hasChecked.replace(/\${checked}/g, checkedLength).replace(/\${total}/g, dataLength)
             : noChecked.replace(/\${total}/g, dataLength);
         } else {
-          return checkedLength > 0
-            ? this.t('el.transfer.hasCheckedFormat', { total: dataLength, checked: checkedLength })
-            : this.t('el.transfer.noCheckedFormat', { total: dataLength });
+          return `${ checkedLength }/${ dataLength }`;
         }
       },
 
@@ -204,6 +205,10 @@
 
       disabledProp() {
         return this.props.disabled || 'disabled';
+      },
+
+      hasFooter() {
+        return !!this.$slots.default;
       }
     },
 

+ 6 - 5
test/unit/specs/transfer.spec.js

@@ -91,11 +91,11 @@ describe('Transfer', () => {
   });
 
   it('customize', () => {
-    vm = createTransfer('v-model="value" :titles="titles" :render-content="renderFunc" :footer-format="format"', {
+    vm = createTransfer('v-model="value" :titles="titles" :render-content="renderFunc" :format="format"', {
       data() {
         return {
           value: [2],
-          titles: ['1', '2'],
+          titles: ['1', '2'],
           format: { noChecked: 'no', hasChecked: 'has' },
           renderFunc(h, option) {
             return <span>{ option.key } - { option.label }</span>;
@@ -104,9 +104,10 @@ describe('Transfer', () => {
       }
     });
     const transfer = vm.$refs.transfer.$el;
-    expect(transfer.querySelector('.el-transfer-panel__header').innerText).to.equal('1');
-    expect(transfer.querySelector('.el-checkbox__label span').innerText).to.equal('1 - 备选项 1');
-    expect(transfer.querySelector('.el-transfer-panel__footer .el-checkbox__label').innerText).to.equal('no');
+    const label = transfer.querySelector('.el-transfer-panel__header .el-checkbox__label');
+    expect(label.innerText.indexOf('表1') > -1).to.true;
+    expect(transfer.querySelector('.el-transfer-panel__list .el-checkbox__label span').innerText).to.equal('1 - 备选项 1');
+    expect(label.querySelector('span').innerText).to.equal('no');
   });
 
   it('check', () => {