You can create a native DOM element by using the document.createElement(). It is also possible to provide a some attribute(s) declaratively using Object.assign(). More precisely, this way you can sets some IDL also known as a JavaScript property.
The assign function provides improved behaviour of Object.assign(). You can declaratively sets any IDL and attribute of the given element. Function prefers IDL and fallback to the element.setAttribute if there is no writable property in the element prototype.
You can study all JavaScript elements interfaces to the corresponding HTML elements. All HTML elements inherits from HTMLElement. To see all available IDLs for example for paragraphs, see HTMLParagraphElement. Moreover, the assign provides a way to sets declaratively some convenient properties:
It is possible to sets data-*/aria-* attributes using object notation.
In opposite, it is also possible to sets data-*/aria-* attribute using camelCase notation.
You can use string or object as a value for style property.
className (IDL – preffered)/class are ways to add CSS class to the element. You can use string (similarly to class="…" syntax in HTML) or array of strings. This is handy to concat conditional classes.
Use classList to toggle specific classes. This will be handy later when the reactivity via signals is beeing introduced.
The assign also accepts the undefined as a value for any property to remove it from the element declaratively. Also for some IDL the corresponding attribute is removed as it can be confusing. For example, natievly the element’s id is removed by setting the IDL to an empty string.
You can use = or . to force processing given key as attribute/property of the element.
For processing, the assign internally uses assignAttribute and classListDeclarative.
You can use functions for encapsulation (repeating) logic. The el accepts function as first argument. In that case, the function should return dom elements and the second argument for el is argument for given element.
As you can see, in case of state-less/basic components there is no difference between calling component function directly or using el function.
It is nice to use similar naming convention as native DOM API. This allows us to use the destructuring assignment syntax and keep track of the native API (things are best remembered through regular use).
Similarly to the native DOM API (document.createElementNS) for non-HTML elements we need to tell JavaScript which kind of the element to create. We can use the elNS function:
import { elNS, assign } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
-const elSVG= elNS("http://www.w3.org/2000/svg");
-const elMath= elNS("http://www.w3.org/1998/Math/MathML");
-document.body.append(
- elSVG("svg"), // see https://developer.mozilla.org/en-US/docs/Web/SVG and https://developer.mozilla.org/en-US/docs/Web/API/SVGElement
- elMath("math") // see https://developer.mozilla.org/en-US/docs/Web/MathML and https://developer.mozilla.org/en-US/docs/Web/MathML/Global_attributes
-);
-
-console.log(
- document.body.innerHTML.includes("<svg></svg><math></math>")
-)
-
\ No newline at end of file
diff --git a/docs/events.html b/docs/events.html
deleted file mode 100644
index d112178..0000000
--- a/docs/events.html
+++ /dev/null
@@ -1,80 +0,0 @@
-`deka-dom-el` — Events and Addons
`deka-dom-el` — Events and Addons
Using not only events in UI declaratively.
Listenning to the native DOM events and other Addons
We quickly introduce helper to listening to the native DOM events. And library syntax/pattern so-called Addon to incorporate not only this in UI templates declaratively.
In JavaScript you can listen to the native DOM events of the given element by using element.addEventListener(type, listener, options). The library provides an alternative (on) accepting the differen order of the arguments:
el("button", { textContent: "click me" }, on("click", console.log))
In the first example we force to use HTML attribute (it corresponds to <button onclick="console.log(event)">click me</button>). Side note: this can be useful in case of SSR. To study difference, you can read a nice summary here: GIST @WebReflection/web_events.md.
From practical point of view, Addons are just functions that accept any html element as their first parameter. You can see that the on(…) fullfills this requirement.
You can use Addons as ≥3rd argument of el function. This way is possible to extends you templates by additional (3rd party) functionalities. But for now mainly, you can add events listeners:
As the example shows, you can also provide types in JSDoc+TypeScript by using global type ddeElementAddon. Also notice, you can use Addons to get element reference.
Addons are called immediately when the element is created, even it is not connected to live DOM yet. Therefore, you can understand the Addon to be “oncreate” event.
The library provide three additional live-cycle events corresponding to how they are named in a case of custom elements: on.connected, on.disconnected and on.attributeChanged.
For Custom elements, we will later introduce a way to replace *Callback syntax with dde:* events. The on.* functions then listen to the appropriate Custom Elements events (see Custom element lifecycle callbacks | MDN).
But, in case of regular elemnets the MutationObserver | MDN is internaly used to track these events. Therefore, there are some drawbacks:
To proper listener registration, you need to use on.* not `on("dde:*", …)`!
Use sparingly! Internally, library must loop of all registered events and fires event properly. It is good practice to use the fact that if an element is removed, its children are also removed! In this spirit, we will introduce later the host syntax to register clean up procedures when the component is removed from the app.
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
index d310ad9..c0ff3cd 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,4 +1,4 @@
-`deka-dom-el` — Introduction
`deka-dom-el` — Introduction
Introducing a library.
The library tries to provide pure JavaScript tool(s) to create reactive interfaces.
We start with creating and modifying a static elements and end up with UI templates. From document.createElement to el. Then we go through the native events system and the way to include it declaratively in UI templates. From element.addEventListener to on.
Next step is providing interactivity not only for our UI templates. We introduce signals (S) and how them incorporate to UI templates.
Now we will clarify how the signals are incorporated into our templates with regard to application performance. This is not the only reason the library uses scopes. We will look at how they work in components represented in JavaScript by functions.
import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
+`deka-dom-el` — Introduction
`deka-dom-el` — Introduction
Introducing a library.
The library tries to provide pure JavaScript tool(s) to create reactive interfaces.
We start with creating and modifying a static elements and end up with UI templates. From document.createElement to el. Then we go through the native events system and the way to include it declaratively in UI templates. From element.addEventListener to on.
Next step is providing interactivity not only for our UI templates. We introduce signals (S) and how them incorporate to UI templates.
Now we will clarify how the signals are incorporated into our templates with regard to application performance. This is not the only reason the library uses scopes. We will look at how they work in components represented in JavaScript by functions.
import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
import { S } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
const clicks= S(0);
document.body.append(
@@ -13,4 +13,4 @@ document.body.append(
})
)
);
-
\ No newline at end of file
diff --git a/docs/p02-elements.html b/docs/p02-elements.html
new file mode 100644
index 0000000..44b12fc
--- /dev/null
+++ b/docs/p02-elements.html
@@ -0,0 +1,133 @@
+`deka-dom-el` — Elements
`deka-dom-el` — Elements
Basic concepts of elements modifications and creations.
Native JavaScript DOM elements creations
Let’s go through all patterns we would like to use and what needs to be improved for better experience.
You can create a native DOM element by using the document.createElement(). It is also possible to provide a some attribute(s) declaratively using Object.assign(). More precisely, this way you can sets some IDL also known as a JavaScript property.
The assign function provides improved behaviour of Object.assign(). You can declaratively sets any IDL and attribute of the given element. Function prefers IDL and fallback to the element.setAttribute if there is no writable property in the element prototype.
You can study all JavaScript elements interfaces to the corresponding HTML elements. All HTML elements inherits from HTMLElement. To see all available IDLs for example for paragraphs, see HTMLParagraphElement. Moreover, the assign provides a way to sets declaratively some convenient properties:
It is possible to sets data-*/aria-* attributes using object notation.
In opposite, it is also possible to sets data-*/aria-* attribute using camelCase notation.
You can use string or object as a value for style property.
className (IDL – preffered)/class are ways to add CSS class to the element. You can use string (similarly to class="…" syntax in HTML) or array of strings. This is handy to concat conditional classes.
Use classList to toggle specific classes. This will be handy later when the reactivity via signals is beeing introduced.
The assign also accepts the undefined as a value for any property to remove it from the element declaratively. Also for some IDL the corresponding attribute is removed as it can be confusing. For example, natievly the element’s id is removed by setting the IDL to an empty string.
You can use = or . to force processing given key as attribute/property of the element.
For processing, the assign internally uses assignAttribute and classListDeclarative.
You can use functions for encapsulation (repeating) logic. The el accepts function as first argument. In that case, the function should return dom elements and the second argument for el is argument for given element.
As you can see, in case of state-less/basic components there is no difference between calling component function directly or using el function.
It is nice to use similar naming convention as native DOM API. This allows us to use the destructuring assignment syntax and keep track of the native API (things are best remembered through regular use).
Similarly to the native DOM API (document.createElementNS) for non-HTML elements we need to tell JavaScript which kind of the element to create. We can use the elNS function:
import { elNS, assign } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
+const elSVG= elNS("http://www.w3.org/2000/svg");
+const elMath= elNS("http://www.w3.org/1998/Math/MathML");
+document.body.append(
+ elSVG("svg"), // see https://developer.mozilla.org/en-US/docs/Web/SVG and https://developer.mozilla.org/en-US/docs/Web/API/SVGElement
+ elMath("math") // see https://developer.mozilla.org/en-US/docs/Web/MathML and https://developer.mozilla.org/en-US/docs/Web/MathML/Global_attributes
+);
+
+console.log(
+ document.body.innerHTML.includes("<svg></svg><math></math>")
+)
+
\ No newline at end of file
diff --git a/docs/p03-events.html b/docs/p03-events.html
new file mode 100644
index 0000000..df763ba
--- /dev/null
+++ b/docs/p03-events.html
@@ -0,0 +1,90 @@
+`deka-dom-el` — Events and Addons
`deka-dom-el` — Events and Addons
Using not only events in UI declaratively.
Listenning to the native DOM events and other Addons
We quickly introduce helper to listening to the native DOM events. And library syntax/pattern so-called Addon to incorporate not only this in UI templates declaratively.
In JavaScript you can listen to the native DOM events of the given element by using element.addEventListener(type, listener, options). The library provides an alternative (on) accepting the differen order of the arguments:
el("button", { textContent: "click me" }, on("click", console.log))
In the first example we force to use HTML attribute (it corresponds to <button onclick="console.log(event)">click me</button>). Side note: this can be useful in case of SSR. To study difference, you can read a nice summary here: GIST @WebReflection/web_events.md.
From practical point of view, Addons are just functions that accept any html element as their first parameter. You can see that the on(…) fullfills this requirement.
You can use Addons as ≥3rd argument of el function. This way is possible to extends you templates by additional (3rd party) functionalities. But for now mainly, you can add events listeners:
As the example shows, you can also provide types in JSDoc+TypeScript by using global type ddeElementAddon. Also notice, you can use Addons to get element reference.
Addons are called immediately when the element is created, even it is not connected to live DOM yet. Therefore, you can understand the Addon to be “oncreate” event.
The library provide three additional live-cycle events corresponding to how they are named in a case of custom elements: on.connected, on.disconnected and on.attributeChanged.
For Custom elements, we will later introduce a way to replace *Callback syntax with dde:* events. The on.* functions then listen to the appropriate Custom Elements events (see Custom element lifecycle callbacks | MDN).
But, in case of regular elemnets the MutationObserver | MDN is internaly used to track these events. Therefore, there are some drawbacks:
To proper listener registration, you need to use on.* not `on("dde:*", …)`!
Use sparingly! Internally, library must loop of all registered events and fires event properly. It is good practice to use the fact that if an element is removed, its children are also removed! In this spirit, we will introduce later the host syntax to register clean up procedures when the component is removed from the app.