1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2024-11-24 17:39:36 +01:00
A library expanding the capabilities of the native DOM API with the aim of offering the possibility of writing reactive UI templates/components declaratively directly in JavaScript. https://jaandrle.github.io/deka-dom-el/
Go to file
2023-09-19 09:30:21 +02:00
bs 🚧 types, linting, caching 2023-09-07 13:52:09 +02:00
dist ♻️ 🔨 🐛 e.g. better namespace #18 2023-09-19 09:30:21 +02:00
src ♻️ 🔨 🐛 e.g. better namespace #18 2023-09-19 09:30:21 +02:00
test ♻️ 🔨 🐛 e.g. better namespace #18 2023-09-19 09:30:21 +02:00
.gitignore dev-package (#15) 2023-09-05 09:25:47 +02:00
index-with-signals.js ♻️ 🔨 🐛 e.g. better namespace #18 2023-09-19 09:30:21 +02:00
index.d.ts 🐛 🚧 connected/disconnected + onAbort 2023-09-09 21:18:28 +02:00
index.js 💥 Signals are now optional + reactive element 2023-08-26 17:32:58 +02:00
jsdom.d.ts 🚚 2023-09-13 21:06:13 +02:00
jsdom.js 🚚 2023-09-13 21:39:24 +02:00
LICENSE Initial commit 2023-08-22 16:29:37 +02:00
package-lock.json 🚧 types, linting, caching 2023-09-07 13:52:09 +02:00
package.json ♻️ 🔨 🐛 e.g. better namespace #18 2023-09-19 09:30:21 +02:00
README.md ♻️ Rename listen to on 2023-08-25 12:04:15 +02:00
signals.d.ts 🚚 2023-09-13 21:06:13 +02:00
signals.js ♻️ 🔨 🐛 e.g. better namespace #18 2023-09-19 09:30:21 +02:00

WIP (the experimentation phase) | source code on Gitea | mirrored on GitHub

Deka DOM Elements

This is reimplementation of jaandrle/dollar_dom_component: Functional DOM components without JSX and virtual DOM..

The goal is to be even more close to the native JavaScript.

Native JavaScript DOM elements creations

Lets go through all patterns we would like to use and what needs to be improved for better experience.

Creating element and DOM templates natively

document.body.append(
	document.createElement("div"),
	document.createElement("span"),
	document.createElement("main")
);
//=> HTML output: <div></div><span></span><main></main>
const template= document.createElement("main").append(
	document.createElement("div"),
	document.createElement("span"),
);
//=> ★:: typeof template==="undefined"

Pitfalls:

  • there is lots of text
  • .append methdo returns void⇒ it cannot be chained (see ★)

Set properties of created element

const element= Object.assign(document.createElement("p"), { className: "red", textContent: "paragraph" });
document.body.append(element);
//=> HTML output: <p class="red">paragraph</p>

Pitfalls:

  • there is lots of text
  • Object.assign isnt ideal as it can set only (some) IDL

Events and dynamic parts

const input= document.createElement("input");
const output= document.createElement("output");
input.addEventListener("change", function(event){
	output.value= event.target.value;
});
document.body.append(
	output,
	input
);
//=> HTML output: <output></output><input>

Pitfalls:

  • there is lots of text
  • very hard to organize code

Helpers and modifications

Now, let's introduce library helpers and modifications.

.append

The .append is owerwrote to always returns element. This seem to be the best way to do it as it is very hard to create Proxy around HTMLElement, ….

document.body.append(
	document.createElement("main").append(
		document.createElement("div"),
		document.createElement("span"),
	)
);
//=> HTML output: <main><div></div><span></span></main>

el and assign functions

const element= assign(document.createElement("a"), {
	className: "red",
	dataTest: "test",
	href: "www.seznam.cz",
	textContent: "Link",
	style: { color: "blue" }
});
document.body.append(element);
assign(element, { style: undefined });
//=> HTML output: <a href="www.seznam.cz" data-test="test" class="red">Link</a>

…but for elements/template creations el is even better:

document.body.append(
	el("div").append(
		el("p").append(
			el("#text", { textContent: "Link: " }),
			el("a", {
				href: "www.seznam.cz",
				textContent: "example",
			})
		)
	)
);

Events and signals for reactivity

investigation:

const value= S("");
document.body.append(
	el("span", { style: { fontWeight: "bold" }, textContent: value }),
	el("input", { type: "text" },
		on("change", event=> value(event.target.value)))
);