Vaadin 12主题可切换的最佳做法

时间:2019-02-05 08:38:39

标签: vaadin vaadin-flow vaadin12 vaadin-themes

我目前正在将Vaadin 8应用程序迁移到Vaadin12。外观应由用户使用,并在登录时或通过按下按钮进行更改。

在Vaadin 8应用程序中,我们有2个主题(一个黑暗和一个明亮的主题),每个主题都有自己的SASS / CSS和一些共享的属性。用户可以使用setTheme()方法进行切换。单击切换按钮时,外观就改变了。在Vaadin 12中,主题化采用了不同的方法,我正在努力寻找在Vaadin 12中实现此功能的好方法。

假设我们不想创建一个全新的主题,而只是想使用自定义的LUMO。我可以通过@Theme Annotation设置Theme / Variant。缺点:主题将在运行时修复。

我还可以编写一些代码以将变体应用于我的应用程序和组件。 (例如,在动态样式章节:https://vaadin.com/docs/flow/element-api/tutorial-dynamic-styling.html中) 缺点:遍历每个元素并应用变体并不是很实际。

我现在的问题:

在运行时在主题之间进行切换的最佳方法是什么?(Lumo或其他主题的自定义明暗变体)。

我是否要创建2个包含CSS的HTML文件(出于兼容性考虑),然后通过动态导入以某种方式覆盖当前使用的File?

我希望我的问题很清楚,并且有人可以指出正确的方向。

2 个答案:

答案 0 :(得分:4)

如果您只对在 light dark 之间切换感兴趣,则可以在DOM中很高的位置添加/删除dark。例如。用户界面的元素通常是body或至少很高。

例如:

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)
            }
        }
    }
}

修改

如另一个答案的评论中所述:

要更改主题的颜色,可以覆盖使用的颜色。这是示例如何更改明暗Lumo主题的文本颜色:

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

答案 1 :(得分:3)

在同一主题的两个不同变体之间进行切换相对容易,例如Lumo的黑暗和光明变体。为此,您只需要在theme元素上切换相应的<html>属性。无法从服务器直接访问该元素,但是可以使用一小段JavaScript:ui.getPage().executeJavaScript("document.documentElement.setAttribute($0, $1)", "theme", "dark");

根据情况,您可以或者必须将更改应用于<body>元素。在这种情况下,您可以在JS代码段中将.documentElement切换为.body,也可以在Java中直接使用ui.getElement().setAttribute("theme", "dark")

在两个不同的基本主题之间切换,例如Lumo vs Material是一件更加复杂的事情。对于每个组件,一次只能在浏览器中加载一个基本主题,并且重新加载页面是摆脱已加载的主题的唯一方法。对于Flow所使用的每个组件,除了没有样式的基础导入外,框架还负责加载正确的主题导入。为了使事情变得更加复杂,使用@Theme指定的主题会自动包含在应用程序的产品包中。为了能够使用多个基本主题,您还必须以某种方式生成多个不同的包,并以某种方式将Flow配置为根据情况使用正确的包。