{"id":21517868,"url":"https://github.com/form-atoms/form-atoms","last_synced_at":"2025-08-21T15:40:55.807Z","repository":{"id":40568178,"uuid":"459223027","full_name":"form-atoms/form-atoms","owner":"form-atoms","description":"Atomic form primitives for Jotai","archived":false,"fork":false,"pushed_at":"2024-10-04T17:34:26.000Z","size":451,"stargazers_count":92,"open_issues_count":3,"forks_count":6,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-28T03:03:54.693Z","etag":null,"topics":["atomic-form","form-hooks","form-library","forms","jotai","jotai-form","jotai-forms","react","react-form","react-form-library","react-forms","react-hook-form","react-hooks"],"latest_commit_sha":null,"homepage":"https://codesandbox.io/s/getting-started-with-form-atoms-v2-ddhgq2?file=/src/App.tsx","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/form-atoms.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-14T15:47:39.000Z","updated_at":"2025-03-25T07:47:53.000Z","dependencies_parsed_at":"2022-08-09T23:21:42.734Z","dependency_job_id":"df3fd3d9-63b0-46b6-94a9-3ee63f98e854","html_url":"https://github.com/form-atoms/form-atoms","commit_stats":{"total_commits":78,"total_committers":4,"mean_commits":19.5,"dds":0.5384615384615384,"last_synced_commit":"608e42c7f8f223fe3d36585770ae5a2a6cfb5575"},"previous_names":["jaredlunde/form-atoms"],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/form-atoms%2Fform-atoms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/form-atoms%2Fform-atoms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/form-atoms%2Fform-atoms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/form-atoms%2Fform-atoms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/form-atoms","download_url":"https://codeload.github.com/form-atoms/form-atoms/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247114000,"owners_count":20885854,"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":["atomic-form","form-hooks","form-library","forms","jotai","jotai-form","jotai-forms","react","react-form","react-form-library","react-forms","react-hook-form","react-hooks"],"created_at":"2024-11-24T00:45:40.565Z","updated_at":"2025-04-04T04:07:54.071Z","avatar_url":"https://github.com/form-atoms.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003chr/\u003e\n\n# form-atoms\n\nAtomic form primitives for [Jotai](https://jotai.org/docs/api/core)\n\n```sh\nnpm i form-atoms jotai\n```\n\n\u003ca href=\"https://flexstack.com\"\u003e\u003cimg src=\"https://flexstack.com/images/supported-by-flexstack.svg?v1\" height=\"36\" alt=\"Supported by FlexStack\"\u003e\u003c/a\u003e\n\n\u003chr\u003e\n\n\u003cp\u003e\n  \u003ca href=\"https://bundlephobia.com/result?p=form-atoms\"\u003e\n    \u003cimg alt=\"Bundlephobia\" src=\"https://img.shields.io/bundlephobia/minzip/form-atoms?style=for-the-badge\u0026labelColor=24292e\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"Types\" href=\"https://www.npmjs.com/package/form-atoms\"\u003e\n    \u003cimg alt=\"Types\" src=\"https://img.shields.io/npm/types/form-atoms?style=for-the-badge\u0026labelColor=24292e\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"Code coverage report\" href=\"https://codecov.io/gh/form-atoms/form-atoms\"\u003e\n    \u003cimg alt=\"Code coverage\" src=\"https://img.shields.io/codecov/c/gh/form-atoms/form-atoms?style=for-the-badge\u0026labelColor=24292e\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"Build status\" href=\"https://github.com/form-atoms/form-atoms/actions/workflows/release.yml\"\u003e\n    \u003cimg alt=\"Build status\" src=\"https://img.shields.io/github/actions/workflow/status/form-atoms/form-atoms/release.yml?branch=main\u0026style=for-the-badge\u0026labelColor=24292e\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"NPM version\" href=\"https://www.npmjs.com/package/form-atoms\"\u003e\n    \u003cimg alt=\"NPM Version\" src=\"https://img.shields.io/npm/v/form-atoms?style=for-the-badge\u0026labelColor=24292e\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"License\" href=\"https://jaredlunde.mit-license.org/\"\u003e\n    \u003cimg alt=\"MIT License\" src=\"https://img.shields.io/npm/l/form-atoms?style=for-the-badge\u0026labelColor=24292e\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Features\n\n- [x] **Renders what changes** and nothing else\n- [x] **Strongly typed** allowing you to quickly iterate on durable code\n- [x] **Tiny** ([\u003c3kB gzipped](https://bundlephobia.com/package/form-atoms)) but powerful API\n- [x] **Nested/array fields** without parsing field names\n- [x] **Dynamic fields** - you aren't stuck with your initial config\n- [x] **Controlled inputs** because no, uncontrolled inputs are not preferrable\n- [x] **Ready for concurrent React** - validation updates have a lower priority\n- [x] **Familiar API** that is very similar to other form libraries\n- [x] **Async field-level validation** with [Zod](https://github.com/colinhacks/zod) and [Valibot](https://valibot.dev/) support\n\n## Quick start\n\n[Check out the example on CodeSandbox ↗](https://codesandbox.io/s/getting-started-with-form-atoms-v2-ddhgq2?file=/src/App.tsx)\n\n```js\nimport { fieldAtom, useInputField, formAtom, useForm } from \"form-atoms\";\n\nconst nameFormAtom = formAtom({\n  name: {\n    first: fieldAtom({ value: \"\" }),\n    last: fieldAtom({ value: \"\" }),\n  },\n});\n\nfunction Form() {\n  const { fieldAtoms, submit } = useForm(nameFormAtom);\n  return (\n    \u003cform\n      onSubmit={submit((values) =\u003e {\n        console.log(values);\n      })}\n    \u003e\n      \u003cField label=\"First name\" atom={fieldAtoms.name.first} /\u003e\n      \u003cField label=\"Last name\" atom={fieldAtoms.name.last} /\u003e\n    \u003c/form\u003e\n  );\n}\n\nfunction Field({ label, atom }) {\n  const field = useInputField(atom);\n  return (\n    \u003clabel\u003e\n      \u003cspan\u003e{label}\u003c/span\u003e\n      \u003cinput {...field.props} /\u003e\n    \u003c/label\u003e\n  );\n}\n```\n\n## Concepts\n\n\u003e [Jotai](https://jotai.org/docs/api/core) was born to solve extra re-render\n\u003e issue in React. Extra re-render is a render process that produces the same\n\u003e UI result, with which users won't see any differences.\n\nLike Jotai, this library was built to solve the extra re-render issue with\nReact _Forms_. It takes a bottom-up approach using Jotai's atomic model.\nIn practice that means that [`formAtom()`](#formatom) derives its state from\n[`fieldAtom()`](#fieldatom). For example, validation occurs at the field-level\nrather than the form-level. Normally that would pose a problem for fields with\nvalidation that is dependent on other state or other fields, but using `fieldAtom`'s\n`validate` function allows you to read the value of other atoms.\n\nThe `form-atoms` minimal API is written to be ergonomic and powerful. It _feels_\nlike other form libraries (_even better in my opinion_). You don't lose anything\nby using it, but you gain a ton of performance and without footguns.\n\n## Table of contents\n\n| Field atoms                                         | Description                                                                                                                                                                                          |\n| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [`fieldAtom()`](#fieldatom)                         | An atom that represents a field in a form. It manages state for the field, including the name, value, errors, dirty, validation, and touched state.                                                  |\n| [`useField()`](#usefield)                           | A hook that returns `state` and `actions` of a field atom from `useFieldState`, and `useFieldActions`.                                                                                               |\n| [`useInputField()`](#useinputfield)                 | A hook that returns `props`, `state`, and `actions` of a field atom from `useInputFieldProps`, `useFieldState`, and `useFieldActions`.                                                               |\n| [`useInputFieldProps()`](#useinputfieldprops)       | A hook that returns a set of props that can be destructured directly into an `\u003cinput\u003e`, `\u003cselect\u003e`, or `\u003ctextarea\u003e` element.                                                                         |\n| [`useTextareaField()`](#usetextareafield)           | A hook that returns `props`, `state`, and `actions` of a field atom from `useTextareaFieldProps`, `useFieldState`, and `useFieldActions`.                                                            |\n| [`useTextareaFieldProps()`](#usetextareafieldprops) | A hook that returns a set of props that can be destructured directly into a `\u003ctextarea\u003e` element.                                                                                                    |\n| [`useSelectField()`](#useselectfield)               | A hook that returns `props`, `state`, and `actions` of a field atom from `useSelectFieldProps`, `useFieldState`, and `useFieldActions`.                                                              |\n| [`useSelectFieldProps()`](#useselectfieldprops)     | A hook that returns a set of props that can be destructured directly into a `\u003cselect\u003e` element.                                                                                                      |\n| [`useFieldState()`](#usefieldstate)                 | A hook that returns the state of a field atom. This includes the field's value, whether it has been touched, whether it is dirty, the validation status, and any errors.                             |\n| [`useFieldActions()`](#usefieldactions)             | A hook that returns a set of actions that can be used to interact with the field atom state.                                                                                                         |\n| [`useFieldInitialValue()`](#usefieldinitialvalue)   | A hook that sets the initial value of a field atom. Initial values can only be set once per scope. Therefore, if the initial value used is changed during rerenders, it won't update the atom value. |\n| [`useFieldValue()`](#usefieldvalue)                 | A hook that returns the value of a field atom.                                                                                                                                                       |\n| [`useFieldErrors()`](#usefielderrors)               | A hook that returns the errors of a field atom.                                                                                                                                                      |\n\n| Form atoms                            | Description                                                                                                                                                                                                                                                                                                           |\n| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [`formAtom()`](#formatom)             | An atom that derives its state fields atoms and allows you to submit, validate, and reset your form.                                                                                                                                                                                                                  |\n| [`useForm()`](#useform)               | A hook that returns an object that contains the `fieldAtoms` and actions to validate, submit, and reset the form.                                                                                                                                                                                                     |\n| [`useFormState()`](#useformstate)     | A hook that returns the primary state of the form atom including values, errors, submit and validation status, as well as the `fieldAtoms`. Note that this hook will cuase its parent component to re-render any time those states change, so it can be useful to use more targeted state hooks like `useFormStatus`. |\n| [`useFormActions()`](#useformactions) | A hook that returns a set of actions that can be used to update the state of the form atom. This includes updating fields, submitting, resetting, and validating the form.                                                                                                                                            |\n| [`useFormValues()`](#useformvalues)   | A hook that returns the values of the form atom.                                                                                                                                                                                                                                                                      |\n| [`useFormErrors()`](#useformerrors)   | A hook that returns the errors of the form atom.                                                                                                                                                                                                                                                                      |\n| [`useFormStatus()`](#useformstatus)   | A hook that returns the `submitStatus` and `validateStatus` of the form atom.                                                                                                                                                                                                                                         |\n| [`useFormSubmit()`](#useformsubmit)   | A hook that returns a callback for handling form submission.                                                                                                                                                                                                                                                          |\n\n| Components                          | Description                                                                                                                                                                                              |\n| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| [`\u003cForm\u003e`](#form)                   | A React component that renders form atoms and their fields in an isolated scope using a Jotai Provider.                                                                                                  |\n| [`\u003cInputField\u003e`](#inputfield)       | A React component that renders field atoms with initial values. This is useful for fields that are rendered as native HTML elements because the props can unpack directly into the underlying component. |\n| [`\u003cTextareaField\u003e`](#textareafield) | A React component that renders field atoms with initial values. This is useful for fields that are rendered as native HTML elements because the props can unpack directly into the underlying component. |\n| [`\u003cSelectField\u003e`](#selectfield)     | A React component that renders field atoms with initial values. This is useful for fields that are rendered as native HTML elements because the props can unpack directly into the underlying component. |\n| [`\u003cField\u003e`](#field)                 | A React component that renders field atoms with initial values. This is useful for fields that aren't rendered as native HTML elements.                                                                  |\n\n| Utility Types               | Description                                                                  |\n| --------------------------- | ---------------------------------------------------------------------------- |\n| [`FormValues`](#formvalues) | A utility type for inferring the value types of a form's nested field atoms. |\n| [`FormErrors`](#formerrors) | A utility type for inferring the error types of a form's nested field atoms. |\n\n| Validator                                  | Description                                                                                                |\n| ------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |\n| [`form-atoms/valibot`](#form-atomsvalibot) | A validator that can be used with the [Valibot](https://valibot.dev) library to validate fields.           |\n| [`form-atoms/zod`](#form-atomszod)         | A validator that can be used with the [Zod](https://github.com/colinhacks/zod) library to validate fields. |\n\n## Recipes\n\n1. [**How to validate on `(blur, change, touch, submit)`**](https://codesandbox.io/s/form-atoms-v2-validate-on-event-example-forked-dkge0i?file=/src/App.tsx)\n1. [**How to validate a field conditional to the state of another field**](https://codesandbox.io/s/form-atoms-v2-validate-on-dependent-state-pscr8p?file=/src/App.tsx)\n1. [**How to validate a field asynchronously**](https://codesandbox.io/s/form-atoms-v2-validate-asynchronously-i86wyo?file=/src/App.tsx)\n1. [**How to validate using a Zod schema**](https://codesandbox.io/s/form-atoms-v2-validate-using-zod-1n1rrr?file=/src/App.tsx)\n1. [**How to create a nested fields**](https://codesandbox.io/s/form-atoms-v2-nested-fields-example-lirr6w)\n1. [**How to create an array of fields**](https://codesandbox.io/s/form-atoms-v2-array-fields-example-22kf4d?file=/src/App.tsx)\n\n## Projects using `form-atoms`\n\n- [**@form-atoms/field**](https://github.com/form-atoms/form-atoms-field) - Declarative \u0026 headless form fields build on top of Jotai \u0026 form-atoms\n\n---\n\n## Field atoms\n\n### fieldAtom()\n\nAn atom that represents a field in a form. It manages state for the field,\nincluding the name, value, errors, dirty, validation, and touched state.\n\n#### Arguments\n\n| Name   | Type                                         | Required? | Description                                       |\n| ------ | -------------------------------------------- | --------- | ------------------------------------------------- |\n| config | [`FieldAtomConfig\u003cValue\u003e`](#FieldAtomConfig) | Yes       | The initial state and configuration of the field. |\n\n#### `FieldAtomConfig`\n\n```ts\ntype FieldAtomConfig\u003cValue\u003e = {\n  /**\n   * Optionally provide a name for the field that will be added\n   * to any attached `\u003cinput\u003e`, `\u003cselect\u003e`, or `\u003ctextarea\u003e` elements\n   */\n  name?: string;\n  /**\n   * The initial value of the field\n   */\n  value: Value;\n  /**\n   * The initial touched state of the field\n   */\n  touched?: boolean;\n  /**\n   * Transform the value of the field each time `setValue` is\n   * called and before validation\n   */\n  preprocess?: (value: Value) =\u003e Value;\n  /**\n   * A function that validates the value of the field any time\n   * one of its atoms changes. It must either return an array of\n   * string error messages or undefined. If it returns undefined,\n   * the validation is \"skipped\" and the current errors in state\n   * are retained.\n   */\n  validate?: (state: {\n    /**\n     * A Jotai getter that can read other atoms\n     */\n    get: Getter;\n    /**\n     * The current value of the field\n     */\n    value: Value;\n    /**\n     * The dirty state of the field\n     */\n    dirty: boolean;\n    /**\n     * The touched state of the field\n     */\n    touched: boolean;\n    /**\n     * The event that caused the validation. Either:\n     *\n     * - `\"change\"` - The value of the field has changed\n     * - `\"touch\"` - The field has been touched\n     * - `\"blur\"` - The field has been blurred\n     * - `\"submit\"` - The form has been submitted\n     * - `\"user\"` - A user/developer has triggered the validation\n     */\n    event: ValidateOn;\n  }) =\u003e void | string[] | Promise\u003cvoid | string[]\u003e;\n};\n```\n\n#### Returns\n\n```ts\ntype FieldAtom\u003cValue\u003e = Atom\u003c{\n  /**\n   * An atom containing the field's name\n   */\n  name: WritableAtom\u003c\n    string | undefined,\n    [string | undefined | typeof RESET],\n    void\n  \u003e;\n  /**\n   * An atom containing the field's value\n   */\n  value: WritableAtom\u003c\n    Value,\n    [Value | typeof RESET | ((prev: Value) =\u003e Value)],\n    void\n  \u003e;\n  /**\n   * An atom containing the field's touched status\n   */\n  touched: WritableAtom\u003c\n    boolean,\n    [boolean | typeof RESET | ((prev: boolean) =\u003e boolean)],\n    void\n  \u003e;\n  /**\n   * An atom containing the field's dirty status\n   */\n  dirty: Atom\u003cboolean\u003e;\n  /**\n   * A write-only atom for validating the field's value\n   */\n  validate: WritableAtom\u003cnull, [] | [ValidateOn], void\u003e;\n  /**\n   * An atom containing the field's validation status\n   */\n  validateStatus: WritableAtom\u003cValidateStatus, [ValidateStatus], void\u003e;\n  /**\n   * An atom containing the field's validation errors\n   */\n  errors: WritableAtom\u003c\n    string[],\n    [string[] | ((value: string[]) =\u003e string[])],\n    void\n  \u003e;\n  /**\n   * A write-only atom for resetting the field atoms to their\n   * initial states.\n   */\n  reset: WritableAtom\u003cnull, [], void\u003e;\n  /**\n   * An atom containing a reference to the `HTMLElement` the field\n   * is bound to.\n   */\n  ref: WritableAtom\u003c\n    HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | null,\n    [\n      | HTMLInputElement\n      | HTMLTextAreaElement\n      | HTMLSelectElement\n      | null\n      | ((\n          value:\n            | HTMLInputElement\n            | HTMLTextAreaElement\n            | HTMLSelectElement\n            | null,\n        ) =\u003e HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | null),\n    ],\n    void\n  \u003e;\n}\u003e;\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useField()\n\nA hook that returns `state` and `actions` of a field atom from\n[`useFieldState`](#usefieldstate) and [`useFieldActions`](#usefieldactions).\n\n#### Arguments\n\n| Name      | Type                     | Required? | Description                                                                                                                       |\n| --------- | ------------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------- |\n| fieldAtom | `FieldAtom\u003cValue\u003e`       | Yes       | The atom that stores the field's state                                                                                            |\n| options   | `UseFieldOptions\u003cValue\u003e` | No        | Provide an `initialValue` here in additon to options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks. |\n\n#### Returns\n\n```ts\ntype UseFieldAtom\u003cValue\u003e = {\n  /**\n   * Actions for managing the state of the field\n   */\n  actions: UseFieldActions\u003cValue\u003e;\n  /**\n   * The current state of the field\n   */\n  state: UseFieldState\u003cValue\u003e;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useInputField()\n\nA hook that returns `props`, `state`, and `actions` of a field atom from\n[`useInputFieldProps`](#useinputfieldprops), [`useFieldState`](#usefieldstate),\nand [`useFieldActions`](#usefieldactions).\n\n#### Arguments\n\n| Name      | Type                                | Required? | Description                                                                                                                       |\n| --------- | ----------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |\n| fieldAtom | `FieldAtom\u003cValue\u003e`                  | Yes       | The atom that stores the field's state                                                                                            |\n| options   | `UseInputFieldOptions\u003cType, Value\u003e` | No        | Provide an `initialValue` here in additon to options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks. |\n\n#### Returns\n\n```ts\ntype UseInputField\u003c\n  Type extends React.HTMLInputTypeAttribute,\n  Value extends InputFieldValueForType\u003cType\u003e = InputFieldValueForType\u003cType\u003e,\n\u003e = {\n  /**\n   * `\u003cinput\u003e` props for the field\n   */\n  props: UseInputFieldProps\u003cType\u003e;\n  /**\n   * Actions for managing the state of the field\n   */\n  actions: UseFieldActions\u003cValue\u003e;\n  /**\n   * The current state of the field\n   */\n  state: UseFieldState\u003cValue\u003e;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useInputFieldProps()\n\nA hook that returns a set of props that can be destructured directly into an `\u003cinput\u003e` element.\n\n#### Arguments\n\n| Name      | Type                              | Required? | Description                                                                                                  |\n| --------- | --------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------ |\n| fieldAtom | `FieldAtom\u003cValue\u003e`                | Yes       | The atom that stores the field's state                                                                       |\n| options   | `UseInputFieldPropsOptions\u003cType\u003e` | No        | A `type` field and other options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseInputFieldProps\u003cType extends React.HTMLInputTypeAttribute\u003e = {\n  /**\n   * The name of the field if there is one\n   */\n  name: string | undefined;\n  /**\n   * The value of the field\n   */\n  value: Type extends DateType\n    ? string\n    : Type extends NumberType\n      ? number | string\n      : Type extends FileType\n        ? undefined\n        : string;\n  /**\n   * The type of the field\n   *\n   * @default \"text\"\n   */\n  type: Type;\n  /**\n   * A WAI-ARIA property that tells a screen reader whether the\n   * field is invalid\n   */\n  \"aria-invalid\": boolean;\n  /**\n   * A React callback ref that is used to bind the field atom to\n   * an `\u003cinput\u003e` element so that it can be read and focused.\n   */\n  ref: React.RefCallback\u003cHTMLInputElement\u003e;\n  onBlur(event: React.FormEvent\u003cHTMLInputElement\u003e): void;\n  onChange(event: React.ChangeEvent\u003cHTMLInputElement\u003e): void;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useTextareaField()\n\nA hook that returns `props`, `state`, and `actions` of a field atom from\n[`useTextareaFieldProps`](#usetextareafieldprops), [`useFieldState`](#usefieldstate),\nand [`useFieldActions`](#usefieldactions).\n\n#### Arguments\n\n| Name      | Type                             | Required? | Description                                                                                                                       |\n| --------- | -------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |\n| fieldAtom | `FieldAtom\u003cValue\u003e`               | Yes       | The atom that stores the field's state                                                                                            |\n| options   | `UseTextareaFieldOptions\u003cValue\u003e` | No        | Provide an `initialValue` here in additon to options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks. |\n\n#### Returns\n\n```ts\ntype UseTextareaField\u003cValue extends string\u003e = {\n  /**\n   * `\u003cinput\u003e` props for the field\n   */\n  props: UseTextareaFieldProps\u003cValue\u003e;\n  /**\n   * Actions for managing the state of the field\n   */\n  actions: UseFieldActions\u003cValue\u003e;\n  /**\n   * The current state of the field\n   */\n  state: UseFieldState\u003cValue\u003e;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useTextareaFieldProps()\n\nA hook that returns a set of props that can be destructured directly into a `\u003ctextarea\u003e` element.\n\n#### Arguments\n\n| Name      | Type                           | Required? | Description                                                                                                  |\n| --------- | ------------------------------ | --------- | ------------------------------------------------------------------------------------------------------------ |\n| fieldAtom | `FieldAtom\u003cValue\u003e`             | Yes       | The atom that stores the field's state                                                                       |\n| options   | `UseTextareaFieldPropsOptions` | No        | A `type` field and other options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseTextareaFieldProps\u003cValue extends string\u003e = {\n  /**\n   * The name of the field if there is one\n   */\n  name: string | undefined;\n  /**\n   * The value of the field\n   */\n  value: Value;\n  /**\n   * A WAI-ARIA property that tells a screen reader whether the\n   * field is invalid\n   */\n  \"aria-invalid\": boolean;\n  /**\n   * A React callback ref that is used to bind the field atom to\n   * an `\u003cinput\u003e` element so that it can be read and focused.\n   */\n  ref: React.RefCallback\u003cHTMLTextAreaElement\u003e;\n  onBlur(event: React.FormEvent\u003cHTMLTextAreaElement\u003e): void;\n  onChange(event: React.ChangeEvent\u003cHTMLTextAreaElement\u003e): void;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useSelectField()\n\nA hook that returns `props`, `state`, and `actions` of a field atom from\n[`useSelectFieldProps`](#usetextareafieldprops), [`useFieldState`](#usefieldstate),\nand [`useFieldActions`](#usefieldactions).\n\n#### Arguments\n\n| Name      | Type                                     | Required? | Description                                                                                                                       |\n| --------- | ---------------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------- |\n| fieldAtom | `FieldAtom\u003cValue\u003e`                       | Yes       | The atom that stores the field's state                                                                                            |\n| options   | `UseSelectFieldOptions\u003cValue, Multiple\u003e` | No        | Provide an `initialValue` here in additon to options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks. |\n\n#### Returns\n\n```ts\ntype UseSelectField\u003c\n  Value extends string,\n  Multiple extends Readonly\u003cboolean\u003e = false,\n\u003e = {\n  /**\n   * `\u003cinput\u003e` props for the field\n   */\n  props: UseSelectFieldProps\u003cValue, Multiple\u003e;\n  /**\n   * Actions for managing the state of the field\n   */\n  actions: UseFieldActions\u003cMultiple extends true ? Value[] : Value\u003e;\n  /**\n   * The current state of the field\n   */\n  state: UseFieldState\u003cMultiple extends true ? Value[] : Value\u003e;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useSelectFieldProps()\n\nA hook that returns a set of props that can be destructured directly into a `\u003cselect\u003e` element.\n\n#### Arguments\n\n| Name      | Type                                   | Required? | Description                                                                                                  |\n| --------- | -------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------ |\n| fieldAtom | `FieldAtom\u003cValue\u003e`                     | Yes       | The atom that stores the field's state                                                                       |\n| options   | `UseSelectFieldPropsOptions\u003cMultiple\u003e` | No        | A `type` field and other options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseSelectFieldProps\u003c\n  Value extends string,\n  Multiple extends Readonly\u003cboolean\u003e = false,\n\u003e = {\n  /**\n   * The name of the field if there is one\n   */\n  name: string | undefined;\n  /**\n   * The value of the field\n   */\n  value: Multiple extends true ? Value[] : Value;\n  /**\n   * Whether the field is a multiple select\n   */\n  multiple?: Multiple;\n  /**\n   * A WAI-ARIA property that tells a screen reader whether the\n   * field is invalid\n   */\n  \"aria-invalid\": boolean;\n  /**\n   * A React callback ref that is used to bind the field atom to\n   * an `\u003cinput\u003e` element so that it can be read and focused.\n   */\n  ref: React.RefCallback\u003cHTMLSelectElement\u003e;\n  onBlur(event: React.FormEvent\u003cHTMLSelectElement\u003e): void;\n  onChange(event: React.ChangeEvent\u003cHTMLSelectElement\u003e): void;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFieldState()\n\nA hook that returns the state of a field atom. This includes the field's value, whether it has been touched, whether it is dirty, the validation status, and any errors.\n\n#### Arguments\n\n| Name      | Type               | Required? | Description                                                                         |\n| --------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| fieldAtom | `FieldAtom\u003cValue\u003e` | Yes       | The atom that stores the field's state                                              |\n| options   | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFieldState\u003cValue\u003e = {\n  /**\n   * The value of the field\n   */\n  value: ExtractAtomValue\u003cExtractAtomValue\u003cFieldAtom\u003cValue\u003e\u003e[\"value\"]\u003e;\n  /**\n   * The touched state of the field\n   */\n  touched: ExtractAtomValue\u003cExtractAtomValue\u003cFieldAtom\u003cValue\u003e\u003e[\"touched\"]\u003e;\n  /**\n   * The dirty state of the field. A field is \"dirty\" if it's value has\n   * been changed.\n   */\n  dirty: ExtractAtomValue\u003cExtractAtomValue\u003cFieldAtom\u003cValue\u003e\u003e[\"dirty\"]\u003e;\n  /**\n   * The validation status of the field\n   */\n  validateStatus: ExtractAtomValue\u003c\n    ExtractAtomValue\u003cFieldAtom\u003cValue\u003e\u003e[\"validateStatus\"]\n  \u003e;\n  /**\n   * The error state of the field\n   */\n  errors: ExtractAtomValue\u003cExtractAtomValue\u003cFieldAtom\u003cValue\u003e\u003e[\"errors\"]\u003e;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFieldActions()\n\nA hook that returns a set of actions that can be used to interact with the field atom state.\n\n#### Arguments\n\n| Name      | Type               | Required? | Description                                                                         |\n| --------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| fieldAtom | `FieldAtom\u003cValue\u003e` | Yes       | The atom that stores the field's state                                              |\n| options   | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFieldActions\u003cValue\u003e = {\n  /**\n   * A function that validates the field's value with a `\"user\"` validation\n   * event.\n   */\n  validate(): void;\n  /**\n   * A function for changing the value of a field. This will trigger a `\"change\"`\n   * validation event.\n   *\n   * @param {Value} value - The new value of the field\n   */\n  setValue(\n    value: ExtractAtomArgs\u003cExtractAtomValue\u003cFieldAtom\u003cValue\u003e\u003e[\"value\"]\u003e[0],\n  ): void;\n  /**\n   * A function for changing the touched state of a field. This will trigger a\n   * `\"touch\"` validation event.\n   *\n   * @param {boolean} touched - The new touched state of the field\n   */\n  setTouched(\n    touched: ExtractAtomArgs\u003cExtractAtomValue\u003cFieldAtom\u003cValue\u003e\u003e[\"touched\"]\u003e[0],\n  ): void;\n  /**\n   * A function for changing the error state of a field\n   *\n   * @param {string[]} errors - The new error state of the field\n   */\n  setErrors(\n    errors: ExtractAtomArgs\u003cExtractAtomValue\u003cFieldAtom\u003cValue\u003e\u003e[\"errors\"]\u003e[0],\n  ): void;\n  /**\n   * Focuses the field atom's `\u003cinput\u003e`, `\u003cselect\u003e`, or `\u003ctextarea\u003e` element\n   * if there is one bound to it.\n   */\n  focus(): void;\n  /**\n   * Resets the field atom to its initial state.\n   */\n  reset(): void;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFieldInitialValue()\n\nA hook that sets the initial value of a field atom. Initial values can only be set\nonce per scope. Therefore, if the initial value used is changed during rerenders,\nit won't update the atom value.\n\n#### Arguments\n\n| Name         | Type               | Required? | Description                                                                                 |\n| ------------ | ------------------ | --------- | ------------------------------------------------------------------------------------------- |\n| fieldAtom    | `FieldAtom\u003cValue\u003e` | Yes       | The atom that stores the field's state                                                      |\n| initialValue | `Value`            | No        | The initial value to set the atom to. If this is `undefined`, no initial value will be set. |\n| options      | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks         |\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFieldValue()\n\nA hook that returns the value of a field atom.\n\n#### Arguments\n\n| Name      | Type               | Required? | Description                                                                         |\n| --------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| fieldAtom | `FieldAtom\u003cValue\u003e` | Yes       | The atom that stores the field's state                                              |\n| options   | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFieldValue\u003cValue\u003e = Value;\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFieldErrors()\n\nA hook that returns the errors of a field atom.\n\n#### Arguments\n\n| Name      | Type               | Required? | Description                                                                         |\n| --------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| fieldAtom | `FieldAtom\u003cValue\u003e` | Yes       | The atom that stores the field's state                                              |\n| options   | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFieldErrors\u003cValue\u003e = UseFieldState\u003cValue\u003e[\"errors\"];\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n## Form atoms\n\n### formAtom()\n\nAn atom that derives its state fields atoms and allows you to submit,\nvalidate, and reset your form.\n\n#### Arguments\n\n| Name   | Type                            | Required? | Description                                                                                                          |\n| ------ | ------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------- |\n| fields | [`FormFields`](#formatomfields) | Yes       | An object containing field atoms to be included in the form. Field atoms can be deeply nested in objects and arrays. |\n\n#### `FormFields`\n\n```ts\ntype FormFields = {\n  [key: string | number]:\n    | FieldAtom\u003cany\u003e\n    | FormFields\n    | FormFields[]\n    | FieldAtom\u003cany\u003e[];\n};\n```\n\n#### Returns\n\n```ts\ntype FormAtom\u003cFields extends FormFields\u003e = Atom\u003c{\n  /**\n   * An atom containing an object of nested field atoms\n   */\n  fields: WritableAtom\u003c\n    Fields,\n    Fields | typeof RESET | ((prev: Fields) =\u003e Fields),\n    void\n  \u003e;\n  /**\n   * An read-only atom that derives the form's values from\n   * its nested field atoms.\n   */\n  values: Atom\u003cFormFieldValues\u003cFields\u003e\u003e;\n  /**\n   * An read-only atom that derives the form's errors from\n   * its nested field atoms.\n   */\n  errors: Atom\u003cFormFieldErrors\u003cFields\u003e\u003e;\n  /**\n   * A read-only atom that returns `true` if any of the fields in\n   * the form are dirty.\n   */\n  dirty: Atom\u003cboolean\u003e;\n  /**\n   * A read-only atom derives the touched state of its nested field atoms.\n   */\n  touchedFields: Atom\u003cTouchedFields\u003cFields\u003e\u003e;\n  /**\n   * A write-only atom that resets the form's nested field atoms\n   */\n  reset: WritableAtom\u003cnull, void\u003e;\n  /**\n   * A write-only atom that validates the form's nested field atoms\n   */\n  validate: WritableAtom\u003cnull, void | ValidateOn\u003e;\n  /**\n   * A read-only atom that derives the form's validation status\n   */\n  validateStatus: Atom\u003cValidateStatus\u003e;\n  /**\n   * A write-only atom for submitting the form\n   */\n  submit: WritableAtom\u003c\n    null,\n    (values: FormFieldValues\u003cFields\u003e) =\u003e void | Promise\u003cvoid\u003e\n  \u003e;\n  /**\n   * A read-only atom that reads the number of times the form has\n   * been submitted\n   */\n  submitCount: Atom\u003cnumber\u003e;\n  /**\n   * An atom that contains the form's submission status\n   */\n  submitStatus: WritableAtom\u003cSubmitStatus, SubmitStatus\u003e;\n}\u003e;\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useForm()\n\nA hook that returns an object that contains the `fieldAtoms` and actions to validate, submit, and reset the form.\n\n#### Arguments\n\n| Name     | Type               | Required? | Description                                                                         |\n| -------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| formAtom | `FormAtom\u003cFields\u003e` | Yes       | The atom that stores the form's state                                               |\n| options  | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFormAtom\u003cFields extends FormFields\u003e = {\n  /**\n   * An object containing the values of a form's nested field atoms\n   */\n  fieldAtoms: Fields;\n  /**\n   * A function for handling form submissions.\n   *\n   * @param handleSubmit - A function that is called with the form's values\n   *   when the form is submitted\n   */\n  submit(\n    handleSubmit: (values: FormFieldValues\u003cFields\u003e) =\u003e void | Promise\u003cvoid\u003e,\n  ): (e?: React.FormEvent\u003cHTMLFormElement\u003e) =\u003e void;\n  /**\n   * A function that validates the form's nested field atoms with a\n   * `\"user\"` validation event.\n   */\n  validate(): void;\n  /**\n   * A function that resets the form's nested field atoms to their\n   * initial states.\n   */\n  reset(): void;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFormState()\n\nA hook that returns the primary state of the form atom including values, errors, submit and validation status, as well as the `fieldAtoms`. Note that this hook will cuase its parent component to re-render any time those states change, so it can be useful to use more targeted state hooks like `useFormStatus`.\n\n#### Arguments\n\n| Name     | Type               | Required? | Description                                                                         |\n| -------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| formAtom | `FormAtom\u003cFields\u003e` | Yes       | The atom that stores the form's state                                               |\n| options  | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFormState\u003cFields extends FormFields\u003e = {\n  /**\n   * An object containing the form's nested field atoms\n   */\n  fieldAtoms: Fields;\n  /**\n   * An object containing the values of a form's nested field atoms\n   */\n  values: FormFieldValues\u003cFields\u003e;\n  /**\n   * An object containing the errors of a form's nested field atoms\n   */\n  errors: FormFieldErrors\u003cFields\u003e;\n  /**\n   * `true` if any of the fields in the form are dirty.\n   */\n  dirty: boolean;\n  /**\n   * An object containing the touched state of the form's nested field atoms.\n   */\n  touchedFields: TouchedFields\u003cFields\u003e;\n  /**\n   * The number of times a form has been submitted\n   */\n  submitCount: number;\n  /**\n   * The validation status of the form\n   */\n  validateStatus: ValidateStatus;\n  /**\n   * The submission status of the form\n   */\n  submitStatus: SubmitStatus;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFormActions()\n\nA hook that returns a set of actions that can be used to update the state of the form atom. This includes updating fields, submitting, resetting, and validating the form.\n\n#### Arguments\n\n| Name     | Type               | Required? | Description                                                                         |\n| -------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| formAtom | `FormAtom\u003cFields\u003e` | Yes       | The atom that stores the form's state                                               |\n| options  | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFormActions\u003cFields extends FormFields\u003e = {\n  /**\n   * A function for adding/removing fields from the form.\n   *\n   * @param fields - An object containing the form's nested field atoms or\n   *   a callback that receives the current fields and returns the next\n   *   fields.\n   */\n  updateFields(\n    fields: ExtractAtomArgs\u003cExtractAtomValue\u003cFormAtom\u003cFields\u003e\u003e[\"fields\"]\u003e[0],\n  ): void;\n  /**\n   * A function for handling form submissions.\n   *\n   * @param handleSubmit - A function that is called with the form's values\n   *   when the form is submitted\n   */\n  submit(\n    handleSubmit: (values: FormFieldValues\u003cFields\u003e) =\u003e void | Promise\u003cvoid\u003e,\n  ): (e?: React.FormEvent\u003cHTMLFormElement\u003e) =\u003e void;\n  /**\n   * A function that validates the form's nested field atoms with a\n   * `\"user\"` validation event.\n   */\n  validate(): void;\n  /**\n   * A function that resets the form's nested field atoms to their\n   * initial states.\n   */\n  reset(): void;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFormValues()\n\nA hook that returns the values of the form atom.\n\n#### Arguments\n\n| Name     | Type               | Required? | Description                                                                         |\n| -------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| formAtom | `FormAtom\u003cFields\u003e` | Yes       | The atom that stores the form's state                                               |\n| options  | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFormValues\u003cFields extends FormFields\u003e = FormFieldValues\u003cFields\u003e;\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFormErrors()\n\nA hook that returns the errors of the form atom.\n\n#### Arguments\n\n| Name     | Type               | Required? | Description                                                                         |\n| -------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| formAtom | `FormAtom\u003cFields\u003e` | Yes       | The atom that stores the form's state                                               |\n| options  | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFormErrors\u003cFields extends FormFields\u003e = FormFieldErrors\u003cFields\u003e;\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFormStatus()\n\nA hook that returns the `submitStatus` and `validateStatus` of the form atom.\n\n#### Arguments\n\n| Name     | Type               | Required? | Description                                                                         |\n| -------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| formAtom | `FormAtom\u003cFields\u003e` | Yes       | The atom that stores the form's state                                               |\n| options  | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFormStatus = {\n  /**\n   * The validation status of the form\n   */\n  validateStatus: ValidateStatus;\n  /**\n   * The submission status of the form\n   */\n  submitStatus: SubmitStatus;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### useFormSubmit()\n\nA hook that returns a callback for handling form submission.\n\n#### Arguments\n\n| Name     | Type               | Required? | Description                                                                         |\n| -------- | ------------------ | --------- | ----------------------------------------------------------------------------------- |\n| formAtom | `FormAtom\u003cFields\u003e` | Yes       | The atom that stores the form's state                                               |\n| options  | `UseAtomOptions`   | No        | Options that are forwarded to the `useAtom`, `useAtomValue`, and `useSetAtom` hooks |\n\n#### Returns\n\n```ts\ntype UseFormSubmit\u003cFields extends FormFields\u003e = {\n  (\n    values: (value: FormFieldValues\u003cFields\u003e) =\u003e void | Promise\u003cvoid\u003e,\n  ): (e?: React.FormEvent\u003cHTMLFormElement\u003e) =\u003e void;\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n## Components\n\n### \u0026lt;Form\u0026gt;\n\nA React component that renders form atoms and their fields in an isolated\nscope using a Jotai Provider.\n\n#### Props\n\n| Name      | Type                                                                                 | Required? | Description                                                  |\n| --------- | ------------------------------------------------------------------------------------ | --------- | ------------------------------------------------------------ |\n| atom      | `FormAtom\u003cFormFields\u003e`                                                               | Yes       | A form atom                                                  |\n| store     | `AtomStore`                                                                          | No        | [A Jotai store](https://jotai.org/docs/api/core#createstore) |\n| component | `React.ComponentType\u003c{state: UseFormState\u003cValue\u003e; actions: UseFormActions\u003cValue\u003e;}\u003e` | No        | A React component to render as the input field               |\n| render    | `(state: UseFormState\u003cValue\u003e, actions: UseFormActions\u003cValue\u003e) =\u003e JSX.Element`        | No        | A render prop                                                |\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### \u0026lt;InputField\u0026gt;\n\nA React component that renders field atoms with initial values. This is\nmost useful for fields that are rendered as native HTML elements because\nthe props can unpack directly into the underlying component.\n\n#### Props\n\n| Name         | Type                                                                                   | Required? | Description                                                  |\n| ------------ | -------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------ |\n| atom         | `FieldAtom\u003cValue\u003e`                                                                     | Yes       | A field atom                                                 |\n| initialValue | `Value`                                                                                | No        | The initial value of the field                               |\n| type         | `Type`                                                                                 | No        | The type of the field. Defaults to `\"text\"`.                 |\n| store        | `AtomStore`                                                                            | No        | [A Jotai store](https://jotai.org/docs/api/core#createstore) |\n| component    | `React.ComponentType\u003c{state: UseFieldState\u003cValue\u003e; actions: UseFieldActions\u003cValue\u003e;}\u003e` | No        | A React component to render as the input field               |\n| render       | `(state: UseFieldState\u003cValue\u003e, actions: UseFieldActions\u003cValue\u003e) =\u003e JSX.Element`        | No        | A render prop                                                |\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### \u0026lt;TextareaField\u0026gt;\n\nA React component that renders field atoms with initial values. This is\nmost useful for fields that are rendered as native HTML elements because\nthe props can unpack directly into the underlying component.\n\n#### Props\n\n| Name         | Type                                                                                   | Required? | Description                                                  |\n| ------------ | -------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------ |\n| atom         | `FieldAtom\u003cValue\u003e`                                                                     | Yes       | A field atom                                                 |\n| initialValue | `Value`                                                                                | No        | The initial value of the field                               |\n| store        | `AtomStore`                                                                            | No        | [A Jotai store](https://jotai.org/docs/api/core#createstore) |\n| component    | `React.ComponentType\u003c{state: UseFieldState\u003cValue\u003e; actions: UseFieldActions\u003cValue\u003e;}\u003e` | No        | A React component to render as the input field               |\n| render       | `(state: UseFieldState\u003cValue\u003e, actions: UseFieldActions\u003cValue\u003e) =\u003e JSX.Element`        | No        | A render prop                                                |\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### \u0026lt;SelectField\u0026gt;\n\nA React component that renders field atoms with initial values. This is\nmost useful for fields that are rendered as native HTML elements because\nthe props can unpack directly into the underlying component.\n\n#### Props\n\n| Name         | Type                                                                                   | Required? | Description                                                  |\n| ------------ | -------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------ |\n| atom         | `FieldAtom\u003cValue\u003e`                                                                     | Yes       | A field atom                                                 |\n| initialValue | `Value`                                                                                | No        | The initial value of the field                               |\n| multiple     | `boolean`                                                                              | No        | Is this a multi-select field?                                |\n| store        | `AtomStore`                                                                            | No        | [A Jotai store](https://jotai.org/docs/api/core#createstore) |\n| component    | `React.ComponentType\u003c{state: UseFieldState\u003cValue\u003e; actions: UseFieldActions\u003cValue\u003e;}\u003e` | No        | A React component to render as the input field               |\n| render       | `(state: UseFieldState\u003cValue\u003e, actions: UseFieldActions\u003cValue\u003e) =\u003e JSX.Element`        | No        | A render prop                                                |\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### \u0026lt;Field\u0026gt;\n\nA React component that renders field atoms with initial values. This is\nmost useful for fields that aren't rendered as native HTML elements.\n\n#### Props\n\n| Name         | Type                                                                                   | Required? | Description                                                  |\n| ------------ | -------------------------------------------------------------------------------------- | --------- | ------------------------------------------------------------ |\n| atom         | `FieldAtom\u003cValue\u003e`                                                                     | Yes       | A field atom                                                 |\n| initialValue | `Value`                                                                                | No        | The initial value of the field                               |\n| store        | `AtomStore`                                                                            | No        | [A Jotai store](https://jotai.org/docs/api/core#createstore) |\n| component    | `React.ComponentType\u003c{state: UseFieldState\u003cValue\u003e; actions: UseFieldActions\u003cValue\u003e;}\u003e` | No        | A React component to render as the field                     |\n| render       | `(state: UseFieldState\u003cValue\u003e, actions: UseFieldActions\u003cValue\u003e) =\u003e JSX.Element`        | No        | A render prop                                                |\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n## Utilities\n\n### walkFields()\n\nA function that walks through an object containing nested field atoms\nand calls a visitor function for each atom it finds.\n\n#### Arguments\n\n| Name    | Type                                                       | Required? | Description                                                                                                    |\n| ------- | ---------------------------------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------- |\n| fields  | `FormFields`                                               | Yes       | An object containing nested field atoms                                                                        |\n| visitor | `(field: FieldAtom\u003cany\u003e, path: string[]) =\u003e void \\| false` | Yes       | A function that will be called for each field atom. You can exit early by returning `false` from the function. |\n\n#### Returns\n\n```ts\nvoid\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n## Utility types\n\n### FormValues\n\nA utility type for inferring the value types of a form's nested field atoms.\n\n```ts\nconst nameForm = formAtom({\n  name: fieldAtom({ value: \"\" }),\n});\n\ntype NameFormValues = FormValues\u003ctypeof nameForm\u003e;\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n### FormErrors\n\nA utility type for inferring the error types of a form's nested field atoms.\n\n```ts\nconst nameForm = formAtom({\n  name: fieldAtom({ value: \"\" }),\n});\n\ntype NameFormErrors = FormErrors\u003ctypeof nameForm\u003e;\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n## form-atoms/valibot\n\n### createValibotValidator()\n\nValidate your field atoms with Valibot schemas. This function validates on every `\"user\"` and\n`\"submit\"` event, in addition to other events you specify.\n\n```ts\nimport { formAtom, fieldAtom } from \"form-atoms\";\nimport { createValibotValidator } from \"form-atoms/valibot\";\nimport { parseAsync, string, pipe, minLength } from \"valibot\";\n\nconst valibotValidate = createValibotValidator(parseAsync);\n//...\nconst nameForm = formAtom({\n  name: fieldAtom({\n    validate: valibotValidate(pipe(string(), minLength(3, \"uh oh\")), {\n      on: \"submit\",\n      when: \"dirty\",\n    }),\n  }),\n});\n```\n\n---\n\n## form-atoms/zod\n\n### zodValidate()\n\nValidate your field atoms with Zod schemas. This function validates on every `\"user\"` and\n`\"submit\"` event, in addition to other events you specify.\n\n[**Check out an example on CodeSandbox**](https://codesandbox.io/s/form-atoms-v2-validate-using-zod-1n1rrr?file=/src/App.tsx)\n\n```ts\nimport { z } from \"zod\";\nimport { formAtom, fieldAtom } from \"form-atoms\";\nimport { zodValidate } from \"form-atoms/zod\";\n\nconst schema = z.object({\n  name: z.string().min(3),\n});\n\nconst nameForm = formAtom({\n  name: fieldAtom({\n    validate: zodValidate(schema.shape.name, {\n      on: \"submit\",\n      when: \"dirty\",\n    }),\n  }),\n});\n```\n\n#### Arguments\n\n| Name   | Type                                      | Required? | Description                                          |\n| ------ | ----------------------------------------- | --------- | ---------------------------------------------------- |\n| schema | `((get: Getter) =\u003e z.Schema) \\| z.Schema` | Yes       | A Zod schema or a function that returns a Zod schema |\n| config | [`ZodValidateConfig`](#zodvalidateconfig) | No        | Configuration options                                |\n\n#### ZodValidateConfig\n\n```ts\ntype ZodValidateConfig = {\n  /**\n   * The event or events that triggers validation.\n   */\n  on?: ZodValidateOn | ZodValidateOn[];\n  /**\n   * Validate if the field is:\n   * - `touched`\n   * - `dirty`\n   */\n  when?: \"touched\" | \"dirty\" | (\"touched\" | \"dirty\")[];\n  /**\n   * Format the error message returned by the validator.\n   *\n   * @param error - A ZodError object\n   */\n  formatError?: (error: ZodError) =\u003e string[];\n};\n```\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n## Wait, it's all atoms?\n\n![Wait it's all atoms? Always has been.](https://i.imgflip.com/65s2ci.jpg)\n\n#### [⇗ Back to top](#table-of-contents)\n\n---\n\n## LICENSE\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fform-atoms%2Fform-atoms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fform-atoms%2Fform-atoms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fform-atoms%2Fform-atoms/lists"}