Themes

Themes are used to manage the visual presentation of the application.

A theme consists of CSS files and other resources like images and fonts.

Jmix provides jmix-lumo theme built on top of Vaadin Lumo theme.

Applying a Theme

The application theme is applied using the @Theme annotation with the name of the theme folder as a parameter. The @Theme annotation must be placed on the class that implements the AppShellConfigurator interface, which is usually the main application class.

@Theme(value = "my-theme")
public class MyProjectApplication implements AppShellConfigurator {
    ...
}

A theme variant can be specified as an additional parameter, such as dark or light.

@Theme(value = "my-theme", variant = "dark")
public class MyProjectApplication implements AppShellConfigurator {
    ...
}
Themes cannot be switched at runtime. Although a project may have multiple themes, only one can be applied for the UI. However, there are ways to switch between variants of the same theme and load dynamically additional styles on top of a theme.

Application Theme

For use in an application, the theme folder is placed inside the frontend/themes folder, with a name of your choosing. Jmix application projects created using Studio have a predefined theme folder with the same name as the project itself.

theme folder structure
Figure 1. Theme folder file structure
  • my-project - the theme folder, also used as theme name

  • styles.css - the master stylesheet

  • my-project.css - an entry point for custom styles and imports

  • theme.json - a theme configuration file, which by default defines jmix-lumo as the default theme.

styles.css is the entry point to the theme’s styles. All CSS, including Lumo style property values and custom component styles, can be added there.

It can be useful to split CSS into multiple files to avoid cluttering the main stylesheet. Additional CSS files are loaded using @import directives. By default, the project’s master stylesheet contains a single import of <theme-name>.css file that defines your styles and any other imports.

styles.css
@import url('./my-project.css');

Reusable Theme

An application theme can be used in multiple applications by packaging it as a JAR dependency.

The theme project’s structure looks as follows:

theme addon structure
Figure 2. Theme project structure
  • cobalt - the theme folder, also used as theme name

  • styles.css - the master stylesheet. Can contain custom styles and imports, for example:

    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 - a theme configuration file. It’s recommended to define jmix-lumo as the parent theme, so your custom theme includes jmix-lumo styles required for proper work of Jmix UI components and views. For example:

    {
      "parent": "jmix-lumo",
      "lumoImports":["typography","color","spacing","badge","utility"]
    }

The build.gradle file of the theme add-on project may look as follows:

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 Dependency to jmix-flowui-themes that contains jmix-lumo theme.

After the theme JAR is added as a dependency to the project, the packaged theme can be used as a standalone theme:

@Theme(value = "cobalt")
public class MyProjectApplication implements AppShellConfigurator {
    ...
}

or as a parent for the project’s themes, for example:

theme.json
{
  "parent": "cobalt",
  "lumoImports":["typography","color","spacing","badge","utility"]
}

In this case, the project’s theme will load on top of the base theme, extending it.

custom theme
Figure 3. Example of applied custom theme

Pluggable Styles

When developing a custom add-on, you can create a file with custom styles in the src/main/resources/META-INF/resources/ directory. To add these styles to the resulting application, define the jmix.ui.export-styles property in the module.properties file. The value of this property is a path relative to src/main/resources/META-INF/resources/, for example, jmix.ui.export-styles = addon-styles/my-addon-styles.css:

my-addon-styles.css
.test {
    color: red;
}

Custom styles are added as <style type="text/css"> to the <head> element:

<style type="text/css">
.test {
    color: red;
}
</style>
Use this approach only for a small number of styles that cannot be applied to a particular UI component. For example, for CSS utility classes of views inside an add-on.