atomico
Version:
Atomico is a small library for the creation of interfaces based on web-components, only using functions and hooks.
71 lines (64 loc) • 1.87 kB
JavaScript
const INTERNAL_PROPS = {
children: 1,
innerHTML: 1,
textContent: 1,
ref: 1,
cloneNode: 1,
staticNode: 1,
shadowDom: 1,
key: 1,
};
const serializeAttr = (value) =>
value.toString().replace(
/[&<>'"]/g,
(tag) =>
({
"&": "&",
"<": "<",
">": ">",
"'": "'",
'"': """,
}[tag])
);
export class Attributes {
toString() {
const attrs = new Map();
for (let prop in this) {
const value = this[prop];
const type = typeof value;
if (INTERNAL_PROPS[prop] || type === "function" || prop[0] === "_")
continue;
const attr =
prop === "className"
? "class"
: prop.replace(
/([\w])([A-Z])/g,
(all, before, after) =>
before + "-" + after.toLowerCase()
);
if (type === "boolean") {
if (value) attrs.set(attr);
} else if (type === "object") {
attrs.set(attr, JSON.stringify(value));
} else {
attrs.set(attr, value);
}
}
const list = [...attrs];
return list.length
? ` ${list
.map(([attr, value]) =>
value != null ? `${attr}="${serializeAttr(value)}"` : attr
)
.join(" ")} `
: "";
}
}
export class Tag extends String {
constructor(type, attributes, innerHTML) {
super(`<${type}${attributes}>${innerHTML}</${type}>`);
this.type = type;
this.attributes = attributes;
this.innerHTML = innerHTML;
}
}