Resumable: validated form

A live-validated form, fully resumed without re-running the component. Two fields (signals) feed a computed graph (emailOk + passOkformOk), which drives the button's disabled attribute and the inline error reads.

Tip
Type an invalid email or a short password: the errors appear and the button stays disabled. The component never runs on the client — the disabled attribute, the chained computeds, and the submit all resume from the server's state.

Live demo


Signup.tsxTSX
"use resumable";
import { signal, computed } from "@bext-stack/framework/signals";

export default function Signup() {
  const email = signal("");
  const password = signal("");
  // computed-of-computed validity graph:
  const emailOk = computed(() => email.value.includes("@"));
  const passOk  = computed(() => password.value.length >= 8);
  const formOk  = computed(() => emailOk.value && passOk.value);
  return (
    <form onSubmit={(e) => { e.preventDefault(); /* … */ }}>
      <input onInput={(e) => { email.value = e.target.value; }} />
      {/* reactive disabled attr bound to a computed: */}
      <button disabled={!formOk.value}>Create account</button>
    </form>
  );
}