Components in Vaadin platform

Component Set

While all the components have been rebuilt based on Web Components, there are some components that don’t yet have a replacement with server side Java API. The ones that have, might have gone through some changes. Some older features might have been removed.

The following table lists the existing Vaadin 8 components and their direct replacements in the Vaadin platform. Note that the replacement component might not have 1-1 feature parity. If no replacement is yet available, current plans or options for replacement is mentioned.

Table 1. Comparison Matrix
V8Vaadin platformDetails

AbsoluteLayout

-

Not planned. Similar functionality in Vaadin platform can be achieved using eg. <div> elements and CSS positioning.

Accordion

-

Not planned. Available as a web component (an example).

Audio

-

Not planned. Use the native <audio> element.

Button

Button

Demo

BrowserFrame

-

Use iframe directly via @Tag("iframe") and Element API

Checkbox

Checkbox

Demo

CheckBoxGroup

CheckBoxGroup (V12)

Not in V10, take vaadin-radio-button-flow 1.1. Included in Vaadin platform 12 (12/2018). Also available as an add-on in Directory for Vaadin platform

ColorPicker

-

Not planned. See vaadin.com/directory for alternatives. <input type="color"> is supported in some browsers.

ComboBox

ComboBox

Demo. Note that lazy-loading between server and client was only included in Vaadin platform V12 (12/2018).

ContextMenu (official add-on)

ContextMenu (V12)

Not in V10, take vaadin-context-menu-flow 1.0 which is Vaadin platform compatible. Included in Vaadin platform V12 (12/2018)

CssLayout

Div & FlexLayout

More details later in this chapter

CustomComponent

Composite

Tutorial

CustomLayout

HTML or PolymerTemplate

See notes below.

DateField

DatePicker

Demo

DateTimeField

DatePicker (V10) & TimePicker (V12)

Planned for 2019. Possible by combining DatePicker and TimePicker. <input type="datetime"> is supported in some browsers.

Embedded

-

Use <object> directly via @Tag("object") and Element API

FormLayout

FormLayout

Demo

Grid

Grid

Demo, Tutorial

GridLayout

-

Not planned. See detailed notes about replacement alternatives below.

HorizontalLayout

HorizontalLayout

Demo, more details later in this chapter

HorizontalSplitPanel

SplitLayout

Demo

Image

Image

-

InlineDateField

-

No inline option of DatePicker available nor planned

InlineDateTimeField

-

Not planned

Label

Text or Span

There is also a Label component based on the <label> element, and should therefore only be used for form field labels.

Link

Anchor

-

ListSelect

ListBox

Demo

LoginForm

Login

In development, see GitHub project

MenuBar

-

Planned for Vaadin 14. Can be made currently by combining Select (V12) and ContextMenu (V12)

NativeButton

NativeButton

-

NativeSelect

-

Planned, by new component Select. Timeline is Q4 2018. As a temporary workaround, low level element API can be used with <select> element.

Notification

Notification

Demo

Panel

-

Planned with vaadin-card web component H1 2019. Also, it’s possible to make any component scrollable with component.getElement().getStyle().set("overflow", "auto")

PasswordField

PasswordField

Demo

PopupView

-

Planned for 2019. Can be made by combining Button and ContextMenu (V12).

ProgressBar

ProgressBar

Demo

RadioButtonGroup

RadioButtonGroup

Demo

RichTextArea

-

Planned for Vaadin 13.

Slider

-

Not planned. There are Web Components available, check vaadin.com/directory. You can also use DOM API and <input type=”range”>

TabSheet

Tabs

Demo

TextArea

TextArea

Demo

TextField

TextField

Demo

Tree

-

Planned for H1 2019

TreeGrid

TreeGrid (V12)

Not in V10, vaadin-grid-flow 1.1.0 (or newer) is V10 compatible. Included in Vaadin 12 (12/2018)

TwinColSelect

-

Not planned. Can be built as a composite using ListBox and Button.

Video

-

Not planned. Can directly use the native <video> element.

VerticalLayout

VerticalLayout

Demo, more details later in this chapter

VerticalSplitPanel

SplitLayout

Demo

UI

UI

-

Upload

Upload

Demo

Window

Dialog

Demo Note that there is only limited support due to missing eg. minimize / maximize feature.

For any missing components, you should first look for alternatives in vaadin.com/directory. It shows both Vaadin platform add-ons with Java API and web components that can be integrated to Java.

For the components that are available in Vaadin platform, you can browse vaadin.com/components/browse for features and examples.

Basic Component Features

The way components are structured has been renewed in Vaadin platform. While the basics stay the same, backwards compatibility has been discarded in favor of optimizing for current and future usage.

