diff --git a/CHANGELOG.md b/CHANGELOG.md
index 87edabf69..27c3fa5bb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Breaking change: `TreeNode` can no longer be imported from `textual.widgets`; it is now available via `from textual.widgets.tree import TreeNode`. https://github.com/Textualize/textual/pull/1637
- `Tree` now shows a (subdued) cursor for a highlighted node when focus has moved elsewhere https://github.com/Textualize/textual/issues/1471
+- Breaking change: renamed `Checkbox` to `Switch`.
### Fixed
diff --git a/docs/api/checkbox.md b/docs/api/checkbox.md
deleted file mode 100644
index 6c9c434f2..000000000
--- a/docs/api/checkbox.md
+++ /dev/null
@@ -1 +0,0 @@
-::: textual.widgets.Checkbox
diff --git a/docs/api/switch.md b/docs/api/switch.md
new file mode 100644
index 000000000..711e817a0
--- /dev/null
+++ b/docs/api/switch.md
@@ -0,0 +1 @@
+::: textual.widgets.Switch
diff --git a/docs/examples/widgets/checkbox.css b/docs/examples/widgets/switch.css
similarity index 86%
rename from docs/examples/widgets/checkbox.css
rename to docs/examples/widgets/switch.css
index 77c9fb368..fb6a0d220 100644
--- a/docs/examples/widgets/checkbox.css
+++ b/docs/examples/widgets/switch.css
@@ -7,7 +7,7 @@ Screen {
width: auto;
}
-Checkbox {
+Switch {
height: auto;
width: auto;
}
@@ -22,7 +22,7 @@ Checkbox {
background: darkslategrey;
}
-#custom-design > .checkbox--switch {
+#custom-design > .switch--switch {
color: dodgerblue;
background: darkslateblue;
}
diff --git a/docs/examples/widgets/checkbox.py b/docs/examples/widgets/switch.py
similarity index 55%
rename from docs/examples/widgets/checkbox.py
rename to docs/examples/widgets/switch.py
index 400f2ae25..54a59ad63 100644
--- a/docs/examples/widgets/checkbox.py
+++ b/docs/examples/widgets/switch.py
@@ -1,35 +1,35 @@
from textual.app import App, ComposeResult
from textual.containers import Horizontal
-from textual.widgets import Checkbox, Static
+from textual.widgets import Switch, Static
-class CheckboxApp(App):
+class SwitchApp(App):
def compose(self) -> ComposeResult:
- yield Static("[b]Example checkboxes\n", classes="label")
+ yield Static("[b]Example switches\n", classes="label")
yield Horizontal(
Static("off: ", classes="label"),
- Checkbox(animate=False),
+ Switch(animate=False),
classes="container",
)
yield Horizontal(
Static("on: ", classes="label"),
- Checkbox(value=True),
+ Switch(value=True),
classes="container",
)
- focused_checkbox = Checkbox()
- focused_checkbox.focus()
+ focused_switch = Switch()
+ focused_switch.focus()
yield Horizontal(
- Static("focused: ", classes="label"), focused_checkbox, classes="container"
+ Static("focused: ", classes="label"), focused_switch, classes="container"
)
yield Horizontal(
Static("custom: ", classes="label"),
- Checkbox(id="custom-design"),
+ Switch(id="custom-design"),
classes="container",
)
-app = CheckboxApp(css_path="checkbox.css")
+app = SwitchApp(css_path="switch.css")
if __name__ == "__main__":
app.run()
diff --git a/docs/roadmap.md b/docs/roadmap.md
index 7589d5c33..f486260b8 100644
--- a/docs/roadmap.md
+++ b/docs/roadmap.md
@@ -40,7 +40,7 @@ Widgets are key to making user-friendly interfaces. The builtin widgets should c
- [x] Buttons
* [x] Error / warning variants
- [ ] Color picker
-- [x] Checkbox
+- [ ] Checkbox
- [ ] Content switcher
- [x] DataTable
* [x] Cell select
@@ -70,6 +70,7 @@ Widgets are key to making user-friendly interfaces. The builtin widgets should c
* [ ] Style variants (solid, thin etc)
- [ ] Radio boxes
- [ ] Spark-lines
+- [X] Switch
- [ ] Tabs
- [ ] TextArea (multi-line input)
* [ ] Basic controls
diff --git a/docs/widgets/checkbox.md b/docs/widgets/checkbox.md
deleted file mode 100644
index a5a247ef9..000000000
--- a/docs/widgets/checkbox.md
+++ /dev/null
@@ -1,63 +0,0 @@
-# Checkbox
-
-A simple checkbox widget which stores a boolean value.
-
-- [x] Focusable
-- [ ] Container
-
-## Example
-
-The example below shows checkboxes in various states.
-
-=== "Output"
-
- ```{.textual path="docs/examples/widgets/checkbox.py"}
- ```
-
-=== "checkbox.py"
-
- ```python
- --8<-- "docs/examples/widgets/checkbox.py"
- ```
-
-=== "checkbox.css"
-
- ```sass
- --8<-- "docs/examples/widgets/checkbox.css"
- ```
-
-## Reactive Attributes
-
-| Name | Type | Default | Description |
-| ------- | ------ | ------- | ---------------------------------- |
-| `value` | `bool` | `False` | The default value of the checkbox. |
-
-## Bindings
-
-The checkbox widget defines directly the following bindings:
-
-::: textual.widgets.Checkbox.BINDINGS
- options:
- show_root_heading: false
- show_root_toc_entry: false
-
-## Component Classes
-
-The checkbox widget provides the following component classes:
-
-::: textual.widgets.Checkbox.COMPONENT_CLASSES
- options:
- show_root_heading: false
- show_root_toc_entry: false
-
-## Messages
-
-### ::: textual.widgets.Checkbox.Changed
-
-## Additional Notes
-
-- To remove the spacing around a checkbox, set `border: none;` and `padding: 0;`.
-
-## See Also
-
-- [Checkbox](../api/checkbox.md) code reference
diff --git a/docs/widgets/switch.md b/docs/widgets/switch.md
new file mode 100644
index 000000000..1cb77be6e
--- /dev/null
+++ b/docs/widgets/switch.md
@@ -0,0 +1,63 @@
+# Switch
+
+A simple switch widget which stores a boolean value.
+
+- [x] Focusable
+- [ ] Container
+
+## Example
+
+The example below shows switches in various states.
+
+=== "Output"
+
+ ```{.textual path="docs/examples/widgets/switch.py"}
+ ```
+
+=== "switch.py"
+
+ ```python
+ --8<-- "docs/examples/widgets/switch.py"
+ ```
+
+=== "switch.css"
+
+ ```sass
+ --8<-- "docs/examples/widgets/switch.css"
+ ```
+
+## Reactive Attributes
+
+| Name | Type | Default | Description |
+|---------|--------|---------|----------------------------------|
+| `value` | `bool` | `False` | The default value of the switch. |
+
+## Bindings
+
+The switch widget defines directly the following bindings:
+
+::: textual.widgets.Switch.BINDINGS
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+
+## Component Classes
+
+The switch widget provides the following component classes:
+
+::: textual.widgets.Switch.COMPONENT_CLASSES
+ options:
+ show_root_heading: false
+ show_root_toc_entry: false
+
+## Messages
+
+### ::: textual.widgets.Switch.Changed
+
+## Additional Notes
+
+- To remove the spacing around a `Switch`, set `border: none;` and `padding: 0;`.
+
+## See Also
+
+- [Switch](../api/switch.md) code reference
diff --git a/mkdocs.yml b/mkdocs.yml
index ad2d90d47..863f1288d 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -126,7 +126,6 @@ nav:
- "styles/width.md"
- Widgets:
- "widgets/button.md"
- - "widgets/checkbox.md"
- "widgets/data_table.md"
- "widgets/directory_tree.md"
- "widgets/footer.md"
@@ -138,6 +137,7 @@ nav:
- "widgets/list_view.md"
- "widgets/placeholder.md"
- "widgets/static.md"
+ - "widgets/switch.md"
- "widgets/text_log.md"
- "widgets/tree.md"
- API:
@@ -145,7 +145,6 @@ nav:
- "api/app.md"
- "api/binding.md"
- "api/button.md"
- - "api/checkbox.md"
- "api/color.md"
- "api/containers.md"
- "api/coordinate.md"
@@ -170,6 +169,7 @@ nav:
- "api/scroll_view.md"
- "api/static.md"
- "api/strip.md"
+ - "api/switch.md"
- "api/text_log.md"
- "api/timer.md"
- "api/tree.md"
diff --git a/src/textual/demo.css b/src/textual/demo.css
index c93224e9f..3fb8c7d71 100644
--- a/src/textual/demo.css
+++ b/src/textual/demo.css
@@ -119,7 +119,7 @@ DarkSwitch .label {
color: $text-muted;
}
-DarkSwitch Checkbox {
+DarkSwitch Switch {
background: $boost;
dock: left;
}
diff --git a/src/textual/demo.py b/src/textual/demo.py
index 907d93307..9f523ab4c 100644
--- a/src/textual/demo.py
+++ b/src/textual/demo.py
@@ -18,7 +18,7 @@ from textual.containers import Container, Horizontal
from textual.reactive import reactive, watch
from textual.widgets import (
Button,
- Checkbox,
+ Switch,
DataTable,
Footer,
Header,
@@ -138,7 +138,7 @@ Build your own or use the builtin widgets.
- **Input** Text / Password input.
- **Button** Clickable button with a number of styles.
-- **Checkbox** A checkbox to toggle between states.
+- **Switch** A switch to toggle between states.
- **DataTable** A spreadsheet-like widget for navigating data. Cells may contain text or Rich renderables.
- **Tree** An generic tree with expandable nodes.
- **DirectoryTree** A tree of file and folders.
@@ -199,16 +199,16 @@ class Title(Static):
class DarkSwitch(Horizontal):
def compose(self) -> ComposeResult:
- yield Checkbox(value=self.app.dark)
+ yield Switch(value=self.app.dark)
yield Static("Dark mode toggle", classes="label")
def on_mount(self) -> None:
watch(self.app, "dark", self.on_dark_change, init=False)
def on_dark_change(self, dark: bool) -> None:
- self.query_one(Checkbox).value = self.app.dark
+ self.query_one(Switch).value = self.app.dark
- def on_checkbox_changed(self, event: Checkbox.Changed) -> None:
+ def on_switch_changed(self, event: Switch.Changed) -> None:
self.app.dark = event.value
diff --git a/src/textual/widgets/__init__.py b/src/textual/widgets/__init__.py
index 98dd81f18..e26881468 100644
--- a/src/textual/widgets/__init__.py
+++ b/src/textual/widgets/__init__.py
@@ -9,7 +9,7 @@ from ..case import camel_to_snake
# be able to "see" them.
if typing.TYPE_CHECKING:
from ._button import Button
- from ._checkbox import Checkbox
+ from ._switch import Switch
from ._data_table import DataTable
from ._directory_tree import DirectoryTree
from ._footer import Footer
@@ -29,7 +29,7 @@ if typing.TYPE_CHECKING:
__all__ = [
"Button",
- "Checkbox",
+ "Switch",
"DataTable",
"DirectoryTree",
"Footer",
diff --git a/src/textual/widgets/__init__.pyi b/src/textual/widgets/__init__.pyi
index 82d25cd90..ad3b73fbb 100644
--- a/src/textual/widgets/__init__.pyi
+++ b/src/textual/widgets/__init__.pyi
@@ -1,7 +1,7 @@
# This stub file must re-export every classes exposed in the __init__.py's `__all__` list:
from ._button import Button as Button
from ._data_table import DataTable as DataTable
-from ._checkbox import Checkbox as Checkbox
+from ._switch import Switch as Switch
from ._directory_tree import DirectoryTree as DirectoryTree
from ._footer import Footer as Footer
from ._header import Header as Header
diff --git a/src/textual/widgets/_checkbox.py b/src/textual/widgets/_switch.py
similarity index 65%
rename from src/textual/widgets/_checkbox.py
rename to src/textual/widgets/_switch.py
index 9b5b1b454..cdc9f21a6 100644
--- a/src/textual/widgets/_checkbox.py
+++ b/src/textual/widgets/_switch.py
@@ -12,12 +12,12 @@ from ..widget import Widget
from ..scrollbar import ScrollBarRender
-class Checkbox(Widget, can_focus=True):
- """A checkbox widget that represents a boolean value.
+class Switch(Widget, can_focus=True):
+ """A switch widget that represents a boolean value.
- Can be toggled by clicking on it or through its [bindings][textual.widgets.Checkbox.BINDINGS].
+ Can be toggled by clicking on it or through its [bindings][textual.widgets.Switch.BINDINGS].
- The checkbox widget also contains [component classes][textual.widgets.Checkbox.COMPONENT_CLASSES]
+ The switch widget also contains [component classes][textual.widgets.Switch.COMPONENT_CLASSES]
that enable more customization.
"""
@@ -27,20 +27,20 @@ class Checkbox(Widget, can_focus=True):
"""
| Key(s) | Description |
| :- | :- |
- | enter,space | Toggle the checkbox status. |
+ | enter,space | Toggle the switch state. |
"""
COMPONENT_CLASSES: ClassVar[set[str]] = {
- "checkbox--switch",
+ "switch--switch",
}
"""
| Class | Description |
| :- | :- |
- | `checkbox--switch` | Targets the switch of the checkbox. |
+ | `switch--switch` | Targets the switch of the switch. |
"""
DEFAULT_CSS = """
- Checkbox {
+ Switch {
border: tall transparent;
background: $panel;
height: auto;
@@ -48,49 +48,49 @@ class Checkbox(Widget, can_focus=True):
padding: 0 2;
}
- Checkbox > .checkbox--switch {
+ Switch > .switch--switch {
background: $panel-darken-2;
color: $panel-lighten-2;
}
- Checkbox:hover {
+ Switch:hover {
border: tall $background;
}
- Checkbox:focus {
+ Switch:focus {
border: tall $accent;
}
- Checkbox.-on {
+ Switch.-on {
}
- Checkbox.-on > .checkbox--switch {
+ Switch.-on > .switch--switch {
color: $success;
}
"""
value = reactive(False, init=False)
- """The value of the checkbox; `True` for on and `False` for off."""
+ """The value of the switch; `True` for on and `False` for off."""
slider_pos = reactive(0.0)
"""The position of the slider."""
class Changed(Message, bubble=True):
- """Posted when the status of the checkbox changes.
+ """Posted when the status of the switch changes.
- Can be handled using `on_checkbox_changed` in a subclass of `Checkbox`
+ Can be handled using `on_switch_changed` in a subclass of `Switch`
or in a parent widget in the DOM.
Attributes:
- value: The value that the checkbox was changed to.
- input: The `Checkbox` widget that was changed.
+ value: The value that the switch was changed to.
+ input: The `Switch` widget that was changed.
"""
- def __init__(self, sender: Checkbox, value: bool) -> None:
+ def __init__(self, sender: Switch, value: bool) -> None:
super().__init__(sender)
self.value: bool = value
- self.input: Checkbox = sender
+ self.input: Switch = sender
def __init__(
self,
@@ -101,14 +101,14 @@ class Checkbox(Widget, can_focus=True):
id: str | None = None,
classes: str | None = None,
):
- """Initialise the checkbox.
+ """Initialise the switch.
Args:
- value: The initial value of the checkbox. Defaults to False.
- animate: True if the checkbox should animate when toggled. Defaults to True.
- name: The name of the checkbox.
- id: The ID of the checkbox in the DOM.
- classes: The CSS classes of the checkbox.
+ value: The initial value of the switch. Defaults to False.
+ animate: True if the switch should animate when toggled. Defaults to True.
+ name: The name of the switch.
+ id: The ID of the switch in the DOM.
+ classes: The CSS classes of the switch.
"""
super().__init__(name=name, id=id, classes=classes)
if value:
@@ -128,7 +128,7 @@ class Checkbox(Widget, can_focus=True):
self.set_class(slider_pos == 1, "-on")
def render(self) -> RenderableType:
- style = self.get_component_rich_style("checkbox--switch")
+ style = self.get_component_rich_style("switch--switch")
return ScrollBarRender(
virtual_size=100,
window_size=50,
@@ -150,6 +150,6 @@ class Checkbox(Widget, can_focus=True):
self.toggle()
def toggle(self) -> None:
- """Toggle the checkbox value. As a result of the value changing,
- a Checkbox.Changed message will be posted."""
+ """Toggle the switch value. As a result of the value changing,
+ a Switch.Changed message will be posted."""
self.value = not self.value
diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
index 5a8c647bf..0064c4c32 100644
--- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
+++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr
@@ -344,166 +344,6 @@
'''
# ---
-# name: test_checkboxes
- '''
-
-
- '''
-# ---
# name: test_columns_height
'''