1 | <template>
|
2 | <div
|
3 | :class="[
|
4 | 'el-color-picker',
|
5 | colorDisabled ? 'is-disabled' : '',
|
6 | colorSize ? `el-color-picker--${ colorSize }` : ''
|
7 | ]"
|
8 | v-clickoutside="hide">
|
9 | <div class="el-color-picker__mask" v-if="colorDisabled"></div>
|
10 | <div class="el-color-picker__trigger" @click="handleTrigger">
|
11 | <span class="el-color-picker__color" :class="{ 'is-alpha': showAlpha }">
|
12 | <span class="el-color-picker__color-inner"
|
13 | :style="{
|
14 | backgroundColor: displayedColor
|
15 | }"></span>
|
16 | <span class="el-color-picker__empty el-icon-close" v-if="!value && !showPanelColor"></span>
|
17 | </span>
|
18 | <span class="el-color-picker__icon el-icon-arrow-down" v-show="value || showPanelColor"></span>
|
19 | </div>
|
20 | <picker-dropdown
|
21 | ref="dropdown"
|
22 | :class="['el-color-picker__panel', popperClass || '']"
|
23 | v-model="showPicker"
|
24 | @pick="confirmValue"
|
25 | @clear="clearValue"
|
26 | :color="color"
|
27 | :show-alpha="showAlpha"
|
28 | :predefine="predefine">
|
29 | </picker-dropdown>
|
30 | </div>
|
31 | </template>
|
32 |
|
33 | <script>
|
34 | import Color from './color';
|
35 | import PickerDropdown from './components/picker-dropdown.vue';
|
36 | import Clickoutside from 'element-ui/src/utils/clickoutside';
|
37 | import Emitter from 'element-ui/src/mixins/emitter';
|
38 |
|
39 | export default {
|
40 | name: 'ElColorPicker',
|
41 |
|
42 | mixins: [Emitter],
|
43 |
|
44 | props: {
|
45 | value: String,
|
46 | showAlpha: Boolean,
|
47 | colorFormat: String,
|
48 | disabled: Boolean,
|
49 | size: String,
|
50 | popperClass: String,
|
51 | predefine: Array
|
52 | },
|
53 |
|
54 | inject: {
|
55 | elForm: {
|
56 | default: ''
|
57 | },
|
58 | elFormItem: {
|
59 | default: ''
|
60 | }
|
61 | },
|
62 |
|
63 | directives: { Clickoutside },
|
64 |
|
65 | computed: {
|
66 | displayedColor() {
|
67 | if (!this.value && !this.showPanelColor) {
|
68 | return 'transparent';
|
69 | }
|
70 |
|
71 | return this.displayedRgb(this.color, this.showAlpha);
|
72 | },
|
73 |
|
74 | _elFormItemSize() {
|
75 | return (this.elFormItem || {}).elFormItemSize;
|
76 | },
|
77 |
|
78 | colorSize() {
|
79 | return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
|
80 | },
|
81 |
|
82 | colorDisabled() {
|
83 | return this.disabled || (this.elForm || {}).disabled;
|
84 | }
|
85 | },
|
86 |
|
87 | watch: {
|
88 | value(val) {
|
89 | if (!val) {
|
90 | this.showPanelColor = false;
|
91 | } else if (val && val !== this.color.value) {
|
92 | this.color.fromString(val);
|
93 | }
|
94 | },
|
95 | color: {
|
96 | deep: true,
|
97 | handler() {
|
98 | this.showPanelColor = true;
|
99 | }
|
100 | },
|
101 | displayedColor(val) {
|
102 | if (!this.showPicker) return;
|
103 | const currentValueColor = new Color({
|
104 | enableAlpha: this.showAlpha,
|
105 | format: this.colorFormat
|
106 | });
|
107 | currentValueColor.fromString(this.value);
|
108 |
|
109 | const currentValueColorRgb = this.displayedRgb(currentValueColor, this.showAlpha);
|
110 | if (val !== currentValueColorRgb) {
|
111 | this.$emit('active-change', val);
|
112 | }
|
113 | }
|
114 | },
|
115 |
|
116 | methods: {
|
117 | handleTrigger() {
|
118 | if (this.colorDisabled) return;
|
119 | this.showPicker = !this.showPicker;
|
120 | },
|
121 | confirmValue() {
|
122 | const value = this.color.value;
|
123 | this.$emit('input', value);
|
124 | this.$emit('change', value);
|
125 | this.dispatch('ElFormItem', 'el.form.change', value);
|
126 | this.showPicker = false;
|
127 | },
|
128 | clearValue() {
|
129 | this.$emit('input', null);
|
130 | this.$emit('change', null);
|
131 | if (this.value !== null) {
|
132 | this.dispatch('ElFormItem', 'el.form.change', null);
|
133 | }
|
134 | this.showPanelColor = false;
|
135 | this.showPicker = false;
|
136 | this.resetColor();
|
137 | },
|
138 | hide() {
|
139 | this.showPicker = false;
|
140 | this.resetColor();
|
141 | },
|
142 | resetColor() {
|
143 | this.$nextTick(_ => {
|
144 | if (this.value) {
|
145 | this.color.fromString(this.value);
|
146 | } else {
|
147 | this.showPanelColor = false;
|
148 | }
|
149 | });
|
150 | },
|
151 | displayedRgb(color, showAlpha) {
|
152 | if (!(color instanceof Color)) {
|
153 | throw Error('color should be instance of Color Class');
|
154 | }
|
155 |
|
156 | const { r, g, b } = color.toRgb();
|
157 | return showAlpha
|
158 | ? `rgba(${ r }, ${ g }, ${ b }, ${ color.get('alpha') / 100 })`
|
159 | : `rgb(${ r }, ${ g }, ${ b })`;
|
160 | }
|
161 | },
|
162 |
|
163 | mounted() {
|
164 | const value = this.value;
|
165 | if (value) {
|
166 | this.color.fromString(value);
|
167 | }
|
168 | this.popperElm = this.$refs.dropdown.$el;
|
169 | },
|
170 |
|
171 | data() {
|
172 | const color = new Color({
|
173 | enableAlpha: this.showAlpha,
|
174 | format: this.colorFormat
|
175 | });
|
176 |
|
177 | return {
|
178 | color,
|
179 | showPicker: false,
|
180 | showPanelColor: false
|
181 | };
|
182 | },
|
183 |
|
184 | components: {
|
185 | PickerDropdown
|
186 | }
|
187 | };
|
188 | </script>
|