Skip to content

Commit

Permalink
fix(VColorPicker): consistent output values (#16674)
Browse files Browse the repository at this point in the history
Fixes #16672
  • Loading branch information
KaelWD committed Feb 21, 2023
1 parent 7190d27 commit 01c35ef
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,17 @@ export const VColorPickerCanvas = defineComponent({
width={ canvasWidth.value }
height={ canvasHeight.value }
/>
<div
class={[
'v-color-picker-canvas__dot',
{
'v-color-picker-canvas__dot--disabled': props.disabled,
},
]}
style={ dotStyles.value }
/>
{ props.color && (
<div
class={[
'v-color-picker-canvas__dot',
{
'v-color-picker-canvas__dot--disabled': props.disabled,
},
]}
style={ dotStyles.value }
/>
)}
</div>
))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { VBtn } from '@/components/VBtn'
// Utilities
import { computed } from 'vue'
import { defineComponent, useRender } from '@/util'
import { modes } from './util'
import { modes, nullColor } from './util'

// Types
import type { PropType } from 'vue'
Expand Down Expand Up @@ -57,20 +57,20 @@ export const VColorPickerEdit = defineComponent({

if (!mode) return []

const color = props.color ? mode.to(props.color) : {}
const color = props.color ? mode.to(props.color) : null

return mode.inputs?.map(({ getValue, getColor, ...inputProps }) => {
return {
...mode.inputProps,
...inputProps,
disabled: props.disabled,
value: getValue(color),
value: color && getValue(color),
onChange: (e: InputEvent) => {
const target = e.target as HTMLInputElement | null

if (!target) return

emit('update:color', mode.from(getColor(color, target.value)))
emit('update:color', mode.from(getColor(color ?? nullColor, target.value)))
},
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ export const VColorPickerPreview = defineComponent({
{ !props.hideAlpha && (
<VSlider
class="v-color-picker-preview__track v-color-picker-preview__alpha"
modelValue={ props.color?.a }
modelValue={ props.color?.a ?? 1 }
onUpdate:modelValue={ a => emit('update:color', { ...(props.color ?? nullColor), a }) }
step={ 0 }
step={ 1 / 256 }
min={ 0 }
max={ 1 }
disabled={ props.disabled }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,4 +307,41 @@ describe('VColorPicker', () => {
cy.get('.bg-primary').should('not.exist')
cy.get('.text-primary').should('not.exist')
})

it('should not show dot or input values if no color is set', () => {
cy.mount(() => (
<Application>
<VColorPicker />
</Application>
))

cy.get('.v-color-picker-canvas__dot').should('not.exist')
.get('.v-color-picker-edit__input input').should('have.value', '')
.get('.v-color-picker-canvas canvas').then(canvas => {
const width = canvas.width() ?? 0
const height = canvas.height() ?? 0

cy.wrap(canvas).click(width / 2, height / 2)
})
.get('.v-color-picker-canvas__dot').should('exist')
.get('.v-color-picker-edit__input input').invoke('val').should('not.be.empty')
})

it('should emit correct color when typing in hex field', () => {
cy.mount(() => (
<Application>
<VColorPicker mode="hexa" />
</Application>
))

cy.get('.v-color-picker-edit__input input')
.type('FF00CC')
.blur()
.vue()
.then(({ wrapper }) => {
const picker = wrapper.findComponent(VColorPicker)
const emitted = picker.emitted('update:modelValue')
expect(emitted).to.deep.equal([['#FF00CC']])
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ describe('VColorPicker Utils', () => {
h: expect.any(Number),
s: expect.any(Number),
v: expect.any(Number),
a: 1,
}))
expect(parseColor('FF00FF00')).toEqual(expect.objectContaining({
h: expect.any(Number),
Expand All @@ -31,7 +30,6 @@ describe('VColorPicker Utils', () => {
h: expect.any(Number),
s: expect.any(Number),
v: expect.any(Number),
a: 1,
}))

const rgba = { r: 128, g: 0, b: 255, a: 0.2 }
Expand All @@ -49,7 +47,6 @@ describe('VColorPicker Utils', () => {
h: expect.any(Number),
s: expect.any(Number),
v: expect.any(Number),
a: 1,
}))

const hsla = { h: 220, s: 0.5, l: 1, a: 0.4 }
Expand All @@ -67,7 +64,6 @@ describe('VColorPicker Utils', () => {
h: expect.any(Number),
s: expect.any(Number),
v: expect.any(Number),
a: 1,
}))

const hsva = { h: 220, s: 0.5, v: 1, a: 0.4 }
Expand Down
4 changes: 2 additions & 2 deletions packages/vuetify/src/components/VColorPicker/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function parseColor (color: any): HSV | null {
}
}

return hsva != null ? { ...hsva, a: hsva.a ?? 1 } : null
return hsva
}

function stripAlpha (color: any, stripAlpha: boolean) {
Expand Down Expand Up @@ -65,7 +65,7 @@ export function extractColor (color: HSV, input: any) {
else if (has(input, ['h', 's', 'l'])) converted = HSVtoHSL(color)
else if (has(input, ['h', 's', 'v'])) converted = color

return stripAlpha(converted, !has(input, ['a']))
return stripAlpha(converted, !has(input, ['a']) && color.a === 1)
}

return color
Expand Down
9 changes: 4 additions & 5 deletions packages/vuetify/src/util/colorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,14 @@ export function RGBtoHex ({ r, g, b, a }: RGB): Hex {
toHex(r),
toHex(g),
toHex(b),
a !== undefined ? toHex(Math.round(a * 255)) : 'FF',
a !== undefined ? toHex(Math.round(a * 255)) : '',
].join('')}` as Hex
}

export function HexToRGB (hex: Hex): RGB {
hex = parseHex(hex)
let [r, g, b, a] = chunk(hex, 2).map((c: string) => parseInt(c, 16))
a = a === undefined ? a : Math.round((a / 255) * 100) / 100
a = a === undefined ? a : (a / 255)

return { r, g, b, a }
}
Expand All @@ -188,9 +189,7 @@ export function parseHex (hex: string): Hex {
hex = hex.split('').map(x => x + x).join('')
}

if (hex.length === 6) {
hex = padEnd(hex, 8, 'F')
} else {
if (hex.length !== 6) {
hex = padEnd(padEnd(hex, 6), 8, 'F')
}

Expand Down

0 comments on commit 01c35ef

Please sign in to comment.