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
2 changes: 1 addition & 1 deletion docs/framework/vue/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ form.provideFormContext()
<div>
<div>
<form.Field name="fullName">
<template v-slot="field">
<template v-slot="{ field }">
<input
:name="field.name"
:value="field.state.value"
Expand Down
12 changes: 8 additions & 4 deletions examples/vue/simple/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,14 @@ async function onChangeFirstName(value) {
:onChangeAsyncDebounceMs="500"
:onChangeAsync="onChangeFirstName"
>
<template v-slot="field, state">
<template v-slot="{ field, state }">
<label :htmlFor="field.name">First Name:</label>
<input
:name="field.name"
:value="field.state.value"
@input="(e) => field.handleChange(e.target.value)"
@input="
(e) => field.handleChange((e.target as HTMLInputElement).value)
"
@blur="field.handleBlur"
/>
<FieldInfo :state="state" />
Expand All @@ -59,12 +61,14 @@ async function onChangeFirstName(value) {
</div>
<div>
<form.Field name="lastName">
<template v-slot="field, state">
<template v-slot="{ field, state }">
<label :htmlFor="field.name">Last Name:</label>
<input
:name="field.name"
:value="field.state.value"
@input="(e) => field.handleChange(e.target.value)"
@input="
(e) => field.handleChange((e.target as HTMLInputElement).value)
"
@blur="field.handleBlur"
/>
<FieldInfo :state="state" />
Expand Down
10 changes: 5 additions & 5 deletions packages/vue-form/src/tests/useField.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('useField', () => {

return () => (
<form.Field name="firstName" defaultValue="FirstName">
{(field: FieldApi<string, Person>) => (
{({ field }: { field: FieldApi<string, Person> }) => (
<input
data-testid={'fieldinput'}
value={field.state.value}
Expand Down Expand Up @@ -68,7 +68,7 @@ describe('useField', () => {
name="firstName"
onChange={(value) => (value === 'other' ? error : undefined)}
>
{(field: FieldApi<string, Person>) => (
{({ field }: { field: FieldApi<string, Person> }) => (
<div>
<input
data-testid="fieldinput"
Expand Down Expand Up @@ -111,7 +111,7 @@ describe('useField', () => {
name="firstName"
onChange={(value) => (value === 'other' ? error : undefined)}
>
{(field: FieldApi<string, Person>) => (
{({ field }: { field: FieldApi<string, Person> }) => (
<div>
<input
data-testid="fieldinput"
Expand Down Expand Up @@ -159,7 +159,7 @@ describe('useField', () => {
return error
}}
>
{(field: FieldApi<string, Person>) => (
{({ field }: { field: FieldApi<string, Person> }) => (
<div>
<input
data-testid="fieldinput"
Expand Down Expand Up @@ -211,7 +211,7 @@ describe('useField', () => {
return error
}}
>
{(field: FieldApi<string, Person>) => (
{({ field }: { field: FieldApi<string, Person> }) => (
<div>
<input
data-testid="fieldinput"
Expand Down
12 changes: 9 additions & 3 deletions packages/vue-form/src/tests/useForm.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe('useForm', () => {

return () => (
<form.Field name="firstName" defaultValue="">
{(field: FieldApi<string, Person>) => (
{({ field }: { field: FieldApi<string, Person> }) => (
<input
data-testid={'fieldinput'}
value={field.state.value}
Expand Down Expand Up @@ -69,7 +69,9 @@ describe('useForm', () => {

return () => (
<form.Field name="firstName" defaultValue="">
{(field: FieldApi<string, Person>) => <p>{field.state.value}</p>}
{({ field }: { field: FieldApi<string, Person> }) => (
<p>{field.state.value}</p>
)}
</form.Field>
)
})
Expand All @@ -96,7 +98,11 @@ describe('useForm', () => {
return () => (
<form.Provider>
<form.Field name="firstName">
{(field: FieldApi<string, { firstName: string }>) => {
{({
field,
}: {
field: FieldApi<string, { firstName: string }>
}) => {
return (
<input
value={field.state.value}
Expand Down
45 changes: 24 additions & 21 deletions packages/vue-form/src/useField.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import {
type DeepKeys,
type DeepValue,
FieldApi,
type FieldOptions,
type Narrow,
import { FieldApi } from '@tanstack/form-core'
import type {
FieldState,
DeepKeys,
DeepValue,
FieldOptions,
Narrow,
} from '@tanstack/form-core'
import { useStore } from '@tanstack/vue-store'
import {
type SetupContext,
defineComponent,
type Ref,
onMounted,
onUnmounted,
watch,
} from 'vue-demi'
import { defineComponent, onMounted, onUnmounted, watch } from 'vue-demi'
import type { SlotsType, SetupContext, Ref } from 'vue-demi'
import { provideFormContext, useFormContext } from './formContext'

declare module '@tanstack/form-core' {
Expand Down Expand Up @@ -113,11 +108,7 @@ export type FieldValue<TFormData, TField> = TFormData extends any[]
// // ^?

export type FieldComponent<TParentData, TFormData> = <TField>(
fieldOptions: {
children?: (
fieldApi: FieldApi<FieldValue<TParentData, TField>, TFormData>,
) => any
} & Omit<
fieldOptions: Omit<
UseFieldOptions<FieldValue<TParentData, TField>, TFormData>,
'name' | 'index'
> &
Expand All @@ -130,7 +121,15 @@ export type FieldComponent<TParentData, TFormData> = <TField>(
name: TField extends undefined ? TField : DeepKeys<TParentData>
index?: never
}),
context: SetupContext,
context: SetupContext<
{},
SlotsType<{
default: {
field: FieldApi<FieldValue<TParentData, TField>, TFormData>
state: FieldState<any>
}
}>
>,
) => any

export const Field = defineComponent(
Expand All @@ -145,7 +144,11 @@ export const Field = defineComponent(
parentFieldName: fieldApi.api.name,
} as never)

return () => context.slots.default!(fieldApi.api, fieldApi.state.value)
return () =>
context.slots.default!({
field: fieldApi.api,
state: fieldApi.state.value,
})
},
{ name: 'Field', inheritAttrs: false },
)
19 changes: 15 additions & 4 deletions packages/vue-form/src/useForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { FormApi, type FormState, type FormOptions } from '@tanstack/form-core'
import { useStore } from '@tanstack/vue-store'
import { type UseField, type FieldComponent, Field, useField } from './useField'
import { provideFormContext } from './formContext'
import { defineComponent } from 'vue-demi'
import {
type EmitsOptions,
type SlotsType,
type SetupContext,
defineComponent,
} from 'vue-demi'
import type { NoInfer } from './types'

declare module '@tanstack/form-core' {
Expand All @@ -15,9 +20,15 @@ declare module '@tanstack/form-core' {
useStore: <TSelected = NoInfer<FormState<TFormData>>>(
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,
) => TSelected
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(props: {
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected
}) => any
Subscribe: <TSelected = NoInfer<FormState<TFormData>>>(
props: {
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected
},
context: SetupContext<
EmitsOptions,
SlotsType<{ default: NoInfer<FormState<TFormData>> }>
>,
) => any
}
}

Expand Down