finform-react-builder
Version:
A powerful, flexible React form builder with dynamic field rendering, custom validation, multi-step forms, Material-UI integration, image component support, toggle/radio buttons, switches, autocomplete, and advanced button positioning
223 lines (222 loc) • 6.34 kB
TypeScript
export interface ValidationRule {
pattern?: string | RegExp;
message?: string;
required?: boolean;
minLength?: number;
maxLength?: number;
min?: number | string;
max?: number | string;
custom?: (value: any) => boolean | string;
}
export interface ApiConfig {
endpoint: string;
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
valueField?: string;
labelField?: string;
headers?: Record<string, string>;
params?: Record<string, any>;
body?: any;
transform?: (data: any[]) => Array<{
label: string;
value: string | number;
}>;
dependsOn?: string;
conditional?: boolean;
}
export interface BaseField {
id?: string;
title?: string;
name: string;
label: string;
type: 'text' | 'email' | 'password' | 'number' | 'tel' | 'select' | 'checkbox' | 'toggle' | 'radio' | 'switch' | 'autocomplete' | 'date' | 'textarea' | 'image' | 'title' | 'section';
placeholder?: string;
required?: boolean;
disabled?: boolean;
validation?: ValidationRule;
step?: number;
value?: any;
col?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
xs?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
sm?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
md?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
lg?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
xl?: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
api_endpoint?: string;
api_method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
value_field?: string;
label_field?: string;
depends_on?: string;
conditional?: boolean;
apiConfig?: ApiConfig;
}
export interface TextField extends BaseField {
type: 'text' | 'email' | 'password' | 'tel' | 'textarea';
minLength?: number;
maxLength?: number;
pattern?: string;
}
export interface NumberField extends BaseField {
type: 'number';
min?: number;
max?: number;
}
export interface SelectField extends BaseField {
type: 'select';
options?: Array<{
label: string;
value: string | number;
}>;
default?: string | number;
api_endpoint?: string;
api_method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
value_field?: string;
label_field?: string;
depends_on?: string;
conditional?: boolean;
apiConfig?: ApiConfig;
}
export interface CheckboxField extends BaseField {
type: 'checkbox';
}
export interface ToggleField extends BaseField {
type: 'toggle';
options: Array<{
label: string;
value: string | number;
}>;
}
export interface RadioField extends BaseField {
type: 'radio';
options: Array<{
label: string;
value: string | number;
}>;
}
export interface SwitchField extends BaseField {
type: 'switch';
}
export interface AutocompleteField extends BaseField {
type: 'autocomplete';
options?: Array<{
label: string;
value: string | number;
}>;
multiple?: boolean;
freeSolo?: boolean;
filterOptions?: boolean;
api_endpoint?: string;
api_method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
value_field?: string;
label_field?: string;
depends_on?: string;
conditional?: boolean;
apiConfig?: ApiConfig;
}
export interface DateField extends BaseField {
type: 'date';
minDate?: string;
maxDate?: string;
}
export interface ImageField extends BaseField {
type: 'image';
src?: string;
alt?: string;
width?: number | string;
height?: number | string;
style?: React.CSSProperties;
className?: string;
onClick?: () => void;
defaultValue?: string;
}
export interface TitleField extends BaseField {
type: 'title';
variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
color?: string;
align?: 'left' | 'center' | 'right';
sx?: any;
}
export interface SectionField extends BaseField {
type: 'section';
variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
color?: string;
align?: 'left' | 'center' | 'right';
sx?: any;
}
export type FieldConfig = TextField | NumberField | SelectField | CheckboxField | ToggleField | RadioField | SwitchField | AutocompleteField | DateField | ImageField | TitleField | SectionField;
export interface FormButton {
text: string;
color?: string;
size?: 'small' | 'medium' | 'large';
onClick?: () => void;
disabled?: boolean;
loading?: boolean;
position?: 'left' | 'center' | 'right' | 'space-between';
type?: 'submit' | 'button' | 'reset';
sx?: any;
}
export interface ButtonGroup {
buttons: FormButton[];
position?: 'left' | 'center' | 'right' | 'space-between';
layout?: 'horizontal' | 'vertical';
spacing?: number;
sx?: any;
}
export interface FormTitle {
text: string;
variant?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
color?: string;
align?: 'left' | 'center' | 'right';
sx?: any;
}
export interface FormTheme {
primaryColor?: string;
secondaryColor?: string;
backgroundColor?: string;
textColor?: string;
borderRadius?: number | string;
spacing?: number;
typography?: {
fontFamily?: string;
fontSize?: number | string;
};
}
export interface FinFormProps {
id?: string;
title?: FormTitle;
theme?: FormTheme;
fields: FieldConfig[];
onSubmit: (data: any) => void;
onChange?: (data: any) => void;
submitButtonText?: string;
onSubmitClick?: (data: any) => void;
defaultValues?: Record<string, any>;
showSubmitButton?: boolean;
buttons?: FormButton[];
buttonGroup?: ButtonGroup;
baseUrl?: string;
apiHeaders?: Record<string, string>;
isMultiStep?: boolean;
currentStep?: number;
onStepChange?: (currentStep: number, totalSteps: number) => void;
showStepNavigation?: boolean;
stepNavigationProps?: {
showStepTitles?: boolean;
stepTitles?: string[];
};
}
export interface FieldRendererProps {
field: FieldConfig;
control: any;
errors: any;
baseUrl?: string;
apiHeaders?: Record<string, string>;
formData?: Record<string, any>;
}
export interface StepNavigationProps {
currentStep: number;
totalSteps: number;
onStepChange: (step: number) => void;
stepTitles?: string[];
showStepTitles?: boolean;
completedSteps?: number[];
}