Containers serve multiple purposes, including:
- Structuring the layout
- Grouping similar content together
- Controlling the visibility of UI elements
The primary function of containers is to organize the layout. Most containers lack inherent meaning on their own; hence, various containers are used to for default layout behaviour.
The simplest among these are the “div” and “span” elements. While they don’t inherently convey any specific meaning, they offer distinct layout configurations without the need for additional styling.
The div element creates a block layout, arranging elements vertically from top to bottom. Conversely, the span element facilitates a line layout, positioning elements horizontally, side by side from left to right.
The default layout can be modified using flexbox and CSS grid layout styles. Although you don’t have the capability to create custom styles within the schemas, you can utilize the styles provided by the system. These layouts can be activated by applying CSS classes to the container element.
{
"body": {
"elements": [
{
"element": "div",
"elements": [ ... child elements ... ]
},
{
"element": "span",
"elements": [ ... child elements ... ]
}
]
}
}
The div elements are among the most frequently used containers in UI design. When combined with ARIA (Accessible Rich Internet Applications) and role attributes, they can form the backbone of UI layout. For instance, to construct a generic toolbar, you would typically use a div element assigned with the role of “toolbar.”
{
"element": "div",
"attributes": {
"role": "toolbar"
},
"elements": [ ... toolbar items ... ]
}
Some containers have their own UI that is interactable and exposes features of the container. For the most part these features allow the showing and hiding of content and based on the component, what that looks like might differ. Common containers for such operations are:
- Tabsheet – show the content of the current tab but hide all the rest.
- Group – a titled UI that allows you to expand and collapse it’s content.
Tabsheet
The tabsheet’s schema definition utilizes templates to structure its UI. This approach allows tabs to be lazy-loaded, meaning content is fetched only when the respective tab is activated. For instance, if a user never accesses the address tab, there’s no need to load the resources required to display address data. In complex enterprise applications, fetching content only as needed enhances performance and reduces memory usage.
{
"variables": {
"person": {
"details": "Details",
"address": "Address"
}
},
"templates": [
{
"id": "details",
"elements": [ ... ui ... ]
},
{
"id": "address",
"elements": [ ... ui ... ]
}
],
"body": {
"elements": [
{
"element": "tabsheet",
"elements": [
{
"id": "tab1",
"title": "@translations.person.details",
"template": "details"
},
{
"id": "tab2",
"title": "@translations.person.address",
"template": "address"
}
]
}
]
}
}
Group box / group
The term ‘group’ is used here as shorthand for a ‘groupbox’. Group boxes are titled elements, featuring a header that remains visible whether the groupbox is expanded or collapsed. Their primary function is to cluster related input and form components within a distinct UI zone. This area can be collapsed to hide its contents or expanded to view them.
{
"variables": {
"person": {
"details": "Details"
}
},
"body": {
"elements": [
{
"element": "group",
"title": "@translation.person.details",
"elements": [ ... ui ... ]
}
]
}
}
A group box can contain a list of elements, or it can utilize templates for its content.
Sections
Sections are a standard HTML grouping strategy, already existing as native DOM elements. The section element should include a header followed by the section’s content. This structure functions similarly to a group box, but by default, it is not designed to be expandable or collapsible.
{
"variables": {
"person": {
"details": "Details"
}
},
"body": {
"elements": [
{
"element": "section",
"elements": [
{
"element": "h2",
"content": @translations.person.details
},
... other elements ...
]
}
]
}
}
Layout container
This dynamic component is designed for flexible layout using CSS grid features, enabling the definition of grid structures based on columns and rows. Due to the nature of CSS grid, the child elements will be automatically arranged according to the specified grid layout.
This implies that the layout container can be utilized for horizontal, vertical, or a mix of both layouts. If you need to divide your UI into three different columns, a layout container is suitable. Similarly, for arranging the UI into three columns across two rows, the layout container is the appropriate choice.
{
"body": {
"elements": [
{
"element": "layout-container",
"attributes": {
"data-columns": "1fr 1fr 1fr",
"data-rows": "1fr"
},
"elements": [
{
"id": "cell1",
"element": "div",
"elements": [ ... ui ... ]
},
{
"id": "cell2",
"element": "div",
"elements": [ ... ui ... ]
},
{
"id": "cell3",
"element": "div",
"elements": [ ... ui ... ]
}
]
}
]
}
}
In the mentioned example, a div element is used as a generic container representing each cell in the layout grid. With three columns and one row, this results in three cells. The CSS grid layout handles the arrangement of these items. Although the CSS grid manages the layout of the cell elements, each cell can independently conduct its own internal layout, as dictated by the UI flow.
Split view
A split view is a custom element featuring two sections: a left cell and a right cell. The left cell remains constantly visible, while the right cell can be hidden as needed. In this example you can see two attributes:
- split-percentage – This specifies the percentage of space occupied by the first (left) cell.
- visible.bind – This is a binding expression used to control the visibility of the right cell. In the provided example, we bind this to a ‘variables’ object containing a ‘ui’ object. This ‘ui’ object includes a boolean field named ‘splitVisible’. When this value is set to false, the right cell becomes hidden.
The ‘left’ and ‘right’ properties function as arrays, similar to the ‘elements’ property, containing a collection of elements. In the given example, each collection (left and right) has only one element, which loads a template for the respective cell.
{
"variables": {
"ui": {
"splitVisible": false
}
},
"templates": [
... templates for split view and UI ...
],
"body": {
"elements": [
{
"id": "splitContainer",
"element": "split-view",
"attributes": {
"split-percentage": 50,
"visible.bind": "@ui.splitVisible"
}
"left": [
{
"element": "template",
"template": "leftUI"
}
],
"right": [
{
"element": "template",
"template": "rightUI"
}
]
}
]
}
}
Panel bar
The panel bar is a component featuring a visual panel element, which includes UI elements, and a toolbar for that panel. By default, the toolbar is positioned at the top. The content within the panel container can be defined using the ‘elements’ property. Additionally, buttons and other controls can be dynamically added to the toolbar by specifying the toolbar content in the “actions” property. By default you should at least have those two properties set. There is also an optional property to display footer content below the panel container. This footer assumes a horizontal layout.
{
"variables": {
"translations": { heading: "Heading Text" }
},
"body": {
"elements": [
{
"element": "panel-bar",
"title": "@translations.heading",
"actions": [ ... header toolbar content ... ],
"elements": [ ... UI to show ... ],
"footer": [ ... UI to show in footer ... ]
}
]
}
}
For the ‘actions’, ‘elements’, and ‘footer’ properties of the panel bar, their elements are defined in the same manner as any other ‘elements’ property. These properties essentially designate content for the different compartments that comprise the panel bar, with each property corresponding to a specific area within it.
- header container – title and actions property content
- body container – elements property content
- footer container – footer property content