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

@stackup/form

v0.3.7

Published

A type-safe approach to managing complex form state in React.

Downloads

4

Readme

Build Version Size License

A type-safe approach to managing complex form state in React.

This library provides integration with @stackup/validate to handle validation. However, it should be pretty easy to integrate whatever validation library you prefer.

You should also checkout @stackup/inputs, which includes some ready-made form fields.

Usage

import React from "react";
import { useForm, useField } from "@stackup/form";

const Form = () => {
  const form = useForm({ initialValue: { email: "", name: "" } });

  const validate = useValidation(form, value => {
    if (value.email) {
      return { valid: true, value };
    } else {
      return { valid: false, error: { email: "is required" } };
    }
  });

  const submit = useSubmit(validate, value => {
    console.log(value);
  });

  return (
    <form onSubmit={submit}>
      <Input type="email" label="Email" field={useField(form, "email")} />
      <Input type="text" label="Name" field={useField(form, "name")} />
      <button type="submit">Save</button>
    </form>
  );
};

const Input = ({
  label,
  field: { id, value, error, touched, setValue, setTouched },
  ...props
}) => (
  <div>
    <label htmlFor={id}>{label}</label>
    <input
      {...props}
      id={id}
      value={value}
      onBlur={useCallback(() => setTouched(true), [])}
      onChange={useCallback(e => setValue(e.target.value), [setValue])}
    />
    {touched && error && <p>{error}</p>}
  </div>
);

API

Table of Contents

useForm

Create a new form. A form requires an initial value, a function to validate, and a submit handler.

A form behaves just like any other field, but with some extra properties for managing submission.

The initial value for the form can be literally anything! Usually, it's an object, but it could be any type of value.

Parameters

Examples

Form values can be primitive

const form = useForm({ initialValue: "" });

But usually, they'll contain an object

const form = useForm({
  initialValue: {
    email: "",
    name: ""
  }
});

Returns Form<Value>

useField

Create a field for a given property.

Parameters

Examples

const form = useForm({
  initialValue: {
    email: "",
    profile: { name: "" } }
  }
});

const email = useField(form, "email");
const profile = useField(form, "profile");
const name = useField(profile, "name");

Returns FormField<any>

useValidation

Use a plain ol' function for validation.

This hook can also be used to incorporate your favorite validation library.

Parameters

Examples

const validation = useValidation(form, value => {
  if (!value.email) {
    return { valid: false, error: { email: "can't be blank" } };
  }

  return { valid: true, value };
});

Returns Form<Value, Result>

useValidate

Add validation to the form using @stackup/validate.

Parameters

Examples

const validator = schema({
  email: assert(isString).then(refute(isBlank))
});

const validate = useValidate(form, validator);

Returns Form<Value, Result>

useSubmit

Create a submit handler for the form.

Parameters

  • form Form<Value, Result>
  • fn SubmitFn<Result>
  • opts ValidateOptions (optional, default {touch:true})

Examples

Sumbitting a form

const form = useForm({ initialValue: "foo" });
const submit = useSubmit(form, console.log);

Sumbitting with validation

const form = useForm({ initialValue: "foo" });
const validate = useValidate(form, myValidator);
const submit = useSubmit(validate, console.log);

Returns Submit

useReset

Create a reset handler for the form.

Parameters

  • form Form<Value, Result>

Examples

const form = useForm({ initialValue: "foo" });
const reset = useReset(form);

Returns Reset

useFieldItem

Create a field for a specific index in an array.

This hook is intended for use in building forms with "Add another" functionality.

Parameters

Examples

const form = useForm({ initialValue: { pets: [{ name: "" }] } });
const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const name = useField(pet, "name");

Returns FormField<Value>

usePushItem

Adds a new value to the end to an array of values.

This can be used to create a form with repeating fields.

Parameters

Examples

const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const addPet = usePushItem(pets, { name: "" });

useInsertItem

Adds a new value at a specific position to an array of values.

This can be used to create a form with repeating fields.

Parameters

Examples

const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const insert = useInsertItem(pets, 0, { name: "" });

useRemoveItem

Removes a value at the given index from array of values.

This can be used to create a form with repeating fields.

Parameters

Examples

const pets = useField(form, "pets");
const pet = useFieldItem(pets, 0);
const removePet = useRemoveItem(pets, 0);

useIdentifier

Creates a unique identifier that will remain consistent across re-renders.

This hook does not currently support SSR.

Parameters

Returns string

Form

Extends FormField<Value>

The value returned by useForm.

initialValue

The initial values for the form.

Type: Value

initialError

The initial errors on the fields.

Type: FormError<Value>

initialTouched

The initially touched fields.

Type: FormTouched<Value>

setValidating

Indicate that the form is validating

Type: SetState<boolean>

setSubmitting

Indicate that the form is validating

Type: SetState<boolean>

setSubmission

Update the form's submission status

Type: SetState<Submission>

reset

Reset the state of the form

Type: function (opts: ResetOptions<Value>): void

validate

Run validation

Type: function (opts: ValidateOptions): Promise<ValidationResult<Value, Result>>

FormField

The primary form data structure.

id

A unique ID for this form field. This can be used to associate fields with a label.

Type: string

name

The name or array index that was given to useField or useFieldItem.

Type: (string | number)

value

The current value of the field.

Type: Value

error

An error or errors that are associated with this field or it's children.

Type: FormError<Value>

touched

Indicates that this field or it's children have been modified by the user.

Type: FormTouched<Value>

isValidating

Indicates that validation is currently being run

Type: boolean

isSubmitting

Indicates that the form is currently being submitted

Type: boolean

submission

Keeps track of the form's submission status

Type: Submission

setValue

Change the value. Just like with setState, you can pass a callback to this function to get the current value and update it.

Type: SetState<Value>

setError

Update the error.

Type: SetState<FormError<Value>>

setTouched

Indicate that this field has been touched. This is usually called in onBlur.

Type: SetState<FormTouched<Value>>

ValidateFn

A function used for validation. This function must indicate whether or not the form is valid.

The error property can be used to set errors on the form.

The value property can be used to transform the form's values before validation.

Type: function (value: Value): (ValidationResult<Value, Result> | PromiseLike<ValidationResult<Value, Result>>)

Submit

Submits the form.

Type: function (event: FormEvent<HTMLFormElement>): Promise<void>

Submission

Keeps track of submissions.

count

The number of times the form has been submitted

Type: number

error

If the submission flow throws an error, it will appear here.

Type: Error

Reset

Resets the form.

Type: function (event: FormEvent<HTMLFormElement>): Promise<void>

UseFormOptions

The options that can be passed to useForm.

id

Customize the base ID for all fields.

Type: string

initialValue

The initial values for the form.

Type: Value

initialError

The initial errors on the fields.

Type: FormError<Value>

initialTouched

The initially touched fields.

Type: FormTouched<Value>

UseValidationOptions

Configures when validation runs.

onChange

Enables validation whenever values change.

Type: boolean

onBlur

Enables validation whenever a field is touched.

Type: boolean