Skip to content

Conversation

kaspernowak
Copy link

@kaspernowak kaspernowak commented Aug 30, 2025

Motivation

Laravel 12 starter kits have moved from the Inertia useForm helper to the Inertia <Form> component. Inertia’s <Form> component does not support Precognition out of the box, making the Laravel 12 Vue starter kits incompatible with Laravel Precognition. This PR adds a thin wrapper over Inertia’s <Form> component to bridge that gap.

Key points

  • Adds <PrecognitionForm> (re-export of named [Form] with live validation built-in.
  • Per-field opt-in or global opt-in via props/attributes.
  • Debounce configurable; errors normalized and synced; slot gets [validating].

Props

  • action: string | { url: string; method: string }
  • method: string (default: 'get') if using string action
  • precognitive: boolean | ValidationConfig (default: true)
  • validateOn: 'input' | 'change' | 'blur' | Array<'input'|'change'|'blur'> (default: 'change')
  • validationTimeout: number | undefined

Per-field opt-in

  • Add precognitive or data-precognitive="true" on inputs to validate that field (even if precognitive=false globally).

Usage: global live validation

<script setup lang="ts">
import { PrecognitionForm } from 'laravel-precognition-vue-inertia'
</script>

<template>
  <PrecognitionForm
    method="post"
    :action="route('register')"
    validate-on="change"
    :validation-timeout="500"
  >
    <template #default="{ data, setData, errors, hasErrors, processing, validating, submit }">
      <label>
        Name
        <input name="name" :value="data.name" @input="setData('name', $event.target.value)" />
        <span v-if="errors.name">{{ errors.name }}</span>
      </label>

      <label>
        Email
        <input name="email" :value="data.email" @input="setData('email', $event.target.value)" />
        <span v-if="errors.email">{{ errors.email }}</span>
      </label>

      <button :disabled="processing || validating" @click="submit()">Save</button>
    </template>
  </PrecognitionForm>
</template>

Usage: per-field opt-in + faster debounce

<PrecognitionForm
  method="patch"
  :action="route('profile.update')"
  :precognitive="false"
  :validate-on="['input','blur']"
  :validation-timeout="300"
>
  <template #default="{ data, setData, errors, validating, submit }">
    <input
      name="username"
      precognitive
      :value="data.username"
      @input="setData('username', $event.target.value)"
    />
    <span v-if="errors.username">{{ errors.username }}</span>

    <input
      name="bio"
      :value="data.bio"
      @input="setData('bio', $event.target.value)"
    />
    <!-- bio won't live-validate without per-field opt-in or precognitive=true -->

    <button :disabled="validating" @click="submit()">Update</button>
  </template>
</PrecognitionForm>

Usage: custom ValidationConfig (headers, hook)

<PrecognitionForm
  action="/api/users"
  method="post"
  :precognitive="{
    headers: { 'X-Extra': '1' },
    onValidationError: (res) => console.debug('precog error', res)
  }"
  validate-on="input"
  :validation-timeout="250"
>
  <template #default="{ data, setData, errors, validating, submit }">
    <!-- fields... -->
  </template>
</PrecognitionForm>

Notes

  • Inputs must have a name attribute.
  • Total latency = debounce + network + server. Tune validationTimeout for UX.

@timacdonald
Copy link
Member

There seems to be a lot of unrelated changes here making it extremely hard to review.

Marking this one as draft until it is in a better spot.

Can you please revert any changes that are not specific to adding the new Form component? Formatting, barrel files, or other miscellaneous fixes that were added along the way – you mentioned restoring the default transform, is that required for this?

I would also hope that we can, like with did with useForm, monkey patch or use composition with the existing Form component to add Precognition, rather than re-implementing everything. It is hard to tell because the diff is rather noisy, but it doesn't feel like we are doing that on first glance.

Thanks for the PR. Will be a good addition.

@timacdonald timacdonald marked this pull request as draft September 1, 2025 03:25
@kaspernowak
Copy link
Author

kaspernowak commented Sep 1, 2025

