Fix color parsing when alpha is 0 (#177)

master
Brad Cornes 2020-08-25 15:21:12 +01:00
parent 7ef77949a3
commit 906d3cfb4e
3 changed files with 29 additions and 25 deletions

View File

@ -89,9 +89,11 @@ function completionsFromClassList(
sortText = '-' + sortText // move to top sortText = '-' + sortText // move to top
} else { } else {
const color = getColor(state, [className]) const color = getColor(state, [className])
if (color) { if (color !== null) {
kind = CompletionItemKind.Color kind = CompletionItemKind.Color
documentation = color.documentation if (typeof color !== 'string' && color.a !== 0) {
documentation = color.toRgbString()
}
} }
} }

View File

@ -27,8 +27,10 @@ export function registerDocumentColorProvider(state: State) {
let parts = getClassNameParts(state, className.className) let parts = getClassNameParts(state, className.className)
if (!parts) return if (!parts) return
let color = getColor(state, parts) let color = getColor(state, parts)
if (!color) return if (color === null || typeof color === 'string' || color.a === 0) {
colors.push({ range: className.range, color: color.documentation }) return
}
colors.push({ range: className.range, color: color.toRgbString() })
}) })
}) })

View File

@ -21,10 +21,14 @@ const COLOR_PROPS = [
'text-decoration-color', 'text-decoration-color',
] ]
function isKeyword(value: string): boolean {
return ['transparent', 'currentcolor'].includes(value.toLowerCase())
}
export function getColor( export function getColor(
state: State, state: State,
keys: string[] keys: string[]
): { documentation?: string } { ): TinyColor | string | null {
const item = dlv(state.classNames.classNames, keys) const item = dlv(state.classNames.classNames, keys)
if (!item.__rule) return null if (!item.__rule) return null
const props = Object.keys(removeMeta(item)) const props = Object.keys(removeMeta(item))
@ -48,40 +52,36 @@ export function getColor(
) )
// check that all of the values are valid colors // check that all of the values are valid colors
if (colors.some((color) => color !== 'transparent' && !color.isValid)) { if (colors.some((color) => typeof color !== 'string' && !color.isValid)) {
return null return null
} }
// check that all of the values are the same color, ignoring alpha // check that all of the values are the same color, ignoring alpha
const colorStrings = dedupe( const colorStrings = dedupe(
colors.map((color) => colors.map((color) =>
color === 'transparent' typeof color === 'string' ? color : `${color.r}-${color.g}-${color.b}`
? 'transparent'
: `${color.r}-${color.g}-${color.b}`
) )
) )
if (colorStrings.length !== 1) { if (colorStrings.length !== 1) {
return null return null
} }
if (colorStrings[0] === 'transparent') { if (isKeyword(colorStrings[0])) {
return { return colorStrings[0]
documentation: 'rgba(0, 0, 0, 0.01)',
}
} }
const nonTransparentColors = colors.filter( const nonKeywordColors = colors.filter(
(color): color is TinyColor => color !== 'transparent' (color): color is TinyColor => typeof color !== 'string'
) )
const alphas = dedupe(nonTransparentColors.map((color) => color.a)) const alphas = dedupe(nonKeywordColors.map((color) => color.a))
if (alphas.length === 1 || (alphas.length === 2 && alphas.includes(0))) { if (alphas.length === 1) {
return { return nonKeywordColors[0]
documentation: nonTransparentColors
.find((color) => color.a !== 0)
.toRgbString(),
} }
if (alphas.length === 2 && alphas.includes(0)) {
return nonKeywordColors.find((color) => color.a !== 0)
} }
return null return null
@ -99,9 +99,9 @@ export function getColorFromValue(value: unknown): string {
return null return null
} }
function createColor(str: string): TinyColor | 'transparent' { function createColor(str: string): TinyColor | string {
if (str === 'transparent') { if (isKeyword(str)) {
return 'transparent' return str
} }
// matches: rgba(<r>, <g>, <b>, var(--bg-opacity)) // matches: rgba(<r>, <g>, <b>, var(--bg-opacity))