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

@adrenalin/react-form

v2.0.3

Published

Adrenalin Media - React Form Validation Component

Downloads

113

Readme

Adrenalin Media - React Form

A React form validation wrapper and templating component. It supports all base html field types (input, textarea, select, radio, checkbox) and includes a few base validation rules for standard validations such as email, password, digits etc.

It includes support for adding custom validators via a defined validator object structure as well as the ability to overide the default field template component at either the parent ReactForm or child ReactFormField level.

Useage

This component uses NPM to install and manage versioning.

Installation

As this is a private npm package, authentication is first required.

npm login
# Username: adrenalin
# Password: *********
# Email: [email protected]

Then install the module -

yarn add @adrenalin/react-form

or

npm install @adrenalin/react-form

Getting Started

The module exposes 2 main components, the parent ReactForm and the child ReactFormField fields.

ReactForm represents the form wrapper and will return a <form> element around its children.

ReactFormField is then used to identify the form inputs to be captured by the form. These can be placed at any child level allowing for custom form layouts. The field comes with a predefined component template layout that will handle the input states, label and errors. The module also includes SCSS for the default field component template.

ReactFormField fields can also be dynamically added or removed from the form which will update it's validation state on each props.children change.

Below is a basic example of use inside a react Component -

Javascript

import React, { Component } from "react";
import { ReactForm, ReactFormField } from "@adrenalin/react-form";

class FormApp extends Component {
	handleFormValidated(formData) {
		console.log("Success:", formData);
	}

	handleFormError(formData) {
		console.log("Error:", formData);
	}

	render() {
		return (
			<ReactForm
				onSuccess={this.handleFormValidated.bind(this)}
				onError={this.handleFormError.bind(this)}
			>
				<ReactFormField
					type="text"
					name="firstName"
					id="firstname"
					label="First Name"
					placeholder="First Name"
					required={true}
					validators={["name"]}
					errorMessages={{
						required: "Please enter your first name."
					}}
				/>

				<ReactFormField
					type="select"
					name="selector"
					label="Select a value"
					required={true}
					errorMessages={{
						required: "Please select an option."
					}}
				>
					<option value="">Select an option</option>
					<option value="first">First option</option>
					<option value="second">Second option</option>
					<option value="third">Third option</option>
				</ReactFormField>

				<ReactFormField
					type="checkbox"
					name="terms"
					label="Please agree to the terms."
					required={true}
					errorMessages={{
						required: "Please make sure you agree to the terms."
					}}
				/>

				<button type="submit">Submit</button>
			</ReactForm>
		);
	}
}

SCSS

The module comes with SCSS to handle the structual styles of the returned ReactFormField template component.

This can be imported as per below -

// Import base scss from @adrenalin/react-form npm module
@import "~@adrenalin/react-form/scss/index";

SCSS Variables

To assist with modifying the default template styles there are number of SCSS variables that can be predefiend before importing the module scss.

// ReactForm override variables
$reactform_color_success: lighten(blue, 20%); // success state color
$reactform_color_error: lighten(red, 20%); // error state color
$reactform_field_padding: 1em; // left/right padding for input, select, textarea elements
$reactform_field_bg: #efefef; // background color for field inputs
$reactform_field_margin: 20px; // top/bottom margin between each field
$reactform_input_size: 1.25em; // height of the text input and select elements/labels
$reactform_textarea_size: 10em; // height of the textarea element/label
$reactform_radio_size: 2em; // height of the radio element/label
$reactform_checkbox_size: 2em; // height of the checkbox element/label

// Import base scss from @adrenalin/react-form npm module
@import "~@adrenalin/react-form/scss/index";

Props

ReactForm

Most props provided to ReactForm will automatically be passed down to the <form> element. Below are the custom ReactForm specific props.

| Prop | Type | Description | | ------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | onSuccess | function | A callback function which returns an array of all the form fields as objects with their name and value. Fired on the form submit action when all required fields and validations are met. | | onError | function | A callback function which returns an array of all the form fields as objects with their name and value. Fired on the form submit action when any required fields or validations fail to validate. | | disableErrorScroll | boolean | If true the form will not attempt to scroll to the first invalid input in the form on form submit. | | disableSubmitUntilValid | boolean | If true any child type="submit" buttons will have a disabled prop and class added to them until the form reaches a valid state. | | validators | array | An array of validator patterns to extend the default validators. Custom validators are detailed further here. | | fieldComponent | component | A react template component that will override the default Field component. More info on custom field template components here. | | pageSubmit | boolean | If true, preventDefault will only be called if the form is invalid. Useful if you would like the handle the form with a regular POST request instead of AJAX. |

ReactFormField

Most props provided to ReactFormField fields will automatically be passed down and extended to the native input element and also the template component. Below explains custom and modified ReactForm properties and their behaviour.

| Prop | Type | Description | | ---------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | type | text, number, tel, email, password, textarea, radio, checkbox, select | Defines the type of input element to render. Select and textarea types will return native <select> and <textarea> elements, all other elements will use <input> with the type="" property. | | name | string | The unique name for the field. This name is used in the return fields array on submit/error and for validation checks. | | id | string | Standard unique dom id. Used to map the input field to it's label in the field template. | | label | string | Text used for the field label. | | required | boolean | If true the field will expect a positive value in order to validate. | | validators | array | An array of strings representing matching validator names. The field will be validated against each validator rule in the array. Validators are detailed further here. | | match | string | The unique name of another field to compare and validate the value against. e.g. match="password" will look for the field with name="password" and not validate until the values match. | | info | string | A string of informational text that the default field template supports. The info text will be rendered just underneath the input and input errors area of the template. | errorMessages | object | An object of keyed custom error messages that will override the default validator errors matching the name. e.g. errorMessages={{required: "Please enter your email address."}} will use the error string when the required validation fails and errorMessages={{required: "Please select an option.", email: "Use a real email eh!"}} will use the email error message when the field fails the email validator name. | | hideErrors | boolean | A boolean to toggle the showing of error messages for the field. Useful if you are just intending to use an error style over the info text prop instead of showing the error message when invalid. | children | array | Child elements are supported only for type="select" fields and are intended to be standard select options. e.g. <option value="first">First option</option> | | fieldComponent | component | A react template component that will override the default Field component. More info on custom field template components here. |

Default Validators

The ReactFormFields can use the following default validators out of the box. Check the validator files in the /src/validators directory of the main repo for more information on the validation and regex used.


Email

Validates the field against a valid email pattern regex.

<ReactFormField
	validators={["email"]}
>

Password

Validates the field to make sure it only contains at least 8 characters long, includes 1 uppercase letter, 1 lower case letter, 1 number and 1 special character.

<ReactFormField
	validators={["password"]}
>

Name

Validates the field to make sure it only contains letters (A-Z) and spaces.

<ReactFormField
	validators={["name"]}
>

Digits

Validates the field to make sure it only contains digits (0-9).

<ReactFormField
	validators={["digits"]}
>

Mobile

Validates the field to make sure it follows an Australian mobile phone number regex.

<ReactFormField
	validators={["mobile"]}
>

Date

Validates the field to make sure it follows a date regex pattern.

<ReactFormField
	validators={["date"]}
>

Postcode

Validates the field to make sure it a standard Australian postcode format and range.

<ReactFormField
	validators={["postcode"]}
>

Custom Validators

Custom validation rules can be created and passed to the <ReactForm> component as an array via the validators prop.

const customValidators = [
	{
	    ID: "ukpostcode",
	    validate: input => {
	    	var ukPostalRegex = /^[A-Z]{1,2}[0-9]{1,2} ?[0-9][A-Z]{2}$/i;
	        return ukPostalRegex.test(input.value);
	    },
	    error: "Please make sure this is a valid UK postcode."
	}
]

<ReactForm
    validators={customValidators}
    onSuccess={this.handleFormValidated.bind(this)}
    onError={this.handleFormError.bind(this)}
>

	<ReactFormField
	    type="text"
	    name="uk_postcode"
	    id="postuk_postcodeode"
	    label="Postcode (UK)"
	    required={true}
	    validators={["ukpostcode"]}
	/>

Validator Pattern

Each validator is represented as an object with 3 keys.

{
    ID: "ukpostcode",
    validate: input => {
    	var ukPostalRegex = /^[A-Z]{1,2}[0-9]{1,2} ?[0-9][A-Z]{2}$/i;
        return ukPostalRegex.test(input.value);
    },
    error: "Please make sure this is a valid UK postcode."
}

ID : string

A string representing the validator name and used to identify which fields to validate against.

validate : function

A function that takes the input element as an argument, processes it and returns true if valid.

error : string

The default error message that will be shown to the user.

Field Template Component

Each instance of ReactFormField should return the processed input and props to a template component that will handle the layout of the field.

Out of the box a default template component will be used for all available field types to handle different structual markup (checkbox, radio, select and textarea fields). For reference the default component can be viewed at /src/components/Field.js in the main repo.

The base component template will also require an import of the SCSS from the module to mainly handle structual styling of the field template.

Below is an example of the rendered markup from a text type input which is invalid -

Initialise the field in react

<ReactFormField
	type="text"
	name="firstName"
	id="firstname"
	label="First Name First"
	placeholder="First Name"
	required={true}
	validators={["name"]}
	errorMessages={{
		required: "Please enter your first name."
	}}
/>

Rendered output markup (in an invalid state with an error message)

<div class="react-form__field react-form__field--text is-incomplete is-invalid">
	<label for="firstname">
		<div class="react-form__field__label">
			<div class="react-form__field__label__inner">First Name First</div>
		</div>
		<input
			type="text"
			name="firstName"
			id="firstname"
			label="First Name First"
			placeholder="First Name"
			value=""
			errors="Please enter your first name."
		/>
	</label>
	<div class="react-form__field__errors">
		<div class="react-form__field__errors__item">
			Please enter your first name.
		</div>
	</div>
</div>

Custom Field Template Component

The ReactForm and ReactFormField components both provide support for passing a custom template component via the fieldComponent prop. Passing the component to at the parent ReactForm level will use this field for all child ReactFormField fields, whereas passing the component at the ReactFormField level will just use the template for that specific field.

Example Component:

const MyCustomFieldTemplate = props => {
	return (
		<div
			className={`my-custom-field-template
                ${props.classes.inheritedClasses}
                ${props.classes.isDisabled}
                ${props.classes.isIncomplete}
                ${props.classes.isFocused}
                ${props.classes.isValid}
                ${props.classes.isInvalid}
                ${props.classes.hasValue}
            `}
		>
			<label htmlFor={props.id}>{props.label}</label>

			{/* input element (input, select, textarea) */}
			{props.inputElement}

			{/* errors */}
			{props.showErrors && props.errors && props.errors.length ? (
				<div className={`my-custom-field-template__errors`}>
					<div className={`my-custom-field-template__errors__item`}>
						{props.errors[0]}
					</div>
				</div>
			) : null}
		</div>
	);
};

Use for all ReactFormField fields

<ReactForm
    onSuccess={this.handleFormValidated.bind(this)}
    onError={this.handleFormError.bind(this)}
    fieldComponent={MyCustomFieldTemplate}
>

Use for a specific ReactFormField field

<ReactFormField
	type="text"
	name="firstName"
	id="firstname"
	label="First Name First"
	placeholder="First Name"
	required={true}
	validators={["name"]}
	errorMessages={{
		required: "Please enter your first name."
	}}
	fieldComponent={MyCustomFieldTemplate}
/>

Available fieldComponent props

All props applied to ReactFormField will be passed down to the template component provided. In addition a number of special props are added to assist with building out the template logic.


inputElement : element

The input element itself (input, textarea, select), this will let you decide where to render the element inside your template.

// template component

return(
	<label htmlFor={props.id}>{props.label}</label>;

	{/*input element*/}
	{props.inputElement}
)

classes : object

An object of conditional state classes detailing the current validation and interaction state of the input -

classes: {
	hasValue: "";
	inheritedClasses: "";
	isDisabled: "";
	isFocused: "";
	isIncomplete: "is-incomplete";
	isInvalid: "";
	isValid: "";
}

errors : array

An array error message for the corresponding current validation errors

errors: ["This field is required.", "Please enter some digits."];

showErrors : boolean

A boolean detailing where to visually show errors for this field. Returned on bluring of an field input or when the form action is submitted.


valid : boolean

A boolean representing if the input is completly valid and will submit.


passwordToggleBtn : element

The prebound password toggle button. Only passed for type="password" inputs.

Developing

JS files for this module are found in the root src folder. The entry point can be found at src/index.js. The module also includes base styles inside the scss/ folder.

To preview and test the module whilst developing there is also an included test react project under test-app. This app is generated from create react app and is not included in the outputted npm package.

Publishing

After making changes, a commit should be created and, if required, merged back into the develop branch. The version number should then be incremented using one of the npm version commands outlined below. This will ensure that a new commit is created and tagged with the new version number.

npm version patch - Minor bug fixes/changes

npm version minor - For new backwards compatible features

npm version major - For any backwards incompatible changes

Finally, publish your changes to NPM using npm publish. This will also push all changes and tags to the develop branch on origin.