We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Make Title of a Collapsible Widget Editable
Can not update title property of the Collapsible widget , looking at CollapsibleTitle class it seems to only set at init
Looks like this was an intentional choice ?
But I think it would be helpful to make the title property editable ,
Eg: changing content in the collapsed state and don't want to toggle it open to get a quick status update, so write something in .title... 

~~~
from textual.app import App, ComposeResult
from textual.containers import Container, Horizontal, VerticalScroll
from textual.widgets import Header, Footer, Collapsible, Placeholder

class AnApp(App):

    TITLE = "Collapsible Titles Should Update"

    BINDINGS = [("d", "toggle_dark", "Update"),
    ("c", "collapse_or_expand(True)", "Collapse"),
    ("e", "collapse_or_expand(False)", "Expand")]
    
    def action_collapse_or_expand(self, collapse: bool) -> None:
        for child in self.walk_children(Collapsible):
            child.collapsed = collapse

    def compose(self) -> ComposeResult:
        """Create child widgets for the app."""
        yield Header(show_clock=True)
        yield VerticalScroll(
            Collapsible(
                Horizontal(
                 Placeholder(variant="text"),
                 Placeholder(variant="size"),
                 Placeholder(variant="text"),
            ),
            title="Top_Stuff",id="top"
            )
        )
        yield Footer()

    def action_toggle_dark(self) -> None:
        """An action to toggle dark mode."""
        top_collapsible_widget = self.query_one("#top")
        top_collapsible_widget.title = "UPDATED_Top_Stuff"
        self.app.title = "UPDATED_App_Title"
        self.dark = not self.dark


if __name__ == "__main__":
    app = AnApp()
    app.run()
~~~

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/textual/widgets/_collapsible.py`
Content:
```
1 from __future__ import annotations
2 
3 from rich.console import RenderableType
4 from rich.text import Text
5 
6 from .. import events
7 from ..app import ComposeResult
8 from ..binding import Binding
9 from ..containers import Container
10 from ..css.query import NoMatches
11 from ..message import Message
12 from ..reactive import reactive
13 from ..widget import Widget
14 
15 __all__ = ["Collapsible", "CollapsibleTitle"]
16 
17 
18 class CollapsibleTitle(Widget, can_focus=True):
19     """Title and symbol for the Collapsible."""
20 
21     DEFAULT_CSS = """
22     CollapsibleTitle {
23         width: auto;
24         height: auto;
25         padding: 0 1 0 1;
26     }
27 
28     CollapsibleTitle:hover {
29         background: $foreground 10%;
30         color: $text;
31     }
32 
33     CollapsibleTitle:focus {
34         background: $accent;
35         color: $text;
36     }
37     """
38 
39     BINDINGS = [Binding("enter", "toggle", "Toggle collapsible", show=False)]
40     """
41     | Key(s) | Description |
42     | :- | :- |
43     | enter | Toggle the collapsible. |
44     """
45 
46     collapsed = reactive(True)
47 
48     def __init__(
49         self,
50         *,
51         label: str,
52         collapsed_symbol: str,
53         expanded_symbol: str,
54         collapsed: bool,
55     ) -> None:
56         super().__init__()
57         self.collapsed_symbol = collapsed_symbol
58         self.expanded_symbol = expanded_symbol
59         self.label = label
60         self.collapse = collapsed
61 
62     class Toggle(Message):
63         """Request toggle."""
64 
65     async def _on_click(self, event: events.Click) -> None:
66         """Inform ancestor we want to toggle."""
67         event.stop()
68         self.post_message(self.Toggle())
69 
70     def action_toggle(self) -> None:
71         """Toggle the state of the parent collapsible."""
72         self.post_message(self.Toggle())
73 
74     def render(self) -> RenderableType:
75         """Compose right/down arrow and label."""
76         if self.collapsed:
77             return Text(f"{self.collapsed_symbol} {self.label}")
78         else:
79             return Text(f"{self.expanded_symbol} {self.label}")
80 
81 
82 class Collapsible(Widget):
83     """A collapsible container."""
84 
85     collapsed = reactive(True)
86 
87     DEFAULT_CSS = """
88     Collapsible {
89         width: 1fr;
90         height: auto;
91         background: $boost;
92         border-top: hkey $background;
93         padding-bottom: 1;
94         padding-left: 1;
95     }
96 
97     Collapsible.-collapsed > Contents {
98         display: none;
99     }
100     """
101 
102     class Toggled(Message):
103         """Parent class subclassed by `Collapsible` messages.
104 
105         Can be handled with `on(Collapsible.Toggled)` if you want to handle expansions
106         and collapsed in the same way, or you can handle the specific events individually.
107         """
108 
109         def __init__(self, collapsible: Collapsible) -> None:
110             """Create an instance of the message.
111 
112             Args:
113                 collapsible: The `Collapsible` widget that was toggled.
114             """
115             self.collapsible: Collapsible = collapsible
116             """The collapsible that was toggled."""
117             super().__init__()
118 
119         @property
120         def control(self) -> Collapsible:
121             """An alias for [Toggled.collapsible][textual.widgets.Collapsible.Toggled.collapsible]."""
122             return self.collapsible
123 
124     class Expanded(Toggled):
125         """Event sent when the `Collapsible` widget is expanded.
126 
127         Can be handled using `on_collapsible_expanded` in a subclass of
128         [`Collapsible`][textual.widgets.Collapsible] or in a parent widget in the DOM.
129         """
130 
131     class Collapsed(Toggled):
132         """Event sent when the `Collapsible` widget is collapsed.
133 
134         Can be handled using `on_collapsible_collapsed` in a subclass of
135         [`Collapsible`][textual.widgets.Collapsible] or in a parent widget in the DOM.
136         """
137 
138     class Contents(Container):
139         DEFAULT_CSS = """
140         Contents {
141             width: 100%;
142             height: auto;
143             padding: 1 0 0 3;
144         }
145         """
146 
147     def __init__(
148         self,
149         *children: Widget,
150         title: str = "Toggle",
151         collapsed: bool = True,
152         collapsed_symbol: str = "▶",
153         expanded_symbol: str = "▼",
154         name: str | None = None,
155         id: str | None = None,
156         classes: str | None = None,
157         disabled: bool = False,
158     ) -> None:
159         """Initialize a Collapsible widget.
160 
161         Args:
162             *children: Contents that will be collapsed/expanded.
163             title: Title of the collapsed/expanded contents.
164             collapsed: Default status of the contents.
165             collapsed_symbol: Collapsed symbol before the title.
166             expanded_symbol: Expanded symbol before the title.
167             name: The name of the collapsible.
168             id: The ID of the collapsible in the DOM.
169             classes: The CSS classes of the collapsible.
170             disabled: Whether the collapsible is disabled or not.
171         """
172         self._title = CollapsibleTitle(
173             label=title,
174             collapsed_symbol=collapsed_symbol,
175             expanded_symbol=expanded_symbol,
176             collapsed=collapsed,
177         )
178         self._contents_list: list[Widget] = list(children)
179         super().__init__(name=name, id=id, classes=classes, disabled=disabled)
180         self.collapsed = collapsed
181 
182     def _on_collapsible_title_toggle(self, event: CollapsibleTitle.Toggle) -> None:
183         event.stop()
184         self.collapsed = not self.collapsed
185         if self.collapsed:
186             self.post_message(self.Collapsed(self))
187         else:
188             self.post_message(self.Expanded(self))
189 
190     def _watch_collapsed(self, collapsed: bool) -> None:
191         """Update collapsed state when reactive is changed."""
192         self._update_collapsed(collapsed)
193 
194     def _update_collapsed(self, collapsed: bool) -> None:
195         """Update children to match collapsed state."""
196         try:
197             self._title.collapsed = collapsed
198             self.set_class(collapsed, "-collapsed")
199         except NoMatches:
200             pass
201 
202     def _on_mount(self, event: events.Mount) -> None:
203         """Initialise collapsed state."""
204         self._update_collapsed(self.collapsed)
205 
206     def compose(self) -> ComposeResult:
207         yield self._title
208         yield self.Contents(*self._contents_list)
209 
210     def compose_add_child(self, widget: Widget) -> None:
211         """When using the context manager compose syntax, we want to attach nodes to the contents.
212 
213         Args:
214             widget: A Widget to add.
215         """
216         self._contents_list.append(widget)
217
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/textual/widgets/_collapsible.py b/src/textual/widgets/_collapsible.py
--- a/src/textual/widgets/_collapsible.py
+++ b/src/textual/widgets/_collapsible.py
@@ -1,8 +1,5 @@
 from __future__ import annotations
 
