svelte-hook-form
Version:
A better version of form validation.
117 lines (96 loc) • 2.94 kB
text/typescript
import type { Readable, Writable } from "svelte/store";
import type { FieldPath, FieldValues } from "./paths";
interface Resolver {
validate(data: any): Promise<any>;
}
export type Fields = Record<string, any>;
export type FormConfig = Partial<{
resolver: Resolver;
validateOnChange: boolean;
}>;
export type SuccessCallback<T extends FieldValues> = (data: T, e: Event) => void;
export type ErrorCallback = (errors: Record<string, any>, e: Event) => void;
export type NodeElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;
export type ValidationResult = true | string;
export type ValidationFunction = (
...args: any[]
) => ValidationResult | Promise<ValidationResult>;
export type Validator = string | ValidationFunction;
export type RuleExpression =
| string
| Array<Validator>
| Record<string, Validator>
| Record<string, any>;
export type RegisterOption<T> = {
defaultValue?: T;
bail?: boolean;
validateOnBlur?: boolean;
validateOnMount?: boolean;
rules?: RuleExpression;
};
export type FieldOption<T = any> = Partial<{
defaultValue: T;
rules: RuleExpression;
validateOnMount: boolean;
handleChange: (state: FieldState, node: Element) => void;
}>;
export interface FormControl<F extends FieldValues = FieldValues> {
register: <T>(key: FieldPath<F>, option?: RegisterOption<T>) => Readable<FieldState>;
unregister: (key: FieldPath<F>) => void;
setValue: (e: Event | FieldPath<F>, value?: any) => void;
getValue: (key: FieldPath<F>) => any;
getValues: () => F;
setError: (key: FieldPath<F>, errors: string[]) => void;
setFocus: (key: FieldPath<F>, focused: boolean) => void;
reset: (values?: Fields) => void;
field: UseField;
watch: (key: FieldPath<F>) => Readable<FieldState>;
}
type UseField = (
node: HTMLElement,
option?: FieldOption
) => { update(v: FieldOption): void; destroy(): void };
export interface Form<F extends FieldValues> extends Readable<FormState>, FormControl<F> {
control: Readable<FormControl<F>>;
errors: Readable<Fields>;
validate: (
paths?: FieldPath<F> | Array<string>
) => Promise<{ valid: boolean; data: F }>;
onSubmit: (
success: SuccessCallback<F>,
error?: ErrorCallback
) => (e: SubmitEvent) => void;
}
export type FormState = Readonly<{
pending: boolean;
dirty: boolean;
touched: boolean;
submitting: boolean;
submitCount: number;
valid: boolean;
}>;
export type FieldState<T = any> = Readonly<{
defaultValue: T;
value: T;
pending: boolean;
dirty: boolean;
touched: boolean;
valid: boolean;
errors: string[];
}>;
export interface FieldStore extends Writable<FieldState> {
destroy(): void;
}
export type ValidationRule = Readonly<{
name: string;
validate: <T>(
value: any,
params?: string[],
ctx?: FormControl<T>
) => Promise<ValidationResult>;
params: any[];
}>;
export type ResetFormOption = {
errors: boolean;
dirtyFields: boolean;
};