Skip to content

Commit 6485ab6

Browse files
authored
Merge pull request #39 from Textualize/colors-and-borders-demo-updates
Fixes and updates in demo apps for new themes
2 parents e654d8c + a50de8e commit 6485ab6

File tree

6 files changed

+751
-562
lines changed

6 files changed

+751
-562
lines changed

poetry.lock

Lines changed: 659 additions & 504 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "textual-dev"
3-
version = "1.6.0"
3+
version = "1.7.0"
44
homepage = "https://github.com/Textualize/textual-dev"
55
description = "Development tools for working with Textual"
66
authors = [
@@ -26,8 +26,8 @@ classifiers = [
2626
include = ["src/textual_dev/py.typed", { path = "tests", format = "sdist" }]
2727

2828
[tool.poetry.dependencies]
29-
python = "^3.8"
30-
textual = ">=0.36.0"
29+
python = "^3.8.1"
30+
textual = ">=0.86.2"
3131
textual_serve = ">=1.0.3"
3232
aiohttp = ">=3.8.1"
3333
click = ">=8.1.2"
@@ -56,9 +56,6 @@ textual = "textual_dev.cli:run"
5656
asyncio_mode = "auto"
5757
testpaths = ["tests"]
5858
addopts = "--strict-markers"
59-
markers = [
60-
"integration_test: marks tests as slow integration tests (deselect with '-m \"not integration_test\"')",
61-
]
6259

6360
[tool.mypy]
6461
implicit_reexport = false

src/textual_dev/previews/borders.py

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
from typing import cast
22

33
from textual.app import App, ComposeResult
4-
from textual.containers import Vertical
54
from textual.css.constants import VALID_BORDER
65
from textual.css.types import EdgeType
7-
from textual.widgets import Button, Label
6+
from textual.widgets import Label, OptionList
7+
from textual.widgets.option_list import Option
88

99
TEXT = """I must not fear.
1010
Fear is the mind-killer.
@@ -15,25 +15,6 @@
1515
Where the fear has gone there will be nothing. Only I will remain."""
1616

1717

18-
class BorderButtons(Vertical):
19-
DEFAULT_CSS = """
20-
BorderButtons {
21-
dock: left;
22-
width: 24;
23-
overflow-y: scroll;
24-
}
25-
26-
BorderButtons > Button {
27-
width: 100%;
28-
}
29-
"""
30-
31-
def compose(self) -> ComposeResult:
32-
for border in sorted(VALID_BORDER):
33-
if border:
34-
yield Button(border, id=border)
35-
36-
3718
class BorderApp(App[None]):
3819
"""Demonstrates the border styles."""
3920

@@ -42,10 +23,15 @@ class BorderApp(App[None]):
4223
align: center middle;
4324
overflow: auto;
4425
}
26+
OptionList#sidebar {
27+
width: 20;
28+
dock: left;
29+
height: 1fr;
30+
}
4531
#text {
4632
margin: 2 4;
4733
padding: 2 4;
48-
border: solid $secondary;
34+
border: solid $border;
4935
height: auto;
5036
background: $panel;
5137
color: $text;
@@ -54,17 +40,38 @@ class BorderApp(App[None]):
5440
"""
5541

5642
def compose(self) -> ComposeResult:
57-
yield BorderButtons()
43+
yield OptionList(
44+
*[Option(border, id=border) for border in sorted(VALID_BORDER) if border],
45+
id="sidebar",
46+
)
47+
5848
self.text = Label(TEXT, id="text")
5949
self.text.shrink = True
6050
self.text.border_title = "solid"
51+
self.text.border_subtitle = "border subtitle"
6152
yield self.text
6253

63-
def on_button_pressed(self, event: Button.Pressed) -> None:
64-
self.text.border_title = event.button.id
54+
def on_mount(self) -> None:
55+
self.theme_changed_signal.subscribe(self, self.update_border)
56+
57+
@property
58+
def sidebar(self) -> OptionList:
59+
return self.query_one("#sidebar", OptionList)
60+
61+
def on_option_list_option_highlighted(
62+
self, event: OptionList.OptionHighlighted
63+
) -> None:
64+
border_name = event.option.id
65+
self.text.border_title = border_name
66+
self.update_border(self.app.current_theme)
67+
68+
def update_border(self, _) -> None:
6569
self.text.styles.border = (
66-
cast(EdgeType, event.button.id),
67-
self.stylesheet._variables["secondary"],
70+
cast(
71+
EdgeType,
72+
self.sidebar.get_option_at_index(self.sidebar.highlighted or 0).id,
73+
),
74+
self.theme_variables["border"],
6875
)
6976

7077

src/textual_dev/previews/colors.py

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
from textual.containers import Horizontal, Vertical, VerticalScroll
55
from textual.design import ColorSystem
66
from textual.widget import Widget
7-
from textual.widgets import Button, Footer, Label, Static, TabbedContent
7+
from textual.widgets import Footer, Label, OptionList, Static, TabbedContent
8+
from textual.widgets.option_list import Option
89

910
try:
1011
from textual.lazy import Lazy
@@ -14,12 +15,6 @@ def Lazy(widget: Widget) -> Widget: # type: ignore
1415
return widget
1516

1617

17-
class ThemeColorButtons(VerticalScroll):
18-
def compose(self) -> ComposeResult:
19-
for color_name in ColorSystem.COLOR_NAMES:
20-
yield Button(color_name, id=color_name)
21-
22-
2318
class ColorBar(Static):
2419
pass
2520

@@ -56,7 +51,7 @@ def compose(self) -> ComposeResult:
5651
yield ColorBar(f"{color.rgb}", classes="text text-left")
5752

5853

59-
class ThemeColorsView(ColorsView):
54+
class ThemeColorsView(ColorsView, can_focus=False):
6055
def compose(self) -> ComposeResult:
6156
LEVELS = [
6257
"darken-3",
@@ -80,22 +75,59 @@ def compose(self) -> ComposeResult:
8075

8176

8277
class ColorsApp(App[None]):
83-
CSS_PATH = "colors.css"
78+
CSS_PATH = "colors.tcss"
8479

85-
BINDINGS = [("d", "toggle_dark", "Toggle dark mode")]
80+
BINDINGS = [
81+
("[", "previous_theme", "Previous theme"),
82+
("]", "next_theme", "Next theme"),
83+
]
84+
85+
def __init__(self) -> None:
86+
super().__init__()
87+
self.theme_names = [
88+
theme for theme in self.available_themes if theme != "textual-ansi"
89+
]
8690

8791
def compose(self) -> ComposeResult:
8892
yield Footer()
8993
with ColorTabs("Theme Colors", "Named Colors"):
90-
yield Content(ThemeColorButtons(), ThemeColorsView(), id="theme")
94+
with Content(id="theme"):
95+
sidebar = OptionList(
96+
*[
97+
Option(color_name, id=color_name)
98+
for color_name in ColorSystem.COLOR_NAMES
99+
],
100+
id="sidebar",
101+
)
102+
sidebar.border_title = "Theme Colors"
103+
yield sidebar
104+
yield ThemeColorsView()
91105
yield Lazy(NamedColorsView())
92106

93-
def on_button_pressed(self, event: Button.Pressed) -> None:
107+
def on_option_list_option_highlighted(
108+
self, event: OptionList.OptionHighlighted
109+
) -> None:
94110
self.query(ColorGroup).remove_class("-active")
95-
group = self.query_one(f"#group-{event.button.id}", ColorGroup)
111+
group = self.query_one(f"#group-{event.option.id}", ColorGroup)
96112
group.add_class("-active")
97113
group.scroll_visible(top=True, speed=150)
98114

115+
def action_next_theme(self) -> None:
116+
themes = self.theme_names
117+
index = themes.index(self.current_theme.name)
118+
self.theme = themes[(index + 1) % len(themes)]
119+
self.notify_new_theme(self.current_theme.name)
120+
121+
def action_previous_theme(self) -> None:
122+
themes = self.theme_names
123+
index = themes.index(self.current_theme.name)
124+
self.theme = themes[(index - 1) % len(themes)]
125+
self.notify_new_theme(self.current_theme.name)
126+
127+
def notify_new_theme(self, theme_name: str) -> None:
128+
self.clear_notifications()
129+
self.notify(f"Theme is {theme_name}")
130+
99131

100132
if __name__ == "__main__":
101133
ColorsApp().run()

src/textual_dev/previews/colors.css renamed to src/textual_dev/previews/colors.tcss

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@ Label {
22
width: 100%;
33
}
44

5-
ThemeColorButtons {
6-
dock: left;
7-
overflow-y: auto;
8-
width: 30;
5+
6+
Tabs {
7+
margin: 1 2;
98
}
109

11-
ThemeColorButtons > Button {
12-
width: 100%;
10+
#sidebar {
11+
dock: left;
12+
width: auto;
13+
padding: 1 2;
14+
border: panel $border;
1315
}
1416

1517
ColorsView {
@@ -49,12 +51,12 @@ ColorGroup {
4951
height: auto;
5052
padding: 1 4 2 4;
5153
background: $surface;
52-
border: wide $surface;
54+
border: wide $border-blurred;
5355
}
5456

5557

5658
ColorGroup.-active {
57-
border: wide $secondary;
59+
border: wide $border;
5860
}
5961

6062
NamedColorsView {

src/textual_dev/previews/easing.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ def on_load(self) -> None:
6262
self.bind(
6363
"ctrl+p", "focus('duration-input')", description="Focus: Duration Input"
6464
)
65-
self.bind("ctrl+b", "toggle_dark", description="Toggle Dark")
6665

6766
def compose(self) -> ComposeResult:
6867
self.animated_bar = Bar()
@@ -112,9 +111,6 @@ def on_input_changed(self, event: Input.Changed) -> None:
112111
if new_duration is not None:
113112
self.duration = new_duration
114113

115-
def action_toggle_dark(self) -> None:
116-
self.dark = not self.dark
117-
118114

119115
def _try_float(string: str) -> float | None:
120116
try:

0 commit comments

Comments
 (0)