vaadinvaadin-flowvaadin12vaadin-themes

Best practice for switchable Vaadin 12 themes


I am currently in the process of migrating a Vaadin 8 application over to Vaadin 12. The look and feel should be used by the user and changed on Login or via a button press.

In Our Vaadin 8 application we had 2 themes (a dark and a light one), each with their own SASS/CSS and some shared properties. The user was able to switch it using the setTheme() Method. When a click to the switching button happened, the Look and Feel just changed. In Vaadin 12 the Theming follows a different approach and I am struggling to find a good way to implement this feature in Vaadin 12.

Let's say we don't want to create a whole new Theme and just want to use customized LUMO. I can set the Theme/Variant through the @Theme Annotation. The Downside: The Theme will be fixed at Runtime.

Also i could just write some code to apply variants to my application and components. (like in the dynamic styling chapter: https://vaadin.com/docs/flow/element-api/tutorial-dynamic-styling.html ) The Downside: It won't be very practicable to iterate through each element and apply the variant.

My question now:

What is the best way to achieve a switch between to themes at runtime? (customized light- and dark variants of Lumo or any other theme).

Would I just create 2 HTML Files (for compatibility) containing CSS and then somehow override the currently used File through a dynamic import?

I hope my question is clear and someone can point me to the right direction.


Solution

  • If you are only interested in toggling between light and dark, then you can just add/remove dark at a very high place in the DOM. E.g. the element of the UI is usually the body or at least very high up.

    E.g.:

    new Checkbox("Use Dark Theme").tap{
        addValueChangeListener{ cb ->
            getUI().ifPresent(){ ui ->
                def themeList = ui.getElement().getThemeList()
                if (cb.value) {
                    themeList.add(Lumo.DARK)
                } else {
                    themeList.remove(Lumo.DARK)
                }
            }
        }
    }
    

    edit

    As asked in the comments of another answer:

    To change the colors in a theme, you can override the used colors. This is the example how to change the text color for light and dark Lumo theme:

    html {
        --lumo-body-text-color: red;
    }
    [theme~="dark"] {
        --lumo-body-text-color: yellow;
    }