Skip to content

Stages & Components: Creating Single Stage

As we know now every component have a main stage. But any component can have multiple stages and some of them can create beyond that further stages, too. A widget component for example is able to create additional stages.

What are we learning here?

  • Some components can create further stages with this.registerStage()

Let's add an element into our HTML structure in which we create a stage:

src/demo/apps/widget-basics/content.ejs.html

1
2
3
4
5
<h2><%= locals.myHeader %></h2>
<div class="mt-2 card">
  <div class="card-header">Loading Components</div>
  <div class="card-body"><div data-role="stage"></div></div>
</div>

We use now the method registerStage() to convert the element taged with data-role=stage into a stage.

Remark: We do not use the <div class="card-body"> to create the stage because this is a flexbox child which collide with the flexbox handling of a stage and would collapse to a zero height.

src/demo/apps/widget-basics/content.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { Widget } from "@codecoupler/cc-ui";
import template from "./content.ejs.html";
export default class extends Widget {
  myHeader = "JS Widget Basics";
  async start() {
    this.injectTemplate(template({
      myHeader: this.myHeader
    }));
    await this.registerStage(this.element.find("[data-role=stage]"));
  }
  injectTemplate(tpl) {
    this.element.html(tpl);
  }
}

Let's create a component what we will load in it. We create two files for the HTML structure and the code. We put this component in a widget subfolder because it will be used by different applications in the next chapters.

Don't wonder why the new component extends from Box and not Widget. The two classes offer roughly the same thing. We will explain the differences in more detail later.

src/demo/widgets/loading-components/index.html

1
<p>Just a placeholder for now</p>

src/demo/widgets/loading-components/index.js

1
2
3
4
5
6
7
8
import { Box } from "@codecoupler/cc-ui";
import template from "./index.html"
export default class extends Box {
  async finalize() {
    super.finalize();
    this.$box.html(template);
  }
}

Now we we use the method load() of the returned stage object, to load our new widget into this stage:

src/demo/apps/widget-basics/content.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import { Widget } from "@codecoupler/cc-ui";
import template from "./content.ejs.html";
import LoadingComponents from "../../widgets/loading-components";
export default class extends Widget {
  myHeader = "JS Widget Basics";
  async start() {
    this.injectTemplate(template({
      myHeader: this.myHeader
    }));
    await this.registerStage(this.element.find("[data-role=stage]")).load(
      LoadingComponents
    );
  }
  injectTemplate(tpl) {
    this.element.html(tpl);
  }
}

Start Definition Object vs Shortcut Signature

We will use here a signature of the load method which expects only one Component. This is just a shortcut signature. The load method normally expects a so called start definition object. This would look like:

load({
  component: LoadingComponents
})

Now you should see our Message in the stage element. We will come back later to this widget and will insert more functionality.