mirror of
https://github.com/LukeHagar/form.git
synced 2025-12-09 04:19:49 +00:00
fix: refactor to flat generics with consistent names & patterns
This commit is contained in:
@@ -6,7 +6,7 @@ import { useForm } from './useForm'
|
||||
export type FormFactory<TFormData> = {
|
||||
useForm: (opts?: FormOptions<TFormData>) => FormApi<TFormData>
|
||||
useField: UseField<TFormData>
|
||||
Field: FieldComponent<TFormData, TFormData>
|
||||
Field: FieldComponent<TFormData>
|
||||
}
|
||||
|
||||
export function createFormFactory<TFormData>(
|
||||
|
||||
@@ -2,8 +2,8 @@ import type { FieldOptions, DeepKeys } from '@tanstack/form-core'
|
||||
|
||||
export type UseFieldOptions<
|
||||
TData,
|
||||
TFormData,
|
||||
TName = unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
> = FieldOptions<TData, TFormData, TName> & {
|
||||
TParentData,
|
||||
TName extends DeepKeys<TParentData>,
|
||||
> = FieldOptions<TData, TParentData, TName> & {
|
||||
mode?: 'value' | 'array'
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import {
|
||||
FieldApi,
|
||||
type FieldApiOptions,
|
||||
type FormApi,
|
||||
import { FieldApi } from '@tanstack/form-core'
|
||||
import type {
|
||||
DeepKeys,
|
||||
DeepValue,
|
||||
Narrow,
|
||||
ResolveData,
|
||||
} from '@tanstack/form-core'
|
||||
import type { DeepKeys, DeepValue, Narrow } from '@tanstack/form-core'
|
||||
import { useStore } from '@tanstack/vue-store'
|
||||
import { defineComponent, onMounted, onUnmounted, watch } from 'vue-demi'
|
||||
import type { SlotsType, SetupContext, Ref } from 'vue-demi'
|
||||
@@ -12,44 +13,52 @@ import type { UseFieldOptions } from './types'
|
||||
|
||||
declare module '@tanstack/form-core' {
|
||||
// eslint-disable-next-line no-shadow
|
||||
interface FieldApi<_TData, TFormData, Opts, TData> {
|
||||
Field: FieldComponent<TFormData, TData>
|
||||
interface FieldApi<
|
||||
TData,
|
||||
TParentData,
|
||||
TName extends DeepKeys<TParentData>,
|
||||
TResolvedData extends ResolveData<TData, TParentData, TName> = ResolveData<
|
||||
TData,
|
||||
TParentData,
|
||||
TName
|
||||
>,
|
||||
> {
|
||||
Field: FieldComponent<TResolvedData>
|
||||
}
|
||||
}
|
||||
|
||||
export type UseField<TFormData> = <TField extends DeepKeys<TFormData>>(
|
||||
opts?: { name: Narrow<TField> } & UseFieldOptions<
|
||||
DeepValue<TFormData, TField>,
|
||||
TFormData
|
||||
export type UseField<TParentData> = <TName extends DeepKeys<TParentData>>(
|
||||
opts?: { name: Narrow<TName> } & UseFieldOptions<
|
||||
DeepValue<TParentData, TName>,
|
||||
TParentData,
|
||||
TName
|
||||
>,
|
||||
) => FieldApi<DeepValue<TFormData, TField>, TFormData>
|
||||
) => FieldApi<DeepValue<TParentData, TName>, TParentData, TName>
|
||||
|
||||
export function useField<
|
||||
TData,
|
||||
TFormData,
|
||||
TName extends unknown extends TFormData
|
||||
? string
|
||||
: DeepKeys<TFormData> = unknown extends TFormData
|
||||
? string
|
||||
: DeepKeys<TFormData>,
|
||||
TParentData,
|
||||
TName extends DeepKeys<TParentData>,
|
||||
>(
|
||||
opts: UseFieldOptions<TData, TFormData, TName>,
|
||||
opts: UseFieldOptions<TData, TParentData, TName>,
|
||||
): {
|
||||
api: FieldApi<
|
||||
TData,
|
||||
TFormData,
|
||||
Omit<typeof opts, 'onMount'> & {
|
||||
form: FormApi<TFormData>
|
||||
}
|
||||
TParentData,
|
||||
TName
|
||||
// Omit<typeof opts, 'onMount'> & {
|
||||
// form: FormApi<TParentData>
|
||||
// }
|
||||
>
|
||||
state: Readonly<
|
||||
Ref<
|
||||
FieldApi<
|
||||
TData,
|
||||
TFormData,
|
||||
Omit<typeof opts, 'onMount'> & {
|
||||
form: FormApi<TFormData>
|
||||
}
|
||||
TParentData,
|
||||
TName
|
||||
// Omit<typeof opts, 'onMount'> & {
|
||||
// form: FormApi<TParentData>
|
||||
// }
|
||||
>['state']
|
||||
>
|
||||
>
|
||||
@@ -91,17 +100,16 @@ export function useField<
|
||||
return { api: fieldApi, state: fieldState } as never
|
||||
}
|
||||
|
||||
export type FieldValue<TFormData, TField> = TFormData extends any[]
|
||||
? unknown extends TField
|
||||
? TFormData[number]
|
||||
: DeepValue<TFormData[number], TField>
|
||||
: DeepValue<TFormData, TField>
|
||||
export type FieldValue<TParentData, TName> = TParentData extends any[]
|
||||
? unknown extends TName
|
||||
? TParentData[number]
|
||||
: DeepValue<TParentData[number], TName>
|
||||
: DeepValue<TParentData, TName>
|
||||
|
||||
type FieldComponentProps<
|
||||
TData,
|
||||
TParentData,
|
||||
TFormData,
|
||||
TField,
|
||||
TName extends unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
TName extends DeepKeys<TParentData>,
|
||||
> = (TParentData extends any[]
|
||||
? {
|
||||
name?: TName
|
||||
@@ -111,40 +119,35 @@ type FieldComponentProps<
|
||||
name: TName
|
||||
index?: never
|
||||
}) &
|
||||
Omit<UseFieldOptions<TField, TFormData, TName>, 'name' | 'index'>
|
||||
Omit<UseFieldOptions<TData, TParentData, TName>, 'name' | 'index'>
|
||||
|
||||
export type FieldComponent<TParentData, TFormData> = <
|
||||
// Type of the field
|
||||
TField,
|
||||
// Name of the field
|
||||
TName extends unknown extends TFormData ? string : DeepKeys<TFormData>,
|
||||
export type FieldComponent<TParentData> = <
|
||||
TData,
|
||||
TName extends DeepKeys<TParentData>,
|
||||
TResolvedData extends ResolveData<TData, TParentData, TName> = ResolveData<
|
||||
TData,
|
||||
TParentData,
|
||||
TName
|
||||
>,
|
||||
>(
|
||||
fieldOptions: FieldComponentProps<TParentData, TFormData, TField, TName>,
|
||||
fieldOptions: FieldComponentProps<TData, TParentData, TName>,
|
||||
context: SetupContext<
|
||||
{},
|
||||
SlotsType<{
|
||||
default: {
|
||||
field: FieldApi<
|
||||
TField,
|
||||
TFormData,
|
||||
FieldApiOptions<TField, TFormData, TName>
|
||||
>
|
||||
state: FieldApi<
|
||||
TField,
|
||||
TFormData,
|
||||
FieldApiOptions<TField, TFormData, TName>
|
||||
>['state']
|
||||
field: FieldApi<TData, TParentData, TName, TResolvedData>
|
||||
state: FieldApi<TData, TParentData, TName, TResolvedData>['state']
|
||||
}
|
||||
}>
|
||||
>,
|
||||
) => any
|
||||
|
||||
export const Field = defineComponent(
|
||||
<TData, TFormData>(
|
||||
fieldOptions: UseFieldOptions<TData, TFormData>,
|
||||
<TData, TParentData, TName extends DeepKeys<TParentData>>(
|
||||
fieldOptions: UseFieldOptions<TData, TParentData, TName>,
|
||||
context: SetupContext,
|
||||
) => {
|
||||
const fieldApi = useField({ ...fieldOptions, ...context.attrs })
|
||||
const fieldApi = useField({ ...fieldOptions, ...context.attrs } as any)
|
||||
|
||||
provideFormContext({
|
||||
formApi: fieldApi.api.form,
|
||||
|
||||
@@ -14,7 +14,7 @@ declare module '@tanstack/form-core' {
|
||||
interface FormApi<TFormData> {
|
||||
Provider: (props: Record<string, any> & {}) => any
|
||||
provideFormContext: () => void
|
||||
Field: FieldComponent<TFormData, TFormData>
|
||||
Field: FieldComponent<TFormData>
|
||||
useField: UseField<TFormData>
|
||||
useStore: <TSelected = NoInfer<FormState<TFormData>>>(
|
||||
selector?: (state: NoInfer<FormState<TFormData>>) => TSelected,
|
||||
|
||||
Reference in New Issue
Block a user