UNPKG

vuetify

Version:

Vue Material Component Framework

189 lines (173 loc) 4.57 kB
// Styles import './VColorPickerEdit.sass' // Components import VBtn from '../VBtn' import VIcon from '../VIcon' // Helpers import { parseHex } from '../../util/colorUtils' // Types import Vue, { VNode, PropType } from 'vue' import { VColorPickerColor, fromRGBA, fromHexa, fromHSLA } from './util' type Input = [string, number, string] export type Mode = { inputs?: Input[] from: Function } export const modes = { rgba: { inputs: [ ['r', 255, 'int'], ['g', 255, 'int'], ['b', 255, 'int'], ['a', 1, 'float'], ], from: fromRGBA, }, hsla: { inputs: [ ['h', 360, 'int'], ['s', 1, 'float'], ['l', 1, 'float'], ['a', 1, 'float'], ], from: fromHSLA, }, hexa: { from: fromHexa, }, } as { [key: string]: Mode } export default Vue.extend({ name: 'v-color-picker-edit', props: { color: Object as PropType<VColorPickerColor>, disabled: Boolean, hideAlpha: Boolean, hideModeSwitch: Boolean, mode: { type: String, default: 'rgba', validator: (v: string) => Object.keys(modes).includes(v), }, }, data () { return { modes, internalMode: this.mode, } }, computed: { currentMode (): Mode { return this.modes[this.internalMode] }, }, watch: { mode (mode) { this.internalMode = mode }, }, created () { this.internalMode = this.mode }, methods: { getValue (v: any, type: string) { if (type === 'float') return Math.round(v * 100) / 100 else if (type === 'int') return Math.round(v) else return 0 }, parseValue (v: string, type: string) { if (type === 'float') return parseFloat(v) else if (type === 'int') return parseInt(v, 10) || 0 else return 0 }, changeMode () { const modes = Object.keys(this.modes) const index = modes.indexOf(this.internalMode) const newMode = modes[(index + 1) % modes.length] this.internalMode = newMode this.$emit('update:mode', newMode) }, genInput (target: string, attrs: any, value: any, on: any): VNode { return this.$createElement('div', { staticClass: 'v-color-picker__input', }, [ this.$createElement('input', { key: target, attrs, domProps: { value, }, on, }), this.$createElement('span', target.toUpperCase()), ]) }, genInputs (): VNode[] | VNode { if (this.internalMode === 'hexa') { const hex = this.color.hexa const value = this.hideAlpha && hex.endsWith('FF') ? hex.substr(0, 7) : hex return this.genInput( 'hex', { maxlength: this.hideAlpha ? 7 : 9, disabled: this.disabled, }, value, { change: (e: Event) => { const el = e.target as HTMLInputElement this.$emit('update:color', this.currentMode.from(parseHex(el.value))) }, } ) } else { const inputs = this.hideAlpha ? this.currentMode.inputs!.slice(0, -1) : this.currentMode.inputs! return inputs.map(([target, max, type]) => { const value = this.color[this.internalMode as keyof VColorPickerColor] as any return this.genInput( target, { type: 'number', min: 0, max, step: type === 'float' ? '0.01' : type === 'int' ? '1' : undefined, disabled: this.disabled, }, this.getValue(value[target], type), { input: (e: Event) => { const el = e.target as HTMLInputElement const newVal = this.parseValue(el.value || '0', type) this.$emit('update:color', this.currentMode.from( Object.assign({}, value, { [target]: newVal }), this.color.alpha )) }, } ) }) } }, genSwitch (): VNode { return this.$createElement(VBtn, { props: { small: true, icon: true, disabled: this.disabled, }, on: { click: this.changeMode, }, }, [ this.$createElement(VIcon, '$unfold'), ]) }, }, render (h): VNode { return h('div', { staticClass: 'v-color-picker__edit', }, [ this.genInputs(), !this.hideModeSwitch && this.genSwitch(), ]) }, })