We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`Button.update` method?
I'm often caught out by `Button.update` not updating the label (or doing anything!)

I thought about overriding the method to simply assign `Button.label`, but the argument type for the `Static` base class is `RenderableType` whereas the button label is `TextType` (I'm afraid I don't fully understand the difference!)

Am I the only one who gets caught out by this?

--- 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/_button.py`
Content:
```
1 from __future__ import annotations
2 
3 from functools import partial
4 from typing import cast
5 
6 import rich.repr
7 from rich.console import ConsoleRenderable, RenderableType
8 from rich.text import Text, TextType
9 from typing_extensions import Literal, Self
10 
11 from .. import events
12 from ..binding import Binding
13 from ..css._error_tools import friendly_list
14 from ..message import Message
15 from ..pad import HorizontalPad
16 from ..reactive import reactive
17 from ..widgets import Static
18 
19 ButtonVariant = Literal["default", "primary", "success", "warning", "error"]
20 """The names of the valid button variants.
21 
22 These are the variants that can be used with a [`Button`][textual.widgets.Button].
23 """
24 
25 _VALID_BUTTON_VARIANTS = {"default", "primary", "success", "warning", "error"}
26 
27 
28 class InvalidButtonVariant(Exception):
29     """Exception raised if an invalid button variant is used."""
30 
31 
32 class Button(Static, can_focus=True):
33     """A simple clickable button."""
34 
35     DEFAULT_CSS = """
36     Button {
37         width: auto;
38         min-width: 16;
39         height: auto;
40         background: $panel;
41         color: $text;
42         border: none;
43         border-top: tall $panel-lighten-2;
44         border-bottom: tall $panel-darken-3;
45         text-align: center;
46         content-align: center middle;
47         text-style: bold;
48     }
49 
50     Button:focus {
51         text-style: bold reverse;
52     }
53 
54     Button:hover {
55         border-top: tall $panel;
56         background: $panel-darken-2;
57         color: $text;
58     }
59 
60     Button.-active {
61         background: $panel;
62         border-bottom: tall $panel-lighten-2;
63         border-top: tall $panel-darken-2;
64         tint: $background 30%;
65     }
66 
67     /* Primary variant */
68     Button.-primary {
69         background: $primary;
70         color: $text;
71         border-top: tall $primary-lighten-3;
72         border-bottom: tall $primary-darken-3;
73 
74     }
75 
76     Button.-primary:hover {
77         background: $primary-darken-2;
78         color: $text;
79         border-top: tall $primary;
80     }
81 
82     Button.-primary.-active {
83         background: $primary;
84         border-bottom: tall $primary-lighten-3;
85         border-top: tall $primary-darken-3;
86     }
87 
88 
89     /* Success variant */
90     Button.-success {
91         background: $success;
92         color: $text;
93         border-top: tall $success-lighten-2;
94         border-bottom: tall $success-darken-3;
95     }
96 
97     Button.-success:hover {
98         background: $success-darken-2;
99         color: $text;
100         border-top: tall $success;
101     }
102 
103     Button.-success.-active {
104         background: $success;
105         border-bottom: tall $success-lighten-2;
106         border-top: tall $success-darken-2;
107     }
108 
109 
110     /* Warning variant */
111     Button.-warning {
112         background: $warning;
113         color: $text;
114         border-top: tall $warning-lighten-2;
115         border-bottom: tall $warning-darken-3;
116     }
117 
118     Button.-warning:hover {
119         background: $warning-darken-2;
120         color: $text;
121         border-top: tall $warning;
122 
123     }
124 
125     Button.-warning.-active {
126         background: $warning;
127         border-bottom: tall $warning-lighten-2;
128         border-top: tall $warning-darken-2;
129     }
130 
131 
132     /* Error variant */
133     Button.-error {
134         background: $error;
135         color: $text;
136         border-top: tall $error-lighten-2;
137         border-bottom: tall $error-darken-3;
138 
139     }
140 
141     Button.-error:hover {
142         background: $error-darken-1;
143         color: $text;
144         border-top: tall $error;
145     }
146 
147     Button.-error.-active {
148         background: $error;
149         border-bottom: tall $error-lighten-2;
150         border-top: tall $error-darken-2;
151     }
152     """
153 
154     BINDINGS = [Binding("enter", "press", "Press Button", show=False)]
155 
156     label: reactive[TextType] = reactive[TextType]("")
157     """The text label that appears within the button."""
158 
159     variant = reactive("default")
160     """The variant name for the button."""
161 
162     class Pressed(Message):
163         """Event sent when a `Button` is pressed.
164 
165         Can be handled using `on_button_pressed` in a subclass of
166         [`Button`][textual.widgets.Button] or in a parent widget in the DOM.
167         """
168 
169         def __init__(self, button: Button) -> None:
170             self.button: Button = button
171             """The button that was pressed."""
172             super().__init__()
173 
174         @property
175         def control(self) -> Button:
176             """An alias for [Pressed.button][textual.widgets.Button.Pressed.button].
177 
178             This will be the same value as [Pressed.button][textual.widgets.Button.Pressed.button].
179             """
180             return self.button
181 
182     def __init__(
183         self,
184         label: TextType | None = None,
185         variant: ButtonVariant = "default",
186         *,
187         name: str | None = None,
188         id: str | None = None,
189         classes: str | None = None,
190         disabled: bool = False,
191     ):
192         """Create a Button widget.
193 
194         Args:
195             label: The text that appears within the button.
196             variant: The variant of the button.
197             name: The name of the button.
198             id: The ID of the button in the DOM.
199             classes: The CSS classes of the button.
200             disabled: Whether the button is disabled or not.
201         """
202         super().__init__(name=name, id=id, classes=classes, disabled=disabled)
203 
204         if label is None:
205             label = self.css_identifier_styled
206 
207         self.label = self.validate_label(label)
208 
209         self.variant = self.validate_variant(variant)
210 
211         self.active_effect_duration = 0.3
212         """Amount of time in seconds the button 'press' animation lasts."""
213 
214     def __rich_repr__(self) -> rich.repr.Result:
215         yield from super().__rich_repr__()
216         yield "variant", self.variant, "default"
217 
218     def validate_variant(self, variant: str) -> str:
219         if variant not in _VALID_BUTTON_VARIANTS:
220             raise InvalidButtonVariant(
221                 f"Valid button variants are {friendly_list(_VALID_BUTTON_VARIANTS)}"
222             )
223         return variant
224 
225     def watch_variant(self, old_variant: str, variant: str):
226         self.remove_class(f"-{old_variant}")
227         self.add_class(f"-{variant}")
228 
229     def validate_label(self, label: TextType) -> Text:
230         """Parse markup for self.label"""
231         if isinstance(label, str):
232             return Text.from_markup(label)
233         return label
234 
235     def render(self) -> RenderableType:
236         assert isinstance(self.label, Text)
237         label = self.label.copy()
238         label.stylize(self.rich_style)
239         return HorizontalPad(
240             label,
241             1,
242             1,
243             self.rich_style,
244             self._get_rich_justify() or "center",
245         )
246 
247     def post_render(self, renderable: RenderableType) -> ConsoleRenderable:
248         return cast(ConsoleRenderable, renderable)
249 
250     async def _on_click(self, event: events.Click) -> None:
251         event.stop()
252         self.press()
253 
254     def press(self) -> Self:
255         """Respond to a button press.
256 
257         Returns:
258             The button instance."""
259         if self.disabled or not self.display:
260             return self
261         # Manage the "active" effect:
262         self._start_active_affect()
263         # ...and let other components know that we've just been clicked:
264         self.post_message(Button.Pressed(self))
265         return self
266 
267     def _start_active_affect(self) -> None:
268         """Start a small animation to show the button was clicked."""
269         if self.active_effect_duration > 0:
270             self.add_class("-active")
271             self.set_timer(
272                 self.active_effect_duration, partial(self.remove_class, "-active")
273             )
274 
275     def action_press(self) -> None:
276         """Activate a press of the button."""
277         self.press()
278 
279     @classmethod
280     def success(
281         cls,
282         label: TextType | None = None,
283         *,
284         name: str | None = None,
285         id: str | None = None,
286         classes: str | None = None,
287         disabled: bool = False,
288     ) -> Button:
289         """Utility constructor for creating a success Button variant.
290 
291         Args:
292             label: The text that appears within the button.
293             disabled: Whether the button is disabled or not.
294             name: The name of the button.
295             id: The ID of the button in the DOM.
296             classes: The CSS classes of the button.
297             disabled: Whether the button is disabled or not.
298 
299         Returns:
300             A [`Button`][textual.widgets.Button] widget of the 'success'
301                 [variant][textual.widgets.button.ButtonVariant].
302         """
303         return Button(
304             label=label,
305             variant="success",
306             name=name,
307             id=id,
308             classes=classes,
309             disabled=disabled,
310         )
311 
312     @classmethod
313     def warning(
314         cls,
315         label: TextType | None = None,
316         *,
317         name: str | None = None,
318         id: str | None = None,
319         classes: str | None = None,
320         disabled: bool = False,
321     ) -> Button:
322         """Utility constructor for creating a warning Button variant.
323 
324         Args:
325             label: The text that appears within the button.
326             disabled: Whether the button is disabled or not.
327             name: The name of the button.
328             id: The ID of the button in the DOM.
329             classes: The CSS classes of the button.
330             disabled: Whether the button is disabled or not.
331 
332         Returns:
333             A [`Button`][textual.widgets.Button] widget of the 'warning'
334                 [variant][textual.widgets.button.ButtonVariant].
335         """
336         return Button(
337             label=label,
338             variant="warning",
339             name=name,
340             id=id,
341             classes=classes,
342             disabled=disabled,
343         )
344 
345     @classmethod
346     def error(
347         cls,
348         label: TextType | None = None,
349         *,
350         name: str | None = None,
351         id: str | None = None,
352         classes: str | None = None,
353         disabled: bool = False,
354     ) -> Button:
355         """Utility constructor for creating an error Button variant.
356 
357         Args:
358             label: The text that appears within the button.
359             disabled: Whether the button is disabled or not.
360             name: The name of the button.
361             id: The ID of the button in the DOM.
362             classes: The CSS classes of the button.
363             disabled: Whether the button is disabled or not.
364 
365         Returns:
366             A [`Button`][textual.widgets.Button] widget of the 'error'
367                 [variant][textual.widgets.button.ButtonVariant].
368         """
369         return Button(
370             label=label,
371             variant="error",
372             name=name,
373             id=id,
374             classes=classes,
375             disabled=disabled,
376         )
377
```
--- 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/_button.py b/src/textual/widgets/_button.py
--- a/src/textual/widgets/_button.py
+++ b/src/textual/widgets/_button.py
@@ -14,7 +14,7 @@
 from ..message import Message
 from ..pad import HorizontalPad
 from ..reactive import reactive
-from ..widgets import Static
+from ..widget import Widget
 
 ButtonVariant = Literal["default", "primary", "success", "warning", "error"]
 """The names of the valid button variants.
@@ -29,7 +29,7 @@
     """Exception raised if an invalid button variant is used."""
 
 
-class Button(Static, can_focus=True):
+class Button(Widget, can_focus=True):
     """A simple clickable button."""
 
     DEFAULT_CSS = """

{"golden_diff": "diff --git a/src/textual/widgets/_button.py b/src/textual/widgets/_button.py\n--- a/src/textual/widgets/_button.py\n+++ b/src/textual/widgets/_button.py\n@@ -14,7 +14,7 @@\n from ..message import Message\n from ..pad import HorizontalPad\n from ..reactive import reactive\n-from ..widgets import Static\n+from ..widget import Widget\n \n ButtonVariant = Literal[\"default\", \"primary\", \"success\", \"warning\", \"error\"]\n \"\"\"The names of the valid button variants.\n@@ -29,7 +29,7 @@\n     \"\"\"Exception raised if an invalid button variant is used.\"\"\"\n \n \n-class Button(Static, can_focus=True):\n+class Button(Widget, can_focus=True):\n     \"\"\"A simple clickable button.\"\"\"\n \n     DEFAULT_CSS = \"\"\"\n", "issue": "`Button.update` method?\nI'm often caught out by `Button.update` not updating the label (or doing anything!)\r\n\r\nI thought about overriding the method to simply assign `Button.label`, but the argument type for the `Static` base class is `RenderableType` whereas the button label is `TextType` (I'm afraid I don't fully understand the difference!)\r\n\r\nAm I the only one who gets caught out by this?\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom functools import partial\nfrom typing import cast\n\nimport rich.repr\nfrom rich.console import ConsoleRenderable, RenderableType\nfrom rich.text import Text, TextType\nfrom typing_extensions import Literal, Self\n\nfrom .. import events\nfrom ..binding import Binding\nfrom ..css._error_tools import friendly_list\nfrom ..message import Message\nfrom ..pad import HorizontalPad\nfrom ..reactive import reactive\nfrom ..widgets import Static\n\nButtonVariant = Literal[\"default\", \"primary\", \"success\", \"warning\", \"error\"]\n\"\"\"The names of the valid button variants.\n\nThese are the variants that can be used with a [`Button`][textual.widgets.Button].\n\"\"\"\n\n_VALID_BUTTON_VARIANTS = {\"default\", \"primary\", \"success\", \"warning\", \"error\"}\n\n\nclass InvalidButtonVariant(Exception):\n    \"\"\"Exception raised if an invalid button variant is used.\"\"\"\n\n\nclass Button(Static, can_focus=True):\n    \"\"\"A simple clickable button.\"\"\"\n\n    DEFAULT_CSS = \"\"\"\n    Button {\n        width: auto;\n        min-width: 16;\n        height: auto;\n        background: $panel;\n        color: $text;\n        border: none;\n        border-top: tall $panel-lighten-2;\n        border-bottom: tall $panel-darken-3;\n        text-align: center;\n        content-align: center middle;\n        text-style: bold;\n    }\n\n    Button:focus {\n        text-style: bold reverse;\n    }\n\n    Button:hover {\n        border-top: tall $panel;\n        background: $panel-darken-2;\n        color: $text;\n    }\n\n    Button.-active {\n        background: $panel;\n        border-bottom: tall $panel-lighten-2;\n        border-top: tall $panel-darken-2;\n        tint: $background 30%;\n    }\n\n    /* Primary variant */\n    Button.-primary {\n        background: $primary;\n        color: $text;\n        border-top: tall $primary-lighten-3;\n        border-bottom: tall $primary-darken-3;\n\n    }\n\n    Button.-primary:hover {\n        background: $primary-darken-2;\n        color: $text;\n        border-top: tall $primary;\n    }\n\n    Button.-primary.-active {\n        background: $primary;\n        border-bottom: tall $primary-lighten-3;\n        border-top: tall $primary-darken-3;\n    }\n\n\n    /* Success variant */\n    Button.-success {\n        background: $success;\n        color: $text;\n        border-top: tall $success-lighten-2;\n        border-bottom: tall $success-darken-3;\n    }\n\n    Button.-success:hover {\n        background: $success-darken-2;\n        color: $text;\n        border-top: tall $success;\n    }\n\n    Button.-success.-active {\n        background: $success;\n        border-bottom: tall $success-lighten-2;\n        border-top: tall $success-darken-2;\n    }\n\n\n    /* Warning variant */\n    Button.-warning {\n        background: $warning;\n        color: $text;\n        border-top: tall $warning-lighten-2;\n        border-bottom: tall $warning-darken-3;\n    }\n\n    Button.-warning:hover {\n        background: $warning-darken-2;\n        color: $text;\n        border-top: tall $warning;\n\n    }\n\n    Button.-warning.-active {\n        background: $warning;\n        border-bottom: tall $warning-lighten-2;\n        border-top: tall $warning-darken-2;\n    }\n\n\n    /* Error variant */\n    Button.-error {\n        background: $error;\n        color: $text;\n        border-top: tall $error-lighten-2;\n        border-bottom: tall $error-darken-3;\n\n    }\n\n    Button.-error:hover {\n        background: $error-darken-1;\n        color: $text;\n        border-top: tall $error;\n    }\n\n    Button.-error.-active {\n        background: $error;\n        border-bottom: tall $error-lighten-2;\n        border-top: tall $error-darken-2;\n    }\n    \"\"\"\n\n    BINDINGS = [Binding(\"enter\", \"press\", \"Press Button\", show=False)]\n\n    label: reactive[TextType] = reactive[TextType](\"\")\n    \"\"\"The text label that appears within the button.\"\"\"\n\n    variant = reactive(\"default\")\n    \"\"\"The variant name for the button.\"\"\"\n\n    class Pressed(Message):\n        \"\"\"Event sent when a `Button` is pressed.\n\n        Can be handled using `on_button_pressed` in a subclass of\n        [`Button`][textual.widgets.Button] or in a parent widget in the DOM.\n        \"\"\"\n\n        def __init__(self, button: Button) -> None:\n            self.button: Button = button\n            \"\"\"The button that was pressed.\"\"\"\n            super().__init__()\n\n        @property\n        def control(self) -> Button:\n            \"\"\"An alias for [Pressed.button][textual.widgets.Button.Pressed.button].\n\n            This will be the same value as [Pressed.button][textual.widgets.Button.Pressed.button].\n            \"\"\"\n            return self.button\n\n    def __init__(\n        self,\n        label: TextType | None = None,\n        variant: ButtonVariant = \"default\",\n        *,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ):\n        \"\"\"Create a Button widget.\n\n        Args:\n            label: The text that appears within the button.\n            variant: The variant of the button.\n            name: The name of the button.\n            id: The ID of the button in the DOM.\n            classes: The CSS classes of the button.\n            disabled: Whether the button is disabled or not.\n        \"\"\"\n        super().__init__(name=name, id=id, classes=classes, disabled=disabled)\n\n        if label is None:\n            label = self.css_identifier_styled\n\n        self.label = self.validate_label(label)\n\n        self.variant = self.validate_variant(variant)\n\n        self.active_effect_duration = 0.3\n        \"\"\"Amount of time in seconds the button 'press' animation lasts.\"\"\"\n\n    def __rich_repr__(self) -> rich.repr.Result:\n        yield from super().__rich_repr__()\n        yield \"variant\", self.variant, \"default\"\n\n    def validate_variant(self, variant: str) -> str:\n        if variant not in _VALID_BUTTON_VARIANTS:\n            raise InvalidButtonVariant(\n                f\"Valid button variants are {friendly_list(_VALID_BUTTON_VARIANTS)}\"\n            )\n        return variant\n\n    def watch_variant(self, old_variant: str, variant: str):\n        self.remove_class(f\"-{old_variant}\")\n        self.add_class(f\"-{variant}\")\n\n    def validate_label(self, label: TextType) -> Text:\n        \"\"\"Parse markup for self.label\"\"\"\n        if isinstance(label, str):\n            return Text.from_markup(label)\n        return label\n\n    def render(self) -> RenderableType:\n        assert isinstance(self.label, Text)\n        label = self.label.copy()\n        label.stylize(self.rich_style)\n        return HorizontalPad(\n            label,\n            1,\n            1,\n            self.rich_style,\n            self._get_rich_justify() or \"center\",\n        )\n\n    def post_render(self, renderable: RenderableType) -> ConsoleRenderable:\n        return cast(ConsoleRenderable, renderable)\n\n    async def _on_click(self, event: events.Click) -> None:\n        event.stop()\n        self.press()\n\n    def press(self) -> Self:\n        \"\"\"Respond to a button press.\n\n        Returns:\n            The button instance.\"\"\"\n        if self.disabled or not self.display:\n            return self\n        # Manage the \"active\" effect:\n        self._start_active_affect()\n        # ...and let other components know that we've just been clicked:\n        self.post_message(Button.Pressed(self))\n        return self\n\n    def _start_active_affect(self) -> None:\n        \"\"\"Start a small animation to show the button was clicked.\"\"\"\n        if self.active_effect_duration > 0:\n            self.add_class(\"-active\")\n            self.set_timer(\n                self.active_effect_duration, partial(self.remove_class, \"-active\")\n            )\n\n    def action_press(self) -> None:\n        \"\"\"Activate a press of the button.\"\"\"\n        self.press()\n\n    @classmethod\n    def success(\n        cls,\n        label: TextType | None = None,\n        *,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ) -> Button:\n        \"\"\"Utility constructor for creating a success Button variant.\n\n        Args:\n            label: The text that appears within the button.\n            disabled: Whether the button is disabled or not.\n            name: The name of the button.\n            id: The ID of the button in the DOM.\n            classes: The CSS classes of the button.\n            disabled: Whether the button is disabled or not.\n\n        Returns:\n            A [`Button`][textual.widgets.Button] widget of the 'success'\n                [variant][textual.widgets.button.ButtonVariant].\n        \"\"\"\n        return Button(\n            label=label,\n            variant=\"success\",\n            name=name,\n            id=id,\n            classes=classes,\n            disabled=disabled,\n        )\n\n    @classmethod\n    def warning(\n        cls,\n        label: TextType | None = None,\n        *,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ) -> Button:\n        \"\"\"Utility constructor for creating a warning Button variant.\n\n        Args:\n            label: The text that appears within the button.\n            disabled: Whether the button is disabled or not.\n            name: The name of the button.\n            id: The ID of the button in the DOM.\n            classes: The CSS classes of the button.\n            disabled: Whether the button is disabled or not.\n\n        Returns:\n            A [`Button`][textual.widgets.Button] widget of the 'warning'\n                [variant][textual.widgets.button.ButtonVariant].\n        \"\"\"\n        return Button(\n            label=label,\n            variant=\"warning\",\n            name=name,\n            id=id,\n            classes=classes,\n            disabled=disabled,\n        )\n\n    @classmethod\n    def error(\n        cls,\n        label: TextType | None = None,\n        *,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ) -> Button:\n        \"\"\"Utility constructor for creating an error Button variant.\n\n        Args:\n            label: The text that appears within the button.\n            disabled: Whether the button is disabled or not.\n            name: The name of the button.\n            id: The ID of the button in the DOM.\n            classes: The CSS classes of the button.\n            disabled: Whether the button is disabled or not.\n\n        Returns:\n            A [`Button`][textual.widgets.Button] widget of the 'error'\n                [variant][textual.widgets.button.ButtonVariant].\n        \"\"\"\n        return Button(\n            label=label,\n            variant=\"error\",\n            name=name,\n            id=id,\n            classes=classes,\n            disabled=disabled,\n        )\n", "path": "src/textual/widgets/_button.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom functools import partial\nfrom typing import cast\n\nimport rich.repr\nfrom rich.console import ConsoleRenderable, RenderableType\nfrom rich.text import Text, TextType\nfrom typing_extensions import Literal, Self\n\nfrom .. import events\nfrom ..binding import Binding\nfrom ..css._error_tools import friendly_list\nfrom ..message import Message\nfrom ..pad import HorizontalPad\nfrom ..reactive import reactive\nfrom ..widget import Widget\n\nButtonVariant = Literal[\"default\", \"primary\", \"success\", \"warning\", \"error\"]\n\"\"\"The names of the valid button variants.\n\nThese are the variants that can be used with a [`Button`][textual.widgets.Button].\n\"\"\"\n\n_VALID_BUTTON_VARIANTS = {\"default\", \"primary\", \"success\", \"warning\", \"error\"}\n\n\nclass InvalidButtonVariant(Exception):\n    \"\"\"Exception raised if an invalid button variant is used.\"\"\"\n\n\nclass Button(Widget, can_focus=True):\n    \"\"\"A simple clickable button.\"\"\"\n\n    DEFAULT_CSS = \"\"\"\n    Button {\n        width: auto;\n        min-width: 16;\n        height: auto;\n        background: $panel;\n        color: $text;\n        border: none;\n        border-top: tall $panel-lighten-2;\n        border-bottom: tall $panel-darken-3;\n        text-align: center;\n        content-align: center middle;\n        text-style: bold;\n    }\n\n    Button:focus {\n        text-style: bold reverse;\n    }\n\n    Button:hover {\n        border-top: tall $panel;\n        background: $panel-darken-2;\n        color: $text;\n    }\n\n    Button.-active {\n        background: $panel;\n        border-bottom: tall $panel-lighten-2;\n        border-top: tall $panel-darken-2;\n        tint: $background 30%;\n    }\n\n    /* Primary variant */\n    Button.-primary {\n        background: $primary;\n        color: $text;\n        border-top: tall $primary-lighten-3;\n        border-bottom: tall $primary-darken-3;\n\n    }\n\n    Button.-primary:hover {\n        background: $primary-darken-2;\n        color: $text;\n        border-top: tall $primary;\n    }\n\n    Button.-primary.-active {\n        background: $primary;\n        border-bottom: tall $primary-lighten-3;\n        border-top: tall $primary-darken-3;\n    }\n\n\n    /* Success variant */\n    Button.-success {\n        background: $success;\n        color: $text;\n        border-top: tall $success-lighten-2;\n        border-bottom: tall $success-darken-3;\n    }\n\n    Button.-success:hover {\n        background: $success-darken-2;\n        color: $text;\n        border-top: tall $success;\n    }\n\n    Button.-success.-active {\n        background: $success;\n        border-bottom: tall $success-lighten-2;\n        border-top: tall $success-darken-2;\n    }\n\n\n    /* Warning variant */\n    Button.-warning {\n        background: $warning;\n        color: $text;\n        border-top: tall $warning-lighten-2;\n        border-bottom: tall $warning-darken-3;\n    }\n\n    Button.-warning:hover {\n        background: $warning-darken-2;\n        color: $text;\n        border-top: tall $warning;\n\n    }\n\n    Button.-warning.-active {\n        background: $warning;\n        border-bottom: tall $warning-lighten-2;\n        border-top: tall $warning-darken-2;\n    }\n\n\n    /* Error variant */\n    Button.-error {\n        background: $error;\n        color: $text;\n        border-top: tall $error-lighten-2;\n        border-bottom: tall $error-darken-3;\n\n    }\n\n    Button.-error:hover {\n        background: $error-darken-1;\n        color: $text;\n        border-top: tall $error;\n    }\n\n    Button.-error.-active {\n        background: $error;\n        border-bottom: tall $error-lighten-2;\n        border-top: tall $error-darken-2;\n    }\n    \"\"\"\n\n    BINDINGS = [Binding(\"enter\", \"press\", \"Press Button\", show=False)]\n\n    label: reactive[TextType] = reactive[TextType](\"\")\n    \"\"\"The text label that appears within the button.\"\"\"\n\n    variant = reactive(\"default\")\n    \"\"\"The variant name for the button.\"\"\"\n\n    class Pressed(Message):\n        \"\"\"Event sent when a `Button` is pressed.\n\n        Can be handled using `on_button_pressed` in a subclass of\n        [`Button`][textual.widgets.Button] or in a parent widget in the DOM.\n        \"\"\"\n\n        def __init__(self, button: Button) -> None:\n            self.button: Button = button\n            \"\"\"The button that was pressed.\"\"\"\n            super().__init__()\n\n        @property\n        def control(self) -> Button:\n            \"\"\"An alias for [Pressed.button][textual.widgets.Button.Pressed.button].\n\n            This will be the same value as [Pressed.button][textual.widgets.Button.Pressed.button].\n            \"\"\"\n            return self.button\n\n    def __init__(\n        self,\n        label: TextType | None = None,\n        variant: ButtonVariant = \"default\",\n        *,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ):\n        \"\"\"Create a Button widget.\n\n        Args:\n            label: The text that appears within the button.\n            variant: The variant of the button.\n            name: The name of the button.\n            id: The ID of the button in the DOM.\n            classes: The CSS classes of the button.\n            disabled: Whether the button is disabled or not.\n        \"\"\"\n        super().__init__(name=name, id=id, classes=classes, disabled=disabled)\n\n        if label is None:\n            label = self.css_identifier_styled\n\n        self.label = self.validate_label(label)\n\n        self.variant = self.validate_variant(variant)\n\n        self.active_effect_duration = 0.3\n        \"\"\"Amount of time in seconds the button 'press' animation lasts.\"\"\"\n\n    def __rich_repr__(self) -> rich.repr.Result:\n        yield from super().__rich_repr__()\n        yield \"variant\", self.variant, \"default\"\n\n    def validate_variant(self, variant: str) -> str:\n        if variant not in _VALID_BUTTON_VARIANTS:\n            raise InvalidButtonVariant(\n                f\"Valid button variants are {friendly_list(_VALID_BUTTON_VARIANTS)}\"\n            )\n        return variant\n\n    def watch_variant(self, old_variant: str, variant: str):\n        self.remove_class(f\"-{old_variant}\")\n        self.add_class(f\"-{variant}\")\n\n    def validate_label(self, label: TextType) -> Text:\n        \"\"\"Parse markup for self.label\"\"\"\n        if isinstance(label, str):\n            return Text.from_markup(label)\n        return label\n\n    def render(self) -> RenderableType:\n        assert isinstance(self.label, Text)\n        label = self.label.copy()\n        label.stylize(self.rich_style)\n        return HorizontalPad(\n            label,\n            1,\n            1,\n            self.rich_style,\n            self._get_rich_justify() or \"center\",\n        )\n\n    def post_render(self, renderable: RenderableType) -> ConsoleRenderable:\n        return cast(ConsoleRenderable, renderable)\n\n    async def _on_click(self, event: events.Click) -> None:\n        event.stop()\n        self.press()\n\n    def press(self) -> Self:\n        \"\"\"Respond to a button press.\n\n        Returns:\n            The button instance.\"\"\"\n        if self.disabled or not self.display:\n            return self\n        # Manage the \"active\" effect:\n        self._start_active_affect()\n        # ...and let other components know that we've just been clicked:\n        self.post_message(Button.Pressed(self))\n        return self\n\n    def _start_active_affect(self) -> None:\n        \"\"\"Start a small animation to show the button was clicked.\"\"\"\n        if self.active_effect_duration > 0:\n            self.add_class(\"-active\")\n            self.set_timer(\n                self.active_effect_duration, partial(self.remove_class, \"-active\")\n            )\n\n    def action_press(self) -> None:\n        \"\"\"Activate a press of the button.\"\"\"\n        self.press()\n\n    @classmethod\n    def success(\n        cls,\n        label: TextType | None = None,\n        *,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ) -> Button:\n        \"\"\"Utility constructor for creating a success Button variant.\n\n        Args:\n            label: The text that appears within the button.\n            disabled: Whether the button is disabled or not.\n            name: The name of the button.\n            id: The ID of the button in the DOM.\n            classes: The CSS classes of the button.\n            disabled: Whether the button is disabled or not.\n\n        Returns:\n            A [`Button`][textual.widgets.Button] widget of the 'success'\n                [variant][textual.widgets.button.ButtonVariant].\n        \"\"\"\n        return Button(\n            label=label,\n            variant=\"success\",\n            name=name,\n            id=id,\n            classes=classes,\n            disabled=disabled,\n        )\n\n    @classmethod\n    def warning(\n        cls,\n        label: TextType | None = None,\n        *,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ) -> Button:\n        \"\"\"Utility constructor for creating a warning Button variant.\n\n        Args:\n            label: The text that appears within the button.\n            disabled: Whether the button is disabled or not.\n            name: The name of the button.\n            id: The ID of the button in the DOM.\n            classes: The CSS classes of the button.\n            disabled: Whether the button is disabled or not.\n\n        Returns:\n            A [`Button`][textual.widgets.Button] widget of the 'warning'\n                [variant][textual.widgets.button.ButtonVariant].\n        \"\"\"\n        return Button(\n            label=label,\n            variant=\"warning\",\n            name=name,\n            id=id,\n            classes=classes,\n            disabled=disabled,\n        )\n\n    @classmethod\n    def error(\n        cls,\n        label: TextType | None = None,\n        *,\n        name: str | None = None,\n        id: str | None = None,\n        classes: str | None = None,\n        disabled: bool = False,\n    ) -> Button:\n        \"\"\"Utility constructor for creating an error Button variant.\n\n        Args:\n            label: The text that appears within the button.\n            disabled: Whether the button is disabled or not.\n            name: The name of the button.\n            id: The ID of the button in the DOM.\n            classes: The CSS classes of the button.\n            disabled: Whether the button is disabled or not.\n\n        Returns:\n            A [`Button`][textual.widgets.Button] widget of the 'error'\n                [variant][textual.widgets.button.ButtonVariant].\n        \"\"\"\n        return Button(\n            label=label,\n            variant=\"error\",\n            name=name,\n            id=id,\n            classes=classes,\n            disabled=disabled,\n        )\n", "path": "src/textual/widgets/_button.py"}]}