Home
Softono
usetheform

usetheform

Open source MIT JavaScript
91
Stars
36
Forks
4
Issues
3
Watchers
1 year
Last Commit

About usetheform

<p align="center"> <img src="https://raw.githubusercontent.com/iusehooks/usetheform/refs/heads/master/workspaces/docs/static/img/logo.png" width="233" height="51" alt="Usetheform Logo" /> </p> <h3 align="center">An easy way to build forms in React.</h3> <div align="center"> [![Code Coverage](https://coveralls.io/repos/github/iusehooks/usetheform/badge.svg?branch=master)](https://coveralls.io/github/iusehooks/usetheform?branch=master) [![Usetheform CI](https://github.com/iusehooks/usetheform/actions/workflows/github-actions.yml/badge.svg?branch=master)](https://github.com/iusehooks/usetheform/actions/workflows/github-actions.yml) [![Bundle Size](https://img.shields.io/bundlephobia/minzip/usetheform.svg)](https://bundlephobia.com/result?p=usetheform@latest) [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=React%20library%20for%20composing%20declarative%20forms%2C%20manage%20their%20state%2C%20handling%20their%20validation%20and%20 ...

Platforms

Web Self-hosted

Languages

JavaScript

Usetheform Logo

An easy way to build forms in React.

Code Coverage Usetheform CI Bundle Size Tweet


Demo GIF

πŸ’‘ What is Usetheform?

Usetheform is a lightweight, dependency-free React library for composing declarative forms and managing their state. It's simple to use, flexible, and powerful for handling nested fields, validation, and much more.

πŸ“š Documentation
⚑ Quickstart
πŸ”₯ Features
πŸ“– Recipes
🧠 Motivation
πŸ§ͺ Code Sandboxes
🀝 How to Contribute
πŸ“„ License

:fire: Features

:zap: Quickstart

Install usetheform using your preferred package manager:

npm install --save usetheform
yarn add usetheform

Basic usage example:

import React from "react";
import { Form, Input, useValidation } from "usetheform";
import { ReducerFn, ValidatorFn, OnChangeFormFn, OnSubmitFormFn } from "usetheform/types";

interface MyFormState {
  firstname: string;
  lastname: string;
  age: number;
}

const preventNegativeNumber: ReducerFn<MyFormState["age"]> = (next) =>
  next <= 0 ? 0 : next;
const required: ValidatorFn<MyFormState["firstname"]> = (value) =>
  value?.trim() ? undefined : "Required";

export default function App() {
  const onChange: OnChangeFormFn<MyFormState> = (formState) => console.log("ON_CHANGE:", formState);
  const onSubmit: OnSubmitFormFn<MyFormState> = (formState) => console.log("ON_SUBMIT:", formState);
  const [status, validation] = useValidation([required]);

  return (
    <Form<MyFormState> onSubmit={onSubmit} onChange={onChange}>
      <Input name="firstname" type="text" touched {...validation} />
      {status.error && <span>{status.error}</span>}
      <Input name="lastname" type="text" />
      <Input name="age" type="number" value={18} reducers={preventNegativeNumber} />
      <button type="submit">Submit</button>
    </Form>
  );
}

:book: Recipes

Accessing form fields outside the Form context

🧱 Step 1: Create a form store

interface FormState { counter: number; }
import { createFormStore } from 'usetheform';

const [formStore, useFormSelector] = createFormStore<FormState>({ counter: 0 });

export const awesomeFormStore = formStore;
export const useAwesomeFormSelector = useFormSelector;

🧩 Step 2: Create your awesome form

import { Form, Input } from 'usetheform';
import { awesomeFormStore } from './awesomeFormStore';


export default function AwesomeForm() {
  return (
    <>
      <Form<FormState> formStore={awesomeFormStore}>
        <Input type="number" name="counter" value="0" placeholder="Counter" />
      </Form>
      <Counter />
    </>
  );
}

πŸ”Œ Step 3: Connect your components

import { useAwesomeFormSelector } from './awesomeFormStore';

export const Counter = () => {
  const [counter, setCounterValue] = useAwesomeFormSelector<"counter">((state) => state.counter);
  return (
    <div>
      <span>{counter}</span>
      <button onClick={() => setCounterValue(prev => ++prev)}>Increase</button>
      <button onClick={() => setCounterValue(prev => --prev)}>Decrease</button>
      <button onClick={() => setCounterValue(0)}>Reset</button>
    </div>
  );
};

:brain: Motivation

Usetheform was created to provide a highly flexible, declarative way to handle forms in React with no dependencies. It supports:

  • Nested field structures
  • Synchronous & asynchronous validation
  • Custom input and reducer logic
  • Schema-based validation
  • Tiny footprint

If you find this library useful, please ⭐ the repo. It means a lot! πŸ™

πŸ‘€ Author

⭐ Stargazers

Stargazers repo roster

Code Sandboxes

How to Contribute

πŸŽ‰ Thanks for considering contributing! Please read our CONTRIBUTING.md for guidelines.

πŸ“„ License

This project is licensed under the MIT License. See the LICENSE file for details.