Tweakit v0.7.2

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 (a color string becomes the picker). 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.

Live
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. With the list open, typing moves to the option whose label starts with the letters you just typed, and the same letter again moves on to the next match; Enter or a click still picks it.

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);

Swatches in a list

An option can carry a color: it shows as a swatch beside the label in the dropdown and, for the chosen option, on the row. The param stays the string you gave it, so a token palette picks by name and your code applies whatever the name maps to.

Neutral 10
const card = target.querySelector(".sw-card");
const fills = { "neutral-10": "#f4f4f5", "neutral-90": "#18181b", accent: "#7C5CFF", warn: "#ff8a5b" };
const panel = tweaks("Tokens", {
  fill: { value: "neutral-10", options: [
    { value: "neutral-10", label: "Neutral 10", color: "#f4f4f5" },
    { value: "neutral-90", label: "Neutral 90", color: "#18181b" },
    { value: "accent",     label: "Accent",     color: "#7C5CFF" },
    { value: "warn",       label: "Warn",       color: "#ff8a5b" },
  ] },
});
mount.append(panel.el);

const apply = (p) => {
  card.style.background = fills[p.fill];
  card.style.color = p.fill === "neutral-10" ? "#222" : "#fff";
  card.textContent = panel.el.querySelector(".twk-select-value").textContent;
};
panel.on(apply);
apply(panel.params);

Radio grid

A single-select laid out as buttons: { type: "radiogrid" } (alias "segmented") with cols (2 or 3) to shape the grid; a pill slides to the pick. With label: "" the row is all buttons, equal widths across it, and four fit on one line. 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);