el-form-react
Version:
React form components and hooks powered by Zod validation
122 lines (119 loc) • 4.22 kB
TypeScript
import { z } from 'zod';
interface FormState<T extends Record<string, any>> {
values: Partial<T>;
errors: Partial<Record<keyof T, string>>;
touched: Partial<Record<keyof T, boolean>>;
isSubmitting: boolean;
isValid: boolean;
isDirty: boolean;
}
interface UseFormOptions<T extends Record<string, any>> {
schema: z.ZodSchema<T>;
initialValues?: Partial<T>;
onSubmit?: (values: T) => void | Promise<void>;
validateOnChange?: boolean;
validateOnBlur?: boolean;
}
interface FieldState {
isDirty: boolean;
isTouched: boolean;
error?: string;
}
interface ResetOptions<T> {
values?: Partial<T>;
keepErrors?: boolean;
keepDirty?: boolean;
keepTouched?: boolean;
}
interface SetFocusOptions {
shouldSelect?: boolean;
}
interface UseFormReturn<T extends Record<string, any>> {
register: (name: string) => {
name: string;
onChange: (e: React.ChangeEvent<any>) => void;
onBlur: (e: React.FocusEvent<any>) => void;
} & ({
checked: boolean;
value?: never;
} | {
value: any;
checked?: never;
});
handleSubmit: (onValid: (data: T) => void, onError?: (errors: Record<keyof T, string>) => void) => (e: React.FormEvent) => void;
formState: FormState<T>;
reset: (options?: ResetOptions<T>) => void;
setValue: (path: string, value: any) => void;
watch: {
(): Partial<T>;
<Name extends keyof T>(name: Name): T[Name];
<Names extends keyof T>(names: Names[]): Pick<T, Names>;
};
getFieldState: <Name extends keyof T>(name: Name) => FieldState;
isDirty: <Name extends keyof T>(name?: Name) => boolean;
getDirtyFields: () => Partial<Record<keyof T, boolean>>;
getTouchedFields: () => Partial<Record<keyof T, boolean>>;
trigger: {
(): Promise<boolean>;
<Name extends keyof T>(name: Name): Promise<boolean>;
<Names extends keyof T>(names: Names[]): Promise<boolean>;
};
clearErrors: (name?: keyof T) => void;
setError: <Name extends keyof T>(name: Name, error: string) => void;
setFocus: <Name extends keyof T>(name: Name, options?: SetFocusOptions) => void;
addArrayItem: (path: string, item: any) => void;
removeArrayItem: (path: string, index: number) => void;
resetField: <Name extends keyof T>(name: Name) => void;
}
type GridColumns = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
interface AutoFormFieldConfig {
name: string;
label?: string;
type?: FieldType;
placeholder?: string;
colSpan?: GridColumns;
component?: React.ComponentType<AutoFormFieldProps>;
options?: Array<{
value: string;
label: string;
}>;
fields?: AutoFormFieldConfig[];
}
interface AutoFormFieldProps {
name: string;
label?: string;
type?: string;
placeholder?: string;
value: any;
onChange: (e: React.ChangeEvent<any>) => void;
onBlur: (e: React.FocusEvent<any>) => void;
error?: string;
touched?: boolean;
options?: Array<{
value: string;
label: string;
}>;
fields?: AutoFormFieldConfig[];
onAddItem?: () => void;
onRemoveItem?: (index: number) => void;
arrayPath?: string;
}
interface AutoFormErrorProps {
errors: Record<string, string>;
touched: Record<string, boolean>;
}
type FieldType = "text" | "email" | "password" | "number" | "textarea" | "select" | "array" | "checkbox" | "date" | "url";
type ComponentMap = Partial<Record<FieldType, React.ComponentType<AutoFormFieldProps>>>;
interface AutoFormProps<T extends Record<string, any>> {
schema: z.ZodSchema<T>;
fields?: AutoFormFieldConfig[];
initialValues?: Partial<T>;
layout?: "grid" | "flex";
columns?: GridColumns;
onSubmit: (data: T) => void | Promise<void>;
onError?: (errors: Record<keyof T, string>) => void;
children?: (formApi: UseFormReturn<T>) => React.ReactNode;
customErrorComponent?: React.ComponentType<AutoFormErrorProps>;
componentMap?: ComponentMap;
}
export type { AutoFormProps as A, ComponentMap as C, FieldType as F, UseFormOptions as U, UseFormReturn as a, AutoFormErrorProps as b, AutoFormFieldProps as c, AutoFormFieldConfig as d };