feat(templates): better web-component examples

- afterViewInit + scoped stype example
- autocompletion example
This commit is contained in:
Ayo 2023-11-12 16:41:18 +01:00
parent 93989ac1e5
commit 5e6ab37598
4 changed files with 42 additions and 36 deletions

View file

@ -1,19 +1,38 @@
class CodeBlockComponent extends HTMLElement { // @ts-check
connectedCallback() {
this.trimmed = this.innerHTML.trim();
const lang = this.getAttribute("language");
const lineNumbers = this.getAttribute("line-numbers") === "true";
console.log(lineNumbers, lang); /**
* Custom element using a minimal Web Component Base class
* @see https://ayco.io/n/web-component-base
*/
class CodeBlockComponent extends WebComponent {
// initialize props
language;
this.innerHTML = ` // tell browser which props to cause render
<div> static properties = ["language"];
<pre class="language-${lang} ${
lineNumbers ? "line-numbers" : "" // Triggered after view is initialized
}" id="pre" style="padding:1em;background:#efefef;margin:1em 0;border-radius:5px;overflow:scroll"><code id="code">${ afterViewInit() {
this.trimmed /**
}</code></pre> * Provides autocompletion on IDEs when @ts-check is enabled on first line
</div> * @type {HTMLPreElement} */
const pre = this.querySelector("#pre");
// scoped style for pre block
pre.style.background = "#f5f2f0";
pre.style.padding = "1em";
pre.style.margin = "1em 0";
pre.style.fontSize = "1.25em";
pre.style.overflow = "auto";
}
// readonly template
get template() {
const trimmed = this.innerHTML.trim();
return `
<pre class="${
this.language && `language-${this.language}`
}" id="pre"><code id="code">${trimmed}</code></pre>
`; `;
} }
} }

View file

@ -3,15 +3,22 @@
* @see https://ayco.io/n/web-component-base * @see https://ayco.io/n/web-component-base
*/ */
class MyHelloWorld extends WebComponent { class MyHelloWorld extends WebComponent {
// intialize props
dataName = 'World';
// tell browser which props to cause render
static properties = ["data-name"]; static properties = ["data-name"];
// Triggered when the component is connected to the DOM
onInit() { onInit() {
let count = 0; let count = 0;
// initialize event handler
this.onclick = () => { this.onclick = () => {
this.setAttribute("data-name", `Clicked ${++count}x`); this.setAttribute("data-name", `Clicked ${++count}x`);
}; };
} }
// give readonly template
get template() { get template() {
/** /**
* any attribute/property in kebab-case... * any attribute/property in kebab-case...

View file

@ -1,18 +0,0 @@
class HelloWorld extends HTMLElement {
static get observedAttributes() {
return ["data-name"];
}
connectedCallback() {
let count = 0;
this.onclick = () => {
this.setAttribute("data-name", `Clicked ${++count}x`);
};
}
attributeChangedCallback(property, previousValue, currentValue) {
if (property === "data-name" && previousValue !== currentValue) {
this.innerHTML = `<button style="cursor:pointer">Hello ${currentValue}!</button>`;
}
}
}

View file

@ -22,10 +22,9 @@
<h2>Welcome to {{ name }}</h2> <h2>Welcome to {{ name }}</h2>
<p> <p>
Here's a vanilla custom element: Here's a vanilla custom element:
<vanilla-hello-world data-name="{{name}}" /> <my-hello-world data-name="{{name}}" />
</p> </p>
<code-block language="js"> <code-block language="js">
<pre>
class HelloWorld extends HTMLElement { class HelloWorld extends HTMLElement {
static get observedAttributes() { static get observedAttributes() {
return [&quot;data-name&quot;]; return [&quot;data-name&quot;];
@ -43,8 +42,7 @@ class HelloWorld extends HTMLElement {
this.innerHTML = `&lt;button style=&quot;cursor:pointer&quot;&gt;Hello ${currentValue}!&lt;/button&gt;`; this.innerHTML = `&lt;button style=&quot;cursor:pointer&quot;&gt;Hello ${currentValue}!&lt;/button&gt;`;
} }
} }
}</pre }
>
</code-block> </code-block>
</main> </main>
<my-footer> <my-footer>