In Vaadin 8, there was a large and complex class hierarchy for components, and the Component interface already declared a large set of API that components were supposed to support. This meant that almost every time, the component had to extend at least AbstractComponent so that they would not need to implement all the methods from the interface. That would mean that there would be a lot of API in the actual component, some of which made no sense in all cases.

In Vaadin Flow the Component is an abstract class, with only the minimal set of API exposed. For the component implementations, it is up to them to pick up pieces of API as mixin interfaces that provide default implementations.

Component is Lightweight and it Maps to an Element

Every Vaadin Flow component always maps to one root element in the server-side DOM representation. A component can contain multiple components or elements inside it. The component is the high level API for application developers to compose UIs efficiently. The Element API is the low level API used to build components. The Element API makes it possible to modify the DOM easily from the server side.

If you look up the Component class in Vaadin Flow, you notice that there is no API even for setting the width or height of the component! For your own components, add the API by implementing the HasSize mixin interface, which has default implementations for e.g. setWidth(String width) and setHeight(String height). So by adding two words of code you can achieve full sizing capabilities for your components. See the Creating A Simple Component Using the Element API tutorial for more info.

All Components Don’t Have Captions or Icons

In Vaadin 8 every component had a caption. The caption was usually shown next to the component, based on the parent layout’s caption handling implementation. The caption could optionally be rendered with an icon. Some layouts didn’t support showing captions and/or icons.

In Vaadin platform there is no universal caption concept anymore. Some components might have a similar feature, but that it is always component specific. Usually that API is setLabel(String label) instead of setCaption. Some layouts, such as FormLayout, also support showing a label text or component for each child component.

In other cases, you can create your own Span or Text component to contain the caption text and add it to the parent layout alongside the component.

Adding icons is possible, it is just HTML5 after all. But as with caption there is no universal support for that.

setEnabled(boolean enabled) is Still a Server Side Security Feature

In Vaadin Flow, the setEnabled method is specific to components marked with the HasEnabled mixin interface (which comes also with HasValue, HasComponents, and Focusable). When a component is disabled, by default, any property changes and DOM events coming from the client side are ignored. However, it is possible to whitelist some properties and events to be allowed if necessary.

The disabled state is automatically cascaded to child components it is up to the component to change the disabled UX to mark the component as "not-working" when it has been disabled. Changes from the client are still always blocked for disabled components even if the component isn’t implemented to appear disabled. All relevant Vaadin components change their looks when disabled.

Read the Component Enabled State tutorial for more details.

setReadOnly(boolean readOnly) is Component Specific and Works Differently

In Flow the setReadOnly(boolean readOnly) method is specific to components accepting user input by implementing HasValue.

For a readonly component, changes from the client will not make the return value of getValue() to change nor fire any ValueChangeEvent. Most components will also update their visual status to indicate to the user that the value cannot be changed.

Tooltips are Component Specific

In Vaadin 8 the framework made it possible to show a tooltip for any component if the user hovered the mouse on top of the component. In Vaadin platform there is no automatic way for this; it is a component specific feature and possible using CSS.

Layouts in Vaadin platform

In Vaadin 8 the layouting of components was managed by a LayoutManager on the client engine. This has its roots in a time when the differences between browsers were big, and the Framework still supported Internet Explorer versions that worked by their own rules. Creating your own layouts was quite complex since it always required writing custom client side code with GWT.

In Vaadin platform, there is no more LayoutManager to do calculations in browser. All layouts are self-contained and mostly just rely on the HTML5 and CSS3 standards, which all modern browsers (as well as IE 11) support. Responsive layouts can be created now using the DOM API in Java on the server side.

As native browser features are used for rendering, layouts are rendered faster than in previous versions.

Core Layouts API and Creating Custom Layouts

In Vaadin platform you can create a custom layout with only server side Java code by using mixin-interfaces and the Element API. The mixin-interfaces are also the basis for the core layouts and replace a complex class hierarchy from Vaadin 8:

  • HasComponents for simply adding components to the parent’s root Element with:

    • add(Component…​ component)

    • remove(Component…​ component) & removeAll()

  • HasOrderedComponents for accessing components based on index

All the core layouts except FlexLayout & Div are based on Web Components, but they still give a good example on how to create your own layouts if needed. For Element API usage, please see the Creating a Component Which Can Contain Other Components tutorial.

Layout Click Listeners

There is currently no direct API exposed for this in the layouts. But if you want to, you can access the element and add a DOM event listener to it for click events. If this is a much requested API, we could make it a standard feature to the layouts. There is an enhancement issue for this.

Available Layouts in Vaadin platform

HorizontalLayout & VerticalLayout

