Skip to content

Field Type Annotations

These annotations control how individual fields are rendered and what input widget is used in edit mode.


Target: FIELD

Sets the input widget type for a field. Mateu infers a default stereotype from the Java type (e.g. String → text input, boolean → checkbox), but @Stereotype overrides that inference.

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Stereotype {
FieldStereotype value();
}
AttributeTypeDescription
valueFieldStereotypeThe widget stereotype to apply
ValueDescription
regularDefault text input
radioRadio button group
checkboxCheckbox input
textareaMulti-line text area
toggleToggle switch
comboboxCombo box (typed input with dropdown)
selectDropdown select
emailEmail input
passwordPassword input (masked)
richTextRich text / WYSIWYG editor
listBoxList box (scrollable options)
htmlRaw HTML display
markdownMarkdown editor / renderer
imageImage display (<img> from a URL / data-URI value)
uploadableImageImage preview + upload (replace) + delete actions — see @UploadableImage
signatureDrawing canvas that stores the accepted strokes as a PNG data URI — see @Signature
cameraDevice camera with live preview; the shot lands as a JPEG data URI — see @PhotoCapture
treeSelectA select whose dropdown unfolds a TREE of options — see @TreeSelect
iconIcon picker
linkHyperlink
moneyCurrency amount
gridEmbedded data grid
colorColor picker
choiceChoice selector
popoverPopover trigger
sliderRange slider
buttonButton
starsStar rating

From the Products demo:

@Stereotype(FieldStereotype.textarea)
@HiddenInList
String description;

Field stereotypes — email, password, textarea, toggle, radio and slider


No attributes. Shorthand for @Stereotype(FieldStereotype.radio). Renders an enum or options field as a radio button group instead of a dropdown.

public @interface UseRadioButtons {}
public class OrderForm {
@UseRadioButtons
DeliveryMethod delivery;
}

Target: FIELD

No attributes. Shorthand for @Stereotype(FieldStereotype.uploadableImage). Renders a String field as an uploadable image: the image preview combined with an Upload (or Replace) action and a Delete action.

public @interface UploadableImage {}

The picked file is read client-side into a data URI (base64) and stored as the field value, so the image travels in the string itself — no upload endpoint is required. The value may also be a plain image URL. Delete clears the value; pressing your form’s action round-trips the value (the data URI or URL) to the backend like any other string.

@UI("/profile")
public class Profile {
String name;
@UploadableImage
@Label("Avatar")
String avatar; // null/empty → "upload" placeholder; a data-URI/URL → preview + replace + delete
@Toolbar
Object save() {
return Message.success("Saved");
}
}

In read-only mode the field shows just the image (same as @Stereotype(FieldStereotype.image)).


Target: FIELD

Renders a String field as a signature capture: a drawing canvas (mouse or touch) with Clear and Accept. Accepting stores the strokes as a PNG data URI in the field value — the same self-contained contract as @UploadableImage, no upload endpoint involved. An existing value shows as the signature image with Sign again / Delete actions, and the read-only rendering shows the image.

@Signature
@Label("Firma del huésped")
String signature;

Target: FIELD

Renders a String field as a photo capture: opens the device camera (getUserMedia) with a live preview and a shutter; the shot is stored as a JPEG data URI in the field value. When the camera is unavailable (no device, permission denied, insecure context) the widget offers a file input with capture, which on phones opens the native camera. Same self-contained round-trip as @UploadableImage.

@PhotoCapture
@Label("Foto del documento")
String documentPhoto;

Target: FIELD

Sets the minimum value for a slider field. Used together with @Stereotype(FieldStereotype.slider) and @SliderMax.

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SliderMin {
int value();
}
AttributeTypeDescription
valueintMinimum value of the slider range

Target: FIELD

Sets the maximum value for a slider field. Used together with @Stereotype(FieldStereotype.slider) and @SliderMin.

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SliderMax {
int value();
}
AttributeTypeDescription
valueintMaximum value of the slider range
@Stereotype(FieldStereotype.slider)
@SliderMin(0)
@SliderMax(100)
int progress;

A field of type io.mateu.uidl.data.File[] is automatically rendered as an upload widget — no annotation needed. Mateu infers dataType = file from the field type.

import io.mateu.uidl.data.File;
public class ContractForm {
File[] documents; // → upload widget, stores { id, name } per file
@Button
Object save() {
for (File f : documents) {
persist(f.id(), f.name());
}
return Message.success("Saved");
}
}

The upload widget POSTs each file to the fixed path POST /upload. Your application must expose that endpoint; it must return the file identifier as plain text. See File Upload for the full guide including Spring Boot, Micronaut, and Quarkus examples.


Target: FIELD

Marks a field so the UI renders a “Search” button next to it. Clicking the button opens a modal containing the class referenced by selector() — typically a Listing that also implements Selector. When the user picks a row the modal closes and the field is populated with the selected id; the label() supplier provides the human-readable display text.

Use @Searchable instead of @Lookup when the selection screen needs filters, sortable columns, row actions, or even CRUD capabilities — anything more complex than a simple dropdown.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Searchable {
Class<? extends Selector> selector() default Selector.class;
Class<? extends LabelSupplier> label() default LabelSupplier.class;
boolean bubble() default false;
boolean editableCode() default false;
boolean showCode() default false;
}
AttributeTypeDefaultDescription
selectorClass<? extends Selector>Selector.classScreen opened in the modal. Must implement Selector<IdType>. Typically also extends Listing.
labelClass<? extends LabelSupplier>LabelSupplier.classResolves the display text for a stored id.
bubblebooleanfalsePropagates the selection event to the parent component.
editableCodebooleanfalseAllows the user to type the code/id directly in the field.
showCodebooleanfalseShows the raw id alongside the resolved label.

The selector class must:

  1. Implement Selector<IdType>selected() is called when the user clicks a row and must return a SelectedItem containing the id and a label.
  2. Optionally implement LabelSupplier — resolves a stored id back to its display text (reused in label()).
  3. Typically extend Listing<Filters, Row> to get a full filterable, pageable table inside the modal.
@Trigger(type = TriggerType.OnLoad, actionId = "search")
@Style("min-width: 40rem;")
public class HotelSelector extends Listing<Filters, Row>
implements Selector<String>, LabelSupplier {
String _fieldId; // injected by the framework
@Override
public ListingData<Row> search(String searchText, Filters filters,
Pageable pageable, HttpRequest httpRequest) {
return ListingData.of(
rows.stream()
.filter(r -> r.name().contains(searchText))
.toList()
);
}
@Override
public SelectedItem<String> selected(HttpRequest httpRequest) {
Row row = httpRequest.getClickedRow(rowClass());
return new SelectedItem<>(row.id(), row.name());
}
@Override
public String label(String fieldName, Object id, HttpRequest httpRequest) {
return rows.stream()
.filter(r -> r.id().equals(id))
.findFirst().orElseThrow().name();
}
}
public class BookingForm {
@Searchable(selector = HotelSelector.class, label = HotelSelector.class)
@NotEmpty
String hotelId;
@Button
Object save() {
return Message.success("Saved " + hotelId);
}
}
@Lookup@Searchable
UI widgetIncremental-search dropdown (inline)Text display + “Search” button → modal
Selector classLookupOptionsSupplier (list of Option)Listing + Selector (full screen)
Suitable forSimple option lists, fast lookupsComplex grids with filters, actions, or CRUD