import PropTypes from '../_util/vue-types'; import { ConfigConsumerProps } from '../config-provider'; import BaseMixin from '../_util/BaseMixin'; import Pickr from '@simonwep/pickr/dist/pickr.es5.min'; import Icon from '../icon'; import LocaleReceiver from '../locale-provider/LocaleReceiver'; import enUS from './locale/en_US'; import debounce from 'lodash-es/debounce'; import { getOptionProps, findDOMNode } from '../_util/props-util'; let colors = '#194d33'; export default { name: 'AColorPicker', mixins: [BaseMixin], model: { prop: 'value', event: 'change.value', //为了支持v-model直接返回颜色字符串 所以用了自定义的事件,与pickr自带change事件进行区分 }, props: { prefixCls: PropTypes.string, defaultValue: PropTypes.string, //默认值 config: PropTypes.object, //pickr配置 value: PropTypes.string, //颜色值 locale: PropTypes.object, //双语包 colorRounded: PropTypes.number, //颜色数值保留几位小数 size: PropTypes.oneOf(['default', 'small', 'large']).def('default'), //尺寸 getPopupContainer: PropTypes.func, //指定渲染容器 disabled: PropTypes.bool.def(false), //是否禁用 format: PropTypes.string, //颜色格式设置 alpha: PropTypes.bool.def(false), //是否开启透明通道 hue: PropTypes.bool.def(true), //是否开启色彩预选 }, inject: { configProvider: { default: () => ConfigConsumerProps }, }, data() { return { colors, myOpen: false, pickr: null, i18n: enUS, }; }, watch: { 'configProvider.locale.ColorPicker': { handler(val) { if (this.locale) return; this.i18n = val; this.reInitialize(); }, }, locale(val) { this.i18n = val.ColorPicker || val.lang; this.reInitialize(); }, value(val) { this.setColor(val); }, disabled(val) { this.pickr[val ? 'disable' : 'enable'](); }, config: { handler() { this.reInitialize(); }, deep: true, }, format(val) { const type = val.toLocaleUpperCase(); let res = this.pickr.setColorRepresentation(type); if (res) { this.pickr.applyColor(); } else { throw new TypeError('format was invalid'); } }, }, mounted() { if (this.locale) { this.i18n = this.locale.ColorPicker || this.locale.lang; } this.createPickr(); this.eventsBinding(); }, destroyed() { this.pickr.destroyAndRemove(); }, methods: { reInitialize() { this.pickr.destroyAndRemove(); const dom = document.createElement('div'); dom.id = 'color-picker' + this._uid; const box = findDOMNode(this).querySelector('#color-picker-box' + this._uid); box.appendChild(dom); this.createPickr(); this.eventsBinding(); }, setColor: debounce(function(val) { this.pickr.setColor(val); }, 1000), eventsBinding() { const pickrEvents = [ 'init', 'hide', 'show', 'save', 'clear', 'change', 'changestop', 'cancel', 'swatchselect', ]; Object.keys(this.$listeners).forEach(event => { pickrEvents.includes(event) && this.pickr.on(event, this.$listeners[event]); }); }, createPickr() { const { getPopupContainer } = getOptionProps(this); const { getPopupContainer: getContextPopupContainer } = this.configProvider; const container = getPopupContainer || getContextPopupContainer; this.pickr = Pickr.create( Object.assign( { el: '#color-picker' + this._uid, container: (container && container(findDOMNode(this))) || document.body, theme: 'monolith', // or 'monolith', or 'nano' default: this.value || this.defaultValue || null, // 有默认颜色pickr才可以获取到_representation components: { // Main components preview: true, opacity: this.alpha, hue: this.hue, // Input / output Options interaction: { hex: true, rgba: true, input: true, clear: true, save: true, }, }, }, this.config, { i18n: this.i18n }, ), ) .on('save', (color, instance) => { if (color) { let _representation = instance._representation || 'HEXA'; color = color['to' + _representation]().toString(this.colorRounded || 0); } this.$emit('change.value', color || ''); }) .on('hide', () => { this.setState({ myOpen: false }); }); }, handleOpenChange() { const open = !this.myOpen; this.setState({ myOpen: open }); this.pickr[open ? 'show' : 'hide'](); this.$emit('openChange', open); }, getDefaultLocale() { const result = { ...enUS, ...this.$props.locale, }; result.lang = { ...result.lang, ...(this.$props.locale || {}).lang, }; return result; }, renderColorPicker() { const { prefixCls: customizePrefixCls } = this.$props; const { getPrefixCls } = this.configProvider; const prefixCls = getPrefixCls('color-picker', customizePrefixCls); const { disabled } = getOptionProps(this); const classString = { [prefixCls]: true, [`${prefixCls}-open`]: this.myOpen, [`${prefixCls}-lg`]: this.size === 'large', [`${prefixCls}-sm`]: this.size === 'small', [`${prefixCls}-disabled`]: this.disabled, }; return (