mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-04-01 19:55:53 +02:00
🔤
This commit is contained in:
parent
05413cb2bb
commit
17e40fdd9c
5
dist/dde-with-signals.js
vendored
5
dist/dde-with-signals.js
vendored
@ -177,6 +177,11 @@ var scope = {
|
||||
pop() {
|
||||
if (scopes.length === 1) return;
|
||||
return scopes.pop();
|
||||
},
|
||||
isolate(fn) {
|
||||
this.push({ prevent: true });
|
||||
fn();
|
||||
this.pop();
|
||||
}
|
||||
};
|
||||
function append(...els) {
|
||||
|
4
dist/dde-with-signals.min.js
vendored
4
dist/dde-with-signals.min.js
vendored
File diff suppressed because one or more lines are too long
5
dist/dde.js
vendored
5
dist/dde.js
vendored
@ -154,6 +154,11 @@ var scope = {
|
||||
pop() {
|
||||
if (scopes.length === 1) return;
|
||||
return scopes.pop();
|
||||
},
|
||||
isolate(fn) {
|
||||
this.push({ prevent: true });
|
||||
fn();
|
||||
this.pop();
|
||||
}
|
||||
};
|
||||
function append(...els) {
|
||||
|
8
dist/dde.min.js
vendored
8
dist/dde.min.js
vendored
File diff suppressed because one or more lines are too long
4
dist/esm-with-signals.d.min.ts
vendored
4
dist/esm-with-signals.d.min.ts
vendored
@ -232,11 +232,13 @@ export const scope: {
|
||||
|
||||
state: Scope[],
|
||||
/** Adds new child scope. All attributes are inherited by default. */
|
||||
push(scope: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
push(scope?: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
/** Adds root scope as a child of the current scope. */
|
||||
pushRoot(): ReturnType<Array<Scope>["push"]>,
|
||||
/** Removes last/current child scope. */
|
||||
pop(): ReturnType<Array<Scope>["pop"]>,
|
||||
/** Runs function in a new (isolated) scope */
|
||||
isolate(fn: Function): void,
|
||||
};
|
||||
|
||||
export function customElementRender<
|
||||
|
4
dist/esm-with-signals.d.ts
vendored
4
dist/esm-with-signals.d.ts
vendored
@ -232,11 +232,13 @@ export const scope: {
|
||||
|
||||
state: Scope[],
|
||||
/** Adds new child scope. All attributes are inherited by default. */
|
||||
push(scope: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
push(scope?: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
/** Adds root scope as a child of the current scope. */
|
||||
pushRoot(): ReturnType<Array<Scope>["push"]>,
|
||||
/** Removes last/current child scope. */
|
||||
pop(): ReturnType<Array<Scope>["pop"]>,
|
||||
/** Runs function in a new (isolated) scope */
|
||||
isolate(fn: Function): void,
|
||||
};
|
||||
|
||||
export function customElementRender<
|
||||
|
5
dist/esm-with-signals.js
vendored
5
dist/esm-with-signals.js
vendored
@ -175,6 +175,11 @@ var scope = {
|
||||
pop() {
|
||||
if (scopes.length === 1) return;
|
||||
return scopes.pop();
|
||||
},
|
||||
isolate(fn) {
|
||||
this.push({ prevent: true });
|
||||
fn();
|
||||
this.pop();
|
||||
}
|
||||
};
|
||||
function append(...els) {
|
||||
|
4
dist/esm-with-signals.min.js
vendored
4
dist/esm-with-signals.min.js
vendored
File diff suppressed because one or more lines are too long
4
dist/esm.d.min.ts
vendored
4
dist/esm.d.min.ts
vendored
@ -232,11 +232,13 @@ export const scope: {
|
||||
|
||||
state: Scope[],
|
||||
/** Adds new child scope. All attributes are inherited by default. */
|
||||
push(scope: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
push(scope?: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
/** Adds root scope as a child of the current scope. */
|
||||
pushRoot(): ReturnType<Array<Scope>["push"]>,
|
||||
/** Removes last/current child scope. */
|
||||
pop(): ReturnType<Array<Scope>["pop"]>,
|
||||
/** Runs function in a new (isolated) scope */
|
||||
isolate(fn: Function): void,
|
||||
};
|
||||
|
||||
export function customElementRender<
|
||||
|
4
dist/esm.d.ts
vendored
4
dist/esm.d.ts
vendored
@ -232,11 +232,13 @@ export const scope: {
|
||||
|
||||
state: Scope[],
|
||||
/** Adds new child scope. All attributes are inherited by default. */
|
||||
push(scope: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
push(scope?: Partial<Scope>): ReturnType<Array<Scope>["push"]>,
|
||||
/** Adds root scope as a child of the current scope. */
|
||||
pushRoot(): ReturnType<Array<Scope>["push"]>,
|
||||
/** Removes last/current child scope. */
|
||||
pop(): ReturnType<Array<Scope>["pop"]>,
|
||||
/** Runs function in a new (isolated) scope */
|
||||
isolate(fn: Function): void,
|
||||
};
|
||||
|
||||
export function customElementRender<
|
||||
|
5
dist/esm.js
vendored
5
dist/esm.js
vendored
@ -152,6 +152,11 @@ var scope = {
|
||||
pop() {
|
||||
if (scopes.length === 1) return;
|
||||
return scopes.pop();
|
||||
},
|
||||
isolate(fn) {
|
||||
this.push({ prevent: true });
|
||||
fn();
|
||||
this.pop();
|
||||
}
|
||||
};
|
||||
function append(...els) {
|
||||
|
2
dist/esm.min.js
vendored
2
dist/esm.min.js
vendored
File diff suppressed because one or more lines are too long
14
docs/components/examples/elements/dde-dom-create.js
Normal file
14
docs/components/examples/elements/dde-dom-create.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { el } from "deka-dom-el";
|
||||
|
||||
// Create element with properties
|
||||
const button = el("button", {
|
||||
textContent: "Click me",
|
||||
className: "primary",
|
||||
disabled: true
|
||||
});
|
||||
|
||||
// Shorter and more expressive
|
||||
// than the native approach
|
||||
|
||||
// Add to DOM
|
||||
document.body.append(button);
|
11
docs/components/examples/elements/dde-dom-tree.js
Normal file
11
docs/components/examples/elements/dde-dom-tree.js
Normal file
@ -0,0 +1,11 @@
|
||||
import { el } from "deka-dom-el";
|
||||
|
||||
// Chainable, natural nesting
|
||||
// append() returns parent element
|
||||
// making chains easy and intuitive
|
||||
document.body.append(
|
||||
el("div").append(
|
||||
el("h1", "Title"),
|
||||
el("p", "Paragraph")
|
||||
)
|
||||
);
|
19
docs/components/examples/elements/native-dom-create.js
Normal file
19
docs/components/examples/elements/native-dom-create.js
Normal file
@ -0,0 +1,19 @@
|
||||
// Create element with properties
|
||||
const button = document.createElement('button');
|
||||
button.textContent = "Click me";
|
||||
button.className = "primary";
|
||||
button.disabled = true;
|
||||
|
||||
// Or using Object.assign()
|
||||
const button2 = Object.assign(
|
||||
document.createElement('button'),
|
||||
{
|
||||
textContent: "Click me",
|
||||
className: "primary",
|
||||
disabled: true
|
||||
}
|
||||
);
|
||||
|
||||
// Add to DOM
|
||||
document.body.appendChild(button);
|
||||
document.body.appendChild(button2);
|
15
docs/components/examples/elements/native-dom-tree.js
Normal file
15
docs/components/examples/elements/native-dom-tree.js
Normal file
@ -0,0 +1,15 @@
|
||||
// Verbose, needs temp variables
|
||||
const div = document.createElement('div');
|
||||
const h1 = document.createElement('h1');
|
||||
h1.textContent = 'Title';
|
||||
div.appendChild(h1);
|
||||
|
||||
const p = document.createElement('p');
|
||||
p.textContent = 'Paragraph';
|
||||
div.appendChild(p);
|
||||
|
||||
// appendChild doesn't return parent
|
||||
// so chaining is not possible
|
||||
|
||||
// Add to DOM
|
||||
document.body.appendChild(div);
|
8
docs/components/examples/events/append-event.js
Normal file
8
docs/components/examples/events/append-event.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { el, on } from "deka-dom-el";
|
||||
|
||||
// Third approach - append with on addon
|
||||
el("button", {
|
||||
textContent: "click me"
|
||||
}).append(
|
||||
on("click", (e) => console.log("Clicked!", e))
|
||||
);
|
7
docs/components/examples/events/attribute-event.js
Normal file
7
docs/components/examples/events/attribute-event.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { el } from "deka-dom-el";
|
||||
|
||||
// Using events with HTML attribute style
|
||||
el("button", {
|
||||
textContent: "click me",
|
||||
"=onclick": "console.log(event)"
|
||||
});
|
8
docs/components/examples/events/chain-event.js
Normal file
8
docs/components/examples/events/chain-event.js
Normal file
@ -0,0 +1,8 @@
|
||||
import { el, on } from "deka-dom-el";
|
||||
|
||||
// Using events as addons - chainable approach
|
||||
el("button", {
|
||||
textContent: "click me",
|
||||
},
|
||||
on("click", (e) => console.log("Clicked!", e))
|
||||
);
|
2
docs/components/examples/events/native-event.js
Normal file
2
docs/components/examples/events/native-event.js
Normal file
@ -0,0 +1,2 @@
|
||||
// Standard DOM event listener approach
|
||||
element.addEventListener('click', callback, options);
|
7
docs/components/examples/events/property-event.js
Normal file
7
docs/components/examples/events/property-event.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { el } from "deka-dom-el";
|
||||
|
||||
// Using events with property assignment
|
||||
el("button", {
|
||||
textContent: "click me",
|
||||
onclick: console.log
|
||||
});
|
14
docs/components/examples/scopes/custom-scope.js
Normal file
14
docs/components/examples/scopes/custom-scope.js
Normal file
@ -0,0 +1,14 @@
|
||||
import { scope } from "deka-dom-el";
|
||||
import { S } from "deka-dom-el/signals";
|
||||
|
||||
function customSignalLogic() {
|
||||
// Create an isolated scope for a specific operation
|
||||
scope.push(); // Start new scope
|
||||
|
||||
// These signals are in the new scope
|
||||
const isolatedCount = S(0);
|
||||
const isolatedDerived = S(() => isolatedCount.get() * 2);
|
||||
|
||||
// Clean up by returning to previous scope
|
||||
scope.pop();
|
||||
}
|
45
docs/components/examples/scopes/with-scope.js
Normal file
45
docs/components/examples/scopes/with-scope.js
Normal file
@ -0,0 +1,45 @@
|
||||
import { el, scope } from "deka-dom-el";
|
||||
import { S } from "deka-dom-el/signals";
|
||||
|
||||
function CounterWithIsolatedTimer() {
|
||||
const { host } = scope;
|
||||
|
||||
// Main component state
|
||||
const count = S(0);
|
||||
|
||||
// Create a timer in an isolated scope
|
||||
scope.isolate(() => {
|
||||
// These subscriptions won't be tied to the component lifecycle
|
||||
// They would continue to run even if the component was removed
|
||||
const timer = S(0);
|
||||
|
||||
// Not recommended for real applications!
|
||||
// Just demonstrating scope isolation
|
||||
setInterval(() => {
|
||||
timer.set(timer.get() + 1);
|
||||
console.log(`Timer: ${timer.get()}`);
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
// Normal component functionality within main scope
|
||||
function increment() {
|
||||
count.set(count.get() + 1);
|
||||
}
|
||||
|
||||
return el("div").append(
|
||||
el("p").append(
|
||||
"Count: ",
|
||||
el("#text", S(() => count.get()))
|
||||
),
|
||||
el("button", {
|
||||
textContent: "Increment",
|
||||
onclick: increment
|
||||
}),
|
||||
el("p", "An isolated timer runs in console")
|
||||
);
|
||||
}
|
||||
|
||||
// Usage
|
||||
document.body.append(
|
||||
el(CounterWithIsolatedTimer)
|
||||
);
|
@ -77,33 +77,11 @@ export function page({ pkg, info }){
|
||||
el("div", { class: "comparison" }).append(
|
||||
el("div").append(
|
||||
el("h5", t`Native DOM API`),
|
||||
el(code, { content: `// Create element with properties
|
||||
const button = document.createElement('button');
|
||||
button.textContent = "Click me";
|
||||
button.className = "primary";
|
||||
button.disabled = true;
|
||||
|
||||
// Or using Object.assign()
|
||||
const button = Object.assign(
|
||||
document.createElement('button'),
|
||||
{
|
||||
textContent: "Click me",
|
||||
className: "primary",
|
||||
disabled: true
|
||||
}
|
||||
);`, page_id })
|
||||
el(code, { src: fileURL("./components/examples/elements/native-dom-create.js"), page_id })
|
||||
),
|
||||
el("div").append(
|
||||
el("h5", t`DDE Approach`),
|
||||
el(code, { content: `// Create element with properties
|
||||
const button = el("button", {
|
||||
textContent: "Click me",
|
||||
className: "primary",
|
||||
disabled: true
|
||||
});
|
||||
|
||||
// Shorter and more expressive
|
||||
// than the native approach`, page_id })
|
||||
el(code, { src: fileURL("./components/examples/elements/dde-dom-create.js"), page_id })
|
||||
)
|
||||
)
|
||||
),
|
||||
@ -159,29 +137,11 @@ const button = el("button", {
|
||||
el("div", { class: "comparison" }).append(
|
||||
el("div", { class: "bad-practice" }).append(
|
||||
el("h5", t`❌ Native DOM API`),
|
||||
el(code, { content: `// Verbose, needs temp variables
|
||||
const div = document.createElement('div');
|
||||
const h1 = document.createElement('h1');
|
||||
h1.textContent = 'Title';
|
||||
div.appendChild(h1);
|
||||
|
||||
const p = document.createElement('p');
|
||||
p.textContent = 'Paragraph';
|
||||
div.appendChild(p);
|
||||
|
||||
// appendChild doesn't return parent
|
||||
// so chaining is not possible`, page_id })
|
||||
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(code, { content: `// Chainable, natural nesting
|
||||
const div = el("div").append(
|
||||
el("h1", "Title"),
|
||||
el("p", "Paragraph")
|
||||
);
|
||||
|
||||
// append() returns parent element
|
||||
// making chains easy and intuitive`, page_id })
|
||||
el(code, { src: fileURL("./components/examples/elements/dde-dom-tree.js"), page_id })
|
||||
)
|
||||
)
|
||||
),
|
||||
|
@ -101,10 +101,7 @@ export function page({ pkg, info }){
|
||||
el("div", { className: "tabs" }).append(
|
||||
el("div", { className: "tab", "data-tab": "html-attr" }).append(
|
||||
el("h4", t`HTML Attribute Style`),
|
||||
el(code, { content: `el("button", {
|
||||
textContent: "click me",
|
||||
"=onclick": "console.log(event)"
|
||||
})`, page_id }),
|
||||
el(code, { src: fileURL("./components/examples/events/attribute-event.js"), page_id }),
|
||||
el("p").append(...T`
|
||||
Forces usage as an HTML attribute. Corresponds to
|
||||
${el("code", `<button onclick="console.log(event)">click me</button>`)}. This can be particularly
|
||||
@ -113,17 +110,12 @@ export function page({ pkg, info }){
|
||||
),
|
||||
el("div", { className: "tab", "data-tab": "property" }).append(
|
||||
el("h4", t`Property Assignment`),
|
||||
el(code, { content: `el("button", {
|
||||
textContent: "click me",
|
||||
onclick: console.log
|
||||
})`, page_id }),
|
||||
el(code, { src: fileURL("./components/examples/events/property-event.js"), page_id }),
|
||||
el("p", t`Assigns the event handler directly to the element's property.`)
|
||||
),
|
||||
el("div", { className: "tab", "data-tab": "addon" }).append(
|
||||
el("h4", t`Addon Approach`),
|
||||
el(code, { content: `el("button", {
|
||||
textContent: "click me"
|
||||
}, on("click", console.log))`, page_id }),
|
||||
el(code, { src: fileURL("./components/examples/events/chain-event.js"), page_id }),
|
||||
el("p", t`Uses the addon pattern, see above.`)
|
||||
)
|
||||
),
|
||||
|
@ -165,19 +165,19 @@ function MyComponent() {
|
||||
el("div", { className: "function-table" }).append(
|
||||
el("h4", t`Manual Scope Control API`),
|
||||
el("dl").append(
|
||||
el("dt", t`scope.current`),
|
||||
el("dd", t`Returns the currently active scope object.`),
|
||||
|
||||
el("dt", t`scope.isolate(callback)`),
|
||||
el("dd", t`Executes the callback function within a temporary scope, then automatically restores the previous scope.
|
||||
Safer than manual push/pop for most use cases.`),
|
||||
|
||||
el("dt", t`scope.push()`),
|
||||
el("dd", t`Creates a new scope and makes it the current active scope. All signals and subscriptions
|
||||
created after this call will be associated with this new scope.`),
|
||||
|
||||
el("dt", t`scope.pop()`),
|
||||
el("dd", t`Restores the previous scope that was active before the matching push() call.`),
|
||||
|
||||
el("dt", t`scope.current()`),
|
||||
el("dd", t`Returns the currently active scope object.`),
|
||||
|
||||
el("dt", t`scope.withScope(callback)`),
|
||||
el("dd", t`Executes the callback function within a temporary scope, then automatically restores the previous scope.
|
||||
Safer than manual push/pop for most use cases.`)
|
||||
)
|
||||
),
|
||||
el("p").append(...T`
|
||||
@ -188,29 +188,8 @@ function MyComponent() {
|
||||
el("li", t`Creating detached reactive logic that shouldn't be tied to a component's lifecycle`),
|
||||
el("li", t`Building utilities that work with signals but need scope isolation`)
|
||||
),
|
||||
el(code, { content: `// Inside a component
|
||||
function SomeComponent() {
|
||||
// Create an isolated scope for a specific operation
|
||||
scope.push(); // Start new scope
|
||||
|
||||
// These signals are in the new scope
|
||||
const isolatedCount = S(0);
|
||||
const isolatedDerived = S(() => isolatedCount.get() * 2);
|
||||
|
||||
// Clean up by returning to previous scope
|
||||
scope.pop();
|
||||
|
||||
// Alternative: Use withScope for automatic scope management
|
||||
scope.withScope(() => {
|
||||
// This code runs in an isolated scope
|
||||
const tempSignal = S("temporary");
|
||||
|
||||
// No need for pop() - scope is restored automatically
|
||||
});
|
||||
|
||||
// Rest of component remains in the original scope
|
||||
return el("div");
|
||||
}`, page_id }),
|
||||
el(example, { src: fileURL("./components/examples/scopes/custom-scope.js"), page_id }),
|
||||
el(example, { src: fileURL("./components/examples/scopes/with-scope.js"), page_id }),
|
||||
el("div", { className: "warning" }).append(
|
||||
el("p").append(...T`
|
||||
${el("strong", "Be careful with manual scope control!")} Always ensure you have matching push() and pop() calls,
|
||||
|
2
index.d.ts
vendored
2
index.d.ts
vendored
@ -237,6 +237,8 @@ export const scope: {
|
||||
pushRoot(): ReturnType<Array<Scope>["push"]>,
|
||||
/** Removes last/current child scope. */
|
||||
pop(): ReturnType<Array<Scope>["pop"]>,
|
||||
/** Runs function in a new (isolated) scope */
|
||||
isolate(fn: Function): void,
|
||||
};
|
||||
|
||||
export function customElementRender<
|
||||
|
@ -72,6 +72,12 @@ export const scope= {
|
||||
if(scopes.length===1) return;
|
||||
return scopes.pop();
|
||||
},
|
||||
|
||||
isolate(fn){
|
||||
this.push({ prevent: true });
|
||||
fn();
|
||||
this.pop();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Chainable append function for elements
|
||||
|
Loading…
x
Reference in New Issue
Block a user