1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2024-11-23 17:19:37 +01:00
deka-dom-el/docs/p02-elements.html.js
2024-11-22 11:00:15 +01:00

156 lines
7.4 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { T, t } from "./utils/index.js";
export const info= {
title: t`Elements`,
description: t`Basic concepts of elements modifications and creations.`,
};
import { el } from "deka-dom-el";
import { simplePage } from "./layout/simplePage.html.js";
import { example } from "./components/example.html.js";
import { h3 } from "./components/pageUtils.html.js";
import { mnemonic } from "./components/mnemonic/elements-init.js";
import { code } from "./components/code.html.js";
/** @param {string} url */
const fileURL= url=> new URL(url, import.meta.url);
const references= {
/** document.createElement() */
mdn_create: {
title: t`MDN documentation page for document.createElement()`,
href: "https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement",
},
/** Interface Description Language (`el.textContent`) */
mdn_idl: {
title: t`MDN page about Interface Description Language`,
href: "https://developer.mozilla.org/en-US/docs/Glossary/IDL",
},
/** HTMLElement */
mdn_el: {
title: t`MDN documentation page for HTMLElement`,
href: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement"
},
/** HTMLParagraphElement */
mdn_p: {
title: t`MDN documentation page for HTMLParagraphElement (\`p\` tag)`,
href: "https://developer.mozilla.org/en-US/docs/Web/API/HTMLParagraphElement"
},
/** `[a, b] = [1, 2]` */
mdn_destruct: {
title: t`MDN page about destructuring assignment syntax (e.g. \`[a, b] = [1, 2]\`)`,
href: "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment",
},
/** document.createElementNS() */
mdn_ns: {
title: t`MDN documentation page for document.createElementNS() (e.g. for SVG elements)`,
href: "https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS",
}
};
/** @param {import("./types.d.ts").PageAttrs} attrs */
export function page({ pkg, info }){
const page_id= info.id;
return el(simplePage, { info, pkg }).append(
el("h2", t`Native JavaScript DOM elements creations`),
el("p", t`
Lets go through all patterns we would like to use and what needs to be improved for better experience.
`),
el(code, { src: fileURL("./components/examples/elements/intro.js"), page_id }),
el(h3, t`Creating element(s) (with custom attributes)`),
el("p").append(...T`
You can create a native DOM element by using the ${el("a", references.mdn_create).append(
el("code", "document.createElement()") )}. It is also possible to provide a some attribute(s) declaratively
using ${el("code", "Object.assign()")}. More precisely, this way you can sets some
${el("a", references.mdn_idl).append( el("abbr", { textContent: "IDL", title: "Interface Description Language" }))}
also known as a JavaScript property.
`),
el(example, { src: fileURL("./components/examples/elements/nativeCreateElement.js"), page_id }),
el("p").append(...T`
To make this easier, you can use the ${el("code", "el")} function. Internally in basic examples,
it is wrapper around ${el("code", "assign(document.createElement(…), { … })")}.
`),
el(example, { src: fileURL("./components/examples/elements/dekaCreateElement.js"), page_id }),
el("p").append(...T`
The ${el("code", "assign")} function provides improved behaviour of ${el("code", "Object.assign()")}.
You can declaratively sets any IDL and attribute of the given element. Function prefers IDL and fallback
to the ${el("code", "element.setAttribute")} if there is no writable property in the element prototype.
`),
el("p").append(...T`
You can study all JavaScript elements interfaces to the corresponding HTML elements. All HTML elements
inherits from ${el("a", { textContent: "HTMLElement", ...references.mdn_el })}. To see
all available IDLs for example for paragraphs, see ${el("a", { textContent: "HTMLParagraphElement", ...references.mdn_p })}.
Moreover, the ${el("code", "assign")} provides a way to sets declaratively some convenient properties:
`),
el("ul").append(
el("li").append(...T`
It is possible to sets ${el("code", "data-*")}/${el("code", "aria-*")} attributes using object notation.
`),
el("li").append(...T`
In opposite, it is also possible to sets ${el("code", "data-*")}/${el("code", "aria-*")} attribute
using camelCase notation.
`),
el("li").append(...T`You can use string or object as a value for ${el("code", "style")} property.`),
el("li").append(...T`
${el("code", "className")} (IDL preffered)/${el("code", "class")} are ways to add CSS classes
to the element. You can use string (similarly to ${el("code", "class=\"…\"")} syntax in HTML) or
array of strings. This is handy to concat conditional classes.
`),
el("li").append(...T`
Use ${el("code", "classList")} to toggle specific classes. This will be handy later when
the reactivity via signals is beeing introduced.
`),
el("li").append(...T`
The ${el("code", "assign")} also accepts the ${el("code", "undefined")} as a value for any property
to remove it from the element declaratively. Also for some IDL the corresponding attribute is removed
as it can be confusing. ${el("em").append(...T`For example, natievly the elements ${el("code", "id")}
is removed by setting the IDL to an empty string.`)}
`),
el("li").append(...T`
You can use ${el("code", "=")} or ${el("code", ".")} to force processing given key as attribute/property
of the element.
`)
),
el("p").append(...T`
For processing, the ${el("code", "assign")} internally uses ${el("code", "assignAttribute")} and
${el("code", "classListDeclarative")}.
`),
el(example, { src: fileURL("./components/examples/elements/dekaAssign.js"), page_id }),
el(h3, t`Native JavaScript templating`),
el("p", t`By default, the native JS has no good way to define HTML template using DOM API:`),
el(example, { src: fileURL("./components/examples/elements/nativeAppend.js"), page_id }),
el("p").append(...T`
This library therefore overwrites the ${el("code", "append")} method of created elements to always return
parent element.
`),
el(example, { src: fileURL("./components/examples/elements/dekaAppend.js"), page_id }),
el(h3, t`Basic (state-less) components`),
el("p").append(...T`
You can use functions for encapsulation (repeating) logic. The ${el("code", "el")} accepts function
as first argument. In that case, the function should return dom elements and the second argument for
${el("code", "el")} is argument for given element.
`),
el(example, { src: fileURL("./components/examples/elements/dekaBasicComponent.js"), page_id }),
el("p").append(...T`
As you can see, in case of state-less/basic components there is no difference between calling component
function directly or using ${el("code", "el")} function.
`),
el("p", { className: "notice" }).append(...T`
It is nice to use similar naming convention as native DOM API. This allows us to use
${el("a", { textContent: t`the destructuring assignment syntax`, ...references.mdn_destruct })} and keep
track of the native API (things are best remembered through regular use).
`),
el(h3, t`Creating non-HTML elements`),
el("p").append(...T`
Similarly to the native DOM API (${el("a", references.mdn_ns).append(el("code", "document.createElementNS"))})
for non-HTML elements we need to tell JavaScript which kind of the element to create. We can use
the ${el("code", "elNS")} function:
`),
el(example, { src: fileURL("./components/examples/elements/dekaElNS.js"), page_id }),
el(mnemonic)
);
}