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-jeff

v1.2.1

Published

A Good Form Library

Downloads

30

Readme

React Jeff

A Good Form Library

  • ~800 bytes minified+gzip
  • Easy to learn API
  • Write your form code in a way that is reusable and testable
  • Seamless sync and async form validations (including on form submit)
  • Tons of utilty features out of the box
  • Written with React Hooks
  • Typed with TypeScript

Install

npm install react-jeff

Usage

import React from "react"
import { useField, useForm } from "react-jeff"

/**
 * 1. Write some validations that accept an input value and return an array of errors.
 * (If the array is empty, the value is considered valid)
 */

function validateUsername(value) {
	let errs = []
	if (value.length < 3) errs.push("Must be at least 3 characters long")
	if (!/^[a-z0-9_-]*$/i.test(value)) errs.push("Must only contain alphanumeric characters or dashes/underscores")
	if (!/^[a-z0-9]/i.test(value)) errs.push("Must start with alphanumeric character")
	if (!/[a-z0-9]$/i.test(value)) errs.push("Must end with alphanumeric character")
	return errs
}

function validatePassword(value) {
	let errs = []
	if (value.length < 6) errs.push("Must be at least 6 characters long")
	if (!/[a-z]/.test(value)) errs.push("Must contain at least one lowercase letter")
	if (!/[A-Z]/.test(value)) errs.push("Must contain at least one uppercase letter")
	if (!/[0-9]/.test(value)) errs.push("Must contain at least one number")
	return errs
}

/**
 * 2. Write some custom components that you'll reuse for all of your forms.
 */

function Form({ onSubmit, ...props }) {
	return (
		<form {...props} onSubmit={event => {
			event.preventDefault() // Make sure you call `event.preventDefault()` on your forms!
			onSubmit()
		}}/>
	)
}

function Input({ onChange, ...props }) {
	return (
		<input {...props} onChange={event => {
			onChange(event.currentTarget.value) // Make sure all of your inputs call `props.onChange` with the new value.
		}} />
	)
}

/**
 * 3. Create your form!
 */
 
function SignupForm() {
        // Create some fields...
	let username = useField({
		defaultValue: "",
		required: true,
		validations: [validateUsername],
	})

	let password = useField({
		defaultValue: "",
		required: true,
		validations: [validatePassword],
	})
	
	// Create your onSubmit handler...
	function onSubmit() {
		// Do something with the form...
	}
	
	// Create your form...
	let form = useForm({
		fields: [username, password],
		onSubmit: onSubmit,
	})
	
	// Write your UI!
	return (
		<Form {...form.props}>
			<Input type="text" {...username.props} />
			<Input type="password" {...password.props} />
			<button type="submit">Sign Up</button>
		</Form>
	)
}

API

useField()

Call useField() to create a single field in a form.

let field = useField({
	defaultValue: (value), // ....... (Required) The default value of the field.
	validations: [(...errors)], // .. (Optional) Validations to run when the field is `validate()`'d.
	required: boolean, // ........... (Optional) Should the field be required?
	disabled: boolean, // ........... (Optional) Should the field be disabled?
	readOnly: boolean, // ........... (Optional) Should the field be readOnly?
})
field == {
	value: (value), // ......... The current value of the field.
	defaultValue: (value), // .. The `defaultValue` passed into `useField({ defaultValue })`.

	dirty: boolean, // ......... Has the field been changed from its defaultValue?
	touched: boolean, // ....... Has the element this field is attached to been focused previously?
	focused: boolean, // ....... Is the element this field is attached to currently focused?
	blurred: boolean, // ....... Has the element this field is attached to been focused and then blurred?

	validating: boolean, // .... Is the field validating itself?
	valid: boolean, // ......... Is the field currently valid? (must have no errors, and if the field is required, must not be empty)
	errors: [(...errors)], // .. The collected errors returned by `opts.validations`

	required: boolean, // ...... Is the field required?
	disabled: boolean, // ...... Is the field disabled?
	readOnly: boolean, // ...... Is the field readOnly?

	setValue: Function, // ..... Call with a value to manually update the value of the field.
	setRequired: Function, // .. Call with true/false to manually set the `required` state of the field.
	setDisabled: Function, // .. Call with true/false to manually set the `disabled` state of the field.
	setReadOnly: Function, // .. Call with true/false to manually set the `readOnly` state of the field.

	reset: Function, // ........ Reset the field to its default state.
	validate: Function, // ..... Manually tell the field to validate itself (updating other fields).

	// Props to pass into an component to attach the `field` to it:
	props: {
		value: (value), // ....... The current value (matches `field.value`).

		onChange: Function, // ... An `onChange` handler to update the value of the field.
		onFocus: Function, // .... An `onFocus` handler to update the focused/touched/blurred states of the field.
		onBlur: Function, // ..... An `onFocus` handler to update the focused/blurred states of the field.

		required: boolean, // .... Should the element be `required`?
		disabled: boolean, // .... Should the element be `disabled`?
		readOnly: boolean, // .... Should the element be `readOnly`?
	},
}

useForm()

Call useForm() with to create a single form.

let form = useForm({
	fields: [(...fields)], // .. All of the fields created via `useField()` that are part of the form.
	onSubmit: Function, // ..... A submit handler for the form that receives the form submit event.
})
form == {
	fieldErrors: [(...errors)], // ... The collected errors from all of the fields in the form.
	submitErrors: [(...errors)], // .. The errors returned by `opts.onSubmit`.

	submitted: boolean, // ........... Has the form been submitted at any point?
	submitting: boolean, // .......... Is the form currently submitting?

	focused: boolean, // ............. Are *any* of the fields in the form currently `focused`?
	touched: boolean, // ............. Are *any* of the fields in the form currently `touched`?
	dirty: boolean, // ............... Are *any* of the fields in the form currently `dirty`?
	valid: boolean, // ............... Are *all* of the fields in the form currently `valid`?
	validating: boolean, // .......... Are *any* of the fields in the form currently `validating`?

	reset: Function, // .............. Reset all of the fields in the form.
	validate: Function, // ........... Validate all of the fields in the form.
	submit: Function, // ............. Submit the form manually.

	// Props to pass into a form component to attach the `form` to it:
	props: {
		onSubmit: Function, // ......... An onSubmit handler to pass to an element that submits the form.
	},
}