Layout
What are we learning here?
- How to use a
Layout
component
Now let's use another component with which you can define more complex layouts without using flexbox
or any other HTML structures like before. We will use a component called Layout
and we will extend
this.
Let's start with a simple skeleton:
src/apps/demo/layout-component/index.js
| import { Application, Layout } from "@codecoupler/cc-ui";
export default class extends Application {
static defaults = {
"@codecoupler": {
panel: {
panelSize: "900 500",
headerTitle: "Test Layout Features"
}
}
};
async start() {
await this.stage.load(Layout);
}
}
|
A Layout need an outer element with specified height
An Layout
component will always adapt its dimensions to the outer element. A Layout
is not
suitable for loading into an empty stage that has no height. In addition, a Layout
cannot
adapt to the content of its own stages.
We load the new application in our root.js file (just by replacing the previous one):
src/root.js
| import { Component, Flexbox } from "@codecoupler/cc-ui";
import LoadingComponents from "./demo/components/loading-components";
import TestApp from "./demo/apps/layout-component";
export default class extends Component {
async start() {
await this.stage.load(Flexbox, {
root: {
type: "column",
content: [
{ type: "stage", id: "top", class: "card-header" },
{ type: "stage", id: "$", grow: true }
]
}
});
await this.getStage("top").load(LoadingComponents);
await this.stage.load(TestApp);
}
}
|
Ok, we have an empty application window. Not very spectacular. Let's start building a layout.
Layout
components can be loaded with an option object without namespaced options. The passed
options will be mapped automatically into the correct namespace.
Now we pass options to the component starting with one property root
to define stages. The
structure is very similar to the options of the Flexbox
component, but there are significant
differences in the details.
In the following step we define first only one stage and load the simple component Message
.
src/apps/demo/layout-component/index.js
| import { Application, Layout, Message } from "@codecoupler/cc-ui";
export default class extends Application {
static defaults = {
"@codecoupler": {
panel: {
panelSize: "900 500",
headerTitle: "Test Layout Features"
}
}
};
async start() {
await this.stage.load(Layout, {
root: { id: "first", type: "stage" }
});
await this.getStage("first").load(Message, { text: "First" });
}
}
|
Still not very spectacular, so lets replace the first stage with the type row
and split this row
into two parts. Sublayouts in a row will be defined in the array content
. Every part is now an own
stage in which we can load a component.
Furthermore, we combine two await
s into one. The components can be loaded in parallel instead of
sequentially.
src/apps/demo/layout-component/index.js
| import { Application, Layout, Message } from "@codecoupler/cc-ui";
export default class extends Application {
static defaults = {
"@codecoupler": {
panel: {
panelSize: "900 500",
headerTitle: "Test Layout Features"
}
}
};
async start() {
await this.stage.load(Layout, {
root: {
type: "row",
content: [
{ id: "first", type: "stage" },
{ id: "second", type: "stage" }
]
}
});
await Promise.all([
this.getStage("first").load(Message, { text: "First" }),
this.getStage("second").load(Message, { text: "Second" })
]);
}
}
|
Now let's go one step further to illustrate how you can use the types row
and column
, how to use
size
and how they can be nested:
src/apps/demo/layout-component/index.js
| import { Application, Layout, Message } from "@codecoupler/cc-ui";
export default class extends Application {
static defaults = {
"@codecoupler": {
panel: {
panelSize: "900 500",
headerTitle: "Test Layout Features"
}
}
};
async start() {
await this.stage.load(Layout, {
root: {
type: "row",
content: [
{ id: "first", type: "stage", size: "60%" },
{
type: "column",
content: [
{ id: "second", type: "stage" },
{ id: "third", type: "stage", size: "60%" }
]
}
]
}
});
await Promise.all([
this.getStage("first").load(Message, { text: "First" }),
this.getStage("second").load(Message, { text: "Second" }),
this.getStage("third").load(Message, { text: "Third" })
]);
}
}
|
Ok, now we have created a basic layout which we could have also done with a flexbox layout. Now
let's add the following property resizable: true
to show borders between the stages and and make
them resizable:
src/apps/demo/layout-component/index.js
| import { Application, Layout, Message } from "@codecoupler/cc-ui";
export default class extends Application {
static defaults = {
"@codecoupler": {
panel: {
panelSize: "900 500",
headerTitle: "Test Layout Features"
}
}
};
async start() {
await this.stage.load(Layout, {
resizable: true,
root: {
type: "row",
content: [
{ id: "first", type: "stage", size: "60%" },
{
type: "column",
content: [
{ id: "second", type: "stage" },
{ id: "third", type: "stage", size: "60%" }
]
}
]
}
});
await Promise.all([
this.getStage("first").load(Message, { text: "First" }),
this.getStage("second").load(Message, { text: "Second" }),
this.getStage("third").load(Message, { text: "Third" })
]);
}
}
|
Info
resizable: true
is just a shortcut for dimensions: { borderWidth: 5, borderGrabWidth: 15 }
.
You can set of course only borderWidth
to have just borders that are not resizable.
Resizing the stages is nice, but what about draging them around and rearange them? Let's insert a
new property reordable: true
.
src/apps/demo/layout-component/index.js
| import { Application, Layout, Message } from "@codecoupler/cc-ui";
export default class extends Application {
static defaults = {
"@codecoupler": {
panel: {
panelSize: "900 500",
headerTitle: "Test Layout Features"
}
}
};
async start() {
await this.stage.load(Layout, {
reordable: true,
resizable: true,
root: {
type: "row",
content: [
{ id: "first", type: "stage", size: "60%" },
{
type: "column",
content: [
{ id: "second", type: "stage" },
{ id: "third", type: "stage", size: "60%" }
]
}
]
}
});
await Promise.all([
this.getStage("first").load(Message, { text: "First" }),
this.getStage("second").load(Message, { text: "Second" }),
this.getStage("third").load(Message, { text: "Third" })
]);
}
}
|
Info
reordable: true
is just a shortcut for header: { show: true }
Now you can drag the areas around, rearange the layout and even maximize single areas. Let's set an
title for every tab:
src/apps/demo/layout-component/index.js
| import { Application, Layout, Message } from "@codecoupler/cc-ui";
export default class extends Application {
static defaults = {
"@codecoupler": {
panel: {
panelSize: "900 500",
headerTitle: "Test Layout Features"
}
}
};
async start() {
await this.stage.load(Layout, {
reordable: true,
resizable: true,
root: {
type: "row",
content: [
{ id: "first", type: "stage", size: "60%", title: "First" },
{
type: "column",
content: [
{ id: "second", type: "stage", title: "Second" },
{ id: "third", type: "stage", size: "60%", title: "Third" }
]
}
]
}
});
await Promise.all([
this.getStage("first").load(Message, { text: "First" }),
this.getStage("second").load(Message, { text: "Second" }),
this.getStage("third").load(Message, { text: "Third" })
]);
}
}
|
Let's demonstrate one last type. Beside row
and column
you can define a stack
:
src/apps/demo/layout-component/index.js
| import { Application, Layout, Message } from "@codecoupler/cc-ui";
export default class extends Application {
static defaults = {
"@codecoupler": {
panel: {
panelSize: "900 500",
headerTitle: "Test Layout Features"
}
}
};
async start() {
await this.stage.load(Layout, {
reordable: true,
resizable: true,
root: {
type: "row",
content: [
{ id: "first", type: "stage", size: "60%", title: "First" },
{
type: "column",
content: [
{ id: "second", type: "stage", title: "Second" },
{
type: "stack",
size: "60%",
content: [
{ id: "third", type: "stage", title: "Third" },
{ id: "fourth", type: "stage", title: "Fourth" }
]
}
]
}
]
}
});
await Promise.all([
this.getStage("first").load(Message, { text: "First" }),
this.getStage("second").load(Message, { text: "Second" }),
this.getStage("third").load(Message, { text: "Third" }),
this.getStage("fourth").load(Message, { text: "Fourth" })
]);
}
}
|