Skip to content

Commit

Permalink
Fixing additional variables not working
Browse files Browse the repository at this point in the history
  • Loading branch information
darrenburns committed Oct 29, 2024
1 parent c75efbf commit de64fb8
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 5 deletions.
8 changes: 5 additions & 3 deletions src/textual/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,10 @@ def get_css_variables(self) -> dict[str, str]:
# Build the Textual color system from the theme.
# This will contain $secondary, $primary, $background, etc.
variables = theme.to_color_system().generate()
return {**self.get_theme_variable_defaults(), **variables}
# Apply the additional variables from the theme
variables = {**variables, **(theme.variables)}
theme_variables = self.get_theme_variable_defaults()
return {**theme_variables, **variables}

def get_theme(self, theme_name: str) -> Theme | None:
"""Get a theme by name.
Expand Down Expand Up @@ -1234,8 +1237,7 @@ def _watch_theme(self, theme_name: str) -> None:
This method is called when the theme reactive attribute is set.
"""
theme = self.get_theme(theme_name)
assert theme is not None # validated by _validate_theme
theme = self.current_theme
dark = theme.dark
self.ansi_color = theme_name == "textual-ansi"
self.set_class(dark, "-dark-mode", update=False)
Expand Down
1 change: 1 addition & 0 deletions src/textual/css/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ def substitute_references(
"""
variables: dict[str, list[Token]] = css_variables.copy() if css_variables else {}
iter_tokens = iter(tokens)
print(variables)

while True:
token = next(iter_tokens, None)
Expand Down
4 changes: 2 additions & 2 deletions src/textual/theme.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from dataclasses import dataclass
from dataclasses import dataclass, field
from functools import partial
from typing import Callable

Expand Down Expand Up @@ -34,7 +34,7 @@ class Theme:
dark: bool = True
luminosity_spread: float = 0.15
text_alpha: float = 0.95
variables: dict[str, str] | None = None
variables: dict[str, str] = field(default_factory=dict)

def to_color_system(self) -> ColorSystem:
"""
Expand Down
55 changes: 55 additions & 0 deletions tests/snapshot_tests/test_snapshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
TextArea,
)
from textual.widgets.text_area import BUILTIN_LANGUAGES, Selection, TextAreaTheme
from textual.theme import Theme

# These paths should be relative to THIS directory.
WIDGET_EXAMPLES_DIR = Path("../../docs/examples/widgets")
Expand Down Expand Up @@ -2454,3 +2455,57 @@ def on_mount(self) -> None:
self.theme = theme_name

assert snap_compare(ThemeApp())


def test_custom_theme_with_variables(snap_compare):
"""Test creating and using a custom theme with variables that get overridden.
After the overrides from the theme, the background should be blue, the text should be white, the border should be yellow,
the style should be bold italic, and the label should be cyan.
"""

class ThemeApp(App[None]):
CSS = """
Screen {
align: center middle;
}
Label {
background: $custom-background;
color: $custom-text;
border: wide $custom-border;
padding: 1 2;
text-style: $custom-style;
text-align: center;
width: auto;
}
"""

def compose(self) -> ComposeResult:
yield Label("Custom Theme")

def get_theme_variable_defaults(self) -> dict[str, str]:
"""Override theme variables."""
return {
"custom-text": "cyan",
"custom-style": "bold italic",
"custom-border": "red",
"custom-background": "#0000ff 50%",
}

def on_mount(self) -> None:
custom_theme = Theme(
name="my-custom",
primary="magenta",
background="black",
variables={
"custom-background": "#ff0000 20%",
"custom-text": "white",
"custom-border": "yellow",
"custom-style": "bold",
},
)
self.register_theme(custom_theme)
self.theme = "my-custom"

assert snap_compare(ThemeApp())

0 comments on commit de64fb8

Please sign in to comment.