diff --git a/src/textual/widgets/_collapsible.py b/src/textual/widgets/_collapsible.py index dcd9441e40..3eb02ede44 100644 --- a/src/textual/widgets/_collapsible.py +++ b/src/textual/widgets/_collapsible.py @@ -44,6 +44,7 @@ class CollapsibleTitle(Widget, can_focus=True): """ collapsed = reactive(True) + label = reactive("Toggle") def __init__( self, @@ -83,6 +84,7 @@ class Collapsible(Widget): """A collapsible container.""" collapsed = reactive(True) + title = reactive("Toggle") DEFAULT_CSS = """ Collapsible { @@ -169,6 +171,8 @@ def __init__( classes: The CSS classes of the collapsible. disabled: Whether the collapsible is disabled or not. """ + super().__init__(name=name, id=id, classes=classes, disabled=disabled) + self.title = title self._title = CollapsibleTitle( label=title, collapsed_symbol=collapsed_symbol, @@ -176,7 +180,6 @@ def __init__( collapsed=collapsed, ) self._contents_list: list[Widget] = list(children) - super().__init__(name=name, id=id, classes=classes, disabled=disabled) self.collapsed = collapsed def _on_collapsible_title_toggle(self, event: CollapsibleTitle.Toggle) -> None: @@ -214,3 +217,8 @@ def compose_add_child(self, widget: Widget) -> None: widget: A Widget to add. """ self._contents_list.append(widget) + + def _watch_title(self, title: str) -> None: + if not self.is_mounted: + return + self._title.label = title diff --git a/tests/test_collapsible.py b/tests/test_collapsible.py index 2214d9fb9c..116ac74c9d 100644 --- a/tests/test_collapsible.py +++ b/tests/test_collapsible.py @@ -189,3 +189,15 @@ def on_collapsible_collapsed(self) -> None: assert pilot.app.query_one(Collapsible).collapsed assert len(hits) == 1 + + +async def test_collapsible_title_reactive_change(): + class CollapsibleApp(App[None]): + def compose(self) -> ComposeResult: + yield Collapsible(title="Old title") + + async with CollapsibleApp().run_test() as pilot: + collapsible = pilot.app.query_one(Collapsible) + assert get_title(collapsible).label == "Old title" + collapsible.title = "New title" + assert get_title(collapsible).label == "New title"