Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .changeset/forty-eyes-fall.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
'@tanstack/vue-form': patch
---

Refactor: Form option types are now no longer adapter-specific
Refactor: Adapter `formOptions`/`appFormOptions` no longer shim the core types and runtime.

Fix: `formOptions.looseSchema`/`strictSchema` now error on missing schema
BREAKING: `formOptions.looseSchema` and `formOptions.strictSchema` now require a schema as
first parameter. This locks down inference to get the best type safety out of it vs. the options object alone.

Fix: `formOptions.looseSchema` now accepts optional `defaultValues` props
Fix: `formOptions.looseSchema` now allows `defaultValues` to omit properties instead of
requiring them to be explicitly undefined.
9 changes: 5 additions & 4 deletions docs/migrate-from-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,10 +376,11 @@ are `undefined`. Validators with literal `runOnSubmit: false` are skipped during
submission, and their slots are typed as `undefined`. Use the parsed entry when
an endpoint expects the schema's output type.

For schema-led option inference, `formOptions.strictSchema(...)` uses the
schema input as the form shape, while `formOptions.looseSchema(...)` permits
editable nullish defaults and combines them with the schema shape. These option
helpers only affect types; the validators still perform the runtime parsing.
For schema-led option inference, pass the schema first and the options second.
`formOptions.strictSchema(...)` uses the schema input as the form shape, while
`formOptions.looseSchema(...)` permits editable nullish defaults and combines
them with the schema shape. These option helpers only affect types; the
validators still perform the runtime parsing.

When manually calling a schema, return `parseIssues(...)` with the failed issue
array. In a field validator it produces field issues; in a form or group
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const serverSchema = z.object({
age: z.number().min(12),
})

export const formOpts = formOptions.strictSchema({
export const formOpts = formOptions.strictSchema(clientSchema, {
defaultValues: {
age: 0,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,43 +38,46 @@ export const rewardEarlyPunishLate = createValidator({
],
})

export const bookingFormOptions = appFormOptions.strictSchema({
errorVisibility: ({ state, fieldState }) =>
fieldState.meta.isBlurred || state.submissionAttempts > 0,
validators: [rewardEarlyPunishLate(bookingFormSchema)],
defaultValues: {
guestDetails: {
name: '',
email: '',
phoneNumber: '',
guestCount: 1,
},
stayDates: {
dateRange: {
from: undefined,
to: undefined,
export const bookingFormOptions = appFormOptions.strictSchema(
bookingFormSchema,
{
errorVisibility: ({ state, fieldState }) =>
fieldState.meta.isBlurred || state.submissionAttempts > 0,
validators: [rewardEarlyPunishLate(bookingFormSchema)],
defaultValues: {
guestDetails: {
name: '',
email: '',
phoneNumber: '',
guestCount: 1,
},
stayDates: {
dateRange: {
from: undefined,
to: undefined,
},
arrivalTime: '',
},
roomPreferences: {
roomType: 'standard',
bedPreference: 'queen',
smokingPreference: 'non-smoking',
floorPreference: 'no-preference',
},
budget: {
maxNightlyBudget: 200,
currency: 'USD',
},
addOns: {
includeBreakfast: false,
airportPickup: false,
parkingRequired: false,
},
specialRequests: {
notes: '',
},
arrivalTime: '',
},
roomPreferences: {
roomType: 'standard',
bedPreference: 'queen',
smokingPreference: 'non-smoking',
floorPreference: 'no-preference',
},
budget: {
maxNightlyBudget: 200,
currency: 'USD',
},
addOns: {
includeBreakfast: false,
airportPickup: false,
parkingRequired: false,
},
specialRequests: {
notes: '',
},
},
})
)

export type BookingForm = ReactFormType<typeof bookingFormOptions>
Loading
Loading