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:
+
+### 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);