Handling invalid color values in CSS and inline styles

This commit is contained in:
Darren Burns
2022-04-22 15:50:04 +01:00
parent 62c3f9e945
commit 5f33050acc
6 changed files with 57 additions and 5 deletions

View File

@@ -9,6 +9,6 @@
.list-item {
height: 8;
min-width: 80;
background: dark_blue;
background: dark_blu;
padding: 2;
}

View File

@@ -87,7 +87,7 @@ class BasicApp(App):
old_margin = self.focused.styles.margin
# new_margin = old_margin + (1,1,1)
# self.focused.styles.padding = (1, 1, 1)
self.focused.styles.display = "banana"
self.focused.styles.color = "banana"
BasicApp.run(css_file="uber.css", log="textual.log", log_verbosity=1)

View File

@@ -206,3 +206,43 @@ def string_enum_help_text(
).get_by_context(context),
],
)
def color_property_help_text(
property_name: str, context: StylingContext | None = None
) -> HelpText:
property_name = _contextualize_property_name(property_name, context)
return HelpText(
summary=f"Invalid value for the [i]{property_name}[/] property",
bullets=[
Bullet(f"The '{property_name}' property can only be set to a valid color"),
Bullet(f"Colors can be specified using hex, RGB, or ANSI color names"),
*ContextSpecificBullets(
inline=[
Bullet(
"In Python, you can assign colors using strings or Color objects",
examples=[
Example(f'widget.styles.{property_name} = "#ff00aa"'),
Example(
f'widget.styles.{property_name} = "rgb(12,231,45)"'
),
Example(f'widget.styles.{property_name} = "red"'),
Example(
f"widget.styles.{property_name} = Color(1, 5, 29, a=0.5)"
),
],
)
],
css=[
Bullet(
"In Textual CSS, colors can be set as follows",
examples=[
Example(f"{property_name}: [#ff00aa]#ff00aa[/];"),
Example(f"{property_name}: rgb(12,231,45);"),
Example(f"{property_name}: [rgb(255,0,0)]red[/];"),
],
)
],
).get_by_context(context),
],
)

View File

@@ -19,8 +19,9 @@ from ._help_text import (
spacing_wrong_number_of_values,
scalar_help_text,
string_enum_help_text,
color_property_help_text,
)
from ..color import Color, ColorPair
from ..color import Color, ColorPair, ColorParseError
from ._error_tools import friendly_list
from .constants import NULL_SPACING
from .errors import StyleTypeError, StyleValueError
@@ -724,8 +725,17 @@ class ColorProperty:
if obj.set_rule(self.name, color):
obj.refresh()
elif isinstance(color, str):
if obj.set_rule(self.name, Color.parse(color)):
try:
parsed_color = Color.parse(color)
except ColorParseError:
raise StyleValueError(
f"Invalid color value '{color}'",
help_text=color_property_help_text(self.name, context="inline"),
)
if obj.set_rule(self.name, parsed_color):
obj.refresh()
else:
raise StyleValueError(f"Invalid color value {color}")
class StyleFlagsProperty:

View File

@@ -11,6 +11,7 @@ from ._help_text import (
scalar_help_text,
spacing_invalid_value,
string_enum_help_text,
color_property_help_text,
)
from .constants import (
VALID_BORDER,
@@ -520,7 +521,7 @@ class StylesBuilder:
self.styles._rules[name] = Color.parse(token.value)
except Exception as error:
self.error(
name, token, f"failed to parse color {token.value!r}; {error}"
name, token, color_property_help_text(name, context="css")
)
else:
self.error(

View File

@@ -34,6 +34,7 @@ class StyleValueError(ValueError):
if self.help_text is not None:
yield ""
yield self.help_text
yield ""
class StylesheetError(Exception):