Browse Source

ColorPicker: support user input (#6167)

* ColorPicker: support user input

* support alpha

* Update picker-dropdown.vue
Dreamacro 8 năm trước cách đây
mục cha
commit
78e947bcac

+ 44 - 2
packages/color-picker/src/components/picker-dropdown.vue

@@ -9,7 +9,14 @@
       </div>
       <alpha-slider v-if="showAlpha" ref="alpha" :color="color"></alpha-slider>
       <div class="el-color-dropdown__btns">
-        <span class="el-color-dropdown__value">{{ currentColor }}</span>
+        <span class="el-color-dropdown__value">
+          <el-input
+            v-model="customInput"
+            @keyup.native.enter="handleConfirm"
+            @blur="handleConfirm"
+            size="mini">
+          </el-input>
+        </span>
         <a href="JavaScript:" class="el-color-dropdown__link-btn" @click="$emit('clear')">{{ t('el.colorpicker.clear') }}</a>
         <button class="el-color-dropdown__btn" @click="confirmValue">{{ t('el.colorpicker.confirm') }}</button>
       </div>
@@ -23,6 +30,7 @@
   import AlphaSlider from './alpha-slider';
   import Popper from 'element-ui/src/utils/vue-popper';
   import Locale from 'element-ui/src/mixins/locale';
+  import ElInput from 'element-ui/packages/input';
 
   export default {
     name: 'el-color-picker-dropdown',
@@ -32,7 +40,8 @@
     components: {
       SvPanel,
       HueSlider,
-      AlphaSlider
+      AlphaSlider,
+      ElInput
     },
 
     props: {
@@ -42,6 +51,12 @@
       showAlpha: Boolean
     },
 
+    data() {
+      return {
+        customInput: ''
+      };
+    },
+
     computed: {
       currentColor() {
         const parent = this.$parent;
@@ -52,6 +67,29 @@
     methods: {
       confirmValue() {
         this.$emit('pick');
+      },
+
+      handleConfirm() {
+        const valid = this.showAlpha ? this.validRGBA(this.customInput) : this.validRGBHex(this.customInput);
+        if (valid) {
+          this.color.fromString(this.customInput);
+        } else {
+          this.customInput = this.currentColor;
+        }
+      },
+
+      validRGBHex(color) {
+        return /^#[A-Fa-f0-9]{6}$/.test(color);
+      },
+
+      validRGBA(color) {
+        const matches = color.match(/^rgba\((\d+), ?(\d+), ?(\d+), ?([.0-9]+)\)$/);
+        if (!matches) return false;
+        const list = matches.map(v => parseInt(v, 10)).slice(1);
+        if (list.some(v => isNaN(v))) return false;
+        const [r, g, b, a] = list;
+        if ([r, g, b].some(v => v < 0 || v > 255) || a < 0 || a > 1) return false;
+        return true;
       }
     },
 
@@ -70,6 +108,10 @@
             alpha && alpha.update();
           });
         }
+      },
+
+      currentColor(val) {
+        this.customInput = val;
       }
     }
   };

+ 2 - 2
test/unit/specs/color-picker.spec.js

@@ -97,8 +97,8 @@ describe('ColorPicker', () => {
     trigger.click();
 
     setTimeout(() => {
-      const value = document.querySelector('.el-color-dropdown__value');
-      expect(value.innerText.trim().toUpperCase()).to.equal('#20A0FF');
+      const input = document.querySelector('.el-color-dropdown__value input');
+      expect(input.value.trim().toUpperCase()).to.equal('#20A0FF');
       done();
     }, ANIMATION_TIME);
   });