Темы
Темы используются для управления визуальным оформлением приложения.
Тема состоит из файлов CSS и других ресурсов, таких как изображения и шрифты.
Jmix предоставляет тему jmix-lumo, построенную на основе темы Lumo Vaadin.
Применение темы
Тема приложения применяется с помощью аннотации @Theme с именем папки темы в качестве параметра. Аннотация @Theme должна быть размещена на классе, который реализует интерфейс AppShellConfigurator, обычно это основной класс приложения.
@Theme(value = "my-theme")
public class MyProjectApplication implements AppShellConfigurator {
    ...
}Вариант темы может быть указан в качестве дополнительного параметра, например dark или light.
@Theme(value = "my-theme", variant = "dark")
public class MyProjectApplication implements AppShellConfigurator {
    ...
}| Темы не могут быть переключены во время выполнения. Хотя проект может иметь несколько тем, для UI приложения может быть применена только одна. Однако существуют способы переключения между вариантами одной и той же темы и динамической загрузки дополнительных стилей поверх темы. | 
Тема приложения
Для использования в приложении каталог темы размещается внутри каталога src/main/frontend/themes. Проекты Jmix, созданные с помощью Studio, имеют предопределенный каталог темы с таким же именем, как и сам проект.
Например:
src
└── main
    └── frontend
        └── themes
            └── my-project
                ├── my-project.css
                ├── styles.css
                ├── theme.json
                └── view
                    ├── login-view.css
                    ├── main-view-top-menu.css
                    └── main-view.css- 
my-project- каталог темы. Имя каталога используется в качестве имени темы в аннотации @Theme.
- 
my-project.css- файл кастомных стилей данной темы.
- 
styles.css- основной файл стилей, является точкой входа для стилей данной темы.
- 
theme.json- файл конфигурации темы. По умолчанию, определяет jmix-lumo в качестве родительской темы.
- 
view- данный каталог содержит файлы CSS, определяющие стили для главного экрана и экрана логина, предоставляемых шаблоном проекта.
Весь код CSS, включая значения CSS-переменных и кастомные стили компонентов, может быть включен в основной файл styles.css. Однако по умолчанию этот файл содержит только директивы импорта, а фактический CSS организован в отдельные файлы, чтобы упростить поддержку кода:
@import url('my-project.css');
@import url('view/main-view.css');
@import url('view/main-view-top-menu.css');
@import url('view/login-view.css');Размещайте CSS-код вашего проекта в файле <theme_name>.css (в данном примере это my-project.css).
| Используйте онлайн-редактор Lumo theme editor от Vaadin для быстрой настройки темы вашего приложения. Настройте нужный внешний вид UI-компонентов, используя элементы управления в правой панели. Затем нажмите Download и вставьте сгенерированный CSS код, расположенный внутри тегов  | 
Переиспользуемая тема
Тема может быть использована в нескольких приложениях путем упаковки ее в виде JAR-зависимости.
Структура проекта c темой выглядит следующим образом:
src
└── main
    └── resources
        └── META-INF
            └── resources
                └── themes
                    └── cobalt
                        ├── styles.css
                        └── theme.json- 
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.3.0' (1)
}| 1 | Зависимость jmix-flowui-themesсодержит тему jmix-lumo. | 
После того, как JAR c темой добавлен в качестве зависимости в проект, упакованную тему можно использовать как самостоятельную тему:
@Theme(value = "cobalt")
public class MyProjectApplication implements AppShellConfigurator {
    ...
}или как родительскую для тем проекта, например:
{
  "parent": "cobalt",
  "lumoImports":["typography","color","spacing","badge","utility"]
}В этом случае тема проекта будет загружаться поверх базовой темы, расширяя ее.
 
Подключаемые стили
При разработке собственного дополнения можно создать файл с пользовательскими стилями в каталоге src/main/resources/META-INF/resources/. Чтобы эти стили добавились в результирующее приложение, определите свойство jmix.ui.export-styles в файле module.properties. Значением этого свойства является путь относительно 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 содержит код, который применяет вариант темы к HTML-документу в зависимости от значения в Web Local Storage и подписывается на prefers-color-scheme, чтобы обновить вариант темы, если пользователь укажет свои предпочтения через настройки операционной системы (например, светлый или тёмный режим) или настройки user agent.
Его нужно импортировать в основной класс приложения:
@JsModule("./src/theme/color-scheme-switching-support.js")
@SpringBootApplication
public class OnboardingApplication implements AppShellConfigurator {