textual
textual copied to clipboard
Theming and style language
We need a system to allow customization of styles, and enforce a consistent look and feel.
- API to switch between color themes
- Semantic styles to enforce a consistent look and feel with widgets
Something inspired by Posting...
Some ideas and a bunch of questions that would be good to chat about:
- Add
App.theme_name (str)reactive which is set to the theme name. - Add
App.themeread-only property which gets the "theme object"? - Add
App.register_theme(theme: Theme)which allows "registering" a theme. A registered theme will appear in the command palette and is just stored in a dict at the app level.- The equivalent for unregistering a theme.
- Define a
Themeobject or exposeColorSystem(possibly rename toTheme?).- The
ColorSystemobject is really convenient because it "fills in the blanks" nicely when values are missing. In Posting, you can define a theme with just a couple of colours and it still looks reasonable thanks to the ColorSystem. Users could provide values forprimary,secondary, etc...
- The
- (Possibly) add a
App.theme_changedreactive of typeSignal[Theme]. Rich renderables don't easily have access to colours from the theme, and when the theme changes they need to be able to refresh themselves to grab the new values from the theme. (Perhaps this should be handled entirely by component classes though?)
Q - How should this interact with App.dark?
Posting has no concept of "dark mode" vs "light mode". It just has themes. Should App.dark become something like App.theme = "textual-dark"? The problem was that colours pretty much always needed tweaked when put against a light background vs a dark background.
I'm also worried that enforcing "if you design a theme then you need to make sure it has a light variant" isn't ideal.
Looks good. A Theme object should be conceived to also support future extensions, like more tcss variables to more properly customize widgets default appearence (button border style and width, but also progress block characters come to mind for example)
About dark mode, in addition to map it to textual-dark, IMHO I'd deprecate it entirely with a clear note both in the docs and at runtime in the dev console.
This might be a convenient way to bundle up a set of styling changes for Linux console support. I think I have boiled the dominant issues down to two points:
- The available fonts I have tried don't have the block drawing characters, just the basic box outlining, so anything using e.g. border: tall hits missing glyphs (and the scrollbar is effected too, for the same reason). For many widgets, setting border solid looks OKish, and much better than the default. For some, the border needs to be on an inner component, rather than the headline widget. For example, with Select, the border works best on SelectCurrent.
- The are very few available colours, so you end up with a black scrollbar on a black background, which is not very visible. You can only see it at all because of the missing glyph markers :-( If we were in theme="linux-console" mode, you would want set it to maybe the foreground colour, or at least something different to the background. You have a whole 16 choices.