import { Component, ComputedRef, MaybeRefOrGetter, Raw, Ref } from "vue"; import { StandardSchemaV1 } from "@standard-schema/spec"; import { Get, PartialDeep, Paths as Paths$1 } from "type-fest"; //#region src/types/shared.d.ts /** * The validation mode determines when validation occurs. * - `lazy`: Validates on blur or submission. * - `eager`: Validates on blur, then on every change if an error exists. */ type ValidationMode = 'eager' | 'lazy'; /** * Interaction events that can trigger a validation check for a field. * - onBlur: Trigger validation when the field loses focus. * - onChange: Trigger validation when the field value is committed. * - onInput: Trigger validation on every keystroke. * - onMount: Trigger validation when the field is mounted. * - onFocus: Trigger validation when the field gains focus. */ type ValidationTrigger = 'onBlur' | 'onChange' | 'onFocus' | 'onInput' | 'onMount'; /** * Constructs a type where all properties of the input type are optional recursively. * @template TData The base data structure to transform. */ type DeepPartial = PartialDeep; /** * Constructs a type representing all possible dot-separated paths within an object. * @template TReference The object type for which to generate paths. */ type Paths = Extract, string> | (string & {}); /** * Represents a validation schema for object-based data structures. * Complies with the Standard Schema specification. */ type ObjectSchema = StandardSchemaV1 & { '~standard': StandardSchemaV1['~standard'] & { types?: { input: object; }; }; }; //#endregion //#region src/types/use-not-form.d.ts /** * Configuration options for initializing a new form instance. * @template TSchema The form schema. */ interface UseNotFormConfig { /** The validation schema used to parse and validate form data */ schema: MaybeRefOrGetter; /** The initial values of the form */ initialValues?: DeepPartial>; /** The initial errors of the form */ initialErrors?: Array; /** * The validation triggers of the form. * @default { onBlur: true, onChange: true, onInput: true } */ validateOn?: Partial>; /** * The validation mode of the form. * @default { eager: true } */ validationMode?: Partial>; /** * Callback triggered when form validation passes and the form is submitted. * @param values The validated output data from the schema. */ onSubmit?: (values: StandardSchemaV1.InferOutput) => Promise | void; } //#endregion //#region src/types/not-form.d.ts /** * The complete state and API of a form instance returned by `useNotForm`. * @template TSchema The form schema. */ type NotFormInstance = Raw<{ /** The values the form was initialised or last reset with. */readonly initialValues: UseNotFormConfig['initialValues']; /** The errors the form was initialised or last reset with. */ readonly initialErrors: UseNotFormConfig['initialErrors']; /** The resolved validation triggers for this form. */ readonly validateOn: Required['validateOn']>>; /** The resolved validation mode for this form. */ readonly validationMode: Required['validationMode']>>; /** * Deeply reactive object of field values. * @example * - Access directly — no `.value` needed: * ```ts * form.values.email * ``` * * - Use with `v-model` for two-way binding: * ```vue * * ``` */ values: StandardSchemaV1.InferInput; /** * Sets a field value by dot-separated path. * * Useful for deeply nested paths or custom inputs that do not use `v-model`. * Does **not** trigger validation — the field's event handlers are responsible for that. * @example * ```ts * form.setValue('address.city', 'Lagos') * ``` */ setValue: >>(path: TPath, value: Get, TPath, { strict: false; }>) => void; /** * The set of field paths the user has interacted with. * Populated for all paths when the form is submitted. */ touchedFields: Set>>; /** Whether any field has been touched. */ isTouched: ComputedRef; /** * Marks a field as touched. * Called automatically by the field's `onBlur` handler. */ touchField: (path: Paths>) => void; /** The set of field paths whose current value differs from the initial value. */ dirtyFields: Set>>; /** Whether any field value differs from its initial value. */ isDirty: ComputedRef; /** * Marks a field as dirty. * Called automatically when a field value changes. */ dirtyField: (path: Paths>) => void; /** The raw validation issues produced by the last validation run. */ errors: Array; /** * A flat map of field path to its first error message. * * Convenient for direct template access without calling `getFieldErrors` * @example * ```vue * * ``` */ errorsMap: ComputedRef>, string>>>; /** * Replaces an existing error for the same path, or appends it if none exists. * Useful for setting server-side errors after submission. */ setError: (error: StandardSchemaV1.Issue) => void; /** Replaces all current errors with the provided issues. */ setErrors: (errors: Array) => void; /** Removes all active validation errors. */ clearErrors: () => void; /** * Returns all validation issues for a specific field path. * @example * ```ts * form.getFieldErrors('address.city') * ``` */ getFieldErrors: (path: Paths>) => Array; /** Whether a validation run is currently in progress. */ isValidating: Ref; /** * Validates the entire form against the schema. * Replaces all current errors with the result. */ validate: () => Promise>>; /** * Validates a single field against the schema. * Only replaces errors for that field — all other fields are left untouched. */ validateField: (path: Paths>) => Promise>>; /** Whether the form currently has no validation errors. */ isValid: ComputedRef; /** Whether the form is currently running its submit handler. */ isSubmitting: Ref; /** * Validates the form and runs `onSubmit` if it passes. * * Marks all fields as touched and dirty before validating so all errors surface. * If validation fails, submission is aborted. * Bind to the native form's `@submit` event: * @example * ```vue * * ``` */ submit: (event: Event) => Promise; /** * Resets the form to its initial state, or to new values and errors if provided. * * Clears all touched and dirty tracking. If `values` or `errors` are passed, * they replace the stored baseline so subsequent resets return to the new state. * @example * ```ts * // Reset to original initial values * form.reset() * * // Reset to new values (becomes the new baseline) * form.reset({ name: 'Jane' }) * ``` */ reset: (values?: DeepPartial>, errors?: Array) => void; }>; /** Props for the `NotForm` component. */ interface NotFormProps { /** The form instance to provide to all descendant `NotField` components. */ form: NotFormInstance; } /** Slots for the `NotForm` component. */ interface NotFormSlots { /** The default slot receives the full form instance */ default?: () => any; } //#endregion //#region src/types/not-array-field.d.ts /** * Props for the `NotArrayField` component. * @template TItemSchema The schema for a single array item. */ interface NotArrayFieldProps { /** Dot-separated path to the array within the form values. */ path: string; /** * Schema for a single array item — used purely for type inference. * Enables typed `append`, `prepend`, `insert`, and `update` methods in the slot. * @example * ```vue * * ``` */ itemSchema?: TItemSchema; /** * Explicit form instance override. * Takes priority over the instance provided by a `NotForm` ancestor. * Required when using `NotArrayField` outside of a `NotForm`. */ form?: NotFormInstance; /** * Per-field validation trigger overrides applied to the array as a whole. * Merged over the form-wide `validateOn` — only the keys you specify are overridden. */ validateOn?: Partial, boolean>>; } /** * Represents a single item in the array field. * Use `key` for `v-for` tracking and `path` to pass to a nested `NotField`. * @example * ```vue * * ``` */ interface NotArrayFieldItem { /** Stable key for `v-for` — does not change when items are reordered. */ key: string; /** Current index of this item in the array. */ index: number; /** Full dot-separated path to this item — pass directly to `NotField`. */ path: string; } /** * Slots for the `NotArrayField` component. * @template TSchema The form schema. * @template TItem An array field item. */ interface NotArrayFieldSlots { /** The default slot receives the full array state and manipulation methods. */ default: (props: { /** The dot-separated path to this array field. */path: string; /** The array items with stable keys and paths for use with `v-for`. */ items: Array; /** All validation issues for this array field from the last validation run. */ errors: Array; /** Whether this array field currently has no validation errors. */ isValid: boolean; /** * Whether any item in this array has been touched. * Derived from the form's `touchedFields` set. */ isTouched: boolean; /** * Whether any item in this array differs from its initial value. * Derived from the form's `dirtyFields` set. */ isDirty: boolean; /** Whether validation is currently running for this array field. */ isValidating: boolean; /** * Manually triggers validation for this array field. * Useful when mutations are performed programmatically outside of the normal flow. */ validate: () => ReturnType['validateField']>; /** * Appends a new item to the end of the array. * @param value The value to append. */ append: (value: TItem) => void; /** * Prepends a new item to the beginning of the array. * @param value The value to prepend. */ prepend: (value: TItem) => void; /** * Removes the item at the given index. * @param index The index of the item to remove. */ remove: (index: number) => void; /** * Inserts a new item at the given index, shifting subsequent items forward. * @param index The index to insert the item at. * @param value The value to insert. */ insert: (index: number, value: TItem) => void; /** * Replaces the value at the given index. * @param index The index of the item to replace. * @param value The value to replace with. */ update: (index: number, value: TItem) => void; /** * Swaps the positions of two items in the array. * @param indexA The index of the first item. * @param indexB The index of the second item. */ swap: (indexA: number, indexB: number) => void; /** * Moves an item from one index to another, shifting items between them. * @param from The current index of the item. * @param to The target index. */ move: (from: number, to: number) => void; }) => any; } //#endregion //#region src/components/not-array-field.vue.d.ts declare const __VLS_export$3: >(__VLS_props: NonNullable>["props"], __VLS_ctx?: __VLS_PrettifyLocal$1>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable>["expose"], __VLS_setup?: Promise<{ props: import("vue").PublicProps & __VLS_PrettifyLocal$1> & (typeof globalThis extends { __VLS_PROPS_FALLBACK: infer P; } ? P : {}); expose: (exposed: {}) => void; attrs: any; slots: NotArrayFieldSlots; emit: {}; }>) => import("vue").VNode & { __ctx?: Awaited; }; declare const _default: typeof __VLS_export$3; type __VLS_PrettifyLocal$1 = (T extends any ? { [K in keyof T]: T[K] } : { [K in keyof T as K]: T[K] }) & {}; //#endregion //#region src/types/not-field.d.ts /** Props for the `NotField` component. */ interface NotFieldProps { /** Dot-separated path to this field within the form values. */ path: string; /** * Explicit form instance override. * Takes priority over the instance provided by a `NotForm` ancestor. * Required when using `NotField` outside of a `NotForm` (singleton fields). * @example * ```vue * * ``` */ form?: NotFormInstance; /** * Per-field validation trigger overrides. * Merged over the form-wide `validateOn` — only the keys you specify are overridden. * @example * ```vue * * ``` */ validateOn?: Partial>; /** * Debounce delay in milliseconds for input- and change-triggered validation. * * When set, validation is deferred until the user stops typing for the given * duration. Only the final call within the window runs — earlier ones are * cancelled. Useful for async validators (e.g. username availability checks) * where firing on every keystroke would cause excessive requests. * * Blur- and submit-triggered validation always runs immediately, regardless * of this setting, so the field never feels unresponsive when the user leaves. * @example * ```vue * * ``` * * Omit or set to `0` to disable debouncing (default behaviour). */ debounce?: number; } /** * Slots for the `NotField` component. * @template TSchema The form schema. */ interface NotFieldSlots { /** The default slot receives the full field state and event handlers. */ default?: (props: { /** The dot-separated path to this field. */path: string; /** * The current value of this field — read-only snapshot for display purposes. * Do not mutate directly or use with `v-model`. * For two-way binding use `v-model="form.values.fieldName"` instead. */ value: any; /** All validation issues for this field from the last validation run. */ errors: Array; /** Whether this field currently has no validation errors. */ isValid: boolean; /** Whether the user has interacted with this field, or the form has been submitted. */ isTouched: boolean; /** Whether this field's current value differs from its initial value. */ isDirty: boolean; /** Whether an async validator is currently running for this field. */ isValidating: boolean; /** * Manually triggers validation for this field. * Useful for custom inputs that manage their own interaction events. */ validate: () => ReturnType['validateField']>; /** * Native DOM event handlers exposed by a field. * Spread onto a native input or bind individually to custom components. * @example * ```vue * * ``` */ events: { /** Triggered when the field loses focus. */onBlur: () => void; /** Triggered on every keystroke or value change. */ onInput: () => void; /** Triggered when the field value is committed. */ onChange: () => void; /** Triggered when the field gains focus. */ onFocus: () => void; }; }) => any; } //#endregion //#region src/components/not-field.vue.d.ts declare const __VLS_export$2: (__VLS_props: NonNullable>["props"], __VLS_ctx?: __VLS_PrettifyLocal>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable>["expose"], __VLS_setup?: Promise<{ props: import("vue").PublicProps & __VLS_PrettifyLocal & (typeof globalThis extends { __VLS_PROPS_FALLBACK: infer P; } ? P : {}); expose: (exposed: {}) => void; attrs: any; slots: NotFieldSlots; emit: {}; }>) => import("vue").VNode & { __ctx?: Awaited; }; declare const _default$1: typeof __VLS_export$2; type __VLS_PrettifyLocal = (T extends any ? { [K in keyof T]: T[K] } : { [K in keyof T as K]: T[K] }) & {}; //#endregion //#region src/components/not-form.vue.d.ts type __VLS_Slots$1 = NotFormSlots; declare const __VLS_base$1: import("vue").DefineComponent & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>; declare const __VLS_export$1: __VLS_WithSlots$1; declare const _default$2: typeof __VLS_export$1; type __VLS_WithSlots$1 = T & { new (): { $slots: S; }; }; //#endregion //#region src/types/not-message.d.ts /** Props for the `NotMessage` component. */ interface NotMessageProps { /** * HTML Tag or component to render as * @default span */ as?: Component | string; /** The name/path of the field whose error message should be displayed */ path: string; /** * Explicit form instance override. * Takes priority over the instance provided by a `NotForm` ancestor. * Required when using `NotMessage` outside of a `NotForm` (singleton fields). * @example * ```vue * * ``` */ form?: NotFormInstance; } /** Slots for the `NotMessage` component. */ interface NotMessageSlots { /** The default slot receives the error message context for custom rendering */ default?: (props: { /** The first active validation error message for the specified field */message?: string; }) => any; } //#endregion //#region src/components/not-message.vue.d.ts type __VLS_Slots = NotMessageSlots; declare const __VLS_base: import("vue").DefineComponent & Readonly<{}>, { as: import("vue").Component | string; }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>; declare const __VLS_export: __VLS_WithSlots; declare const _default$3: typeof __VLS_export; type __VLS_WithSlots = T & { new (): { $slots: S; }; }; //#endregion //#region src/composables/use-not-form.d.ts /** * Creates a reactive NotFormInstance for managing form state and validation. * @template TSchema The standard schema type. * @param config Configuration object. * @returns A reactive NotFormInstance. */ declare function useNotForm(config: UseNotFormConfig): NotFormInstance; //#endregion export { type DeepPartial, _default as NotArrayField, type NotArrayFieldItem, type NotArrayFieldProps, type NotArrayFieldSlots, _default$1 as NotField, type NotFieldProps, type NotFieldSlots, _default$2 as NotForm, type NotFormInstance, type NotFormProps, type NotFormSlots, _default$3 as NotMessage, type NotMessageProps, type NotMessageSlots, type ObjectSchema, type Paths, type UseNotFormConfig, type ValidationMode, type ValidationTrigger, useNotForm };