APL Container
A Container
component displays multiple child items. The Container
uses a subset of Flexbox/Yoga as the layout language.
Properties
The Container component has the following properties:
- All multi-child component properties
- All base component properties
- The
Container
properties listed in following table. See the meaning of the columns.
Property | Type | Default | Styled | Dynamic | Description |
---|---|---|---|---|---|
|
One of: |
stretch |
Yes |
Yes |
Alignment for children in the cross-axis. |
|
One of: |
column |
Yes |
Yes |
Direction in which to display the child components. |
|
One of: |
start |
Yes |
Yes |
How to distribute free space when there is room on the main axis. Defaults to |
|
boolean |
false |
No |
No |
When |
|
One of: |
|
Yes |
Yes |
Determines how to wrap child components to multiple lines. |
Unlike standard Flexbox containers, The APL Container
component doesn't scroll. Place the Container
within a ScrollView
to create a scrolling component.
When the Container
is the source or target of an event, the following values are reported in event.source
or event.target
:
{
// Container-specific values
"type": "Container",
// General component values
"bind": Map, // Access to component data-binding context
"checked": Boolean, // Checked state
"disabled": Boolean, // Disabled state
"focused": Boolean, // Focused state
"height": Number, // Height of the component, in dp (includes the padding)
"id": ID, // ID of the component
"opacity": Number, // Opacity of the component [0-1]
"pressed": Boolean, // Pressed state
"uid": UID, // Runtime-generated unique ID of the component
"width": Number // Width of the component, in dp (includes the padding)
}
layoutDirection component property
The component layoutDirection
property determines the direction to lay out the Container
child components. An APL Container
follows the same rules as the Yoga layoutDirection
property.
The component layoutDirection
property determines the override behavior of the following properties that control positioning for the Container children:
left
andright
start
andend
alignItems
The Flexbox specification for how to align the child components in the cross-axis of the container. Defaults to stretch
.
direction
The direction of layout in the container. Defaults to column
. The direction
property can take the following values:
Type | Description |
---|---|
|
Lay out the child components in a vertical column (Default). |
|
Lay out the child components in a horizontal row. |
|
Lay out the child components in a vertical column, but start from the opposite side |
|
Lay out the child components in a horizontal row , but start from the opposite side |
The layoutDirection
property determines the horizontal direction of the items when direction
is row
. For example, when layoutDirection
is RTL
and direction
is row
, the child items start on the right and display to the left.
justifyContent
The Flexbox specification for how to distribute free space when there is room on the main axis. This property applies when the container is larger than the size of its children. Defaults to start
.
numbered
When true
, set the data-binding ordinal
for each of the items in the Container
. The ordinals start with "1" and increment by one unless the numbering
property in a child is set to "skip" or "reset". Note that the firstItem
and lastItem
properties don't participate in ordinal numbering. Defaults to false
.
wrap
The Flexbox wrapping behavior of the children. The wrap
property takes the following values:
Type | Description |
---|---|
|
The |
|
The child components can break into multiple lines. |
|
The child components can break into multiple lines, but start from the opposite side. |
The following example shows a Container
that displays five child components. Each child component is a Frame
that defines a box. The Container
isn't wide enough to show all five boxes. With the wrap
property set to wrap
, the child components wrap to the next line. If you set wrap
to noWrap
, the child components display on a single line and any that don't fit are truncated.
If you change the direction
property to column
, the child components wrap to the next column.
Multichild properties
A Container
is a multi-child component. The Container
inherits all of the multi-child properties.
Container child component properties
The child components of a Container
have additional properties to control positioning within the parent container.
Property | Type | Default | Styled | Dynamic | Description |
---|---|---|---|---|---|
|
|
auto |
Yes |
Yes |
Cross-axis layout position. Defaults to |
|
Dimension |
auto |
Yes |
Yes |
Specifies the position offset of the bottom edge. |
|
Dimension |
none |
Yes |
Yes |
Position offset of the end edge. The end edge is either the left or right side of the component, depending on the |
|
Number |
0 |
Yes |
Yes |
When positive, proportionally stretch this component if there is extra space in the |
|
Dimension |
auto |
Yes |
Yes |
Specifies the position offset of the left edge. |
|
|
normal |
No |
No |
Control ordinal numbering of the next child. Defaults to |
|
|
relative |
Yes |
Yes |
Adjust the position of the child component. When |
|
Dimension |
auto |
Yes |
Yes |
Specifies the position offset of the right edge. |
|
Number |
0 |
Yes |
Yes |
When positive, proportionally shrink this component if there is not enough space in the Container. Defaults to 0. |
|
Absolute Dimension |
0 |
Yes |
Yes |
Additional space to add between this component and the previous component in the layout. Defaults to 0. |
|
Dimension |
none |
Yes |
Yes |
Position offset of the starting edge. The starting edge is either the left or right side of the component, depending on the |
|
Dimension |
auto |
Yes |
Yes |
Specifies the position offset of the top edge. |
The following example demonstrates the alignSelf
and position
properties. This example displays six child components in a Container
. Each child uses a Frame
to display a colored square. The Container
sets alignItems
to start
, so the items display in a column on the left side of the viewport. Two of the child components use their own properties to change how they display:
- The second square sets
alignSelf
tocenter
, which overridesalignItems
. The orange square therefore displays horizontally centered in the viewport. - The fourth square sets
position
toabsolute
andright
to50
. Theposition
property removes this component from the normal list and displays it 50 pixels from the right side of the viewport. Becausetop
defaults to 0, the square displays at the top of the viewport. Note that the next component, the blue "5" square, moves up to display immediately after the third component.
alignSelf
Overrides the alignItems
property for this child component.
position, bottom, left, right, top
The position
property determines how the bottom
, left
, right
, and top
properties adjust the position of the child component from its "standard" location.
The start
and end
properties also override left
and right
based on the layoutDirection
for the ``Container`.
Absolute positioning
When position
is absolute
, the child component is taken out of the normal layout ordering for the container and instead positioned absolutely relative to the parent. The top
, bottom
, left
, and right
properties are dimensional offsets from the sides of the parent container. The padding of the parent container is ignored for an absolutely positioned child component.
In an "absolute"-positioned element where the size of the element is fixed, the top
property overrides the bottom
property when both are set. The left
and right
properties depend on the layoutDirection
property of the parent container:
- Parent container's
layoutDirection
is set to "LTR" – ifleft
is set, theright
property is ignored. If neither position properties are set, the element is positioned at the top-left of the parent container. - Parent container's
layoutDirection
is set to "RTL" – ifright
is set, theleft
property is ignored. If neither position properties are set, the element is positioned at the top-right of the parent container.
The following example shows a component that sets all four position properties.
{
"position": "absolute",
"width": 100,
"height": 100,
"top": 5,
"bottom": 5,
"left": 5,
"right": 5
}
When layoutDirection
for the Container
is LTR
, this component is positioned 5 units from the top-left of the parent container. The values for bottom
and right
are ignored because top
and left
are set.
When layoutDirection
for this Container
is RTL
, this component is positioned 5 units from the top-right of the parent container. The values for bottom
and left
are ignored because top
and right
are set.
Relative positioning
When position
is relative
, the bottom
, left
, right
, and top
properties are dimensional offsets from the "normal" position of the child, relative to the other components in the Container
. When top
has a value, the bottom
property is ignored. The left
and right
properties depend on the layoutDirection
property of the parent container:
- Parent container's
layoutDirection
is set to "LTR" – ifleft
is set, theright
property is ignored. - Parent container's
layoutDirection
is set to "RTL" – ifright
is set, theleft
property is ignored.
The following example shows a component that sets top
, bottom
, and right
.
{
"position": "relative",
"top": 5,
"bottom": 20,
"right": 5
}
When layoutDirection
for the Container
is LTR
, this component is positioned 5 units down and 5 units to the left of its normal position relative to the other child components. The bottom
and right
properties are ignored.
When layoutDirection
for the Container
is RTL
, this component displays 5 units down and 5 units to the right of its normal position relative to the other child components. The bottom
and left
properties are ignored.
Sticky positioning
When position
is relative
, the bottom
, left
, right
, and top
properties are dimensional offsets calculated in reference to the nearest scrollable ancestor component. This position "sticks" the component to the ancestor component.
For a sticky component, the top
and bottom
properties represent insets from the respective edges of the nearest vertical scrollable component. The left
and right
properties represent insets from the edges of the nearest horizontal scrollable. These properties define the "sticky view" rectangle used to constrain the component’s position.
If the sticky view rectangle size in any axis is less than the size of the default bounds of the sticky component in that axis, then the effective end-edge inset in the affected axis is reduced (possibly becoming negative) to bring the sticky view rectangle’s size up to the size of the default bounds in that axis.
For example:
Assume the nearest vertical scrollable item is 300px tall and the sticky component has a default bounds of 200px tall. The top
property is 20px. This means that the top edge inset of the nearest ancestor is 20px and the bottom edge inset is 0px. The sticky view rectangle is therefore 280px tall.
However, if the nearest vertical scrollable item is 100px tall, then the effective bottom edge inset becomes -120px. This results in a sticky view rectangle that's 200px tall.
For each side of the component, if the corresponding inset property is not auto, and the corresponding border edge of the component would be outside the corresponding edge of the sticky view rectangle, then the component must be visually shifted (as for relative positioning) to be inward of that sticky view rectangle edge, insofar as it can while its position component remains contained within its containing block. If offsetting the sticky component would put it outside the bounds of its parent the offset is reduced to keep the sticky component within its parents bounds.
A sticky positioned element with a non-auto top value and an auto bottom value will only ever be pushed down by sticky positioning; it will never be offset upwards. In the same way a sticky component with a non-auto left, right or bottom property and a corresponding auto right, left or top property will only ever be pushed right, left or upwards respectively.
Multiple sticky positioned components in the same container are offset independently, and therefore might overlap.
When the value of the top
or bottom
properties is a percentage, it is a percentage of the nearest vertical scrollable ancestor or the nearest horizontal ancestor for the right
or left
properties.
Containers with position: sticky are drawn after any non-sticky siblings.
The following example shows a component that stays 10 units down from the top edge of the vertical scrollable. It won’t stick to any other edges because the corresponding right
, bottom
, or left
properties haven’t been set:
{
"position": "sticky",
"top": 10
}
The following example defines a component that sticks to both the left and right side of the nearest horizontal scrollable ancestor. If this component reaches the left edge of the scrollable ancestor it sticks 10 units to the right of the left edge of the scrollable. As a result, the left 10 units of the component are hidden from the view. If the scrollable ancestor is scrolled left this component stays at least 20 units from the right edge of the scrollable:
{
"position": "sticky",
"left": -10,
"right": 20
}
Note that the default bounds of the parent of a sticky component can be used to restrict the offsets of a sticky component.
The images below show two components (in red) with parents (in blue) inside a scrollable. The two components have position
set to sticky
and left
set to values of 0px and 20px respectively.
{
"type": "APL",
"version": "2024.3",
"mainTemplate": {
"item": [
{
"type": "ScrollView",
"width": 500,
"height": 500,
"item": {
"type": "Container",
"height": 1000,
"width": 500,
"items": [
{
"type": "Frame",
"height": 300,
"width": 500,
"backgroundColor": "#1a73e8",
"items": [
{
"type": "Container",
"height": 300,
"width": 500,
"items": [
{
"position": "sticky",
"top": 0,
"type": "Frame",
"height": 100,
"width": 500,
"backgroundColor": "#dc3912",
"items": []
}
]
}
]
},
{
"type": "Frame",
"height": 100,
"width": 500,
"backgroundColor": "white"
},
{
"type": "Frame",
"height": 1000,
"width": 500,
"backgroundColor": "#1a73e8",
"items": [
{
"type": "Container",
"height": 300,
"width": 500,
"items": [
{
"position": "sticky",
"top": 20,
"type": "Frame",
"height": 100,
"width": 500,
"backgroundColor": "#dc3912",
"items": []
}
]
}
]
}
]
}
}
]
}
}
start, end
When specified, the start
and end
properties override left
and right
for specifying the component position. The override depends on the layoutDirection
property:
Property | Left-to-right ("LTR") | Right-to-left ("RTL") |
---|---|---|
|
Overrides |
Overrides |
|
Overrides |
Overrides |
The following example shows a component with absolute positioning. When the layoutDirection
for the Container
is RTL
, this component displays 5 units from the top-right of its parent container. The start
property (5) overrides the right
property (10).
{
"position": "absolute",
"width": 100,
"height": 100,
"start": 5,
"left": 10,
"right": 10,
"top": 5
}
start
and end
properties require APL 1.7 or later. You can set both these properties and the left
/ right
properties for your component. Earlier versions of APL ignore the newer properties.grow, shrink
Flexbox grow
and shrink
properties. A positive grow
value stretches the component proportionally when there is extra space in the container. A positive shrink
value allows the component to shrink below its normal size when there is not enough space in the container.
Negative grow
or shrink
values are ignored.
The following example demonstrates the alignSelf
and position
properties. This example displays three child components in a Container
. Each child uses a Frame
to display a colored square. The first child component sets grow
to 1
. On a viewport with more vertical space, the red box grows in height to fill the full height of the Container
. On a smaller viewport, the red box shrinks back down closer to the size defined for the Frame
.
numbering
Controls the ordinal value when the parent has set numbered. This property controls how the ordinal value updates for the next child in the sequence, not the current child in the sequence.
normal
: The next child's ordinal = ordinal + 1.skip
: The next child's ordinal = ordinalreset
: The next child's ordinal = 1
spacing
An amount of spacing to add between this component and the previous child component in the layout. The first item in the layout ignores spacing. Specify the spacing in absolute dimensions. The spacing
property doesn't support relative dimensions.
The spacing
properties applies to child components where position
is relative
. The property is ignored for child components where position
is absolute
.
Last updated: Nov 28, 2023