主题
主题(Themes)用于管理应用程序的可视化展示。
一个主题由一些 CSS 文件和其他资源构成,比如图片、字体等。
Jmix 提供了基于 Vaadin Lumo 主题 构建的 jmix-lumo 主题。
使用主题
应用程序主题通过 @Theme
注解提供,注解中使用主题文件夹的名称作为参数。@Theme
注解必须配置在实现了 AppShellConfigurator
接口的类上,通常为主应用程序类。
@Theme(value = "my-theme")
public class MyProjectApplication implements AppShellConfigurator {
...
}
主题的样式版本(variant)可以作为附加参数,例如 dark 或 light。
@Theme(value = "my-theme", variant = "dark")
public class MyProjectApplication implements AppShellConfigurator {
...
}
应用程序主题
在应用程序中,主题的文件夹放在 frontend/themes
目录中,文件夹的目录可以自定义。使用 Studio 创建的 Jmix 应用程序项目有一个预定义的主题文件夹,其名称与项目本身相同。
-
my-project
- 主题文件夹,也作为主题名称使用 -
styles.css
- 主样式文件 -
my-project.css
- 自定义样式和导入样式写在这里 -
theme.json
- 主题配置文件,默认使用 jmix-lumo 主题。
styles.css
文件是主题样式的入口文件。所有的 CSS,包括 Lumo 样式的一些属性值以及自定义的组件样式,都包含在内。
将 CSS 拆分为多个文件可以避免主样式表中混乱的结构。其他 CSS 文件使用 @import
指令加载。默认情况下,项目的主样式文件导入了 <theme-name>.css
文件,其中可以自定义样式或导入其他文件。
@import url('./my-project.css');
可重用主题
应用程序的主题可以打包成独立的 JAR 文件,从而提供给多给项目使用。
主题项目的结构如下:
-
cobalt
- 主题文件夹,也用作主题名称 -
styles.css
- 主样式文件。可以包含自定义样式和导入,示例:html { --lumo-border-radius: calc(var(--lumo-size-m) / 2); --lumo-primary-color: rgb(0, 85, 166); --lumo-primary-color-50pct: rgba(0, 85, 166, 0.5); --lumo-primary-color-10pct: rgba(0, 85, 166, 0.1); --lumo-primary-text-color: rgb(0, 85, 166); }
-
theme.json
- 主题配置文件。建议使用 jmix-lumo 作为父主题,这样自定义的主题可以使用 jmix-lumo 中的默认样式渲染 Jmix UI 组件和视图。示例:{ "parent": "jmix-lumo", "lumoImports":["typography","color","spacing","badge","utility"] }
主题项目中的 build.gradle
文件如下:
plugins {
id 'java'
id 'com.gradle.plugin-publish' version '1.2.1'
}
group = 'com.company'
version = '0.0.1-SNAPSHOT'
repositories {
mavenCentral()
maven {
url 'https://global.repo.jmix.io/repository/public'
}
}
dependencies {
implementation 'io.jmix.flowui:jmix-flowui-themes:2.4.0' (1)
}
1 | 依赖 jmix-flowui-themes ,其中包含 jmix-lumo 主题。 |
在项目中添加了这个主题 JAR 之后,可以使用 JAR 中打包的主题:
@Theme(value = "cobalt")
public class MyProjectApplication implements AppShellConfigurator {
...
}
或者也可以作为项目主题的父主题,示例:
{
"parent": "cobalt",
"lumoImports":["typography","color","spacing","badge","utility"]
}
这样项目中的主题会基于该主题扩展。
可插拔样式
当开发一个 自定义扩展组件 时,可以在 src/main/resources/META-INF/resources/
目录创建包含自定义样式的文件。如需在最终的应用程序中包含这些样式,可以在 module.properties
文件中定义 jmix.ui.export-styles
属性。该属性的值是 src/main/resources/META-INF/resources/
下的相对路径,例如,jmix.ui.export-styles = addon-styles/my-addon-styles.css
:
.test {
color: red;
}
自定义样式会作为 <style type="text/css">
添加到 <head>
元素中:
<style type="text/css">
.test {
color: red;
}
</style>
这种方式仅适用于少量无法用到特定 UI 组件的样式。例如,扩展组件内视图的 CSS 工具类。 |
运行时更改主题
为了实现在不同的样式版本之间切换,例如 light 和 dark,框架提供了一个与 JavaScript 文件结合使用的静态帮助类。
ThemeUtils
类提供了用于切换样式版本的方法,主要是在 Web Local Storage 中设置样式版本,然后调用 JavaScript 代码使其生效。
例如,可以在主视图中添加一个 dropdownButton 用于切换不同的主题:
<dropdownButton id="themeSwitcher"
text="Theme" icon="ADJUST"
classNames="ms-auto me-m"
dropdownIndicatorVisible="false">
<items>
<actionItem id="systemThemeItem">
<action id="systemThemeAction"
text="System" icon="ADJUST"/>
</actionItem>
<actionItem id="lightThemeItem">
<action id="lightThemeAction"
text="Light" icon="SUN_O"/>
</actionItem>
<actionItem id="darkThemeItem">
<action id="darkThemeAction"
text="Dark" icon="MOON_O"/>
</actionItem>
</items>
</dropdownButton>
@Subscribe("themeSwitcher.systemThemeItem.systemThemeAction")
public void onThemeSwitcherSystemThemeItemSystemThemeAction(final ActionPerformedEvent event) {
ThemeUtils.applySystemTheme();
}
@Subscribe("themeSwitcher.lightThemeItem.lightThemeAction")
public void onThemeSwitcherLightThemeItemLightThemeAction(final ActionPerformedEvent event) {
ThemeUtils.applyLightTheme();
}
@Subscribe("themeSwitcher.darkThemeItem.darkThemeAction")
public void onThemeSwitcherDarkThemeItemDarkThemeAction(final ActionPerformedEvent event) {
ThemeUtils.applyDarkTheme();
}
JavaScript 文件中的代码根据 Web Local Storage 中的值在 HTML 中使用特定的主题版本,并订阅 prefers-color-scheme:在用户通过操作系统设置(例如,浅色或深色模式)或 user agent 设置主题偏好时可以更新主题。
需要在主应用程序类中 import:
@JsModule("./src/theme/color-scheme-switching-support.js")
@SpringBootApplication
public class OnboardingApplication implements AppShellConfigurator {