import { T, t } from "./utils/index.js"; export const info= { title: t`Web Components`, description: t`Using custom elements in combinantion with DDE`, }; 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/customElement-init.js"; import { code } from "./components/code.html.js"; /** @param {string} url */ const fileURL= url=> new URL(url, import.meta.url); const references= { /** Web Components on MDN */ mdn_web_components: { title: t`MDN documentation page for Web Components`, href: "https://developer.mozilla.org/en-US/docs/Web/API/Web_components", }, /** observedAttributes on MDN */ mdn_observedAttributes: { title: t`MDN documentation page for observedAttributes`, href: "https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#responding_to_attribute_changes", }, /** Custom Elements on MDN */ mdn_custom_elements: { title: t`MDN documentation page for Custom Elements`, href: "https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements", }, /** Custom Elements tips from WebReflection */ custom_elements_tips: { title: t`Ideas and tips from WebReflection`, href: "https://gist.github.com/WebReflection/ec9f6687842aa385477c4afca625bbf4", }, /** Shallow DOM on mdn */ mdn_shadow_dom_depth: { title: t`MDN documentation page for Shadow DOM`, href: "https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM", }, /** Shallow DOM */ shadow_dom_depth: { title: t`Everything you need to know about Shadow DOM (github repo praveenpuglia/shadow-dom-in-depth)`, href: "https://github.com/praveenpuglia/shadow-dom-in-depth", }, }; /** @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`Using web components in combinantion with DDE`), el("p").append(...T` The DDE library allows for use within ${el("a", references.mdn_web_components).append( el("strong", "Web Components") )} for dom-tree generation. However, in order to be able to use signals (possibly mapping to registered ${el("a", references.mdn_observedAttributes).append( el("code", "observedAttributes") )}) and additional functionality is (unfortunately) required to use helpers provided by the library. `), el(code, { src: fileURL("./components/examples/customElement/intro.js"), page_id }), el(h3, t`Custom Elements Introduction`), el("p").append(...T` To start with, let’s see how to use native Custom Elements. As starting point please read ${el("a", references.mdn_custom_elements).append( el("strong", "Using Custom Elements"), " on MDN" )}. To sum up and for mnemonic see following code overview: `), el(code, { src: fileURL("./components/examples/customElement/native-basic.js"), page_id }), el("p").append(...T` For more advanced use of Custom Elements, the summary ${el("a", references.custom_elements_tips) .append( el("strong", t`Handy Custom Elements' Patterns`) )} may be useful. Especially pay attention to linking HTML attributes and defining setters/getters, this is very helpful to use in combination with the library (${el("code", "el(HTMLCustomElement.tagName, { customAttribute: \"new-value\" });")}). `), el("p").append(...T` Also see the Life Cycle Events sections, very similarly we would like to use ${el("a", { textContent: t`DDE events`, href: "./p03-events.html", title: t`See events part of the library documentation` })}. To do it, the library provides function ${el("code", "customElementWithDDE")}… `), el(example, { src: fileURL("./components/examples/customElement/customElementWithDDE.js"), page_id }), el("h3", t`Custom Elements with DDE`), el("p").append(...T` The ${el("code", "customElementWithDDE")} function is only (small) part of the inregration of the library. More important for coexistence is render component function as a body of the Custom Element. For that, you can use ${el("code", "customElementRender")} with arguments instance reference, target for connection, render function and optional properties (will be passed to the render function) see later… `), el(example, { src: fileURL("./components/examples/customElement/dde.js"), page_id }), el("p").append(...T` …as you can see, you can use components created based on the documentation previously introduced. To unlock full potential, use with combination ${el("code", "customElementWithDDE")} (allows to use livecycle events) and ${el("code", "observedAttributes")} (converts attributes to render function arguments — ${el("em", "default")}) or ${el("code", "S.observedAttributes")} (converts attributes to signals). `), el(example, { src: fileURL("./components/examples/customElement/observedAttributes.js"), page_id }), el(h3, t`Shadow DOM`), el("p").append(...T` Regarding to ${el("code", "this.attachShadow({ mode: 'open' })")} see quick overview ${el("a", { textContent: t`Using Shadow DOM`, ...references.mdn_shadow_dom_depth })}. An another source of information can be ${el("a", { textContent: t`Shadow DOM in Depth`, ...references.shadow_dom_depth })}. To sum up, there in basic three ways to render component body: `), el(mnemonic) ); }