npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-modular-forms

v1.1.0

Published

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 submissi

Downloads

1,818

Readme

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
});