Ex04: Overlays

In this example we will add an overlay to a POST. This overlay will be opened with a button click.

Here are two examples of an overlay:

First we implement an overlay written on HTML with pure JavaScript. Second - the React based component.

Here is the initial code for this example, including both of the above overlays: ex04-overlays-exercise.

Now let's create overlays.

HTML with JavaScript overlay#

  1. In pure-html-page/index.html import Bridge class from https://unpkg.com/@dapplets/dapplet-overlay-bridge package.
import Bridge from 'https://unpkg.com/@dapplets/dapplet-overlay-bridge';
  1. Create Bridge class instance and subscribe it to the data event.
1const bridge = new Bridge();
2
3bridge.on('data', ({ message, counter }) => {
4 document.querySelector('.dappletMessage').innerText = message;
5 document.querySelector('.dappletCounter').innerText = counter ?? 0;
6});
  1. Add an event handler to the button click.
1let isTick = true;
2const button = document.querySelector('.ch-state-btn');
3button.addEventListener('click', async () => {
4 const counter = await bridge.increaseCounterAndToggleLabel(isTick);
5 document.querySelector('.dappletCounter').innerText = counter;
6 isTick = !isTick;
7});

React.js based overlay#

First install Dapplet-Overlay Bridge: in /overlayWithReact module.

cd overlayWithReact
npm i @dapplets/dapplet-overlay-bridge
cd ..
  1. In /overlayWithReact/src/App.tsx import Bridge class from @dapplets/dapplet-overlay-bridge package.
import Bridge from '@dapplets/dapplet-overlay-bridge';
  1. Create IDappletApi interface and Bridge class instance typing with the inteface.
1interface IDappletApi {
2 increaseCounterAndToggleLabel: (isTick: boolean) => Promise<number>,
3}
4
5const bridge = new Bridge<IDappletApi>();
  1. Add a listener to the 'data' event.
componentDidMount() {
bridge.on('data', ({ message, counter }: { message: string, counter: number }) => this.setState({ message, counter }));
}
  1. Add an event handler to the button click.
1handleClick = async () => {
2 const counter = await bridge.increaseCounterAndToggleLabel(this.state.isTick);
3 this.setState({ isTick: !this.state.isTick, counter });
4};

Change the dapplet#

  1. Implement the IDappletApi interface, the same as in the React-based overlay.
interface IDappletApi {
increaseCounterAndToggleLabel: (isTick: boolean) => Promise<number>,
}
  1. Implement the overlay opening on the button click. To get the current overlay use Core.overlay({ name: string, title: string }).
const overlay = Core.overlay({ name: 'example-04-overlay', title: 'Example 4' });
  1. Create an object that implements the interface. Write increaseCounterAndToggleLabel function. Declare the API in the overlay.
1const dappletApi: IDappletApi = {
2 increaseCounterAndToggleLabel: (isTick: boolean) => {
3 ctx.counter = ctx.counter === undefined ? 1 : ctx.counter + 1;
4 me.label = `${isTick ? 'tick' : 'tock'} ${ctx.counter}`;
5 return ctx.counter;
6 }
7};
8overlay.declare(dappletApi);
  1. Send 'Hello, World!' message and ctx.counter to the overlay using 'data' event.
overlay.send('data', { message: 'Hello, World!', counter: ctx.counter });

There is also an onClose function. It allows handling the closing of the overlay.

overlay.onClose(() => console.log('The overlay closed!'));
  1. Add to the dapplet.json manifest the following option:
1{
2 ...
3 "overlays": {
4 "example-04-overlay": "http://localhost:3000"
5 }
6}

Dependencies must be installed before running:

npm i

To run the dapplet with pure JS overlay, change start script in package.json:

"start": "concurrently -c \"yellow,green\" -n \"dapplet,overlay\" \"rollup -w --config rollup.config.js\" \"cd pure-html-page && npx serve -l 3000\"",

To run the dapplet with ReactJS overlay, change start script to the following:

"start": "concurrently -c \"yellow,blue\" -n \"dapplet,overlay\" \"rollup -w --config rollup.config.js\" \"cd overlayWithReact && npm start\"",

Run the dapplet

npm start
tip

To publish a dapplet with an overlay, you need assets-manifest.json. When overlay is written in React, webpack or another module bundler builds it on its own. But when you write it in pure JS, you need to create the manifest yourself. As you can see, if you create a React based overlay from the example, the manifest will have the following structure:

1{
2 "index.html": "index.html",
3 "main.js": "main.js"
4}

Here is the result code of the example: ex04-overlays-solution.

video