diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f34d7dc59..64fba1b744 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added experimental Canvas class https://github.com/Textualize/textual/pull/3669/ - Added `keyline` rule https://github.com/Textualize/textual/pull/3669/ - Widgets can now have an ALLOW_CHILDREN (bool) classvar to disallow adding children to a widget https://github.com/Textualize/textual/pull/3758 +- Added the ability to set the `label` property of a `Checkbox` https://github.com/Textualize/textual/pull/3765 +- Added the ability to set the `label` property of a `RadioButton` https://github.com/Textualize/textual/pull/3765 ### Changed diff --git a/src/textual/widgets/_toggle_button.py b/src/textual/widgets/_toggle_button.py index 2d2841e672..c8a6570b1b 100644 --- a/src/textual/widgets/_toggle_button.py +++ b/src/textual/widgets/_toggle_button.py @@ -149,18 +149,35 @@ def __init__( # NOTE: Don't send a Changed message in response to the initial set. with self.prevent(self.Changed): self.value = value - self._label = Text.from_markup(label) if isinstance(label, str) else label + self._label = self._make_label(label) + + def _make_label(self, label: TextType) -> Text: + """Make a `Text` label from a `TextType` value. + + Args: + label: The source value for the label. + + Returns: + A `Text` rendering of the label for use in the button. + """ + label = Text.from_markup(label) if isinstance(label, str) else label try: # Only use the first line if it's a multi-line label. - self._label = self._label.split()[0] + label = label.split()[0] except IndexError: pass + return label @property def label(self) -> Text: """The label associated with the button.""" return self._label + @label.setter + def label(self, label: TextType) -> None: + self._label = self._make_label(label) + self.refresh(layout=True) + @property def _button(self) -> Text: """The button, reflecting the current value.""" diff --git a/tests/toggles/test_labels.py b/tests/toggles/test_labels.py new file mode 100644 index 0000000000..a879351d0d --- /dev/null +++ b/tests/toggles/test_labels.py @@ -0,0 +1,36 @@ +"""Test that setting a toggle button's label has the desired effect.""" + +from rich.text import Text + +from textual.app import App, ComposeResult +from textual.widgets import Checkbox, RadioButton, RadioSet + + +class LabelChangeApp(App[None]): + def compose(self) -> ComposeResult: + yield Checkbox("Before") + yield RadioButton("Before") + yield RadioSet("Before") + + +async def test_change_labels() -> None: + """It should be possible to change the labels of toggle buttons.""" + async with LabelChangeApp().run_test() as pilot: + assert pilot.app.query_one(Checkbox).label == Text("Before") + assert pilot.app.query_one("Screen > RadioButton", RadioButton).label == Text( + "Before" + ) + assert pilot.app.query_one("RadioSet > RadioButton", RadioButton).label == Text( + "Before" + ) + pilot.app.query_one(Checkbox).label = "After" + pilot.app.query_one("Screen > RadioButton", RadioButton).label = "After" + pilot.app.query_one("RadioSet > RadioButton", RadioButton).label = "After" + await pilot.pause() + assert pilot.app.query_one(Checkbox).label == Text("After") + assert pilot.app.query_one("Screen > RadioButton", RadioButton).label == Text( + "After" + ) + assert pilot.app.query_one("RadioSet > RadioButton", RadioButton).label == Text( + "After" + )