import type { FieldPath, FieldPathValue, FieldValues, IsEqual } from './path'; import type { ArrayProxy, DerivedStateProps, ObjectMutationMethods, ObjectStateValue, Prettify, ValueState } from './types'; export { type CreateFormOptions, createForm, type DeepNonNullable, type FormArrayState, type FormObjectState, type FormState, type FormStore, type FormValueState, useForm }; /** * Common form field methods available on every form state node. */ type FormCommon = { /** Subscribe and read the validation error. Re-renders when the error changes. */ useError: () => string | undefined; /** Read the validation error without subscribing. */ readonly error: string | undefined; /** Manually set a validation error. */ setError: (error: string | undefined) => void; }; type FormState = IsEqual extends true ? never : [NonNullable] extends [readonly (infer U)[]] ? FormArrayState : [NonNullable] extends [FieldValues] ? FormObjectState, T> : FormValueState; type FormReadOnlyState = Prettify>>, 'value' | 'use' | 'useCompute' | 'error' | 'setError'>>; interface FormValueState extends Omit, 'ensureArray' | 'ensureObject' | 'withDefault' | 'derived'>, FormCommon { /** Ensure the value is an array. */ ensureArray(): NonNullable extends (infer U)[] ? FormArrayState : never; /** Ensure the value is an object. */ ensureObject(): NonNullable extends FieldValues ? FormObjectState> : never; /** Return a new state with a default value, and make the type non-nullable */ withDefault(defaultValue: T): FormState>; /** Virtual state derived from the current value. * * @returns ArrayState if the derived value is an array, ObjectState if the derived value is an object, otherwise State. * @example * const state = store.a.b.c.derived({ * from: value => value + 1, * to: value => value - 1 * }) * state.use() // returns the derived value * state.set(10) // sets the derived value * state.reset() // resets the derived value */ derived: ({ from, to }: DerivedStateProps) => FormState; } type FormObjectProxy = { /** Virtual state for the object's keys. * * This does NOT read from a real `keys` property on the stored object; it results in a stable array of keys. */ readonly keys: FormReadOnlyState[]>; } & { [K in keyof T]-?: FormState>; }; type FormArrayState = IsEqual extends true ? never : FormValueState & ArrayProxy>; type FormObjectState = FormObjectProxy & FormValueState & ObjectMutationMethods; /** Type for nested objects with proxy methods */ type DeepNonNullable = [NonNullable] extends [readonly (infer U)[]] ? U[] : [NonNullable] extends [FieldValues] ? { [K in keyof NonNullable]-?: DeepNonNullable[K]>; } : NonNullable; /** * The form store type, combining form state with validation and submission handling. */ type FormStore = FormState & { /** Clears all validation errors from the form. */ clearErrors(): void; /** Returns a form submit handler that validates and calls onSubmit with form values. */ handleSubmit(onSubmit: (values: T) => void): (e: React.SyntheticEvent) => void; }; type NoEmptyValidator = 'not-empty'; type RegexValidator = RegExp; type FunctionValidator = (value: FieldPathValue>, state: FormStore) => string | undefined; type Validator = NoEmptyValidator | RegexValidator | FunctionValidator; type FieldConfig = { validate?: Validator; }; type CreateFormOptions = Partial, FieldConfig>>; type UnsubscribeFn = () => void; type UnsubscribeFns = UnsubscribeFn[]; /** * React hook that creates a form store with validation support. * * The form store extends the memory store with error handling and validation. * Fields can be configured with validators that run on every change. * * @param defaultValue - Initial form values * @param fieldConfigs - Optional validation configuration per field * @returns A form store with validation and submission handling * * @example * const form = useForm( * { email: '', password: '' }, * { * email: { validate: 'not-empty' }, * password: { validate: v => v && v.length < 8 ? 'Too short' : undefined } * } * ) * *
console.log(values))}> * form.email.set(e.target.value)} /> * {form.email.useError() && {form.email.error}} *
*/ declare function useForm(defaultValue: T, fieldConfigs?: CreateFormOptions): FormStore; declare function createForm(namespace: string, defaultValue: T, fieldConfigs?: CreateFormOptions): [FormStore, UnsubscribeFns];