1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2025-04-01 19:55:53 +02:00

Compare commits

...

4 Commits

Author SHA1 Message Date
e1f321004d Merge remote-tracking branch 'origin/main' 2025-03-07 21:50:05 +01:00
47c5fda8d6
🐛 DDE + dd<el> in md 2025-03-07 21:47:49 +01:00
7f3b818fa5
🐛 DDE + dd<el> in md 2025-03-07 21:45:44 +01:00
d742d960ac 🔤 dd<el>, iief 2025-03-07 21:32:15 +01:00
22 changed files with 142 additions and 118 deletions

View File

@ -6,7 +6,7 @@
<img src="docs/assets/logo.svg" alt="Deka DOM Elements Logo" width="180" height="180">
</p>
# Deka DOM Elements
# Deka DOM Elements (dd\<el\> or DDE)
***Vanilla for flavouring — a full-fledged feast for large projects***
@ -74,7 +74,7 @@ Creating reactive elements, components, and Web Components using the native
This library bridges the gap between minimal solutions like van/hyperscript and more comprehensive frameworks like
[solid-js](https://github.com/solidjs/solid), offering a balanced trade-off between size, complexity, and usability.
Following functional programming principles, Deka DOM Elements starts with pure JavaScript (DOM API) and gradually adds
Following functional programming principles, dd\<el\> starts with pure JavaScript (DOM API) and gradually adds
auxiliary functions. These range from minor improvements to advanced features for building complete declarative
reactive UI templates.
@ -94,9 +94,9 @@ into existing projects.
#### Direct Script
```html
<script src="https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/dde-with-signals.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/iife-with-signals.min.js"></script>
<script type="module">
const { el, S } = dde;
const { el, S } = DDE;
</script>
```

View File

@ -27,7 +27,7 @@ $.api("")
files: [ "signals" ],
filesOut(file){ return "dist/."+file; },
minify: "no",
dde: false,
iife: false,
});
return $.exit(regular);
})

View File

