toolmark-monorepo / @toolmark/inertia / inertiaFormComponentAdapter
Function: inertiaFormComponentAdapter()
inertiaFormComponentAdapter(
o):FormAdapter<Record<string,unknown>> &object
Defined in: packages/inertia/src/form-component.ts:102
Adapts an Inertia <Form> component (@inertiajs/react 2.1+, uncontrolled; spec §10.1, D11) to form tools. getValues, setValues, dirtyPaths, fields and onUserInteraction (trusted user input / focus / submit interactions for tour hooks, spec §13) come unmodified from domFormAdapter over the <Form>'s underlying <form> element; dispose extends its dispose (see below).
submit() calls formRef.current.submit() — the <Form>'s documented imperative ref method — and settles from the global router events of the visit it starts: the <Form> component drives its own visit internally, so there is no router.visit call here to attach per-visit callbacks to (contrast inertiaAdapter, which submits and settles through visit-outcome.ts). It arms on the next start event after submit() is called, then watches — until that visit's finish — for: error (server-side validation errors) → settles invalid (one issue per error key, path: '' with a generic message if none can be read); httpException (Inertia 3) / invalid (Inertia 2) → settles error "Request failed"; networkError (Inertia 3) / exception (Inertia 2) → settles error "Network error"; otherwise, at finish, visit.cancelled || visit.interrupted → cancelled 'signal', else ok({}). Both majors' event names are listened to (harmless: whichever major is installed never fires the names it doesn't recognize — verified against the installed 3.7.1 and a packed 2.3.28), and every listener is removed once the promise settles. A missing ref (formRef.current is null, e.g. before the <Form> has mounted) settles immediately with error"Form is not mounted", without attaching any listener. If no start arrives within 1000 ms of formRef.current.submit() (e.g. an onBefore returned false, or the submit was swallowed), the call settles error"Submit did not start a visit" and its listeners are removed; once a visit has started it may take as long as it needs.
A bare finish maps to ok here. A finish with no earlier failure event and no cancelled/interrupted flag settles ok({}) — unlike visit-outcome.ts (used by inertiaAdapter), where a per-visit onFinish with no earlier outcome means error"Visit did not complete". The difference is deliberate: that path also receives the per-visit onSuccess, so reaching onFinish without it means the request failed; here success is only observable through the global finish itself.
Visit correlation. The events carry no visit id, so the visit is correlated by url + method: the first start after submit() records its visit.url.href and visit.method, and from then on a finish — or an error/httpException/invalid/networkError/exception that carries a visit — is only accepted when its url + method match; an interleaved, unrelated visit (a background poll, another form) is ignored. Failure events without a visit (their usual shape in both majors) are accepted while this visit is in flight, so an unrelated visit's failure arriving in that window is still indistinguishable from this one's. When the start visit has no readable url/method, every event is accepted (the pre-correlation behaviour).
dispose() also tears down any in-flight submit(): its router listeners are removed and its promise settles cancelled 'signal'.
Parameters
o
element is the <Form>'s underlying <form> element; formRef is the ref object passed to <Form ref={...}>; router is @inertiajs/react's router, passed directly.
element
HTMLFormElement
formRef
{ current: { submit: void; } | null; }
formRef.current
{ submit: void; } | null
router
Returns
A FormAdapter; call dispose() when the <Form> goes away.