The core Material package defines the basic building blocks for component themes as CSS custom properties, also known as design tokens, such as colors, typography and other visual styles.
Getting Started
The Material theme comes bundled with Vaadin, including all individual components.
If you need, you can also install the core Material package separately from npm.
Source code
terminal
npm i @vaadin/vaadin-material-styles
Import and Include Style Sheets
The global style sheets, which define the global custom properties (a.k.a. design tokens) and define basic color and typography rules, are automatically included in your Vaadin application when you are using Material as your theme.
You can import and include these style sheets manually if needed, for example if you are building a client-side only application.
In server-side views (Java), use the @Theme annotation, as described in Using Themes.
Source code
UsingComponentThemes.java
/*
* Copyright 2000-2017 Vaadin Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.vaadin.flow.tutorial.theme;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.textfield.TextFieldVariant;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouterLayout;
import com.vaadin.flow.theme.AbstractTheme;
import com.vaadin.flow.theme.NoTheme;
import com.vaadin.flow.theme.Theme;
import com.vaadin.flow.theme.lumo.Lumo;
import com.vaadin.flow.theme.material.Material;
import com.vaadin.flow.tutorial.annotations.CodeFor;
@CodeFor("../documentation-themes/theme-variants.asciidoc")
public class UsingComponentThemes {
@Route(value = "")
public class DefaultLumoApplication extends Div {
}
@Route(value = "")
@Theme(value = Lumo.class)
public class LumoApplication extends Div {
}
@Route(value = "")
@Theme(value = Material.class)
public class MaterialApplication extends Div {
}
//
@Route(value = "")
@Theme(MyTheme.class)
public class MyApplication extends Div {
}
@Theme(MyTheme.class)
public class MainLayout extends Div
implements RouterLayout {
}
@Route(value = "", layout = MainLayout.class)
public class HomeView extends Div {
}
@Route(value = "blog", layout = MainLayout.class)
public class BlogPost extends Div {
}
@Route(value = "")
@NoTheme
public class UnThemedApplication extends Div {
}
@Route(value = "")
@Theme(value = MyTheme.class, variant = "large")
public class LargeThemedApplication extends Div {
}
@Route(value = "")
@Theme(value = Lumo.class, variant = Lumo.DARK)
public class DarkApplication extends Div {
}
@Route(value = "")
@Theme(value = Material.class, variant = Material.DARK)
public class DarkMaterialApplication extends Div {
}
public class Button extends Component {
public Button(String string) {
}
public void addThemeVariants(ButtonVariant... vars) {
}
public List<String> getThemeNames() {
return null;
}
}
{
// Using the high-level HasTheme API
Button button = new Button("Themed button");
button.addThemeVariants(ButtonVariant.LUMO_PRIMARY,
ButtonVariant.LUMO_SMALL);
}
{
Button button = new Button("Themed button");
button.getThemeNames().addAll(Arrays.asList("primary", "small"));
}
{
// Using the low-level Element API
Button button = new Button("Themed button");
String themeAttributeName = "theme";
String oldValue = button.getElement().getAttribute(themeAttributeName);
String variantsToAdd = "primary small";
button.getElement().setAttribute(themeAttributeName,
oldValue == null || oldValue.isEmpty() ?
variantsToAdd
: ' ' + variantsToAdd);
}
{
ComboBox comboBox = new ComboBox();
comboBox.getElement().setAttribute("theme", TextFieldVariant.LUMO_SMALL.getVariantName());
}
@JsModule("@vaadin/vaadin-lumo-styles/presets/compact.js")
@Theme(Lumo.class)
public class CompactMainLayout extends Div implements RouterLayout {
}
@JsModule("@vaadin/vaadin-lumo-styles/color.js")
public class MyTheme implements AbstractTheme {
@Override
public String getBaseUrl() {
return "/src/";
}
@Override
public String getThemeUrl() {
return "/theme/myTheme/";
}
}
}
Material.js
// tutorial::../documentation-themes/lumo/overview.asciidoc
// Import the main style sheets which set all the
// global custom properties
import '@vaadin/vaadin-material-styles/color.js';
import '@vaadin/vaadin-material-styles/typography.js';
// Import the <custom-style> element from Polymer and include
// the style sheets in the global scope
import '@polymer/polymer/lib/elements/custom-style.js';
const style = document.createElement('custom-style');
style.innerHTML = `<style include="material-color material-typography"></style>`;
document.head.appendChild(style);
Customization
The Material theme can be customized to fit your visual style requirements by adjusting the CSS Custom Properties it exposes as its public API.
The custom properties are documented in the following sections: