react-modular-forms v1.1.0
react-modulr-forms
This library aims at solving the issues of complex forms in an extensible way. It allows multiple types of validation and arranging forms inn any way you see fit. It allows plugin any external library into it's validation process to prevent form submission or display errors in a unified manner.
Components
ModularForm
The ModularForm component will wrap our FormField elements, it simply has an id prop that will be referenced
by each field. It can wrap its elements but any element outside of the form will also be registered as
long as it holds the correct formId.
import { ModularForm } from 'react-modular-forms';
const formId = 'my-form';
<ModularForm id={formId}>
</ModularForm>ModularFormField
The ModularFormField is used to render any form field element. It must have a formId prop to reference it's
parent form and either a name or an id prop.
If you need to pass a class to the input field or the inner component you can use the innerClassName prop.
Every native HTML form field element should be supported out of the box.
```TSX
const formId = 'my-form';
<ModularForm id={formId}>
<ModularFormField formId={formId} name="email" type="email" />
</ModularForm>Validation
Validation is implemented by providing the validation prop to ModularFormField components.
export type ValidationType = {
required?: boolean;
/**
* If field valued doesn't match RegExp in negativeRegExps the error string will be displayed
*/
negativeRegExps?: { [error: string]: RegExp };
/**
* If field valued matches RegExp in positiveRegExps the error string will be displayed
*/
positiveRegExps?: { [error: string]: RegExp };
/**
* A custom validator function, should return an error string if value isn't valid or null if it is
*/
validator?: (value: any) => string | null;
validateOnBlur?: boolean;
/**
* The group prop allows the form to validate multiple fields
*/
group?: string;
/**
* groupMin tells the form how many fields in the group must be valid for the form to be submitted
*/
groupMin?: number;
};Registering new components with registerType
The registerType helper allows you to register external libraries or custom components as form fields. If you for example wanted to register react-select as component:
import React from 'react';
import Select from 'react-select';
const ReactSelectWrapper = ({ name, value: _value, onChange, componentRef,...props }: FieldComponentProps) => {
const [value, setValue] = useState<any>(_value);
useEffect(() => {
componentRef.current = value;
}, []);
return (
<Select
name={Array.isArray(name) ? name.join('.') : name}
value={value}
onChange={(option) => {
setValue(option);
componentRef.current = option.value;
onChange(null, option.value);
return option;
}}
{...props}
/>
);
};
registerType('react-select', {
Component: ReactSelectWrapper,
getValue: (ref: RefObject<string | undefined>) => ref.current
});When registering custom form field types, you should ensure events
methods are handled on the component for validation to be properly handled. You can use
the componentRef or the setComponentRef props to give the library something to access the
field's value. This ref will be passed to the getValue function that will be used to validate the field.
{
onChange?: (e: unknown, ...any: any[]) => void;
onBlur?: (e: React.SyntheticEvent) => void;
onFocus?: (e: React.SyntheticEvent) => void;
componentRef: React.MutableRefObject<any>;
setComponentRef: (value: any) => RefObject<any>;
}Using registerType to register complex types without adding validation hooks
If you wish to create ModularFormField types without adding validation hook you can use the
isStatic boolean option of the registerType function. This will prevent the logic from being
implemented twice if the components referenced are already ModularFormFields. This will allow the
creation of complex fields with ease or even group multiple fields into a single component.
registerType('address-fields', {
Component: ({ formId, prefix }: FieldComponentProps & { prefix: string}) => {
return <>
<ModularFormField formId={formId} type="text" name={`${prefix}address`} label="Address" validation={{required: true}} />
<ModularFormField formId={formId} type="text" name={`${prefix}city`} label="City" validation={{required: true}} />
<ModularFormField formId={formId} type="tel" name={`${prefix}zipcode`} label="Zipcode" validation={{required: true}} />
<ModularFormField formId={formId} type="text" name={`${prefix}country`} label="Country" validation={{required: true}} />
</>
},
isStatic: true
});1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago