Skip to content

Special Levels: Modal Applications

What are we learning here?

  • How to load an Application component modal

Now let's have a look at the stage level block. This level have always a semi-transparent background and will block any levels below as soon a component was loaded into it. This is perfect for modal applications.

In addition to the level block we will use the stage root. This ensures that always the entire component will be blocked.

Let's add one more button into our HTML structure:

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

 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
35
36
37
38
39
40
41
42
43
44
45
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Modal
  <button class="btn btn-xs btn-info" data-role="modalApp">
    <i style="pointer-events: none" class="fas fa-check-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Hint
  <button class="btn btn-xs btn-info" data-role="hintInfo">
    <i style="pointer-events: none" class="fas fa-info-circle"></i>
  </button>
  <button class="btn btn-xs btn-success" data-role="hintSuccess">
    <i style="pointer-events: none" class="fas fa-check-circle"></i>
  </button>
  <button class="btn btn-xs btn-danger" data-role="hintError">
    <i style="pointer-events: none" class="fas fa-exclamation-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Note
  <button class="btn btn-xs btn-info" data-role="hintInfoP">
    <i style="pointer-events: none" class="fas fa-info-circle"></i>
  </button>
  <button class="btn btn-xs btn-success" data-role="hintSuccessP">
    <i style="pointer-events: none" class="fas fa-check-circle"></i>
  </button>
  <button class="btn btn-xs btn-danger" data-role="hintErrorP">
    <i style="pointer-events: none" class="fas fa-exclamation-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  Splash
  <button class="btn btn-xs btn-info" data-role="hintSplash">
    <i style="pointer-events: none" class="fas fa-exclamation-circle"></i>
  </button>
</div>
<div class="border rounded d-inline-block p-1 mr-2 my-1 bg-white text-dark">
  App
  <button class="btn btn-xs btn-info" data-role="appNoId">
    <i style="pointer-events: none" class="fas fa-times-circle"></i>
  </button>
  <button class="btn btn-xs btn-info" data-role="appId">
    <i style="pointer-events: none" class="pe-none fas fa-check-circle"></i>
  </button>
</div>

And add some handlers:

src/demo/components/loading-components/index.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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { Canvas, Hint } from "@codecoupler/cc-ui";
import Mockup from "../../apps/mockup";
import { toRaw } from "vue";
import template from "./index.html";
export default class extends Canvas {
  static defaults = { target: null };
  async start() {
    this.element.innerHTML = template;
    this.element.addEventListener("click", (e) => {
      if (e.target.dataset.role) this[e.target.dataset.role]();
    });
    this.target = toRaw(this.options.target) ?? this.env.parent;
  }
  modalApp() {
    this.target.getStage("root").load({ component: Mockup, level: "block" });
  }
  hintInfo() {
    this.target.getStage("root").load(Hint, { type: "info", text: "Hint!" });
  }
  hintSuccess() {
    this.target.hint("success", "Hint!");
  }
  hintError() {
    this.target.hint("error", "Hint!");
  }
  hintInfoP() {
    this.target.hint("info-permanent", "Permanent Hint!");
  }
  hintSuccessP() {
    this.target.hint("success-permanent", "Permanent Hint!");
  }
  hintErrorP() {
    this.target.hint("error-permanent", "Permanent Hint!");
  }
  async hintSplash() {
    let splash = await this.target.hint("splash", "Splash!");
    for (let x = 0; x <= 100; x += 25) {
      await new Promise((r) => setTimeout(() => r(), 750));
      splash.text = `Please Wait\n${x}% Progress`;
    }
    await new Promise((r) => setTimeout(() => r(), 2000));
    splash.destroy();
  }
  appNoId() {
    this.target.stage.load(Mockup);
  }
  appId() {
    this.target.stage.load(Mockup, "fixed-id");
  }
}

And now you have loaded an application into the root stage in it's blocking layer. You will not get access to the widget below until you close the application component.