ui/ Layout
A convenient tool for laying-out content using Layout
, Cell
, Row
, and Column
.
Layout is a powerful and versatile tool used for arranging content on the screen. On a conceptual
level, it mixes the best parts of HTML tables wtih the best parts of HTML framesets, both of
which were largely abandoned for their drawbacks, ignoring their strengths. A Layout
is simply
a container for Cell
, the only "legal" child. Conversely, Cell
may only be used in a
Layout
. Cells in a Layout can either be positioned next to each other (horizontally) or
above/below each other (vertically) in what we refer to as a Row or
Column, respectively.
The Row
and Column
layout presets describe the direction of layout for their children. This
can sometimes cause confusion. A Row
of children naturally forms a layout whose children can
have the appearance of columns. To keep things clear, think about the layout rather than the
what the children themselves represent.
Layout
is an implementation of flex-box, but with built-in rails, properties, and features to
help avoid common problems with flex-box; things like content overflowing, sizing quirks, and
positioning problems regarding content of unknown or undefined dimension.
The following scenarios are some common cases where Layout
can truly help out. A quality of
Cell
you'll see below is that when a Cell
has no defined size, it automatically sizes to fill
any remaining space in the Layout
. If there are multiple auto-sizing Cell
components, they
share the space, subdividing it equally among themselves. It's great to leverage this and only
apply sizes to Cell
s which must have defined sizes. shrink
is one of the ways you can impose
size guidelines on a Cell
. It automatically fits the size of the Cell to the size of its
content.
A row of cells where the last one should always attach to the right side, regardless of the size of the main "content" cell:
βββββββββ¬ββ
βMain βRβ
βββββββββ΄ββ
<Row>
<Cell>Main Content</Cell>
<Cell shrink>Right Side</Cell>
</Row>
A "two-column" layout with equal sized cells using Row
:
ββββββ¬βββββ
βL βR β
ββββββ΄βββββ
<Row style={{height: '100%'}}>
<Cell>Left Column</Cell>
<Cell>Right Column</Cell>
</Row>
Remember: The cells of the Row
are the columns in our layout. It's likely that in a complex
layout Column
would be used inside the left and right cells to arrange the components, as in
the example below.
A full-height sidebar with a header and body to the right:
ββββ¬βββββββ
βS βHEADERβ
β ββββββββ€
β βBody β
β β β
ββββ΄βββββββ
<Row style={{height: '100%'}}>
<Cell size="20%">Sidebar</Cell>
<Cell>
<Column>
<Cell size={90} component="header">
<h1>HEADER</h1>
</Cell>
<Cell>
<p>Body area</p>
</Cell>
</Column>
</Cell>
</Row>
Note: Here, we've set the height of Row
so it fills the height of the screen, allowing the
Sidebar Cell and content Cell to stretch from the top to the bottom. We've also leveraged the
component
prop on the header cell, which tells Cell
to render itself as a "header" HTML tag
rather than its usual "div" tag.
The example below produces a layout like the following:
βββ¬ββββββ¬ββ
βoβItem βoβ
βββ΄ββββββ΄ββ
You'll notice the use of some special classes in the example: "debug layout"
. Adding these on
any element in your DOM hierarchy will enable borders in Layout and Cell to help visualize what
is happening in the layout. They automatically change color the deeper in the stack they go.
import Layout from '@enact/ui/Layout';
Members
LayoutComponent
A container for Cell
s.
A stateless component that acts as a containing area for Cells to be
positioned in a row or a column (horizontally or vertically, respectively. It supports an
orientation property for laying-out its contents
(Cells
) in an organized, readable way.
Example:
import Input from '@enact/moonstone/Input';
import css from './LayoutExample.less';
...
<fieldset>
<Layout align="center">
<Cell component="label" size="40%" className={css.label} shrink>First Name</Cell>
<Cell component={Input} placeholder="First" className={css.input} />
</Layout>
<Layout align="center">
<Cell component="label" size="40%" className={css.label} shrink>Last Name</Cell>
<Cell component={Input} placeholder="Last" className={css.input} />
</Layout>
</fieldset>
import Layout from '@enact/ui/Layout';
CellComponent
A stateless component that provides a space for your content in a Layout.
import {Cell} from '@enact/ui/Layout';
CellBaseComponent
A stateless component that provides a space for your content in a Layout, without CellDecorator applied.
import {CellBase} from '@enact/ui/Layout';
Properties
The alignment of
Cell
.Aligns this
Cell
vertically in the case of a horizontal layout or horizontally in the case of a vertical layout."start"
,"center"
and"end"
are the most commonly used, although all values ofalign-self
are supported."start"
refers to the top in a horizontal layout, and left in a vertical LTR layout"end"
refers to the bottom in a horizontal layout, and right in a vertical LTR layout"start"
and"end"
reverse places when in a vertical layout in a RTL locale.Any valid Node that should be positioned in this
Cell
.The type of component to use to render as the
Cell
. May be a DOM node name (e.g 'div', 'span', etc.) or a custom component.Default: 'div'Sizes
Cell
to its contents.A
shrink
able cell will contract to its minimum size, according to the dimensions of its contents. This is used when you want the size of this Cell's content to influence the dimensions of this cell.shrink
will not allow the contents of the Layout to be pushed beyond its boundaries (overflowing). See the size property for more details.Default: falseSets the desired size of the Cell using any valid CSS measurement value.
When used in conjunction with shrink, the size will be the maximum size, shrinking as necessary, to fit the content.
E.g.
size="400px"
-> cell will be 400px, regardless of the dimensions of your contentsize="400px" shrink
-> cell will be 400px if your content is greater than 400px, and will match your contents size if it's smaller
This accepts any valid CSS measurement value string. If a numeric value is used, it will be treated as a pixel value and converted to a relative unit based on the rules of resolution independence.
CellDecoratorHigher-Order Component
Applies Cell behaviors.
import {CellDecorator} from '@enact/ui/Layout';
ColumnComponent
Shorthand for <Layout orientation="vertical">
, which positions its
Cells vertically.
ββββββ
ββββββ€
ββββββ€
ββββββ€
ββββββ
import {Column} from '@enact/ui/Layout';
LayoutBaseComponent
A container for Cell
s.
A stateless component that acts as a containing area for Cells to be
positioned in a row or a column (horizontally or vertically, respectively. It supports an
orientation property for laying-out its contents
(Cells
) in an organized, readable way.
Example:
import Input from '@enact/moonstone/Input';
import css from './LayoutExample.less';
...
<fieldset>
<Layout align="center">
<Cell component="label" size="40%" className={css.label} shrink>First Name</Cell>
<Cell component={Input} placeholder="First" className={css.input} />
</Layout>
<Layout align="center">
<Cell component="label" size="40%" className={css.label} shrink>Last Name</Cell>
<Cell component={Input} placeholder="Last" className={css.input} />
</Layout>
</fieldset>
import {LayoutBase} from '@enact/ui/Layout';
Properties
The alignment of children.
Aligns the children Cells vertically in the case of a horizontal layout or horizontally in the case of a vertical layout.
"start"
,"center"
and"end"
are the most commonly used, although all values ofalign-items
are supported."start"
refers to the top in a horizontal layout, and left in a vertical LTR layout"end"
refers to the bottom in a horizontal layout, and right in a vertical LTR layout"start"
and"end"
reverse places when in a vertical layout in a RTL locale. This includes support foralign-parts
which is shorthand for combiningalign-items
andjustify-content
into a single property, separated by a space, in that order. This allows you to specify both the horizontal and vertical alignment in one property, separated by a space.Only Cell components are supported as children.
The type of component to use to render as the
Layout
. May be a DOM node name (e.g 'div', 'span', etc.) or a custom component.Default: 'div'Allows this
Layout
to have following siblings drawn on the same line as itself instead of carving out the entire horizontal space for itself.Default: falseThe orientation of the
Layout
, i.e. how the children Cells are positioned on the screen. Must be either'horizontal'
or'vertical'
.Default: 'horizontal'Sets the Layout's
flex-wrap
values.Determines how a Layout handles its cells if there are more than fit in the available space. This works like a normal
Boolean
prop, but also accepts strings for customization beyond the basic on/off support. In addition totrue
andfalse
, the following strings are supported: 'wrap', 'nowrap', 'reverse'. 'reverse' performs standard line wrapping but additional lines are placed above/before the preceding line instead of below/after.
LayoutDecoratorHigher-Order Component
Applies Layout behaviors.
import {LayoutDecorator} from '@enact/ui/Layout';
RowComponent
Shorthand for <Layout orientation="horizontal">
, which positions its
Cells horizontally.
βββ¬ββ¬ββ¬ββ
β β β β β
βββ΄ββ΄ββ΄ββ
import {Row} from '@enact/ui/Layout';