Skip to content

Commit d1e284f

Browse files
authored
Merge pull request #1311 from Textualize/fix-1309
Empty containers with auto dimensions will collapse
2 parents cdf43d7 + f1500f8 commit d1e284f

File tree

7 files changed

+46
-8
lines changed

7 files changed

+46
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1717
### Changed
1818

1919
- Rebuilt `DirectoryTree` with new `Tree` control.
20+
- Empty containers with a dimension set to `"auto"` will now collapse instead of filling up the available space.
2021
- Container widgets now have default height of `1fr`.
2122
- The default `width` of a `Label` is now `auto`.
2223

src/textual/_layout.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def get_content_width(self, widget: Widget, container: Size, viewport: Size) ->
6767
)
6868
width = child_width if width is None else max(width, child_width)
6969
if width is None:
70-
width = container.width
70+
width = 0
7171

7272
return width
7373

@@ -86,7 +86,7 @@ def get_content_height(
8686
int: Content height (in lines).
8787
"""
8888
if not widget.displayed_children:
89-
height = container.height
89+
height = 0
9090
else:
9191
placements, *_ = widget._arrange(Size(width, container.height))
9292
height = max(

src/textual/box_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ def get_box_model(
124124
)
125125
content_height = min(content_height, max_height)
126126

127-
content_height = max(Fraction(1), content_height)
127+
content_height = max(Fraction(0), content_height)
128128
model = BoxModel(
129129
content_width + gutter.width, content_height + gutter.height, margin
130130
)

src/textual/layouts/horizontal.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def get_content_width(self, widget: Widget, container: Size, viewport: Size) ->
7373
int: Width of the content.
7474
"""
7575
if not widget.displayed_children:
76-
width = container.width
76+
width = 0
7777
else:
7878
placements, *_ = widget._arrange(container)
7979
width = max(

src/textual/widgets/_input.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,13 @@ class Input(Widget, can_focus=True):
6161
border: tall $background;
6262
width: 100%;
6363
height: 1;
64+
min-height: 1;
6465
}
6566
Input.-disabled {
6667
opacity: 0.6;
6768
}
6869
Input:focus {
69-
border: tall $accent;
70+
border: tall $accent;
7071
}
7172
Input>.input--cursor {
7273
background: $surface;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import pytest
2+
3+
from textual.layouts.grid import GridLayout
4+
from textual.layouts.horizontal import HorizontalLayout
5+
from textual.layouts.vertical import VerticalLayout
6+
from textual.geometry import Size
7+
from textual.widget import Widget
8+
9+
10+
LAYOUTS = [GridLayout, HorizontalLayout, VerticalLayout]
11+
12+
13+
@pytest.mark.parametrize("layout", LAYOUTS)
14+
def test_empty_widget_height(layout):
15+
"""Test that an empty widget has height equal to 0."""
16+
l = layout()
17+
# Make sure this measurement does not depend on the width.
18+
assert l.get_content_height(Widget(), Size(80, 24), Size(80, 24), 24) == 0
19+
assert l.get_content_height(Widget(), Size(80, 24), Size(80, 24), 20) == 0
20+
assert l.get_content_height(Widget(), Size(80, 24), Size(80, 24), 10) == 0
21+
assert l.get_content_height(Widget(), Size(80, 24), Size(80, 24), 0) == 0
22+
23+
24+
@pytest.mark.parametrize("layout", LAYOUTS)
25+
def test_empty_widget_width(layout):
26+
"""Test that an empty widget has width equal to 0."""
27+
l = layout()
28+
assert l.get_content_width(Widget(), Size(80, 24), Size(80, 24)) == 0

tests/test_box_model.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def get_auto_height(container: Size, parent: Size, width: int) -> int:
100100

101101

102102
def test_height():
103-
"""Test width settings."""
103+
"""Test height settings."""
104104
styles = Styles()
105105
one = Fraction(1)
106106

@@ -123,15 +123,15 @@ def get_auto_height(container: Size, parent: Size, width: int) -> int:
123123
)
124124
assert box_model == BoxModel(Fraction(54), Fraction(16), Spacing(1, 2, 3, 4))
125125

126-
# Set width to 100 vw which should make it the width of the parent
126+
# Set height to 100 vw which should make it the height of the parent
127127
styles.height = "100vh"
128128

129129
box_model = get_box_model(
130130
styles, Size(60, 20), Size(80, 24), one, one, get_auto_width, get_auto_height
131131
)
132132
assert box_model == BoxModel(Fraction(54), Fraction(24), Spacing(1, 2, 3, 4))
133133

134-
# Set the width to 100% should make it fill the container size
134+
# Set the height to 100% should make it fill the container size
135135
styles.height = "100%"
136136

137137
box_model = get_box_model(
@@ -156,6 +156,14 @@ def get_auto_height(container: Size, parent: Size, width: int) -> int:
156156
)
157157
assert box_model == BoxModel(Fraction(54), Fraction(10), Spacing(1, 2, 3, 4))
158158

159+
# Set height to auto and set content height to 0 to check if box collapses.
160+
styles.height = "auto"
161+
162+
box_model = get_box_model(
163+
styles, Size(60, 20), Size(80, 24), one, one, get_auto_width, lambda *_: 0
164+
)
165+
assert box_model == BoxModel(Fraction(54), Fraction(0), Spacing(1, 2, 3, 4))
166+
159167

160168
def test_max():
161169
"""Check that max_width and max_height are respected."""

0 commit comments

Comments
 (0)