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:
@@ -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 that’s 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, they’re 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 doesn’t 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 dont’t 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 signal’s 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 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(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
|
||||
`)
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user