1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2026-01-11 08:16:29 +01:00

v0.9.2 — 🐛 types, on.defer and other small (#36)

* 🔤  T now uses DocumentFragment

* 🔤

* 🔤 

* 🐛 lint

*  cleanup

*  🔤 lib download

*  🔤 ui

*  reorganize files

*  on.host

* 🐛 on.* types

*  🔤 cdn

* 🔤 converter

* 🐛 signal.set(value, force)

*  🔤

* 🔤  converter - convert also comments

*  bs/build

* 🔤 ui p14

* 🔤

* 🔤 Examples

* 🔤

* 🐛 now only el(..., string|number)

* 🐛 fixes #38

* 🔤

*  on.host → on.defer

* 🔤

* 📺
This commit is contained in:
2025-03-16 11:30:42 +01:00
committed by GitHub
parent 25d475ec04
commit f0dfdfde54
83 changed files with 4624 additions and 2919 deletions

View File

@@ -2,7 +2,7 @@ import { T, t } from "./utils/index.js";
export const info= {
title: t`Appendix & Summary`,
fullTitle: t`dd<el> Comprehensive Reference`,
description: t`A final overview, case studies, key concepts, and best practices for working with deka-dom-el.`,
description: t`A final overview, case studies, key concepts, and best practices for working with deka-dom-el.`,
};
import { el } from "deka-dom-el";
@@ -25,6 +25,16 @@ const references= {
performance: {
title: t`Performance Optimization Guide`,
href: "p09-optimization.html",
},
/** Examples gallery */
examples: {
title: t`Examples Gallery`,
href: "p15-examples.html",
},
/** Converter */
converter: {
title: t`HTML to dd<el> Converter`,
href: "p14-converter.html",
}
};
@@ -32,56 +42,64 @@ const references= {
export function page({ pkg, info }){
const page_id= info.id;
return el(simplePage, { info, pkg }).append(
el("p").append(...T`
This reference guide provides a comprehensive summary of dd<el>'s key concepts, best practices,
case studies, and advanced techniques. Use it as a quick reference when working with the library
el("p").append(T`
This reference guide provides a comprehensive summary of dd<el>s key concepts, best practices,
case studies, and advanced techniques. Use it as a quick reference when working with the library
or to deepen your understanding of its design principles and patterns.
`),
el(h3, t`Core Principles of dd<el>`),
el("p").append(...T`
el("p").append(T`
At its foundation, dd<el> is built on several core principles that shape its design and usage:
`),
el("div", { className: "callout" }).append(
el("h4", t`Guiding Principles`),
el("ul").append(
el("li").append(...T`
el("li").append(T`
${el("strong", "DOM-First Approach:")} Working directly with the real DOM instead of virtual DOM
abstractions
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "Declarative Syntax:")} Creating UIs by describing what they should look like, not
how to create them
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "Minimal Overhead:")} Staying close to standard Web APIs without unnecessary
abstractions
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "Progressive Enhancement:")} Starting simple and adding complexity only when needed
`),
el("li").append(...T`
${el("strong", "Functional Composition:")} Building UIs through function composition rather than
inheritance
el("li").append(T`
${el("strong", "Flexibility:")} Using what you need, whether thats plain DOM elements, event
handling, or signals for reactivity
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "Functional Composition:")} Building UIs through function composition
`),
el("li").append(T`
${el("strong", "Clear Patterns:")} Promoting maintainable code organization with the 3PS pattern
`),
el("li").append(...T`
${el("strong", "Targeted Reactivity:")} Using signals for efficient, fine-grained updates
el("li").append(T`
${el("strong", "Targeted Reactivity:")} Using signals for efficient, fine-grained updates only when
needed
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "Unix Philosophy:")} Doing one thing well and allowing composability with other tools
`)
)
),
el(h3, t`Case Studies & Real-World Applications`),
el("p").append(T`
Explore our ${el("a", references.examples).append("Examples Gallery")} to see how dd<el> can be used to build
various real-world applications, from simple components to complex interactive UIs.
`),
el("h4", t`TodoMVC Implementation`),
el("p").append(...T`
The ${el("a", references.todomvc).append("TodoMVC implementation")} showcases how dd<el> handles a complete,
real-world application with all standard features of a modern web app:
el("p").append(T`
The ${el("a", references.todomvc).append("TodoMVC implementation")} showcases how dd<el> handles a complete,
real-world application with all standard features of a modern web app:
`),
el("ul").append(
el("li", t`Persistent storage with localStorage`),
@@ -92,41 +110,112 @@ export function page({ pkg, info }){
el("li", t`Custom event system for component communication`),
el("li", t`Proper focus management and accessibility`)
),
el("p").append(...T`
el("p").append(T`
Key takeaways from the TodoMVC example:
`),
el("ul").append(
el("li").append(...T`
el("li").append(T`
Signal factories like ${el("code", "routerSignal")} and ${el("code", "todosSignal")}
encapsulate related functionality
`),
el("li").append(...T`
el("li").append(T`
Custom events provide clean communication between components
`),
el("li").append(...T`
el("li").append(T`
Targeted memoization improves rendering performance dramatically
`),
el("li").append(...T`
el("li").append(T`
Derived signals simplify complex UI logic like filtering
`)
),
el("h4", t`Using Signals Appropriately`),
el("p").append(T`
While signals provide powerful reactivity for complex UI interactions, theyre not always necessary.
`),
el("div", { className: "tabs" }).append(
el("div", { className: "tab", dataTab: "events" }).append(
el("h4", t`We can process form events without signals`),
el("p", t`This can be used when the form data doesnt need to be reactive and we just waiting for
results.`),
el(code, { page_id, content: `
const onFormSubmit = on("submit", e => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
// this can be sent to a server
// or processed locally
// e.g.: console.log(Object.fromEntries(formData))
});
// …
return el("form", null, onFormSubmit).append(
// …
);
` })
),
el("div", { className: "tab", dataTab: "variables" }).append(
el("h4", t`We can use variables without signals`),
el("p", t`We use this when we dontt need to reflect changes in the elsewhere (UI).`),
el(code, { page_id, content: `
let canSubmit = false;
const onFormSubmit = on("submit", e => {
e.preventDefault();
if(!canSubmit) return; // some message
// …
});
const onAllowSubmit = on("click", e => {
canSubmit = true;
});
`}),
),
el("div", { className: "tab", dataTab: "state" }).append(
el("h4", t`Using signals`),
el("p", t`We use this when we need to reflect changes for example in the UI (e.g. enable/disable
buttons).`),
el(code, { page_id, content: `
const canSubmit = S(false);
const onFormSubmit = on("submit", e => {
e.preventDefault();
// …
});
const onAllowSubmit = on("click", e => {
canSubmit.set(true);
});
return el("form", null, onFormSubmit).append(
// ...
el("button", { textContent: "Allow Submit", type: "button" }, onAllowSubmit),
el("button", { disabled: S(()=> !canSubmit), textContent: "Submit" })
);
`}),
),
el("p").append(T`
A good approach is to started with variables/constants and when necessary, convert them to signals.
`),
),
el("h4", t`Migrating from Traditional Approaches`),
el("p").append(...T`
el("p").append(T`
When migrating from traditional DOM manipulation or other frameworks to dd<el>:
`),
el("ol").append(
el("li").append(...T`
${el("strong", "Start with state:")}: Convert global variables or ad-hoc state to signals
el("li").append(T`
${el("strong", "Start with state")}: Convert global variables or ad-hoc state to signals
`),
el("li").append(...T`
${el("strong", "Replace query selectors:")}: Replace getElementById/querySelector with direct references to elements
el("li").append(T`
${el("strong", "Replace query selectors")}: Replace getElementById/querySelector with direct references
to elements
`),
el("li").append(...T`
${el("strong", "Convert imperative updates:")}: Replace manual DOM updates with declarative signal bindings
el("li").append(T`
${el("strong", "Convert imperative updates")}: Replace manual DOM updates with declarative signal
bindings
`),
el("li").append(...T`
${el("strong", "Refactor into components:")}: Organize related UI elements into component functions
el("li").append(T`
${el("strong", "Refactor into components")}: Organize related UI elements into component functions
`)
),
el(code, { content: `
@@ -157,7 +246,7 @@ export function page({ pkg, info }){
el("dd", t`Core function for creating DOM elements with declarative properties`),
el("dt", t`el().append(...children)`),
el("dd", t`Add child elements to a parent element`),
el("dd", t`Add child elements to a parent element`),
el("dt", t`memo(key, () => element)`),
el("dd", t`Cache and reuse DOM elements for performance optimization`),
@@ -171,22 +260,22 @@ export function page({ pkg, info }){
el("h4", t`Signals & Reactivity`),
el("dl").append(
el("dt", t`S(initialValue)`),
el("dd", t`Create a signal with an initial value`),
el("dd", t`Create a signal with an initial value`),
el("dt", t`S(() => computation)`),
el("dd", t`Create a derived signal that updates when dependencies change`),
el("dd", t`Create a derived signal that updates when dependencies change`),
el("dt", t`S.el(signal, data => element)`),
el("dd", t`Create reactive elements that update when a signal changes`),
el("dd", t`Create reactive elements that update when a signal changes`),
el("dt", t`S.action(signal, "method", ...args)`),
el("dd", t`Call custom methods defined on a signal`),
el("dd", t`Call custom methods defined on a signal`),
el("dt", t`signal.get()`),
el("dd", t`Get the current value of a signal`),
el("dd", t`Get the current value of a signal`),
el("dt", t`signal.set(newValue)`),
el("dd", t`Update a signal's value and trigger reactive updates`)
el("dd", t`Update a signals value and trigger reactive updates`)
)
),
@@ -200,7 +289,7 @@ export function page({ pkg, info }){
el("dd", t`Provides access to component context, signal, host element`),
el("dt", t`dispatchEvent(type, element)`),
el("dd", t`Creates a function for dispatching custom events`),
el("dd", t`Creates a function for dispatching custom events`),
el("dt", t`Signal Factories`),
el("dd", t`Functions that create and configure signals with domain-specific behavior`)
@@ -211,20 +300,46 @@ export function page({ pkg, info }){
el("div").append(
el("h4", t`Code Organization`),
el("ul").append(
el("li").append(...T`
${el("strong", "Follow the 3PS pattern:")}: Separate state creation, binding to elements, and state updates
el("li").append(T`
${el("strong", "Follow the 3PS pattern")}: Separate state creation, binding to elements, and state updates
`),
el("li").append(...T`
${el("strong", "Use component functions:")}: Create reusable UI components as functions
el("li").append(T`
${el("strong", "Use component functions")}: Create reusable UI components as functions
`),
el("li").append(...T`
${el("strong", "Create signal factories:")}: Extract reusable signal patterns into factory functions
el("li").append(T`
${el("strong", "Create signal factories")}: Extract reusable signal patterns into factory functions
`),
el("li").append(...T`
${el("strong", "Leverage scopes:")}: Use scope for component context and clean resource management
el("li").append(T`
${el("strong", "Leverage scopes")}: Use scope for component context and clean resource management
`),
el("li").append(...T`
${el("strong", "Event delegation:")}: Prefer component-level event handlers over many individual handlers
el("li").append(T`
${el("strong", "Event delegation")}: Prefer component-level event handlers over many individual handlers
`)
)
),
el("div").append(
el("h4", t`When to Use Signals vs. Plain DOM`),
el("ul").append(
el("li").append(T`
${el("strong", "Use signals for")}: Data that changes frequently, multiple elements that need to
stay in sync, computed values dependent on other state
`),
el("li").append(T`
${el("strong", "Use plain DOM for")}: Static content, one-time DOM operations, simple toggling of
elements, single-element updates
`),
el("li").append(T`
${el("strong", "Mixed approach")}: Start with plain DOM and events, then add signals only where
needed for reactivity
`),
el("li").append(T`
${el("strong", "Consider derived signals")}: For complex transformations of data rather than manual
updates
`),
el("li").append(T`
${el("strong", "Use event delegation")}: For handling multiple similar interactions without
individual signal bindings
`)
)
),
@@ -232,23 +347,23 @@ export function page({ pkg, info }){
el("div").append(
el("h4", t`Performance Optimization`),
el("ul").append(
el("li").append(...T`
${el("strong", "Memoize list items:")}: Use ${el("code", "memo")} for items in frequently-updated lists
el("li").append(T`
${el("strong", "Memoize list items")}: Use ${el("code", "memo")} for items in frequently-updated lists
`),
el("li").append(...T`
${el("strong", "Avoid unnecessary signal updates:")}: Only update signals when values actually change
el("li").append(T`
${el("strong", "Avoid unnecessary signal updates")}: Only update signals when values actually change
`),
el("li").append(...T`
${el("strong", "Use AbortSignals:")}: Clean up resources when components are removed
el("li").append(T`
${el("strong", "Use AbortSignals")}: Clean up resources when components are removed
`),
el("li").append(...T`
${el("strong", "Prefer derived signals:")}: Use computed values instead of manual updates
el("li").append(T`
${el("strong", "Prefer derived signals")}: Use computed values instead of manual updates
`),
el("li").append(...T`
${el("strong", "Avoid memoizing fragments:")}: Never memoize DocumentFragments, only individual elements
el("li").append(T`
${el("strong", "Avoid memoizing fragments")}: Never memoize DocumentFragments, only individual elements
`)
),
el("p").append(...T`
el("p").append(T`
See the ${el("a", references.performance).append("Performance Optimization Guide")} for detailed strategies.
`)
),
@@ -263,7 +378,7 @@ export function page({ pkg, info }){
el("dd", t`Use scope.signal or AbortSignals to handle resource cleanup when elements are removed`),
el("dt", t`Circular Signal Dependencies`),
el("dd", t`Avoid signals that depend on each other in a circular way, which can cause infinite update loops`),
el("dd", t`Avoid signals that depend on each other in a circular way, which can cause infinite update loops`),
el("dt", t`Memoizing with Unstable Keys`),
el("dd", t`Always use stable, unique identifiers as memo keys, not array indices or objects`),
@@ -324,59 +439,76 @@ export function page({ pkg, info }){
),
el(h3, t`Looking Ahead: Future Directions`),
el("p").append(...T`
el("p").append(T`
The dd<el> library continues to evolve, with several areas of focus for future development:
`),
el("ul").append(
el("li").append(...T`
el("li").append(T`
${el("strong", "Future Compatibility:")} Alignment with the TC39 Signals proposal for native browser support
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "SSR Improvements:")} Enhanced server-side rendering capabilities
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "Ecosystem Growth:")} More utilities, patterns, and integrations with other libraries
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "Documentation Expansion:")} Additional examples, tutorials, and best practices
`),
el("li").append(...T`
el("li").append(T`
${el("strong", "TypeScript Enhancements:")} Improved type definitions and inference
`)
),
el(h3, t`Contribution and Community`),
el("p").append(...T`
dd<el> is an open-source project that welcomes contributions from the community:
el("p").append(T`
dd<el> is an open-source project that welcomes contributions from the community:
`),
el("ul").append(
el("li").append(...T`
el("li").append(T`
${el("a", references.github).append("GitHub Repository")}: Star, fork, and contribute to the project
`),
el("li").append(...T`
el("li").append(T`
Bug reports and feature requests: Open issues on GitHub
`),
el("li").append(...T`
el("li").append(T`
Documentation improvements: Help expand and clarify these guides
`),
el("li").append(...T`
el("li").append(T`
Examples and case studies: Share your implementations and solutions
`)
),
el("div", { className: "callout" }).append(
el("h4", t`Final Thoughts`),
el("p").append(...T`
dd<el> provides a lightweight yet powerful approach to building modern web interfaces
el("p").append(T`
dd<el> provides a lightweight yet powerful approach to building modern web interfaces
with minimal overhead and maximal flexibility. By embracing standard web technologies
rather than abstracting them away, it offers a development experience that scales
rather than abstracting them away, it offers a development experience that scales
from simple interactive elements to complex applications while remaining close
to what makes the web platform powerful.
`),
el("p").append(...T`
Whether you're building a small interactive component or a full-featured application,
dd<el>'s combination of declarative syntax, targeted reactivity, and pragmatic design
provides the tools you need without the complexity you don't.
el("p").append(T`
Whether youre building a small interactive component or a full-featured application,
dd<el>s combination of declarative syntax, targeted reactivity, and pragmatic design
provides the tools you need without the complexity you dont.
`)
),
el(h3, t`Tools and Resources`),
el("p").append(T`
To help you get started with dd<el>, we provide several tools and resources:
`),
el("ul").append(
el("li").append(T`
${el("a", references.converter).append("HTML to dd<el> Converter")}: Easily convert existing HTML markup
to dd<el> JavaScript code
`),
el("li").append(T`
${el("a", references.examples).append("Examples Gallery")}: Browse real-world examples and code snippets
`),
el("li").append(T`
${el("a", references.github).append("Documentation")}: Comprehensive guides and API reference
`)
),
);