I have a CustomField like in the first example in https://vaadin.com/docs/latest/components/custom-field
I’d like to use it in different places with different labels without react/lit, just by calling myCustomField.setLabel("myLabel");
but the label does not appear.
Of course I can propagate the label to the content of the CustomField, but since I have several items in the CustomField (like in the example), the label is only as wide as the first item.
Hmm - I reduced my component to the bare minimum and found the “problem”:
If I tag my component with @Tag(“div”) then setLabel() does not work.
I could reproduce that as well for the simple last example on that page:
@Tag("div")
public class MoneyField extends CustomField<Money> {
private TextField amount;
private Select<String> currency;
public MoneyField(String label) {
this();
setLabel(label);
}
public MoneyField() {
amount = new TextField();
// Sets title for screen readers
amount.setAriaLabel("Amount");
currency = new Select<>();
currency.setItems("AUD", "CAD", "CHF", "EUR", "GBP", "JPY", "USD");
currency.setWidth("6em");
currency.setAriaLabel("Currency");
HorizontalLayout layout = new HorizontalLayout(amount, currency);
// Removes default spacing
layout.setSpacing(false);
// Adds small amount of space between the components
layout.getThemeList().add("spacing-s");
add(layout);
}
public void addThemeVariant(CustomFieldVariant variant) {
super.addThemeVariants(variant);
amount.addThemeVariants(TextFieldVariant.valueOf(variant.name()));
currency.addThemeVariants(SelectVariant.valueOf(variant.name()));
}
@Override
protected Money generateModelValue() {
return new Money(amount.getValue(), currency.getValue());
}
@Override
protected void setPresentationValue(Money money) {
amount.setValue(money.getAmount());
currency.setValue(money.getCurrency());
}
}
setLabel() then does not work unless I remove the @Tag(“div”)
no it’s a misunderstanding of your usage of the API. If you overwrite vaadin-custom-field with div you have to manage the label yourself. How should a div know about the label slot?
I think the confusion stems from the fact that you can use the @Tag annotation to define what html element a generic custom Flow component should be based on.
So to clear that up:
A generic custom Flow component with @Tag(“div”) means: this is a custom Flow-based component that’s really just a <div> (and whatever I put inside it) on the client side. Since it’s just a container for whatever you put inside, without any parts or functionality of its own, it can be literally any html element.
CustomField is an actual Vaadin component with its own client side implementation in the form of a custom html element vaadin-custom-field. The label is part of the client-side implementation of that element. If you replace that custom html element with @Tag("div"), there is no label, because <div> has no such thing.