我目前正在将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?
我希望我的问题很清楚,并且有人可以指出正确的方向。
答案 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配置为根据情况使用正确的包。