Public
Edited
Nov 12, 2022
Importers
3 stars
Insert cell
Insert cell
Insert cell
Icon.cycling
Insert cell
icon("white-flag")
Insert cell
icon("attach-outline", {
source: Sources.EvaOutline
})
Insert cell
icon("checkmark-circle-2", {
source: Sources.EvaFill
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
icon = (name, options) => {
const size = options?.size || "1.30em";
const className = options?.className || "icon";
const source = options?.source || Sources.Iconoir;
const style = Object.assign({}, source?.style, options?.style);
const container = options?.container || Icons;
const node = Object.entries({ width: size, height: size }).reduce(
(r, [k, v]) => {
r.setAttribute(k, v);
return r;
},
document.createElementNS("http://www.w3.org/2000/svg", "svg")
);
loadIcon(name, container, source).then((symbol) => {
["viewBox"].forEach((_) => {
const icon = symbol.firstChild;
if (icon && icon.getAttribute) {
node.setAttribute(_, icon.getAttribute(_));
} else {
console.error(`Could not load icon "${name}", got:`, symbol);
}
});
});
const use = document.createElementNS("http://www.w3.org/2000/svg", "use");
use.classList.add(className);
Object.assign(node.style, style);
use.setAttribute("href", `#icon-${name}-${sourceName(source)}`);
node.appendChild(use);
return node;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Sources = ({
Iconoir: {
url: "https://unpkg.com/iconoir@5.4.0/icons/${name}.svg",
style: {
fill: "none",
stroke: "current-color",
"stroke-width": "1.5px",
"vector-effect": "non-scaling-stroke"
}
},
EvaOutline: {
url: "https://unpkg.com/eva-icons@1.1.3/outline/svg/${name}.svg",
style: { stroke: "transparent", fill: "current-color" }
},
EvaFill: {
url: "https://unpkg.com/eva-icons@1.1.3/fill/svg/${name}.svg",
style: { stroke: "transparent", fill: "current-color" }
}
})
Insert cell
sourceName = (source, sources = Sources) => {
let sourceName = "generic";
for (let k in sources) {
if (sources[k].url == source) {
sourceName = k;
break;
}
}
return sourceName.toLowerCase();
}
Insert cell
Insert cell
loadIcon = (name, container = Icons, source = Sources.Iconoir) => {
const iconId = `icon-${name}-${sourceName(source)}`;
const existing = container.getElementById(iconId);
const url = (source?.url || source).replace("${name}", name);
return existing
? Promise.resolve(existing)
: fetch(url)
.then((_) => _.text())
.then((text) => {
const symbol = document.createElementNS(
"http://www.w3.org/2000/svg",
"symbol"
);
symbol.id = iconId;
symbol.innerHTML = text;
const icon = symbol.firstChild;
if (icon && icon.attributes) {
["stroke-width", "fill", "stroke"].forEach(
(_) => icon.hasAttribute(_) && icon.setAttribute(_, "")
);
} else {
console.error(`Icon "${name}" should have a content, got:`, text);
}
container.appendChild(symbol);
if (!container.parentElement) {
document.body.appendChild(container);
}
return symbol;
})
.catch((reason) => {
console.error(`Could not load icon ${name} from ${url}: ${reason}`);
});
}
Insert cell
Insert cell
Icons = Object.entries({
width: "0",
height: "0",
viewBox: "0 0 0 0"
}).reduce((r, [k, v]) => {
r.setAttribute(k, v);
return r;
}, document.createElementNS("http://www.w3.org/2000/svg", "svg"))
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more