Search code examples
vaadin20vaadin-fusionhilla

Vaadin Fusion Styling of Sub-Components


How do I apply part styling to a nested Vaadin component? Vaadin components expose "parts" for styling in their published APIs.

Specifically, the vaadin-upload component hosts another component, vaadin-upload-file. I can style the main vaadin-upload component alright, but how do I reach the parts of the nested vaadin-upload-file component?

E.g. for the "name" part of vaadin-upload-file I unsuccessfully tried CSS selectors like

[part="name"]  { ... // plain, as if it were passed through
vaadin-upload-file[part="name"]  { ... // qualified with the component name
[part="file-list"][part="name"] { ... // qualified by the part of vaadin-upload that hosts the file list
:host([part="file-list"]) [part="name"] { ... // same with :host() selector

This is all in the style of the component that deploys vaadin-upload.


Solution

  • As the answer made its way to me on a different path, here is the solution for SO:

    You can only apply styles to Vaadin components and their sub-components using a custom theme.

    Here is a slightly extended way to set this up using a parent theme.

    • Create a local custom theme in your app
      • path is frontend/themes/<my-theme-name>/
      • must contain a sub-directory components (to style Vaadin components)
      • must contain a styles.css (even empty)
      • must contain a theme.json with contents
        {
           "parent": "<my-parent-theme>"
        }
        
        but there are other keys for theme.json like importCss, documentCss or assets
      • the parent theme can be a pom dependency
    • Use the custom theme in your Application.java:
      @Theme(value = "<my-theme-name>")
      public class Application extends SpringBootServletInitializer ...
      
    • Then you can add style files locally to style Vaadin components, e.g.
      • add frontend/themes/<my-theme-name>/components/vaadin-upload.css:
        [part=file-list]::before {
          content: "These are the current files:";
        }
        
      • frontend/themes/<my-theme-name>/components/vaadin-upload-file.css:
        [part=name] {
          background-color: yellow;
        }
        

    This applies to Vaadin21 (e.g. in Vaadin19 using a parent theme is not working this way).