diff --git a/_plotly_utils/basevalidators.py b/_plotly_utils/basevalidators.py index c1f0d193341..2e69546e546 100644 --- a/_plotly_utils/basevalidators.py +++ b/_plotly_utils/basevalidators.py @@ -1033,6 +1033,7 @@ class ColorValidator(BaseValidator): """ re_hex = re.compile('#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})') re_rgb_etc = re.compile('(rgb|hsl|hsv)a?\([\d.]+%?(,[\d.]+%?){2,3}\)') + re_ddk = re.compile('var\(\-\-.*\)') named_colors = [ "aliceblue", "antiquewhite", "aqua", "aquamarine", "azure", "beige", @@ -1229,6 +1230,11 @@ def perform_validate_coerce(v, allow_number=None): # Valid rgb(a), hsl(a), hsv(a) color # (e.g. rgba(10, 234, 200, 50%) return v + elif fullmatch(ColorValidator.re_ddk, v_normalized): + # Valid var(--*) DDK theme variable, inspired by CSS syntax + # (e.g. var(--accent) ) + # DDK will crawl & eval var(-- colors for Graph theming + return v elif v_normalized in ColorValidator.named_colors: # Valid named color (e.g. 'coral') return v diff --git a/_plotly_utils/tests/validators/test_color_validator.py b/_plotly_utils/tests/validators/test_color_validator.py index 0ffb31a2f14..480bd0ef625 100644 --- a/_plotly_utils/tests/validators/test_color_validator.py +++ b/_plotly_utils/tests/validators/test_color_validator.py @@ -28,7 +28,7 @@ def validator_aok_colorscale(): # Array not ok, numbers not ok # ---------------------------- @pytest.mark.parametrize('val', - ['red', 'BLUE', 'rgb(255, 0, 0)', 'hsl(0, 100%, 50%)', 'hsla(0, 100%, 50%, 100%)', + ['red', 'BLUE', 'rgb(255, 0, 0)', 'var(--accent)', 'hsl(0, 100%, 50%)', 'hsla(0, 100%, 50%, 100%)', 'hsv(0, 100%, 100%)', 'hsva(0, 100%, 100%, 50%)']) def test_acceptance(val, validator): assert validator.validate_coerce(val) == val @@ -58,7 +58,7 @@ def test_rejection(val, validator): # ------------------------ # ### Acceptance ### @pytest.mark.parametrize('val', - ['red', 'BLUE', 23, 15, 'rgb(255, 0, 0)', 'hsl(0, 100%, 50%)', 'hsla(0, 100%, 50%, 100%)', + ['red', 'BLUE', 23, 15, 'rgb(255, 0, 0)', 'var(--accent)', 'hsl(0, 100%, 50%)', 'hsla(0, 100%, 50%, 100%)', 'hsv(0, 100%, 100%)', 'hsva(0, 100%, 100%, 50%)']) def test_acceptance_colorscale(val, validator_colorscale): assert validator_colorscale.validate_coerce(val) == val