Resumable: validated form
A live-validated form, fully resumed without re-running the component. Two fields (signals) feed a computed graph (emailOk + passOk → formOk), 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
"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>
);
}