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 {
connectedCallback() {
this.trimmed = this.innerHTML.trim();
const lang = this.getAttribute("language");
const lineNumbers = this.getAttribute("line-numbers") === "true";
// @ts-check
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 = `
<div>
<pre class="language-${lang} ${
lineNumbers ? "line-numbers" : ""
}" id="pre" style="padding:1em;background:#efefef;margin:1em 0;border-radius:5px;overflow:scroll"><code id="code">${
this.trimmed
}</code></pre>
</div>
// tell browser which props to cause render
static properties = ["language"];
// Triggered after view is initialized
afterViewInit() {
/**
* Provides autocompletion on IDEs when @ts-check is enabled on first line
* @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
*/
class MyHelloWorld extends WebComponent {
// intialize props
dataName = 'World';
// tell browser which props to cause render
static properties = ["data-name"];
// Triggered when the component is connected to the DOM
onInit() {
let count = 0;
// initialize event handler
this.onclick = () => {
this.setAttribute("data-name", `Clicked ${++count}x`);
};
}
// give readonly template
get template() {
/**
* 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>
<p>
Here's a vanilla custom element:
<vanilla-hello-world data-name="{{name}}" />
<my-hello-world data-name="{{name}}" />
</p>
<code-block language="js">
<pre>
class HelloWorld extends HTMLElement {
static get observedAttributes() {
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;`;
}
}
}</pre
>
}
</code-block>
</main>
<my-footer>