From 0a2710f96bf3b7386983427b4bbbd2c7856aed37 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 25 Jun 2025 16:03:20 +0100 Subject: [PATCH 1/3] Containers How-to --- CHANGELOG.md | 6 + docs/examples/how-to/containers01.py | 29 +++++ docs/examples/how-to/containers02.py | 29 +++++ docs/examples/how-to/containers03.py | 35 ++++++ docs/examples/how-to/containers04.py | 39 +++++++ docs/examples/how-to/containers05.py | 39 +++++++ docs/examples/how-to/containers06.py | 34 ++++++ docs/examples/how-to/containers07.py | 34 ++++++ docs/examples/how-to/containers08.py | 36 ++++++ docs/examples/how-to/containers09.py | 36 ++++++ docs/how-to/work-with-containers.md | 167 +++++++++++++++++++++++++++ src/textual/containers.py | 12 ++ 12 files changed, 496 insertions(+) create mode 100644 docs/examples/how-to/containers01.py create mode 100644 docs/examples/how-to/containers02.py create mode 100644 docs/examples/how-to/containers03.py create mode 100644 docs/examples/how-to/containers04.py create mode 100644 docs/examples/how-to/containers05.py create mode 100644 docs/examples/how-to/containers06.py create mode 100644 docs/examples/how-to/containers07.py create mode 100644 docs/examples/how-to/containers08.py create mode 100644 docs/examples/how-to/containers09.py create mode 100644 docs/how-to/work-with-containers.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 19b78b6104..53d8ea9bc0 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 `CenterMiddle` container + ## [3.5.0] - 2025-06-20 ### Changed diff --git a/docs/examples/how-to/containers01.py b/docs/examples/how-to/containers01.py new file mode 100644 index 0000000000..122ab7e80e --- /dev/null +++ b/docs/examples/how-to/containers01.py @@ -0,0 +1,29 @@ +from textual.app import App, ComposeResult +from textual.containers import Horizontal +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 8; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + def compose(self) -> ComposeResult: + with Horizontal(): # (1)! + yield Box() # (2)! + yield Box() + yield Box() + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/examples/how-to/containers02.py b/docs/examples/how-to/containers02.py new file mode 100644 index 0000000000..9a2b45c859 --- /dev/null +++ b/docs/examples/how-to/containers02.py @@ -0,0 +1,29 @@ +from textual.app import App, ComposeResult +from textual.containers import Vertical +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 8; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + def compose(self) -> ComposeResult: + with Vertical(): # (1)! + yield Box() + yield Box() + yield Box() + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/examples/how-to/containers03.py b/docs/examples/how-to/containers03.py new file mode 100644 index 0000000000..0e41596969 --- /dev/null +++ b/docs/examples/how-to/containers03.py @@ -0,0 +1,35 @@ +from textual.app import App, ComposeResult +from textual.containers import Horizontal +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 8; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + CSS = """ + .with-border { + border: heavy green; + } + """ + + def compose(self) -> ComposeResult: + with Horizontal(classes="with-border"): # (1)! + yield Box() + yield Box() + yield Box() + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/examples/how-to/containers04.py b/docs/examples/how-to/containers04.py new file mode 100644 index 0000000000..e2c90e5f08 --- /dev/null +++ b/docs/examples/how-to/containers04.py @@ -0,0 +1,39 @@ +from textual.app import App, ComposeResult +from textual.containers import Horizontal +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 8; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + CSS = """ + .with-border { + border: heavy green; + } + """ + + def compose(self) -> ComposeResult: + with Horizontal(classes="with-border"): + yield Box() + yield Box() + yield Box() + with Horizontal(classes="with-border"): + yield Box() + yield Box() + yield Box() + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/examples/how-to/containers05.py b/docs/examples/how-to/containers05.py new file mode 100644 index 0000000000..c3aceceb93 --- /dev/null +++ b/docs/examples/how-to/containers05.py @@ -0,0 +1,39 @@ +from textual.app import App, ComposeResult +from textual.containers import HorizontalGroup +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 8; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + CSS = """ + .with-border { + border: heavy green; + } + """ + + def compose(self) -> ComposeResult: + with HorizontalGroup(classes="with-border"): + yield Box() + yield Box() + yield Box() + with HorizontalGroup(classes="with-border"): + yield Box() + yield Box() + yield Box() + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/examples/how-to/containers06.py b/docs/examples/how-to/containers06.py new file mode 100644 index 0000000000..00e717c96b --- /dev/null +++ b/docs/examples/how-to/containers06.py @@ -0,0 +1,34 @@ +from textual.app import App, ComposeResult +from textual.containers import Horizontal +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 8; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + CSS = """ + .with-border { + border: heavy green; + } + """ + + def compose(self) -> ComposeResult: + with Horizontal(classes="with-border"): + for n in range(10): + yield Box(label=f"Box {n+1}") + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/examples/how-to/containers07.py b/docs/examples/how-to/containers07.py new file mode 100644 index 0000000000..1b773abbbd --- /dev/null +++ b/docs/examples/how-to/containers07.py @@ -0,0 +1,34 @@ +from textual.app import App, ComposeResult +from textual.containers import HorizontalScroll +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 8; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + CSS = """ + .with-border { + border: heavy green; + } + """ + + def compose(self) -> ComposeResult: + with HorizontalScroll(classes="with-border"): + for n in range(10): + yield Box(label=f"Box {n+1}") + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/examples/how-to/containers08.py b/docs/examples/how-to/containers08.py new file mode 100644 index 0000000000..d12d6a5b4f --- /dev/null +++ b/docs/examples/how-to/containers08.py @@ -0,0 +1,36 @@ +from textual.app import App, ComposeResult +from textual.containers import Center, Right +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 5; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + CSS = """ + .with-border { + border: heavy green; + } + """ + + def compose(self) -> ComposeResult: + yield Box("Box 1") + with Center(classes="with-border"): + yield Box("Box 2") + with Right(classes="with-border"): + yield Box("Box 3") + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/examples/how-to/containers09.py b/docs/examples/how-to/containers09.py new file mode 100644 index 0000000000..1a845b5593 --- /dev/null +++ b/docs/examples/how-to/containers09.py @@ -0,0 +1,36 @@ +from textual.app import App, ComposeResult +from textual.containers import HorizontalGroup, Middle +from textual.widgets import Placeholder + + +class Box(Placeholder): + """Example widget.""" + + DEFAULT_CSS = """ + Box { + width: 16; + height: 5; + } + """ + + +class ContainerApp(App): + """Simple app to play with containers.""" + + CSS = """ + .with-border { + border: heavy green; + } + """ + + def compose(self) -> ComposeResult: + with HorizontalGroup(): + yield Box("Box 1") + with Middle(classes="with-border"): + yield Box("Box 2") + yield Box("Box 3") + + +if __name__ == "__main__": + app = ContainerApp() + app.run() diff --git a/docs/how-to/work-with-containers.md b/docs/how-to/work-with-containers.md new file mode 100644 index 0000000000..6b08dd9230 --- /dev/null +++ b/docs/how-to/work-with-containers.md @@ -0,0 +1,167 @@ +# Work with containers + +Textual's [containers][textual.containers] provide a convenient way of arranging your widgets. Let's look at them in a little detail! + +## What are containers? + +Containers are reusable [compound widgets](../guide/widgets.md#compound-widgets) with preset styles to arrange their children. +For instance, there is a [Horizontal][textual.containers.Horizontal] container which arranges all of its children in a horizontal row. +Let's look at a quick example of that: + +```python hl_lines="2 21" +--8<-- "docs/examples/how-to/containers01.py" +``` + +1. Use the with statement to add the Horizontal container. +2. Any widgets yielded within the Horizontal block will be arranged in a horizontal row. + +Here's the output: + +```{.textual path="docs/examples/how-to/containers01.py"} +``` + +Note that inside the `Horizontal` block new widgets will be placed to the right of previous widgets, forming a row. +This will still be the case if you later add or remove widgets. +Without the container, the widgets would be stacked vertically. + +### How are containers implemented? + +Before I describe some of the other containers, I would like to show how containers are implemented. +The following is the actual source of the `Horizontal` widget: + +```python +class Horizontal(Widget, inherit_bindings=False): + """An expanding container with horizontal layout and no scrollbars.""" + + DEFAULT_CSS = """ + Horizontal { + width: 1fr; + height: 1fr; + layout: horizontal; + overflow: hidden hidden; + } + """ +``` + +That's it! +A simple widget with a few preset styles. +The other containers are just as simple. + +You can customize the container with TCSS in the same way as other widgets. + +## Horizontal and Vertical + +We've seen the `Horizontal` container in action. +The [Vertical][textual.containers.Vertical] container, as you may have guessed, work the same but arranges its children vertically, i.e. from top to bottom. + +You can probably imagine what this looks like, but for sake of completeness, here is an example with a Vertical container: + +```python hl_lines="2 21" +--8<-- "docs/examples/how-to/containers02.py" +``` + +1. Stack the widgets vertically. + +And here's the output: + +```{.textual path="docs/examples/how-to/containers02.py"} +``` + +Three boxes, vertically stacked. + +### Size behavior + +Something to keep in mind when using `Horizontal` or `Vertical` is that they will consume the remaining space in the screen. Let's look at an example to illustrate that. + +The following code adds a `with-border` style which draws a green border around the container. +This will help us visualize the dimensions of the container. + +```python +--8<-- "docs/examples/how-to/containers03.py" +``` + +1. Add the `with-border` class to draw a border around the container. + +Here's the output: + +```{.textual path="docs/examples/how-to/containers03.py"} +``` + +Notice how the container is as large as the screen. +Let's look at what happens if we add another container: + +```python hl_lines="31-34" +--8<-- "docs/examples/how-to/containers04.py" +``` + +And here's the result: + +```{.textual path="docs/examples/how-to/containers04.py"} +``` + +Two horizontal containers divide the remaining screen space in two. +If you were to add another horizontal it would divide the screen space in to thirds--and so on. + +This makes `Horizontal` and `Vertical` excellent for designing the macro layout of your app's interface, but not for making tightly packed rows or columns. For that you need the *group* containers which I'll cover next. + +!!! tip "FR Units" + + You can implement this behavior of dividing the screen in your own widgets with [FR units](../guide/styles.md#fr-units) + + +## Group containers + +The [HorizontalGroup][textual.containers.HorizontalGroup] and [VerticalGroup][textual.containers.VerticalGroup] containers are very similar to their non-group counterparts, but don't expand to fill the screen space. + +Let's look at an example. +In the following code, we have two HorizontalGroups with a border so we can visualize their size. + +```python hl_lines="2 27 31" +--8<-- "docs/examples/how-to/containers05.py" +``` + +Here's the output: + +```{.textual path="docs/examples/how-to/containers05.py"} +``` + +We can see that the widgets are arranged horizontally as before, but they only use as much vertical space as required to fit. + +## Scrolling containers + +Something to watch out for regarding the previous containers we have discussed, is that they don't scroll by default. +Let's see what happens if we add more boxes than could fit on the screen. + +In the following example, we will add boxes: + +```python hl_lines="28 29" +--8<-- "docs/examples/how-to/containers06.py" +``` + +Here's the output: + +```{.textual path="docs/examples/how-to/containers06.py"} +``` + +We have add 10 `Box` widgets, but there is not enough room for them to fit. +The remaining boxes are off-screen and can't be viewed unless the user resizes their screen. + +If we expect more content that fits, we can replacing the containers with [HorizontalScroll][textual.containers.HorizontalScroll] or [VerticalScroll][textual.containers.VerticalScroll], which will automatically add scrollbars if required. + +Let's make that change: + +```python hl_lines="2 27" +--8<-- "docs/examples/how-to/containers07.py" +``` + +Here's the output: + +```{.textual path="docs/examples/how-to/containers07.py"} +``` + +We now have a scrollbar we can click and drag to see all the boxes. + +!!! tip "Automatic scrollbars" + + You can implement automatic scrollbars with the [overflow](../styles/overflow.md) style. + diff --git a/src/textual/containers.py b/src/textual/containers.py index 4f6cb0bde9..3811b6839d 100644 --- a/src/textual/containers.py +++ b/src/textual/containers.py @@ -230,6 +230,18 @@ class Middle(Widget, inherit_bindings=False): """ +class CenterMiddle(Widget, inherit_bindings=False): + """A container which aligns its children on both axis.""" + + DEFAULT_CSS = """ + CenterMiddle { + align: center middle; + width: 1fr; + height: 1fr; + } + """ + + class Grid(Widget, inherit_bindings=False): """A container with grid layout.""" From 74a4fddef4ed2aab03e64283f7ca9be25c8bfd7f Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 25 Jun 2025 17:22:16 +0100 Subject: [PATCH 2/3] more words --- CHANGELOG.md | 6 -- docs/examples/how-to/containers08.py | 6 +- docs/examples/how-to/containers09.py | 11 ++- docs/how-to/work-with-containers.md | 104 ++++++++++++++++++++++++--- src/textual/containers.py | 22 +++--- 5 files changed, 113 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53d8ea9bc0..19b78b6104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,6 @@ 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 `CenterMiddle` container - ## [3.5.0] - 2025-06-20 ### Changed diff --git a/docs/examples/how-to/containers08.py b/docs/examples/how-to/containers08.py index d12d6a5b4f..b366a42b03 100644 --- a/docs/examples/how-to/containers08.py +++ b/docs/examples/how-to/containers08.py @@ -24,10 +24,10 @@ class ContainerApp(App): """ def compose(self) -> ComposeResult: - yield Box("Box 1") - with Center(classes="with-border"): + yield Box("Box 1") # (1)! + with Center(classes="with-border"): # (2)! yield Box("Box 2") - with Right(classes="with-border"): + with Right(classes="with-border"): # (3)! yield Box("Box 3") diff --git a/docs/examples/how-to/containers09.py b/docs/examples/how-to/containers09.py index 1a845b5593..df7fd04245 100644 --- a/docs/examples/how-to/containers09.py +++ b/docs/examples/how-to/containers09.py @@ -1,5 +1,5 @@ from textual.app import App, ComposeResult -from textual.containers import HorizontalGroup, Middle +from textual.containers import Middle from textual.widgets import Placeholder @@ -24,11 +24,10 @@ class ContainerApp(App): """ def compose(self) -> ComposeResult: - with HorizontalGroup(): - yield Box("Box 1") - with Middle(classes="with-border"): - yield Box("Box 2") - yield Box("Box 3") + with Middle(classes="with-border"): # (1)! + yield Box("Box 1.") + yield Box("Box 2.") + yield Box("Box 3.") if __name__ == "__main__": diff --git a/docs/how-to/work-with-containers.md b/docs/how-to/work-with-containers.md index 6b08dd9230..ac30bb5beb 100644 --- a/docs/how-to/work-with-containers.md +++ b/docs/how-to/work-with-containers.md @@ -1,6 +1,11 @@ -# Work with containers +# Save time with Textual containers + +Textual's [containers][textual.containers] provide a convenient way of arranging your widgets. Let's look at them in a little detail. + +!!! info "Are you in the right place?" + + We are talking about Textual container widgets here. Not to be confused with [containerization](https://en.wikipedia.org/wiki/Containerization_(computing))—which is something else entirely! -Textual's [containers][textual.containers] provide a convenient way of arranging your widgets. Let's look at them in a little detail! ## What are containers? @@ -30,7 +35,7 @@ Before I describe some of the other containers, I would like to show how contain The following is the actual source of the `Horizontal` widget: ```python -class Horizontal(Widget, inherit_bindings=False): +class Horizontal(Widget): """An expanding container with horizontal layout and no scrollbars.""" DEFAULT_CSS = """ @@ -47,8 +52,6 @@ That's it! A simple widget with a few preset styles. The other containers are just as simple. -You can customize the container with TCSS in the same way as other widgets. - ## Horizontal and Vertical We've seen the `Horizontal` container in action. @@ -69,6 +72,10 @@ And here's the output: Three boxes, vertically stacked. +!!! tip "Styling layout" + + You can set the layout of a compound widget with the [layout](../styles/layout.md) rule. + ### Size behavior Something to keep in mind when using `Horizontal` or `Vertical` is that they will consume the remaining space in the screen. Let's look at an example to illustrate that. @@ -100,7 +107,7 @@ And here's the result: ``` Two horizontal containers divide the remaining screen space in two. -If you were to add another horizontal it would divide the screen space in to thirds--and so on. +If you were to add another horizontal it would divide the screen space in to thirds—and so on. This makes `Horizontal` and `Vertical` excellent for designing the macro layout of your app's interface, but not for making tightly packed rows or columns. For that you need the *group* containers which I'll cover next. @@ -132,7 +139,7 @@ We can see that the widgets are arranged horizontally as before, but they only u Something to watch out for regarding the previous containers we have discussed, is that they don't scroll by default. Let's see what happens if we add more boxes than could fit on the screen. -In the following example, we will add boxes: +In the following example, we will add 10 boxes: ```python hl_lines="28 29" --8<-- "docs/examples/how-to/containers06.py" @@ -161,7 +168,84 @@ Here's the output: We now have a scrollbar we can click and drag to see all the boxes. -!!! tip "Automatic scrollbars" +!!! tip "Automatic scrollbars" + + You can also implement automatic scrollbars with the [overflow](../styles/overflow.md) style. + + +## Center, Right, and Middle + +The [Center][textual.containers.Center], [Right][textual.containers.Right], and [Middle][textual.containers.Middle] containers are handy for setting the alignment of select widgets. + +First lets look at `Center` and `Right` which align their children on the horizontal axis (there is no `Left` container, as this is the default). + +Here's an example: + +```python hl_lines="2 28 30" +--8<-- "docs/examples/how-to/containers08.py" +``` + +1. The default is to align widgets to the left. +2. Align the child to the center. +3. Align the child to the right edge. + +Here's the output: + +```{.textual path="docs/examples/how-to/containers08.py"} +``` + +Note how `Center` and `Right` expand to fill the horizontal dimension, but are only as tall as they need to be. + +!!! tip "Alignment in TCSS" + + You can set alignment in TCSS with the [align](../styles/align.md) rule. + +The [Middle][textual.containers.Middle] container aligns its children to the center of the *vertical* axis. +Let's look at an example. +The following code aligns three boxes on the vertical axis: + +```python hl_lines="2 27" +--8<-- "docs/examples/how-to/containers09.py" +``` + +1. Align children to the center of the vertical axis. + +Here's the output: + +```{.textual path="docs/examples/how-to/containers09.py"} +``` + +Note how the container expands on the vertical axis, but fits on the horizontal axis. + +## Other containers + +This how-to covers the most common widgets, but isn't exhausted. +Be sure to visit the [container reference][textual.containers] for the full list. +There may be new containers added in future versions of Textual. + +## Custom containers + +The builtin [containers][textual.containers] cover a number of common layout patterns, but are unlikely to cover every possible requirement. +Fortunately, creating your own is easy. +Just like the builtin containers, you can create a container by extending Widget and adding little TCSS. + +Here's a template for a custom container: + +```python +class MyContainer(Widget): + """My custom container.""" + DEFAULT_CSS = """ + MyContainer { + # Your rules here + } + """ +``` + +## Summary - You can implement automatic scrollbars with the [overflow](../styles/overflow.md) style. - +- Containers are compound widgets with preset styles for arranging their children. +- [`Horizontal`][textual.containers.Horizontal] and [`Vertical`][textual.containers.Vertical] containers stretch to fill available space. +- [`HorizontalGroup`][textual.containers.HorizontalGroup] and [`VerticalGroup`][textual.containers.VerticalGroup] fit to the height of their contents. +- [`HorizontalScroll`][textual.containers.HorizontalScroll] and [`VerticalScroll`][textual.containers.VerticalScroll] add automatic scrollbars. +- [`Center`][textual.containers.Center], [`Right`][textual.containers.Right], and [`Middle`][textual.containers.Middle] set alignment. +- Custom containers are trivial to create. diff --git a/src/textual/containers.py b/src/textual/containers.py index 3811b6839d..4478901d35 100644 --- a/src/textual/containers.py +++ b/src/textual/containers.py @@ -29,7 +29,7 @@ class Container(Widget): """ -class ScrollableContainer(Widget, can_focus=True, inherit_bindings=False): +class ScrollableContainer(Widget, can_focus=True): """A scrollable container with vertical layout, and auto scrollbars on both axis.""" # We don't typically want to maximize scrollable containers, @@ -118,7 +118,7 @@ def allow_maximize(self) -> bool: return self.can_maximize -class Vertical(Widget, inherit_bindings=False): +class Vertical(Widget): """An expanding container with vertical layout and no scrollbars.""" DEFAULT_CSS = """ @@ -131,7 +131,7 @@ class Vertical(Widget, inherit_bindings=False): """ -class VerticalGroup(Widget, inherit_bindings=False): +class VerticalGroup(Widget): """A non-expanding container with vertical layout and no scrollbars.""" DEFAULT_CSS = """ @@ -156,7 +156,7 @@ class VerticalScroll(ScrollableContainer): """ -class Horizontal(Widget, inherit_bindings=False): +class Horizontal(Widget): """An expanding container with horizontal layout and no scrollbars.""" DEFAULT_CSS = """ @@ -169,7 +169,7 @@ class Horizontal(Widget, inherit_bindings=False): """ -class HorizontalGroup(Widget, inherit_bindings=False): +class HorizontalGroup(Widget): """A non-expanding container with horizontal layout and no scrollbars.""" DEFAULT_CSS = """ @@ -194,7 +194,7 @@ class HorizontalScroll(ScrollableContainer): """ -class Center(Widget, inherit_bindings=False): +class Center(Widget): """A container which aligns children on the X axis.""" DEFAULT_CSS = """ @@ -206,7 +206,7 @@ class Center(Widget, inherit_bindings=False): """ -class Right(Widget, inherit_bindings=False): +class Right(Widget): """A container which aligns children on the X axis.""" DEFAULT_CSS = """ @@ -218,7 +218,7 @@ class Right(Widget, inherit_bindings=False): """ -class Middle(Widget, inherit_bindings=False): +class Middle(Widget): """A container which aligns children on the Y axis.""" DEFAULT_CSS = """ @@ -230,7 +230,7 @@ class Middle(Widget, inherit_bindings=False): """ -class CenterMiddle(Widget, inherit_bindings=False): +class CenterMiddle(Widget): """A container which aligns its children on both axis.""" DEFAULT_CSS = """ @@ -242,7 +242,7 @@ class CenterMiddle(Widget, inherit_bindings=False): """ -class Grid(Widget, inherit_bindings=False): +class Grid(Widget): """A container with grid layout.""" DEFAULT_CSS = """ @@ -254,7 +254,7 @@ class Grid(Widget, inherit_bindings=False): """ -class ItemGrid(Widget, inherit_bindings=False): +class ItemGrid(Widget): """A container with grid layout and automatic columns.""" DEFAULT_CSS = """ From ae1174019c11303e868c30f7a6e2752c6f5c4fe1 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 25 Jun 2025 20:45:38 +0100 Subject: [PATCH 3/3] update nav --- mkdocs-nav.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/mkdocs-nav.yml b/mkdocs-nav.yml index af48d6c6ff..a2ef39e727 100644 --- a/mkdocs-nav.yml +++ b/mkdocs-nav.yml @@ -237,6 +237,7 @@ nav: - "how-to/package-with-hatch.md" - "how-to/render-and-compose.md" - "how-to/style-inline-apps.md" + - "how-to/work-with-containers.md" - "FAQ.md" - "roadmap.md" - "Blog":