import { ValidationLogicFn } from './ValidationLogic.cjs'; import { AnyFieldLikeMeta, AnyFieldLikeMetaBase, FieldErrorMapFromValidator, FieldInfo, FieldLikeAPI, FieldLikeMeta, FieldLikeMetaBase, FieldLikeOptions, FormLikeAPI, ListenerCause, UpdateMetaOptions, ValidationCause, ValidationError, ValidationErrorMap } from './types.cjs'; import { FormApi, FormAsyncValidateOrFn, FormValidateOrFn } from './FormApi.cjs'; import { AnyFieldApi } from './FieldApi.cjs'; import { StandardSchemaV1, TStandardSchemaValidatorValue } from './standardSchemaValidator.cjs'; import { Updater } from './utils.cjs'; import { ReadonlyStore } from '@tanstack/store'; import { DeepKeys, DeepKeysOfType, DeepValue } from './util-types.cjs'; /** * @private */ export type FormGroupValidateFn, TData extends DeepValue = DeepValue> = (props: { value: TData; groupApi: FormGroupApi; }) => unknown; /** * @private */ export type FormGroupValidateOrFn, TData extends DeepValue = DeepValue> = FormGroupValidateFn | StandardSchemaV1; /** * @private */ export type FormGroupValidateAsyncFn, TData extends DeepValue = DeepValue> = (options: { value: TData; groupApi: FormGroupApi; signal: AbortSignal; }) => unknown | Promise; /** * @private */ export type FormGroupAsyncValidateOrFn, TData extends DeepValue = DeepValue> = FormGroupValidateAsyncFn | StandardSchemaV1; /** * @private */ export type FormGroupListenerFn, TData extends DeepValue = DeepValue> = (props: { value: TData; groupApi: FormGroupApi; }) => void; export interface FormGroupValidators, TData extends DeepValue, TOnMount extends undefined | FormGroupValidateOrFn, TOnChange extends undefined | FormGroupValidateOrFn, TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn, TOnBlur extends undefined | FormGroupValidateOrFn, TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn, TOnSubmit extends undefined | FormGroupValidateOrFn, TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn, TOnDynamic extends undefined | FormGroupValidateOrFn, TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn> { /** * An optional function, that runs on the mount event of input. */ onMount?: TOnMount; /** * An optional function, that runs on the change event of input. * * @example z.string().min(1) */ onChange?: TOnChange; /** * 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 */ /** * An optional function, that runs on the blur event of input. * * @example z.string().min(1) */ onBlur?: TOnBlur; /** * 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 */ /** * An optional function, that runs on the submit event of form. * * @example z.string().min(1) */ onSubmit?: TOnSubmit; /** * An optional property similar to `onSubmit` but async validation. * * @example z.string().refine(async (val) => val.length > 3, { message: 'Testing 123' }) */ onSubmitAsync?: TOnSubmitAsync; onDynamic?: TOnDynamic; onDynamicAsync?: TOnDynamicAsync; onDynamicAsyncDebounceMs?: number; } export interface FormGroupListeners, TData extends DeepValue = DeepValue> { onChange?: FormGroupListenerFn; onChangeDebounceMs?: number; onBlur?: FormGroupListenerFn; onBlurDebounceMs?: number; onMount?: FormGroupListenerFn; onUnmount?: FormGroupListenerFn; onSubmit?: FormGroupListenerFn; onGroupSubmit?: FormGroupListenerFn; } interface FormGroupExtraOptions, in out TData extends DeepValue, in out TOnMount extends undefined | FormGroupValidateOrFn, in out TOnChange extends undefined | FormGroupValidateOrFn, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnBlur extends undefined | FormGroupValidateOrFn, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnSubmit extends undefined | FormGroupValidateOrFn, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnDynamic extends undefined | FormGroupValidateOrFn, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn, in out TSubmitMeta, 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 list of validators to pass to the field */ validators?: FormGroupValidators; /** * If true, allows the form to be submitted in an invalid state i.e. canSubmit will remain true regardless of validation errors. Defaults to undefined. */ canSubmitWhenInvalid?: boolean; /** * A list of listeners which attach to the corresponding events */ listeners?: FormGroupListeners; defaultState?: FormGroupState; /** * Optional validation logic strategy to use for this group's own * validators (e.g. `revalidateLogic()`). When omitted, the parent form's * `validationLogic` (or the default) is used. */ validationLogic?: ValidationLogicFn; /** * onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit function props */ onSubmitMeta?: TSubmitMeta; /** * A function to be called when the form is submitted, what should happen once the user submits a valid form returns `any` or a promise `Promise` */ onGroupSubmit?: (props: { value: TData; groupApi: FormGroupApi; meta: TSubmitMeta; }) => any | Promise; /** * Specify an action for scenarios where the user tries to submit an invalid form. */ onGroupSubmitInvalid?: (props: { value: TData; groupApi: FormGroupApi; meta: TSubmitMeta; }) => void; } export interface FormGroupOptions, in out TData extends DeepValue, in out TOnMount extends undefined | FormGroupValidateOrFn, in out TOnChange extends undefined | FormGroupValidateOrFn, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnBlur extends undefined | FormGroupValidateOrFn, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnSubmit extends undefined | FormGroupValidateOrFn, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnDynamic extends undefined | FormGroupValidateOrFn, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn, in out TSubmitMeta, 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 FieldLikeOptions, FormGroupExtraOptions { } export interface FormGroupApiOptions, in out TData extends DeepValue, in out TOnMount extends undefined | FormGroupValidateOrFn, in out TOnChange extends undefined | FormGroupValidateOrFn, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnBlur extends undefined | FormGroupValidateOrFn, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnSubmit extends undefined | FormGroupValidateOrFn, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnDynamic extends undefined | FormGroupValidateOrFn, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn, in out TSubmitMeta, 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 FormGroupOptions { form: FormApi; } export interface FormGroupState { /** * A boolean indicating if the form is currently in the process of being submitted after `handleSubmit` is called. * * Goes back to `false` when submission completes for one of the following reasons: * - the validation step returned errors. * - the `onSubmit` function has completed. * * Note: if you're running async operations in your `onSubmit` function make sure to await them to ensure `isSubmitting` is set to `false` only when the async operation completes. * * This is useful for displaying loading indicators or disabling form inputs during submission. * */ isSubmitting: boolean; /** * A boolean indicating if the `onSubmit` function has completed successfully. * * Goes back to `false` at each new submission attempt. * * Note: you can use isSubmitting to check if the form is currently submitting. */ isSubmitted: boolean; /** * A boolean indicating if the form or any of its fields are currently validating. */ isValidating: boolean; /** * A counter for tracking the number of submission attempts. */ submissionAttempts: number; /** * A boolean indicating if the last submission was successful. */ isSubmitSuccessful: boolean; } /** * @public * * A type representing the FormGroup API with all generics set to `any` for convenience. */ export type AnyFormGroupApi = FormGroupApi; /** * @public * * The `meta` shape exposed on `FormGroupApi.state.meta`. Mirrors * `FieldApi.state.meta` (since `FormGroupMeta extends FieldLikeMeta`) but * additionally surfaces the group's submission lifecycle and aggregated * validity flags. All derivation lives on the parent `FormApi` (in * `formGroupMetaDerived`), keeping per-instance `FormGroupApi.store` as * minimal as `FieldApi.store`. * * Aggregated booleans (`isTouched`, `isBlurred`, `isDirty`, `isPristine`, * `isDefaultValue`) are computed across the group's descendant fields * rather than the group's own field-meta entry. */ export interface FormGroupMeta, in out TData extends DeepValue, in out TOnMount extends undefined | FormGroupValidateOrFn, in out TOnChange extends undefined | FormGroupValidateOrFn, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnBlur extends undefined | FormGroupValidateOrFn, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnSubmit extends undefined | FormGroupValidateOrFn, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnDynamic extends undefined | FormGroupValidateOrFn, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn, 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> extends FieldLikeMeta, FormGroupState { isFieldsValidating: boolean; isFieldsValid: boolean; isGroupValid: boolean; isValid: boolean; canSubmit: boolean; } /** * @public * * `FormGroupMeta` with all generics widened to `any`. */ export type AnyFormGroupMeta = FormGroupMeta; export interface FormGroupStoreState, in out TData extends DeepValue, in out TOnMount extends undefined | FormGroupValidateOrFn, in out TOnChange extends undefined | FormGroupValidateOrFn, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnBlur extends undefined | FormGroupValidateOrFn, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnSubmit extends undefined | FormGroupValidateOrFn, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnDynamic extends undefined | FormGroupValidateOrFn, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn, 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> { /** * The current value of the form group. */ value: TData; /** * The current metadata of the form group, including aggregated validity, * group-level errors, and submission lifecycle. */ meta: FormGroupMeta; } /** * @private * * Builds a default `FormGroupMeta` value, used as a fallback when the * parent form's `formGroupMetaDerived` store has no entry for this group * yet (e.g. between `new FormGroupApi(...)` and `mount()`). */ export declare function getDefaultFormGroupMeta(defaultMeta?: Partial): AnyFormGroupMeta; export declare class FormGroupApi, in out TData extends DeepValue, in out TOnMount extends undefined | FormGroupValidateOrFn, in out TOnChange extends undefined | FormGroupValidateOrFn, in out TOnChangeAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnBlur extends undefined | FormGroupValidateOrFn, in out TOnBlurAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnSubmit extends undefined | FormGroupValidateOrFn, in out TOnSubmitAsync extends undefined | FormGroupAsyncValidateOrFn, in out TOnDynamic extends undefined | FormGroupValidateOrFn, in out TOnDynamicAsync extends undefined | FormGroupAsyncValidateOrFn, in out TSubmitMeta, 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> implements FormLikeAPI, FieldLikeAPI> { /** * A reference to the form API instance. */ form: FormGroupApiOptions['form']; /** * The field name. */ name: TName; /** * The field options. */ options: FormGroupApiOptions; /** * The field state store. */ store: ReadonlyStore>; /** * The current field state. */ get state(): FormGroupStoreState; /** * @private * * Updates this group's submission lifecycle state on the parent form's * `baseStore` (where group state is now persisted), preserving entries * for any other mounted groups. After writing, the form's * `formGroupMetaDerived` re-derives so this group's `state.meta` picks * up the new lifecycle values automatically. */ private setFormGroupState; timeoutIds: { validations: Record | null>; listeners: Record | null>; formListeners: Record | null>; }; /** * @private * * Tracks the set of fully-qualified child field names that this group's * validators last set form-source errors on, keyed by `errorMap` key. * Used to clear stale group-level field errors on subsequent runs without * trampling errors set by the parent form's validators. */ private _lastDistributedFieldNames; private fieldInfo; constructor(opts: FormGroupApiOptions); /** * Updates the field instance with new options. */ update: (opts: FormGroupApiOptions) => void; /** * @private */ runValidator & { groupApi: AnyFormGroupApi; }, TType extends 'validate' | 'validateAsync'>(props: { validate: TType extends 'validate' ? FormGroupValidateOrFn : FormGroupAsyncValidateOrFn; value: TValue; type: TType; }): unknown; mount: () => () => void; /** * Sets the field value and run the `change` validator. */ setValue: (updater: Updater, options?: UpdateMetaOptions) => void; getMeta: () => FormGroupMeta; /** * Sets the field metadata. */ setMeta: (updater: Updater>) => void; /** * Gets the field information object. */ getInfo: () => FieldInfo; /** * @private */ getRelatedFields: () => AnyFieldApi[]; /** * @private */ getRelatedFieldMetasDerived: () => (FieldLikeMetaBase & import('./types.cjs').FieldLikeMetaDerived & { name: string; })[]; /** * @private * * Builds a fully-qualified field name from a path that is relative to this * group, supporting both dot (`name`, `nested.value`) and bracket * (`[0].name`) notation. */ private buildChildFieldName; /** * @private * * Distributes a `{ fields: { ... } }` payload returned by one of this * group's own validators onto the corresponding child fields. Tracks * which fields have been touched so subsequent runs can clear stale * errors without trampling errors set by the parent form's validators. */ private distributeFieldErrors; /** * @private */ validateSync: (cause: ValidationCause, errorFromForm: ValidationErrorMap, opts?: { skipRelatedFieldValidation?: boolean; }) => { hasErrored: boolean; }; /** * @private */ validateAsync: (cause: ValidationCause, formValidationResultPromise: Promise>, opts?: { skipRelatedFieldValidation?: boolean; }) => Promise; /** * Validates all fields according to the FIELD level validators. * This will ignore FORM level validators, use form.validate({ValidationCause}) for a complete validation */ validateAllFields: (cause: ValidationCause) => Promise; validateArrayFieldsStartingFrom: >(field: TField, index: number, cause: ValidationCause) => Promise; validateField: >(field: TField, cause: ValidationCause) => any[] | Promise; getFieldValue: >(field: TField) => DeepValue; getFieldMeta: >(field: TField) => AnyFieldLikeMeta | undefined; setFieldMeta: >(field: TField, updater: Updater) => void; setFieldValue: >(field: TField, value: any) => void; deleteField: >(field: TField) => void; pushFieldValue: >(field: TField, value: any) => void; insertFieldValue: >(field: TField, index: number, value: any) => Promise; replaceFieldValue: >(field: TField, index: number, value: any) => Promise; swapFieldValues: >(field: TField, index1: number, index2: number) => void; moveFieldValues: >(field: TField, fromIndex: number, toIndex: number) => void; clearFieldValues: >(field: TField) => void; resetField: >(field: TField) => void; removeFieldValue: >(field: TField, index: number) => Promise; areRelatedFieldsValid: () => boolean; /** * Validates the form group and all related children. */ validate: (cause: ValidationCause, opts?: { skipFormValidation?: boolean; skipRelatedFieldValidation?: boolean; }) => ValidationError[] | Promise; /** * @private */ triggerOnChangeListener: () => void; /** * @private */ triggerOnSubmitListener: () => void; handleSubmit(): Promise; handleSubmit(submitMeta: TSubmitMeta): Promise; /** * Handles the form submission, performs validation, and calls the appropriate onSubmit or onSubmitInvalid callbacks. */ _handleSubmit: (submitMeta?: TSubmitMeta) => Promise; } export {};