{"id":13450512,"url":"https://github.com/j-a-y-h/react-uniformed","last_synced_at":"2025-03-23T16:31:38.037Z","repository":{"id":35059399,"uuid":"201851326","full_name":"j-a-y-h/react-uniformed","owner":"j-a-y-h","description":"Declarative React Forms","archived":false,"fork":false,"pushed_at":"2023-01-07T08:38:31.000Z","size":2540,"stargazers_count":6,"open_issues_count":11,"forks_count":2,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2024-05-13T20:04:26.136Z","etag":null,"topics":["form","form-validation","react","react-form","react-form-validation","react-hooks","react-uniformed","reactjs"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/j-a-y-h.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-12T03:28:32.000Z","updated_at":"2022-08-20T10:51:35.000Z","dependencies_parsed_at":"2023-01-15T13:01:23.210Z","dependency_job_id":null,"html_url":"https://github.com/j-a-y-h/react-uniformed","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j-a-y-h%2Freact-uniformed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j-a-y-h%2Freact-uniformed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j-a-y-h%2Freact-uniformed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/j-a-y-h%2Freact-uniformed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/j-a-y-h","download_url":"https://codeload.github.com/j-a-y-h/react-uniformed/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221856412,"owners_count":16892438,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["form","form-validation","react","react-form","react-form-validation","react-hooks","react-uniformed","reactjs"],"created_at":"2024-07-31T07:00:35.465Z","updated_at":"2024-10-28T16:31:23.193Z","avatar_url":"https://github.com/j-a-y-h.png","language":"TypeScript","funding_links":[],"categories":["Packages"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\u003cp align=\"center\"\u003e\n\u003ch1\u003ereact-uniformed\u003c/h1\u003e\n\u003cb\u003eYou shouldn't have to learn a library’s ridiculously complex API in order to do React forms.\u003c/b\u003e\u003c/u\u003e\u003c/i\u003e\u003cbr/\u003e\u003cbr/\u003e\n\n[![travis](https://travis-ci.com/j-a-y-h/react-uniformed.svg?branch=develop)](https://travis-ci.com/j-a-y-h/react-uniformed.svg?branch=develop)\n[![Downloads](https://img.shields.io/npm/dt/react-uniformed.svg?style=flat)](https://img.shields.io/npm/dt/react-uniformed.svg?style=flat)\n[![Coverage Status](https://coveralls.io/repos/github/j-a-y-h/react-uniformed/badge.svg?branch=develop)](https://coveralls.io/github/j-a-y-h/react-uniformed?branch=develop)\n[![license](https://badgen.now.sh/badge/license/MIT)](./LICENSE)\n[![npm](https://badgen.net/bundlephobia/minzip/react-uniformed)](https://badgen.net/bundlephobia/minzip/react-uniformed)\n\n\u003c/p\u003e\u003c/div\u003e\n\n**react-uniformed** allows you to easily create declarative React forms using only React Hooks. The simplicity of this library removes the pain of remembering another complex React library, allowing you to focus on your app's business logic. We built this library with exceptional performance so that you can maintain a great user experience regardless of your application's scale - [try the performance story](https://github.com/j-a-y-h/react-uniformed/blob/develop/stories).\n\n##### Overview\n\n- ‍️💆🏾‍♂️ Simple API\n- 🙅🏻‍♀️ Zero dependencies\n- 📜 HTML standard validation\n- 🚀 Controlled \u0026 Uncontrolled inputs support\n\n##### Documentation\n\n- [API Reference](https://github.com/j-a-y-h/react-uniformed/blob/develop/docs/README.md)\n- [Quick Start](#quick-start)\n- [Validation](#validation)\n- [Performance](#performance)\n\n##### Examples\n\n- [codesandbox.io](https://codesandbox.io/s/react-uniformed-nwj10)\n- [Storybook](https://github.com/j-a-y-h/react-uniformed/blob/develop/stories)\n- [Code Examples](https://github.com/j-a-y-h/react-uniformed/blob/develop/examples/)\n\n## Install\n\nNPM\n\n```shell\nnpm install --save react-uniformed\n```\n\nYarn\n\n```shell\nyarn add react-uniformed\n```\n\n## Quick Start\n\n```javascript\nimport React from 'react';\nimport { useForm, useSettersAsEventHandler } from 'react-uniformed';\n\n// useForm holds the state of the form (eg touches, values, errors)\nconst { setValue, values, submit } = useForm({\n  onSubmit: (data) =\u003e console.log(JSON.stringify(data)),\n});\n\n// compose your event handlers\nconst handleChange = useSettersAsEventHandler(setValue);\n\n// jsx\n\u003cform onSubmit={submit}\u003e\n  \u003clabel\u003eName\u003c/label\u003e\n  \u003cinput name='name' value={values.name} onChange={handleChange} /\u003e\n\n  \u003cbutton\u003eSubmit\u003c/button\u003e\n\u003c/form\u003e;\n```\n\n## Validation\n\nAdd validation to your form by setting the `validators` property in `useForm` and start validation by calling `validateByName` or `validate`. Then read the validation state from the `errors` object.\n\n```javascript\nimport { useForm, useSettersAsEventHandler } from 'react-uniformed';\n\nconst { setValue, validateByName, errors } = useForm({\n  // Declarative HTML5 style form validation\n  constraints: {\n    name: { required: true, minLength: 1, maxLength: 55 },\n    // email \u0026 url types are validated using HTML standard regex\n    email: { type: 'email' },\n    date: {\n      // set the error message for required by using a non empty string\n      required: 'Date is required',\n      type: 'date',\n      // set the error message and constraint using an array\n      min: [Date.now(), 'Date must be today or later'],\n    },\n  },\n  // the onSubmit function is only called after the form passes validation.\n  onSubmit: (data) =\u003e console.log(JSON.stringify(data)),\n});\n\n// No configs for when to validate the form because useSettersAsEventHandler\n// allows you to configure your event handlers how ever you want to.\n\n// validate on change\n// const handleChange = useSettersAsEventHandler(setValue, validateByName);\n// validate on blur\nconst handleBlur = useSettersAsEventHandler(validateByName);\n```\n\n## Performance\n\n**react-uniformed** supports uncontrolled inputs that uses React refs to synchronize the state of the input in the DOM and the state of the form in the Virtual DOM. The uncontrolled input allows us to avoid expensive React renders on keyup or change.\n\n```javascript\nimport { useSettersAsRefEventHandler } from 'react-uniformed';\n\n// useSettersAsRefEventHandler defaults to an on change event\nconst changeRef = useSettersAsRefEventHandler(setValue);\n\n// name attribute is still required as the changeRef calls setValue(name, value) on change\n\u003cinput name='name' ref={changeRef} /\u003e;\n```\n\n`useSettersAsRefEventHandler` is generally only needed for larger forms or larger React VDOMs. In addition to the `useSettersAsRefEventHandler`, **react-uniformed** also supports validation maps. Validation maps allows you to only validate the input that changed using `validateByName`. There are several ways to accomplish this...\n\n```javascript\nconst { validateByName, errors } = useForm({\n  validators: {\n    // validators must return empty string for valid values\n    name: (value) =\u003e (value ? '' : 'email is required'),\n  },\n});\n\n// useConstraints supports mixing validators and constraints\nconst validators = useConstraints({\n  name: (value) =\u003e \"name still won't be valid\",\n  email: { required: true },\n});\n\n// when used with useSettersAsEventHandler the validator\n// will call the validation that matches the current input element's name\nconst handleBlur = useSettersAsEventHandler(validateByName);\n```\n\nIf you prefer to validate in one function, then you can do that as well\n\n```javascript\nconst {\n  // note: validateByName will call the validate function on each call\n  // but the error will be the one with the corresponding name.\n  validateByName,\n  validate, // validate all values\n} = useForm({\n  validators(values) {\n    const errors = { name: 'name will never be valid', email: '' };\n    if (!values.email) {\n      errors.email = 'email is required';\n    }\n    return errors;\n  },\n});\n```\n\n## More Hooks\n\nIt should be noted that `useForm` is just one layer of abstraction used to simplify the form building process. If you need more granular control and orchestration of your form, then you should avoid using `useForm` in favor of other form hooks like `useFields`, `useTouch`, `useValidation`, and `useSubmission`. The following is a basic implementation of `useForm` that you can use to compose your forms.\n\n```javascript\nimport { useCallback } from 'react';\nimport { useFields, useTouch, useValidation, useHandlers, useSubmission } from 'react-uniformed';\n\nfunction useForm({ onSubmit, validators, constraints }) {\n  // tracks the input values\n  const { values, setValue, resetValues } = useFields();\n\n  // tracks the touch state of inputs\n  const { touches, touchField, resetTouches, isDirty } = useTouch();\n\n  // handles validation\n  const { validateByName, validate, errors, resetErrors, hasErrors } = useValidation(\n    validators || constraints,\n  ); // this is not the real implementation\n\n  // composes a \"form reset\" function\n  const reset = useHandlers(resetValues, resetErrors, resetTouches);\n\n  // creates a validation handler that binds the values\n  const validator = useCallback(() =\u003e validate(values), [values, validate]);\n\n  // Guards against submissions until all values are valid\n  const { submit } = useSubmission({ onSubmit, validator, values, reset, disabled: hasErrors });\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj-a-y-h%2Freact-uniformed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fj-a-y-h%2Freact-uniformed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fj-a-y-h%2Freact-uniformed/lists"}