textual icon indicating copy to clipboard operation
textual copied to clipboard

Theming and style language

Open willmcgugan opened this issue 1 year ago • 3 comments

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...

willmcgugan avatar Oct 02 '24 09:10 willmcgugan

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.theme read-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 Theme object or expose ColorSystem (possibly rename to Theme?).
    • The ColorSystem object 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 for primary, secondary, etc...
  • (Possibly) add a App.theme_changed reactive of type Signal[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.

darrenburns avatar Oct 02 '24 12:10 darrenburns

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.

amottola avatar Oct 09 '24 06:10 amottola

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.

jsatchell avatar Oct 19 '24 15:10 jsatchell