{"id":31773754,"url":"https://github.com/byteclaw/forms","last_synced_at":"2026-03-14T02:02:40.412Z","repository":{"id":33453942,"uuid":"158199008","full_name":"Byteclaw/forms","owner":"Byteclaw","description":"📋 Easily built forms in React using Hooks API","archived":false,"fork":false,"pushed_at":"2023-01-04T21:38:48.000Z","size":2450,"stargazers_count":8,"open_issues_count":23,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-09-17T21:48:09.956Z","etag":null,"topics":["forms","hooks","hooks-api-react","library","react","validation","yup-compatibility"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@byteclaw/forms","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/Byteclaw.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2018-11-19T09:57:04.000Z","updated_at":"2021-04-06T19:05:52.000Z","dependencies_parsed_at":"2023-01-15T00:59:16.723Z","dependency_job_id":null,"html_url":"https://github.com/Byteclaw/forms","commit_stats":null,"previous_names":["napred/forms"],"tags_count":44,"template":false,"template_full_name":null,"purl":"pkg:github/Byteclaw/forms","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byteclaw%2Fforms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byteclaw%2Fforms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byteclaw%2Fforms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byteclaw%2Fforms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Byteclaw","download_url":"https://codeload.github.com/Byteclaw/forms/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Byteclaw%2Fforms/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279002686,"owners_count":26083442,"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","status":"online","status_checked_at":"2025-10-10T02:00:06.843Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["forms","hooks","hooks-api-react","library","react","validation","yup-compatibility"],"created_at":"2025-10-10T04:28:33.886Z","updated_at":"2025-10-10T04:28:37.770Z","avatar_url":"https://github.com/Byteclaw.png","language":"TypeScript","readme":"# @byteclaw/forms\n\n[![CircleCI](https://img.shields.io/circleci/project/github/Byteclaw/forms/master.svg?style=flat-square)](https://circleci.com/gh/Byteclaw/forms)\n[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors)\n![Version](https://img.shields.io/npm/v/@byteclaw/forms.svg?style=flat-square)\n![License](https://img.shields.io/npm/l/@byteclaw/forms.svg?style=flat-square)\n\nEasily create complex forms in [React](https://github.com/facebook/react).\n\n- [Installation](#installation)\n- [Yup compatibility](#yup-compatibility)\n- [Requirements](#requirements)\n- [Up and running example](#up-and-running-example)\n- [API](#api)\n  - [Form](#form)\n  - [Field](#field)\n  - [FieldError](#fielderror)\n  - [ArrayField](#arrayfield)\n  - [ObjectField](#objectfield)\n  - [ValidationError](#validationerror)\n  - [useArrayField](#usearrayfield)\n  - [useDebouncedCallback](#usedebouncedcallback)\n  - [useError](#useerror)\n  - [useField](#usefield)\n  - [useForm](#useform)\n  - [useFormState](#useformstate)\n  - [useObjectField](#useobjectfield)\n  - [useParentField](#useparentfield)\n  - [useValues](#usevalues)\n  - [createValidatorFromYup](#createvalidatorfromyup)\n  - [validationErrorFromYupError](#validationerrorfromyuperror)\n- [Examples](#examples)\n- [Contributions](#contributions)\n\n## Installation\n\n```console\nnpm install @byteclaw/forms\n\n# or using yarn\n\nyarn add @byteclaw/forms\n```\n\n## Yup compatibility\n\nThis library supports [Yup](https://github.com/jquense/yup) validation library. In order to use it please install [Yup](https://github.com/jquense/yup) because it isn't a part of this library.\n\n## Requirements\n\n- `react \u003e= 16.8.3`\n\n## Up and running example\n\n```js\nimport { Fragment } from 'react';\nimport {\n  ArrayField,\n  Field,\n  Form,\n  FormProvider,\n  ObjectField,\n  createValidatorFromYup,\n} from '@byteclaw/forms';\nimport * as yup from 'yup';\n\nconst validator = createValidatorFromYup(\n  yup.object().shape({\n    productTitle: yup.string().required(),\n    images: yup\n      .array()\n      .of(\n        yup.object().shape({\n          title: yup.string().required(),\n          url: yup\n            .string()\n            .url()\n            .required(),\n        }),\n      )\n      .required(),\n    attributes: yup.object().shape({\n      color: yup\n        .string()\n        .matches(/^#[0-9a-fA-F]{6}$/)\n        .required(),\n    }),\n  }),\n);\n\n\u003cForm onSubmit={async values =\u003e {}} onValidate={validator}\u003e\n  {/* global error of form */}\n  \u003cFieldError\u003e{({ error }) =\u003e error || null}\u003c/FieldError\u003e\n  \u003cField name=\"productTitle\" /\u003e\n  \u003cFieldError name=\"productTitle\"\u003e{({ error }) =\u003e error || null}\u003c/FieldError\u003e\n  \u003cArrayField name=\"images\"\u003e\n    {({ value }, dispatch) =\u003e (\n      \u003cFragment\u003e\n        {/* value can be undefined/null if is not initialized */}\n        {(value || []).map((val, i) =\u003e (\n          \u003cObjectField name={i}\u003e\n            \u003cField name=\"url\" type=\"url\" /\u003e\n            \u003cFieldError name=\"url\"\u003e{({ error }) =\u003e error || null}\u003c/FieldError\u003e\n            \u003cField name=\"title\" /\u003e\n            \u003cFieldError name=\"title\"\u003e{({ error }) =\u003e error || null}\u003c/FieldError\u003e\n            \u003cbutton onClick={() =\u003e removeItem(i)} type=\"button\"\u003e\n              Remove\n            \u003c/button\u003e\n          \u003c/ObjectField\u003e\n        ))}\n        \u003cbutton onClick={() =\u003e dispatch({ type: 'CHANGE', value: [...value, {}] })} type=\"button\"\u003e\n          Add image\n        \u003c/button\u003e\n      \u003c/Fragment\u003e\n    )}\n  \u003c/ArrayField\u003e\n  \u003cFieldError name=\"images\"\u003e{({ error }) =\u003e error || null}\u003c/FieldError\u003e\n  \u003cObjectField name=\"attributes\"\u003e\n    \u003cField name=\"color\" /\u003e\n    \u003cFieldError name=\"color\"\u003e{({ error }) =\u003e error || null}\u003c/FieldError\u003e\n  \u003c/ObjectField\u003e\n  \u003cFieldError name=\"attributes\"\u003e{({ error }) =\u003e error || null}\u003c/FieldError\u003e\n  \u003cFormProvider\u003e\n    {form =\u003e (\n      \u003cbutton disabled={form.status !== 'IDLE'} type=\"submit\"\u003e\n        Save\n      \u003c/button\u003e\n    )}\n  \u003c/FormProvider\u003e\n\u003c/Form\u003e;\n```\n\n## API\n\n### [Form](./src/components/Form.tsx)\n\n`Form` component is a root component necessary to use Forms at all. It provides a context for all fields in a given form.\n\nForm accepts `onValidate`, `onSubmit` and `validateOnChange` props along with standard attributes accepted by `\u003cform /\u003e`.\n\n- `onValidate\u003cTValues\u003e(values?: TValues): Promise\u003cTValues | void\u003e`\n  - optional validation function\n  - in case of an error please throw [`ValidationError`](#validation-error) provided by this library\n- `onSubmit\u003cTValues\u003e(values: TValues): Promise\u003cvoid\u003e`\n  - optional submit function\n  - it can validate form too, in case of an error throw [`ValidationError`](#validation-error) provided by this library\n- `onChange\u003cTValues\u003e(values: TValues): Promise\u003cvoid\u003e`\n  - optional on change function\n- `validateOnChange`\n  - default is `false`\n  - optional\n  - will validate form on change\n\n### [FormProvider](./src/components/FormProvider.ts)\n\n`FormProvider` is a way to connect to `FormState` when you need to react on something.\n\n- `children: (state: FormState) =\u003e any`\n\n### [Field](./src/components/Field.ts)\n\n`Field` is a base component to construct simple widgets using `\u003cinput /\u003e` elements. On change is debounced.\n\n### [FieldError](./src/components/FieldError.ts)\n\n`FieldError` is a base component if you want to render validation errors that are connected with a specific field or a form root.\n\nTo connect to a root of ObjectField/ArrayField/Form use it like this:\n\n```jsx\n\u003cFieldError name=\"\"\u003e{err =\u003e JSON.stringify(err, null, ' ')}\u003cFieldError\u003e\n```\n\nOr specify `name` as a name that was used by `Field` component.\n\n### [ArrayField](./src/components/ArrayField.tsx)\n\n`ArrayField` is a base component to construct complex fields for array values.\n\n### [ObjectField](./src/components/ObjectField.tsx)\n\n`ObjectField` is a base component to construct nested objects in your form.\n\n### [ValidationError](./src/components/ValidationError.ts)\n\n`ValidationError` is a way how to map errors to fields in your form.\n\n### [useArrayField](./src/hooks/useArrayField.ts)\n\n### [useDebouncedCallback](./src/hooks/useDebouncedCallback.ts)\n\n### [useError](./src/hooks/useError.ts)\n\n### [useForm](./src/hooks/useForm.ts)\n\n### [useField](./src/hooks/useField.ts)\n\n### [useFormState](./src/hooks/useFormState.ts)\n\n### [useObjectField](./src/hooks/useObjectField.ts)\n\n### [useParentField](./src/hooks/useParentField.ts)\n\n### [useValues](./src/hooks/useValues.ts)\n\n### [createValidationErrorFromYup](./src/utils/createValidationErrorFromYup.ts)\n\n### [validationErrorFromYupError](./src/utils/validationErrorFromYupError.ts)\n\n## Examples\n\n- [Simple Form](./examples/SimpleForm.md)\n\n## Contributors\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore --\u003e\n| [\u003cimg src=\"https://avatars1.githubusercontent.com/u/174716?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMichal Kvasničák\u003c/b\u003e\u003c/sub\u003e](https://github.com/michalkvasnicak)\u003cbr /\u003e[💬](#question-michalkvasnicak \"Answering Questions\") [💻](https://github.com/byteclaw/@byteclaw/forms/commits?author=michalkvasnicak \"Code\") [🎨](#design-michalkvasnicak \"Design\") [📖](https://github.com/byteclaw/@byteclaw/forms/commits?author=michalkvasnicak \"Documentation\") [💡](#example-michalkvasnicak \"Examples\") [🤔](#ideas-michalkvasnicak \"Ideas, Planning, \u0026 Feedback\") [👀](#review-michalkvasnicak \"Reviewed Pull Requests\") [⚠️](https://github.com/byteclaw/@byteclaw/forms/commits?author=michalkvasnicak \"Tests\") | [\u003cimg src=\"https://avatars1.githubusercontent.com/u/373788?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJuraj Hríb\u003c/b\u003e\u003c/sub\u003e](https://github.com/jurajhrib)\u003cbr /\u003e[💬](#question-jurajhrib \"Answering Questions\") [🐛](https://github.com/byteclaw/@byteclaw/forms/issues?q=author%3Ajurajhrib \"Bug reports\") [💻](https://github.com/byteclaw/@byteclaw/forms/commits?author=jurajhrib \"Code\") [📖](https://github.com/byteclaw/@byteclaw/forms/commits?author=jurajhrib \"Documentation\") [🤔](#ideas-jurajhrib \"Ideas, Planning, \u0026 Feedback\") [👀](#review-jurajhrib \"Reviewed Pull Requests\") |\n| :---: | :---: |\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!\n\n## License\n\nMIT License\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyteclaw%2Fforms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyteclaw%2Fforms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyteclaw%2Fforms/lists"}