2024-11-22 10:20:59 +01:00
|
|
|
|
import { T, t } from "./utils/index.js";
|
2024-05-22 21:43:49 +02:00
|
|
|
|
export const info= {
|
2024-11-22 10:20:59 +01:00
|
|
|
|
title: t`Elements`,
|
|
|
|
|
description: t`Basic concepts of elements modifications and creations.`,
|
2024-05-22 21:43:49 +02:00
|
|
|
|
};
|
2023-11-21 14:37:57 +01:00
|
|
|
|
|
2023-11-24 16:16:08 +01:00
|
|
|
|
import { el } from "deka-dom-el";
|
2024-05-22 21:43:49 +02:00
|
|
|
|
import { simplePage } from "./layout/simplePage.html.js";
|
2023-11-10 17:15:59 +01:00
|
|
|
|
import { example } from "./components/example.html.js";
|
2023-11-24 16:16:08 +01:00
|
|
|
|
import { h3 } from "./components/pageUtils.html.js";
|
2023-11-29 18:25:21 +01:00
|
|
|
|
import { mnemonic } from "./components/mnemonic/elements-init.js";
|
2023-11-24 17:02:16 +01:00
|
|
|
|
import { code } from "./components/code.html.js";
|
2023-11-10 17:15:59 +01:00
|
|
|
|
/** @param {string} url */
|
|
|
|
|
const fileURL= url=> new URL(url, import.meta.url);
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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",
|
|
|
|
|
}
|
|
|
|
|
};
|
2023-11-07 15:10:55 +01:00
|
|
|
|
/** @param {import("./types.d.ts").PageAttrs} attrs */
|
2023-11-10 17:15:59 +01:00
|
|
|
|
export function page({ pkg, info }){
|
2023-11-07 15:10:55 +01:00
|
|
|
|
const page_id= info.id;
|
2023-11-24 16:16:08 +01:00
|
|
|
|
return el(simplePage, { info, pkg }).append(
|
2024-11-22 10:20:59 +01:00
|
|
|
|
el("h2", t`Native JavaScript DOM elements creations`),
|
|
|
|
|
el("p", t`
|
|
|
|
|
Let’s go through all patterns we would like to use and what needs to be improved for better experience.
|
|
|
|
|
`),
|
2023-11-24 17:02:16 +01:00
|
|
|
|
|
|
|
|
|
el(code, { src: fileURL("./components/examples/elements/intro.js"), page_id }),
|
2024-11-22 16:26:42 +01:00
|
|
|
|
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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.
|
|
|
|
|
`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
el(example, { src: fileURL("./components/examples/elements/nativeCreateElement.js"), page_id }),
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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(…), { … })")}.
|
|
|
|
|
`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
el(example, { src: fileURL("./components/examples/elements/dekaCreateElement.js"), page_id }),
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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
|
2024-11-22 16:26:42 +01:00
|
|
|
|
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:
|
2024-11-22 10:20:59 +01:00
|
|
|
|
`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
el("ul").append(
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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 element’s ${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.
|
|
|
|
|
`)
|
2023-11-24 16:16:08 +01:00
|
|
|
|
),
|
2024-11-22 10:20:59 +01:00
|
|
|
|
el("p").append(...T`
|
|
|
|
|
For processing, the ${el("code", "assign")} internally uses ${el("code", "assignAttribute")} and
|
|
|
|
|
${el("code", "classListDeclarative")}.
|
|
|
|
|
`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
el(example, { src: fileURL("./components/examples/elements/dekaAssign.js"), page_id }),
|
2024-11-22 16:26:42 +01:00
|
|
|
|
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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:`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
el(example, { src: fileURL("./components/examples/elements/nativeAppend.js"), page_id }),
|
2024-11-22 10:20:59 +01:00
|
|
|
|
el("p").append(...T`
|
|
|
|
|
This library therefore overwrites the ${el("code", "append")} method of created elements to always return
|
|
|
|
|
parent element.
|
|
|
|
|
`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
el(example, { src: fileURL("./components/examples/elements/dekaAppend.js"), page_id }),
|
2024-11-22 16:26:42 +01:00
|
|
|
|
|
|
|
|
|
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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.
|
|
|
|
|
`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
el(example, { src: fileURL("./components/examples/elements/dekaBasicComponent.js"), page_id }),
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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).
|
|
|
|
|
`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
|
2024-11-22 10:20:59 +01:00
|
|
|
|
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:
|
|
|
|
|
`),
|
2023-11-24 16:16:08 +01:00
|
|
|
|
el(example, { src: fileURL("./components/examples/elements/dekaElNS.js"), page_id }),
|
2024-11-22 16:26:42 +01:00
|
|
|
|
|
2023-11-29 18:25:21 +01:00
|
|
|
|
el(mnemonic)
|
2023-11-07 15:10:55 +01:00
|
|
|
|
);
|
|
|
|
|
}
|