Skip to content

Commit c049872

Browse files
authored
Optimize rendering, support specifying tagName & observedAttributes directly on the Component
1 parent 03b354d commit c049872

File tree

1 file changed

+20
-14
lines changed

1 file changed

+20
-14
lines changed

src/index.js

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { h, render } from 'preact';
2-
3-
const Empty = () => null;
1+
import { h, cloneElement, render } from 'preact';
42

53
export default function register(Component, tagName, propNames) {
64
function PreactElement() {
@@ -10,27 +8,35 @@ export default function register(Component, tagName, propNames) {
108
}
119
PreactElement.prototype = Object.create(HTMLElement.prototype);
1210
PreactElement.prototype.constructor = PreactElement;
13-
PreactElement.prototype.connectedCallback = renderElement;
14-
PreactElement.prototype.attributeChangedCallback = renderElement;
15-
PreactElement.prototype.detachedCallback = unRenderElement;
16-
PreactElement.observedAttributes = propNames;
11+
PreactElement.prototype.connectedCallback = connectedCallback;
12+
PreactElement.prototype.attributeChangedCallback = attributeChangedCallback;
13+
PreactElement.prototype.detachedCallback = detachedCallback;
14+
PreactElement.observedAttributes = propNames || Component.observedAttributes || Object.keys(Component.propTypes || {});
1715

18-
return window.customElements.define(
19-
tagName || Component.displayName || Component.name,
16+
return customElements.define(
17+
tagName || Component.tagName || Component.displayName || Component.name,
2018
PreactElement
2119
);
2220
}
2321

24-
function renderElement() {
25-
this._root = render(toVdom(this, this._vdomComponent), this, this._root);
22+
function connectedCallback() {
23+
this._vdom = toVdom(this, this._vdomComponent);
24+
render(this._vdom, this);
25+
}
26+
27+
function attributeChangedCallback(name, oldValue, newValue) {
28+
const props = {};
29+
props[name] = newValue;
30+
this._vdom = cloneElement(this._vdom, props);
31+
render(this._vdom, this);
2632
}
2733

28-
function unRenderElement() {
29-
render(h(Empty), this, this._root);
34+
function detachedCallback() {
35+
render(this._vdom = null, this);
3036
}
3137

3238
function toVdom(element, nodeName) {
33-
if (element.nodeType === 3) return element.nodeValue;
39+
if (element.nodeType === 3) return element.data;
3440
if (element.nodeType !== 1) return null;
3541
let children = [],
3642
props = {},

0 commit comments

Comments
 (0)