feat: props blueprint (#8)
This commit is contained in:
parent
000e3811cd
commit
00648883fa
12 changed files with 78 additions and 16 deletions
|
@ -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() {
|
||||
|
|
|
@ -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"];
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { WebComponent } from "../../src";
|
||||
import { WebComponent } from "../../src/index.js"
|
||||
|
||||
export class BooleanPropTest extends WebComponent {
|
||||
static properties = ["is-inline", "anotherone"];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @ts-check
|
||||
import { WebComponent } from "../../src";
|
||||
import { WebComponent } from "../../src/index.js"
|
||||
|
||||
export class Counter extends WebComponent {
|
||||
static properties = ["count"];
|
||||
|
|
|
@ -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"];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// @ts-check
|
||||
import { WebComponent } from "../../src"
|
||||
import { WebComponent } from "../../src/index.js"
|
||||
|
||||
class SimpleText extends WebComponent {
|
||||
clickCallback() {
|
||||
|
|
12
examples/props-blueprint/hello-world.js
Normal file
12
examples/props-blueprint/hello-world.js
Normal 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);
|
14
examples/props-blueprint/index.html
Normal file
14
examples/props-blueprint/index.html
Normal 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>
|
15
examples/props-blueprint/index.js
Normal file
15
examples/props-blueprint/index.js
Normal 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);
|
|
@ -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)
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue