mirror of
				https://github.com/jaandrle/deka-dom-el
				synced 2025-11-04 07:09:15 +01:00 
			
		
		
		
	🔤 intro
This commit is contained in:
		
							
								
								
									
										14
									
								
								docs/components/examples/introducing/3ps-before.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								docs/components/examples/introducing/3ps-before.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
// pseudocode
 | 
			
		||||
// Mixed concerns make code hard to maintain
 | 
			
		||||
const button = document.querySelector('button');
 | 
			
		||||
let count = 0;
 | 
			
		||||
 | 
			
		||||
button.addEventListener('click', () => {
 | 
			
		||||
  count++;
 | 
			
		||||
  document.querySelector('p').textContent =
 | 
			
		||||
    'Clicked ' + count + ' times';
 | 
			
		||||
 | 
			
		||||
  if (count > 10) {
 | 
			
		||||
    button.disabled = true;
 | 
			
		||||
  }
 | 
			
		||||
});
 | 
			
		||||
@@ -1,6 +1,14 @@
 | 
			
		||||
// pseudo code!
 | 
			
		||||
const onchage=
 | 
			
		||||
	event=>
 | 
			
		||||
		console.log("Reacting to the:", event); // A
 | 
			
		||||
input.addEventListener("change", onchange); // B
 | 
			
		||||
input.dispatchEvent(new Event("change")); // C
 | 
			
		||||
// pseudocode
 | 
			
		||||
// 1. Create state
 | 
			
		||||
const count = S(0);
 | 
			
		||||
 | 
			
		||||
// 2. React to state changes
 | 
			
		||||
