Skip to content

bind()

Spread bind(signal, options?) into a form control to wire it to a signal in one line. Covers text inputs (including textarea and select), numbers, checkboxes, and radio groups.

function bind(signal: Signal<string>): TextBind;
function bind(
signal: Signal<number>,
options: { as: "number" },
): NumberBind;
function bind(
signal: Signal<boolean>,
options: { as: "checkbox" },
): CheckboxBind;
function bind<V extends string>(
signal: Signal<V>,
options: { as: "radio"; value: V },
): RadioBind<V>;
ParamTypeDescription
signalSignal<string | number | boolean>The signal to read from and write to
options{ as: "number" | "checkbox" | "radio"; value?: V }Kind of input; radio also needs the per-radio value

A plain props object matching the input kind:

KindReturn typeProps
defaultTextBind{ value: () => string, oninput: (e) => void }
numberNumberBind{ value: () => string, oninput: (e) => void } (coerces)
checkboxCheckboxBind{ checked: () => boolean, onchange: (e) => void }
radioRadioBind<V>{ value: V, checked: () => boolean, onchange: (e) => void }
import { signal, bind, input, textarea, select, option } from "@whisq/core";
const name = signal("");
input({ ...bind(name) }); // text
const age = signal(0);
input({ type: "number", ...bind(age, { as: "number" }) });
const agreed = signal(false);
input({ type: "checkbox", ...bind(agreed, { as: "checkbox" }) });
const role = signal<"admin" | "user">("user");
input({ type: "radio", name: "role", ...bind(role, { as: "radio", value: "admin" }) });
input({ type: "radio", name: "role", ...bind(role, { as: "radio", value: "user" }) });
const bio = signal("");
textarea({ ...bind(bio) });
const tier = signal("free");
select({ ...bind(tier) }, option({ value: "free" }, "Free"), option({ value: "pro" }, "Pro"));

See Forms guide for the full pattern including validation and reset.