@ -1,16 +1,15 @@
#!/usr/bin/env -S npx nodejsscript
import { bundle, bundle as bundleDTS } from "dts-bundler";
const css= echo.css`
.info{ color: gray; }
`;
export async function build({ files, filesOut, minify= "partial", dde= true }){
export async function build({ files, filesOut, minify= "partial", iife= true }){
for(const file_root of files){
const file= file_root+".js";
echo(`Processing ${file} (minified: ${minify})`);
const out= filesOut(file);
const esbuild_output= buildEsbuild({ file, out, minify });
echoVariant(esbuild_output.stderr.split("\n")[1].trim()+ " (esbuild)");
echoVariant(esbuild_output.stderr.split("\n")[1].trim());
const file_dts= file_root+".d.ts";
const file_dts_out= filesOut(file_dts);
@ -21,26 +20,27 @@ export async function build({ files, filesOut, minify= "partial", dde= true }){
});
echoVariant(file_dts_out);
if(dde) toDDE(file, file_root);
if(iife) toIIFE(file, file_root);
}
return 0;
async function toDDE(file, file_root){
const name= "dde";
const out= filesOut(file_root+".js", name);
async function toIIFE(file, file_root){
const fileMark= "iife";
const name= "DDE";
const out= filesOut(file_root+".js", fileMark);
const params= [
"--format=iife",
"--global-name="+name,
];
const dde_output= buildEsbuild({ file, out, minify, params });
echoVariant(`${out} (${file} → globalThis.${name})`)
echoVariant(`${out} (${name})`)
const file_dts= file_root+".d.ts";
const file_dts_out= filesOut(file_dts, name);
const file_dts_out= filesOut(file_dts, fileMark);
echoVariant(file_dts_out, true);
buildDts({
name,
name: fileMark,
bundle: out,
entry: file_dts,
})

View File

@ -780,6 +780,6 @@ export {
elNS as createElementNS,
};
export as namespace dde;
export as namespace iife;
export {};

View File

@ -1,4 +1,4 @@
var dde = (() => {
var DDE = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;

View File

@ -780,6 +780,6 @@ export {
elNS as createElementNS,
};
export as namespace dde;
export as namespace iife;
export {};

File diff suppressed because one or more lines are too long

View File

@ -779,6 +779,6 @@ export {
elNS as createElementNS,
};
export as namespace dde;
export as namespace iife;
export {};

View File

@ -1,4 +1,4 @@
var dde = (() => {
var DDE = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;

View File

@ -779,6 +779,6 @@ export {
elNS as createElementNS,
};
export as namespace dde;
export as namespace iife;
export {};

File diff suppressed because one or more lines are too long

View File

@ -6,8 +6,29 @@
version="1.1"
id="svg5"
xml:space="preserve"
sodipodi:docname="logo.svg"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="3.296875"
inkscape:cx="128"
inkscape:cy="101.61137"
inkscape:window-width="1920"
inkscape:window-height="1052"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g2" /><defs
id="defs4"><linearGradient
id="bgGradient"
x1="18"
@ -45,14 +66,14 @@
style="fill:url(#bgGradient);stroke-width:1.13636"
ry="50" /><g
id="g2"
transform="translate(-3.5569814,-1.5165883)"><g
transform="translate(0.4430186,-1.5165883)"><g
id="g1"
transform="matrix(1.5900346,0,0,1.5900346,-121.12651,-66.626074)"><g
opacity="0.25"
fill="#ffffff"
filter="url(#glow)"
id="g5"
transform="matrix(0.55415879,0,0,0.56134669,110.90661,51.505106)"><path
transform="matrix(0.55415879,0,0,0.56134669,112.16444,51.505106)"><path
d="m 80,60 -30,68 30,68"
stroke="#ffffff"
stroke-width="8"
@ -66,6 +87,6 @@
d="m 152.28246,124.58038 q 0,-4.06854 1.24681,-7.15275 1.24681,-3.08421 3.28107,-5.15785 2.03427,-2.06051 4.65913,-3.11046 2.62486,-1.04994 5.38096,-1.04994 6.82464,0 10.3682,4.02916 3.54356,4.04228 3.54356,11.78562 0,0.78746 -0.0263,1.64054 -0.0394,0.85308 -0.10499,1.37805 h -20.01456 q 0,3.01859 2.49362,4.76412 2.49362,1.73241 6.43091,1.73241 2.42799,0 4.63287,-0.52497 2.19176,-0.52497 3.70106,-1.04995 l 1.11556,6.89026 q -2.09989,0.72184 -4.46226,1.20744 -2.36237,0.49872 -5.31534,0.49872 -3.93729,0 -7.04775,-1.02369 -3.12359,-1.01058 -5.31534,-3.00547 -2.20489,-2.00802 -3.38607,-4.96098 -1.18114,-2.95297 -1.18114,-6.89026 m 20.67077,-3.21546 q 0,-1.2468 -0.3281,-2.40174 -0.32811,-1.14182 -1.04995,-2.06052 -0.72183,-0.9187 -1.8374,-1.48304 -1.11557,-0.55123 -2.7561,-0.55123 -1.57492,0 -2.71673,0.52498 -1.15494,0.52497 -1.91615,1.44367 -0.74809,0.9187 -1.16806,2.09989 -0.43311,1.18119 -0.56435,2.42799 z m 40.75096,17.06159 q -0.19687,0.13125 -0.89245,0.45936 -0.68247,0.3281 -1.79803,0.69558 -1.11557,0.35436 -2.71673,0.61685 -1.61429,0.26248 -3.64856,0.26248 -5.57783,0 -8.13707,-3.32045 -2.55923,-3.30732 -2.55923,-9.67261 v -26.18298 h -8.5308 v -6.693389 h 16.60224 v 33.466969 q 0,3.14983 1.24681,4.26539 1.24681,1.11557 3.14983,1.11557 2.428,0 4.06853,-0.65621 1.64054,-0.65622 2.16551,-0.85308 z"
id="path1-3"
style="fill:#ff5252;stroke-width:1.31243" /></g><path
d="m 27.256467,130.12148 q 0,6.64555 2.489444,10.86495 2.468347,4.21939 7.953563,4.21939 1.582274,0 2.953578,-0.10548 1.371303,-0.10549 2.848092,-0.31646 v -27.00413 q -1.476789,-0.84388 -3.375517,-1.4346 -1.898728,-0.56962 -4.008427,-0.56962 -4.641336,0 -6.751034,3.69197 -2.109699,3.69198 -2.109699,10.65398 m 29.219322,23.62862 q -3.586487,1.16034 -8.755248,1.89873 -5.168761,0.7384 -10.126552,0.7384 -11.603341,0 -17.55269,-6.85651 -5.970447,-6.85652 -5.970447,-18.77632 0,-12.13076 5.021083,-19.15606 4.999985,-7.0042 14.810082,-7.0042 2.637123,0 5.168761,0.56962 2.531638,0.59072 4.430366,1.64557 V 84.235539 l 12.974645,-2.215183 z m 23.523136,-23.62862 q 0,6.64555 2.489444,10.86495 2.468344,4.21939 7.953559,4.21939 1.582268,0 2.953578,-0.10548 1.3713,-0.10549 2.84809,-0.31646 v -27.00413 q -1.47679,-0.84388 -3.37552,-1.4346 -1.89873,-0.56962 -4.008423,-0.56962 -4.64133,0 -6.75103,3.69197 -2.109698,3.69198 -2.109698,10.65398 m 29.219315,23.62862 q -3.58648,1.16034 -8.75524,1.89873 -5.168774,0.7384 -10.126562,0.7384 -11.603332,0 -17.552681,-6.85651 -5.970446,-6.85652 -5.970446,-18.77632 0,-12.13076 4.999984,-19.15606 5.021082,-7.0042 14.831178,-7.0042 2.63712,0 5.168753,0.56962 2.53164,0.59072 4.43037,1.64557 V 84.235539 l 12.974644,-2.215183 z"
d="m 25.256467,130.12148 q 0,6.64555 2.489444,10.86495 2.468347,4.21939 7.953563,4.21939 1.582274,0 2.953578,-0.10548 1.371303,-0.10549 2.848092,-0.31646 v -27.00413 q -1.476789,-0.84388 -3.375517,-1.4346 -1.898728,-0.56962 -4.008427,-0.56962 -4.641336,0 -6.751034,3.69197 -2.109699,3.69198 -2.109699,10.65398 m 29.219322,23.62862 q -3.586487,1.16034 -8.755248,1.89873 -5.168761,0.7384 -10.126552,0.7384 -11.603341,0 -17.55269,-6.85651 -5.970447,-6.85652 -5.970447,-18.77632 0,-12.13076 5.021083,-19.15606 4.999985,-7.0042 14.810082,-7.0042 2.637123,0 5.168761,0.56962 2.531638,0.59072 4.430366,1.64557 V 84.235539 l 12.974645,-2.215183 z m 23.523136,-23.62862 q 0,6.64555 2.489444,10.86495 2.468344,4.21939 7.953559,4.21939 1.582268,0 2.953578,-0.10548 1.3713,-0.10549 2.84809,-0.31646 v -27.00413 q -1.47679,-0.84388 -3.37552,-1.4346 -1.89873,-0.56962 -4.008423,-0.56962 -4.64133,0 -6.75103,3.69197 -2.109698,3.69198 -2.109698,10.65398 m 29.219315,23.62862 q -3.58648,1.16034 -8.75524,1.89873 -5.168774,0.7384 -10.126562,0.7384 -11.603332,0 -17.552681,-6.85651 -5.970446,-6.85652 -5.970446,-18.77632 0,-12.13076 4.999984,-19.15606 5.021082,-7.0042 14.831178,-7.0042 2.63712,0 5.168753,0.56962 2.53164,0.59072 4.43037,1.64557 V 84.235539 l 12.974644,-2.215183 z"
id="path1"
style="fill:#ff5252;stroke-width:2.1097;fill-opacity:0.66479665" /></g></svg>
style="fill:#ff5252;fill-opacity:0.664797;stroke-width:2.1097" /></g></svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -28,12 +28,12 @@ export function page({ pkg, info }){
const page_id= info.id;
return el(simplePage, { info, pkg }).append(
el("p").append(...T`
Welcome to Deka DOM Elements (DDE) a lightweight library for building dynamic UIs with a declarative
syntax that stays close to the native DOM API. DDE gives you powerful reactive tools without the complexity
and overhead of larger frameworks.
Welcome to Deka DOM Elements (dd<el> or DDE) a lightweight library for building dynamic UIs with
a declarative syntax that stays close to the native DOM API. dd<el> gives you powerful reactive tools
without the complexity and overhead of larger frameworks.
`),
el("div", { className: "callout" }).append(
el("h4", t`What Makes DDE Special`),
el("h4", t`What Makes dd<el> Special`),
el("ul").append(
el("li", t`No build step required — use directly in the browser`),
el("li", t`Lightweight core (~1015kB minified) with zero dependencies`),
@ -46,7 +46,7 @@ export function page({ pkg, info }){
el(h3, { textContent: t`The 3PS Pattern: A Better Way to Build UIs`, id: "h-3ps" }),
el("p").append(...T`
At the heart of DDE is the 3PS (3-Part Separation) pattern. This simple yet powerful approach helps you
At the heart of dd<el> is the 3PS (3-Part Separation) pattern. This simple yet powerful approach helps you
organize your UI code into three distinct areas, making your applications more maintainable and easier
to reason about.
`),
@ -57,7 +57,7 @@ export function page({ pkg, info }){
el(code, { src: fileURL("./components/examples/introducing/3ps-before.js"), page_id }),
),
el("div", { className: "tab" }).append(
el("h5", t`DDE's 3PS Pattern`),
el("h5", t`dd<el>'s 3PS Pattern`),
el(code, { src: fileURL("./components/examples/introducing/3ps.js"), page_id }),
)
)
@ -94,7 +94,7 @@ export function page({ pkg, info }){
el(h3, t`How to Use This Documentation`),
el("p").append(...T`
This guide will take you through DDE's features step by step:
This guide will take you through dd<el>'s features step by step:
`),
el("ol").append(
el("li").append(...T`${el("strong", "Elements")} — Creating and manipulating DOM elements`),
@ -106,7 +106,7 @@ export function page({ pkg, info }){
el("li").append(...T`${el("strong", "Extensions")} — Integrating third-party functionalities`),
el("li").append(...T`${el("strong", "Ireland Components")}
Creating interactive demos with server-side pre-rendering`),
el("li").append(...T`${el("strong", "SSR")} — Server-side rendering with DDE`)
el("li").append(...T`${el("strong", "SSR")} — Server-side rendering with dd<el>`)
),
el("p").append(...T`
Each section builds on the previous ones, so we recommend following them in order.

View File

@ -51,11 +51,11 @@ export function page({ pkg, info }){
return el(simplePage, { info, pkg }).append(
el("p").append(...T`
Building user interfaces in JavaScript often involves creating and manipulating DOM elements.
DDE provides a simple yet powerful approach to element creation that is declarative, chainable,
dd<el> provides a simple yet powerful approach to element creation that is declarative, chainable,
and maintains a clean syntax close to HTML structure.
`),
el("div", { class: "callout" }).append(
el("h4", t`DDE Elements: Key Benefits`),
el("h4", t`dd<el> Elements: Key Benefits`),
el("ul").append(
el("li", t`Declarative element creation with intuitive property assignment`),
el("li", t`Chainable methods for natural DOM tree construction`),
@ -67,7 +67,7 @@ export function page({ pkg, info }){
el(code, { src: fileURL("./components/examples/elements/intro.js"), page_id }),
el(h3, t`Creating Elements: Native vs DDE`),
el(h3, t`Creating Elements: Native vs dd<el>`),
el("p").append(...T`
In standard JavaScript, you create DOM elements using the
${el("a", references.mdn_create).append(el("code", "document.createElement()"))} method
@ -80,7 +80,7 @@ export function page({ pkg, info }){
el(code, { src: fileURL("./components/examples/elements/native-dom-create.js"), page_id })
),
el("div").append(
el("h5", t`DDE Approach`),
el("h5", t`dd<el> Approach`),
el(code, { src: fileURL("./components/examples/elements/dde-dom-create.js"), page_id })
)
)
@ -93,9 +93,9 @@ export function page({ pkg, info }){
el(h3, t`Advanced Property Assignment`),
el("p").append(...T`
The ${el("code", "assign")} function is the heart of DDE's element property handling. It is internally used
to assign properties using the ${el("code", "el")} function. ${el("code", "assign")} provides intelligent
assignment of both properties (IDL) and attributes:
The ${el("code", "assign")} function is the heart of dd<el>'s element property handling. It is internally
used to assign properties using the ${el("code", "el")} function. ${el("code", "assign")} provides
intelligent assignment of both properties (IDL) and attributes:
`),
el("div", { class: "function-table" }).append(
el("dl").append(
@ -130,8 +130,8 @@ export function page({ pkg, info }){
el(h3, t`Building DOM Trees with Chainable Methods`),
el("p").append(...T`
One of the most powerful features of DDE is its approach to building element trees.
Unlike the native DOM API which doesn't return the parent after appendChild(), DDE's
One of the most powerful features of dd<el> is its approach to building element trees.
Unlike the native DOM API which doesn't return the parent after appendChild(), dd<el>'s
append() always returns the parent element:
`),
el("div", { class: "illustration" }).append(
@ -141,7 +141,7 @@ export function page({ pkg, info }){
el(code, { src: fileURL("./components/examples/elements/native-dom-tree.js"), page_id })
),
el("div", { class: "good-practice" }).append(
el("h5", t`DDE Approach`),
el("h5", t`dd<el> Approach`),
el(code, { src: fileURL("./components/examples/elements/dde-dom-tree.js"), page_id })
)
)
@ -172,8 +172,9 @@ export function page({ pkg, info }){
el(h3, t`Working with SVG and Other Namespaces`),
el("p").append(...T`
For non-HTML elements like SVG, MathML, or custom namespaces, DDE provides the ${el("code", "elNS")} function
which corresponds to the native ${el("a", references.mdn_ns).append(el("code", "document.createElementNS"))}:
For non-HTML elements like SVG, MathML, or custom namespaces, dd<el> provides the ${el("code", "elNS")}
function which corresponds to the native ${el("a", references.mdn_ns).append(el("code",
"document.createElementNS"))}:
`),
el(example, { src: fileURL("./components/examples/elements/dekaElNS.js"), page_id }),
el("p").append(...T`

View File

@ -47,12 +47,12 @@ export function page({ pkg, info }){
const page_id= info.id;
return el(simplePage, { info, pkg }).append(
el("p").append(...T`
Events are at the core of interactive web applications. DDE provides a clean, declarative approach to
Events are at the core of interactive web applications. dd<el> provides a clean, declarative approach to
handling DOM events and extends this pattern with a powerful Addon system to incorporate additional
functionalities into your UI templates.
`),
el("div", { className: "callout" }).append(
el("h4", t`Why DDE's Event System and Addons Matters`),
el("h4", t`Why dd<el>'s Event System and Addons Matters`),
el("ul").append(
el("li", t`Integrate event handling directly in element declarations`),
el("li", t`Leverage lifecycle events for better component design`),
@ -68,7 +68,8 @@ export function page({ pkg, info }){
el("p").append(...T`
In JavaScript you can listen to native DOM events using
${el("a", references.mdn_listen).append(el("code", "element.addEventListener(type, listener, options)"))}.
DDE provides an alternative approach with arguments ordered differently to better fit its declarative style:
dd<el> provides an alternative approach with arguments ordered differently to better fit its declarative
style:
`),
el("div", { className: "illustration" }).append(
el("div", { className: "tabs" }).append(
@ -77,13 +78,13 @@ export function page({ pkg, info }){
el(code, { content: `element.addEventListener('click', callback, options);`, page_id })
),
el("div", { className: "tab" }).append(
el("h5", t`DDE Approach`),
el("h5", t`dd<el> Approach`),
el(code, { content: `on('click', callback, options)(element);`, page_id })
)
)
),
el("p").append(...T`
The main benefit of DDE's approach is that it works as an Addon, making it easy to integrate
The main benefit of dd<el>'s approach is that it works as an Addon, making it easy to integrate
directly into element declarations.
`),
el(example, { src: fileURL("./components/examples/events/compare.js"), page_id }),
@ -91,7 +92,7 @@ export function page({ pkg, info }){
el(h3, t`Removing Event Listeners`),
el("div", { className: "note" }).append(
el("p").append(...T`
Unlike the native addEventListener/removeEventListener pattern, DDE uses the ${el("a", {
Unlike the native addEventListener/removeEventListener pattern, dd<el> uses the ${el("a", {
textContent: "AbortSignal", ...references.mdn_abortListener })} for declarative approach for removal:
`)
),
@ -126,7 +127,7 @@ export function page({ pkg, info }){
el(h3, t`Understanding Addons`),
el("p").append(...T`
Addons are a powerful pattern in DDE that extends beyond just event handling.
Addons are a powerful pattern in dd<el> that extends beyond just event handling.
An Addon is any function that accepts an HTML element as its first parameter.
`),
el("div", { className: "callout" }).append(
@ -155,7 +156,7 @@ export function page({ pkg, info }){
You can think of an Addon as an "oncreate" event handler.
`),
el("p").append(...T`
DDE provides three additional lifecycle events that correspond to custom element lifecycle callbacks:
dd<el> provides three additional lifecycle events that correspond to custom element lifecycle callbacks:
`),
el("div", { className: "function-table" }).append(
el("dl").append(
@ -173,7 +174,7 @@ export function page({ pkg, info }){
el("div", { className: "note" }).append(
el("p").append(...T`
For regular elements (non-custom elements), DDE uses
For regular elements (non-custom elements), dd<el> uses
${el("a", references.mdn_mutation).append(el("code", "MutationObserver"), " | MDN")}
internally to track lifecycle events.
`)
@ -194,7 +195,7 @@ export function page({ pkg, info }){
see section later in documentation regarding hosts elements
`),
el("li").append(...T`
DDE ensures that connected/disconnected events fire only once for better predictability
dd<el> ensures that connected/disconnected events fire only once for better predictability
`)
)
),

View File

@ -45,7 +45,7 @@ export function page({ pkg, info }){
const page_id= info.id;
return el(simplePage, { info, pkg }).append(
el("p").append(...T`
Signals provide a simple yet powerful way to create reactive applications with DDE. They handle the
Signals provide a simple yet powerful way to create reactive applications with dd<el>. They handle the
fundamental challenge of keeping your UI in sync with changing data in a declarative, efficient way.
`),
el("div", { class: "callout" }).append(
@ -197,7 +197,7 @@ items.push("New todo");
el(h3, t`Connecting Signals to the DOM`),
el("p").append(...T`
Signals really shine when connected to your UI. DDE provides several ways to bind signals to DOM elements:
Signals really shine when connected to your UI. dd<el> provides several ways to bind signals to DOM elements:
`),
el("div", { class: "tabs" }).append(

View File

@ -99,7 +99,7 @@ function MyComponent() {
el(h3, t`Class-Based Components`),
el("p").append(...T`
While functional components are the primary pattern in DDE, you can also create class-based components.
While functional components are the primary pattern in dd<el>, you can also create class-based components.
For this, we implement function ${el("code", "elClass")} and use it to demonstrate implementation details
for better understanding of the scope logic.
`),
@ -114,7 +114,7 @@ function MyComponent() {
el("h4", t`Lifecycle Flow`),
el("pre").append(el("code", `
1. Component created scope established
2. Component added to DOM connected event
2. Component add<el> to DOM connected event
3. Component interactions happen
4. Component removed from DOM disconnected event
5. Automatic cleanup of:
@ -177,7 +177,8 @@ function MyComponent() {
${el("strong", "Keep components focused:")} Each component should do one thing well
`),
el("li").append(...T`
${el("strong", "Add explicit cleanup:")} For resources not managed by DDE, use ${el("code", "on.disconnected")}
${el("strong", "Add explicit cleanup:")} For resources not managed by dd<el>, use ${el("code",
"on.disconnected")}
`)
),

View File

@ -1,8 +1,8 @@
import { T, t } from "./utils/index.js";
export const info= {
title: t`Web Components`,
fullTitle: t`Using Web Components with DDE: Better Together`,
description: t`Using custom elements in combination with DDE`,
fullTitle: t`Using Web Components with dd<el>: Better Together`,
description: t`Using custom elements in combination with dd<el>`,
};
import { el } from "deka-dom-el";
@ -55,12 +55,12 @@ export function page({ pkg, info }){
const page_id= info.id;
return el(simplePage, { info, pkg }).append(
el("p").append(...T`
DDE pairs powerfully with ${el("a", references.mdn_web_components).append(el("strong", t`Web Components`))}
to create reusable, encapsulated custom elements with all the benefits of DDE's declarative DOM
construction and reactivity system.
dd<el> pairs powerfully with ${el("a", references.mdn_web_components).append(el("strong", t`Web
Components`))} to create reusable, encapsulated custom elements with all the benefits of dd<el>'s
declarative DOM construction and reactivity system.
`),
el("div", { className: "callout" }).append(
el("h4", t`Why Combine DDE with Web Components?`),
el("h4", t`Why Combine dd<el> with Web Components?`),
el("ul").append(
el("li", t`Declarative DOM creation within your components`),
el("li", t`Reactive attribute updates through signals`),
@ -88,7 +88,7 @@ export function page({ pkg, info }){
`)
),
el("p").append(...T`
Let's start with a basic Custom Element example without DDE to establish the foundation:
Let's start with a basic Custom Element example without dd<el> to establish the foundation:
`),
el(code, { src: fileURL("./components/examples/customElement/native-basic.js"), page_id }),
@ -101,17 +101,17 @@ export function page({ pkg, info }){
`)
),
el(h3, t`DDE Integration: Step 1 - Event Handling`),
el(h3, t`dd<el> Integration: Step 1 - Event Handling`),
el("p").append(...T`
The first step in integrating DDE with Web Components is enabling DDE's event system to work with your
The first step in integrating dd<el> with Web Components is enabling dd<el>'s event system to work with your
Custom Elements. This is done with ${el("code", "customElementWithDDE")}, which makes your Custom Element
compatible with DDE's event handling.
compatible with dd<el>'s event handling.
`),
el("div", { className: "function-table" }).append(
el("h4", t`customElementWithDDE`),
el("dl").append(
el("dt", t`Purpose`),
el("dd", t`Enables DDE's event system to work with your Custom Element`),
el("dd", t`Enables dd<el>'s event system to work with your Custom Element`),
el("dt", t`Usage`),
el("dd", t`customElementWithDDE(YourElementClass)`),
el("dt", t`Benefits`),
@ -123,20 +123,20 @@ export function page({ pkg, info }){
el("div", { className: "tip" }).append(
el("p").append(...T`
${el("strong", "Key Point:")} The ${el("code", "customElementWithDDE")} function adds event dispatching
to your Custom Element lifecycle methods, making them work seamlessly with DDE's event system.
to your Custom Element lifecycle methods, making them work seamlessly with dd<el>'s event system.
`)
),
el(h3, t`DDE Integration: Step 2 - Rendering Components`),
el(h3, t`dd<el> Integration: Step 2 - Rendering Components`),
el("p").append(...T`
The next step is to use DDE's component rendering within your Custom Element. This is done with
${el("code", "customElementRender")}, which connects your DDE component function to the Custom Element.
The next step is to use dd<el>'s component rendering within your Custom Element. This is done with
${el("code", "customElementRender")}, which connects your dd<el> component function to the Custom Element.
`),
el("div", { className: "function-table" }).append(
el("h4", t`customElementRender`),
el("dl").append(
el("dt", t`Purpose`),
el("dd", t`Connects a DDE component function to a Custom Element`),
el("dd", t`Connects a dd<el> component function to a Custom Element`),
el("dt", t`Parameters`),
el("dd").append(
el("ol").append(
@ -160,8 +160,8 @@ export function page({ pkg, info }){
el(h3, t`Reactive Web Components with Signals`),
el("p").append(...T`
One of the most powerful features of integrating DDE with Web Components is connecting HTML attributes
to DDE's reactive signals system. This creates truly reactive custom elements.
One of the most powerful features of integrating dd<el> with Web Components is connecting HTML attributes
to dd<el>'s reactive signals system. This creates truly reactive custom elements.
`),
el("div", { className: "tip" }).append(
el("p").append(...T`
@ -186,7 +186,7 @@ export function page({ pkg, info }){
el("h4", t`How S.observedAttributes Works`),
el("ol").append(
el("li", t`Takes each attribute listed in static observedAttributes`),
el("li", t`Creates a DDE signal for each one`),
el("li", t`Creates a dd<el> signal for each one`),
el("li", t`Automatically updates these signals when attributes change`),
el("li", t`Passes the signals to your component function`),
el("li", t`Your component reacts to changes through signal subscriptions`)
@ -195,7 +195,7 @@ export function page({ pkg, info }){
el(h3, t`Working with Shadow DOM`),
el("p").append(...T`
Shadow DOM provides encapsulation for your component's styles and markup. When using DDE with Shadow DOM,
Shadow DOM provides encapsulation for your component's styles and markup. When using dd<el> with Shadow DOM,
you get the best of both worlds: encapsulation plus declarative DOM creation.
`),
el("div", { className: "illustration" }).append(
@ -205,7 +205,7 @@ export function page({ pkg, info }){
  
    #shadow-root
      Created with DDE:
      Created with dd<el>
    
      <div>
       <h2>Title</h2>
@ -236,9 +236,9 @@ export function page({ pkg, info }){
)
),
el(h3, t`Best Practices for Web Components with DDE`),
el(h3, t`Best Practices for Web Components with dd<el>`),
el("p").append(...T`
When combining DDE with Web Components, follow these recommendations:
When combining dd<el> with Web Components, follow these recommendations:
`),
el("ol").append(
el("li").append(...T`

View File

@ -1,8 +1,8 @@
import { T, t } from "./utils/index.js";
export const info= {
title: t`Debugging`,
fullTitle: t`Debugging applications with deka-dom-el`,
description: t`Techniques for debugging applications using deka-dom-el, especially signals.`,
fullTitle: t`Debugging applications with dd<el>`,
description: t`Techniques for debugging applications using dd<el>, especially signals.`,
};
import { el } from "deka-dom-el";
@ -19,7 +19,7 @@ export function page({ pkg, info }){
return el(simplePage, { info, pkg }).append(
el("p").append(...T`
Debugging is an essential part of application development. This guide provides techniques
and best practices for debugging applications built with deka-dom-el, with a focus on signals.
and best practices for debugging applications built with dd<el>, with a focus on signals.
`),
el(h3, t`Debugging signals`),
@ -87,14 +87,14 @@ console.log('Current value:', signal.valueOf());
),
el(code, { src: fileURL("./components/examples/debugging/debouncing.js"), page_id }),
el(h3, t`Browser DevTools tips for deka-dom-el`),
el(h3, t`Browser DevTools tips for dd<el>`),
el("p").append(...T`
When debugging in the browser, deka-dom-el provides several helpful DevTools-friendly features:
When debugging in the browser, dd<el> provides several helpful DevTools-friendly features:
`),
el("h4", t`Identifying components in the DOM`),
el("p").append(...T`
deka-dom-el marks components in the DOM with special comment nodes to help you identify component boundaries.
dd<el> marks components in the DOM with special comment nodes to help you identify component boundaries.
Components created with ${el("code", "el(ComponentFunction)")} are marked with comment nodes
${el("code", "<!--<dde:mark type=\"component\" name=\"MyComponent\" host=\"parentElement\"/>-->")} and
includes:
@ -107,7 +107,7 @@ console.log('Current value:', signal.valueOf());
el("h4", t`Finding reactive elements in the DOM`),
el("p").append(...T`
When using ${el("code", "S.el()")}, deka-dom-el creates reactive elements in the DOM
When using ${el("code", "S.el()")}, dd<el> creates reactive elements in the DOM
that are automatically updated when signal values change. These elements are wrapped in special
comment nodes for debugging (to be true they are also used internally, so please do not edit them by hand):
`),
@ -120,7 +120,7 @@ console.log('Current value:', signal.valueOf());
el("h4", t`DOM inspection properties`),
el("p").append(...T`
Elements created with the deka-dom-el library have special properties to aid in debugging:
Elements created with the dd<el> library have special properties to aid in debugging:
`),
el("p").append(...T`
${el("code", "<element>.__dde_reactive")} - An array property on DOM elements that tracks signal-to-element
@ -160,7 +160,7 @@ console.log('Current value:', signal.valueOf());
`),
el("ul").append(
el("li", "signal — the signal triggering the changes"),
el("li", "listener — the listener function (this is an internal function for DDE)"),
el("li", "listener — the listener function (this is an internal function for dd<el>)"),
el("li", "element — the DOM element that is bound to the signal"),
el("li", "property — the attribute or property name which is changing based on the signal"),
),

View File

@ -1,8 +1,8 @@
import { T, t } from "./utils/index.js";
export const info= {
title: t`Extensions and 3rd Party`,
fullTitle: t`Extending deka-dom-el with Third-Party Functionalities`,
description: t`How to extend deka-dom-el with third-party libraries and custom functionalities.`,
fullTitle: t`Extending dd<el> with Third-Party Functionalities`,
description: t`How to extend dd<el> with third-party libraries and custom functionalities.`,
};
import { el } from "deka-dom-el";
@ -17,14 +17,14 @@ export function page({ pkg, info }){
const page_id= info.id;
return el(simplePage, { info, pkg }).append(
el("p").append(...T`
deka-dom-el is designed with extensibility in mind. This page covers how to separate
dd<el> is designed with extensibility in mind. This page covers how to separate
third-party functionalities and integrate them seamlessly with the library, focusing on
proper resource cleanup and interoperability.
`),
el(h3, t`DOM Element Extensions with Addons`),
el("p").append(...T`
The primary method for extending DOM elements in deka-dom-el is through the Addon pattern.
The primary method for extending DOM elements in dd<el> is through the Addon pattern.
Addons are functions that take an element and applying some functionality to it. This pattern enables a
clean, functional approach to element enhancement.
`),
@ -55,7 +55,7 @@ el("div", { id: "example" }, myAddon({ option: "value" }));
el("p").append(...T`
When extending elements with functionality that uses resources like event listeners, timers,
or external subscriptions, it's critical to clean up these resources when the element is removed
from the DOM. deka-dom-el provides utilities for this through AbortSignal integration.
from the DOM. dd<el> provides utilities for this through AbortSignal integration.
`),
el("div", { className: "tip" }).append(
el("p").append(...T`
@ -111,7 +111,7 @@ function enhancementElement({ signal, ...config }) {
el("div", { className: "tab" }).append(
el("h5", t`⚠️ Library-Dependent`),
el(code, { content: `
// Tightly coupled to deka-dom-el
// Tightly coupled to dd<el>
function enhancementElement(config) {
return function(element) {
// do something
@ -127,7 +127,7 @@ function enhancementElement(config) {
el(h3, t`Signal Extensions and Future Compatibility`),
el("p").append(...T`
Unlike DOM elements, signal functionality in deka-dom-el currently lacks a standardized
Unlike DOM elements, signal functionality in dd<el> currently lacks a standardized
way to create library-independent extensions. This is because signals are implemented
differently across libraries.
`),
@ -135,7 +135,7 @@ function enhancementElement(config) {
el("p").append(...T`
In the future, JavaScript may include built-in signals through the
${el("a", { href: "https://github.com/tc39/proposal-signals", textContent: "TC39 Signals Proposal" })}.
deka-dom-el is designed with future compatibility in mind and will hopefully support these
dd<el> is designed with future compatibility in mind and will hopefully support these
native signals without breaking changes when they become available.
`)
),
@ -241,7 +241,7 @@ console.log(doubled.get()); // 10`, page_id }),
are disconnected`),
el("dt", t`Tight coupling with library internals`),
el("dd", t`Focus on standard DOM APIs and clean interfaces rather than depending on deka-dom-el
el("dd", t`Focus on standard DOM APIs and clean interfaces rather than depending on dd<el>
implementation details`),
el("dt", t`Mutating element prototypes`),

View File

@ -1,8 +1,8 @@
import { T, t } from "./utils/index.js";
export const info= {
title: t`Server-Side Rendering (SSR)`,
fullTitle: t`Server-Side Rendering with deka-dom-el`,
description: t`Using deka-dom-el for server-side rendering with jsdom to generate static HTML.`,
fullTitle: t`Server-Side Rendering with dd<el>`,
description: t`Using dd<el> for server-side rendering with jsdom to generate static HTML.`,
};
import { el } from "deka-dom-el";
@ -22,11 +22,11 @@ export function page({ pkg, info }){
3rd-party libraries. It describes an advanced feature, not a core part of the library. Most users will
not need to implement this functionality directly in their applications. This capability will hopefully
be covered by third-party libraries or frameworks that provide simpler SSR integration using
deka-dom-el.
dd<el>.
`)
),
el("p").append(...T`
deka-dom-el isn't limited to browser environments. Thanks to its flexible architecture,
dd<el> isn't limited to browser environments. Thanks to its flexible architecture,
it can be used for server-side rendering (SSR) to generate static HTML files.
This is achieved through integration with for example ${el("a", { href: "https://github.com/tmpvar/jsdom",
textContent: "jsdom" })}, a JavaScript implementation of web standards for Node.js.
@ -47,12 +47,12 @@ export function page({ pkg, info }){
el(h3, t`How jsdom Integration Works`),
el("p").append(...T`
The jsdom export in deka-dom-el provides the necessary tools to use the library in Node.js
The jsdom export in dd<el> provides the necessary tools to use the library in Node.js
by integrating with jsdom. Here's what it does:
`),
el("ol").append(
el("li", t`Creates a virtual DOM environment in Node.js using jsdom`),
el("li", t`Registers DOM globals like HTMLElement, document, etc. for deka-dom-el to use`),
el("li", t`Registers DOM globals like HTMLElement, document, etc. for dd<el> to use`),
el("li", t`Sets an SSR flag in the environment to enable SSR-specific behaviors`),
el("li", t`Provides a promise queue system for managing async operations during rendering`),
el("li", t`Handles DOM property/attribute mapping differences between browsers and jsdom`)
@ -61,14 +61,14 @@ export function page({ pkg, info }){
el(h3, t`Basic SSR Example`),
el("p").append(...T`
Here's a simple example of how to use deka-dom-el for server-side rendering in a Node.js script:
Here's a simple example of how to use dd<el> for server-side rendering in a Node.js script:
`),
el(code, { src: fileURL("./components/examples/ssr/basic-example.js"), page_id }),
el(h3, t`Building a Static Site Generator`),
el("p").append(...T`
You can build a complete static site generator with deka-dom-el. In fact, this documentation site
is built using deka-dom-el for server-side rendering! Here's how the documentation build process works:
You can build a complete static site generator with dd<el>. In fact, this documentation site
is built using dd<el> for server-side rendering! Here's how the documentation build process works:
`),
el(code, { src: fileURL("./components/examples/ssr/static-site-generator.js"), page_id }),
@ -109,7 +109,7 @@ export function page({ pkg, info }){
el(h3, t`SSR Considerations and Limitations`),
el("p").append(...T`
When using deka-dom-el for SSR, keep these considerations in mind:
When using dd<el> for SSR, keep these considerations in mind:
`),
el("ul").append(
el("li", t`Browser-specific APIs like window.localStorage are not available in jsdom by default`),
@ -124,7 +124,7 @@ export function page({ pkg, info }){
el(h3, t`Real Example: How This Documentation is Built`),
el("p").append(...T`
This documentation site itself is built using deka-dom-el's SSR capabilities.
This documentation site itself is built using dd<el>'s SSR capabilities.
The build process collects all page components, renders them with jsdom, and outputs static HTML files.
`),
el(code, { src: fileURL("./components/examples/ssr/static-site-generator.js"), page_id }),

View File

@ -24,7 +24,7 @@ export function page({ pkg, info }){
3rd-party libraries. It describes an advanced feature, not a core part of the library. Most users will
not need to implement this functionality directly in their applications. This capability will hopefully
be covered by third-party libraries or frameworks that provide simpler SSR integration using
deka-dom-el.
dd<el>.
`)
),
@ -103,7 +103,7 @@ for(const { id, info } of pages) {
const serverDOM = createHTMl("");
serverDOM.registerGlobally("HTMLScriptElement");
// Register deka-dom-el with the virtual DOM
// Register dd<el> with the virtual DOM
const { el } = await register(serverDOM.dom);
// Import and render the page component
@ -355,7 +355,7 @@ export function loadIrelands(store) {
el("p").append(...T`
This documentation site itself is built using the techniques described here,
showcasing how deka-dom-el can be used to create both the documentation and
showcasing how dd<el> can be used to create both the documentation and
the interactive examples within it. The implementation here is simplified for clarity,
while a production-ready system would need to address the considerations above.
`)