Skip to content

Metadata Annotations

Any string attribute that accepts a label or title supports ${...} template expressions evaluated against the current component context. The available variables are:

VariableContains
stateThe component’s tracked state object
dataThe component’s data object
appStateThe application-level state
appDataThe application-level data

Supported locations: @Tab labels, @Section titles, subsection titles, field @Label values, accordion panel labels, button / toolbar button labels, CRUD titles and subtitles, column header labels (including group headers), filter bar active-filter badges, banner title/description, and KPI titles.

// Tab label that shows a field value
@Tab("${state.customerName} — Details")
String phone;
// Section title with state data
@Section("Room ${state.roomNumber}")
String roomType;
// Button label that reflects the current record
@Toolbar
@Label("Email ${state.guestName}")
Object sendEmail() { ... }

Labels without ${ are treated as plain strings and are never evaluated — there is no performance cost for the common case.


Target: FIELD, METHOD

Overrides the auto-generated label for a field or action. By default Mateu derives the label from the Java field name (e.g. dateOfBirth becomes “Date Of Birth”). Use @Label when you need a different wording.

public @interface Label {
String value();
}
public class CustomerForm {
@Label("Full name")
String name;
@Label("Date of birth")
LocalDate dob;
@Label("Save customer")
@Button
public void save() { ... }
}

Target: TYPE, FIELD, METHOD

Attaches a help text to a class, field, or action. Displayed as a tooltip or helper text below the component, depending on the frontend theme.

public @interface Help {
String value();
}
public class CustomerForm {
@Label("VAT number")
@Help("Enter the full VAT number including country prefix, e.g. ES12345678A")
String vatNumber;
}

Applied to a String field, these annotations render its value as an HTML heading of the corresponding level. Useful for adding section titles or dynamic headings inside a form.

public @interface H1 { String style() default ""; }
public @interface H2 { String style() default ""; }
public @interface H3 { String style() default ""; }
public @interface H4 { String style() default ""; }
public @interface H5 { String style() default ""; }
AttributeTypeDefaultDescription
styleString""Optional inline CSS applied to the heading element
public class ReportPage {
@H1
String title = "Annual Report";
@H2
String section = "Financial Summary";
@H3(style = "color: gray;")
String subsection = "Revenue";
}

Target: FIELD

Displays a String field as static text instead of an input field. The container attribute controls the HTML wrapper element.

public @interface Text {
TextContainer container() default TextContainer.p;
}
AttributeTypeDefaultDescription
containerTextContainerpHTML element used to wrap the text

TextContainer values: div, p, h1, h2, h3, h4, h5, h6, span

public class ConfirmationPage {
@Text
String message = "Your order has been placed successfully.";
@Text(container = TextContainer.span)
String note = "A confirmation email will be sent shortly.";
}

Applied at type level. See App Annotations for full documentation.

  • @Title — sets the visible heading rendered inside the page.
  • @Subtitle — sets a subtitle displayed below the title.

Target: FIELD, METHOD

Assigns an icon to an enum constant. When an enum field is rendered as a radio group or checkbox group, each option displays its icon next to the label.

Note: Icons on enum values do not appear in select or combobox controls due to a Vaadin limitation. They only work with radio and checkbox stereotypes.

public @interface Icon {
IconKey value();
}

Icons are specified using the IconKey enum from io.mateu.uidl.interfaces.IconKey, which maps named constants to Vaadin icon identifiers (e.g. IconKey.Male"vaadin:male").

import io.mateu.uidl.annotations.Icon;
import io.mateu.uidl.annotations.Label;
import io.mateu.uidl.interfaces.IconKey;
public enum Sex {
@Label("Male")
@Icon(IconKey.Male)
Male,
@Label("Female")
@Icon(IconKey.Female)
Female
}
public class PersonForm {
@Stereotype(FieldStereotype.radio)
Sex sex; // renders as a radio group with ♂/♀ icons next to each option
}

Target: FIELD

Renders an enum field as a coloured status badge instead of a plain text value. Each enum constant is mapped to a StatusType colour.

public @interface Status {
StatusMapping[] mappings();
StatusType defaultStatus();
}
public @interface StatusMapping {
String from(); // enum constant name as a String
StatusType to(); // badge colour
}

Status attributes:

AttributeTypeDescription
mappingsStatusMapping[]Array of enum-value-to-colour mappings
defaultStatusStatusTypeColour used when no mapping matches

StatusMapping attributes:

AttributeTypeDescription
fromStringThe enum constant name to match (case-sensitive)
toStatusTypeThe badge colour to display

StatusType values:

ValueBadge appearance
NONENo badge (plain text)
INFOBlue informational badge
SUCCESSGreen success badge
WARNINGYellow/orange warning badge
DANGERRed danger / error badge

From the Products demo:

enum ProductStatus {
Available, OutOfStock
}
record Product(
String id,
String name,
@NotNull
@Status(
defaultStatus = StatusType.NONE,
mappings = {
@StatusMapping(from = "Available", to = StatusType.SUCCESS),
@StatusMapping(from = "OutOfStock", to = StatusType.DANGER)
}
)
ProductStatus status
) implements Identifiable { ... }

The status field is displayed as a green “Available” badge or a red “OutOfStock” badge in both list and detail views.

From the status demo form:

enum ItemStatus {
Active, Inactive
}
@UI("/status-demo")
@Title("Status Demo")
public class StatusDemoForm {
@Status(
defaultStatus = StatusType.NONE,
mappings = {
@StatusMapping(from = "Active", to = StatusType.SUCCESS),
@StatusMapping(from = "Inactive", to = StatusType.DANGER)
}
)
ItemStatus status = ItemStatus.Active;
@Button
public Message activate() {
status = ItemStatus.Active;
return new Message("Activated!");
}
@Button
public Message deactivate() {
status = ItemStatus.Inactive;
return new Message("Deactivated!");
}
}