diff --git a/README.md b/README.md index 0591ba4..1cd6a6c 100644 --- a/README.md +++ b/README.md @@ -60,3 +60,29 @@ In your HTML page: The result is a reactive UI that updates on attribute changes: UI showing feeling toward Web Components changing from SAD to EXCITED + +### Hooks + +Currently, you can define behavior when an attribute value changes by defining a method `onChanges` in your component: + +```js +import WebComponent from "../index.mjs"; + +export class HelloWorld extends WebComponent { + name = "World"; + emotion = "excited"; + + static get observedAttributes() { + return ["name", "emotion"]; + } + + onChanges({ previousValue, currentValue }) { + console.log(">>> changed", { previousValue, currentValue }); + } + + get template() { + return ` +

Hello ${this.name}${this.emotion === "sad" ? ". 😭" : "! 🙌"}

`; + } +} +``` \ No newline at end of file diff --git a/WebComponent.mjs b/WebComponent.mjs index 72b2608..ac1b0c4 100644 --- a/WebComponent.mjs +++ b/WebComponent.mjs @@ -1,23 +1,29 @@ // @ts-check export class WebComponent extends HTMLElement { + get template() { + return ""; + } - get template () { - return '' + /** + * triggered when an attribute value changed + */ + onChanges({ previousValue, currentValue }) {} + + connectedCallback() { + this.render(); + } + + attributeChangedCallback(property, previousValue, currentValue) { + if (previousValue !== currentValue) { + this[property] = currentValue; + this.render(); } - connectedCallback() { - this.render() - } + this.onChanges({previousValue, currentValue}); + } - attributeChangedCallback(property, prev, value) { - if (prev !== value) { - this[property] = value - this.render() - } - } - - render() { - this.innerHTML = this.template - } -} \ No newline at end of file + render() { + this.innerHTML = this.template; + } +} diff --git a/demo/HelloWorld.mjs b/demo/HelloWorld.mjs index c32bc46..950406c 100644 --- a/demo/HelloWorld.mjs +++ b/demo/HelloWorld.mjs @@ -9,14 +9,14 @@ export class HelloWorld extends WebComponent { return ["name", "emotion"]; } + onChanges({ previousValue, currentValue }) { + console.log(">>> changed", { previousValue, currentValue }); + } + get template() { return ` -

Hello ${this.name}${ - this.emotion === 'sad' - ? '. 😭' - : '! 🙌' - }

` +

Hello ${this.name}${this.emotion === "sad" ? ". 😭" : "! 🙌"}

`; } } -customElements.define('hello-world', HelloWorld); \ No newline at end of file +customElements.define("hello-world", HelloWorld);