Композитный компонент
Композитный компонент — это компонент, состоящий из других компонентов. Как и фрагменты, композитные компоненты позволяют повторно использовать элементы компоновки и логику экранов.
Композитные компоненты рекомендуется использовать в следующих случаях:
- 
Функциональность компонента может быть реализована как комбинация существующих визуальных компонентов. 
 Если вам нужны какие-либо нестандартные функции, интегрируйте библиотеку JavaScript или создайте веб-компонент с нуля.
- 
Компонент относительно прост и не загружает и не сохраняет данные самостоятельно. В противном случае рассмотрите возможность создания фрагмента. 
Использование Composite
В приведенном ниже примере компонент ColorComponent создается путем комбинирования компонента ColorPicker, созданного в разделе Использование Element API, и компонента span, который отображает его значение:
import com.vaadin.flow.component.Composite;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
public class ColorComponent extends Composite<HorizontalLayout> { (1)
    private final ColorPicker colorPicker;
    public ColorComponent() {
        colorPicker = new ColorPicker();
        Span valueLabel = new Span(colorPicker.getValue());
        colorPicker.addValueChangeListener(event ->
                valueLabel.setText(event.getValue()));
        getContent().add(colorPicker, valueLabel); (2)
    }
    @Override
    protected HorizontalLayout initContent() { (3)
        HorizontalLayout content = super.initContent();
        content.setAlignItems(FlexComponent.Alignment.CENTER);
        return content;
    }
    public String getValue() { (4)
        return colorPicker.getValue();
    }
    public void setValue(String value) {
        colorPicker.setValue(value);
    }
}| 1 | Базовый класс Compositeпараметризован типом корневого компонента. | 
| 2 | Доступ к корневому компоненту можно получить, используя метод getContent(). | 
| 3 | Метод initContent()вызывается, когда содержимое композитного компонента запрашивается в первый раз. Этот метод должен инициализировать структуру компонента дляCompositeи вернуть корневой компонент. По умолчанию этот метод использует рефлексию для создания экземпляра компонента на основе generic-типа подкласса. | 
| 4 | Публичный API композитного компонента, который делегирует вызовы компоненту colorPicker. | 
 
Использование CustomField
CustomField — это базовый класс для обертывания нескольких компонентов в одно поле. Он предоставляет стандартные функции ввода, такие как надпись, подсказка и валидация. Используйте его для создания собственных компонентов ввода.
Предыдущий пример можно переписать как CustomField:
import com.vaadin.flow.component.customfield.CustomField;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.dom.Style;
public class ColorField extends CustomField<String> {
    private final ColorPicker colorPicker;
    public ColorField() {
        colorPicker = new ColorPicker();
        Span valueLabel = new Span(colorPicker.getValue());
        valueLabel.getStyle().setMarginInlineStart("var(--lumo-space-s)");
        colorPicker.addValueChangeListener(event -> {
            valueLabel.setText(event.getValue());
        });
        add(colorPicker, valueLabel);
    }
    @Override
    protected String generateModelValue() {
        return colorPicker.getValue();
    }
    @Override
    protected void setPresentationValue(String presentationValue) {
        colorPicker.setValue(presentationValue);
    }
}После реализации компонента его можно использовать в экранах, например:
@Subscribe
public void onInit(final InitEvent event) {
    ColorField customField = new ColorField();
    customField.setLabel("Color Field");
    customField.setHelperText("Helper text");
    getContent().add(customField);
}