Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ 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/).

## Unreleased
## [7.3.0] - 2026-01-15

### Changed
### Fixed

- Fixed triple click on command palette raising an exception https://github.com/Textualize/textual/pull/6329

- Allow `Sparkline` to be of any height, not just 1 https://github.com/Textualize/textual/pull/6171
-
### Added

- Added `DOM.query_one_optional`
- Added `default` parameter to `get_component_rich_style` get_component_rich_style

### Changed

- Added super+c (command on mac) alternative bindings for copy, for terminals that support it (Ghostty does)
- Allow `Sparkline` to be of any height, not just 1 https://github.com/Textualize/textual/pull/6171

## [7.2.0] - 2026-01-11

Expand Down Expand Up @@ -3320,6 +3322,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

[7.3.0]: https://github.com/Textualize/textual/compare/v7.2.0...v7.3.0
[7.2.0]: https://github.com/Textualize/textual/compare/v7.1.0...v7.2.0
[7.1.0]: https://github.com/Textualize/textual/compare/v7.0.3...v7.1.0
[7.0.3]: https://github.com/Textualize/textual/compare/v7.0.2...v7.0.3
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "textual"
version = "7.2.0"
version = "7.3.0"
homepage = "https://github.com/Textualize/textual"
repository = "https://github.com/Textualize/textual"
documentation = "https://textual.textualize.io/"
Expand Down
2 changes: 1 addition & 1 deletion src/textual/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ class CommandPalette(SystemModalScreen[None]):

AUTO_FOCUS = "CommandInput"

COMPONENT_CLASSES: ClassVar[set[str]] = {
COMPONENT_CLASSES: ClassVar[set[str]] = Screen.COMPONENT_CLASSES | {
"command-palette--help-text",
"command-palette--highlight",
}
Expand Down
5 changes: 4 additions & 1 deletion src/textual/dom.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import rich.repr
from rich.highlighter import ReprHighlighter
from rich.style import NULL_STYLE as RICH_NULL_STYLE
from rich.style import Style
from rich.text import Text
from rich.tree import Tree
Expand Down Expand Up @@ -1072,7 +1073,9 @@ def text_style(self) -> Style:
@property
def selection_style(self) -> Style:
"""The style of selected text."""
style = self.screen.get_component_rich_style("screen--selection")
style = self.screen.get_component_rich_style(
"screen--selection", default=RICH_NULL_STYLE
)
return style

@property
Expand Down
5 changes: 4 additions & 1 deletion src/textual/visual.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from rich.measure import Measurement
from rich.protocol import is_renderable, rich_cast
from rich.segment import Segment
from rich.style import NULL_STYLE as RICH_NULL_STYLE
from rich.style import Style as RichStyle
from rich.text import Text

Expand Down Expand Up @@ -219,7 +220,9 @@ def to_strips(
selection = widget.text_selection
if selection is not None:
selection_style: Style | None = Style.from_rich_style(
widget.screen.get_component_rich_style("screen--selection")
widget.screen.get_component_rich_style(
"screen--selection", default=RICH_NULL_STYLE
)
)
else:
selection_style = None
Expand Down
17 changes: 15 additions & 2 deletions src/textual/widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -1140,19 +1140,32 @@ def get_child_by_type(self, expect_type: type[ExpectType]) -> ExpectType:
return child
raise NoMatches(f"No immediate child of type {expect_type}; {self._nodes}")

def get_component_rich_style(self, *names: str, partial: bool = False) -> Style:
def get_component_rich_style(
self, *names: str, partial: bool = False, default: Style | None = None
) -> Style:
"""Get a *Rich* style for a component.

Args:
names: Names of components.
partial: Return a partial style (not combined with parent).
default: A Style to return if any component style doesn't exist.

Raises:
KeyError: If a component style doesn't exist, and no `default` is provided.

Returns:
A Rich style object.
"""

if names not in self._rich_style_cache:
component_styles = self.get_component_styles(*names)
if default is None:
component_styles = self.get_component_styles(*names)
else:
try:
component_styles = self.get_component_styles(*names)
except KeyError:
return default

style = component_styles.rich_style
text_opacity = component_styles.text_opacity
if text_opacity < 1 and style.bgcolor is not None:
Expand Down
Loading