1 1
// Styles
2 1
import './VColorPickerEdit.sass'
3

4
// Components
5 1
import VBtn from '../VBtn'
6 1
import VIcon from '../VIcon'
7

8
// Helpers
9 1
import { parseHex } from '../../util/colorUtils'
10

11
// Types
12 1
import Vue, { VNode, PropType } from 'vue'
13 1
import { VColorPickerColor, fromRGBA, fromHexa, fromHSLA } from './util'
14

15
type Input = [string, number, string]
16

17
export type Mode = {
18
  inputs?: Input[]
19
  from: Function
20
}
21

22 1
export const modes = {
23
  rgba: {
24
    inputs: [
25
      ['r', 255, 'int'],
26
      ['g', 255, 'int'],
27
      ['b', 255, 'int'],
28
      ['a', 1, 'float'],
29
    ],
30
    from: fromRGBA,
31
  },
32
  hsla: {
33
    inputs: [
34
      ['h', 360, 'int'],
35
      ['s', 1, 'float'],
36
      ['l', 1, 'float'],
37
      ['a', 1, 'float'],
38
    ],
39
    from: fromHSLA,
40
  },
41
  hexa: {
42
    from: fromHexa,
43
  },
44
} as { [key: string]: Mode }
45

46 1
export default Vue.extend({
47
  name: 'v-color-picker-edit',
48

49
  props: {
50
    color: Object as PropType<VColorPickerColor>,
51
    disabled: Boolean,
52
    hideAlpha: Boolean,
53
    hideModeSwitch: Boolean,
54
    mode: {
55
      type: String,
56
      default: 'rgba',
57 1
      validator: (v: string) => Object.keys(modes).includes(v),
58
    },
59
  },
60

61 1
  data () {
62 1
    return {
63
      modes,
64
      internalMode: this.mode,
65
    }
66
  },
67

68
  computed: {
69 1
    currentMode (): Mode {
70 1
      return this.modes[this.internalMode]
71
    },
72
  },
73

74
  watch: {
75 1
    mode (mode) {
76 1
      this.internalMode = mode
77
    },
78
  },
79

80 1
  created () {
81 1
    this.internalMode = this.mode
82
  },
83

84
  methods: {
85 1
    getValue (v: any, type: string) {
86 1
      if (type === 'float') return Math.round(v * 100) / 100
87 1
      else if (type === 'int') return Math.round(v)
88 0
      else return 0
89
    },
90 1
    parseValue (v: string, type: string) {
91 1
      if (type === 'float') return parseFloat(v)
92 1
      else if (type === 'int') return parseInt(v, 10) || 0
93 0
      else return 0
94
    },
95 1
    changeMode () {
96 1
      const modes = Object.keys(this.modes)
97 1
      const index = modes.indexOf(this.internalMode)
98 1
      const newMode = modes[(index + 1) % modes.length]
99 1
      this.internalMode = newMode
100 1
      this.$emit('update:mode', newMode)
101
    },
102 1
    genInput (target: string, attrs: any, value: any, on: any): VNode {
103 1
      return this.$createElement('div', {
104
        staticClass: 'v-color-picker__input',
105
      }, [
106
        this.$createElement('input', {
107
          key: target,
108
          attrs,
109
          domProps: {
110
            value,
111
          },
112
          on,
113
        }),
114
        this.$createElement('span', target.toUpperCase()),
115
      ])
116
    },
117 1
    genInputs (): VNode[] | VNode {
118 1
      switch (this.internalMode) {
119 1
        case 'hexa': {
120 1
          const hex = this.color.hexa
121 1
          const value = this.hideAlpha && hex.endsWith('FF') ? hex.substr(0, 7) : hex
122 1
          return this.genInput(
123
            'hex',
124
            {
125 1
              maxlength: this.hideAlpha ? 7 : 9,
126
              disabled: this.disabled,
127
            },
128
            value,
129
            {
130 1
              change: (e: Event) => {
131 1
                const el = e.target as HTMLInputElement
132 1
                this.$emit('update:color', this.currentMode.from(parseHex(el.value)))
133
              },
134
            }
135
          )
136
        }
137 1
        default: {
138 1
          const inputs = this.hideAlpha ? this.currentMode.inputs!.slice(0, -1) : this.currentMode.inputs!
139 1
          return inputs.map(([target, max, type]) => {
140 1
            const value = this.color[this.internalMode as keyof VColorPickerColor] as any
141 1
            return this.genInput(
142
              target,
143
              {
144
                type: 'number',
145
                min: 0,
146
                max,
147 1
                step: type === 'float' ? '0.01' : type === 'int' ? '1' : undefined,
148
                disabled: this.disabled,
149
              },
150
              this.getValue(value[target], type),
151
              {
152 1
                input: (e: Event) => {
153 1
                  const el = e.target as HTMLInputElement
154 1
                  const newVal = this.parseValue(el.value || '0', type)
155

156 1
                  this.$emit('update:color', this.currentMode.from(
157
                    Object.assign({}, value, { [target]: newVal }),
158
                    this.color.alpha
159
                  ))
160
                },
161
              }
162
            )
163
          })
164
        }
165
      }
166
    },
167 1
    genSwitch (): VNode {
168 1
      return this.$createElement(VBtn, {
169
        props: {
170
          small: true,
171
          icon: true,
172
          disabled: this.disabled,
173
        },
174
        on: {
175
          click: this.changeMode,
176
        },
177
      }, [
178
        this.$createElement(VIcon, '$unfold'),
179
      ])
180
    },
181
  },
182

183 1
  render (h): VNode {
184 1
    return h('div', {
185
      staticClass: 'v-color-picker__edit',
186
    }, [
187
      this.genInputs(),
188 1
      !this.hideModeSwitch && this.genSwitch(),
189
    ])
190
  },
191
})

Read our documentation on viewing source code .

Loading