Skip to content

Widget: Container

Let's add some elements to our widget to explain how a widget behaves in general.

What are we learning here?

  • Adding a scoped style to this.element
  • A widget will always resize to the dimensions of its container

We start adding a stylesheet. We use a local scope and you should always do that. Please note the .module.html extension. This is important so that local scopes can be used:

src/demo/apps/widget-basics/content.module.css

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
:local(.widget) {
  padding: 20px;
  position: relative;

  & .arrow {
    opacity: 0.5;
    position: absolute;
    color: red;
  }

  & .arrow-left {
    top: 50%;
    transform: translate(0, -100%);
    left: 0;
  }

  & .arrow-right {
    top: 50%;
    transform: translate(0, -100%);
    right: 0;
  }

  & .arrow-up {
    left: 50%;
    transform: translate(-50%, 0);
    top: 0;
  }

  & .arrow-down {
    left: 50%;
    transform: translate(-50%, 0);
    bottom: 0;
  }
}

Now we import this stylesheet in our widget and add the local class name to the component element:

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { Widget } from "@codecoupler/cc-ui";
import template from "./content.ejs.html";
import LoadingComponents from "../../widgets/loading-components";
import styles from "./content.module.css";
export default class extends Widget {
  myHeader = "JS Widget Basics";
  static defaults = {
    myWidgetArg1: "Default 1",
    myWidgetArg2: "Default 2"
  };
  async start() {
    this.injectTemplate(template({
      myHeader: this.myHeader,
      Argument1: this.options.myWidgetArg1,
      Argument2: this.options.myWidgetArg2
    }));
    await this.registerStage(this.element.find("[data-role=stage]")).load(
      LoadingComponents
    );
    this.on("changed.options", () => {
      this.element.find("[data-role=arg1]").text(this.options.myWidgetArg1);
    });
    this.element.addClass(styles.widget);
  }
  injectTemplate(tpl) {
    this.element.html(tpl);
  }
}

Finally we add some HTML elements:

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<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>
<div class="mt-2 card">
  <div class="card-header">Pass Options</div>
  <div class="card-body">
    Argument 1: <span data-role="arg1"><%= locals.Argument1 %></span><br />
    Argument 2: <span data-role="arg2"><%= locals.Argument2 %></span>
  </div>
</div>
<div class="arrow arrow-left"><i class="fas fa-chevron-circle-left"></i></div>
<div class="arrow arrow-right"><i class="fas fa-chevron-circle-right"></i></div>
<div class="arrow arrow-up"><i class="fas fa-chevron-circle-up"></i></div>
<div class="arrow arrow-down"><i class="fas fa-chevron-circle-down"></i></div>

If you run the application you will see four arrows. They point to the border of your widget container.

If you resize the application you will notice is that the container of the widget is always stretched to 100% of width and height.