Skip to content
A lightweight framework and utility for building powerful forms in React applications
Branch: master
Clone or download
Latest commit 0d5c052 Jul 16, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.storybook
config/webpack added rollup and esm export Feb 7, 2019
docs updated docs Jun 27, 2019
patches
src fixes issue 227 where allowEmptyStrings form level prop did not work Jul 8, 2019
stories added zip badge to readme and docs Jun 27, 2019
tests fixed issue 219 where array fields would not work in scope Jul 2, 2019
.eslintrc.json refactored HOCS to use hooks wooo Jan 7, 2019
.gitignore Gitignore IntelliJ IDE project files Jul 3, 2018
.prettierrc added eslint Aug 8, 2018
.travis.yml added travis yml and link to spectrum Jun 15, 2018
CHANGELOG.md updated changelog Jul 16, 2019
LICENSE Update LICENSE Oct 5, 2018
README.md
index.d.ts Add allowEmptyStrings to Form's TS props Jul 12, 2019
package-lock.json 2.11.8 Jul 16, 2019
package.json 2.11.8 Jul 16, 2019
rollup.config.js added rollup and esm export Feb 7, 2019

README.md

Informed

We have released V2!!!

Go to live examples, code and docs!

npmversion Informed-Chat Build Status Coverage Status Minzipped-Size

Introduction

Say hello to the best react form library you have ever used! Informed is an extensive, simple, and efficient solution for creating basic to complex forms in react. Out of the box you get the ability to grab and manipulate values, validate fields, create custom inputs, and much much more!!!

Oh and YES WE USE HOOKS!!

Getting Started

Install with npm
npm install --save informed

Create a Simple Form

import { Form, Text } from 'informed';

<Form>
  <label>
    First name:
    <Text field="name"/>
  </label>
  <button type="submit">Submit</button>
</Form>;

Create a Simple Form With Validation

import { Form, Text } from 'informed';

const validate = value => {
  return !value || value.length < 5
    ? 'Field must be at least five characters'
    : undefined;
};

<Form>
  <label>
    First name:
    <Text field="name" validate={validate}/>
  </label>
  <button type="submit">Submit</button>
</Form>;

Create a Complex Form

import { Form, Text, Option, Select, Checkbox, Scope, TextArea, RadioGroup, Radio } from 'informed';

<Form>
  <label>First name:<Text field="name"/></label>
  <Scope scope="favorite">
    <label>Favorite color:<Text field="color"/></label>
    <label>Favorite food:<Text field="food"/></label>
  </Scope>
  <label>Friend 1:<Text field="friends[0]" /></label>
  <label>Friend 2:<Text field="friends[1]" /></label>
  <label>Friend 3:<Text field="friends[2]" /></label>
  <label>Bio:<TextArea field="bio"/></label>
  <RadioGroup field="gender">
    <label>Male <Radio value="male"/></label>            
    <label>Female <Radio value="female"/></label>
  </RadioGroup>
  <label>
    Relationship status:
    <Select field="status">
      <Option value="" disabled>
        Select One...
      </Option>
      <Option value="single">Single</Option>
      <Option value="relationship">Relationship</Option>
      <Option value="complicated">Complicated</Option>
    </Select>
  </label>
  <label>
    Colors:
    <Select
      field="colors"
      multiple
    >
      <Option value="red">Red</Option>
      <Option value="green">Green</Option>
      <Option value="blue">Blue</Option>
      <Option value="yellow">Yellow</Option>
      <Option value="orange">Orange</Option>
      <Option value="purple">Purple</Option>
    </Select>
  </label>
  <label>Authorize: <Checkbox field="authorize"/></label>
  <button type="submit">Submit</button>
</Form>

Access Form State with Hooks!

import { Form, Text, useFormState } from 'informed';

const ComponentUsingFormState = () => {
  const formState = useFormState();
  return (
    <pre>
      <code>{JSON.stringify(formState, null, 2)}</code>
    </pre>
  );
};

<Form>
  <label>Name:<Text field="name" /></label>
  <button type="submit">Submit</button>
  <h5>Component using formState:</h5>
  <ComponentUsingFormState />
</Form>

Control Form via FormApi through the use of Hooks!!

import { Form, Text, useFormApi } from 'informed';

const ComponentUsingFormApi = () => {
  const formApi = useFormApi();
  return (
    <button type="button" onClick={()=>
      formApi.setValue(
        'name', 
        Math.floor(Math.random() * Math.floor(Number.MAX_SAFE_INTEGER)))}>
      Random
    </button>
  );
};
  
<Form>
  <div>
    <label>Name:<Text field="name"/></label>
    <button type="submit">Submit</button>
    <h5>Component using formApi:</h5>
    <ComponentUsingFormApi />
  </div>
</Form>

Create custom inputs with built in validation!!

import { Form, BasicText, asField } from 'informed';

const validate = value => {
  return !value || value.length < 5
    ? 'Field must be at least five characters'
    : undefined;
};

const ErrorText = asField(({ fieldState, ...props }) => (
  <React.Fragment>
    <BasicText
      fieldState={fieldState}
      {...props}
      style={fieldState.error ? { border: 'solid 1px red' } : null}
    />
    {fieldState.error ? (
      <small style={{ color: 'red' }}>{fieldState.error}</small>
    ) : null}
  </React.Fragment>
));

<Form>
  <label>
    First name:
    <ErrorText
      field="name"
      validate={validate}
      validateOnChange
      validateOnBlur
    />
  </label>
  <button type="submit">Submit</button>
</Form>;

Create dynamic forms

import { Form, Text, RadioGroup, Radio } from 'informed';

<Form>
  {({ formState }) => (
    <React.Fragment>
      <label>First name:<Text field="name"/></label>
      <label>Are you married?</label>
      <RadioGroup field="married">
        <label>Yes <Radio value="yes"/></label>
        <label>No <Radio value="no"/></label>
      </RadioGroup>
      {formState.values.married === 'yes' ? (
        <label >Spouse name:<Text field="spouse" /></label>
      ) : null}
      <button type="submit">Submit</button>
    </React.Fragment>
  )}
</Form>

WARNING: writing this in the above way is fine, it works they way we expect and gets us what we need... BUT! There is a better way!

import { Form, Text, RadioGroup, Radio, useFieldState } from 'informed';

const Spouse = () => {
  const { value: married } = useFieldState('married'); 
  return married === 'yes' ? <label >Spouse name:<Text field="spouse" /></label> : null;
};

<Form>
  <label>First name:<Text field="name"/></label>
  <label>Are you married?</label>
  <RadioGroup field="married">
    <label>Yes <Radio value="yes"/></label>
    <label>No <Radio value="no"/></label>
  </RadioGroup>
  <Spouse />
  <button type="submit">Submit</button>  
</Form>

Writing code the second way can typically save excess rendering! And, it looks much cleaner.

Create dynamic forms with dynamic arrays !!! Mind Blown!!!

import { Form, Text, ArrayField } from 'informed';

const DynamicArrays = () => {

  return (
    <div>
      <Form>
        <ArrayField field="sibling">
          {({ add, fields }) => (
            <>
              <button onClick={add} type="button">
                Add Sibling
              </button>
              {fields.map(({ field, key, remove }, i) => (
                <label htmlFor={i} key={key}>
                  Sibling {i}:
                  <Text field={field} id={i} />
                  <button type="button" onClick={remove}>
                    Remove
                  </button>
                </label>
              ))}
            </>
          )}
        </ArrayField>
        <button type="submit">Submit</button>
        <FormState />
      </Form>
    </div>
  );
};
You can’t perform that action at this time.