z-react-dynamic-form
Version:
A dynamic form builder for React applications with various input types and validation
166 lines (165 loc) • 5.24 kB
TypeScript
import { ReactNode } from "react";
import { z } from "zod";
import { SelectOption } from "../components/select/types";
import { AxiosRequestConfig } from "axios";
export interface FileWithPreview {
name: string;
size: number;
type: string;
lastModified: number;
preview: string;
}
export declare enum SUCCESSTYPE {
VERIFIED = "verified",
SUCCESS = "success"
}
export declare enum ControllerType {
TEXT = "text",
EMAIL = "email",
PASSWORD = "password",
NUMBER = "number",
TEXTAREA = "textarea",
CHECKBOX = "checkbox",
RADIO = "radio",
SELECT = "select",
SEARCHABLE_SELECT = "searchable-select",
SELECT_FROM_API = "select-from-api",
SEARCHABLE_SELECT_FROM_API = "searchable-select-from-api",
MULTI_SELECT = "multi-select",
SEARCHABLE_MULTI_SELECT = "searchable-multi-select",
MULTI_SELECT_FROM_API = "multi-select-from-api",
SEARCHABLE_MULTI_SELECT_FROM_API = "searchable-multi-select-from-api",
DATE = "date",
DATE_OF_BIRTH = "date-of-birth",
TIME = "time",
DATETIME = "datetime",
FILE = "file",
IMAGE_UPLOAD = "image-upload"
}
export type ControllerTypeType = "text" | "email" | "password" | "number" | "textarea" | "checkbox" | "radio" | "select" | "searchable-select" | "select-from-api" | "searchable-select-from-api" | "multi-select" | "searchable-multi-select" | "multi-select-from-api" | "searchable-multi-select-from-api" | "date" | "date-of-birth" | "time" | "datetime" | "file" | "image-upload" | "phone" | "group-checkbox" | "phone-number" | "upload" | "rich-text-editor" | "react-node";
export interface ModalType {
open: boolean;
data: any[];
}
export interface OptionsApiOptions {
api?: string;
method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
dependingContrllerName?: string;
parameterName?: string;
params?: Record<string, any>;
includeAll?: boolean;
}
export interface Controller {
type: ControllerTypeType;
name: string;
label?: string;
placeholder?: string;
required?: boolean;
disabled?: boolean;
tooltip?: string;
helperText?: string;
colSpan?: number;
defaultValue?: any;
min?: number;
max?: number;
step?: number;
options?: SelectOption[] | {
label: string;
value: string | number;
}[] | "from-api";
apiUrl?: string;
mapControllerType?: "group" | "each";
mapController?: (value: any, values?: any) => Controller[] | Promise<Controller[]>;
transformResponse?: (data: any) => SelectOption[];
searchParam?: string;
minSearchLength?: number;
maxSelections?: number;
multiple?: boolean;
accept?: string;
maxSize?: number;
rows?: number;
cols?: number;
pattern?: string;
autoComplete?: string;
readOnly?: boolean;
renderComponent?: (props: any) => JSX.Element;
optionsApiOptions?: OptionsApiOptions;
display?: (formData: Record<string, any>) => boolean;
visible?: (formData: Record<string, any>) => boolean;
maxFiles?: number;
acceptedFileTypes?: Record<string, string[]>;
imageReturnType?: "file" | "base64";
allowCamera?: boolean;
imageWidth?: number;
imageHeight?: number;
maxSizeMB?: number;
[key: string]: any;
}
export interface Step {
title: string;
description?: string;
controllers: Controller[];
}
export type apiOptionsType = {
api: string;
method: "POST" | "PATCH" | "PUT" | "DELETE" | "GET";
options?: AxiosRequestConfig<{}> | undefined;
errorHandler?: (data: any, type: errorHandlertType) => void;
onFinish?: (data: any) => void;
};
export type errorHandlertType = "form" | "modal" | "toast" | "redirect";
export type PropsPropsType = {
form?: {
className?: string;
[key: string]: any;
};
controllerBase?: JSX.IntrinsicElements["div"] & {
ref?: React.Ref<HTMLDivElement>;
};
groupcontrollerBase?: JSX.IntrinsicElements["div"] & {
ref?: React.Ref<HTMLDivElement>;
};
submitBtn?: JSX.IntrinsicElements["button"];
grid?: {
className?: string;
};
controller?: {
className?: string;
};
};
export interface DynamicFormProps<T extends z.ZodType<any, any>> {
controllers?: Controller[];
formSchema?: T;
defaultValues?: Partial<z.infer<T>>;
handleSubmit?: (data: {
values: z.infer<T>;
setError: any;
reset: () => void;
}) => Promise<void>;
apiOptions?: apiOptionsType;
tricker?: (props: {
submitLoading: boolean;
isValid: boolean;
}) => JSX.Element;
props?: PropsPropsType;
modalComponenet?: (modal: ModalType, setModal: (modal: ModalType) => void) => ReactNode;
steps?: Step[];
formtype?: "normal" | "steper";
stepPreview?: boolean;
submitBtn?: {
label?: string;
className?: string;
type?: string;
disabled?: boolean;
};
watch?: (values: Record<string, any>) => void;
extraData?: Record<string, any>;
}
export type StepsType<T> = {
stepName?: string;
stepNameByNumber?: number;
stepSchema?: T;
skip?: (value: any) => boolean;
condition?: (value: any) => string;
controllers: Controller[];
};