Skip to content

Commit 8abd17e

Browse files
committed
Add method to register theme as a textual theme, and update picker example.
1 parent 6d72af4 commit 8abd17e

2 files changed

Lines changed: 46 additions & 22 deletions

File tree

examples/textual_demo.py

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,12 @@ def load_current_theme(self) -> None:
103103
_, theme = self.themes[self.current_index]
104104
self.current_theme_data = theme
105105

106+
# Register and apply the TCA theme as a Textual theme so that all
107+
# CSS design tokens ($background, $surface, $border, etc.) update.
108+
textual_theme = theme.to_textual_theme()
109+
self.register_theme(textual_theme)
110+
self.theme = textual_theme.name
111+
106112
# Force refresh content
107113
content = self.query_one("#content")
108114
content.remove_children()
@@ -148,28 +154,6 @@ def build_content(self) -> list[Vertical]:
148154
# Left column widgets
149155
left_widgets.append(Label(f"Theme: {theme.meta.name}", classes="section-title"))
150156

151-
# Palette ramps
152-
if theme.palette and isinstance(theme.palette, dict):
153-
left_widgets.append(Label("Palette:", classes="section-title"))
154-
155-
# Show neutral ramp first
156-
colors = [c for c in theme.palette["neutral"] if c]
157-
if colors:
158-
left_widgets.append(
159-
ColorRampDisplay("neutral", colors, classes="color-line")
160-
)
161-
162-
# Show other ramps
163-
for name in sorted(theme.palette.keys()):
164-
if name != "neutral":
165-
ramp = theme.palette[name]
166-
if isinstance(ramp, ColorRamp):
167-
colors = [c for c in ramp if c]
168-
if colors:
169-
left_widgets.append(
170-
ColorRampDisplay(name, colors, classes="color-line")
171-
)
172-
173157
# ANSI colors
174158
left_widgets.append(Label("ANSI Colors:", classes="section-title"))
175159
ansi_colors = [
@@ -196,6 +180,28 @@ def build_content(self) -> list[Vertical]:
196180
label.styles.color = color
197181
left_widgets.append(label)
198182

183+
# Palette ramps
184+
if theme.palette and isinstance(theme.palette, dict):
185+
left_widgets.append(Label("Palette:", classes="section-title"))
186+
187+
# Show neutral ramp first
188+
colors = [c for c in theme.palette["neutral"] if c]
189+
if colors:
190+
left_widgets.append(
191+
ColorRampDisplay("neutral", colors, classes="color-line")
192+
)
193+
194+
# Show other ramps
195+
for name in sorted(theme.palette.keys()):
196+
if name != "neutral":
197+
ramp = theme.palette[name]
198+
if isinstance(ramp, ColorRamp):
199+
colors = [c for c in ramp if c]
200+
if colors:
201+
left_widgets.append(
202+
ColorRampDisplay(name, colors, classes="color-line")
203+
)
204+
199205
# Right column widgets
200206

201207
# Semantic colors

src/tca/textual.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,24 @@ def color_system(self) -> ColorSystem:
5353
dark=self.meta.is_dark,
5454
)
5555

56+
def to_textual_theme(self) -> Any:
57+
"""Build a textual.theme.Theme that can be registered with App.register_theme()."""
58+
from textual.theme import Theme as _TTextualTheme
59+
return _TTextualTheme(
60+
name=self.meta.slug,
61+
primary=self.semantic.info,
62+
secondary=self.ui.fg_secondary,
63+
warning=self.semantic.warning,
64+
error=self.semantic.error,
65+
success=self.semantic.success,
66+
accent=self.semantic.highlight,
67+
foreground=self.ui.fg_primary,
68+
background=self.ui.bg_primary,
69+
surface=self.ui.bg_secondary,
70+
panel=self.ui.bg_secondary,
71+
dark=self.meta.is_dark,
72+
)
73+
5674
def ansi_color(self, name: str) -> Color:
5775
"""Get ANSI color by name as Textual Color."""
5876
return _color(getattr(self.ansi, name))

0 commit comments

Comments
 (0)