Skip to content

Commit

Permalink
fix(VColorPicker): alpha controls showing when they shouldnt (#8427)
Browse files Browse the repository at this point in the history
alpha controls will be hidden when given a hex color without alpha channel.

closes #8390
  • Loading branch information
nekosaur authored and johnleider committed Aug 12, 2019
1 parent 2cc5a4a commit 31ed439
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 16 deletions.
10 changes: 9 additions & 1 deletion packages/vuetify/src/components/VColorPicker/VColorPicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import VColorPickerEdit, { Mode, modes } from './VColorPickerEdit'
import VColorPickerSwatches from './VColorPickerSwatches'

// Helpers
import { VColorPickerColor, parseColor, fromRGBA, extractColor } from './util'
import { VColorPickerColor, parseColor, fromRGBA, extractColor, hasAlpha } from './util'
import mixins from '../../util/mixins'
import Themeable from '../../mixins/themeable'

Expand Down Expand Up @@ -58,6 +58,12 @@ export default mixins(Themeable).extend({
internalValue: fromRGBA({ r: 255, g: 0, b: 0, a: 1 }),
}),

computed: {
hideAlpha (): boolean {
return this.value && !hasAlpha(this.value)
},
},

watch: {
value: {
handler (color: any) {
Expand Down Expand Up @@ -104,6 +110,7 @@ export default mixins(Themeable).extend({
props: {
color: this.internalValue,
disabled: this.disabled,
hideAlpha: this.hideAlpha,
hideModeSwitch: this.hideModeSwitch,
mode: this.mode,
},
Expand All @@ -118,6 +125,7 @@ export default mixins(Themeable).extend({
props: {
color: this.internalValue,
disabled: this.disabled,
hideAlpha: this.hideAlpha,
},
on: {
'update:color': this.updateColor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export default Vue.extend({
props: {
color: Object as PropValidator<VColorPickerColor>,
disabled: Boolean,
hideAlpha: Boolean,
hideModeSwitch: Boolean,
mode: {
type: String,
Expand Down Expand Up @@ -118,11 +119,11 @@ export default Vue.extend({
switch (this.internalMode) {
case 'hexa': {
const hex = this.color.hexa
const value = hex.endsWith('FF') ? hex.substr(0, 7) : hex
const value = this.hideAlpha && hex.endsWith('FF') ? hex.substr(0, 7) : hex
return this.genInput(
'hex',
{
maxlength: 9,
maxlength: this.hideAlpha ? 7 : 9,
disabled: this.disabled,
},
value,
Expand All @@ -135,7 +136,8 @@ export default Vue.extend({
)
}
default: {
return this.currentMode.inputs!.map(([target, max, type]) => {
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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@
height: 100%

.v-color-picker__hue
margin-bottom: 24px

&:not(.v-input--is-disabled)
background: linear-gradient(to right, #F00 0%, #FF0 16.66%, #0F0 33.33%, #0FF 50%, #00F 66.66%, #F0F 83.33%, #F00 100%)

Expand All @@ -54,3 +52,7 @@

.v-slider__track-container
opacity: 0

&:not(.v-color-picker__preview--hide-alpha)
.v-color-picker__hue
margin-bottom: 24px
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default Vue.extend({
props: {
color: Object as PropValidator<VColorPickerColor>,
disabled: Boolean,
hideAlpha: Boolean,
},

methods: {
Expand Down Expand Up @@ -47,7 +48,7 @@ export default Vue.extend({
staticClass: 'v-color-picker__sliders',
}, [
this.genHue(),
this.genAlpha(),
!this.hideAlpha && this.genAlpha(),
])
},
genDot (): VNode {
Expand Down Expand Up @@ -92,6 +93,9 @@ export default Vue.extend({
render (h): VNode {
return h('div', {
staticClass: 'v-color-picker__preview',
class: {
'v-color-picker__preview--hide-alpha': this.hideAlpha,
},
}, [
this.genDot(),
this.genSliders(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,14 @@ describe('VColorPicker.ts', () => {

expect(fn).toHaveBeenLastCalledWith({ r: 255, g: 0, b: 255, a: 1 })
})

it('should not show alpha controls if given hex value without alpha', async () => {
const wrapper = mountFunction({
propsData: {
value: '#00FF00',
},
})

expect(wrapper.html()).toMatchSnapshot()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,114 @@ exports[`VColorPicker.ts should hide inputs 1`] = `
</div>
`;
exports[`VColorPicker.ts should not show alpha controls if given hex value without alpha 1`] = `
<div class="v-color-picker v-sheet theme--light theme--light"
style="max-width: 300px;"
>
<div class="v-color-picker__canvas"
style="width: 300px; height: 150px;"
>
<canvas width="300"
height="150"
>
</canvas>
<div class="v-color-picker__canvas-dot"
style="width: 10px; height: 10px; transform: translate(295px, -5px);"
>
</div>
</div>
<div class="v-color-picker__controls">
<div class="v-color-picker__preview v-color-picker__preview--hide-alpha">
<div class="v-color-picker__dot">
<div style="background: rgb(0, 255, 0);">
</div>
</div>
<div class="v-color-picker__sliders">
<div class="v-input v-color-picker__hue v-input--hide-details v-input--is-label-active v-input--is-dirty theme--light v-input__slider v-color-picker__track">
<div class="v-input__control">
<div class="v-input__slot">
<div class="v-slider v-slider--horizontal theme--light">
<input value="120"
id="input-70"
readonly="readonly"
tabindex="-1"
>
<div class="v-slider__track-container">
<div class="v-slider__track-background primary lighten-3"
style="right: 0px;"
>
</div>
<div class="v-slider__track-fill primary"
style="left: 0px; width: 33.33333333333333%;"
>
</div>
</div>
<div role="slider"
tabindex="0"
aria-valuemin="0"
aria-valuemax="360"
aria-valuenow="120"
aria-readonly="false"
aria-orientation="horizontal"
class="v-slider__thumb-container grey--text text--lighten-2"
style="left: 33.33333333333333%;"
>
<div class="v-slider__thumb grey lighten-2">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="v-color-picker__edit">
<div class="v-color-picker__input">
<input type="number"
min="0"
max="255"
step="1"
>
<span>
R
</span>
</div>
<div class="v-color-picker__input">
<input type="number"
min="0"
max="255"
step="1"
>
<span>
G
</span>
</div>
<div class="v-color-picker__input">
<input type="number"
min="0"
max="255"
step="1"
>
<span>
B
</span>
</div>
<button type="button"
class="v-btn v-btn--flat v-btn--icon v-btn--round theme--light v-size--small"
>
<span class="v-btn__content">
<i aria-hidden="true"
class="v-icon notranslate material-icons theme--light"
>
$vuetify.icons.unfold
</i>
</span>
</button>
</div>
</div>
</div>
`;
exports[`VColorPicker.ts should render color picker 1`] = `
<div class="v-color-picker v-sheet theme--light theme--light"
style="max-width: 300px;"
Expand Down
32 changes: 26 additions & 6 deletions packages/vuetify/src/components/VColorPicker/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,39 +28,43 @@ export interface VColorPickerColor {
export function fromHSVA (hsva: HSVA): VColorPickerColor {
hsva = { ...hsva }
const hexa = HSVAtoHex(hsva)
const hsla = HSVAtoHSLA(hsva)
const rgba = HSVAtoRGBA(hsva)
return {
alpha: hsva.a,
hex: hexa.substr(0, 7),
hexa,
hsla: HSVAtoHSLA(hsva),
hsla,
hsva,
hue: hsva.h,
rgba: HSVAtoRGBA(hsva),
rgba,
}
}

export function fromHSLA (hsla: HSLA): VColorPickerColor {
const hsva = HSLAtoHSVA(hsla)
const hexa = HSVAtoHex(hsva)
const rgba = HSVAtoRGBA(hsva)
return {
alpha: hsva.a,
hex: hexa.substr(0, 7),
hexa,
hsla,
hsva,
hue: hsva.h,
rgba: HSVAtoRGBA(hsva),
rgba,
}
}

export function fromRGBA (rgba: RGBA): VColorPickerColor {
const hsva = RGBAtoHSVA(rgba)
const hexa = RGBAtoHex(rgba)
const hsla = HSVAtoHSLA(hsva)
return {
alpha: hsva.a,
hex: hexa.substr(0, 7),
hexa,
hsla: HSVAtoHSLA(hsva),
hsla,
hsva,
hue: hsva.h,
rgba,
Expand All @@ -69,14 +73,16 @@ export function fromRGBA (rgba: RGBA): VColorPickerColor {

export function fromHexa (hexa: Hexa): VColorPickerColor {
const hsva = HexToHSVA(hexa)
const hsla = HSVAtoHSLA(hsva)
const rgba = HSVAtoRGBA(hsva)
return {
alpha: hsva.a,
hex: hexa.substr(0, 7),
hexa,
hsla: HSVAtoHSLA(hsva),
hsla,
hsva,
hue: hsva.h,
rgba: HSVAtoRGBA(hsva),
rgba,
}
}

Expand Down Expand Up @@ -133,3 +139,17 @@ export function extractColor (color: VColorPickerColor, input: any) {

return color
}

export function hasAlpha (color: any) {
if (!color) return false

if (typeof color === 'string') {
return color.length > 7
}

if (typeof color === 'object') {
return has(color, ['a'])
}

return false
}
9 changes: 6 additions & 3 deletions packages/vuetify/src/util/colorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import { toXYZ } from './color/transformSRGB'
export type ColorInt = number
export type XYZ = [number, number, number]
export type LAB = [number, number, number]
export type HSVA = { h: number, s: number, v: number, a: number }
export type RGBA = { r: number, g: number, b: number, a: number }
export type HSLA = { h: number, s: number, l: number, a: number }
export type HSV = { h: number, s: number, v: number }
export type HSVA = HSV & { a: number }
export type RGB = { r: number, g: number, b: number }
export type RGBA = RGB & { a: number }
export type HSL = { h: number, s: number, l: number }
export type HSLA = HSL & { a: number }
export type Hex = string
export type Hexa = string
export type Color = string | number | {}
Expand Down

0 comments on commit 31ed439

Please sign in to comment.