@tanstack/form-core
Advanced tools
Comparing version 0.3.2 to 0.3.3
@@ -112,5 +112,14 @@ import { Store } from '@tanstack/store'; | ||
} | ||
type FieldApiOptions<TData, TFormData> = FieldOptions<TData, TFormData> & { | ||
interface FieldApiOptions<_TData, TFormData, | ||
/** | ||
* This allows us to restrict the name to only be a valid field name while | ||
* also assigning it to a generic | ||
*/ | ||
TName = unknown extends TFormData ? string : DeepKeys<TFormData>, | ||
/** | ||
* If TData is unknown, we can use the TName generic to determine the type | ||
*/ | ||
TData = unknown extends _TData ? DeepValue<TFormData, TName> : _TData> extends FieldOptions<_TData, TFormData, TName, TData> { | ||
form: FormApi<TFormData>; | ||
}; | ||
} | ||
type FieldMeta = { | ||
@@ -127,32 +136,19 @@ isTouched: boolean; | ||
}; | ||
/** | ||
* TData may not be known at the time of FieldApi construction, so we need to | ||
* use a conditional type to determine if TData is known or not. | ||
* | ||
* If TData is not known, we use the TFormData type to determine the type of | ||
* the field value based on the field name. | ||
*/ | ||
type GetTData<Name, TData, TFormData> = unknown extends TData ? DeepValue<TFormData, Name> : TData; | ||
declare class FieldApi<TData, TFormData> { | ||
type GetTData<TData, TFormData, Opts extends FieldApiOptions<TData, TFormData>> = Opts extends FieldApiOptions<infer _TData, infer _TFormData, infer _TName, infer RealTData> ? RealTData : never; | ||
declare class FieldApi<_TData, TFormData, Opts extends FieldApiOptions<_TData, TFormData> = FieldApiOptions<_TData, TFormData>, TData extends GetTData<_TData, TFormData, Opts> = GetTData<_TData, TFormData, Opts>> { | ||
#private; | ||
uid: number; | ||
form: FormApi<TFormData>; | ||
form: Opts['form']; | ||
name: DeepKeys<TFormData>; | ||
/** | ||
* This is a hack that allows us to use `GetTData` without calling it everywhere | ||
* | ||
* Unfortunately this hack appears to be needed alongside the `TName` hack | ||
* further up in this file. This properly types all of the internal methods, | ||
* while the `TName` hack types the options properly | ||
*/ | ||
_tdata: GetTData<typeof this$1.name, TData, TFormData>; | ||
store: Store<FieldState<typeof this$1._tdata>>; | ||
state: FieldState<typeof this$1._tdata>; | ||
prevState: FieldState<typeof this$1._tdata>; | ||
options: FieldOptions<typeof this$1._tdata, TFormData>; | ||
constructor(opts: FieldApiOptions<TData, TFormData>); | ||
options: Opts; | ||
store: Store<FieldState<TData>>; | ||
state: FieldState<TData>; | ||
prevState: FieldState<TData>; | ||
constructor(opts: Opts & { | ||
form: FormApi<TFormData>; | ||
}); | ||
mount: () => () => void; | ||
update: (opts: FieldApiOptions<typeof this$1._tdata, TFormData>) => void; | ||
getValue: () => typeof this$1._tdata; | ||
setValue: (updater: Updater<typeof this$1._tdata>, options?: { | ||
update: (opts: FieldApiOptions<TData, TFormData>) => void; | ||
getValue: () => TData; | ||
setValue: (updater: Updater<TData>, options?: { | ||
touch?: boolean; | ||
@@ -165,12 +161,12 @@ notify?: boolean; | ||
getInfo: () => Record<DeepKeys<TFormData>, FieldInfo<TFormData>>[DeepKeys<TFormData>]; | ||
pushValue: (value: typeof this$1._tdata extends any[] ? (typeof this$1._tdata)[number] : never) => void; | ||
insertValue: (index: number, value: typeof this$1._tdata extends any[] ? (typeof this$1._tdata)[number] : never) => void; | ||
pushValue: (value: TData extends any[] ? TData[number] : never) => void; | ||
insertValue: (index: number, value: TData extends any[] ? TData[number] : never) => void; | ||
removeValue: (index: number) => void; | ||
swapValues: (aIndex: number, bIndex: number) => void; | ||
getSubField: <TName extends DeepKeys<GetTData<DeepKeys<TFormData>, TData, TFormData>>>(name: TName) => FieldApi<DeepValue<GetTData<DeepKeys<TFormData>, TData, TFormData>, TName>, TFormData>; | ||
validateSync: (value: GetTData<DeepKeys<TFormData>, TData, TFormData> | undefined, cause: ValidationCause) => void; | ||
getSubField: <TName extends DeepKeys<TData>>(name: TName) => FieldApi<DeepValue<TData, TName>, TFormData, FieldApiOptions<DeepValue<TData, TName>, TFormData, unknown extends TFormData ? string : DeepKeys<TFormData>, unknown extends DeepValue<TData, TName> ? DeepValue<TFormData, unknown extends TFormData ? string : DeepKeys<TFormData>> : DeepValue<TData, TName>>, unknown extends DeepValue<TData, TName> ? DeepValue<TFormData, unknown extends TFormData ? string : DeepKeys<TFormData>> : DeepValue<TData, TName>>; | ||
validateSync: (value: TData | undefined, cause: ValidationCause) => void; | ||
cancelValidateAsync: () => void; | ||
validateAsync: (value: GetTData<DeepKeys<TFormData>, TData, TFormData> | undefined, cause: ValidationCause) => Promise<ValidationError[]>; | ||
validate: (cause: ValidationCause, value?: typeof this$1._tdata) => ValidationError[] | Promise<ValidationError[]>; | ||
handleChange: (updater: Updater<typeof this$1._tdata>) => void; | ||
validateAsync: (value: TData | undefined, cause: ValidationCause) => Promise<ValidationError[]>; | ||
validate: (cause: ValidationCause, value?: TData) => ValidationError[] | Promise<ValidationError[]>; | ||
handleChange: (updater: Updater<TData>) => void; | ||
handleBlur: () => void; | ||
@@ -177,0 +173,0 @@ } |
@@ -112,5 +112,14 @@ import { Store } from '@tanstack/store'; | ||
} | ||
type FieldApiOptions<TData, TFormData> = FieldOptions<TData, TFormData> & { | ||
interface FieldApiOptions<_TData, TFormData, | ||
/** | ||
* This allows us to restrict the name to only be a valid field name while | ||
* also assigning it to a generic | ||
*/ | ||
TName = unknown extends TFormData ? string : DeepKeys<TFormData>, | ||
/** | ||
* If TData is unknown, we can use the TName generic to determine the type | ||
*/ | ||
TData = unknown extends _TData ? DeepValue<TFormData, TName> : _TData> extends FieldOptions<_TData, TFormData, TName, TData> { | ||
form: FormApi<TFormData>; | ||
}; | ||
} | ||
type FieldMeta = { | ||
@@ -127,32 +136,19 @@ isTouched: boolean; | ||
}; | ||
/** | ||
* TData may not be known at the time of FieldApi construction, so we need to | ||
* use a conditional type to determine if TData is known or not. | ||
* | ||
* If TData is not known, we use the TFormData type to determine the type of | ||
* the field value based on the field name. | ||
*/ | ||
type GetTData<Name, TData, TFormData> = unknown extends TData ? DeepValue<TFormData, Name> : TData; | ||
declare class FieldApi<TData, TFormData> { | ||
type GetTData<TData, TFormData, Opts extends FieldApiOptions<TData, TFormData>> = Opts extends FieldApiOptions<infer _TData, infer _TFormData, infer _TName, infer RealTData> ? RealTData : never; | ||
declare class FieldApi<_TData, TFormData, Opts extends FieldApiOptions<_TData, TFormData> = FieldApiOptions<_TData, TFormData>, TData extends GetTData<_TData, TFormData, Opts> = GetTData<_TData, TFormData, Opts>> { | ||
#private; | ||
uid: number; | ||
form: FormApi<TFormData>; | ||
form: Opts['form']; | ||
name: DeepKeys<TFormData>; | ||
/** | ||
* This is a hack that allows us to use `GetTData` without calling it everywhere | ||
* | ||
* Unfortunately this hack appears to be needed alongside the `TName` hack | ||
* further up in this file. This properly types all of the internal methods, | ||
* while the `TName` hack types the options properly | ||
*/ | ||
_tdata: GetTData<typeof this$1.name, TData, TFormData>; | ||
store: Store<FieldState<typeof this$1._tdata>>; | ||
state: FieldState<typeof this$1._tdata>; | ||
prevState: FieldState<typeof this$1._tdata>; | ||
options: FieldOptions<typeof this$1._tdata, TFormData>; | ||
constructor(opts: FieldApiOptions<TData, TFormData>); | ||
options: Opts; | ||
store: Store<FieldState<TData>>; | ||
state: FieldState<TData>; | ||
prevState: FieldState<TData>; | ||
constructor(opts: Opts & { | ||
form: FormApi<TFormData>; | ||
}); | ||
mount: () => () => void; | ||
update: (opts: FieldApiOptions<typeof this$1._tdata, TFormData>) => void; | ||
getValue: () => typeof this$1._tdata; | ||
setValue: (updater: Updater<typeof this$1._tdata>, options?: { | ||
update: (opts: FieldApiOptions<TData, TFormData>) => void; | ||
getValue: () => TData; | ||
setValue: (updater: Updater<TData>, options?: { | ||
touch?: boolean; | ||
@@ -165,12 +161,12 @@ notify?: boolean; | ||
getInfo: () => Record<DeepKeys<TFormData>, FieldInfo<TFormData>>[DeepKeys<TFormData>]; | ||
pushValue: (value: typeof this$1._tdata extends any[] ? (typeof this$1._tdata)[number] : never) => void; | ||
insertValue: (index: number, value: typeof this$1._tdata extends any[] ? (typeof this$1._tdata)[number] : never) => void; | ||
pushValue: (value: TData extends any[] ? TData[number] : never) => void; | ||
insertValue: (index: number, value: TData extends any[] ? TData[number] : never) => void; | ||
removeValue: (index: number) => void; | ||
swapValues: (aIndex: number, bIndex: number) => void; | ||
getSubField: <TName extends DeepKeys<GetTData<DeepKeys<TFormData>, TData, TFormData>>>(name: TName) => FieldApi<DeepValue<GetTData<DeepKeys<TFormData>, TData, TFormData>, TName>, TFormData>; | ||
validateSync: (value: GetTData<DeepKeys<TFormData>, TData, TFormData> | undefined, cause: ValidationCause) => void; | ||
getSubField: <TName extends DeepKeys<TData>>(name: TName) => FieldApi<DeepValue<TData, TName>, TFormData, FieldApiOptions<DeepValue<TData, TName>, TFormData, unknown extends TFormData ? string : DeepKeys<TFormData>, unknown extends DeepValue<TData, TName> ? DeepValue<TFormData, unknown extends TFormData ? string : DeepKeys<TFormData>> : DeepValue<TData, TName>>, unknown extends DeepValue<TData, TName> ? DeepValue<TFormData, unknown extends TFormData ? string : DeepKeys<TFormData>> : DeepValue<TData, TName>>; | ||
validateSync: (value: TData | undefined, cause: ValidationCause) => void; | ||
cancelValidateAsync: () => void; | ||
validateAsync: (value: GetTData<DeepKeys<TFormData>, TData, TFormData> | undefined, cause: ValidationCause) => Promise<ValidationError[]>; | ||
validate: (cause: ValidationCause, value?: typeof this$1._tdata) => ValidationError[] | Promise<ValidationError[]>; | ||
handleChange: (updater: Updater<typeof this$1._tdata>) => void; | ||
validateAsync: (value: TData | undefined, cause: ValidationCause) => Promise<ValidationError[]>; | ||
validate: (cause: ValidationCause, value?: TData) => ValidationError[] | Promise<ValidationError[]>; | ||
handleChange: (updater: Updater<TData>) => void; | ||
handleBlur: () => void; | ||
@@ -177,0 +173,0 @@ } |
{ | ||
"name": "@tanstack/form-core", | ||
"version": "0.3.2", | ||
"version": "0.3.3", | ||
"description": "Powerful, type-safe, framework agnostic forms.", | ||
@@ -5,0 +5,0 @@ "author": "tannerlinsley", |
@@ -46,6 +46,15 @@ import { type DeepKeys, type DeepValue, type Updater } from './utils' | ||
export type FieldApiOptions<TData, TFormData> = FieldOptions< | ||
TData, | ||
TFormData | ||
> & { | ||
export interface FieldApiOptions< | ||
_TData, | ||
TFormData, | ||
/** | ||
* This allows us to restrict the name to only be a valid field name while | ||
* also assigning it to a generic | ||
*/ | ||
TName = unknown extends TFormData ? string : DeepKeys<TFormData>, | ||
/** | ||
* If TData is unknown, we can use the TName generic to determine the type | ||
*/ | ||
TData = unknown extends _TData ? DeepValue<TFormData, TName> : _TData, | ||
> extends FieldOptions<_TData, TFormData, TName, TData> { | ||
form: FormApi<TFormData> | ||
@@ -69,31 +78,41 @@ } | ||
/** | ||
* TData may not be known at the time of FieldApi construction, so we need to | ||
* use a conditional type to determine if TData is known or not. | ||
* | ||
* If TData is not known, we use the TFormData type to determine the type of | ||
* the field value based on the field name. | ||
*/ | ||
type GetTData<Name, TData, TFormData> = unknown extends TData | ||
? DeepValue<TFormData, Name> | ||
: TData | ||
type GetTData< | ||
TData, | ||
TFormData, | ||
Opts extends FieldApiOptions<TData, TFormData>, | ||
> = Opts extends FieldApiOptions< | ||
infer _TData, | ||
infer _TFormData, | ||
infer _TName, | ||
infer RealTData | ||
> | ||
? RealTData | ||
: never | ||
export class FieldApi<TData, TFormData> { | ||
export class FieldApi< | ||
_TData, | ||
TFormData, | ||
Opts extends FieldApiOptions<_TData, TFormData> = FieldApiOptions< | ||
_TData, | ||
TFormData | ||
>, | ||
TData extends GetTData<_TData, TFormData, Opts> = GetTData< | ||
_TData, | ||
TFormData, | ||
Opts | ||
>, | ||
> { | ||
uid: number | ||
form: FormApi<TFormData> | ||
form: Opts['form'] | ||
name!: DeepKeys<TFormData> | ||
/** | ||
* This is a hack that allows us to use `GetTData` without calling it everywhere | ||
* | ||
* Unfortunately this hack appears to be needed alongside the `TName` hack | ||
* further up in this file. This properly types all of the internal methods, | ||
* while the `TName` hack types the options properly | ||
*/ | ||
_tdata!: GetTData<typeof this.name, TData, TFormData> | ||
store!: Store<FieldState<typeof this._tdata>> | ||
state!: FieldState<typeof this._tdata> | ||
prevState!: FieldState<typeof this._tdata> | ||
options: FieldOptions<typeof this._tdata, TFormData> = {} as any | ||
options: Opts = {} as any | ||
store!: Store<FieldState<TData>> | ||
state!: FieldState<TData> | ||
prevState!: FieldState<TData> | ||
constructor(opts: FieldApiOptions<TData, TFormData>) { | ||
constructor( | ||
opts: Opts & { | ||
form: FormApi<TFormData> | ||
}, | ||
) { | ||
this.form = opts.form | ||
@@ -109,3 +128,3 @@ this.uid = uid++ | ||
this.store = new Store<FieldState<typeof this._tdata>>( | ||
this.store = new Store<FieldState<TData>>( | ||
{ | ||
@@ -144,3 +163,3 @@ value: this.getValue(), | ||
const info = this.getInfo() | ||
info.instances[this.uid] = this | ||
info.instances[this.uid] = this as never | ||
@@ -174,3 +193,3 @@ const unsubscribe = this.form.store.subscribe(() => { | ||
update = (opts: FieldApiOptions<typeof this._tdata, TFormData>) => { | ||
update = (opts: FieldApiOptions<TData, TFormData>) => { | ||
// Default Value | ||
@@ -197,3 +216,3 @@ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
getValue = (): typeof this._tdata => { | ||
getValue = (): TData => { | ||
return this.form.getFieldValue(this.name) | ||
@@ -203,3 +222,3 @@ } | ||
setValue = ( | ||
updater: Updater<typeof this._tdata>, | ||
updater: Updater<TData>, | ||
options?: { touch?: boolean; notify?: boolean }, | ||
@@ -228,13 +247,8 @@ ) => { | ||
pushValue = ( | ||
value: typeof this._tdata extends any[] | ||
? (typeof this._tdata)[number] | ||
: never, | ||
) => this.form.pushFieldValue(this.name, value as any) | ||
pushValue = (value: TData extends any[] ? TData[number] : never) => | ||
this.form.pushFieldValue(this.name, value as any) | ||
insertValue = ( | ||
index: number, | ||
value: typeof this._tdata extends any[] | ||
? (typeof this._tdata)[number] | ||
: never, | ||
value: TData extends any[] ? TData[number] : never, | ||
) => this.form.insertFieldValue(this.name, index, value as any) | ||
@@ -247,4 +261,4 @@ | ||
getSubField = <TName extends DeepKeys<typeof this._tdata>>(name: TName) => | ||
new FieldApi<DeepValue<typeof this._tdata, TName>, TFormData>({ | ||
getSubField = <TName extends DeepKeys<TData>>(name: TName) => | ||
new FieldApi<DeepValue<TData, TName>, TFormData>({ | ||
name: `${this.name}.${name}` as never, | ||
@@ -383,3 +397,3 @@ form: this.form, | ||
cause: ValidationCause, | ||
value?: typeof this._tdata, | ||
value?: TData, | ||
): ValidationError[] | Promise<ValidationError[]> => { | ||
@@ -402,3 +416,3 @@ // If the field is pristine and validatePristine is false, do not validate | ||
handleChange = (updater: Updater<typeof this._tdata>) => { | ||
handleChange = (updater: Updater<TData>) => { | ||
this.setValue(updater, { touch: true }) | ||
@@ -405,0 +419,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4429
342575