diff --git a/CHANGELOG.md b/CHANGELOG.md index bfdb7fd07..edafb2b82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [0.4.0] - Unreleased +### Changed + +- Dropped support for mounting "named" and "anonymous" widgets via + `App.mount` and `Widget.mount`. Both methods now simply take one or more + widgets as positional arguments. + ### Added - Added `init` param to reactive.watch diff --git a/src/textual/app.py b/src/textual/app.py index 9e96a4b94..7ea329ed4 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -822,27 +822,27 @@ class App(Generic[ReturnType], DOMNode): self._require_stylesheet_update.add(self.screen if node is None else node) self.check_idle() - def mount(self, *anon_widgets: Widget, **widgets: Widget) -> AwaitMount: - """Mount widgets. Widgets specified as positional args, or keywords args. If supplied - as keyword args they will be assigned an id of the key. + def mount(self, *widgets: Widget) -> AwaitMount: + """Mount the given widgets. + + Args: + *widgets (Widget): The widget(s) to mount. Returns: AwaitMount: An awaitable object that waits for widgets to be mounted. - """ - mounted_widgets = self._register(self.screen, *anon_widgets, **widgets) - return AwaitMount(mounted_widgets) + return AwaitMount(self._register(self.screen, *widgets)) def mount_all(self, widgets: Iterable[Widget]) -> AwaitMount: """Mount widgets from an iterable. Args: widgets (Iterable[Widget]): An iterable of widgets. + + Returns: + AwaitMount: An awaitable object that waits for widgets to be mounted. """ - mounted_widgets = list(widgets) - for widget in mounted_widgets: - self._register(self.screen, widget) - return AwaitMount(mounted_widgets) + return self.mount(*widgets) def is_screen_installed(self, screen: Screen | str) -> bool: """Check if a given screen has been installed. @@ -1300,37 +1300,33 @@ class App(Generic[ReturnType], DOMNode): return True return False - def _register( - self, parent: DOMNode, *anon_widgets: Widget, **widgets: Widget - ) -> list[Widget]: + def _register(self, parent: DOMNode, *widgets: Widget) -> list[Widget]: """Register widget(s) so they may receive events. Args: - parent (Widget): Parent Widget. + parent (DOMNode): Parent node. + *widgets: The widget(s) to register. Returns: list[Widget]: List of modified widgets. """ - if not anon_widgets and not widgets: + + if not widgets: return [] - name_widgets: list[tuple[str | None, Widget]] - name_widgets = [*((None, widget) for widget in anon_widgets), *widgets.items()] + apply_stylesheet = self.stylesheet.apply - for widget_id, widget in name_widgets: + for widget in widgets: if not isinstance(widget, Widget): raise AppError(f"Can't register {widget!r}; expected a Widget instance") if widget not in self._registry: - if widget_id is not None: - widget.id = widget_id self._register_child(parent, widget) if widget.children: self._register(widget, *widget.children) apply_stylesheet(widget) - registered_widgets = [widget for _, widget in name_widgets] - return registered_widgets + return list(widgets) def _unregister(self, widget: Widget) -> None: """Unregister a widget. diff --git a/src/textual/dom.py b/src/textual/dom.py index 89cd3b95b..aa8f9a1b4 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -609,21 +609,16 @@ class DOMNode(MessagePump): self.children._append(node) node._attach(self) - def _add_children(self, *nodes: Widget, **named_nodes: Widget) -> None: + def _add_children(self, *nodes: Widget) -> None: """Add multiple children to this node. Args: *nodes (DOMNode): Positional args should be new DOM nodes. - **named_nodes (DOMNode): Keyword args will be assigned the argument name as an ID. """ _append = self.children._append for node in nodes: node._attach(self) _append(node) - for node_id, node in named_nodes.items(): - node._attach(self) - _append(node) - node.id = node_id WalkType = TypeVar("WalkType") diff --git a/src/textual/widget.py b/src/textual/widget.py index 13fd2ab5b..9d1f50bb2 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -375,23 +375,16 @@ class Widget(DOMNode): if self._scrollbar_corner is not None: yield self._scrollbar_corner - def mount(self, *anon_widgets: Widget, **widgets: Widget) -> AwaitMount: + def mount(self, *widgets: Widget) -> AwaitMount: """Mount child widgets (making this widget a container). - Widgets may be passed as positional arguments or keyword arguments. If keyword arguments, - the keys will be set as the Widget's id. - - Example: - ```python - self.mount(Static("hello"), header=Header()) - ``` + Args: + *widgets (Widget): The widget(s) to mount. Returns: AwaitMount: An awaitable object that waits for widgets to be mounted. - """ - mounted_widgets = self.app._register(self, *anon_widgets, **widgets) - return AwaitMount(mounted_widgets) + return AwaitMount(self.app._register(self, *widgets)) def compose(self) -> ComposeResult: """Called by Textual to create child widgets.