Skip to content

Capabilities ​

@jayoncode/form-intelligence is a headless form workflow engine. You pick the features you need; the engine centralizes validation, formatting, conditional logic, business rules, autosave, drafts, submission, and integrations while you keep full control of UI.

Previous: Core concepts · Next: Validation

One sentence

Form Intelligence manages everything that happens before, during, and after form submission — not just validation.

Status legend ​

BadgeMeaning
SHIPPEDAvailable today
PARTIALFoundation shipped; polish or integration pending
PLANNEDOn the roadmap

Core lifecycle ​

1. Form state management — SHIPPED ​

One instance owns values, errors, loading, dirty, and touched state.

ts
const form = createForm({
  initialValues: { email: "" },
  // Optional: declarative listeners (same store as form.subscribe; until destroy)
  subscribe: (form) => {
    syncUi(form.state);
  },
});

form.state.values;
form.state.errors;
form.state.isSubmitting;
form.state.isDirty;

State explorer →

2. Validation engine — SHIPPED ​

Declarative schema — no manual if (!email.includes("@")). On DOM-backed forms, Phase 1 HTML attributes (required, minlength, pattern, type="email"|"url", …) are imported into the same engine on attach (Field > Schema > HTML).

ts
createForm({
  schema: { email: { required: true, type: "email" } },
});
html
<!-- Or zero JS validators — attributes alone: -->
<input name="email" required type="email" />

Validation guide → · HTML constraints playground →

3. Custom validation — SHIPPED ​

Encode business rules in the schema or validator list.

ts
username: {
  validate(value) {
    return value !== "admin" || "Username already taken";
  },
}

4. Async validation — SHIPPED ​

Debounced onChange checks, per-field form.state.fieldMeta[path].isValidating for "Checking…" UI.

ts
username: {
  async validate(value) {
    const exists = await api.exists(value);
    return !exists || "Username already exists";
  },
}

Validation playground →


Input transformation ​

5. Formatting engine — SHIPPED ​

Presets: philippine-phone, credit-card, plus custom format / parse hooks.

Formatters →

5b. Transform pipeline — SHIPPED ​

Inbound stages before validation (trim / normalize / sanitize / parse):

ts
form.field("name", { transform: { trim: true, normalize: true } });
form.transform("code").pipe((v) => String(v).toUpperCase());

Import helpers from @jayoncode/form-intelligence/transform.


Conditional logic and rules ​

6. Conditional logic — SHIPPED ​

Show, hide, require, and enable fields based on other values — no scattered useEffect.

ts
import { createForm, when } from "@jayoncode/form-intelligence";

createForm({
  initialValues: { customerType: "Personal", companyName: "" },
  rules: [when("customerType").equals("Business").show("companyName")],
});

Wrap fields for DOM hide/show:

html
<div data-form-intelligent-field="companyName">
  <label>Company Name</label>
  <input name="companyName" />
</div>

Read presentation without digging into snapshots:

ts
form.getPresentation("companyName").field.visible;
form.field("companyName").ui.visible;
form.getPresentation().formUi.submitDisabled;

Import helpers from @jayoncode/form-intelligence/presentation when needed.

Rules guide →

7. Enable / disable — SHIPPED ​

ts
when("country").equals("Philippines").enable("province");

8. Required / optional — SHIPPED ​

ts
when("customerType").equals("Business").require("taxNumber");

9. Field dependency — SHIPPED ​

ts
when("country").changes(loadProvinces).populate("province");

// Structural cascade (clear children on parent change)
createForm({
  dependencies: { province: ["country"], city: ["province"] },
});

Dependencies playground → · Rules guide →

10. Calculations — SHIPPED ​

ts
form.calculate("total", ({ values }) => values.price * values.quantity);

form
  .calculate("total")
  .from("price", "quantity")
  .compute(({ get }) => Number(get("price")) * Number(get("quantity")));

Calculations guide → · Playground →

25. Business rule engine — SHIPPED ​

