Skip to content

Instantly share code, notes, and snippets.

@JakubKoralewski
Forked from borestad/h.ts
Last active September 5, 2022 17:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakubKoralewski/ab20c250ff826f3314474650ecaaeb17 to your computer and use it in GitHub Desktop.
Save JakubKoralewski/ab20c250ff826f3314474650ecaaeb17 to your computer and use it in GitHub Desktop.
JSX/TSX without React with style={var} working
/* https://gist.github.com/borestad/eac42120613bc67a3714f115e8b485a7
* Custom jsx parser
* See: tsconfig.json
*
* {
* "jsx": "react",
* "jsxFactory": "h",
* "lib": [
* "es2017",
* "dom",
* "dom.iterable"
* ]
* }
*
*/
export const entityMap = {
'&': 'amp',
'<': 'lt',
'>': 'gt',
'"': 'quot',
"'": '#39',
'/': '#x2F'
};
export const escapeHtml = str =>
String(str).replace(/[&<>"'\/\\]/g, s => `&${entityMap[s]};`);
// To keep some consistency with React DOM, lets use a mapper
// https://reactjs.org/docs/dom-elements.html
export const AttributeMapper = val =>
({
tabIndex: 'tabindex',
className: 'class',
readOnly: 'readonly'
}[val] || val);
// tslint:disable-next-line:no-default-export
export default function h(
tag: Function | string,
attrs?: { [key: string]: any },
...children: (HTMLElement | string)[]
): HTMLElement {
attrs = attrs || {};
const stack: any[] = [...children];
// Support for components(ish)
if (typeof tag === 'function') {
attrs.children = stack;
return tag(attrs);
}
const elm = document.createElement(tag);
// Add attributes
for (let [name, val] of Object.entries(attrs)) {
name = escapeHtml(AttributeMapper(name));
if (name === 'style') {
Object.assign(elm.style, val);
} else if (val === true) {
elm.setAttribute(name, name);
} else if (val !== false && val != null) {
elm.setAttribute(name, escapeHtml(val));
} else if (val === false) {
elm.removeAttribute(name);
}
}
// Append children
while (stack.length) {
const child = stack.shift();
// Is child a leaf?
if (!Array.isArray(child)) {
elm.appendChild(
(child as HTMLElement).nodeType == null
? document.createTextNode(child.toString())
: child
);
} else {
stack.push(...child);
}
}
return elm;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment