From 2648f82fdf1925ad4195ac218b008469d4d8ab1e Mon Sep 17 00:00:00 2001 From: = <=> Date: Sat, 10 May 2025 23:46:31 -0700 Subject: [PATCH 1/2] Refresh layout of option lists on add. Ensures options added to an empty list after mount are displayed. --- src/textual/widgets/_option_list.py | 1 + .../test_snapshots/test_option_list_build.svg | 124 +++++++++--------- .../snapshot_apps/option_list.py | 13 ++ tests/snapshot_tests/test_snapshots.py | 2 +- 4 files changed, 77 insertions(+), 63 deletions(-) diff --git a/src/textual/widgets/_option_list.py b/src/textual/widgets/_option_list.py index 00909e3d9..3cd4bdd48 100644 --- a/src/textual/widgets/_option_list.py +++ b/src/textual/widgets/_option_list.py @@ -373,6 +373,7 @@ class OptionList(ScrollView, can_focus=True): self._id_to_option[option._id] = option add_option(option) if self.is_mounted: + self.refresh(layout=True) self._update_lines() return self diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_build.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_build.svg index ac2797250..9378efcf5 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_build.svg +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_build.svg @@ -19,138 +19,138 @@ font-weight: 700; } - .terminal-242230253-matrix { + .terminal-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-242230253-title { + .terminal-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-242230253-r1 { fill: #121212 } -.terminal-242230253-r2 { fill: #0178d4 } -.terminal-242230253-r3 { fill: #191919 } -.terminal-242230253-r4 { fill: #c5c8c6 } -.terminal-242230253-r5 { fill: #ddedf9;font-weight: bold } -.terminal-242230253-r6 { fill: #e0e0e0 } -.terminal-242230253-r7 { fill: #424242 } -.terminal-242230253-r8 { fill: #3b3b3b } -.terminal-242230253-r9 { fill: #f4005f } + .terminal-r1 { fill: #121212 } +.terminal-r2 { fill: #0178d4 } +.terminal-r3 { fill: #191919 } +.terminal-r4 { fill: #c5c8c6 } +.terminal-r5 { fill: #ddedf9;font-weight: bold } +.terminal-r6 { fill: #e0e0e0 } +.terminal-r7 { fill: #424242 } +.terminal-r8 { fill: #3b3b3b } +.terminal-r9 { fill: #f4005f } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - OptionListApp + OptionListApp - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -OneOneOne -TwoTwoTwo -──────────────────────────────────────────────────────────────────── -ThreeThreeThree -▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +OneOneOneOne +TwoTwoTwoTwo +──────────────────────────────────────────────────────────────── +ThreeThreeThreeThree +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/snapshot_apps/option_list.py b/tests/snapshot_tests/snapshot_apps/option_list.py index 36e4691dd..580a3c8cf 100644 --- a/tests/snapshot_tests/snapshot_apps/option_list.py +++ b/tests/snapshot_tests/snapshot_apps/option_list.py @@ -10,6 +10,8 @@ from textual.widgets.option_list import Option class OptionListApp(App[None]): + BINDINGS = [("a", "add", "add")] + def compose( self ) -> ComposeResult: with Horizontal(): yield OptionList( @@ -20,6 +22,7 @@ class OptionListApp(App[None]): ) yield OptionList(id="later-individual") yield OptionList(id="later-at-once") + yield OptionList(id="after-mount") def on_mount(self) -> None: options: list[None | str | Text | Option] = [ @@ -41,5 +44,15 @@ class OptionListApp(App[None]): ]) option_list.highlighted = 0 + def action_add(self): + option_list = self.query_one("#after-mount", OptionList) + option_list.add_options([ + "One", + Option("Two"), + None, + Text.from_markup("[red]Three[/]"), + ]) + option_list.highlighted = 0 + if __name__ == "__main__": OptionListApp().run() diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index 07f046d1e..7f95c17f8 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -505,7 +505,7 @@ def test_option_list_tables(snap_compare): def test_option_list_build(snap_compare): - assert snap_compare(SNAPSHOT_APPS_DIR / "option_list.py") + assert snap_compare(SNAPSHOT_APPS_DIR / "option_list.py", press=["a"]) def test_option_list_replace_prompt_from_single_line_to_single_line(snap_compare): From 1cd868f791aaee2768c2d5122d205c370985ba56 Mon Sep 17 00:00:00 2001 From: = <=> Date: Sun, 11 May 2025 08:34:50 -0700 Subject: [PATCH 2/2] Skip relayout if auto_dimensions are off. --- src/textual/widgets/_option_list.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/widgets/_option_list.py b/src/textual/widgets/_option_list.py index 3cd4bdd48..a63dca972 100644 --- a/src/textual/widgets/_option_list.py +++ b/src/textual/widgets/_option_list.py @@ -373,7 +373,7 @@ class OptionList(ScrollView, can_focus=True): self._id_to_option[option._id] = option add_option(option) if self.is_mounted: - self.refresh(layout=True) + self.refresh(layout=self.styles.auto_dimensions) self._update_lines() return self