@timacdonald Thank you for the reply. I agree with this PR not being in a good state, I should have marked it as a draft, my bad.
I have been working on a cleaner PR over the weekend, which should align with your monkey patch approach.
I hope I can have the PR cleaned up by the end of the day, and mark it ready for review.

@kaspernowak kaspernowak force-pushed the feature/form-component-support branch from f17629b to bd2d9f3 Compare September 1, 2025 14:12
@kaspernowak kaspernowak marked this pull request as ready for review September 1, 2025 15:15
@timacdonald
Copy link
Member

Hey, @kaspernowak, there still seems to be a lot of formatting and type changes in here unrelated to the feature.

An example of a formatting change that is causing a bigger diff:

- validateFiles(): Data & Form<Data>,
+ validateFiles(): Data & Form<Data>;

There are type changes to utilise types from Inertia. While I think this is generally good, it makes the changes hard to grok for this feature. If they aren't required, can we please revert them as well?

Any type changes that remain, we will need to check compatibility with currently supported versions of Inertia in Precognition or drop support for them and push the requirement forward.

@kaspernowak
Copy link
Author

kaspernowak commented Sep 1, 2025

@timacdonald This PR should now be easier to review, with only essential changes to pass typechecks for the vue-inertia package.

I also added a PR in the inertajs/inertia github repo, which follows a different approach, by supporting live validation from the inertia Form component directly, driven by live validation providers like Laravel Precognition.
Either this PR or the one in inertiajs/inertia should be chosen, as merging both would create a conflict.

@kaspernowak kaspernowak changed the title Vue-Inertia: Precognition-enabled Inertia Form component + shared useForm Vue-Inertia: Precognition-enabled Inertia Form component Sep 1, 2025
@kaspernowak
Copy link
Author

kaspernowak commented Sep 1, 2025

@timacdonald I did not see your comment before I posted mine.
I can clear up the formatting, and look into reverting the type changes, but I think it would only make sense for me to do, if this PR is the one that gets chosen as the best approach. Would you agree?

@kaspernowak kaspernowak force-pushed the feature/form-component-support branch from e38e38e to 04b2ff6 Compare September 2, 2025 09:01
@kaspernowak kaspernowak force-pushed the feature/form-component-support branch from 04b2ff6 to c45ca5d Compare September 2, 2025 09:04
@kaspernowak
Copy link
Author

kaspernowak commented Sep 2, 2025

@timacdonald I removed the formatting changes (I hope) and reverted the usage of the Method type to the RequestMethod type.

I found it hard to get the vue-inertia package to build without implementing the FormDataKeys, FormDataType, FormDataErrors, and ErrorValue types from @inertiajs/core, so I kept those.
Do you have any suggestions for getting the vue-inertia (and perhaps react-inertia as well) package to build successfully from a clean git pull, without aligning the useForm types with the types used by the current @inertiajs/inertia package?

@kaspernowak kaspernowak marked this pull request as ready for review September 2, 2025 09:40
@taylorotwell taylorotwell marked this pull request as draft September 2, 2025 13:04
@taylorotwell
Copy link
Member

Drafting until ready for review. cc @timacdonald

@kaspernowak
Copy link
Author

@taylorotwell Do you have a preference between the provider driven live validation in the inertia form approach and this thin wrapper around the inertia form approach?
Then I could focus my attention on the preferred PR

@kaspernowak
Copy link
Author

@timacdonald Would you prefer that I ignored any TS errors with // @ts-expect-error instead of correcting the types? I am unsure about what is needed here before this is ready for review.

@timacdonald
Copy link
Member

@kaspernowak, thanks for your work on this. I am going to close this PR as we have an alternative path we are taking to bring the form component to Precognition.

Appreciate you getting us moving on this one.

@timacdonald timacdonald closed this Sep 9, 2025
@kaspernowak
Copy link
Author

kaspernowak commented Sep 9, 2025

@timacdonald Thank you, do you have an estimate of when we can expect precognition to work with the form component?

@timacdonald
Copy link
Member

No estimate, yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants