import { ReadonlyStore } from '@tanstack/store'; import { DeepKeys, DeepValue, RejectPromiseValidator, UnwrapOneLevelOfArray } from './util-types.js'; import { StandardSchemaV1, StandardSchemaV1Issue, TStandardSchemaValidatorValue } from './standardSchemaValidator.js'; import { FieldInfo, FormApi, FormAsyncValidateOrFn, FormValidateAsyncFn, FormValidateFn, FormValidateOrFn } from './FormApi.js'; import { ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap, ValidationErrorMapSource } from './types.js'; import { Updater } from './utils.js'; /** * @private */ type FieldErrorMapFromValidator, TData extends DeepValue, TOnMount extends undefined | FieldValidateOrFn, TOnChange extends undefined | FieldValidateOrFn, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, TOnBlur extends undefined | FieldValidateOrFn, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, TOnSubmit extends undefined | FieldValidateOrFn, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn> = Partial, ValidationErrorMap>>; /** * @private */ export type FieldValidateFn, TData extends DeepValue = DeepValue> = (props: { value: TData; fieldApi: FieldApi; }) => unknown; /** * @private */ export type FieldValidateOrFn, TData extends DeepValue = DeepValue> = FieldValidateFn | StandardSchemaV1; type StandardBrandedSchemaV1 = T & { __standardSchemaV1: true; }; type UnwrapFormValidateOrFnForInner> = [TValidateOrFn] extends [FormValidateFn] ? ReturnType : [TValidateOrFn] extends [StandardSchemaV1] ? StandardBrandedSchemaV1 : undefined; export type UnwrapFieldValidateOrFn, TFormValidateOrFn extends undefined | FormValidateOrFn> = ([TFormValidateOrFn] extends [StandardSchemaV1] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormValidateOrFnForInner extends infer TFormValidateVal ? TFormValidateVal extends { __standardSchemaV1: true; } ? [DeepValue] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends { fields: any; } ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateFn] ? ReturnType : [TValidateOrFn] extends [StandardSchemaV1] ? StandardSchemaV1Issue[] : undefined); /** * @private */ export type FieldValidateAsyncFn, TData extends DeepValue = DeepValue> = (options: { value: TData; fieldApi: FieldApi; signal: AbortSignal; }) => unknown | Promise; /** * @private */ export type FieldAsyncValidateOrFn, TData extends DeepValue = DeepValue> = FieldValidateAsyncFn | StandardSchemaV1; type UnwrapFormAsyncValidateOrFnForInner> = [TValidateOrFn] extends [FormValidateAsyncFn] ? Awaited> : [TValidateOrFn] extends [StandardSchemaV1] ? StandardBrandedSchemaV1 : undefined; export type UnwrapFieldAsyncValidateOrFn, TFormValidateOrFn extends undefined | FormAsyncValidateOrFn> = ([TFormValidateOrFn] extends [StandardSchemaV1] ? TName extends keyof TStandardOut ? StandardSchemaV1Issue[] : undefined : undefined) | (UnwrapFormAsyncValidateOrFnForInner extends infer TFormValidateVal ? TFormValidateVal extends { __standardSchemaV1: true; } ? [DeepValue] extends [never] ? undefined : StandardSchemaV1Issue[] : TFormValidateVal extends { fields: any; } ? TName extends keyof TFormValidateVal['fields'] ? TFormValidateVal['fields'][TName] : undefined : undefined : never) | ([TValidateOrFn] extends [FieldValidateAsyncFn] ? Awaited> : [TValidateOrFn] extends [StandardSchemaV1] ? StandardSchemaV1Issue[] : undefined); /** * @private */ export type FieldListenerFn, TData extends DeepValue = DeepValue> = (props: { value: TData; fieldApi: FieldApi; }) => void; export interface FieldValidators, TData extends DeepValue, TOnMount extends undefined | FieldValidateOrFn, TOnChange extends undefined | FieldValidateOrFn, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, TOnBlur extends undefined | FieldValidateOrFn, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, TOnSubmit extends undefined | FieldValidateOrFn, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn, TOnDynamic extends undefined | FieldValidateOrFn, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn> { /** * An optional function, that runs on the mount event of input. */ onMount?: RejectPromiseValidator; /** * An optional function, that runs on the change event of input. * * @example z.string().min(1) */ onChange?: RejectPromiseValidator; /** * An optional property similar to `onChange` but async validation * * @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' }) */ onChangeAsync?: TOnChangeAsync; /** * An optional number to represent how long the `onChangeAsync` should wait before running * * If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds */ onChangeAsyncDebounceMs?: number; /** * An optional list of field names that should trigger this field's `onChange` and `onChangeAsync` events when its value changes */ onChangeListenTo?: DeepKeys[]; /** * An optional function, that runs on the blur event of input. * * @example z.string().min(1) */ onBlur?: RejectPromiseValidator; /** * An optional property similar to `onBlur` but async validation. * * @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' }) */ onBlurAsync?: TOnBlurAsync; /** * An optional number to represent how long the `onBlurAsync` should wait before running * * If set to a number larger than 0, will debounce the async validation event by this length of time in milliseconds */ onBlurAsyncDebounceMs?: number; /** * An optional list of field names that should trigger this field's `onBlur` and `onBlurAsync` events when its value changes */ onBlurListenTo?: DeepKeys[]; /** * An optional function, that runs on the submit event of form. * * @example z.string().min(1) */ onSubmit?: RejectPromiseValidator; /** * An optional property similar to `onSubmit` but async validation. * * @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' }) */ onSubmitAsync?: TOnSubmitAsync; onDynamic?: RejectPromiseValidator; onDynamicAsync?: TOnDynamicAsync; onDynamicAsyncDebounceMs?: number; } export interface FieldListeners, TData extends DeepValue = DeepValue> { onChange?: FieldListenerFn; onChangeDebounceMs?: number; onBlur?: FieldListenerFn; onBlurDebounceMs?: number; onMount?: FieldListenerFn; onUnmount?: FieldListenerFn; onSubmit?: FieldListenerFn; } /** * An object type representing the options for a field in a form. */ export interface FieldOptions, TData extends DeepValue, TOnMount extends undefined | FieldValidateOrFn, TOnChange extends undefined | FieldValidateOrFn, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, TOnBlur extends undefined | FieldValidateOrFn, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, TOnSubmit extends undefined | FieldValidateOrFn, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn, TOnDynamic extends undefined | FieldValidateOrFn, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn> { /** * The field name. The type will be `DeepKeys` to ensure your name is a deep key of the parent dataset. */ name: TName; /** * An optional default value for the field. */ defaultValue?: NoInfer; /** * The default time to debounce async validation if there is not a more specific debounce time passed. */ asyncDebounceMs?: number; /** * If `true`, always run async validation, even if there are errors emitted during synchronous validation. */ asyncAlways?: boolean; /** * A list of validators to pass to the field */ validators?: FieldValidators; /** * An optional object with default metadata for the field. */ defaultMeta?: Partial>; /** * A list of listeners which attach to the corresponding events */ listeners?: FieldListeners; /** * Disable the `flat(1)` operation on `field.errors`. This is useful if you want to keep the error structure as is. Not suggested for most use-cases. */ disableErrorFlat?: boolean; } /** * An object type representing the required options for the FieldApi class. */ export interface FieldApiOptions, in out TData extends DeepValue, in out TOnMount extends undefined | FieldValidateOrFn, in out TOnChange extends undefined | FieldValidateOrFn, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, in out TOnBlur extends undefined | FieldValidateOrFn, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, in out TOnSubmit extends undefined | FieldValidateOrFn, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn, in out TOnDynamic extends undefined | FieldValidateOrFn, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn, in out TFormOnMount extends undefined | FormValidateOrFn, in out TFormOnChange extends undefined | FormValidateOrFn, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn, in out TFormOnBlur extends undefined | FormValidateOrFn, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn, in out TFormOnSubmit extends undefined | FormValidateOrFn, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn, in out TFormOnDynamic extends undefined | FormValidateOrFn, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn, in out TFormOnServer extends undefined | FormAsyncValidateOrFn, in out TParentSubmitMeta> extends FieldOptions { form: FormApi; } export type FieldMetaBase, TData extends DeepValue, TOnMount extends undefined | FieldValidateOrFn, TOnChange extends undefined | FieldValidateOrFn, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, TOnBlur extends undefined | FieldValidateOrFn, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, TOnSubmit extends undefined | FieldValidateOrFn, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn, TOnDynamic extends undefined | FieldValidateOrFn, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn, TFormOnMount extends undefined | FormValidateOrFn, TFormOnChange extends undefined | FormValidateOrFn, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn, TFormOnBlur extends undefined | FormValidateOrFn, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn, TFormOnSubmit extends undefined | FormValidateOrFn, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn, TFormOnDynamic extends undefined | FormValidateOrFn, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn> = { /** * A flag indicating whether the field has been touched. */ isTouched: boolean; /** * A flag indicating whether the field has been blurred. */ isBlurred: boolean; /** * A flag that is `true` if the field's value has been modified by the user. Opposite of `isPristine`. */ isDirty: boolean; /** * A map of errors related to the field value. */ errorMap: ValidationErrorMap, UnwrapFieldValidateOrFn, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn, UnwrapFieldAsyncValidateOrFn>; /** * @private allows tracking the source of the errors in the error map */ errorSourceMap: ValidationErrorMapSource; /** * A flag indicating whether the field is currently being validated. */ isValidating: boolean; /** * @private a counter that is incremented every time a structural array * operation (push, insert, remove, swap, move, replace, clear) modifies * the value of an array field. Adapters can subscribe to this to trigger * re-renders for `mode="array"` fields without having to subscribe to the * full field value. */ _arrayVersion: number; }; export type AnyFieldMetaBase = FieldMetaBase; export type FieldMetaDerived, TData extends DeepValue, TOnMount extends undefined | FieldValidateOrFn, TOnChange extends undefined | FieldValidateOrFn, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, TOnBlur extends undefined | FieldValidateOrFn, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, TOnSubmit extends undefined | FieldValidateOrFn, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn, TOnDynamic extends undefined | FieldValidateOrFn, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn, TFormOnMount extends undefined | FormValidateOrFn, TFormOnChange extends undefined | FormValidateOrFn, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn, TFormOnBlur extends undefined | FormValidateOrFn, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn, TFormOnSubmit extends undefined | FormValidateOrFn, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn, TFormOnDynamic extends undefined | FormValidateOrFn, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn> = { /** * An array of errors related to the field value. */ errors: Array> | UnwrapOneLevelOfArray> | UnwrapOneLevelOfArray> | UnwrapOneLevelOfArray> | UnwrapOneLevelOfArray> | UnwrapOneLevelOfArray> | UnwrapOneLevelOfArray> | UnwrapOneLevelOfArray> | UnwrapOneLevelOfArray>>; /** * A flag that is `true` if the field's value has not been modified by the user. Opposite of `isDirty`. */ isPristine: boolean; /** * A boolean indicating if the field is valid. Evaluates `true` if there are no field errors. */ isValid: boolean; /** * A flag indicating whether the field's current value is the default value */ isDefaultValue: boolean; }; export type AnyFieldMetaDerived = FieldMetaDerived; /** * An object type representing the metadata of a field in a form. */ export type FieldMeta, TData extends DeepValue, TOnMount extends undefined | FieldValidateOrFn, TOnChange extends undefined | FieldValidateOrFn, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, TOnBlur extends undefined | FieldValidateOrFn, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, TOnSubmit extends undefined | FieldValidateOrFn, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn, TOnDynamic extends undefined | FieldValidateOrFn, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn, TFormOnMount extends undefined | FormValidateOrFn, TFormOnChange extends undefined | FormValidateOrFn, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn, TFormOnBlur extends undefined | FormValidateOrFn, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn, TFormOnSubmit extends undefined | FormValidateOrFn, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn, TFormOnDynamic extends undefined | FormValidateOrFn, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn> = FieldMetaBase & FieldMetaDerived; export type AnyFieldMeta = FieldMeta; /** * An object type representing the state of a field. */ export type FieldState, TData extends DeepValue, TOnMount extends undefined | FieldValidateOrFn, TOnChange extends undefined | FieldValidateOrFn, TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, TOnBlur extends undefined | FieldValidateOrFn, TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, TOnSubmit extends undefined | FieldValidateOrFn, TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn, TOnDynamic extends undefined | FieldValidateOrFn, TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn, TFormOnMount extends undefined | FormValidateOrFn, TFormOnChange extends undefined | FormValidateOrFn, TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn, TFormOnBlur extends undefined | FormValidateOrFn, TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn, TFormOnSubmit extends undefined | FormValidateOrFn, TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn, TFormOnDynamic extends undefined | FormValidateOrFn, TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn> = { /** * The current value of the field. */ value: TData; /** * The current metadata of the field. */ meta: FieldMeta; }; /** * @public * * A type representing the Field API with all generics set to `any` for convenience. */ export type AnyFieldApi = FieldApi; /** * We cannot use methods and must use arrow functions. Otherwise, our React adapters * will break due to loss of the method when using spread. */ /** * A class representing the API for managing a form field. * * Normally, you will not need to create a new `FieldApi` instance directly. * Instead, you will use a framework hook/function like `useField` or `createField` * to create a new instance for you that uses your framework's reactivity model. * However, if you need to create a new instance manually, you can do so by calling * the `new FieldApi` constructor. */ export declare class FieldApi, in out TData extends DeepValue, in out TOnMount extends undefined | FieldValidateOrFn, in out TOnChange extends undefined | FieldValidateOrFn, in out TOnChangeAsync extends undefined | FieldAsyncValidateOrFn, in out TOnBlur extends undefined | FieldValidateOrFn, in out TOnBlurAsync extends undefined | FieldAsyncValidateOrFn, in out TOnSubmit extends undefined | FieldValidateOrFn, in out TOnSubmitAsync extends undefined | FieldAsyncValidateOrFn, in out TOnDynamic extends undefined | FieldValidateOrFn, in out TOnDynamicAsync extends undefined | FieldAsyncValidateOrFn, in out TFormOnMount extends undefined | FormValidateOrFn, in out TFormOnChange extends undefined | FormValidateOrFn, in out TFormOnChangeAsync extends undefined | FormAsyncValidateOrFn, in out TFormOnBlur extends undefined | FormValidateOrFn, in out TFormOnBlurAsync extends undefined | FormAsyncValidateOrFn, in out TFormOnSubmit extends undefined | FormValidateOrFn, in out TFormOnSubmitAsync extends undefined | FormAsyncValidateOrFn, in out TFormOnDynamic extends undefined | FormValidateOrFn, in out TFormOnDynamicAsync extends undefined | FormAsyncValidateOrFn, in out TFormOnServer extends undefined | FormAsyncValidateOrFn, in out TParentSubmitMeta> { /** * A reference to the form API instance. */ form: FieldApiOptions['form']; /** * The field name. */ name: TName; /** * The field options. */ options: FieldApiOptions; /** * The field state store. */ store: ReadonlyStore>; /** * The current field state. */ get state(): FieldState; timeoutIds: { validations: Record | null>; listeners: Record | null>; formListeners: Record | null>; }; /** * Initializes a new `FieldApi` instance. */ constructor(opts: FieldApiOptions); /** * @private */ runValidator & { fieldApi: AnyFieldApi; }, TType extends 'validate' | 'validateAsync'>(props: { validate: TType extends 'validate' ? FieldValidateOrFn : FieldAsyncValidateOrFn; value: TValue; type: TType; }): unknown; /** * Mounts the field instance to the form. * @returns A function to unmount the field instance. */ mount: () => () => void; /** * Updates the field instance with new options. */ update: (opts: FieldApiOptions) => void; /** * Gets the current field value. * @deprecated Use `field.state.value` instead. */ getValue: () => TData; /** * Sets the field value and run the `change` validator. */ setValue: (updater: Updater, options?: UpdateMetaOptions) => void; getMeta: () => FieldMeta; /** * Sets the field metadata. */ setMeta: (updater: Updater>) => void; /** * Gets the field information object. */ getInfo: () => FieldInfo; /** * Pushes a new value to the field. */ pushValue: (value: TData extends any[] ? TData[number] : never, options?: UpdateMetaOptions) => void; /** * Inserts a value at the specified index, shifting the subsequent values to the right. */ insertValue: (index: number, value: TData extends any[] ? TData[number] : never, options?: UpdateMetaOptions) => void; /** * Replaces a value at the specified index. */ replaceValue: (index: number, value: TData extends any[] ? TData[number] : never, options?: UpdateMetaOptions) => void; /** * Removes a value at the specified index. */ removeValue: (index: number, options?: UpdateMetaOptions) => void; /** * Swaps the values at the specified indices. */ swapValues: (aIndex: number, bIndex: number, options?: UpdateMetaOptions) => void; /** * Moves the value at the first specified index to the second specified index. */ moveValue: (aIndex: number, bIndex: number, options?: UpdateMetaOptions) => void; /** * Clear all values from the array. */ clearValues: (options?: UpdateMetaOptions) => void; /** * @private */ getLinkedFields: (cause: ValidationCause) => AnyFieldApi[]; /** * @private */ validateSync: (cause: ValidationCause, errorFromForm: ValidationErrorMap) => { hasErrored: boolean; }; /** * @private */ validateAsync: (cause: ValidationCause, formValidationResultPromise: Promise>) => Promise; /** * Validates the field value. */ validate: (cause: ValidationCause, opts?: { skipFormValidation?: boolean; }) => ValidationError[] | Promise; /** * Handles the change event. */ handleChange: (updater: Updater) => void; /** * Handles the blur event. */ handleBlur: () => void; /** * Updates the field's errorMap */ setErrorMap: (errorMap: ValidationErrorMap, UnwrapFieldValidateOrFn, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn, UnwrapFieldAsyncValidateOrFn, UnwrapFieldValidateOrFn, UnwrapFieldAsyncValidateOrFn>) => void; /** * Parses the field's value with the given schema and returns * issues (if any). This method does NOT set any internal errors. * @param schema The standard schema to parse this field's value with. */ parseValueWithSchema: (schema: StandardSchemaV1) => StandardSchemaV1Issue[] | undefined; /** * Parses the field's value with the given schema and returns * issues (if any). This method does NOT set any internal errors. * @param schema The standard schema to parse this field's value with. */ parseValueWithSchemaAsync: (schema: StandardSchemaV1) => Promise; private triggerOnBlurListener; /** * @private */ triggerOnChangeListener: () => void; } export {};