feat: props blueprint (#8)

This commit is contained in:
Ayo Ayco 2023-12-08 18:00:40 +01:00 committed by GitHub
parent 000e3811cd
commit 00648883fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 78 additions and 16 deletions

View file

@ -1,5 +1,5 @@
// @ts-check
import { WebComponent, attachEffect } from "../../src/";
import { WebComponent, attachEffect } from "../../src/index.js";
export class Counter extends WebComponent {
static properties = ["count"];
onInit() {

View file

@ -1,5 +1,5 @@
// @ts-check
import { WebComponent, attachEffect } from "../../src/";
import { WebComponent, attachEffect } from "../../src/index.js";
export class Decrease extends WebComponent {
static properties = ["count"];

View file

@ -1,4 +1,4 @@
import { WebComponent } from "../../src";
import { WebComponent } from "../../src/index.js"
export class BooleanPropTest extends WebComponent {
static properties = ["is-inline", "anotherone"];

View file

@ -1,5 +1,5 @@
// @ts-check
import { WebComponent } from "../../src";
import { WebComponent } from "../../src/index.js"
export class Counter extends WebComponent {
static properties = ["count"];

View file

@ -1,5 +1,5 @@
// @ts-check
import { WebComponent } from "../../src";
import { WebComponent } from "../../src/index.js"
export class HelloWorld extends WebComponent {
static properties = ["count", "emotion"];

View file

@ -1,5 +1,5 @@
// @ts-check
import { WebComponent } from "../../src"
import { WebComponent } from "../../src/index.js"
class SimpleText extends WebComponent {
clickCallback() {

View file

@ -0,0 +1,12 @@
import { WebComponent } from "../../src/index.js";
export class HelloWorld extends WebComponent {
static props = {
myName: 'World',
};
get template() {
return `<p>Hello ${this.props.myName}</p>`;
}
}
customElements.define("hello-world", HelloWorld);

View file

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WC demo</title>
<script type="module" src="./index.js"></script>
<script type="module" src="./hello-world.js"></script>
</head>
<body>
<my-counter></my-counter>
<hello-world></hello-world>
</body>
</html>

View file

@ -0,0 +1,15 @@
import { WebComponent } from "../../src/index.js";
export class Counter extends WebComponent {
static props = {
count: 123,
};
onInit() {
this.onclick = () => ++this.props.count;
}
get template() {
return `<button id="btn">${this.props.count}</button>`;
}
}
customElements.define("my-counter", Counter);

View file

@ -1,12 +1,12 @@
import { WebComponent } from "../../src/WebComponent.js";
export class ObjectText extends WebComponent {
static properties = ["object"];
onInit() {
this.props.object = {
hello: 'worldzz',
age: 2
};
// static properties = ["object"];
static props = {
object: {
hello: 'worldzz',
age: 2
}
}
onChanges() {
console.log('>>> object', this.props.object)

View file

@ -1,6 +1,6 @@
{
"name": "web-component-base",
"version": "2.0.0-beta.4",
"version": "2.0.0-beta.6",
"description": "A zero-dependency, ~600 Bytes (minified & gzipped), JS base class for creating reactive custom elements easily",
"type": "module",
"exports": {

View file

@ -1,4 +1,4 @@
import { getKebabCase, getCamelCase, serialize, deserialize } from "./utils";
import { getKebabCase, getCamelCase, serialize, deserialize } from "./utils/index.js";
/**
* A minimal base class to reduce the complexity of creating reactive custom elements
@ -13,6 +13,11 @@ export class WebComponent extends HTMLElement {
*/
static properties = [];
/**
* Blueprint for the Proxy props
*/
static props;
/**
* Read-only string property that represents how the component will be rendered
* @returns {string | Node | (string | Node)[]}
@ -74,7 +79,14 @@ export class WebComponent extends HTMLElement {
}
static get observedAttributes() {
return this.properties;
const propKeys = this.props ? Object.keys(this.props).map(camelCase => getKebabCase(camelCase)) : [];
return [...(
new Set([
...this.properties,
...propKeys
])
)]
}
connectedCallback() {
@ -147,9 +159,18 @@ export class WebComponent extends HTMLElement {
}
#initializeProps() {
let initialProps = {}
if(this.constructor.props) {
initialProps = this.constructor.props;
Object.keys(initialProps).forEach(camelCase => {
const value = initialProps[camelCase]
this.#typeMap[camelCase] = typeof value
this.setAttribute(getKebabCase(camelCase), serialize(value))
})
}
if (!this.#props) {
this.#props = new Proxy(
{},
initialProps,
this.#handler((key, value) => this.setAttribute(key, value), this)
);
}