Skip to content

Signals

Signal constructor and some built-in signals.

Signal(executor)

Defines a new signal with specified executor.

The executor is a function executed by the constructor, which receives two functions as parameters: next and view and returns a disposal hook. The next function is used to produce new values continuously and can be called multiple times. The view function is used to resolve the mounted element and can be called only one time. The disposal hook should dispose some resources the Signal allocates, say to cancel an animation loop or remove event listeners.

In Genji, if the view function of a signal is not called, the new values produced by the next function will be inspected into the document. For example, to track the mouse position:

js
pointer = new Signal((next) => {
  const pointermoved = (event) => next([event.clientX, event.clientY]);
  addEventListener("pointermove", pointermoved);
  next([0, 0]);
  return () => removeEventListener("pointermove", pointermoved);
});

Otherwise the return element will be displayed in the document. For example, to define a custom input:

js
name = new Signal((next, view) => {
  const input = document.createElement("input");
  const onChange = (e) => next(e.target.value);
  input.addEventListener("input", onChange);
  view(input);
  next("");
  return () => input.removeEventListener("input", onChange);
});
js
`My name is ${name}`;

width

The reactive signal produces the current width of page.

js
(() => {
  const div = document.createElement("div");
  div.style.width = width + "px";
  div.style.height = "100px";
  div.style.background = "orange";
  div.style.borderRadius = "10px";
  return div;
})();

now

The reactive signal produces the current timestamp.

js
now;

dark ^0.2.2

The reactive signal produces if the current theme is set to dark mode.

js
(() => {
  const div = document.createElement("div");
  div.style.width = "100px";
  div.style.height = "100px";
  div.style.background = dark ? "#fff" : "#000";
  return div;
})();

Released under the MIT License.