import * as v from "valibot"; import { JSX } from "solid-js"; //#region ../../packages/core/dist/index.solid.d.ts //#region src/types/utils/utils.d.ts /** * Checks if a type is `any`. */ type IsAny = 0 extends 1 & T ? true : false; /** * Checks if a type is `never`. */ type IsNever = [T] extends [never] ? true : false; /** * Constructs a type that is maybe a promise. */ type MaybePromise = T | Promise; /** * Makes all properties deeply optional. */ type DeepPartial = TValue extends Record | readonly unknown[] ? { [TKey in keyof TValue]?: DeepPartial | undefined } : TValue | undefined; /** * Makes all value properties optional. * * Hint: For dynamic arrays, only plain objects and nested arrays have their * values made optional. Primitives and class instances are kept as-is to avoid * types like `(string | undefined)[]`. */ type PartialValues = TValue extends readonly (infer TItem)[] ? number extends TValue["length"] ? (TItem extends Record | readonly unknown[] ? { [TKey in keyof TItem]: PartialValues } : TItem)[] : { [TKey in keyof TValue]: PartialValues } : TValue extends Record ? { [TKey in keyof TValue]: PartialValues } : TValue | undefined; //#endregion //#region src/types/path/path.d.ts /** * Path key type. */ type PathKey = string | number; /** * Path type. */ type Path = readonly PathKey[]; /** * Required path type. */ type RequiredPath = readonly [PathKey, ...Path]; /** * Extracts the exact keys of a tuple, array or object. Tuples return their * literal numeric indices, dynamic arrays return `number`, objects return * their `keyof` keys, and any other input returns `never`. */ type ExactKeysOf = IsAny extends true ? never : TValue extends readonly unknown[] ? number extends TValue["length"] ? number : { [TKey in keyof TValue]: TKey extends `${infer TIndex extends number}` ? TIndex : never }[number] : TValue extends Record ? keyof TValue & PathKey : never; /** * Returns the flat object of all indexable properties of `TValue`. For object * unions, properties from every member are merged so that any single property * is accessible. For primitives and other non-indexable types, the result is * `{}`. * * Hint: This is necessary to make properties accessible across union members. * By default, properties that do not exist in all union options are not * accessible and result in "any" when accessed. */ type PropertiesOf = { [TKey in ExactKeysOf]: TValue extends Record ? TItem : never }; /** * Lazily evaluates only the first valid path segment based on the given value. */ type LazyPath = TPathToCheck extends readonly [] ? TValidPath : TPathToCheck extends readonly [infer TFirstKey extends ExactKeysOf, ...infer TPathRest extends Path] ? LazyPath[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever> extends false ? readonly [...TValidPath, ExactKeysOf] : TValidPath; /** * Returns the path if valid, otherwise the first possible valid path based on * the given value. */ type ValidPath = TPath extends LazyPath, TPath> ? TPath : LazyPath, TPath>; /** * Detects whether the consuming project is configured with * `exactOptionalPropertyTypes: true`. * * Hint: If `false` the built-in `Required` strips `| undefined` from * optional properties, so `Required<{ key?: undefined }>['key']` collapses * to `never` — under strict mode the same expression yields `undefined`. */ type IsExactOptionalProps = Required<{ key?: undefined; }>["key"] extends never ? false : true; /** * Like the built-in `Required`, but preserves `| undefined` in two * places where `Required` strips it: * * 1. Optional property values under `exactOptionalPropertyTypes: false` * — without this, input typings for `v.optional`/`v.nullish` schemas * narrow incorrectly (issue #15). * 2. Array/tuple element types — e.g. `(string | undefined)[]` stays * `(string | undefined)[]` instead of becoming `string[]`. Arrays * fall through unchanged because they only have a numeric index * signature and don't structurally extend `Record` (which requires string keys). */ type ExactRequired = TValue extends Record ? IsExactOptionalProps extends true ? Required : { [TKey in keyof Required]: TValue[TKey] } : TValue; /** * Extracts the value type at the given path. */ type PathValue = TPath extends readonly [infer TKey, ...infer TRest extends Path] ? TKey extends ExactKeysOf> ? PathValue>[TKey], TRest> : unknown : TValue; /** * Checks whether a value is a dynamic array or contains one anywhere in its * shape. A fixed-length tuple is not itself a dynamic array, but it counts when * it contains one, so paths can still navigate through tuples to reach nested * arrays. * * Hint: The inner conditionals (`TValue extends readonly unknown[]` and * `TValue extends Record`) distribute over union members, * so the inner expression returns the union of each member's result (e.g. * `true | false` when some members contain arrays and others don't). * Downstream code uses `IsOrHasArray extends true`, but * `boolean extends true` is `false` — so we collapse the result via * `true extends ...`, which is `true` whenever at least one union member * contributed `true`. */ type IsOrHasArray = true extends (IsAny extends true ? false : TValue extends readonly unknown[] ? number extends TValue["length"] ? true : IsOrHasArray : TValue extends Record ? { [TKey in keyof TValue]: IsOrHasArray }[keyof TValue] : false) ? true : false; /** * Extracts the exact keys of a tuple, array or object that contain arrays. */ type ExactKeysOfArrayPath = IsAny extends true ? never : TValue extends readonly (infer TItem)[] ? number extends TValue["length"] ? IsOrHasArray extends true ? number : never : { [TKey in keyof TValue]: TKey extends `${infer TIndex extends number}` ? IsOrHasArray> extends true ? TIndex : never : never }[number] : TValue extends Record ? { [TKey in keyof TValue]: IsOrHasArray> extends true ? TKey : never }[keyof TValue] & PathKey : never; /** * Returns the flat object of indexable properties of `TValue` whose values * are or contain arrays. Mirrors `PropertiesOf` but keyed by * `ExactKeysOfArrayPath` so the lookup is provably valid for array-path * navigation in `LazyArrayPath`. */ type PropertiesOfArrayPath = { [TKey in ExactKeysOfArrayPath]: TValue extends Record ? TItem : never }; /** * Lazily evaluates only the first valid array path segment based on the given value. */ type LazyArrayPath = TPathToCheck extends readonly [] ? TValue extends readonly unknown[] ? number extends TValue["length"] ? TValidPath : IsNever> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath] : never : readonly [...TValidPath, ExactKeysOfArrayPath] : TPathToCheck extends readonly [infer TFirstKey extends ExactKeysOfArrayPath, ...infer TPathRest extends Path] ? LazyArrayPath[TFirstKey]>, TPathRest, readonly [...TValidPath, TFirstKey]> : IsNever> extends false ? readonly [...TValidPath, ExactKeysOfArrayPath] : never; /** * Returns the path if valid, otherwise the first possible valid array path * based on the given value. */ type ValidArrayPath = TPath extends LazyArrayPath, TPath> ? TPath : LazyArrayPath, TPath>; /** * Recursive helper for `DirtyPath` that prepends `TKey` to each deeper path, * or falls through to `never` when the child is not an object. */ type DeepDirtyPath = TChild extends Record ? readonly [TKey$1, ...DirtyPath] : never; /** * Returns the union of all `RequiredPath`s that `getDirtyPaths` can emit * for a given input type. Object fields contribute their own path and the * paths of their descendants; arrays and tuples are atomic and contribute * only their own path, because dirty arrays are returned as complete units. * * Narrowing is exact for the first 5 levels of nesting; deeper paths fall * back to `RequiredPath` to keep the result a complete superset of any * path the runtime can address. * * Hint: Arrays and tuples are atomic because they don't structurally * extend `Record` and so fall through to `never` * via `DeepDirtyPath` — no explicit array check is needed. `TDepth` is * a tuple-length counter capped at 5 to bound TypeScript instantiation * cost. */ type DirtyPath = TDepth["length"] extends 5 ? RequiredPath : TValue extends Record ? { [TKey in ExactKeysOf]: readonly [TKey] | DeepDirtyPath[TKey]>, TKey, TDepth> }[ExactKeysOf] : never; /** * Recursive helper for `FieldPath` that prepends `TKey` to each deeper field * path, or falls through to `never` when the child is a leaf value. */ type DeepFieldPath = TChild extends readonly unknown[] | Record ? readonly [TKey$1, ...FieldPath] : never; /** * Returns the union of all `RequiredPath`s that address a field within the * given input type. Object and array fields contribute their own path and the * paths of their descendants; unlike `DirtyPath`, arrays are recursed into so * that fields at any depth, including array items, can be addressed. Leaf * values contribute only their own path (emitted by their parent). * * Narrowing is exact for the first 5 levels of nesting; deeper paths fall * back to `RequiredPath` to keep the result a complete superset of any path * the runtime can address. `TDepth` is a tuple-length counter capped at 5 to * bound TypeScript instantiation cost. */ type FieldPath = TDepth["length"] extends 5 ? RequiredPath : TValue extends readonly unknown[] | Record ? { [TKey in ExactKeysOf]: readonly [TKey] | DeepFieldPath[TKey]>, TKey, TDepth> }[ExactKeysOf] : never; //#endregion //#region src/types/schema/schema.d.ts /** * Schema type. */ type Schema = v.GenericSchema | v.GenericSchemaAsync; /** * Form schema type. * * Forms must have an object root, so this is constrained structurally to a * schema with an object output (sync or async) rather than to specific Valibot * schema types. Staying decoupled from concrete Valibot types lets this later * move to Standard Schema (e.g. to also support Zod or ArkType). Use * {@link Schema} for nested field schemas. */ type FormSchema = v.GenericSchema> | v.GenericSchemaAsync>; //#endregion //#region src/types/signal/signal.d.ts /** * Signal interface. */ interface Signal { /** * The value of the signal. */ value: T; } /** * Batch interface. */ //#endregion //#region src/types/field/field.d.ts /** * Field element type. */ type FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement; /** * Internal base store interface. */ interface InternalBaseStore { /** * The kind of field store. */ kind: "array" | "object" | "value"; /** * The name of the field. */ name: string; /** * The path to the field. */ path: Path; /** * The schema of the field. */ schema: Schema; /** * Whether the schema is wrapped in a nullish schema. * * Hint: This indicates whether a missing input should be represented as the * nullish value (`null`/`undefined`) instead of a present empty fallback * (`true` for arrays and objects, or the empty input for values). It keeps * resetting consistent with the initial state. */ isNullish: boolean; /** * The initial elements of the field. * * Hint: This may look unused, but do not remove it. `copyItemState` and * `swapItemState` move the `elements` reference between field stores when * array items are inserted, moved, removed or swapped, and `reset` restores * each field's original element via `elements = initialElements`. Without it, * focus and file reset target the wrong element after a reorder followed by a * reset. */ initialElements: FieldElement[]; /** * The elements of the field. */ elements: FieldElement[]; /** * The errors of the field. */ errors: Signal<[string, ...string[]] | null>; /** * The touched state of the field. */ isTouched: Signal; /** * The edited state of the field. * * Hint: Unlike `isTouched`, which is also set when a field is focused, this * is only set when the field's value is changed. Unlike `isDirty`, it stays * `true` even if the value is changed back to its initial value. It is only * reset when the field is reset. */ isEdited: Signal; /** * The dirty state of the field. */ isDirty: Signal; } /** * Internal array store interface. */ interface InternalArrayStore extends InternalBaseStore { /** * The kind of field store. */ kind: "array"; /** * The children of the array field. */ children: InternalFieldStore[]; /** * The initial input of the array field. * * Hint: The initial input is used for resetting and may only be changed * during this process. It does not move when a field is moved. */ initialInput: Signal; /** * The start input of the array field. * * Hint: The start input is used to determine whether the field is dirty * and moves with it. */ startInput: Signal; /** * The input of the array field. * * Hint: The input indicates whether it is `null`, `undefined`, or found in * the children. */ input: Signal; /** * The initial items of the array field. * * Hint: The initial items are used for resetting and may only be changed * during this process. It does not move when a field is moved. */ initialItems: Signal; /** * The start items of the array field. * * Hint: The start items are used to determine whether the field is dirty * and moves with it. */ startItems: Signal; /** * The items of the array field. */ items: Signal; } /** * Internal object store interface. */ interface InternalObjectStore extends InternalBaseStore { /** * The kind of field store. */ kind: "object"; /** * The children of the object field. */ children: Record; /** * The initial input of the object field. * * Hint: The initial input is used for resetting and may only be changed * during this process. It does not move when a field is moved. */ initialInput: Signal; /** * The start input of the object field. * * Hint: The start input is used to determine whether the field is dirty * and moves with it. */ startInput: Signal; /** * The input of the object field. * * Hint: The input indicates whether it is `null`, `undefined`, or found in * the children. */ input: Signal; } /** * Internal value store interface. */ interface InternalValueStore extends InternalBaseStore { /** * The kind of field store. */ kind: "value"; /** * The initial input of the value field. * * Hint: The initial input is used for resetting and may only be changed * during this process. It does not move when a field is moved. */ initialInput: Signal; /** * The start input of the value field. * * Hint: The start input is used to determine whether the field is dirty * and moves with it. */ startInput: Signal; /** * The input of the value field. */ input: Signal; } /** * Internal field store type. */ type InternalFieldStore = InternalArrayStore | InternalObjectStore | InternalValueStore; //#endregion //#region src/values.d.ts /** * Internal symbol constant. */ declare const INTERNAL: "~internal"; //#endregion //#region src/types/form/form.d.ts /** * Validation mode type. */ type ValidationMode = "initial" | "touch" | "input" | "change" | "blur" | "submit"; /** * Empty input interface. * * Defines the value a required field of a given type starts at when no initial * input is provided. Optional and nullable fields are not affected, as they * accept `undefined`. Only required fields whose input is `undefined` fall back * to these values. */ interface EmptyInput { /** * The empty input of a string field. Defaults to an empty string so that an * untouched field matches the DOM and validates with its own message instead * of a type mismatch. Set to `undefined` to opt out. */ readonly string?: string | undefined; /** * The empty input of a number field. Defaults to `undefined`. */ readonly number?: number | undefined; /** * The empty input of a boolean field. Defaults to `undefined`. */ readonly boolean?: boolean | undefined; /** * The empty input of a date field. Defaults to `undefined`. */ readonly date?: Date | undefined; } /** * Form config interface. */ interface FormConfig { /** * The schema of the form. */ readonly schema: TSchema; /** * The initial input of the form. */ readonly initialInput?: DeepPartial> | undefined; /** * The empty input of the form, keyed by field type. Merged on top of the * defaults, so `{ string: '' }` stays in effect unless overridden. */ readonly emptyInput?: EmptyInput | undefined; /** * The validation mode of the form. */ readonly validate?: ValidationMode | undefined; /** * The revalidation mode of the form. */ readonly revalidate?: Exclude | undefined; } /** * Internal form store interface. */ interface InternalFormStore extends InternalObjectStore { /** * The element of the form. */ element?: HTMLFormElement | undefined; /** * The number of active validators. */ validators: number; /** * The resolved empty input of the form, keyed by field type. */ emptyInput: EmptyInput; /** * The validation mode of the form. */ validate: ValidationMode; /** * The revalidation mode of the form. */ revalidate: Exclude; /** * The parse function of the form. */ parse: (input: unknown) => Promise>; /** * The submitting state of the form. */ isSubmitting: Signal; /** * The submitted state of the form. */ isSubmitted: Signal; /** * The validating state of the form. */ isValidating: Signal; } /** * Base form store interface. */ interface BaseFormStore { /** * The internal form store. * * @internal */ readonly [INTERNAL]: InternalFormStore; } /** * Submit handler type. */ type SubmitHandler = (output: v.InferOutput) => MaybePromise; /** * Submit event handler type. */ type SubmitEventHandler = (output: v.InferOutput, event: SubmitEvent) => MaybePromise; //#endregion //#region src/array/copyItemState/copyItemState.d.ts /** * Copies the deeply nested state (signal values) from one field store to * another. This includes the `elements`, `errors`, `startInput`, `input`, * `isTouched`, `isEdited`, `isDirty`, and for arrays `startItems` and `items` * properties. Recursively walks through the field stores and copies all signal * values. * * @param internalFormStore The form store providing the empty input config. * @param fromInternalFieldStore The source field store to copy from. * @param toInternalFieldStore The destination field store to copy to. */ //#endregion //#region ../../packages/methods/dist/index.solid.d.ts //#region src/focus/focus.d.ts /** * Focus field config interface. */ interface FocusFieldConfig { /** * The path to the field to focus. */ readonly path: ValidPath, TFieldPath>; } /** * Focuses the first focusable input element of a field. This is useful for * programmatically setting focus to a specific field, such as after * validation errors or user interactions. * * @param form The form store containing the field. * @param config The focus field configuration. */ declare function focus(form: BaseFormStore, config: FocusFieldConfig): void; //#endregion //#region src/getDeepErrorEntries/getDeepErrorEntries.d.ts /** * Deep error entry interface. */ interface DeepErrorEntry { /** * The path to the field with errors, or an empty path for form-level errors. */ readonly path: unknown extends TValue ? Path : readonly [] | FieldPath; /** * The error messages of the field. */ readonly errors: [string, ...string[]]; } /** * Get form deep error entries config interface. */ interface GetFormDeepErrorEntriesConfig { /** * The path to a field. Leave undefined to get the entries of the entire form. */ readonly path?: undefined; } /** * Get field deep error entries config interface. */ interface GetFieldDeepErrorEntriesConfig { /** * The path to the field to retrieve the entries from. */ readonly path: ValidPath, TFieldPath>; } /** * Retrieves the errors of a specific field or the entire form as a list of * entries, each pairing the path to a field with its error messages. This is * useful for building custom error summaries that link each message back to * its field. Form-level errors are included with an empty path. * * @param form The form store to retrieve error entries from. * * @returns A list of path and error message entries. */ declare function getDeepErrorEntries(form: BaseFormStore): DeepErrorEntry>[]; /** * Retrieves the errors of a specific field or the entire form as a list of * entries, each pairing the path to a field with its error messages. This is * useful for building custom error summaries that link each message back to * its field. Form-level errors are included with an empty path. * * @param form The form store to retrieve error entries from. * @param config The get deep error entries configuration. * * @returns A list of path and error message entries. */ declare function getDeepErrorEntries(form: BaseFormStore, config: TFieldPath extends RequiredPath ? GetFieldDeepErrorEntriesConfig : GetFormDeepErrorEntriesConfig): DeepErrorEntry>[]; //#endregion //#region src/getDeepErrors/getDeepErrors.d.ts /** * Get form deep errors config interface. */ interface GetFormDeepErrorsConfig { /** * The path to a field. Leave undefined to get the errors of the entire form. */ readonly path?: undefined; } /** * Get field deep errors config interface. */ interface GetFieldDeepErrorsConfig { /** * The path to the field to retrieve the errors from. */ readonly path: ValidPath, TFieldPath>; } /** * Retrieves all error messages of a specific field or the entire form by * walking through the field store and all its descendants. This is useful for * displaying a summary of all validation errors within a section or the whole * form. Form-level errors are included. * * @param form The form store to retrieve errors from. * * @returns A non-empty array of error messages, or null if no errors exist. */ declare function getDeepErrors(form: BaseFormStore): [string, ...string[]] | null; /** * Retrieves all error messages of a specific field or the entire form by * walking through the field store and all its descendants. This is useful for * displaying a summary of all validation errors within a section or the whole * form. Form-level errors are included. * * @param form The form store to retrieve errors from. * @param config The get deep errors configuration. * * @returns A non-empty array of error messages, or null if no errors exist. */ declare function getDeepErrors(form: BaseFormStore, config: TFieldPath extends RequiredPath ? GetFieldDeepErrorsConfig : GetFormDeepErrorsConfig): [string, ...string[]] | null; //#endregion //#region src/getDirtyInput/getDirtyInput.d.ts /** * Get form dirty input config interface. */ interface GetFormDirtyInputConfig { /** * The path to a field. Leave undefined to get the dirty input of the entire * form. */ readonly path?: undefined; } /** * Get field dirty input config interface. */ interface GetFieldDirtyInputConfig { /** * The path to the field to retrieve the dirty input from. */ readonly path: ValidPath, TFieldPath>; } /** * Retrieves only the dirty input values of a specific field or the entire * form. Arrays are treated as atomic and returned in full if any item is * dirty, while object keys without a dirty descendant are omitted. Returns * `undefined` if no field in the inspected subtree is dirty. * * @param form The form store to retrieve dirty input from. * * @returns The dirty input of the form or specified field, or `undefined`. */ declare function getDirtyInput(form: BaseFormStore): DeepPartial> | undefined; /** * Retrieves only the dirty input values of a specific field or the entire * form. Arrays are treated as atomic and returned in full if any item is * dirty, while object keys without a dirty descendant are omitted. Returns * `undefined` if no field in the inspected subtree is dirty. * * @param form The form store to retrieve dirty input from. * @param config The get dirty input configuration. * * @returns The dirty input of the form or specified field, or `undefined`. */ declare function getDirtyInput(form: BaseFormStore, config: TFieldPath extends RequiredPath ? GetFieldDirtyInputConfig : GetFormDirtyInputConfig): DeepPartial, TFieldPath> : v.InferInput> | undefined; //#endregion //#region src/getDirtyPaths/getDirtyPaths.d.ts /** * Get form dirty paths config interface. */ interface GetFormDirtyPathsConfig { /** * The path to a field. Leave undefined to inspect the entire form. */ readonly path?: undefined; } /** * Get field dirty paths config interface. */ interface GetFieldDirtyPathsConfig { /** * The path to the field to inspect. */ readonly path: ValidPath, TFieldPath>; } /** * Returns a list of paths to the dirty fields of a specific field or the * entire form. Arrays are treated as atomic and contribute only their own * path if any item is dirty, while object branches are recursed into. Returns * an empty list if no field in the inspected subtree is dirty. * * @param form The form store to inspect. * * @returns The list of paths to the dirty fields. */ declare function getDirtyPaths(form: BaseFormStore): DirtyPath>[]; /** * Returns a list of paths to the dirty fields of a specific field or the * entire form. Arrays are treated as atomic and contribute only their own * path if any item is dirty, while object branches are recursed into. Returns * an empty list if no field in the inspected subtree is dirty. * * @param form The form store to inspect. * @param config The get dirty paths configuration. * * @returns The list of paths to the dirty fields. */ declare function getDirtyPaths(form: BaseFormStore, config: TFieldPath extends RequiredPath ? GetFieldDirtyPathsConfig : GetFormDirtyPathsConfig): DirtyPath>[]; //#endregion //#region src/getErrors/getErrors.d.ts /** * Get form errors config interface. */ interface GetFormErrorsConfig { /** * The path to a field. Leave undefined to get form-level errors. */ readonly path?: undefined; } /** * Get field errors config interface. */ interface GetFieldErrorsConfig { /** * The path to the field to retrieve errors from. */ readonly path: ValidPath, TFieldPath>; } /** * Retrieves error messages from the form. When called without a config, * returns form-level errors. When called with a path, returns errors for * that specific field. * * @param form The form store to retrieve errors from. * * @returns A non-empty array of error messages, or null if no errors exist. */ declare function getErrors(form: BaseFormStore): [string, ...string[]] | null; /** * Retrieves error messages from the form. When called without a config, * returns form-level errors. When called with a path, returns errors for * that specific field. * * @param form The form store to retrieve errors from. * @param config The get errors configuration. * * @returns A non-empty array of error messages, or null if no errors exist. */ declare function getErrors(form: BaseFormStore, config: TFieldPath extends RequiredPath ? GetFieldErrorsConfig : GetFormErrorsConfig): [string, ...string[]] | null; //#endregion //#region src/getInput/getInput.d.ts /** * Get form input config interface. */ interface GetFormInputConfig { /** * The path to a field. Leave undefined to get the entire form input. */ readonly path?: undefined; } /** * Get field input config interface. */ interface GetFieldInputConfig { /** * The path to the field to retrieve input from. */ readonly path: ValidPath, TFieldPath>; } /** * Retrieves the current input value of a specific field or the entire form. * Returns a partial object as not all fields may have been set. * * @param form The form store to retrieve input from. * * @returns The partial input values of the form or the specified field. */ declare function getInput(form: BaseFormStore): PartialValues>; /** * Retrieves the current input value of a specific field or the entire form. * Returns a partial object as not all fields may have been set. * * @param form The form store to retrieve input from. * @param config The get input configuration. * * @returns The partial input values of the form or the specified field. */ declare function getInput(form: BaseFormStore, config: TFieldPath extends RequiredPath ? GetFieldInputConfig : GetFormInputConfig): PartialValues, TFieldPath> : v.InferInput>; //#endregion //#region src/handleSubmit/handleSubmit.d.ts /** * Creates a submit event handler for the form that validates the form input, * and calls the provided handler if validation succeeds. This is designed to * be used with the form's onsubmit event. * * @param form The form store to handle submission for. * @param handler The submit handler function called with validated output if validation succeeds. * * @returns A submit event handler function to attach to the form element. */ declare function handleSubmit(form: BaseFormStore, handler: SubmitHandler): () => Promise; /** * Creates a submit event handler for the form that prevents default browser * submission, validates the form input, and calls the provided handler if * validation succeeds. This is designed to be used with the form's onsubmit event. * * @param form The form store to handle submission for. * @param handler The submit handler function called with validated output if validation succeeds. * * @returns A submit event handler function to attach to the form element. */ declare function handleSubmit(form: BaseFormStore, handler: SubmitEventHandler): (event: SubmitEvent) => Promise; //#endregion //#region src/insert/insert.d.ts /** * Insert array field config interface. */ interface InsertConfig { /** * The path to the field array to insert into. */ readonly path: ValidArrayPath, TFieldArrayPath>; /** * The index to insert the new item at. If undefined, appends to the end. */ readonly at?: number | undefined; /** * The partial initial input value for the new item. */ readonly initialInput?: DeepPartial, [...TFieldArrayPath, number]>> | undefined; } /** * Inserts a new item into a field array at the specified index. All items at * or after the insertion point are shifted up by one index. * * @param form The form store containing the field array. * @param config The insert configuration specifying the path, index, and initial value. */ declare function insert(form: BaseFormStore, config: InsertConfig): void; //#endregion //#region src/isDirty/isDirty.d.ts /** * Is form dirty config interface. */ interface IsFormDirtyConfig { /** * The path to a field. Leave undefined to check the entire form. */ readonly path?: undefined; } /** * Is field dirty config interface. */ interface IsFieldDirtyConfig { /** * The path to the field to check for dirtiness. */ readonly path: ValidPath, TFieldPath>; } /** * Checks whether a specific field or the entire form is dirty by walking * through the field store and all its descendants. A field is dirty when its * input differs from its initial value. * * @param form The form store to check for dirtiness. * * @returns Whether the field or form is dirty. */ declare function isDirty(form: BaseFormStore): boolean; /** * Checks whether a specific field or the entire form is dirty by walking * through the field store and all its descendants. A field is dirty when its * input differs from its initial value. * * @param form The form store to check for dirtiness. * @param config The is dirty configuration. * * @returns Whether the field or form is dirty. */ declare function isDirty(form: BaseFormStore, config: TFieldPath extends RequiredPath ? IsFieldDirtyConfig : IsFormDirtyConfig): boolean; //#endregion //#region src/isEdited/isEdited.d.ts /** * Is form edited config interface. */ interface IsFormEditedConfig { /** * The path to a field. Leave undefined to check the entire form. */ readonly path?: undefined; } /** * Is field edited config interface. */ interface IsFieldEditedConfig { /** * The path to the field to check for being edited. */ readonly path: ValidPath, TFieldPath>; } /** * Checks whether a specific field or the entire form is edited by walking * through the field store and all its descendants. A field is edited once its * value has been changed by the user. * * @param form The form store to check for being edited. * * @returns Whether the field or form is edited. */ declare function isEdited(form: BaseFormStore): boolean; /** * Checks whether a specific field or the entire form is edited by walking * through the field store and all its descendants. A field is edited once its * value has been changed by the user. * * @param form The form store to check for being edited. * @param config The is edited configuration. * * @returns Whether the field or form is edited. */ declare function isEdited(form: BaseFormStore, config: TFieldPath extends RequiredPath ? IsFieldEditedConfig : IsFormEditedConfig): boolean; //#endregion //#region src/isTouched/isTouched.d.ts /** * Is form touched config interface. */ interface IsFormTouchedConfig { /** * The path to a field. Leave undefined to check the entire form. */ readonly path?: undefined; } /** * Is field touched config interface. */ interface IsFieldTouchedConfig { /** * The path to the field to check for being touched. */ readonly path: ValidPath, TFieldPath>; } /** * Checks whether a specific field or the entire form is touched by walking * through the field store and all its descendants. A field is touched once it * has received and lost focus. * * @param form The form store to check for being touched. * * @returns Whether the field or form is touched. */ declare function isTouched(form: BaseFormStore): boolean; /** * Checks whether a specific field or the entire form is touched by walking * through the field store and all its descendants. A field is touched once it * has received and lost focus. * * @param form The form store to check for being touched. * @param config The is touched configuration. * * @returns Whether the field or form is touched. */ declare function isTouched(form: BaseFormStore, config: TFieldPath extends RequiredPath ? IsFieldTouchedConfig : IsFormTouchedConfig): boolean; //#endregion //#region src/isValid/isValid.d.ts /** * Is form valid config interface. */ interface IsFormValidConfig { /** * The path to a field. Leave undefined to check the entire form. */ readonly path?: undefined; } /** * Is field valid config interface. */ interface IsFieldValidConfig { /** * The path to the field to check for validity. */ readonly path: ValidPath, TFieldPath>; } /** * Checks whether a specific field or the entire form is valid by walking * through the field store and all its descendants. A field is valid when * neither it nor any of its descendants contains an error. Form-level errors * are included. * * @param form The form store to check for validity. * * @returns Whether the field or form is valid. */ declare function isValid(form: BaseFormStore): boolean; /** * Checks whether a specific field or the entire form is valid by walking * through the field store and all its descendants. A field is valid when * neither it nor any of its descendants contains an error. Form-level errors * are included. * * @param form The form store to check for validity. * @param config The is valid configuration. * * @returns Whether the field or form is valid. */ declare function isValid(form: BaseFormStore, config: TFieldPath extends RequiredPath ? IsFieldValidConfig : IsFormValidConfig): boolean; //#endregion //#region src/move/move.d.ts /** * Move array field config interface. */ interface MoveConfig { /** * The path to the field array to move an item within. */ readonly path: ValidArrayPath, TFieldArrayPath>; /** * The index of the item to move from. */ readonly from: number; /** * The index to move the item to. */ readonly to: number; } /** * Moves an item from one index to another within a field array. All items * between the source and destination indices are shifted accordingly. * * @param form The form store containing the field array. * @param config The move configuration specifying the path and source/destination indices. */ declare function move(form: BaseFormStore, config: MoveConfig): void; //#endregion //#region src/pickDirty/pickDirty.d.ts /** * Pick dirty config interface. */ interface PickDirtyConfig { /** * The value to filter down to its dirty parts. Must be structurally * compatible with the form's schema. */ readonly from: TValue; } /** * Picks only the dirty parts of the given value, using the form's dirty fields * as a structural mask. Arrays are treated as atomic and object keys without a * dirty descendant are omitted. Returns `undefined` if no field is dirty. * Useful for filtering a validated output down to its changed parts before * submitting. * * @param form The form store providing the dirty mask. * @param config The pick dirty configuration. * * @returns The dirty parts of the value, or `undefined`. */ declare function pickDirty(form: BaseFormStore, config: PickDirtyConfig): DeepPartial | undefined; //#endregion //#region src/remove/remove.d.ts /** * Remove array field config interface. */ interface RemoveConfig { /** * The path to the field array to remove an item from. */ readonly path: ValidArrayPath, TFieldArrayPath>; /** * The index of the item to remove. */ readonly at: number; } /** * Removes an item from a field array at the specified index. All items after * the removed item are shifted down by one index. * * @param form The form store containing the field array. * @param config The remove configuration specifying the path and index. */ declare function remove(form: BaseFormStore, config: RemoveConfig): void; //#endregion //#region src/replace/replace.d.ts /** * Replace array field config interface. */ interface ReplaceConfig { /** * The path to the field array to replace an item within. */ readonly path: ValidArrayPath, TFieldArrayPath>; /** * The index of the item to replace. */ readonly at: number; /** * The partial initial input value for the replacement item. */ readonly initialInput?: DeepPartial, [...TFieldArrayPath, number]>> | undefined; } /** * Replaces an item in a field array at the specified index with new initial input. * * @param form The form store containing the field array. * @param config The replace configuration specifying the path, index, and initial input. */ declare function replace(form: BaseFormStore, config: ReplaceConfig): void; //#endregion //#region src/reset/reset.d.ts /** * Reset base config interface. */ interface ResetBaseConfig { /** * Whether to keep the current input values during reset. Defaults to false. */ readonly keepInput?: boolean | undefined; /** * Whether to keep the touched state during reset. Defaults to false. */ readonly keepTouched?: boolean | undefined; /** * Whether to keep the edited state during reset. Defaults to false. */ readonly keepEdited?: boolean | undefined; /** * Whether to keep the error messages during reset. Defaults to false. */ readonly keepErrors?: boolean | undefined; } /** * Reset form config interface. */ interface ResetFormConfig extends ResetBaseConfig { /** * The path to a field. Leave undefined to reset the entire form. */ readonly path?: undefined; /** * The new initial input to reset to. If provided, replaces the form's * initial input. */ readonly initialInput?: DeepPartial> | undefined; /** * Whether to keep the submitted state during reset. Defaults to false. */ readonly keepSubmitted?: boolean | undefined; } /** * Reset field config interface. */ interface ResetFieldConfig extends ResetBaseConfig { /** * The path to the field to reset. */ readonly path: ValidPath, TFieldPath>; /** * The new initial input to reset the field to. If provided, replaces the * field's initial input. */ readonly initialInput?: DeepPartial, TFieldPath>> | undefined; } /** * Resets a specific field or the entire form to its initial state. Provides * fine-grained control over which state to preserve during reset through the * configuration options. * * @param form The form store to reset. */ declare function reset(form: BaseFormStore): void; /** * Resets a specific field or the entire form to its initial state. Provides * fine-grained control over which state to preserve during reset through the * configuration options. * * @param form The form store to reset. * @param config The reset configuration specifying what to reset and what to keep. */ declare function reset(form: BaseFormStore, config: TFieldPath extends RequiredPath ? ResetFieldConfig : ResetFormConfig): void; //#endregion //#region src/setErrors/setErrors.d.ts /** * Set form errors config interface. */ interface SetFormErrorsConfig { /** * The path to a field. Leave undefined to set form-level errors. */ readonly path?: undefined; /** * The error messages to set, or null to clear errors. */ readonly errors: [string, ...string[]] | null; } /** * Set field errors config interface. */ interface SetFieldErrorsConfig { /** * The path to the field to set errors on. */ readonly path: ValidPath, TFieldPath>; /** * The error messages to set, or null to clear errors. */ readonly errors: [string, ...string[]] | null; } /** * Sets or clears error messages on the form or a specific field. This is * useful for setting custom validation errors that don't come from schema * validation. * * @param form The form store to set errors on. * @param config The set errors configuration specifying the path and error messages. */ declare function setErrors(form: BaseFormStore, config: TFieldPath extends RequiredPath ? SetFieldErrorsConfig : SetFormErrorsConfig): void; //#endregion //#region src/setInput/setInput.d.ts /** * Set form input config interface. */ interface SetFormInputConfig { /** * The path to a field. Leave undefined to set the entire form input. */ readonly path?: undefined; /** * The input value to set for the form. */ readonly input: v.InferInput; } /** * Set field input config interface. */ interface SetFieldInputConfig { /** * The path to the field to set input on. */ readonly path: ValidPath, TFieldPath>; /** * The input value to set for the field. */ readonly input: PathValue, TFieldPath>; } /** * Sets the input value of a specific field or the entire form. This updates * the field value(s) and triggers validation if required by the form's * validation mode. * * @param form The form store to set input on. * @param config The set form input configuration specifying the new input values. */ declare function setInput(form: BaseFormStore, config: SetFormInputConfig): void; /** * Sets the input value of a specific field or the entire form. This updates * the field value(s) and triggers validation if required by the form's * validation mode. * * @param form The form store to set input on. * @param config The set input configuration specifying the path and new value. */ declare function setInput(form: BaseFormStore, config: TFieldPath extends RequiredPath ? SetFieldInputConfig : SetFormInputConfig): void; //#endregion //#region src/submit/submit.d.ts /** * Programmatically requests form submission by calling the native * `requestSubmit()` method on the underlying form element. * * @param form The form store to submit. */ declare function submit(form: BaseFormStore): void; //#endregion //#region src/swap/swap.d.ts /** * Swap array field config interface. */ interface SwapConfig { /** * The path to the field array to swap items within. */ readonly path: ValidArrayPath, TFieldArrayPath>; /** * The index of the first item to swap. */ readonly at: number; /** * The index of the second item to swap with the first. */ readonly and: number; } /** * Swaps two items in a field array by exchanging their positions. * * @param form The form store containing the field array. * @param config The swap configuration specifying the path and indices to swap. */ declare function swap(form: BaseFormStore, config: SwapConfig): void; //#endregion //#region src/validate/validate.d.ts /** * Validate form config interface. */ interface ValidateFormConfig { /** * Whether to focus the first field with errors after validation. Defaults to false. */ readonly shouldFocus?: boolean | undefined; } /** * Validates the entire form input against its schema. Returns a safe parse result * indicating success or failure with detailed issues. Optionally focuses the first * field with validation errors. * * @param form The form store to validate. * @param config The validate form configuration specifying focus behavior. * * @returns A promise resolving to the validation result. */ declare function validate(form: BaseFormStore, config?: ValidateFormConfig): Promise>; //#endregion //#endregion //#region src/types/field.d.ts /** * Field element props interface. */ interface FieldElementProps { /** * The name attribute of the field element. */ readonly name: string; /** * Whether to autofocus the field element when there are errors. */ readonly autofocus: boolean; /** * The ref callback to register the field element. */ readonly ref: (element: FieldElement) => void; /** * The focus event handler of the field element. */ readonly onFocus: JSX.EventHandler; /** * The input event handler of the field element. */ readonly onInput: JSX.EventHandler; /** * The change event handler of the field element. */ readonly onChange: JSX.EventHandler; /** * The blur event handler of the field element. */ readonly onBlur: JSX.EventHandler; } /** * Field store interface. */ interface FieldStore { /** * The path to the field within the form. */ readonly path: ValidPath, TFieldPath>; /** * The current input value of the field. */ readonly input: PartialValues, TFieldPath>>; /** * The current error messages of the field. */ readonly errors: [string, ...string[]] | null; /** * Whether the field has been touched. */ readonly isTouched: boolean; /** * Whether the field value has been edited. */ readonly isEdited: boolean; /** * Whether the field input differs from its initial value. */ readonly isDirty: boolean; /** * Whether the field is valid according to the schema. */ readonly isValid: boolean; /** * Sets the field input value programmatically. */ readonly onInput: (value: PartialValues, TFieldPath>>) => void; /** * The props to spread onto the field element for integration. */ readonly props: FieldElementProps; } /** * Field array store interface. */ interface FieldArrayStore { /** * The path to the array field within the form. */ readonly path: ValidArrayPath, TFieldArrayPath>; /** * The item IDs of the array field. */ readonly items: string[]; /** * The current error messages of the field array. */ readonly errors: [string, ...string[]] | null; /** * Whether the field array has been touched. */ readonly isTouched: boolean; /** * Whether the field array value has been edited. */ readonly isEdited: boolean; /** * Whether the field array input differs from its initial value. */ readonly isDirty: boolean; /** * Whether the field array is valid according to the schema. */ readonly isValid: boolean; } //#endregion //#region src/types/form.d.ts /** * Form store interface. */ interface FormStore extends BaseFormStore { /** * Whether the form is currently submitting. */ readonly isSubmitting: boolean; /** * Whether the form has been submitted. */ readonly isSubmitted: boolean; /** * Whether the form is currently validating. */ readonly isValidating: boolean; /** * Whether any field in the form has been touched. */ readonly isTouched: boolean; /** * Whether any field in the form has been edited. */ readonly isEdited: boolean; /** * Whether any field in the form differs from its initial value. */ readonly isDirty: boolean; /** * Whether the form is valid according to the schema. */ readonly isValid: boolean; /** * The current error messages of the form. * * Hint: This property only contains validation errors at the root level * of the form. To get all errors from all fields, use `getDeepErrors`. */ readonly errors: [string, ...string[]] | null; } //#endregion //#region src/types/utils.d.ts /** * Constructs a type that is maybe a getter function. */ type MaybeGetter = TValue | (() => TValue); //#endregion //#region src/components/Field/Field.d.ts /** * Field component props interface. */ interface FieldProps { /** * The form store to which the field belongs. */ readonly of: FormStore; /** * The path to the field within the form schema. */ readonly path: ValidPath, TFieldPath>; /** * The render function that receives the field store and returns JSX. */ readonly children: (store: FieldStore) => JSX.Element; } /** * Headless form field component that provides reactive properties and state. * The field component takes a form store, path to field, and a render function * that receives a field store to display field state and handle user interactions. * * @param props The field component props. * * @returns The UI of the field to be rendered. */ declare function Field(props: FieldProps): JSX.Element; //#endregion //#region src/components/FieldArray/FieldArray.d.ts /** * FieldArray component props interface. */ interface FieldArrayProps { /** * The form store to which the field array belongs. */ readonly of: FormStore; /** * The path to the field array within the form schema. */ readonly path: ValidArrayPath, TFieldArrayPath>; /** * The render function that receives the field array store and returns JSX. */ readonly children: (store: FieldArrayStore) => JSX.Element; } /** * Headless field array that provides reactive properties and state. The field array * component takes a form store, path to array field, and a render function that receives * a field array store to manage array items and handle array operations. * * @param props The field array component props. * * @returns The UI of the field array to be rendered. */ declare function FieldArray(props: FieldArrayProps): JSX.Element; //#endregion //#region src/components/Form/Form.d.ts /** * Form component props type. */ type FormProps = Omit, "onSubmit" | "novalidate" | "noValidate"> & { /** * The form store instance. */ readonly of: FormStore; /** * The child elements to render within the form. */ readonly children: JSX.Element; /** * The submit handler called when the form is submitted and validation succeeds. */ readonly onSubmit: SubmitEventHandler; }; /** * Form component that manages form submission and applies internal state. * Wraps form element and passes submission events to the provided handler. * * @param props The form component props. * * @returns The a native form element. */ declare function Form(props: FormProps): JSX.Element; //#endregion //#region src/primitives/createForm/createForm.d.ts /** * Creates a reactive form store from a form configuration. The form store * manages form state and provides reactive properties. * * @param config The form configuration. * * @returns The form store with reactive properties. */ declare function createForm(config: FormConfig): FormStore; //#endregion //#region src/primitives/useField/useField.d.ts /** * Use field config interface. */ interface UseFieldConfig { /** * The path to the field within the form schema. */ readonly path: ValidPath, TFieldPath>; } /** * Creates a reactive field store of a specific field within a form store. * * @param form The form store instance. * @param config The field configuration. * * @returns The field store with reactive properties and element props. */ declare function useField(form: MaybeGetter>, config: MaybeGetter>): FieldStore; //#endregion //#region src/primitives/useFieldArray/useFieldArray.d.ts /** * Use field array config interface. */ interface UseFieldArrayConfig { /** * The path to the field array within the form schema. */ readonly path: ValidArrayPath, TFieldArrayPath>; } /** * Creates a reactive field array store of a specific field array within a form store. * * @param form The form store instance. * @param config The field array configuration. * * @returns The field array store with reactive properties for array management. */ declare function useFieldArray(form: MaybeGetter>, config: MaybeGetter>): FieldArrayStore; //#endregion export { DeepErrorEntry, type DeepPartial, Field, FieldArray, FieldArrayProps, FieldArrayStore, type FieldElement, FieldElementProps, FieldProps, FieldStore, FocusFieldConfig, Form, type FormConfig, FormProps, type FormSchema, FormStore, GetFieldDeepErrorEntriesConfig, GetFieldDeepErrorsConfig, GetFieldDirtyInputConfig, GetFieldDirtyPathsConfig, GetFieldErrorsConfig, GetFieldInputConfig, GetFormDeepErrorEntriesConfig, GetFormDeepErrorsConfig, GetFormDirtyInputConfig, GetFormDirtyPathsConfig, GetFormErrorsConfig, GetFormInputConfig, InsertConfig, IsFieldDirtyConfig, IsFieldEditedConfig, IsFieldTouchedConfig, IsFieldValidConfig, IsFormDirtyConfig, IsFormEditedConfig, IsFormTouchedConfig, IsFormValidConfig, MaybeGetter, MoveConfig, type PartialValues, type PathValue, PickDirtyConfig, RemoveConfig, ReplaceConfig, type RequiredPath, ResetFieldConfig, ResetFormConfig, type Schema, SetFieldErrorsConfig, SetFieldInputConfig, SetFormErrorsConfig, SetFormInputConfig, type SubmitEventHandler, type SubmitHandler, SwapConfig, UseFieldArrayConfig, UseFieldConfig, type ValidArrayPath, type ValidPath, ValidateFormConfig, type ValidationMode, createForm, focus, getDeepErrorEntries, getDeepErrors, getDirtyInput, getDirtyPaths, getErrors, getInput, handleSubmit, insert, isDirty, isEdited, isTouched, isValid, move, pickDirty, remove, replace, reset, setErrors, setInput, submit, swap, useField, useFieldArray, validate };