These layouts have made it easy to compose UIs. For Vaadin platform they are now based on fast native CSS rendering in browsers, instead of custom JavaScript calculations. This means that the API has been changed to match the underlying CSS concepts instead of custom names - this is also to highlight that it might not work exactly the same way as before:

  • setComponentAlignment & setDefaultComponentAlignement

    • HorizontalLayout: setVerticalComponentAlignment and setDefaultVerticalComponentAligment

    • VerticalLayout: setHorizontalComponentAlignment and setDefaultHorizontalComponentAligment

    • These map to the align-self and align-items CSS property values.

  • setExpandRatio is now setFlexGrow

  • expand() sets flex-grow to 1

  • setMargin is now setPadding

  • Spacing and Padding are only available as on/off for all edges of the layout, instead of separately for top/right/bottom/left. Fine-grained control is available using CSS, e.g. component.getElement().getStyle().set("padding-top", "20px")

  • Using setSizeFull(), setHeight("100%") or setWidth("100%") for any contained component will not have the same effect as before - it will cause the component to get the full size of the parent layout, instead of full size of the slot. Instead, leave the size undefined and flex-grow will take care of sizing the component.

For better understanding how to use the setFlexGrow() and expand() methods and how the flex layouts work, please see the Mozilla Foundation documentation on CSS flex.

FormLayout

FormLayout has been made responsive and it now supports multiple columns. Thus it also in some ways replaces the old GridLayout.

FlexLayout

This layout is a server side convenience API for using a <div> with display: flex and then setting the flexbox properties via Java. If you haven’t already, you should introduce yourself to flexbox. It will allow you to easily build more responsive layouts.

Div AKA CssLayout

The most powerful layout of Vaadin 8 in terms of customizability is the CssLayout, which is just a <div> element in the browser. This is now also available, but it is now named to what is actually is - a Div element in the browser.

The getCss method from V8 is not available, but in Vaadin platform you can easily modify the element CSS from the server side for any component using component.getElement().getStyle(). This works with any layout, not only Div.

Replacing Existing Layouts

In addition to the options listed below, you should also see if directory has add-ons available that can be used as a replacement.

AbsoluteLayout

AbsoluteLayout can be replaced with the Div component and then applying the CSS properties position: absolute and coordinates as top/right/bottom/left properties to the components added inside it using the Element API.

GridLayout

There is currently no direct replacement, but depending on your use case, you could replace the old GridLayout with either

  • Board which is commercial and fully responsive

  • FormLayout which now supports multiple columns

  • FlexLayout which is powerful but requires mastering the flexbox concepts

  • Nesting HorizontalLayout and VerticalLayout together

  • Use Div together with the new CSS Grid functionality that is supported in most browsers

CustomLayout

For replacing CustomLayout you can just use a Html container component for static content. For dynamic content you can use PolymerTemplate with @Id bindings.

Migrating Your Own Components

One of the biggest improvements in Vaadin Flow compared to Vaadin 8 is making it possible to access and customize the DOM from server-side Java. This obsoletes many reasons for using GWT for creating components. It also means that existing custom components from V8 have to be rebuilt again. The server side API can be reused, but some changes may be needed since the class hierarchy has changed in Flow.

Simple components can be composed using existing components and the Element API. The creating components tutorials have examples on this. For more complex components, with lots of client side logic or a complex DOM structure, it might be better to implement them as Web Components and provide a Java API to those.

Are you planning on migrating your application? Get help from Vaadin experts.

Open in a
new tab
export class RenderBanner extends HTMLElement {
  connectedCallback() {
    this.renderBanner();
  }

  renderBanner() {
    let bannerWrapper = document.getElementById('tocBanner');

    if (bannerWrapper) {
      return;
    }

    let tocEl = document.getElementById('toc');

    // Add an empty ToC div in case page doesn't have one.
    if (!tocEl) {
      const pageTitle = document.querySelector(
        'main > article > header[class^=PageHeader-module--pageHeader]'
      );
      tocEl = document.createElement('div');
      tocEl.classList.add('toc');

      pageTitle?.insertAdjacentElement('afterend', tocEl);
    }

    // Prepare banner container
    bannerWrapper = document.createElement('div');
    bannerWrapper.id = 'tocBanner';
    tocEl?.appendChild(bannerWrapper);

    // Banner elements
    const text = document.querySelector('.toc-banner-source-text')?.innerHTML;
    const link = document.querySelector('.toc-banner-source-link')?.textContent;

    const bannerHtml = `<div class='toc-banner'>
          <a href='${link}'>
            <div class="toc-banner--img"></div>
            <div class='toc-banner--content'>${text}</div>
          </a>
        </div>`;

    bannerWrapper.innerHTML = bannerHtml;

    // Add banner image
    const imgSource = document.querySelector('.toc-banner-source .image');
    const imgTarget = bannerWrapper.querySelector('.toc-banner--img');

    if (imgSource && imgTarget) {
      imgTarget.appendChild(imgSource);
    }
  }
}