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

@virtuslab/formts

v1.0.1

Published

Type-safe, declarative and performant React form & validation library

Downloads

102

Readme

build status GitHub license npm npm bundle size examples

Formts

Type-safe, declarative and performant React form & validation library

Status

A stable release has been reached. Further development of new features is currently not planned. Bug fixes will be provided if needed, feature requests wil still be considered.

Features

  • Fully type-safe API, purpose built to get the most out of Typescript type-inference
  • Declarative definition of form shape and validation rules
  • Runtime type-checking of form values against the schema
  • Convenient hooks & context based API allowing for isolated re-renders
  • Plain react-typescript, 0 dependencies
  • View layer agnostic - no components are provided, works with any 3rd-party components
  • handleChange function for dealing with change events automatically
  • Advanced validation API which enables:
    • specifying dependencies on other fields
    • specifying validation triggers for individual rules
    • selective validation of just the affected fields on value changes
    • separation of error messages from error codes (optional)
    • async validation rules with debounce option
    • easy mixing of built-in rules with custom functions
    • combining multiple validation rules into composite validators
  • Good scalability for very large and complex forms

Getting Started

1) Install

npm install @virtuslab/formts

2) Define shape of the form

import { FormSchemaBuilder, FormFields } from "@virtuslab/formts";

const Schema = new FormSchemaBuilder()
  .fields({ answer: FormFields.string() })
  .errors<string>()
  .build();

3) Define validation rules (optional)

import { FormValidatorBuilder } from "@virtuslab/formts";

const validator = new FormValidatorBuilder(Schema)
  .validate(
    Schema.answer,
    val => (val === "" ? "Required!" : null),
    val => (val !== "42" ? "Wrong answer!" : null)
  )
  .build();

3) Create controller holding form state

import { useFormController, FormProvider } from "@virtuslab/formts";

const MyForm: React.FC = () => {
  const controller = useFormController({ Schema, validator });

  return (
    <FormProvider controller={controller}>
      <AnswerField />
      <FormActions />
    </FormProvider>
  );
};

4) Connect inputs to form

import { useField } from "@virtuslab/formts";

const AnswerField: React.FC = () => {
  const field = useField(Schema.answer);

  return (
    <section>
      <label htmlFor={field.id}>
        What is the answer to the meaning of life, the universe, and everything?
      </label>
      <input
        id={field.id}
        value={field.value}
        onChange={field.handleChange}
        onBlur={field.handleBlur}
      />
      <div className="error">{field.error}</div>
    </section>
  );
};

5) Connect actions to form

import { useFormHandle } from "@virtuslab/formts";

const FormActions: React.FC = () => {
  const form = useFormHandle(Schema);

  return (
    <section>
      <button
        type="submit"
        disabled={form.isValid === false}
        onClick={() => form.submit(console.log)}
      >
        Submit!
      </button>

      <button type="reset" onClick={form.reset}>
        Reset
      </button>
    </section>
  );
};

Documentation

Currently API documentation is available in form of:

Examples

Play around with the code on CodeSandbox to learn Formts API and features:

a) Step-by-step introduction:

  1. basic form (naive)
  2. basic form + optimized re-renders
  3. basic form + validation
  4. basic form + Material-UI

b) HTML input bindings:

  1. radio group input
  2. checkbox group input
  3. select input
  4. input array
  5. mui multi-select input
  6. mui date-picker input

c) Advanced examples:

  1. change password form
  2. order pizza form
  3. form with summary of validation errors
  4. registration stepper form

Why another form lib?

Update 2023:

Some of the reasons outlined below are no longer valid as react-hook-form has improved since this project started. It offers good type-safety and performance. If for some reason you are not happy with it however, this library offers different approach to many aspects of form management and a powerful validation API - so it may suit your needs better.

a) Type-safety

Most popular form libraries like Formik and react-hook-form are written in Typescript but are not designed with type-safe API as a primary concern.

There is some evidence that this is important for some people:

There are some existing truly type-safe react form solutions, but each has a costly dependency associated with it:

b) Performance

There are SOME form libraries with really good performance (react-hook-form). However combining convenient Context based hook API with React performance optimizations is still problematic. See https://react-hook-form.com/advanced-usage#FormProviderPerformance for example.

c) Declarative validation API

Usually form libs "outsource" advanced validation to schema-based libraries such as Yup. This seems like a great idea but has some limitations:

  • yup and similar packages are not designed with type-safety in mind
  • Advanced optimizations (such as validating only the affected fields rather than the entire form) are not available.

Limitations

  • Form values type is limited by schema definition API and can't represent more advanced TS types
  • Adding required validator does not impact type of values.
  • number() fields are typed as number | "", this is because HTML number inputs work with "" as empty value.
  • Definition of form shape and validation split into 2 separate steps
  • Binding to input components is more verbose than with other form libraries (this is intentional to keep API type-safe and view-layer agnostic)