Skip to content

Commit c7370f3

Browse files
authored
Merge pull request #4285 from davep/tabs-event-isolation
Ensure TabbedContent only handles tab messages intended for it
2 parents 144deb8 + ea1687b commit c7370f3

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3030
- Markdown component classes weren't refreshed when watching for CSS https://github.com/Textualize/textual/issues/3464
3131
- Rename `Switch.action_toggle` to `action_toggle_switch` to fix clash with `DOMNode.action_toggle` https://github.com/Textualize/textual/issues/4262
3232
- Fixed `OptionList.OptionHighlighted` leaking out of `Select` https://github.com/Textualize/textual/issues/4224
33+
- Fixed `Tab` enable/disable messages leaking into `TabbedContent` https://github.com/Textualize/textual/issues/4233
3334
- Fixed a style leak from `TabbedContent` https://github.com/Textualize/textual/issues/4232
3435

3536
### Changed

src/textual/widgets/_tabbed_content.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,8 @@ def get_pane(self, pane_id: str | ContentTab) -> TabPane:
610610

611611
def _on_tabs_tab_disabled(self, event: Tabs.TabDisabled) -> None:
612612
"""Disable the corresponding tab pane."""
613+
if event.tabs.parent is not self:
614+
return
613615
event.stop()
614616
tab_id = event.tab.id or ""
615617
try:
@@ -631,6 +633,8 @@ def _on_tab_pane_disabled(self, event: TabPane.Disabled) -> None:
631633

632634
def _on_tabs_tab_enabled(self, event: Tabs.TabEnabled) -> None:
633635
"""Enable the corresponding tab pane."""
636+
if event.tabs.parent is not self:
637+
return
634638
event.stop()
635639
tab_id = event.tab.id or ""
636640
try:

tests/test_tabbed_content.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -867,3 +867,26 @@ def compose(self) -> ComposeResult:
867867

868868
assert inner_tabs.active_tab is None
869869
assert tabbed_content.active == "outer1"
870+
871+
872+
async def test_disabling_tab_within_tabbed_content_stays_isolated():
873+
"""Disabling a tab within a tab pane should not affect the TabbedContent."""
874+
875+
class TabsNestedInTabbedContent(App):
876+
def compose(self) -> ComposeResult:
877+
with TabbedContent():
878+
with TabPane("TabbedContent", id="duplicate"):
879+
yield Tabs(
880+
Tab("Tab1", id="duplicate"),
881+
Tab("Tab2", id="stay-enabled"),
882+
id="test-tabs",
883+
)
884+
885+
app = TabsNestedInTabbedContent()
886+
async with app.run_test() as pilot:
887+
assert app.query_one("Tab#duplicate").disabled is False
888+
assert app.query_one("TabPane#duplicate").disabled is False
889+
app.query_one("#test-tabs", Tabs).disable("duplicate")
890+
await pilot.pause()
891+
assert app.query_one("Tab#duplicate").disabled is True
892+
assert app.query_one("TabPane#duplicate").disabled is False

0 commit comments

Comments
 (0)