-from rich.console import RenderableType
-from rich.text import Text
-
 from .. import events
 from ..app import ComposeResult
 from ..binding import Binding
@@ -11,11 +8,12 @@
 from ..message import Message
 from ..reactive import reactive
 from ..widget import Widget
+from ..widgets import Static
 
 __all__ = ["Collapsible", "CollapsibleTitle"]
 
 
-class CollapsibleTitle(Widget, can_focus=True):
+class CollapsibleTitle(Static, can_focus=True):
     """Title and symbol for the Collapsible."""
 
     DEFAULT_CSS = """
@@ -44,6 +42,7 @@
     """
 
     collapsed = reactive(True)
+    label = reactive("Toggle")
 
     def __init__(
         self,
@@ -57,7 +56,9 @@
         self.collapsed_symbol = collapsed_symbol
         self.expanded_symbol = expanded_symbol
         self.label = label
-        self.collapse = collapsed
+        self.collapsed = collapsed
+        self._collapsed_label = f"{collapsed_symbol} {label}"
+        self._expanded_label = f"{expanded_symbol} {label}"
 
     class Toggle(Message):
         """Request toggle."""
@@ -71,18 +72,26 @@
         """Toggle the state of the parent collapsible."""
         self.post_message(self.Toggle())
 
-    def render(self) -> RenderableType:
-        """Compose right/down arrow and label."""
+    def _watch_label(self, label: str) -> None:
+        self._collapsed_label = f"{self.collapsed_symbol} {label}"
+        self._expanded_label = f"{self.expanded_symbol} {label}"
         if self.collapsed:
-            return Text(f"{self.collapsed_symbol} {self.label}")
+            self.update(self._collapsed_label)
+        else:
+            self.update(self._expanded_label)
+
+    def _watch_collapsed(self, collapsed: bool) -> None:
+        if collapsed:
+            self.update(self._collapsed_label)
         else:
-            return Text(f"{self.expanded_symbol} {self.label}")
+            self.update(self._expanded_label)
 
 
 class Collapsible(Widget):
     """A collapsible container."""
 
     collapsed = reactive(True)
+    title = reactive("Toggle")
 
     DEFAULT_CSS = """
     Collapsible {
@@ -169,14 +178,15 @@
             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 = CollapsibleTitle(
             label=title,
             collapsed_symbol=collapsed_symbol,
             expanded_symbol=expanded_symbol,
             collapsed=collapsed,
         )
+        self.title = title
         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 +224,6 @@
             widget: A Widget to add.
         """
         self._contents_list.append(widget)
+
+    def _watch_title(self, title: str) -> None:
+        self._title.label = title

{"golden_diff": "diff --git a/src/textual/widgets/_collapsible.py b/src/textual/widgets/_collapsible.py\n--- a/src/textual/widgets/_collapsible.py\n+++ b/src/textual/widgets/_collapsible.py\n@@ -1,8 +1,5 @@\n from __future__ import annotations\n \n-from rich.console import RenderableType\n-from rich.text import Text\n-\n from .. import events\n from ..app import ComposeResult\n from ..binding import Binding\n@@ -11,11 +8,12 @@\n from ..message import Message\n from ..reactive import reactive\n from ..widget import Widget\n+from ..widgets import Static\n \n __all__ = [\"Collapsible\", \"CollapsibleTitle\"]\n \n \n-class CollapsibleTitle(Widget, can_focus=True):\n+class CollapsibleTitle(Static, can_focus=True):\n     \"\"\"Title and symbol for the Collapsible.\"\"\"\n \n     DEFAULT_CSS = \"\"\"\n@@ -44,6 +42,7 @@\n     \"\"\"\n \n     collapsed = reactive(True)\n+    label = reactive(\"Toggle\")\n \n     def __init__(\n         self,\n@@ -57,7 +56,9 @@\n         self.collapsed_symbol = collapsed_symbol\n         self.expanded_symbol = expanded_symbol\n         self.label = label\n-        self.collapse = collapsed\n+        self.collapsed = collapsed\n+        self._collapsed_label = f\"{collapsed_symbol} {label}\"\n+        self._expanded_label = f\"{expanded_symbol} {label}\"\n \n     class Toggle(Message):\n         \"\"\"Request toggle.\"\"\"\n@@ -71,18 +72,26 @@\n         \"\"\"Toggle the state of the parent collapsible.\"\"\"\n         self.post_message(self.Toggle())\n \n-    def render(self) -> RenderableType:\n-        \"\"\"Compose right/down arrow and label.\"\"\"\n+    def _watch_label(self, label: str) -> None:\n+        self._collapsed_label = f\"{self.collapsed_symbol} {label}\"\n+        self._expanded_label = f\"{self.expanded_symbol} {label}\"\n         if self.collapsed:\n-            return Text(f\"{self.collapsed_symbol} {self.label}\")\n+            self.update(self._collapsed_label)\n+        else:\n+            self.update(self._expanded_label)\n+\n+    def _watch_collapsed(self, collapsed: bool) -> None:\n+        if collapsed:\n+            self.update(self._collapsed_label)\n         else:\n-            return Text(f\"{self.expanded_symbol} {self.label}\")\n+            self.update(self._expanded_label)\n \n \n class Collapsible(Widget):\n     \"\"\"A collapsible container.\"\"\"\n \n     collapsed = reactive(True)\n+    title = reactive(\"Toggle\")\n \n     DEFAULT_CSS = \"\"\"\n     Collapsible {\n@@ -169,14 +178,15 @@\n             classes: The CSS classes of the collapsible.\n             disabled: Whether the collapsible is disabled or not.\n         \"\"\"\n+        super().__init__(name=name, id=id, classes=classes, disabled=disabled)\n         self._title = CollapsibleTitle(\n             label=title,\n             collapsed_symbol=collapsed_symbol,\n             expanded_symbol=expanded_symbol,\n             collapsed=collapsed,\n         )\n+        self.title = title\n         self._contents_list: list[Widget] = list(children)\n-        super().__init__(name=name, id=id, classes=classes, disabled=disabled)\n         self.collapsed = collapsed\n \n     def _on_collapsible_title_toggle(self, event: CollapsibleTitle.Toggle) -> None:\n@@ -214,3 +224,6 @@\n             widget: A Widget to add.\n         \"\"\"\n         self._contents_list.append(widget)\n+\n+    def _watch_title(self, title: str) -> None:\n+        self._title.label = title\n", "issue": "Make Title of a Collapsible Widget Editable\nCan not update title property of the Collapsible widget , looking at CollapsibleTitle class it seems to only set at init\r\nLooks like this was an intentional choice ?\r\nBut I think it would be helpful to make the title property editable ,\r\nEg: changing content in the collapsed state and don't want to toggle it open to get a quick status update, so write something in .title... \r\n\r\n~~~\r\nfrom textual.app import App, ComposeResult\r\nfrom textual.containers import Container, Horizontal, VerticalScroll\r\nfrom textual.widgets import Header, Footer, Collapsible, Placeholder\r\n\r\nclass AnApp(App):\r\n\r\n    TITLE = \"Collapsible Titles Should Update\"\r\n\r\n    BINDINGS = [(\"d\", \"toggle_dark\", \"Update\"),\r\n    (\"c\", \"collapse_or_expand(True)\", \"Collapse\"),\r\n    (\"e\", \"collapse_or_expand(False)\", \"Expand\")]\r\n    \r\n    def action_collapse_or_expand(self, collapse: bool) -> None:\r\n        for child in self.walk_children(Collapsible):\r\n            child.collapsed = collapse\r\n\r\n    def compose(self) -> ComposeResult:\r\n        \"\"\"Create child widgets for the app.\"\"\"\r\n        yield Header(show_clock=True)\r\n        yield VerticalScroll(\r\n            Collapsible(\r\n                Horizontal(\r\n                 Placeholder(variant=\"text\"),\r\n                 Placeholder(variant=\"size\"),\r\n                 Placeholder(variant=\"text\"),\r\n            ),\r\n            title=\"Top_Stuff\",id=\"top\"\r\n            )\r\n        )\r\n        yield Footer()\r\n\r\n    def action_toggle_dark(self) -> None:\r\n        \"\"\"An action to toggle dark mode.\"\"\"\r\n        top_collapsible_widget = self.query_one(\"#top\")\r\n        top_collapsible_widget.title = \"UPDATED_Top_Stuff\"\r\n        self.app.title = \"UPDATED_App_Title\"\r\n        self.dark = not self.dark\r\n\r\n\r\nif __name__ == \"__main__\":\r\n    app = AnApp()\r\n    app.run()\r\n~~~\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom rich.console import RenderableType\nfrom rich.text import Text\n\nfrom .. import events\nfrom ..app import ComposeResult\nfrom ..binding import Binding\nfrom ..containers import Container\nfrom ..css.query import NoMatches\nfrom ..message import Message\nfrom ..reactive import reactive\nfrom ..widget import Widget\n\n__all__ = [\"Collapsible\", \"CollapsibleTitle\"]\n\n\nclass CollapsibleTitle(Widget, can_focus=True):\n    \"\"\"Title and symbol for the Collapsible.\"\"\"\n\n    DEFAULT_CSS = \"\"\"\n    CollapsibleTitle {\n        width: auto;\n        height: auto;\n        padding: 0 1 0 1;\n    }\n\n    CollapsibleTitle:hover {\n        background: $foreground 10%;\n        color: $text;\n    }\n\n    CollapsibleTitle:focus {\n        background: $accent;\n        color: $text;\n    }\n    \"\"\"\n\n    BINDINGS = [Binding(\"enter\", \"toggle\", \"Toggle collapsible\", show=False)]\n    \"\"\"\n    | Key(s) | Description |\n    | :- | :- |\n    | enter | Toggle the collapsible. |\n    \"\"\"\n\n    collapsed = reactive(True)\n\n    def __init__(\n        self,\n        *,\n        label: str,\n        collapsed_symbol: str,\n        expanded_symbol: str,\n        collapsed: bool,\n    ) -> None:\n        super().__init__()\n        self.collapsed_symbol = collapsed_symbol\n        self.expanded_symbol = expanded_symbol\n        self.label = label\n        self.collapse = collapsed\n\n    class Toggle(Message):\n        \"\"\"Request toggle.\"\"\"\n\n    async def _on_click(self, event: events.Click) -> None:\n        \"\"\"Inform ancestor we want to toggle.\"\"\"\n        event.stop()\n        self.post_message(self.Toggle())\n\n    def action_toggle(self) -> None:\n        \"\"\"Toggle the state of the parent collapsible.\"\"\"\n        self.post_message(self.Toggle())\n\n    def render(self) -> RenderableType:\n        \"\"\"Compose right/down arrow and label.\"\"\"\n        if self.collapsed:\n            return Text(f\"{self.collapsed_symbol} {self.label}\")\n        else:\n            return Text(f\"{self.expanded_symbol} {self.label}\")\n\n\nclass Collapsible(Widget):\n    \"\"\"A collapsible container.\"\"\"\n\n    collapsed = reactive(True)\n\n    DEFAULT_CSS = \"\"\"\n    Collapsible {\n        width: 1fr;\n        height: auto;\n        background: $boost;\n        border-top: hkey $background;\n        padding-bottom: 1;\n        padding-left: 1;\n    }\n\n    Collapsible.-collapsed > Contents {\n        display: none;\n    }\n    \"\"\"\n\n    class Toggled(Message):\n        \"\"\"Parent class subclassed by `Collapsible` messages.\n\n        Can be handled with `on(Collapsible.Toggled)` if you want to handle expansions\n        and collapsed in the same way, or you can handle the specific events individually.\n        \"\"\"\n\n        def __init__(self, collapsible: Collapsible) -> None:\n            \"\"\"Create an instance of the message.\n\n            Args:\n                collapsible: The `Collapsible` widget that was toggled.\n            \"\"\"\n            self.collapsible: Collapsible = collapsible\n            \"\"\"The collapsible that was toggled.\"\"\"\n            super().__init__()\n\n        @property\n        def control(self) -> Collapsible:\n            \"\"\"An alias for [Toggled.collapsible][textual.widgets.Collapsible.Toggled.collapsible].\"\"\"\n            return self.collapsible\n\n    class Expanded(Toggled):\n        \"\"\"Event sent when the `Collapsible` widget is expanded.\n\n        Can be handled using `on_collapsible_expanded` in a subclass of\n        [`Collapsible`][textual.widgets.Collapsible] or in a parent widget in the DOM.\n        \"\"\"\n\n    class Collapsed(Toggled):\n        \"\"\"Event sent when the `Collapsible` widget is collapsed.\n\n        Can be handled using `on_collapsible_collapsed` in a subclass of\n        [`Collapsible`][textual.widgets.Collapsible] or in a parent widget in the DOM.\n        \"\"\"\n\n    class Contents(Container):\n        DEFAULT_CSS = \"\"\"\n        Contents {\n            width: 100%;\n            height: auto;\n            padding: 1 0 0 3;\n        }\n        \"\"\"\n\n    def __init__(\n        self,\n        *children: Widget,\n        title: str = \"Toggle\",\n        collapsed: bool = True,\n        collapsed_symbol: str = \"\u25b6\",\n        expanded_symbol: str = \"\u25bc\",\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ) -> None:\n        \"\"\"Initialize a Collapsible widget.\n\n        Args:\n            *children: Contents that will be collapsed/expanded.\n            title: Title of the collapsed/expanded contents.\n            collapsed: Default status of the contents.\n            collapsed_symbol: Collapsed symbol before the title.\n            expanded_symbol: Expanded symbol before the title.\n            name: The name of the collapsible.\n            id: The ID of the collapsible in the DOM.\n            classes: The CSS classes of the collapsible.\n            disabled: Whether the collapsible is disabled or not.\n        \"\"\"\n        self._title = CollapsibleTitle(\n            label=title,\n            collapsed_symbol=collapsed_symbol,\n            expanded_symbol=expanded_symbol,\n            collapsed=collapsed,\n        )\n        self._contents_list: list[Widget] = list(children)\n        super().__init__(name=name, id=id, classes=classes, disabled=disabled)\n        self.collapsed = collapsed\n\n    def _on_collapsible_title_toggle(self, event: CollapsibleTitle.Toggle) -> None:\n        event.stop()\n        self.collapsed = not self.collapsed\n        if self.collapsed:\n            self.post_message(self.Collapsed(self))\n        else:\n            self.post_message(self.Expanded(self))\n\n    def _watch_collapsed(self, collapsed: bool) -> None:\n        \"\"\"Update collapsed state when reactive is changed.\"\"\"\n        self._update_collapsed(collapsed)\n\n    def _update_collapsed(self, collapsed: bool) -> None:\n        \"\"\"Update children to match collapsed state.\"\"\"\n        try:\n            self._title.collapsed = collapsed\n            self.set_class(collapsed, \"-collapsed\")\n        except NoMatches:\n            pass\n\n    def _on_mount(self, event: events.Mount) -> None:\n        \"\"\"Initialise collapsed state.\"\"\"\n        self._update_collapsed(self.collapsed)\n\n    def compose(self) -> ComposeResult:\n        yield self._title\n        yield self.Contents(*self._contents_list)\n\n    def compose_add_child(self, widget: Widget) -> None:\n        \"\"\"When using the context manager compose syntax, we want to attach nodes to the contents.\n\n        Args:\n            widget: A Widget to add.\n        \"\"\"\n        self._contents_list.append(widget)\n", "path": "src/textual/widgets/_collapsible.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom .. import events\nfrom ..app import ComposeResult\nfrom ..binding import Binding\nfrom ..containers import Container\nfrom ..css.query import NoMatches\nfrom ..message import Message\nfrom ..reactive import reactive\nfrom ..widget import Widget\nfrom ..widgets import Static\n\n__all__ = [\"Collapsible\", \"CollapsibleTitle\"]\n\n\nclass CollapsibleTitle(Static, can_focus=True):\n    \"\"\"Title and symbol for the Collapsible.\"\"\"\n\n    DEFAULT_CSS = \"\"\"\n    CollapsibleTitle {\n        width: auto;\n        height: auto;\n        padding: 0 1 0 1;\n    }\n\n    CollapsibleTitle:hover {\n        background: $foreground 10%;\n        color: $text;\n    }\n\n    CollapsibleTitle:focus {\n        background: $accent;\n        color: $text;\n    }\n    \"\"\"\n\n    BINDINGS = [Binding(\"enter\", \"toggle\", \"Toggle collapsible\", show=False)]\n    \"\"\"\n    | Key(s) | Description |\n    | :- | :- |\n    | enter | Toggle the collapsible. |\n    \"\"\"\n\n    collapsed = reactive(True)\n    label = reactive(\"Toggle\")\n\n    def __init__(\n        self,\n        *,\n        label: str,\n        collapsed_symbol: str,\n        expanded_symbol: str,\n        collapsed: bool,\n    ) -> None:\n        super().__init__()\n        self.collapsed_symbol = collapsed_symbol\n        self.expanded_symbol = expanded_symbol\n        self.label = label\n        self.collapsed = collapsed\n        self._collapsed_label = f\"{collapsed_symbol} {label}\"\n        self._expanded_label = f\"{expanded_symbol} {label}\"\n\n    class Toggle(Message):\n        \"\"\"Request toggle.\"\"\"\n\n    async def _on_click(self, event: events.Click) -> None:\n        \"\"\"Inform ancestor we want to toggle.\"\"\"\n        event.stop()\n        self.post_message(self.Toggle())\n\n    def action_toggle(self) -> None:\n        \"\"\"Toggle the state of the parent collapsible.\"\"\"\n        self.post_message(self.Toggle())\n\n    def _watch_label(self, label: str) -> None:\n        self._collapsed_label = f\"{self.collapsed_symbol} {label}\"\n        self._expanded_label = f\"{self.expanded_symbol} {label}\"\n        if self.collapsed:\n            self.update(self._collapsed_label)\n        else:\n            self.update(self._expanded_label)\n\n    def _watch_collapsed(self, collapsed: bool) -> None:\n        if collapsed:\n            self.update(self._collapsed_label)\n        else:\n            self.update(self._expanded_label)\n\n\nclass Collapsible(Widget):\n    \"\"\"A collapsible container.\"\"\"\n\n    collapsed = reactive(True)\n    title = reactive(\"Toggle\")\n\n    DEFAULT_CSS = \"\"\"\n    Collapsible {\n        width: 1fr;\n        height: auto;\n        background: $boost;\n        border-top: hkey $background;\n        padding-bottom: 1;\n        padding-left: 1;\n    }\n\n    Collapsible.-collapsed > Contents {\n        display: none;\n    }\n    \"\"\"\n\n    class Toggled(Message):\n        \"\"\"Parent class subclassed by `Collapsible` messages.\n\n        Can be handled with `on(Collapsible.Toggled)` if you want to handle expansions\n        and collapsed in the same way, or you can handle the specific events individually.\n        \"\"\"\n\n        def __init__(self, collapsible: Collapsible) -> None:\n            \"\"\"Create an instance of the message.\n\n            Args:\n                collapsible: The `Collapsible` widget that was toggled.\n            \"\"\"\n            self.collapsible: Collapsible = collapsible\n            \"\"\"The collapsible that was toggled.\"\"\"\n            super().__init__()\n\n        @property\n        def control(self) -> Collapsible:\n            \"\"\"An alias for [Toggled.collapsible][textual.widgets.Collapsible.Toggled.collapsible].\"\"\"\n            return self.collapsible\n\n    class Expanded(Toggled):\n        \"\"\"Event sent when the `Collapsible` widget is expanded.\n\n        Can be handled using `on_collapsible_expanded` in a subclass of\n        [`Collapsible`][textual.widgets.Collapsible] or in a parent widget in the DOM.\n        \"\"\"\n\n    class Collapsed(Toggled):\n        \"\"\"Event sent when the `Collapsible` widget is collapsed.\n\n        Can be handled using `on_collapsible_collapsed` in a subclass of\n        [`Collapsible`][textual.widgets.Collapsible] or in a parent widget in the DOM.\n        \"\"\"\n\n    class Contents(Container):\n        DEFAULT_CSS = \"\"\"\n        Contents {\n            width: 100%;\n            height: auto;\n            padding: 1 0 0 3;\n        }\n        \"\"\"\n\n    def __init__(\n        self,\n        *children: Widget,\n        title: str = \"Toggle\",\n        collapsed: bool = True,\n        collapsed_symbol: str = \"\u25b6\",\n        expanded_symbol: str = \"\u25bc\",\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ) -> None:\n        \"\"\"Initialize a Collapsible widget.\n\n        Args:\n            *children: Contents that will be collapsed/expanded.\n            title: Title of the collapsed/expanded contents.\n            collapsed: Default status of the contents.\n            collapsed_symbol: Collapsed symbol before the title.\n            expanded_symbol: Expanded symbol before the title.\n            name: The name of the collapsible.\n            id: The ID of the collapsible in the DOM.\n            classes: The CSS classes of the collapsible.\n            disabled: Whether the collapsible is disabled or not.\n        \"\"\"\n        super().__init__(name=name, id=id, classes=classes, disabled=disabled)\n        self._title = CollapsibleTitle(\n            label=title,\n            collapsed_symbol=collapsed_symbol,\n            expanded_symbol=expanded_symbol,\n            collapsed=collapsed,\n        )\n        self.title = title\n        self._contents_list: list[Widget] = list(children)\n        self.collapsed = collapsed\n\n    def _on_collapsible_title_toggle(self, event: CollapsibleTitle.Toggle) -> None:\n        event.stop()\n        self.collapsed = not self.collapsed\n        if self.collapsed:\n            self.post_message(self.Collapsed(self))\n        else:\n            self.post_message(self.Expanded(self))\n\n    def _watch_collapsed(self, collapsed: bool) -> None:\n        \"\"\"Update collapsed state when reactive is changed.\"\"\"\n        self._update_collapsed(collapsed)\n\n    def _update_collapsed(self, collapsed: bool) -> None:\n        \"\"\"Update children to match collapsed state.\"\"\"\n        try:\n            self._title.collapsed = collapsed\n            self.set_class(collapsed, \"-collapsed\")\n        except NoMatches:\n            pass\n\n    def _on_mount(self, event: events.Mount) -> None:\n        \"\"\"Initialise collapsed state.\"\"\"\n        self._update_collapsed(self.collapsed)\n\n    def compose(self) -> ComposeResult:\n        yield self._title\n        yield self.Contents(*self._contents_list)\n\n    def compose_add_child(self, widget: Widget) -> None:\n        \"\"\"When using the context manager compose syntax, we want to attach nodes to the contents.\n\n        Args:\n            widget: A Widget to add.\n        \"\"\"\n        self._contents_list.append(widget)\n\n    def _watch_title(self, title: str) -> None:\n        self._title.label = title\n", "path": "src/textual/widgets/_collapsible.py"}]}