Text & choices
Strings, booleans and one-of-N choices. All four of these are built-in controls —
they ship in the core bundle and are live the moment tweaks() returns.
Text
A bare string is a text input. The verbose form adds
placeholder, or rows to turn it into a textarea.
Synthesizers
Voltage in, music out.
const card = target.querySelector(".txt-card");
const panel = tweaks("Text", {
headline: "Synthesizers",
body: { type: "text", value: "Voltage in, music out.", rows: 3,
placeholder: "Card body…" },
});
mount.append(panel.el);
const apply = (p) => {
card.querySelector("h3").textContent = p.headline;
card.querySelector("p").textContent = p.body;
};
panel.on(apply);
apply(panel.params);mount is the panel's slot inside the stage; target is the demo surface it controls. In your own page you'd just document.body.append(panel.el).
Checkbox
true or false is all it takes. The control
renders as an inline toggle pill; the param is a plain boolean.
const badge = target.querySelector(".chk-badge");
const panel = tweaks("Checkbox", {
enabled: true,
color: true,
});
mount.append(panel.el);
const apply = (p) => {
badge.style.opacity = p.enabled ? 1 : 0.25;
badge.style.filter = p.color ? "none" : "grayscale(1)";
};
panel.on(apply);
apply(panel.params);List
An array of strings is a dropdown. Options can also be
{ value, label } pairs when the displayed text shouldn't be the value.
Here the value lands on mix-blend-mode.
const top = target.querySelector(".lst-b");
const panel = tweaks("List", {
blend: ["normal", "screen", "overlay", "multiply", "difference",
{ value: "plus-lighter", label: "add (plus-lighter)" }],
});
mount.append(panel.el);
const apply = (p) => { top.style.mixBlendMode = p.blend; };
panel.on(apply);
apply(panel.params);Radio grid
A single-select laid out as buttons — { type: "radiogrid" }
(alias "segmented") with cols to shape the grid. Nine
alignment options, three columns, and the value drops straight into
place-items.
const frame = target.querySelector(".rg-frame");
const panel = tweaks("Radio grid", {
align: { type: "radiogrid", cols: 3, value: "center center", options: [
{ value: "start start", label: "↖" }, { value: "start center", label: "↑" }, { value: "start end", label: "↗" },
{ value: "center start", label: "←" }, { value: "center center", label: "·" }, { value: "center end", label: "→" },
{ value: "end start", label: "↙" }, { value: "end center", label: "↓" }, { value: "end end", label: "↘" },
] },
});
mount.append(panel.el);
const apply = (p) => { frame.style.placeItems = p.align; };
panel.on(apply);
apply(panel.params);