Skip to content

Commit aed5879

Browse files
authored
Merge pull request #6210 from Textualize/grid-size
expose grid-size
2 parents 17df56d + 6e728c7 commit aed5879

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1212
- Fixed `TextArea` cursor display on wrapped lines https://github.com/Textualize/textual/pull/6196
1313
- Fixed `remove_children` not refreshing layout https://github.com/Textualize/textual/pull/6206
1414

15+
### Added
16+
17+
- Added `grid_size` property to `GridLayout` https://github.com/Textualize/textual/pull/6210
18+
1519
## [6.5.0] - 2025-10-31
1620

1721
### Added

src/textual/layouts/grid.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ def __init__(self) -> None:
2929
"""Shrink the grid to fit the container if it is larger."""
3030
self.auto_minimum: bool = False
3131
"""If self.shrink is `True`, auto-detect and limit the width."""
32+
self._grid_size: tuple[int, int] | None = None
33+
"""Grid size after last arrange call."""
34+
35+
@property
36+
def grid_size(self) -> tuple[int, int] | None:
37+
"""The grid size after the last arrange call.
38+
39+
Returns:
40+
A tuple of (WIDTH, HEIGHT) or `None` prior to the first `arrange`.
41+
"""
42+
return self._grid_size
3243

3344
def arrange(
3445
self, parent: Widget, children: list[Widget], size: Size, greedy: bool = True
@@ -60,6 +71,7 @@ def arrange(
6071
table_size_columns -= 1
6172

6273
table_size_rows = styles.grid_size_rows
74+
6375
viewport = parent.app.viewport_size
6476
keyline_style, _keyline_color = styles.keyline
6577
offset = (0, 0)
@@ -157,9 +169,9 @@ def repeat_scalars(scalars: Iterable[Scalar], count: int) -> list[Scalar]:
157169
cell_coord = next_coord()
158170

159171
column_scalars = repeat_scalars(column_scalars, table_size_columns)
160-
row_scalars = repeat_scalars(
161-
row_scalars, table_size_rows if table_size_rows else row + 1
162-
)
172+
table_size_rows = table_size_rows if table_size_rows else row + 1
173+
row_scalars = repeat_scalars(row_scalars, table_size_rows)
174+
self._grid_size = (table_size_columns, table_size_rows)
163175

164176
def apply_width_limits(widget: Widget, width: int) -> int:
165177
"""Apply min and max widths to dimension.

tests/layouts/test_grid.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from textual import containers, widgets
2+
from textual.app import App, ComposeResult
3+
from textual.layouts.grid import GridLayout
4+
5+
6+
async def test_grid_size():
7+
"""Test the `grid_size` property on GridLayout."""
8+
9+
class GridApp(App):
10+
CSS = """
11+
Grid {
12+
grid-size: 3;
13+
grid-columns: auto;
14+
height: auto;
15+
Label {
16+
padding: 2 4;
17+
border: blue;
18+
}
19+
}
20+
"""
21+
22+
def compose(self) -> ComposeResult:
23+
with containers.VerticalScroll():
24+
with containers.Grid():
25+
for _ in range(7):
26+
yield widgets.Label("Hello, World!")
27+
28+
app = GridApp()
29+
async with app.run_test() as pilot:
30+
await pilot.pause()
31+
await app.wait_for_refresh()
32+
grid_layout = app.query_one(containers.Grid).layout
33+
assert isinstance(grid_layout, GridLayout)
34+
assert grid_layout.grid_size == (3, 3)

0 commit comments

Comments
 (0)