ts
form
  .when("loanAmount")
  .greaterThan(500_000)
  .then((ctx) => {
    ctx.show("managerApproval");
    ctx.require("managerApproval");
    ctx.disableSubmit();
  });

Rules playground →


Workflow ​

11. Wizard — SHIPPED ​

Multi-step forms with per-step validation, branching (when / next / canLeave / canEnter), goTo modes, and optional persistStepInDraft.

Workflow guide →

12. Progress — SHIPPED ​

form.state.workflow.progress — percentage and step navigation built in.

13. Autosave — SHIPPED ​

ts
workflow: { autosave: { enabled: true, debounceMs: 5000, onSave } }

14. Draft recovery — SHIPPED ​

form.saveDraft(), form.restoreDraft({ force?, prompt?, merge? }), restore on reload, optional promptOnRestore / onRestorePrompt / onRestoreDecline (keep | clear | remember) + envelopes/migrateDraft.

15. Offline queue — SHIPPED ​

workflow.offlineQueue — maxItems / overflow, idempotencyKey, onConflict, form.flushOfflineQueue() on reconnect.

Submission playground →


Submission and change tracking ​

16. Submission engine — SHIPPED ​

Validate → loading → disable button → API → success/error → re-enable. submitPhase machine + form.useMiddleware onion (same stack as plugin hooks).

Submission guide →

17. Dirty tracking — SHIPPED ​

form.isDirty() for leave-page guards.

18. Undo / redo — SHIPPED ​

form.undo() / form.redo() with value history stack.

19. Changed fields — SHIPPED ​

form.changedFields() returns paths that differ from initial values.

State guide →


Integrations ​

20. Browser session — SHIPPED ​

ts
import { createBrowserLifecyclePlugin } from "@jayoncode/form-intelligence/plugins";

form.use(createBrowserLifecyclePlugin({ saveDraftOnHidden: true }));

Saves draft when the tab is hidden.

21. Keyboard shortcuts — SHIPPED ​

workflow.keyboard or createKeyboardPlugin() — Ctrl+S save, Ctrl+Enter submit.

Integrations guide → · Playground →

22. Analytics — SHIPPED ​

form.getAnalytics() — errors by field, field views, drop-off, timings. Path allow/deny; never snapshots values. Not a product analytics SDK.

23. Plugin system — SHIPPED ​

createForm({ plugins }) / form.use(plugin) / registerPlugin(), hook bus, error isolation (onPluginError), version / engines metadata, PLUGIN_PIPELINE_STAGES.

Plugins guide → · Author guide →

24. React adapter — SHIPPED ​

tsx
import { useForm } from "@jayoncode/form-intelligence-react";

const form = useForm({ schema: { email: "email" } });
// form.controller · form.fieldController · aria on form.field()

Vue / Angular packages ship the same controller contract as React (controller, fieldController, focusFirstInvalid).

Adapters guide →

26. Controllers + accessibility — SHIPPED ​

createFormController(form), field.aria / setAriaIds, focusFirstInvalid, @jayoncode/form-intelligence/accessibility.

27. DevTools — SHIPPED (optional subpath) ​

ts
import { enableFormDevTools, getFormDevTools } from "@jayoncode/form-intelligence/devtools";

Inspector: events, validation, workflow, plugins, performance marks. Not pulled into the core-login bundle.

Integrations → · Playground →


How it fits together ​

USER TYPES → State Updates → Validation / Formatting / Rules
          → Update State → Re-render → Submit → Submission Engine

Next steps ​

GoalGuide
Get startedTutorial
Conditional fieldsRules
Derived valuesCalculations
Snapshots / undoState
Session / keyboardIntegrations
Controllers / a11yAdapters
Bundle / timingPerformance
Engineering roadmap002-form-os-capabilities

An ecosystem of independent, headless TypeScript libraries engineered for modern web development. Every package includes interactive playgrounds and documentation that evolves alongside the code.