diff --git a/CHANGELOG.md b/CHANGELOG.md index 751324ccdc..5e3455af5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Added + +- Added `ContentSwitcher.add_content` + ## [0.67.1] - 2024-06-12 ### Changed diff --git a/src/textual/_partition.py b/src/textual/_partition.py index be93fbe1be..09920bf579 100644 --- a/src/textual/_partition.py +++ b/src/textual/_partition.py @@ -21,7 +21,7 @@ def partition( """ result: tuple[list[T], list[T]] = ([], []) - appends = (result[0].append, result[1].append) + appends = (result[1].append, result[0].append) for value in iterable: - appends[1 if predicate(value) else 0](value) + appends[not predicate(value)](value) return result diff --git a/src/textual/widgets/_content_switcher.py b/src/textual/widgets/_content_switcher.py index 8e63e7a502..7077232233 100644 --- a/src/textual/widgets/_content_switcher.py +++ b/src/textual/widgets/_content_switcher.py @@ -4,6 +4,7 @@ from typing import Optional +from ..await_complete import AwaitComplete from ..containers import Container from ..css.query import NoMatches from ..events import Mount @@ -98,3 +99,34 @@ def watch_current(self, old: str | None, new: str | None) -> None: pass if new: self.get_child_by_id(new).display = True + + def add_content( + self, widget: Widget, *, id: str | None = None, set_current: bool = False + ) -> AwaitComplete: + """Add new content to the `ContentSwitcher`. + + Args: + widget: A Widget to add. + id: ID for the widget, or `None` if the widget already has an ID. + set_current: Set the new widget as current (which will cause it to display). + + Returns: + An awaitable to wait for the new content to be mounted. + """ + if id is not None and widget.id != id: + widget.id = id + + if not widget.id: + raise ValueError( + "Widget must have an ID (or set id parameter when calling add_content)" + ) + + async def _add_content() -> None: + """Add new widget and potentially change the current widget.""" + widget.display = False + with self.app.batch_update(): + await self.mount(widget) + if set_current: + self.current = widget.id + + return AwaitComplete(_add_content()) diff --git a/tests/test_content_switcher.py b/tests/test_content_switcher.py index a5e329e497..cc1e37a3e9 100644 --- a/tests/test_content_switcher.py +++ b/tests/test_content_switcher.py @@ -107,3 +107,16 @@ async def test_set_current_to_unknown_id() -> None: ) with pytest.raises(NoMatches): pilot.app.query_one(ContentSwitcher).current = "does-not-exist" + + +async def test_add_content() -> None: + async with SwitcherApp().run_test() as pilot: + switcher = pilot.app.query_one(ContentSwitcher) + await switcher.add_content(Widget(id="foo")) + assert not switcher.query_one("#foo").display + await switcher.add_content(Widget(), id="bar", set_current=True) + assert not switcher.query_one("#foo").display + assert switcher.query_one("#bar").display + assert switcher.current == "bar" + with pytest.raises(ValueError): + switcher.add_content(Widget())