Layout Annotations
These annotations are placed on a class or field to control how its content is arranged on screen — columns, tabs, accordion panels, split panes, and more.
@FormLayout
Section titled “@FormLayout”Renders the page fields in a responsive multi-column grid. This is the standard layout for data-entry forms.
@Retention(RetentionPolicy.RUNTIME)public @interface FormLayout { String theme() default ""; String style() default ""; int columns() default 2;}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
columns | int | 2 | Number of columns in the grid |
style | String | "" | Inline CSS applied to the layout container |
theme | String | "" | Theme variant string passed to the design system |
Example
Section titled “Example”@UI("/customers")@FormLayout(columns = 3)public class CustomerForm { String firstName; String lastName; String email; String phone; LocalDate birthDate;}@HorizontalLayout
Section titled “@HorizontalLayout”Renders the page content in a horizontal row.
public @interface HorizontalLayout { String theme() default ""; String style() default "";}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
theme | String | "" | Theme variant |
style | String | "" | Inline CSS |
Example
Section titled “Example”@UI("/summary")@HorizontalLayout(style = "gap: 1rem;")public class SummaryPage { Component salesChart; Component revenueChart;}@VerticalLayout
Section titled “@VerticalLayout”Renders the page content in a vertical column.
public @interface VerticalLayout { String theme() default ""; String style() default "";}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
theme | String | "" | Theme variant |
style | String | "" | Inline CSS |
Example
Section titled “Example”@UI("/profile")@VerticalLayoutpublic class ProfilePage { Component avatar; String bio;}Places on the class to wrap all fields in a tabbed container. Individual fields are assigned to tabs via @Tab.
public @interface Tabs { String theme() default ""; String direction() default ""; String style() default "";}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
theme | String | "" | Visual theme variant |
direction | String | "" | Tab strip direction — "horizontal" or "vertical" |
style | String | "" | Inline CSS for the tab container |
Assigns the annotated field or method to a named tab. Requires @Tabs on the enclosing class.
Target: FIELD, METHOD
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD, ElementType.METHOD})public @interface Tab { String value() default ""; int order() default 0;}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
value | String | "" | Tab label |
order | int | 0 | Display order among tabs |
Example
Section titled “Example”@UI("/account")@Tabspublic class AccountPage { @Tab("Profile") String firstName; String lastName;
@Tab("Security") String password; boolean mfaEnabled;
@Tab("Preferences") String language; String timezone;}Each @Tab annotation starts a new tab. Fields without @Tab fall into a default tab.
@Accordion
Section titled “@Accordion”Places on the class to render all fields inside a collapsible accordion. Individual panels are configured with @AccordionPanel.
public @interface Accordion { String style() default ""; int opened() default 0;}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
style | String | "" | Inline CSS for the accordion container |
opened | int | 0 | Zero-based index of the initially expanded panel |
@AccordionPanel
Section titled “@AccordionPanel”Assigns the annotated field to a named accordion panel. Requires @Accordion on the enclosing class.
public @interface AccordionPanel { String theme() default ""; String style() default ""; String summary() default ""; boolean disabled() default false;}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
summary | String | "" | Panel header text shown in collapsed state |
theme | String | "" | Visual theme variant |
style | String | "" | Inline CSS for this panel |
disabled | boolean | false | Whether this panel is non-interactive |
Example
Section titled “Example”@UI("/settings")@Accordion(opened = 0)public class SettingsPage { @AccordionPanel(summary = "General") String language; String timezone;
@AccordionPanel(summary = "Notifications") boolean emailNotifications; boolean smsNotifications;}@SplitLayout
Section titled “@SplitLayout”Renders the page as a two-panel layout with a resizable divider. The first field becomes the primary panel and the second becomes the secondary panel.
public @interface SplitLayout { String theme() default ""; String style() default "";}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
theme | String | "" | Theme variant |
style | String | "" | Inline CSS |
Example
Section titled “Example”@UI("/orders")@SplitLayoutpublic class OrdersPage { Component orderList; Component orderDetail;}@MasterDetail
Section titled “@MasterDetail”Target: FIELD
Renders the annotated field as a master-detail layout. When a row in the master list is selected, the detail panel appears beside it. The minHeightWhenDetailVisible value sets the minimum height of the component while the detail panel is open.
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD})public @interface MasterDetail { String minHeightWhenDetailVisible();}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
minHeightWhenDetailVisible | String | — | CSS minimum height when the detail panel is open (e.g. "400px") |
Example
Section titled “Example”public class OrdersPage { @MasterDetail(minHeightWhenDetailVisible = "500px") List<OrderRow> orders;}@Section
Section titled “@Section”Target: FIELD, METHOD
Groups the annotated field and all following fields under a named section heading within a form. The section ends at the next @Section annotation.
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD, ElementType.METHOD})public @interface Section { String value(); int columns() default 1; String style() default "";}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
value | String | — | Section heading label (required) |
columns | int | 1 | Number of columns inside this section |
style | String | "" | Inline CSS for the section container |
Example
Section titled “Example”public class CustomerForm { @Section("Personal data") String firstName; String lastName; LocalDate birthDate;
@Section(value = "Contact", columns = 2) String email; String phone; String address;}@Colspan
Section titled “@Colspan”Sets how many columns a field spans inside its containing form layout. A value of 2 makes the field stretch across two column slots.
@Retention(RetentionPolicy.RUNTIME)public @interface Colspan { int value();}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
value | int | — | Number of grid columns to span (required) |
Example
Section titled “Example”@FormLayout(columns = 2)public class ProductForm { String name; double price;
@Colspan(2) List<ProductComponent> components; // stretches across both columns}@ColumnWidth
Section titled “@ColumnWidth”Target: FIELD
Specifies a CSS width for this field’s column in a grid or listing. Accepts any valid CSS length value.
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD})public @interface ColumnWidth { String value();}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
value | String | — | CSS width string, e.g. "150px" or "20%" (required) |
Example
Section titled “Example”record InvoiceRow( @ColumnWidth("80px") String id, String description, @ColumnWidth("120px") double total) {}@Scroller
Section titled “@Scroller”Wraps the page content in a scrollable container.
public @interface Scroller { String direction() default ""; String style() default "";}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
direction | String | "" | Scroll direction: "vertical", "horizontal", or "both" |
style | String | "" | Inline CSS for the scroller container |
Example
Section titled “Example”@UI("/feed")@Scroller(direction = "vertical")public class FeedPage { Component items;}@DetailFormCustomisation
Section titled “@DetailFormCustomisation”Target: FIELD
Customises where the detail form appears when using a master-detail or embedded CRUD. Controls the position, column count, and visual styling of the detail panel.
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.FIELD})public @interface DetailFormCustomisation { FormPosition position() default FormPosition.right; String style() default ""; String theme() default ""; int columns() default 2;}FormPosition values
Section titled “FormPosition values”| Value | Description |
|---|---|
right | Detail panel opens to the right of the master (default) |
left | Detail panel opens to the left |
top | Detail panel opens above |
bottom | Detail panel opens below |
modal | Detail opens in a centred modal dialog |
modalLeft | Detail opens in a modal anchored left |
modalRight | Detail opens in a modal anchored right |
Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
position | FormPosition | right | Where the detail panel appears |
columns | int | 2 | Number of form columns in the detail panel |
style | String | "" | Inline CSS for the detail panel |
theme | String | "" | Theme variant |
Example
Section titled “Example”public class Level1View { @DetailFormCustomisation(position = FormPosition.right, columns = 1) List<Level2Row> items;}@DivStyle
Section titled “@DivStyle”Target: TYPE, FIELD, PARAMETER
Applies inline CSS to the wrapper <div> of the annotated element. Useful for controlling the outer container independently of the element’s own style.
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})public @interface DivStyle { String value();}Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
value | String | — | Inline CSS string applied to the wrapping div (required) |
Example
Section titled “Example”@DivStyle("padding: 1rem; background: #f5f5f5;")public class InfoBox { String message;}Real-world example
Section titled “Real-world example”MixedPage from the admin-panel demo combines @FormLayout, @Style, and a mix of data fields and fluent components on a single page:
@UI("/mixed")@Style(StyleConstants.CONTAINER)@FormLayout(columns = 1)public class MixedPage {
String name;
Component stats = new HorizontalLayout( Chart.builder() .chartType(ChartType.doughnut) .chartData(ChartData.builder() .labels(List.of("Scrap", "Create release", "Deploy")) .datasets(List.of(ChartDataset.builder() .label("label 1") .data(List.of(1d, 2d, 3d)) .build())) .build()) .chartOptions(ChartOptions.builder() .maintainAspectRatio(false) .build()) .build(), new Avatar("Mateu") );
@Button void save() {}}The single-column @FormLayout stacks the name text field on top of the stats component row, with the save button rendered inline below both.