mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
Add help text for style-flags properties
This commit is contained in:
@@ -10,6 +10,7 @@ from textual.css.constants import (
|
|||||||
VALID_EDGE,
|
VALID_EDGE,
|
||||||
VALID_ALIGN_HORIZONTAL,
|
VALID_ALIGN_HORIZONTAL,
|
||||||
VALID_ALIGN_VERTICAL,
|
VALID_ALIGN_VERTICAL,
|
||||||
|
VALID_STYLE_FLAGS,
|
||||||
)
|
)
|
||||||
|
|
||||||
if sys.version_info >= (3, 8):
|
if sys.version_info >= (3, 8):
|
||||||
@@ -384,7 +385,7 @@ def border_property_help_text(
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
Bullet(
|
Bullet(
|
||||||
f"Valid values for <bordertype> are:\n {friendly_list(VALID_BORDER)}"
|
f"Valid values for <bordertype> are:\n{friendly_list(VALID_BORDER)}"
|
||||||
),
|
),
|
||||||
Bullet(
|
Bullet(
|
||||||
f"Colors can be specified using hex, RGB, or ANSI color names"
|
f"Colors can be specified using hex, RGB, or ANSI color names"
|
||||||
@@ -626,3 +627,36 @@ def offset_single_axis_help_text(property_name: str) -> HelpText:
|
|||||||
Bullet(f"Valid scalar units are {friendly_list(SYMBOL_UNIT)}"),
|
Bullet(f"Valid scalar units are {friendly_list(SYMBOL_UNIT)}"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def style_flags_property_help_text(
|
||||||
|
property_name: str, value: str, context: StylingContext | None
|
||||||
|
) -> HelpText:
|
||||||
|
property_name = _contextualize_property_name(property_name, context)
|
||||||
|
return HelpText(
|
||||||
|
summary=f"Invalid value '{value}' in [i]{property_name}[/] property",
|
||||||
|
bullets=[
|
||||||
|
Bullet(
|
||||||
|
f"Style flag values such as [i]{property_name}[/] expect space-separated values"
|
||||||
|
),
|
||||||
|
Bullet(f"Permitted values are {friendly_list(VALID_STYLE_FLAGS)}"),
|
||||||
|
*ContextSpecificBullets(
|
||||||
|
inline=[
|
||||||
|
Bullet(
|
||||||
|
markup="In Python, you can supply a string or Style object",
|
||||||
|
examples=[
|
||||||
|
Example(
|
||||||
|
f'widget.styles.{property_name} = "bold italic underline"'
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
css=[
|
||||||
|
Bullet(
|
||||||
|
markup="In Textual CSS, you can supply style flags separated by spaces",
|
||||||
|
examples=[Example(f"{property_name}: bold italic underline;")],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
).get_by_context(context),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from ._help_text import (
|
|||||||
layout_property_help_text,
|
layout_property_help_text,
|
||||||
fractional_property_help_text,
|
fractional_property_help_text,
|
||||||
offset_property_help_text,
|
offset_property_help_text,
|
||||||
|
style_flags_property_help_text,
|
||||||
)
|
)
|
||||||
from ._help_text import (
|
from ._help_text import (
|
||||||
spacing_wrong_number_of_values,
|
spacing_wrong_number_of_values,
|
||||||
@@ -28,7 +29,7 @@ from ._help_text import (
|
|||||||
)
|
)
|
||||||
from ..color import Color, ColorPair, ColorParseError
|
from ..color import Color, ColorPair, ColorParseError
|
||||||
from ._error_tools import friendly_list
|
from ._error_tools import friendly_list
|
||||||
from .constants import NULL_SPACING
|
from .constants import NULL_SPACING, VALID_STYLE_FLAGS
|
||||||
from .errors import StyleTypeError, StyleValueError
|
from .errors import StyleTypeError, StyleValueError
|
||||||
from .scalar import (
|
from .scalar import (
|
||||||
get_symbols,
|
get_symbols,
|
||||||
@@ -790,20 +791,6 @@ class ColorProperty:
|
|||||||
class StyleFlagsProperty:
|
class StyleFlagsProperty:
|
||||||
"""Descriptor for getting and set style flag properties (e.g. ``bold italic underline``)."""
|
"""Descriptor for getting and set style flag properties (e.g. ``bold italic underline``)."""
|
||||||
|
|
||||||
_VALID_PROPERTIES = {
|
|
||||||
"none",
|
|
||||||
"not",
|
|
||||||
"bold",
|
|
||||||
"italic",
|
|
||||||
"underline",
|
|
||||||
"overline",
|
|
||||||
"strike",
|
|
||||||
"b",
|
|
||||||
"i",
|
|
||||||
"u",
|
|
||||||
"o",
|
|
||||||
}
|
|
||||||
|
|
||||||
def __set_name__(self, owner: Styles, name: str) -> None:
|
def __set_name__(self, owner: Styles, name: str) -> None:
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
@@ -840,12 +827,14 @@ class StyleFlagsProperty:
|
|||||||
obj.refresh()
|
obj.refresh()
|
||||||
else:
|
else:
|
||||||
words = [word.strip() for word in style_flags.split(" ")]
|
words = [word.strip() for word in style_flags.split(" ")]
|
||||||
valid_word = self._VALID_PROPERTIES.__contains__
|
valid_word = VALID_STYLE_FLAGS.__contains__
|
||||||
for word in words:
|
for word in words:
|
||||||
if not valid_word(word):
|
if not valid_word(word):
|
||||||
raise StyleValueError(
|
raise StyleValueError(
|
||||||
f"unknown word {word!r} in style flags, "
|
f"unknown word {word!r} in style flags",
|
||||||
f"valid values are {friendly_list(self._VALID_PROPERTIES)}"
|
help_text=style_flags_property_help_text(
|
||||||
|
self.name, word, context="inline"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
style = Style.parse(style_flags)
|
style = Style.parse(style_flags)
|
||||||
if obj.set_rule(self.name, style):
|
if obj.set_rule(self.name, style):
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from ._help_text import (
|
|||||||
align_help_text,
|
align_help_text,
|
||||||
offset_property_help_text,
|
offset_property_help_text,
|
||||||
offset_single_axis_help_text,
|
offset_single_axis_help_text,
|
||||||
|
style_flags_property_help_text,
|
||||||
)
|
)
|
||||||
from .constants import (
|
from .constants import (
|
||||||
VALID_ALIGN_HORIZONTAL,
|
VALID_ALIGN_HORIZONTAL,
|
||||||
@@ -30,6 +31,7 @@ from .constants import (
|
|||||||
VALID_DISPLAY,
|
VALID_DISPLAY,
|
||||||
VALID_OVERFLOW,
|
VALID_OVERFLOW,
|
||||||
VALID_VISIBILITY,
|
VALID_VISIBILITY,
|
||||||
|
VALID_STYLE_FLAGS,
|
||||||
)
|
)
|
||||||
from .errors import DeclarationError, StyleValueError
|
from .errors import DeclarationError, StyleValueError
|
||||||
from .model import Declaration
|
from .model import Declaration
|
||||||
@@ -542,6 +544,15 @@ class StylesBuilder:
|
|||||||
process_scrollbar_background_active = process_color
|
process_scrollbar_background_active = process_color
|
||||||
|
|
||||||
def process_text_style(self, name: str, tokens: list[Token]) -> None:
|
def process_text_style(self, name: str, tokens: list[Token]) -> None:
|
||||||
|
for token in tokens:
|
||||||
|
value = token.value
|
||||||
|
if value not in VALID_STYLE_FLAGS:
|
||||||
|
self.error(
|
||||||
|
name,
|
||||||
|
token,
|
||||||
|
style_flags_property_help_text(name, value, context="css"),
|
||||||
|
)
|
||||||
|
|
||||||
style_definition = " ".join(token.value for token in tokens)
|
style_definition = " ".join(token.value for token in tokens)
|
||||||
self.styles.text_style = style_definition
|
self.styles.text_style = style_definition
|
||||||
|
|
||||||
|
|||||||
@@ -31,5 +31,18 @@ VALID_BOX_SIZING: Final = {"border-box", "content-box"}
|
|||||||
VALID_OVERFLOW: Final = {"scroll", "hidden", "auto"}
|
VALID_OVERFLOW: Final = {"scroll", "hidden", "auto"}
|
||||||
VALID_ALIGN_HORIZONTAL: Final = {"left", "center", "right"}
|
VALID_ALIGN_HORIZONTAL: Final = {"left", "center", "right"}
|
||||||
VALID_ALIGN_VERTICAL: Final = {"top", "middle", "bottom"}
|
VALID_ALIGN_VERTICAL: Final = {"top", "middle", "bottom"}
|
||||||
|
VALID_STYLE_FLAGS: Final = {
|
||||||
|
"none",
|
||||||
|
"not",
|
||||||
|
"bold",
|
||||||
|
"italic",
|
||||||
|
"underline",
|
||||||
|
"overline",
|
||||||
|
"strike",
|
||||||
|
"b",
|
||||||
|
"i",
|
||||||
|
"u",
|
||||||
|
"o",
|
||||||
|
}
|
||||||
|
|
||||||
NULL_SPACING: Final = Spacing.all(0)
|
NULL_SPACING: Final = Spacing.all(0)
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ class StylesBase(ABC):
|
|||||||
align_vertical = StringEnumProperty(VALID_ALIGN_VERTICAL, "top")
|
align_vertical = StringEnumProperty(VALID_ALIGN_VERTICAL, "top")
|
||||||
|
|
||||||
def __eq__(self, styles: object) -> bool:
|
def __eq__(self, styles: object) -> bool:
|
||||||
"""Check that Styles containts the same rules."""
|
"""Check that Styles contains the same rules."""
|
||||||
if not isinstance(styles, StylesBase):
|
if not isinstance(styles, StylesBase):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
return self.get_rules() == styles.get_rules()
|
return self.get_rules() == styles.get_rules()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import pytest
|
|||||||
from rich.style import Style
|
from rich.style import Style
|
||||||
|
|
||||||
from textual.color import Color
|
from textual.color import Color
|
||||||
from textual.css.errors import StyleTypeError, StyleValueError
|
from textual.css.errors import StyleValueError
|
||||||
from textual.css.styles import Styles, RenderStyles
|
from textual.css.styles import Styles, RenderStyles
|
||||||
from textual.dom import DOMNode
|
from textual.dom import DOMNode
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user