Published
Edited
Sep 11, 2022
Importers
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
createElement([
"div",
{
style: {
padding: "1.25em",
fontFamily: "sans-serif",
borderRadius: "4px",
backgroundColor: "rgb(251, 248, 226)",
border: "1px solid #E0E0E0"
}
},
"This is an example of how to define ",
["a", { href: "https://reactjs.org/docs/introducing-jsx.html" }, "JSX-like"],
" structures directly in JavaScript",
["ol", ["li", "Get bread"], ["li", "Get wine"], ["li", "Get cheese"]]
])
Insert cell
Insert cell
html.div(
{
style: {
padding: "1.25em",
fontFamily: "sans-serif",
borderRadius: "4px",
backgroundColor: "rgb(251, 248, 226)",
border: "1px solid #E0E0E0"
}
},
"This is an example of how to define ",
html.a({ href: "https://reactjs.org/docs/introducing-jsx.html" }, "JSX-like"),
" structures directly in JavaScript",
html.ol(html.li("Get bread"), html.li("Get wine"), html.li("Get cheese"))
)
Insert cell
Insert cell
Insert cell
createElement = {
const createElement = (value, handler = undefined) => {
if (value instanceof Array) {
const attrs =
value[1] instanceof Object &&
!(value[1] instanceof Array || value[1] instanceof Node)
? value[1]
: null;
const content = attrs === null ? value.slice(1) : value.slice(1);
if (value[0] === "#") {
return document.createComment(
value
.slice(1)
.map((_) => `${1}`)
.join()
);
} else {
const node =
value[0] === ""
? document.createDocumentFragment()
: document.createElement(value[0], handler);
attrs &&
Object.entries(attrs).forEach(([k, v]) =>
setElementAttribute(node, k, v)
);
content.forEach((_) =>
appendElementChild(node, createElement(_), handler)
);
return node;
}
} else if (typeof value === "string") {
return document.createTextNode(value);
} else if (typeof value === "number") {
return document.createTextNode(`${value}`);
} else if (typeof value === undefined || typeof value == null) {
return document.createTextNode("");
} else if (value instanceof Node) {
return value;
} else if (handler) {
return handler(value);
}
};
return createElement;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
appendElementChild = {
const appendElementChild = (node, child, handler) => {
if (child === null || child === undefined) {
return node;
} else if (child instanceof Array) {
child.forEach((_) => appendElementChild(node, _, handler));
} else if (child instanceof Node) {
node.appendChild(child);
} else if (handler) {
return handler(child);
}
return node;
};
return appendElementChild;
}
Insert cell
Insert cell
setElementAttribute = (node, name, value, append = 0, ns = undefined) => {
const t = typeof value;
if (!ns && name.startsWith("on")) {
const n = name.toLowerCase();
if (node[n] !== undefined) {
// We have a callback
node[n] = value;
}
return node;
}
if (!ns & (name === "style") && t === "object") {
// We manage style properties by valle
if (!append) {
node.setAttribute("style", "");
}
Object.assign(node.style, value);
} else if (!ns && name === "value" && node.value !== undefined) {
node.value = value ? value : "";
} else if (!ns && name.startsWith("on") && node[name] !== undefined) {
// We have a callback
node[name] = value;
} else if (value === undefined || value === null) {
// We remove the attribute
ns ? node.removeAttributeNS(ns, name) : node.removeAttribute(name);
} else {
// We have a regular value that we stringify
const v =
t === "number"
? `${value}`
: t === "string"
? value
: JSON.stringify(value);
// If we append, we create an inermediate value.
if (append) {
const e = ns ? node.getAttributeNS(ns, name) : node.getAttribute(name);
const w = `${append < 0 && e ? e + " " : ""}${v}${
append > 0 && e ? " " + e : ""
}`;
ns ? node.setAttributeNS(ns, name, w) : node.setAttribute(name, w);
} else {
ns ? node.setAttributeNS(ns, name, v) : node.setAttribute(name, v);
}
}
return node;
}
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more