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

formwheels

v2.0.0

Published

React form hooks

Downloads

32

Readme

React FormWheels

TODOS

  • Finish checkbox control.

NPM JavaScript Style Guide

React hooks: You need [email protected] for using hooks.

FormWheels is a library for dealing with forms in React with hooks. It allows you to manage Form State with controlled components in an easy and expressive way. It was developed having in mind performance and developer experience,

Features

  • Performant: It doesn't re-render all the form, just the component that is being updated.
  • Flexible: You can use it with almost every UI-Kit library, as soon as your components are controlled.
  • Validation: Validate your fields without effort, basic validators included.
  • Expressive: Compose your forms in an easy and expressive way.

Install

npm install --save formwheels

Usage

For start working, you need to connect your controlled components to the form state with the useFormState hook, this hook provides some methods and properties for connecting with the form state.

After you have defined your fields, then you compose your form with the Form component in a similar way you do it with plain html.

here you can define a submit handler, so you have access to the form values.

Fields

You need to connect every field to the form state by using the value and setValue coming from useFormState, in the case of Fields, you must provide the props to the hook and your control should have a name property, so the Form State can reference your control.

const { hasErrors, errors, setValue, touched, value } = useFormState(props);

additionaly you can display errors and check if the field has been touched.

// InputField.js

import React from 'react';
import { useFormState } from 'formwheels';

const InputField = (props) => {
  const { hasErrors, errors, setValue, touched, value } = useFormState(props);
  return (
    <div>
      <label>{props.label}</label>
      <input
        {...props}
        onChange={event => setValue(event.target.value)}
        value={value}
      />
      {hasErrors && (
        <ul>
          {errors.map(
            error => (
              <li>{error}</li>
            )
          )}
        </ul>
      )}
    </div>
  );
};

export default InputField;

General FormState

If you need to watch over the general Form State, for accessing values and errors on the complete form, then you can create a component and connect it with useFormState without sending props. In this case you will not receive touched, instead you have isDirt.

Note: It is important to notice the difference between a Field and a FormState component, depending on what you are working on, you will receive properties for a Field or the Form.

const { errors, getValue, hasErrors, isDirt, setValue, values } = useFormState();
// FormErrors.js

import React from 'react';
import { useFormState } from 'formwheels';

const getErrorList = (errors = {}) =>
  Object.keys(errors).reduce(
    (list, key) => list.concat(errors[key]), []
  );

const FormErrors = () => {
  const { errors, hasErrors } = useFormState();
  // errors is a hash of error arrays, so I use a small function to
  // get an array of errors.
  const errorList = getErrorList(errors);
  const items = errorList.map(error => (
    <ListItem key={error}>
      {error}
    </ListItem>
  ));
  return hasErrors ? (
    <div>
      <h2>
        Form Errors
      </h2>
      <List>
        {items}
      </List>
    </div>
  ) : null;
};

export default FormErrors;

Submit

It's not necessary that you connect the submit button to the form state, but it can be useful to disable the submit button till the form is valid.

Note: Submit component should be a button or input element with type attribute set to submit, so the Form component fires an onSubmit event.

// Submit.js

import React from 'react';
import { useFormState } from 'formwheels';

const Submit = () => {
  const { hasErrors } = useFormState();
  return <input type="submit" disabled={hasErrors} />;
};

export default Submit;

Form

Once you have created your connected fields, you can compose your form.

Note: Every Form should have a name.

// CommentForm.js

import React from 'react';
import { Form, validators } from 'formwheels';
import InputField from './InputField';
import Submit from './Submit';

const CommentForm = () => {
  const submitHandler = values => console.log(values);
  return (
    <Form name="comment" onSubmit={submitHandler}>
      <InputField
        label="Name"
        name="name"
        validators={[
          validators.isNotEmpty('First Name should not be empty'),
        ]}
      />
      <InputField
        label="Age"
        name="age"
        validators={[
          validators.isNotEmpty('Age should not be empty'),
          validators.isNumber('Age should be a number'),
          validators.greaterThan(16, 'Age should be over 16'),
        ]}
      />
      <InputField
        label="Comment"
        name="comment"
        validators={[
          validators.isNotEmpty('First Name should not be empty'),
        ]}
        value="My initial comment"
      />
      <Submit/>
    </Form>
  );
};

export default CommentForm;

Initial Values

You can define field initial values just by setting the value property on a Field.

// CommentForm fragment ..

<InputField
  label="Comment"
  name="comment"
  validators={[
    validators.isNotEmpty('First Name should not be empty'),
  ]}
  value="My initial comment"
/>

Form Submit

You can define a Form onSubmit event handler to access the values when the form is submitted.

// CommentForm fragment ..

const submitHandler = values => console.log(values);
  return (
    <Form name="comment" onSubmit={submitHandler}>

Note: To submit a form, you need to have a submit input or button inside your form.

Field Validation

You can set an array of validators for a field with the validators property, this library already comes with some basic validators that you can use out of the box.

// CommentForm fragment ...

<InputField
  label="Age"
  name="age"
  validators={[
    validators.isNotEmpty('Age should not be empty'),
    validators.isNumber('Age should be a number'),
    validators.greaterThan(16, 'Age should be over 16'),
  ]}
/>

Special Use Cases

Setting initial values

Modifying field values programmatically

Getting access to FormState values

Dynamic validation

API Reference

Form Component

The Form component is a context wrapper that holds the FormState, you need to wrapp all of your forms with this components, so you have access to the FormState.

name

Every form needs a name.

onSubmit(values)

Callback when the form is submitted, you receive the values of the form.

useFormState Hook

The useFormState is a hook that gives you access to the FormState. You can use the hook in two ways:

Connecting Fields: Connects fields to the Form State. For this you need to send the properties comming from the Control, like explained before.

Accessing Form State: Access to the entire Form State. For this you use the hook without sending any props. Like explained before.

errors

hasErrors

isDirt

setValue

touched

value

FormState

FormState is the core of the library, although you don't access it directly, it lives in the context of the Form component, and is responsible of handling the state of the form and validation. You can access the FormState on the onChange events dispatched by fields connected to the Form State.

errors: hasErrors: isDirt: values:

clear(): getValue(field: string): isFieldRegistered(field: string): isFieldTouched(field: string): registerField(field: Field): reset(): setValue(field: string, value: any, process?: boolean): subscribe(subscriber: Subscriber): unregisterField(field: string): unsubscribe(subscriber:Subscriber): updateFieldValidators(field: string, validators: Function[]): validate():

License

MIT © londonbarrett