Feature #10848
custom theme improvements
0%
Related issues
History
#1 Updated by Greg Shah 8 months ago
In embedded mode, the CSS for the web portions has no connection to the theming in the legacy screens. I can see a scenario where we would read specific CSS values from the web client side of the embedded mode and honor those values from our theme classes.
I'm also open to other ideas of how to improve our theming support.
#2 Updated by Hynek Cihlar 8 months ago
Beside the trivial solutions of driving some basic CSS styling values into the theme classes I offer yet another solution.
DOM mode and DOM driver. Currently we have ChUI and GUI modes, we could as well introduce another one - a DOM mode. That is to render the widgets in the HTML document object model. This is certainly a lot bigger scope, but otherwise a viable solution IMHO.
#3 Updated by Alexandru Lungu 8 months ago
There are plenty of things that can be improved in the theming IMHO, so I will list some of them so we can approve/disapprove some leads:
Note ahead:- I really like #10848-2 suggestion, so Hynek has my vote :) My suggestions will not cover this tho.
New Web themes¶
Preset themes are limited to Windows and MaterialUI. AFAIK, there are plenty of other Web frameworks for theming that are as popular as MaterialUI. In the context of embedded Web client, I guess it is fine to have presents for more popular frameworks:Bootstrap: https://getbootstrap.com/ Tailwind: https://tailwindcss.com/ Bulma: https://bulma.io/ Pico: https://picocss.com/
- Nevertheless, there are also framework specific frameworks that have their own styling (e.g. for React components, there are:
AntD: https://ant.design/ Mantine: https://mantine.dev/ ChakraUI: https://chakra-ui.com/
I am bringing this up because, in the context of embedded mode, I presume the web portions will most probably use a styling library. Thus, it would be nice to have FWD integrate some popular frameworks out-of-the-box so that integration will be seamless. Something like: "I use Bootstrap on Web, so I just need to set-up Bootstrap integration in FWD - goal achieved".
If we do not support a certain framework, then we can start supporting it :) Or until then, the theming can be done on a custom basis according to the documentation to be improved by #10849.
Static integration¶
If we know that a certain framework is used for theming the outer application, we can integrate natively with it, without the need to actually duplicating the specs in FWD. I was thinking that each and one of the frameworks described above has a "standard way" of overriding the defaults - most probably through JSON or Sass files that are ingested by the framework and bootstrap the right theme. What if FWD will be able to do the same ingestion of JSON files to customize on its own. It would be seamless.
Case study: Bootstrap¶
- Compile-time: there is a
_variables.scssfile that holds the colors (primary, secondary, success, etc.). When the Scss is compiles in plain CSS, the colors are resolved accordingly. - Run-time: one can override different style classes to change colors (e.g.
--bs-primary: #90caf9).
Case study: Tailwind¶
- Compile-time: there is a
tailwind.config.jsthat is used to generate the CSS files manually. The JS only exports a "theme object", which can be extracted in a separate JSON file. - Run-time: ne can override different style classes to change colors (e.g.
--color-primary: #90caf9).
Case study: Other React framework¶
Usually there is a "theme object" somewhere that can be extracted in a JSON file and ingested by FWD as well.
Dynamic integration¶
There can be theme changes in the outer application at run-time and most common is light/dark mode setting. If FWD forces a specific theme for a client, then it can't be changed at run-time. I mean, there is a theme picker at login, but there is no way to change the theme after that. I would imagine we can simply replace the used theme and redraw everything to simulate that, but it should be implemented.
As for the integration part, we would need to ingest multiple configuration files from the CSS framework, store them in FWD as themes and allow them to be changed at run-time. We can experiment with this to enable light/dark mode functionality to start with in non-embedded applications.
Implementation details¶
- We can create Java themes in advance. This means we are considering a separate tool that parses some of the configuration files from different styling frameworks and generate either Java source-code or Java classes. These should extend the base classes for the framework chosen. OR
- The themes can be loaded at server start-up based on the styling artifact.
- It either creates and loads Java classes at run-time.
- Or we bootstrap a
GenericThemewith the value read.
Non-standard Web themes¶
If we do not support a certain framework (or none is used), then I do not think we should stress that much. One can set the theme to "Bootstrap" (even if it is not using Bootstrap for styling per se) and just plug in a _variables.scss (or JSON file matching the chosen framework) to configure that. It would be "FWD standard" way of ingesting CSS values. My point is that we shouldn't revamp the specifications of a CSS file that is compatible with FWD, but rather use a preexisting one. This way we support both a big framework (i.e. Tailwind, Bootstrap, etc.) and provide customization for non-framework outer application with one single code-base.
#4 Updated by Greg Shah 8 months ago
DOM mode and DOM driver. Currently we have ChUI and GUI modes, we could as well introduce another one - a DOM mode. That is to render the widgets in the HTML document object model.
Please provide more details of the idea. Are you suggesting that we would use HTML input widgets or just that we would create artificial DOM elements to duplicate the 4GL widget tree (which then could be styled with CSS)?
#5 Updated by Greg Shah 8 months ago
Alex, these are interesting ideas.
The theme classes today include the full implementation of drawing operations, so it is not clear to me how we would take much more than superficial styling from CSS (or a framework). Is that what you are proposing? In other words, the overall drawing of a widget can't easily be implemented using any of the JS frameworks but we can extract some styling elements and apply them to our themes.
Is your concept more about how we read these style elements than it is about the non-style aspects?
So far, in our embedded mode we have been neutral in terms of framework. My worry with starting to add integrations with specific frameworks is that it can be a lot of maintenance to support each framework and how would we even pick the right ones? Customers will have their own choices and we don't want to limit them. If our customers don't use the frameworks we integrate with, then it is a lot of time spent (not just once, but over time as we support later versions) without any benefit. Although we do see customers using Angular and React, it is not clear to me how safe it is to pick specific frameworks. Since each framework has its own approach, there would be a lot of bespoke code needed.
#6 Updated by Alexandru Lungu 8 months ago
There are two layers here:The theme classes today include the full implementation of drawing operations, so it is not clear to me how we would take much more than superficial styling from CSS (or a framework).
- the framework that states the drawing operations and how the widgets should feel and look like. This would translate to a manually written theme class in FWD.
- the framework configuration that states under which parameters it should work (colors for instance). This would translate to an automatically generated sub-class of the theme class in FWD.
With this "combo", FWD is batteries included - this is what I am suggesting. Without the second part, the FWD user should duplicate his superficial styling in JS to Java. Without the first part, the dev. should get into all the drawing operations realm, which IMHO is way more difficult to apprehend.
I guess this is what happened with Material UI back in the days, right? Just take a look into how the widgets are styled and get close to that. I can agree that some things may get absurd (like input fields with very round borders that may overlap text), but I was thinking at a best effort approach.
Is your concept more about how we read these style elements than it is about the non-style aspects?
Read style elements, implement non-style elements.
My worry with starting to add integrations with specific frameworks is that it can be a lot of maintenance to support each framework and how would we even pick the right ones?
This is customer driven; I don't imagine supporting every framework, so that only 1 or 2 are used :)
Nevertheless, I think there are good fallbacks for lack of maintenance or complete lack of support. If a theme is not maintained anymore, then at least is serves as a reasonable starting point for updating it. For instance, Material UI is supported to a certain degree - but it can be more useful as a starting point than Classic theme I suppose.
The alternative is to let FWD users design that from scratch which might get quite painful.
Customers will have their own choices and we don't want to limit them.
I guess it is more about "better integration" with some technologies than other, but do not rule out the complete customization possibility. I would imagine having the Themed wiki page (set-up in #10849) way easier to read and accept based on some prefabricated themes that needs tweaking. I would personally enjoy "How to set-up Tailwind Theme" chapter than "Understanding the Primitive Drawing Operations" chapter :)
But, #10848-2 will completely mitigate this as the styling will be done straight-away by the browser.
#7 Updated by Hynek Cihlar 8 months ago
Greg Shah wrote:
Please provide more details of the idea. Are you suggesting that we would use HTML input widgets or just that we would create artificial DOM elements to duplicate the 4GL widget tree (which then could be styled with CSS)?
The idea is not about improving the existing theme classes or extending the GUI mode per se. It stems from the same motivation, though: enabling the legacy application (or its portions) to blend seamlessly into a modern web application frame.
When customers embed their legacy app inside a larger web app, they typically don’t want to retain the legacy look and behavior. Quite the opposite, they expect a modern web experience.
Given that, I propose we take a more fundamental step forward and introduce a new UI mode: the DOM mode. Just as we once introduced the GUI mode when only ChUI existed, this would be another rendering path, one that maps our widget tree directly into the HTML document object model.
This may sound ambitious, but I believe it’s quite feasible. The required effort would be significant but still only a fraction of what we invested when developing GUI mode. Here’s why:
- The core infrastructure for supporting multiple UI modes already exists, adding a new mode wouldn’t require large-scale refactoring.
- Input handling for web is already implemented and could be reused almost as is.
- The number of distinct widget types is relatively small, and their HTML equivalents would be simpler to implement than our current 2D canvas rendering.
- We wouldn’t need pixel-perfect fidelity to the original, and in fact, customers wouldn’t want it. After all this is why this ticket exists: to achieve better integration, not visual reproduction.
- True native web experience.
- Unlimited CSS styling and theming possibilities.
- Standards-based implementation.
- No performance overhead from 2D canvas rendering.
- Happier customers and more flexible integration scenarios.
- EDIT: Testing!
I realize the proposed DOM mode might be too ambitious for the current project scope or schedule, but I believe it’s a direction worth exploring in the longer term.
#8 Updated by Greg Shah 8 months ago
I realize the proposed DOM mode might be too ambitious for the current project scope or schedule, but I believe it’s a direction worth exploring in the longer term.
I agree, it is an interesting idea. This overlaps with an idea I've had for some time, in which we (at runtime) render ChUI screens as a GUI or web UI. As you say, this would not be limited by compatibility. The key point woul dbe where we decide to break compatibility and where not to break it.
#9 Updated by Hynek Cihlar 8 months ago
Greg Shah wrote:
The key point woul dbe where we decide to break compatibility and where not to break it.
Yes. Also as the resulting look would not be 1:1 to the original, this would to some extent break the appearance of the converted app. Especially for complex layouts with pixel perfect positioning. So typically some intervention would be required, perhaps even at the legacy code level (I can imagine legacy layout logic being disabled when running in DOM mode).
#10 Updated by Alexandru Lungu 8 months ago
Just noticed a MSG_GET_WEB_BASIC_PALETTE actually exists to retrieve a color pallet from the Web socket. But this is marked as // TODO: get the 5-color palette (where from? CSS?).
#11 Updated by Alexandru Lungu 8 months ago
- Related to Bug #10913: multiple tabs draw labels highlighted at the same time added
#12 Updated by Alexandru Lungu 8 months ago
- Related to Support #10849: improve documentation on implementation of custom themes added
#13 Updated by Alexandru Lungu 8 months ago
- Related to Feature #10923: Improve drawRoundRect and fillRoundRect added
#14 Updated by Alexandru Lungu 8 months ago
- Related to Bug #10924: drawFillInBorder hover is always false added
#15 Updated by Alexandru Lungu 8 months ago
- Related to Support #10926: General clean-up of Theme added