jsx-view
Version:
Minimal JSX for HTML DOM tightly integrated with RxJS. TypeScript definitions, and attributes can be assigned to observables.
54 lines • 1.9 kB
JavaScript
import { combineLatest, of } from "rxjs";
import { map } from "rxjs/operators";
import { isObservableUnchecked } from "./isObservableUnchecked";
const DOMSpecElementMarker = Symbol.for("jsx-view/DOMSpecElement");
export class DOMSpecElement {
spec;
_dev;
constructor(spec) {
this.spec = spec;
}
[DOMSpecElementMarker] = true;
}
/** @internal */
export function __isDOMSpecElement(obj) {
// The !! is to ensure that this publicly exposed function returns
// `false` if something like `null` or `0` is passed.
return (!!obj && obj instanceof DOMSpecElement) || obj?.[DOMSpecElementMarker] === true;
}
export function jsx(elemName, props) {
if (typeof elemName === "string") {
// intrinsic elements like <div/> or <p/>
if (!props)
props = {};
const { children, ...givenProps } = props;
const fixChildren = flattenChildren(Array.isArray(children) ? children : [children]);
return new DOMSpecElement([elemName, givenProps, ...fixChildren]);
}
// custom elements like <MyComponent/>
return new DOMSpecElement([elemName, props]);
}
export function jsxCombineValues(values, merge) {
return combineLatest(values.map((a) => (isObservableUnchecked(a) ? a : of(a)))).pipe(map(merge));
}
export function flattenChildren(children) {
return flatMap(children, (a) => {
if (a == null)
return [];
if (a instanceof DOMSpecElement)
return a;
if (typeof a === "string") {
return new DOMSpecElement(a);
}
else if (Array.isArray(a)) {
return flattenChildren(a);
}
else {
return new DOMSpecElement(typeof a === "number" ? String(a) : a);
}
});
}
function flatMap(items, lambda) {
return Array.prototype.concat.apply([], items.map(lambda));
}
//# sourceMappingURL=jsxSpec.js.map