Default css

This commit is contained in:
Will McGugan
2022-09-02 09:56:04 +01:00
parent b6728a694f
commit e555b8512f
33 changed files with 64 additions and 50 deletions

View File

@@ -7,7 +7,7 @@ from textual.widget import Widget
class Clock(Widget):
"""A clock app."""
CSS = """
DEFAULT_CSS = """
Clock {
content-align: center middle;
}

View File

@@ -4,7 +4,7 @@ from textual.widgets import Button
class ButtonApp(App):
CSS = """
DEFAULT_CSS = """
Button {
width: 100%;
}

View File

@@ -8,7 +8,7 @@ from textual.widgets import Placeholder
class VerticalContainer(Widget):
CSS = """
DEFAULT_CSS = """
VerticalContainer {
layout: vertical;
overflow: hidden auto;
@@ -24,7 +24,7 @@ class VerticalContainer(Widget):
class Introduction(Widget):
CSS = """
DEFAULT_CSS = """
Introduction {
background: indigo;
color: white;

View File

@@ -23,7 +23,7 @@ class ColorDisplay(Widget, can_focus=True):
class ColorNames(App):
CSS = """
DEFAULT_CSS = """
ColorDisplay {
height: 1;
}

View File

@@ -5,7 +5,7 @@ from textual.widget import Widget
class FiftyApp(App):
CSS = """
DEFAULT_CSS = """
Screen {
layout: vertical;
}
@@ -24,6 +24,7 @@ class FiftyApp(App):
yield layout.Horizontal(Widget(), Widget())
yield layout.Horizontal(Widget(), Widget())
app = FiftyApp()
if __name__ == "__main__":
app.run()

View File

@@ -9,7 +9,7 @@ placeholders_count = 12
class VerticalContainer(Widget):
CSS = """
DEFAULT_CSS = """
VerticalContainer {
layout: vertical;
overflow: hidden auto;
@@ -26,7 +26,7 @@ class VerticalContainer(Widget):
class Introduction(Widget):
CSS = """
DEFAULT_CSS = """
Introduction {
background: indigo;
color: white;

View File

@@ -10,7 +10,7 @@ initial_placeholders_count = 4
class VerticalContainer(Widget):
CSS = """
DEFAULT_CSS = """
VerticalContainer {
layout: vertical;
overflow: hidden auto;
@@ -30,7 +30,7 @@ class VerticalContainer(Widget):
class Introduction(Widget):
CSS = """
DEFAULT_CSS = """
Introduction {
background: indigo;
color: white;

View File

@@ -11,7 +11,7 @@ class Thing(Static):
class AddRemoveApp(App):
CSS = """
DEFAULT_CSS = """
#buttons {
dock: top;
height: auto;

View File

@@ -3,7 +3,7 @@ from textual.widgets import Static
class CenterApp(App):
CSS = """
DEFAULT_CSS = """
CenterApp Screen {
layout: center;

View File

@@ -4,7 +4,7 @@ from textual.widgets import Static
class CenterApp(App):
CSS = """
DEFAULT_CSS = """
#sidebar {
dock: left;

View File

@@ -10,7 +10,7 @@ from textual.widget import Widget
class Box(Widget, can_focus=True):
CSS = "#box {background: blue;}"
DEFAULT_CSS = "#box {background: blue;}"
def render(self) -> RenderableType:
return Panel("Box")

View File

@@ -21,7 +21,7 @@ class NewScreen(Screen):
class ScreenApp(App):
CSS = """
DEFAULT_CSS = """
ScreenApp Screen {
background: #111144;
color: white;

View File

@@ -5,7 +5,7 @@ from textual.widgets import DirectoryTree
class TreeApp(App):
CSS = """
DEFAULT_CSS = """
Screen {
overflow: auto;

View File

@@ -142,7 +142,11 @@ class App(Generic[ReturnType], DOMNode):
"""
CSS = """
# Inline CSS for quick scripts (generally css_path should be preferred.)
CSS = ""
# Default (lowest priority) CSS
DEFAULT_CSS = """
App {
background: $background;
color: $text-background;
@@ -683,7 +687,6 @@ class App(Generic[ReturnType], DOMNode):
async def _on_css_change(self) -> None:
"""Called when the CSS changes (if watch_css is True)."""
if self.css_path is not None:
try:
time = perf_counter()
stylesheet = self.stylesheet.copy()
@@ -1060,6 +1063,16 @@ class App(Generic[ReturnType], DOMNode):
self.stylesheet.add_source(
css, path=path, is_default_css=True, tie_breaker=tie_breaker
)
if self.CSS:
try:
app_css_path = (
f"{inspect.getfile(self.__class__)}:{self.__class__.__name__}"
)
except TypeError:
app_css_path = f"{self.__class__.__name__}"
self.stylesheet.add_source(
self.CSS, path=app_css_path, is_default_css=False
)
except Exception as error:
self.on_exception(error)
self._print_error_renderables()

View File

@@ -571,7 +571,7 @@ class Styles(StylesBase):
Args:
specificity (Specificity3): A node specificity.
is_default_rules (bool): True if the rules we're extracting are
default (i.e. in Widget.CSS) rules. False if they're from user defined CSS.
default (i.e. in Widget.DEFAULT_CSS) rules. False if they're from user defined CSS.
Returns:
list[tuple[str, Specificity5, Any]]]: A list containing a tuple of <RULE NAME>, <SPECIFICITY> <RULE VALUE>.

View File

@@ -555,7 +555,7 @@ if __name__ == "__main__":
print(app.tree)
print()
CSS = """
DEFAULT_CSS = """
App > View {
layout: dock;
docks: sidebar=left | widgets=top;

View File

@@ -14,7 +14,7 @@ Where the fear has gone there will be nothing. Only I will remain."""
class BorderButtons(layout.Vertical):
CSS = """
DEFAULT_CSS = """
BorderButtons {
dock: left;
width: 24;
@@ -34,7 +34,7 @@ class BorderButtons(layout.Vertical):
class BorderApp(App):
"""Demonstrates the border styles."""
CSS = """
DEFAULT_CSS = """
Static {
margin: 2 4;
padding: 2 4;

View File

@@ -54,8 +54,8 @@ class NoParent(Exception):
class DOMNode(MessagePump):
"""The base class for object that can be in the Textual DOM (App and Widget)"""
# Custom CSS
CSS: ClassVar[str] = ""
# CSS defaults
DEFAULT_CSS: ClassVar[str] = ""
# Default classes argument if not supplied
DEFAULT_CLASSES: str = ""
@@ -198,7 +198,7 @@ class DOMNode(MessagePump):
return f"{base.__name__}"
for tie_breaker, base in enumerate(self._node_bases):
css = base.CSS.strip()
css = base.DEFAULT_CSS.strip()
if css:
css_stack.append((get_path(base), css, -tie_breaker))

View File

@@ -4,7 +4,7 @@ from .widget import Widget
class Container(Widget):
"""Simple container widget, with vertical layout."""
CSS = """
DEFAULT_CSS = """
Container {
layout: vertical;
overflow: auto;
@@ -16,13 +16,13 @@ class Vertical(Container):
"""A container widget to align children vertically."""
# Blank CSS is important, otherwise you get a clone of Container
CSS = ""
DEFAULT_CSS = ""
class Horizontal(Container):
"""A container widget to align children horizontally."""
CSS = """
DEFAULT_CSS = """
Horizontal {
layout: horizontal;
}
@@ -32,7 +32,7 @@ class Horizontal(Container):
class Center(Container):
"""A container widget to align children in the center."""
CSS = """
DEFAULT_CSS = """
Center {
layout: center;
}

View File

@@ -29,7 +29,7 @@ UPDATE_PERIOD: Final = 1 / 60
class Screen(Widget):
"""A widget for the root of the app."""
CSS = """
DEFAULT_CSS = """
Screen {
layout: vertical;
overflow-y: auto;

View File

@@ -16,7 +16,7 @@ class ScrollView(Widget):
"""
CSS = """
DEFAULT_CSS = """
ScrollView {
overflow-y: auto;

View File

@@ -72,7 +72,7 @@ class Widget(DOMNode):
"""
CSS = """
DEFAULT_CSS = """
Widget{
scrollbar-background: $panel-darken-1;
scrollbar-background-hover: $panel-darken-2;

View File

@@ -29,7 +29,7 @@ class InvalidButtonVariant(Exception):
class Button(Widget, can_focus=True):
"""A simple clickable button."""
CSS = """
DEFAULT_CSS = """
Button {
width: auto;
min-width: 10;

View File

@@ -106,7 +106,7 @@ class Coord(NamedTuple):
class DataTable(ScrollView, Generic[CellType], can_focus=True):
CSS = """
DEFAULT_CSS = """
DataTable {
background: $surface;
color: $text-surface;

View File

@@ -13,7 +13,7 @@ from ..widget import Widget
@rich.repr.auto
class Footer(Widget):
CSS = """
DEFAULT_CSS = """
Footer {
background: $accent;
color: $text-accent;

View File

@@ -11,7 +11,7 @@ from ..reactive import Reactive, watch
class HeaderIcon(Widget):
"""Display an 'icon' on the left of the header."""
CSS = """
DEFAULT_CSS = """
HeaderIcon {
dock: left;
padding: 0 1;
@@ -28,7 +28,7 @@ class HeaderIcon(Widget):
class HeaderClock(Widget):
"""Display a clock on the right of the header."""
CSS = """
DEFAULT_CSS = """
HeaderClock {
dock: right;
width: auto;
@@ -50,7 +50,7 @@ class HeaderClock(Widget):
class HeaderTitle(Widget):
"""Display the title / subtitle in the header."""
CSS = """
DEFAULT_CSS = """
HeaderTitle {
content-align: center middle;
width: 100%;
@@ -70,7 +70,7 @@ class HeaderTitle(Widget):
class Header(Widget):
"""A header widget with icon and clock."""
CSS = """
DEFAULT_CSS = """
Header {
dock: top;
width: 100%;

View File

@@ -7,7 +7,7 @@ from ..widget import Widget
class Pretty(Widget):
CSS = """
DEFAULT_CSS = """
Static {
height: auto;
}

View File

@@ -25,7 +25,7 @@ def _check_renderable(renderable: object):
class Static(Widget):
CSS = """
DEFAULT_CSS = """
Static {
height: auto;
}

View File

@@ -169,7 +169,7 @@ class TreeClick(Generic[NodeDataType], Message, bubble=True):
class TreeControl(Generic[NodeDataType], Widget, can_focus=True):
CSS = """
DEFAULT_CSS = """
TreeControl {
background: $panel;
color: $text-panel;

View File

@@ -112,7 +112,7 @@ class TextInput(TextWidgetBase, can_focus=True):
suggestion will be displayed as dim text similar to suggestion text in the zsh or fish shells.
"""
CSS = """
DEFAULT_CSS = """
TextInput {
width: auto;
background: $surface;
@@ -417,7 +417,7 @@ class TextInput(TextWidgetBase, can_focus=True):
class TextArea(Widget):
CSS = """
DEFAULT_CSS = """
TextArea { overflow: auto auto; height: 5; background: $primary-darken-1; }
"""
@@ -428,7 +428,7 @@ class TextArea(Widget):
class TextAreaChild(TextWidgetBase, can_focus=True):
# TODO: Not nearly ready for prime-time, but it exists to help
# model the superclass.
CSS = "TextAreaChild { height: auto; background: $primary-darken-1; }"
DEFAULT_CSS = "TextAreaChild { height: auto; background: $primary-darken-1; }"
STOP_PROPAGATE = {"tab", "shift+tab"}
def render(self) -> RenderableType:

View File

@@ -106,7 +106,7 @@ def test_stylesheet_apply_user_css_over_widget_css():
user_css = ".a {color: red; tint: yellow;}"
class MyWidget(Widget):
CSS = ".a {color: blue !important; background: lime;}"
DEFAULT_CSS = ".a {color: blue !important; background: lime;}"
node = MyWidget()
node.add_class("a")

View File

@@ -110,7 +110,7 @@ async def test_composition_of_vertical_container_with_children(
expected_placeholders_offset_x: int,
):
class VerticalContainer(Widget):
CSS = (
DEFAULT_CSS = (
"""
VerticalContainer {
layout: vertical;
@@ -304,7 +304,7 @@ async def test_scrollbar_size_impact_on_the_layout(
class LargeWidgetContainer(Widget):
# TODO: Once textual#581 ("Default versus User CSS") is solved the following CSS should just use the
# "LargeWidgetContainer" selector, without having to use a more specific one to be able to override Widget's CSS:
CSS = """
DEFAULT_CSS = """
#large-widget-container {
width: 20;
height: 20;

View File

@@ -48,7 +48,7 @@ async def test_scroll_to_widget(
last_screen_expected_placeholder_ids: Sequence[int],
):
class VerticalContainer(Widget):
CSS = """
DEFAULT_CSS = """
VerticalContainer {
layout: vertical;
overflow: hidden auto;
@@ -60,7 +60,7 @@ async def test_scroll_to_widget(
"""
class MyTestApp(AppTest):
CSS = """
DEFAULT_CSS = """
Placeholder {
height: 5; /* minimal height to see the name of a Placeholder */
}