nano-jsx
Version:
SSR first, lightweight 1kB JSX library.
86 lines • 3.19 kB
JavaScript
import { h, isSSR, render, _render } from './core.js';
const defineAsCustomElementsSSR = (component, componentName, _publicProps = [], _options = {}) => {
if (!/^[a-zA-Z0-9]+-[a-zA-Z0-9]+$/.test(componentName))
console.log(`Error: WebComponent name "${componentName}" is invalid.`);
else
_nano.customElements.set(componentName, component);
};
export const defineAsCustomElements = function (component, componentName, publicProps, shadow) {
if (isSSR()) {
defineAsCustomElementsSSR(component, componentName, publicProps);
return;
}
customElements.define(componentName, class extends HTMLElement {
constructor() {
super();
if (shadow) {
this.attachShadow(shadow);
this.$root = this.shadowRoot;
}
else {
this.$root = this;
}
let ref;
const el = this.buildEl(_render({
component,
props: {
ref: (r) => (ref = r),
children: Array.from(this.children).map(c => render(c))
}
}));
// ------------------------------ first render
this.component = ref;
this.isFunctionalComponent = !component.isClass;
this.functionalComponentsProps = {};
this.appendEl(el);
// ------------------------------------------
if (!this.isFunctionalComponent) {
this.component.updatePropsValue = (name, value) => {
// @ts-ignore
if (!this.component.props)
this.component.props = {};
this.component.props[name] = value;
this.component[name] = value;
};
}
}
static get observedAttributes() {
return publicProps;
}
buildEl(contents) {
return h('template', null, contents);
}
appendEl(el) {
this.$root.append(...el.childNodes);
}
removeChildren() {
var _a;
if (this.$root) {
const children = Array.from((_a = this.$root) === null || _a === void 0 ? void 0 : _a.children) || [];
for (const el of children) {
el.remove();
}
}
}
attributeChangedCallback(name, _, newValue) {
if (!this.isFunctionalComponent) {
this.component.updatePropsValue(name, newValue);
this.component.update();
}
else {
this.removeChildren();
this.functionalComponentsProps[name] = newValue;
const el = this.buildEl(_render({
component,
props: {
children: [],
ref: (r) => (this.component = r),
...this.functionalComponentsProps
}
}));
this.appendEl(el);
}
}
});
};
//# sourceMappingURL=customElementsMode.js.map