jsx-dom-runtime
Version:
A tiny 500-byte library for JSX syntax templates targeting the DOM. Supports HTML, SVG, and MathML tags
69 lines (64 loc) • 2.26 kB
JavaScript
const svgNs = 'http://www.w3.org/2000/svg';
const mathmlNs = 'http://www.w3.org/1998/Math/MathML';
const extensions = new Map([['style', (node, value, key) => {
if ('string' == typeof value) {
node.setAttribute(key, value);
} else {
for (key in value) {
if (key.startsWith('-')) {
node.style.setProperty(key, value[key]);
} else {
node.style[key] = value[key];
}
}
}
}], ['$', (node, value, key) => {
for (key in value) {
node.addEventListener(key, value[key]);
}
}]]);
const appendChildren = (content, node) => false !== content && null != content && (Array.isArray(content) ? content.forEach(i => appendChildren(i, node)) : node.append(content));
const setRef = (content, node) => content && (Array.isArray(content) ? content.forEach(i => setRef(i, node)) : 'function' == typeof content ? content(node) : content.current = node);
const Fragment = content => (appendChildren(content, content = new DocumentFragment()), content);
const jsx = (tag, props, children) => {
let key,
value,
node = props._ ? document.createElementNS(props._, tag) : document.createElement(tag, props.is ? {
is: props.is
} : key);
for (key in props) {
if ('_' != key && 'ref' != key) {
value = props[key];
if (extensions.has(key)) {
extensions.get(key)(node, value, key);
} else if (null != value) {
if ('boolean' != typeof value || key.startsWith('-', 4)) {
node.setAttribute(key, value);
} else if (value) {
node.setAttribute(key, '');
}
}
}
}
appendChildren(children, 'template' == tag ? node.content : node);
setRef(props.ref, node);
return node;
};
const useRef = current => ({
current
});
const parseFromString = html => /*#__PURE__*/jsx('template', {
ref(node) {
node.innerHTML = html;
}
}).content;
const Template = props => /*#__PURE__*/parseFromString(props.children);
const useText = initContent => {
const text = new Text(initContent);
return [text, content => {
if (initContent !== content) {
text.textContent = initContent = content;
}
}];
};
export { Fragment, Template, appendChildren, extensions, jsx, mathmlNs, parseFromString, svgNs, useRef, useText };