S.on(count, value => {
 | 
			
		||||
  updateUI(value);
 | 
			
		||||
  if (value > 10) disableButton();
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 3. Update state on events
 | 
			
		||||
button.addEventListener('click', () => {
 | 
			
		||||
  count.set(count.get() + 1);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,30 @@
 | 
			
		||||
import { el } from "deka-dom-el";
 | 
			
		||||
import { el, on } from "deka-dom-el";
 | 
			
		||||
import { S } from "deka-dom-el/signals";
 | 
			
		||||
const threePS= ({ emoji= "🚀" })=> {
 | 
			
		||||
	const clicks= S(0); // A
 | 
			
		||||
	return el().append(
 | 
			
		||||
		el("p", S(()=>
 | 
			
		||||
			"Hello World "+emoji.repeat(clicks.get()) // B
 | 
			
		||||
		)),
 | 
			
		||||
		el("button", {
 | 
			
		||||
			type: "button",
 | 
			
		||||
			onclick: ()=> clicks.set(clicks.get()+1), // C
 | 
			
		||||
			textContent: "Fire",
 | 
			
		||||
		})
 | 
			
		||||
	);
 | 
			
		||||
};
 | 
			
		||||
document.body.append(
 | 
			
		||||
	el(threePS, { emoji: "🎉" }),
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
// A HelloWorld component using the 3PS pattern
 | 
			
		||||
function HelloWorld({ emoji = "🚀" }) {
 | 
			
		||||
  // PART 1: Create reactive state
 | 
			
		||||
  const clicks = S(0);
 | 
			
		||||
  
 | 
			
		||||
  return el().append(
 | 
			
		||||
    // PART 2: Bind state to UI elements
 | 
			
		||||
    el("p", {
 | 
			
		||||
      className: "greeting",
 | 
			
		||||
      // This paragraph automatically updates when clicks changes
 | 
			
		||||
      textContent: S(() => `Hello World ${emoji.repeat(clicks.get())}`)
 | 
			
		||||
    }),
 | 
			
		||||
    
 | 
			
		||||
    // PART 3: Update state in response to events
 | 
			
		||||
    el("button", {
 | 
			
		||||
      type: "button",
 | 
			
		||||
      textContent: "Add emoji",
 | 
			
		||||
      // When clicked, update the state
 | 
			
		||||
      onclick: () => clicks.set(clicks.get() + 1)
 | 
			
		||||
    })
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Use the component in your app
 | 
			
		||||
document.body.append(
 | 
			
		||||
  el(HelloWorld, { emoji: "🎉" })
 | 
			
		||||
);
 | 
			
		||||
@@ -2,7 +2,7 @@ import { t, T } from "./utils/index.js";
 | 
			
		||||
export const info= {
 | 
			
		||||
	href: "./",
 | 
			
		||||
	title: t`Introduction`,
 | 
			
		||||
	description: t`Introducing a library.`,
 | 
			
		||||
	description: t`A lightweight, reactive DOM library for creating dynamic UIs with a declarative syntax`,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
import { el } from "deka-dom-el";
 | 
			
		||||
@@ -26,37 +26,86 @@ const references= {
 | 
			
		||||
export function page({ pkg, info }){
 | 
			
		||||
	const page_id= info.id;
 | 
			
		||||
	return el(simplePage, { info, pkg }).append(
 | 
			
		||||
		el("p", t`The library tries to provide pure JavaScript tool(s) to create reactive interfaces using …`),
 | 
			
		||||
 | 
			
		||||
		el(h3, t`Event-driven programming (3 parts separation ≡ 3PS)`),
 | 
			
		||||
		el("p").append(t`
 | 
			
		||||
			Let's introduce the basic principle on which the library is built. We'll use the JavaScript listener as
 | 
			
		||||
			a starting point.
 | 
			
		||||
		`),
 | 
			
		||||
		el(code, { src: fileURL("./components/examples/introducing/3ps.js"), page_id }),
 | 
			
		||||
		el("h2", t`Vanilla for flavouring — a full-fledged feast for large projects`),
 | 
			
		||||
		el("p").append(...T`
 | 
			
		||||
			As we can see, in the code at location “A” we define ${el("em", t`how to react`)} when the function
 | 
			
		||||
			is called with any event as an argument. At that moment, we ${el("em", t`don’t care who/why/how`)}
 | 
			
		||||
			the function was called. Similarly, at point “B”, we reference to a function to be called on the event
 | 
			
		||||
			${el("em", t`without caring`)} what the function will do at that time. Finally, at point “C”, we tell
 | 
			
		||||
			the application that a change has occurred, in the input, and we ${el("em", t`don't care if/how someone`)}
 | 
			
		||||
			is listening for the event.
 | 
			
		||||
			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.
 | 
			
		||||
		`),
 | 
			
		||||
		el("div", { className: "callout" }).append(
 | 
			
		||||
			el("h4", t`What Makes DDE Special`),
 | 
			
		||||
			el("ul").append(
 | 
			
		||||
				el("li", t`No build step required — use directly in the browser`),
 | 
			
		||||
				el("li", t`Lightweight core (~10-15kB minified) with zero dependencies`),
 | 
			
		||||
				el("li", t`Natural DOM API — work with real DOM nodes, not abstractions`),
 | 
			
		||||
				el("li", t`Built-in reactivity with powerful signals system`),
 | 
			
		||||
				el("li", t`Clean code organization with the 3PS pattern`)
 | 
			
		||||
			)
 | 
			
		||||
		),
 | 
			
		||||
		el(example, { src: fileURL("./components/examples/introducing/helloWorld.js"), page_id }),
 | 
			
		||||
 | 
			
		||||
		el(h3, t`The 3PS Pattern: A Better Way to Build UIs`),
 | 
			
		||||
		el("p").append(...T`
 | 
			
		||||
			The library introduces a new “type” of variable/constant called ${el("em", t`signal`)} allowing us to
 | 
			
		||||
			to use introduced 3PS pattern in our applications. As you can see it in the example above.
 | 
			
		||||
			At the heart of DDE 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.
 | 
			
		||||
		`),
 | 
			
		||||
		el("div", { className: "illustration" }).append(
 | 
			
		||||
			el("div", { className: "tabs" }).append(
 | 
			
		||||
				el("div", { className: "tab" }).append(
 | 
			
		||||
					el("h5", t`Traditional DOM Manipulation`),
 | 
			
		||||
					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(code, { src: fileURL("./components/examples/introducing/3ps.js"), page_id }),
 | 
			
		||||
				)
 | 
			
		||||
			)
 | 
			
		||||
		),
 | 
			
		||||
		el("p").append(...T`
 | 
			
		||||
			Also please notice that there is very similar 3PS pattern used for separate creation of UI and
 | 
			
		||||
			business logic.
 | 
			
		||||
			The 3PS pattern separates your code into three clear parts:
 | 
			
		||||
		`),
 | 
			
		||||
		el("ol").append(
 | 
			
		||||
			el("li").append(...T`
 | 
			
		||||
				${el("strong", "Create State")}: Define your application's reactive data using signals
 | 
			
		||||
			`),
 | 
			
		||||
			el("li").append(...T`
 | 
			
		||||
				${el("strong", "Bind to Elements")}: Define how UI elements react to state changes
 | 
			
		||||
			`),
 | 
			
		||||
			el("li").append(...T`
 | 
			
		||||
				${el("strong", "Update State")}: Modify state in response to user events or other triggers
 | 
			
		||||
			`)
 | 
			
		||||
		),
 | 
			
		||||
 | 
			
		||||
		el("p").append(...T`
 | 
			
		||||
			The 3PS is very simplified definition of the pattern. There are more deep/academic definitions more precisely
 | 
			
		||||
			describe usage in specific situations, see for example ${el("a", { textContent: t`MVVM`, ...references.w_mvv })}
 | 
			
		||||
			or ${el("a", { textContent: t`MVC`, ...references.w_mvc })}.
 | 
			
		||||
			By separating these concerns, your code becomes more modular, testable, and easier to maintain. This approach
 | 
			
		||||
			shares principles with more formal patterns like ${el("a", { textContent: "MVVM", ...references.w_mvv })} and
 | 
			
		||||
			${el("a", { textContent: "MVC", ...references.w_mvc })}, but with less overhead and complexity.
 | 
			
		||||
		`),
 | 
			
		||||
 | 
			
		||||
		el(h3, t`Organization of the documentation`),
 | 
			
		||||
		el("div", { className: "note" }).append(
 | 
			
		||||
			el("p").append(...T`
 | 
			
		||||
				The 3PS pattern becomes especially powerful when combined with components, allowing you to create
 | 
			
		||||
				reusable pieces of UI with encapsulated state and behavior. You'll learn more about this in the
 | 
			
		||||
				following sections.
 | 
			
		||||
			`)
 | 
			
		||||
		),
 | 
			
		||||
 | 
			
		||||
		el(h3, t`How to Use This Documentation`),
 | 
			
		||||
		el("p").append(...T`
 | 
			
		||||
			This guide will take you through DDE's features step by step:
 | 
			
		||||
		`),
 | 
			
		||||
		el("ol").append(
 | 
			
		||||
			el("li").append(...T`${el("strong", "Elements")} — Creating and manipulating DOM elements`),
 | 
			
		||||
			el("li").append(...T`${el("strong", "Events")} — Handling user interactions and lifecycle events`),
 | 
			
		||||
			el("li").append(...T`${el("strong", "Signals")} — Adding reactivity to your UI`),
 | 
			
		||||
			el("li").append(...T`${el("strong", "Scopes")} — Managing component lifecycles`),
 | 
			
		||||
			el("li").append(...T`${el("strong", "Custom Elements")} — Building web components`),
 | 
			
		||||
			el("li").append(...T`${el("strong", "Debugging")} — Tools to help you build and fix your apps`),
 | 
			
		||||
			el("li").append(...T`${el("strong", "SSR")} — Server-side rendering with DDE`)
 | 
			
		||||
		),
 | 
			
		||||
		el("p").append(...T`
 | 
			
		||||
			Each section builds on the previous ones, so we recommend following them in order.
 | 
			
		||||
			Let's get started with the basics of creating elements!
 | 
			
		||||
		`),
 | 
			
		||||
	);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user