button labels

This commit is contained in:
Will McGugan
2025-03-21 16:07:14 +00:00
parent 44b9cf3559
commit adfac0c3af
4 changed files with 27 additions and 11 deletions

View File

@@ -171,6 +171,11 @@ class Content(Visual):
markup = "".join(output)
return markup
@classmethod
def empty(cls) -> Content:
"""Get an empty (blank) content"""
return EMPTY_CONTENT
@classmethod
def from_text(
cls, markup_content_or_text: ContentText, markup: bool = True
@@ -1449,3 +1454,6 @@ class _FormattedLine:
if style is not None
]
return segments
EMPTY_CONTENT: Final = Content("")

View File

@@ -340,7 +340,10 @@ class Padding(Visual):
)
def get_height(self, rules: RulesMap, width: int) -> int:
return self._visual.get_height(rules, width) + self._spacing.height
return (
self._visual.get_height(rules, width - self._spacing.width)
+ self._spacing.height
)
def render_strips(
self,

View File

@@ -3871,6 +3871,7 @@ class Widget(DOMNode):
bold=style.bold,
dim=style.dim,
italic=style.italic,
reverse=style.reverse,
underline=style.underline,
strike=style.strike,
)

View File

@@ -6,10 +6,11 @@ from typing import TYPE_CHECKING, cast
import rich.repr
from rich.cells import cell_len
from rich.console import ConsoleRenderable, RenderableType
from rich.text import Text, TextType
from rich.text import TextType
from typing_extensions import Literal, Self
from textual import events
from textual.visual import Padding
if TYPE_CHECKING:
from textual.app import RenderResult
@@ -17,8 +18,9 @@ if TYPE_CHECKING:
from rich.style import Style
from textual.binding import Binding
from textual.content import Content, ContentText
from textual.css._error_tools import friendly_list
from textual.geometry import Size
from textual.geometry import Size, Spacing
from textual.message import Message
from textual.pad import HorizontalPad
from textual.reactive import reactive
@@ -154,7 +156,7 @@ class Button(Widget, can_focus=True):
BINDINGS = [Binding("enter", "press", "Press button", show=False)]
label: reactive[TextType] = reactive[TextType]("")
label: reactive[ContentText] = reactive[ContentText](Content.empty)
"""The text label that appears within the button."""
variant = reactive("default", init=False)
@@ -182,7 +184,7 @@ class Button(Widget, can_focus=True):
def __init__(
self,
label: TextType | None = None,
label: ContentText | None = None,
variant: ButtonVariant = "default",
*,
name: str | None = None,
@@ -209,7 +211,7 @@ class Button(Widget, can_focus=True):
if label is None:
label = self.css_identifier_styled
self.label = label
self.label = Content.from_text(label)
self.variant = variant
self.action = action
self.active_effect_duration = 0.2
@@ -219,6 +221,7 @@ class Button(Widget, can_focus=True):
self.tooltip = tooltip
def get_content_width(self, container: Size, viewport: Size) -> int:
assert isinstance(self.label, Content)
try:
return max([cell_len(line) for line in self.label.plain.splitlines()]) + 2
except ValueError:
@@ -240,14 +243,15 @@ class Button(Widget, can_focus=True):
self.remove_class(f"-{old_variant}")
self.add_class(f"-{variant}")
def validate_label(self, label: TextType) -> Text:
def validate_label(self, label: ContentText) -> Content:
"""Parse markup for self.label"""
if isinstance(label, str):
return Text.from_markup(label)
return label
return Content.from_text(label)
def render(self) -> RenderResult:
assert isinstance(self.label, Text)
assert isinstance(self.label, Content)
return Padding(self.label, Spacing.unpack((0, 1)))
label = self.label.copy()
label.stylize_before(self.rich_style)
return HorizontalPad(