Olejon
Olejon

Reputation: 99

Custom Theme Class and Theme Structure in Vaadin 14

I created a custom theme as an jar file and imported it into my project using annotation @Theme(themeFolder = "basetheme"). The structure of the theme is as follows

enter image description here

I also added dependencies to the pom.xml file. This way everything works great.

When I create my custom BaseTheme class, then my styles from the custom theme and the standard styles from the lumo theme are not imported.

public class BaseTheme implements AbstractTheme
{

 @Override
    public String getBaseUrl()
    {
        return "/src/";
    }

    @Override
    public String getThemeUrl()
    {
        return "/themes/basetheme/";
    }
 }

What needs to be changed or added to make the custom theme work with a custom class?

Upvotes: 2

Views: 424

Answers (1)

Oliver
Oliver

Reputation: 1645

I had the same issue when I wrote my first theme.

Add a theme.json file to your basetheme folder. The documentation for this can be found here, but is lacking and doesn't discuss the following:

If you want your theme to include Lumo styles, you have to list them in lumoImports. E.g.,

{
  "lumoImports": [
    "badge",
    "color",
    "sizing",
    "spacing",
    "style,
    "typography"
    ...
  ]
}

You can see how lumoImports's value is used theme-generator.js.

const lumoImports = themeProperties.lumoImports || ["color", "typography"];
if (lumoImports && lumoImports.length > 0) {
  lumoImports.forEach((lumoImport) => {
    imports.push(`import '@vaadin/vaadin-lumo-styles/${lumoImport}.js';\n`);
  });

  lumoCssCode.push(`// Lumo styles are injected into shadow roots.\n`)
  lumoCssCode.push(`// For the document, we need to be compatible with flow-generated-imports and add missing <style> tags.\n`)
  lumoCssCode.push(`const shadowRoot = (target instanceof ShadowRoot);\n`)
  lumoCssCode.push(`if (shadowRoot) {\n`);
  lumoImports.forEach((lumoImport) => {
    lumoCssCode.push(`injectGlobalCss(getStyleModule("lumo-${lumoImport}"), target, true);\n`);
  });

  lumoCssCode.push(`} else if (!document['${lumoCssFlag}']) {\n`);
  lumoImports.forEach((lumoImport) => {
    lumoCssCode.push(`addStyleInclude("lumo-${lumoImport}", target);\n`);
  });
  lumoCssCode.push(`document['${lumoCssFlag}'] = true;\n`);
  lumoCssCode.push(`}\n`);
}

The strings in lumoImports are matched literally to the JavaScript files in the root directory of the vaadin-lumo-styles package. See more here.

By the way, theme-generator.js is what's creating basetheme.generated.js in your basetheme directory. You can check to make sure adding lumoImports worked by looking at this file. The end of the file should look something like this:

  const shadowRoot = (target instanceof ShadowRoot);
  if(shadowRoot) {
    injectGlobalCss(getStyleModule("lumo-badge"), target, true);
    injectGlobalCss(getStyleModule("lumo-color"), target, true);
    injectGlobalCss(getStyleModule("lumo-sizing"), target, true);
    injectGlobalCss(getStyleModule("lumo-spacing"), target, true);
    injectGlobalCss(getStyleModule("lumo-style"), target, true);
    injectGlobalCss(getStyleModule("lumo-typography"), target, true);
  } else if(!document['_vaadinthemelumoimports_']) {
    addStyleInclude("lumo-badge", target);
    addStyleInclude("lumo-color", target);
    addStyleInclude("lumo-sizing", target);
    addStyleInclude("lumo-spacing", target);
    addStyleInclude("lumo-style", target);
    addStyleInclude("lumo-typography", target);
    document['_vaadinthemelumoimports_'] = true;
  }

}

Also, on the topic of those generated files, make sure it is not packaged with your build. See more here.

Upvotes: 3

Related Questions