Published
Edited
Nov 3, 2021
Importers
2 stars
Insert cell
Insert cell
Insert cell
check
Insert cell
trash = actionButton("🗑️", { name: "trash", callback: () => mutable trashed++ })
Insert cell
mutable trashed = 0
Insert cell
Insert cell
foobar
Insert cell
Insert cell
thick
Insert cell
Insert cell
color
Insert cell
Insert cell
function checkButton(text, options = {}) {
let {
size = 30,
draw = null,
value = false,
style = "",
name = null
} = options;
name = name || text;
let b = htl.html`<canvas width=${size} height=${size} style=${style} title=${name}>`;
const styleValue = () => {
b.style.cursor = "pointer";
if (b.value) {
b.style.border = `2px inset gray`;
b.style.background = "lightgray";
} else {
b.style.border = `2px solid #eeeeee`;
b.style.background = null;
}
};
b.value = value;
styleValue();
let ctx = b.getContext("2d");
draw =
draw ||
((ctx, text) => {
ctx.textAlign = "center";
ctx.textBaseline = "top";
ctx.font = `${size * 0.9}px sans-serif`;
ctx.fillStyle = "black";
ctx.fillText(text, size / 2, size * 0.1);
});
draw(ctx, text);
b.setValue = (v) => {
b.value = value = v;
styleValue();
};
b.onclick = () => {
b.value = !b.value;
styleValue();
b.dispatchEvent(new CustomEvent("input"));
};
return b;
}
Insert cell
function actionButton(text, options = {}) {
let b = checkButton(text, options);
let div = htl.html`<div>${b}`;
b.oninput = (e) => {
if (options.callback) options.callback(text);
setTimeout(() => b.setValue(false), 100);
};
return div;
}
Insert cell
function radioGroup(labels, options = {}) {
let { names = [...labels] } = options;
let {
value = names[0],
draw = null,
size = 30,
style = "",
buttonStyle = "",
columns = 1000
} = options;
let buttons = [...labels].map((t, i) =>
checkButton(t, {
size,
draw,
style: buttonStyle,
value: value == names[i],
name: names[i]
})
);

let group = htl.html`<div style=${style}>`;
group.style.width = "fit-content";
let table = htl.html`<table>`;
table.style.width = "fit-content";
table.style.margin = 0;
const styleValue = () => {
buttons.forEach((b, i) => b.setValue(names[i] == group.value));
};
group.append(table);
const n = buttons.length;
let row = null;
buttons.forEach((b, i) => {
if (i % columns == 0) {
row = htl.html`<tr>`;
table.append(row);
}
row.append(htl.html`${b}`);
});
group.setValue = (v) => {
group.value = value = v;
styleValue();
};
buttons.forEach((b, i) => {
b.oninput = () => {
group.setValue(names[i]);
group.dispatchEvent(new CustomEvent("input"));
};
});
group.value = value;
return group;
}
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