Flow: Add a way to set dark theme

Created on 8 Mar 2018  路  4Comments  路  Source: vaadin/flow

I want to be able to set the dark theme variant for my entire application. Setting the theme attribute on the main layout doesn't change the body background color.

enhancement theming tutorial

Most helpful comment

Current way of using the dark variant:

@Theme(Lumo.class)
public class RootLayout extends Div implements PageConfigurator, RouterLayout {

    @Override
    public void configurePage(InitialPageSettings settings) {
        settings.getUi().getElement().setAttribute("theme", "dark");
    }
    ...
}

I think we should #ffs this to make it even easier, a proposal:

@Theme(Lumo.class, variant = Lumo.DARK)
public class RootLayout extends Div implements RouterLayout {
}

Here variant would be a just a String with an empty default, and the bootstrapping process automatically maps any value as the theme attribute for the body element (I presume it doesn't ever have to go to the html element).

If there would be more complex variants, there could be another parameter, like variantClass where anyone can give a class type of the variant that gets eg. InitialPageSettings as the parameter and can just do additional customizations dynamically. One use case for having this could be that the generation of the theme variant is based on preferences the user has saved. But, for now, the PageConfigurator can be used for that, and I think just applying the attribute should be fine.

All 4 comments

Current way of using the dark variant:

@Theme(Lumo.class)
public class RootLayout extends Div implements PageConfigurator, RouterLayout {

    @Override
    public void configurePage(InitialPageSettings settings) {
        settings.getUi().getElement().setAttribute("theme", "dark");
    }
    ...
}

I think we should #ffs this to make it even easier, a proposal:

@Theme(Lumo.class, variant = Lumo.DARK)
public class RootLayout extends Div implements RouterLayout {
}

Here variant would be a just a String with an empty default, and the bootstrapping process automatically maps any value as the theme attribute for the body element (I presume it doesn't ever have to go to the html element).

If there would be more complex variants, there could be another parameter, like variantClass where anyone can give a class type of the variant that gets eg. InitialPageSettings as the parameter and can just do additional customizations dynamically. One use case for having this could be that the generation of the theme variant is based on preferences the user has saved. But, for now, the PageConfigurator can be used for that, and I think just applying the attribute should be fine.

Another alternative would be a meta annotation approach, allowing each theme do define their own annotation that can have any strongly typed parameters. In that case, the application code could be

@Lumo(variant = LumoVariant.DARK)
public class RootLayout extends Div implements RouterLayout {
}

where LumoVariant is an enum.

We could also see dark Lumo as a theme of its own, e.g. either @Theme(LumoDark.class) or alternatively with the meta annotation approach simply @LumoDark.

The problem with the current workaround that @pleku suggested above is that it runs too late and results in the light variant being shown first, and then a flash as the theme variant changes.

Whichever alternative we go with needs to send the variant info with the initial server response so we avoid flashing.

Decided to go for:

@Theme(Lumo.class, variant = Lumo.DARK)
public class RootLayout extends Div implements RouterLayout {
}

Here variant would be a just a String with an empty default, and the bootstrapping process automatically maps any value as the theme attribute for the body element (I presume it doesn't ever have to go to the html element).

We should update the documentation for using component themes about the variant usage. Also update the disclaimer that you cannot mix different variants together.
https://vaadin.com/docs/v10/flow/theme/using-component-themes.html

Was this page helpful?
0 / 5 - 0 ratings