diff --git a/attach-effect/Counter.mjs b/attach-effect/Counter.mjs
new file mode 100644
index 0000000..0c44864
--- /dev/null
+++ b/attach-effect/Counter.mjs
@@ -0,0 +1,17 @@
+// @ts-check
+import WebComponent from "../src/WebComponent.js";
+// import { attachEffect } from "../src/attach-effect.js";
+
+export class Counter extends WebComponent {
+ static properties = ["count"];
+ onInit() {
+ this.props.count = 0;
+ this.onclick = () => ++this.props.count;
+ // attachEffect(this.props, 'count', console.log);
+ }
+ get template() {
+ return ``;
+ }
+}
+
+customElements.define("my-counter", Counter);
diff --git a/attach-effect/index.html b/attach-effect/index.html
new file mode 100644
index 0000000..0b077eb
--- /dev/null
+++ b/attach-effect/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ WC demo
+
+
+
+ Attach Effect Test
+
+
+
diff --git a/site/.npmrc b/site/.npmrc
deleted file mode 100644
index cf04042..0000000
--- a/site/.npmrc
+++ /dev/null
@@ -1,2 +0,0 @@
-shamefully-hoist=true
-strict-peer-dependencies=false
diff --git a/site/nitro.config.mjs b/site/nitro.config.mjs
index 1064497..82a71b7 100644
--- a/site/nitro.config.mjs
+++ b/site/nitro.config.mjs
@@ -1,2 +1 @@
-import McFly from "@mcflyjs/config";
-export default defineNitroConfig({ ...McFly() });
+export default defineNitroConfig({ extends: '@mcflyjs/config' });
diff --git a/src/WebComponent.js b/src/WebComponent.js
index 65e1fcb..526975f 100644
--- a/src/WebComponent.js
+++ b/src/WebComponent.js
@@ -87,75 +87,77 @@ export class WebComponent extends HTMLElement {
this.onDestroy();
}
- /**
- * @param {string} property
- * @param {any} previousValue
- * @param {any} currentValue
- */
- attributeChangedCallback(property, previousValue, currentValue) {
+ attributeChangedCallback(property, previousValue, currentValue) {
const camelCaps = this.#getCamelCaps(property);
if (previousValue !== currentValue) {
this[property] = currentValue === "" || currentValue;
this[camelCaps] = this[property]; // remove on v2
- this.props[camelCaps] = this[property];
+ this.props[camelCaps] = {
+ attributeChanged: true,
+ value: this[property],
+ }
this.render();
this.onChanges({ property, previousValue, currentValue });
}
}
-
- /**
- * Converts a kebab-cased string into camelCaps
- * @param {string} kebab string in kebab-case
- * @returns {string}
- */
+
#getCamelCaps(kebab) {
return kebab.replace(/-./g, (x) => x[1].toUpperCase());
}
- /**
- * Proxy handler for observed attribute - property counterpart
- * @param {(qualifiedName: string, value: string) => void} setter
- * @returns
- */
- #handler = (setter) => ({
- set(obj, prop, newValue) {
+ #typeMap = {}
+ #handler = (setter, typeMap) => ({
+ set(obj, prop, value) {
+ const attributeChanged = value?.attributeChanged ?? false;
+ let newValue = attributeChanged ? value.value : value;
const oldValue = obj[prop];
+
+ console.log(">>>", newValue, oldValue);
- obj[prop] = newValue;
+ if (!(prop in typeMap)) {
+ typeMap[prop] = typeof newValue;
+ }
- /**
- * Converts camelCaps string into kebab-case
- * @param {string} str
- * @returns {string}
- */
- const getKebab = (str) =>
- str.replace(
- /[A-Z]+(?![a-z])|[A-Z]/g,
- ($, ofs) => (ofs ? "-" : "") + $.toLowerCase()
- );
+ obj[prop] = restoreType(newValue, typeMap[prop])
- if (oldValue != newValue) {
+ if (attributeChanged && !oldValue != newValue) {
const kebab = getKebab(prop);
setter(kebab, newValue);
}
+
+ function getKebab(str) {
+ return str.replace(
+ /[A-Z]+(?![a-z])|[A-Z]/g,
+ ($, ofs) => (ofs ? "-" : "") + $.toLowerCase()
+ );
+ }
+
+ function restoreType(value, type) {
+ switch(type) {
+ case 'string': return value;
+ case 'number': return parseInt(value);
+ case 'boolean': return JSON.parse(value);
+ default: return value
+ }
+ }
+
+
+
return true;
},
});
- /**
- * Initialize the `props` proxy object
- */
#initializeProps() {
if (!this.#props) {
this.#props = new Proxy(
{},
- this.#handler((key, value) => this.setAttribute(key, value))
+ this.#handler((key, value) => this.setAttribute(key, value), this.#typeMap)
);
}
}
}
-export default WebComponent;
\ No newline at end of file
+export default WebComponent;
diff --git a/src/attach-effect.js b/src/attach-effect.js
new file mode 100644
index 0000000..330212a
--- /dev/null
+++ b/src/attach-effect.js
@@ -0,0 +1,6 @@
+export function attachEffect(proxy, prop, callback) {
+ proxy[prop] = {
+ attach: 'effect',
+ callback
+ }
+}
\ No newline at end of file