diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d889e62ed..205fecfde7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ 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/). +## [0.63.5] + +### Fixed + +- Fixed data table disappearing from tabs + +### Added + +- Added `Styles.is_auto_width` and `Style.is_auto_height` + ## [0.63.4] ### Added @@ -2023,6 +2033,7 @@ https://textual.textualize.io/blog/2022/11/08/version-040/#version-040 - New handler system for messages that doesn't require inheritance - Improved traceback handling +[0.63.5]: https://github.com/Textualize/textual/compare/v0.63.4...v0.63.5 [0.63.4]: https://github.com/Textualize/textual/compare/v0.63.3...v0.63.4 [0.63.3]: https://github.com/Textualize/textual/compare/v0.63.2...v0.63.3 [0.63.2]: https://github.com/Textualize/textual/compare/v0.63.1...v0.63.2 diff --git a/pyproject.toml b/pyproject.toml index 9cd24b9b78..3470afd8d7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "textual" -version = "0.63.4" +version = "0.63.5" homepage = "https://github.com/Textualize/textual" repository = "https://github.com/Textualize/textual" documentation = "https://textual.textualize.io/" diff --git a/src/textual/css/styles.py b/src/textual/css/styles.py index 9112b6c618..733c84ba23 100644 --- a/src/textual/css/styles.py +++ b/src/textual/css/styles.py @@ -441,6 +441,18 @@ def is_relative_height(self) -> bool: height = self.height return height is not None and height.unit in (Unit.FRACTION, Unit.PERCENT) + @property + def is_auto_width(self) -> bool: + """Does the node have automatic width?""" + width = self.width + return width is not None and width.unit == Unit.AUTO + + @property + def is_auto_height(self) -> bool: + """Does the node have automatic height?""" + height = self.height + return height is not None and height.unit == Unit.AUTO + @abstractmethod def has_rule(self, rule: str) -> bool: """Check if a rule is set on this Styles object. diff --git a/src/textual/screen.py b/src/textual/screen.py index 78a4c7f9c0..9b724cd386 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -136,7 +136,7 @@ class Screen(Generic[ScreenResultType], Widget): Screen { layout: vertical; overflow-y: auto; - background: $surface; + background: $surface; &:inline { height: auto; diff --git a/src/textual/widget.py b/src/textual/widget.py index 696468b30e..49f6afa534 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -1211,13 +1211,19 @@ def _get_box_model( min_width -= gutter.width content_width = max(content_width, min_width, Fraction(0)) - if styles.max_width is not None: + if styles.max_width is not None and not ( + container.width == 0 + and not styles.max_width.is_cells + and self._parent is not None + and self._parent.styles.is_auto_width + ): # Restrict to maximum width, if set max_width = styles.max_width.resolve( container - margin.totals, viewport, width_fraction ) if is_border_box: max_width -= gutter.width + content_width = min(content_width, max_width) content_width = max(Fraction(0), content_width) @@ -1255,7 +1261,12 @@ def _get_box_model( min_height -= gutter.height content_height = max(content_height, min_height, Fraction(0)) - if styles.max_height is not None: + if styles.max_height is not None and not ( + container.height == 0 + and not styles.max_height.is_cells + and self._parent is not None + and self._parent.styles.is_auto_height + ): # Restrict maximum height, if set max_height = styles.max_height.resolve( container - margin.totals, viewport, height_fraction diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index a84ea380f8..138d1b7d47 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -15474,6 +15474,167 @@ ''' # --- +# name: test_data_table_in_tabs + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dashboard + + + + + + + + + + + Workflows + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +  Id   Description  Status  Result Id  +  1    2            3       4          +  a    b            c       d          +  fee  fy           fo      fum        + + + + + + + + + + + + + + + + + + + + + ''' +# --- # name: test_datatable_add_column ''' diff --git a/tests/snapshot_tests/snapshot_apps/data_table_tabs.py b/tests/snapshot_tests/snapshot_apps/data_table_tabs.py new file mode 100644 index 0000000000..2f5fc15467 --- /dev/null +++ b/tests/snapshot_tests/snapshot_apps/data_table_tabs.py @@ -0,0 +1,35 @@ +from textual.app import App, ComposeResult +from textual.binding import Binding +from textual.widgets import TabbedContent, DataTable + + +class Dashboard(App): + """Dashboard""" + + BINDINGS = [ + ("d", "toggle_dark", "Toggle dark mode"), + Binding("ctrl+q", "app.quit", "Quit", show=True), + ] + TITLE = "Dashboard" + CSS = """ + + DataTable { + height: auto; + } + """ + + def compose(self) -> ComposeResult: + """Create child widgets for the app.""" + with TabbedContent("Workflows"): + yield DataTable(id="table") + + def on_mount(self) -> None: + table = self.query_one(DataTable) + table.add_columns("Id", "Description", "Status", "Result Id") + for row in [(1, 2, 3, 4), ("a", "b", "c", "d"), ("fee", "fy", "fo", "fum")]: + table.add_row(key=row[0], *row) + + +if __name__ == "__main__": + app = Dashboard() + app.run() diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index da35a43893..51cd71fb41 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -1269,3 +1269,7 @@ def test_grid_gutter(snap_compare): def test_multi_keys(snap_compare): # https://github.com/Textualize/textual/issues/4542 assert snap_compare(SNAPSHOT_APPS_DIR / "multi_keys.py") + + +def test_data_table_in_tabs(snap_compare): + assert snap_compare(SNAPSHOT_APPS_DIR / "data_table_tabs.py")