Maybe this is better for <#CJLTWPH7S|compose> but ...
# compose-desktop
m
Maybe this is better for #compose but I'm curious - it seems like the way theming is handled in Compose (and obv. reactjfs as well) is that in effect, every theme is its own widget toolkit. This is very different to OOP toolkits, where a theme is a set of styles or objects that render the stock controls for you. It seems common that these 'themes' aren't documented at all, which seems problematic - if you want to port or switch from one theme to another, how do you know the one you want has all the features and APIs you need? Why does each 'theme' have to reinvent a button out of boxes and other low level primitives?
đź‘€ 1
k
Compose by design chose this approach based on the decade+ worth of experience of doing (or perhaps, trying to do) themeable components. Over the evolution of the design language (early days, gingerbread green, ics blue, kitkat grey, lollipop+ material) it turned out that it becomes more and more difficult to create a “canonical” set of components that can evolve their theming in a non-breaking way. In addition, it’s not clear how to allow third-party developers to create their own simple and composite components that match that canonical set of components. And then, it’s not clear how to allow third-party theme developers to create skins that can be applied across the whole landscape of “canonical” and custom components. Swing has tried to do that and failed. This is why you see Swing third-party libraries shipping not only with their own skins / themes, but also with their own additional components on top of what Swing provides, but only under the skins / themes from that particular library. At least in the Swing land, nobody has been able to crack this problem of cleanly composing components and themes in a pluggable, many-to-many fashion.
So what Compose is doing is providing a set of lower-level primitives to handle user input, state management, accessibility etc, as well as a sort-of-a-reference implementation of a very particular design language with a baseline / canonical set of components. Third-party devs can use that set as is, wrap it and tweak it within its limitations, or build their own component set on top of those lower-level primitives.
I think they key part in your statement is “a set of styles that render the stock controls for you”. Once you want to go outside of that, and do something that is not part of that stock set, that’s where that model starts showing its limitations.
m
Yes, but I'm not sure it's as difficult as that makes it sound. If you look at AtlantaFX as an example of a modern JavaFX theme, it does add a few controls of its own but mostly just because the stock JavaFX controls were designed a decade ago and fashion changed in a few places (e.g. toggle sliders vs checkboxes). Still, almost the entire theme consists of sass stylesheets that just change the look of the built-in widgets. The Control/Skin split seems to work well enough along with inheritance to add minor features to the standard controls - it doesn't have to be perfect to still be very useful. Also, from a quick look, I bet most of the 'new' controls in AtlantaFX could actually just be custom skin classes, it's not clear why a full new widget is needed (even where it's just inheriting from a pre-existing base). It seems like the Compose design gives up on the idea of sophisticated core controls in favor of repeatedly re-building simple controls as part of app branding. Seems hard to achieve complex controls like spreadsheets, calendars, embedded rich text editors etc with this approach. In mobile maybe it doesn't matter as UIs don't tend to have complex widgets anyway.
k
A set of sophisticated core controls today is a set of slightly obsolete and somewhat outdated controls ten years down the line. JavaFX does not (yet or ever) show a successful example of N third-party themes and M third-party controls with seamless NxM combinations between them. And sure, just because many have tried and failed, doesn’t mean that there is no solution out there for somebody to discover.
b
You get both: The "Material" widgets provide what you say is like "OOP toolkits, where a theme is a set of styles or objects that render the stock controls for you". And then you ALSO have lots of power to extend/use parts of Material or create your own from scratch. You don't lose out on anything.
k
Coming back to this one more / last time, I would say that IntelliJ lets you change IntelliJ themes, and the same way, Material lets you change Material themes.
There needs to be a certain contract between the two sides, the theme that provides a certain set of these visual settings and the components that configure their presentation according to those settings.