Support the three/four/six-value syntax variants of <hex-color>

This commit is contained in:
Fülöp Kovács 2022-06-07 16:05:45 +02:00 committed by Andrew Prifer
parent b323588d78
commit abdda0afab
2 changed files with 48 additions and 9 deletions

View file

@ -1,10 +1,29 @@
import {clamp} from 'lodash-es' import {clamp} from 'lodash-es'
/**
* Robust check for a valid hex value (without the "#") in a string
*
* @remarks
*
* Supports all the syntax variants of <hex-color>
* {@link https://google.com}:
*
*
* ```javascript
* #RGB // The three-value syntax
* #RGBA // The four-value syntax
* #RRGGBB // The six-value syntax
* #RRGGBBAA // The eight-value syntax
* ```
*/
export const validHexRegExp = /^#*([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i
export function parseRgbaFromHex(rgba: string) { export function parseRgbaFromHex(rgba: string) {
rgba = rgba.trim().toLowerCase() rgba = rgba.trim().toLowerCase()
const hex = rgba.match(/^#?([0-9a-f]{8})$/i)
if (!hex) { const match = rgba.match(validHexRegExp)
if (!match) {
return { return {
r: 0, r: 0,
g: 0, g: 0,
@ -13,12 +32,13 @@ export function parseRgbaFromHex(rgba: string) {
} }
} }
const match = hex[1] const hex = _hexInEightValueSyntax(match[1])
return { return {
r: parseInt(match.substr(0, 2), 16) / 255, r: parseInt(hex.substr(0, 2), 16) / 255,
g: parseInt(match.substr(2, 2), 16) / 255, g: parseInt(hex.substr(2, 2), 16) / 255,
b: parseInt(match.substr(4, 2), 16) / 255, b: parseInt(hex.substr(4, 2), 16) / 255,
a: parseInt(match.substr(6, 2), 16) / 255, a: parseInt(hex.substr(6, 2), 16) / 255,
} }
} }
@ -126,3 +146,21 @@ export type Laba = {
b: number b: number
alpha: number alpha: number
} }
/**
* Returns a hex string in the eight-value syntax
*/
function _hexInEightValueSyntax(hex: string): string {
switch (hex.length) {
case 3:
return `${hex.repeat(2)}ff`
case 4:
const rgb = hex.substr(0, 3)
const alpha = hex[3]
return `${rgb.repeat(2)}${alpha.repeat(2)}`
case 6:
return `${hex}ff`
}
return hex
}

View file

@ -1,5 +1,6 @@
import type {PropTypeConfig_Rgba} from '@theatre/core/propTypes' import type {PropTypeConfig_Rgba} from '@theatre/core/propTypes'
import type {Rgba} from '@theatre/shared/utils/color' import type {Rgba} from '@theatre/shared/utils/color';
import { validHexRegExp} from '@theatre/shared/utils/color'
import { import {
decorateRgba, decorateRgba,
rgba2hex, rgba2hex,
@ -114,7 +115,7 @@ function RgbaPropEditor({
temporarilySetValue={noop} temporarilySetValue={noop}
discardTemporaryValue={noop} discardTemporaryValue={noop}
permanentlySetValue={onChange} permanentlySetValue={onChange}
isValid={(v) => !!v.match(/^#?([0-9a-f]{8})$/i)} isValid={(v) => !!v.match(validHexRegExp)}
/> />
</RowContainer> </RowContainer>
{popoverNode} {popoverNode}