UNPKG

trellis

Version:

Agentic State Engine — event-sourced causal graph with branching, decision traces, and realtime sync for AI-native applications

77 lines (75 loc) 2.23 kB
import { createFormCore, formSchemaFrom } from "../../chunk-25WAHQHF.js"; import "../../chunk-2ESYSVXG.js"; // src/forms/vanilla/index.ts function createVanillaForm(schema, initialValues) { const core = createFormCore(formSchemaFrom(schema), initialValues ?? {}); const form = { get state() { return core.state; }, actions: core.actions, field: core.field, subscribe: (listener) => core.subscribe(() => listener(core.state)) }; return form; } function bindFormToDOM(form, formElement, fieldSelectors, onSubmit, options = {}) { const errorAttribute = options.errorAttribute ?? "data-error-for"; const handleSubmit = (e) => { e.preventDefault(); void (async () => { const result = await form.actions.validate(); if (result.valid) { await onSubmit?.(form.state.values); } })(); }; formElement.addEventListener("submit", handleSubmit); const fieldElements = {}; const removers = []; for (const [name, selector] of Object.entries(fieldSelectors)) { const el = formElement.querySelector( selector ); if (!el) continue; fieldElements[name] = el; const onInput = () => { form.actions.setValue(name, el.value); }; const onBlur = () => { form.actions.setTouched(name, true); }; el.addEventListener("input", onInput); el.addEventListener("blur", onBlur); removers.push(() => { el.removeEventListener("input", onInput); el.removeEventListener("blur", onBlur); }); } const unsubscribe = form.subscribe((state) => { for (const [name, el] of Object.entries(fieldElements)) { if (document.activeElement !== el) { el.value = state.values[name] !== void 0 ? String(state.values[name]) : ""; } const errorEl = formElement.querySelector( `[${errorAttribute}="${name}"]` ); if (errorEl) { errorEl.textContent = state.errors[name] ?? ""; errorEl.style.display = state.errors[name] ? "block" : "none"; } } }); return () => { formElement.removeEventListener("submit", handleSubmit); removers.forEach((remove) => remove()); unsubscribe(); }; } export { bindFormToDOM, createVanillaForm };