Full Code of final-form/react-final-form for AI

main fcea1a1af63a cached
293 files
748.1 KB
233.0k tokens
131 symbols
1 requests
Download .txt
Showing preview only (816K chars total). Download the full file or copy to clipboard to get everything.
Repository: final-form/react-final-form
Branch: main
Commit: fcea1a1af63a
Files: 293
Total size: 748.1 KB

Directory structure:
gitextract_z4w9ccys/

├── .babelrc.js
├── .eslintrc
├── .flowconfig
├── .github/
│   ├── CODEOWNERS
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       ├── ci.yml
│       └── lock.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── MIGRATION_V7.md
├── README.md
├── docs/
│   ├── api/
│   │   ├── Field.md
│   │   ├── Form.md
│   │   ├── FormSpy.md
│   │   ├── useField.md
│   │   ├── useForm.md
│   │   └── useFormState.md
│   ├── api.md
│   ├── examples/
│   │   ├── chakra.md
│   │   ├── field-level-validation.md
│   │   ├── record-level-validation.md
│   │   ├── simple.md
│   │   ├── submission-errors.md
│   │   ├── subscriptions.md
│   │   └── wizard.md
│   ├── examples.md
│   ├── faq.md
│   ├── getting-started.md
│   ├── migration/
│   │   ├── formik.md
│   │   └── redux-form.md
│   ├── philosophy.md
│   └── types/
│       ├── FieldProps.md
│       ├── FieldRenderProps.md
│       ├── FormProps.md
│       ├── FormRenderProps.md
│       ├── FormSpyProps.md
│       └── FormSpyRenderProps.md
├── eslint.config.mjs
├── examples/
│   ├── async-field-level-validation/
│   │   ├── Spinner.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── async-redux-submission/
│   │   ├── Styles.js
│   │   ├── asyncSubmissionMiddleware.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   ├── registrationDuck.js
│   │   └── store.js
│   ├── async-typeahead-redux/
│   │   ├── GithubUserTypeahead.jsx
│   │   ├── Styles.js
│   │   ├── actions.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   ├── store.js
│   │   └── useKeyword.js
│   ├── auto-save-field-blur/
│   │   ├── AutoSave.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── auto-save-selective-debounce/
│   │   ├── AutoSave.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── auto-save-with-debounce/
│   │   ├── AutoSave.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── calculated-fields/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── chakra/
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── validate.js
│   ├── conditional-fields/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── pickupTimes.js
│   │   └── readme.md
│   ├── credit-card/
│   │   ├── Card.js
│   │   ├── Styles.js
│   │   ├── cardUtils.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── sandbox.config.json
│   ├── custom-validation-engine/
│   │   ├── OnBlurValidation.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── debounced-record-level-validation/
│   │   ├── ErrorWithDelay.js
│   │   ├── README.md
│   │   ├── Styles.js
│   │   ├── index.js
│   │   └── package.json
│   ├── declarative-form-rules/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── downshift-typeahead/
│   │   ├── DownshiftInput.js
│   │   ├── Styles.js
│   │   ├── fruit.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── external-submit/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── field-arrays/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── field-level-validation/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── field-warnings/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── warning-engine.js
│   ├── fields-component/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── focus-first-error/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── validate.js
│   ├── format-on-blur/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── format-string-by-pattern/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── hybrid-sync-async-record-level-validation/
│   │   ├── Spinner.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── independent-error-component-render-props/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── independent-error-component-with-hooks/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── listening-for-external-changes/
│   │   ├── BooleanDecay.js
│   │   ├── ExternalModificationDetector.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── loading-initializing-values/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── loading-saving-reinitializing/
│   │   ├── LoadSaveReinitializeForm.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── material-ui/
│   │   ├── .prettierrc
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── parse-format/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── prefixed-fields/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── readme.md
│   ├── record-level-validation/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── redux/
│   │   ├── FormStateFromRedux.js
│   │   ├── FormStateToRedux.js
│   │   ├── Styles.js
│   │   ├── finalFormDuck.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── store.js
│   ├── reusable-field-groups/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── simple/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── strongly-typed-values-typescript/
│   │   ├── Styles.tsx
│   │   ├── components/
│   │   │   ├── CheckboxInput.tsx
│   │   │   ├── MultiCheckboxInput.tsx
│   │   │   ├── MultiSelectInput.tsx
│   │   │   ├── NumberInput.tsx
│   │   │   ├── RadioInput.tsx
│   │   │   ├── SelectInput.tsx
│   │   │   ├── TextAreaInput.tsx
│   │   │   └── TextInput.tsx
│   │   ├── index.tsx
│   │   └── readme.md
│   ├── styling-with-smooth-ui/
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── submission-errors/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── subscriptions/
│   │   ├── RenderCount.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── third-party-components/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── states.js
│   └── wizard/
│       ├── Styles.js
│       ├── Wizard.js
│       ├── index.js
│       ├── package.json
│       └── readme.md
├── package-scripts.js
├── package.json
├── rollup.config.mjs
├── src/
│   ├── Field.test.js
│   ├── Field.tsx
│   ├── FormSpy.test.js
│   ├── FormSpy.tsx
│   ├── ReactFinalForm.test.js
│   ├── ReactFinalForm.tsx
│   ├── context.test.js
│   ├── context.ts
│   ├── getValue.test.js
│   ├── getValue.ts
│   ├── getters.ts
│   ├── index.ts
│   ├── isReactNative.ts
│   ├── isSyntheticEvent.ts
│   ├── renderComponent.test.js
│   ├── renderComponent.ts
│   ├── shallowEqual.test.js
│   ├── shallowEqual.ts
│   ├── testUtils.ts
│   ├── types.ts
│   ├── useConstant.ts
│   ├── useConstantCallback.test.js
│   ├── useConstantCallback.ts
│   ├── useField.dynamic-name-869.test.js
│   ├── useField.test.js
│   ├── useField.ts
│   ├── useForm.test.js
│   ├── useForm.ts
│   ├── useFormState.test.js
│   ├── useFormState.ts
│   ├── useLatest.ts
│   └── useWhenValueChanges.ts
├── tsconfig.build.json
├── tsconfig.json
├── tslint.json
└── typescript/
    ├── Field.test.tsx
    ├── FormSpy.test.tsx
    ├── ReactFinalForm.test.tsx
    ├── index.d.ts
    ├── tsconfig.json
    ├── useField.test.tsx
    └── useFormState.test.tsx

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc.js
================================================
const { NODE_ENV } = process.env;
const test = NODE_ENV === "test";
const loose = true;

module.exports = {
  presets: [
    [
      "@babel/preset-env",
      {
        loose,
        ...(test ? { targets: { node: "8" } } : {}),
      },
    ],
    "@babel/preset-react",
    "@babel/preset-typescript",
  ],
  plugins: [
    "@babel/plugin-syntax-dynamic-import",
    "@babel/plugin-syntax-import-meta",
    test && "@babel/plugin-transform-react-jsx-source",
  ].filter(Boolean),
};


================================================
FILE: .eslintrc
================================================
{
  "extends": "react-app",
  "plugins": ["react-hooks"],
  "rules": {
    "jsx-a11y/href-no-hash": 0,
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",
    "import/no-anonymous-default-export": 0
  }
}


================================================
FILE: .flowconfig
================================================
[ignore]
dist

[include]

[libs]

[options]


================================================
FILE: .github/CODEOWNERS
================================================
* @erikras


================================================
FILE: .github/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of
experience, nationality, personal appearance, race, religion, or sexual identity
and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
  advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at rasmussenerik@gmail.com. The project
team will review and investigate all complaints, and will respond in a way that
it deems appropriate to the circumstances. The project team is obligated to
maintain confidentiality with regard to the reporter of an incident. Further
details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributing

Thanks for your interest in contributing to 🏁 React Final Form! Please take a
moment to review this document **before submitting a pull request**.

We are open to, and grateful for, any contributions made by the community.

## Reporting issues and asking questions

Before opening an issue, please search
the [issue tracker](https://github.com/final-form/react-final-form/issues) to
make sure your issue hasn’t already been reported.

**We use the issue tracker to keep track of bugs and improvements** to 🏁 React
Final Form itself, its examples, and the documentation. We encourage you to open
issues to discuss improvements, architecture, internal implementation, etc. If a
topic has been discussed before, we will ask you to join the previous
discussion.

For support or usage questions, please search and ask on
[StackOverflow with a `react-final-form` tag](https://stackoverflow.com/questions/tagged/react-final-form).
We ask you to do this because StackOverflow has a much better job at keeping
popular questions visible. Unfortunately good answers get lost and outdated on
GitHub.

**If you already asked at StackOverflow and still got no answers, post an issue
with the question link, so we can either answer it or evolve into a bug/feature
request.**

## Sending a pull request

**Please ask first before starting work on any significant new features.**

It's never a fun experience to have your pull request declined after investing a
lot of time and effort into a new feature. To avoid this from happening, we
request that contributors create
[an issue](https://github.com/final-form/react-final-form/issues) to first
discuss any significant new features.

Please try to keep your pull request focused in scope and avoid including
unrelated commits.

After you have submitted your pull request, we’ll try to get back to you as soon
as possible. We may suggest some changes or improvements.

Please format the code before submitting your pull request by running:

```sh
npm run precommit
```

## Coding standards

Our code formatting rules are defined in
[.eslintrc](https://github.com/final-form/react-final-form/blob/master/.eslintrc).
You can check your code against these standards by running:

```sh
npm start lint
```

To automatically fix any style violations in your code, you can run:

```sh
npm run precommit
```

## Running tests

You can run the test suite using the following commands:

```sh
npm test
```

Please ensure that the tests are passing when submitting a pull request. If
you're adding new features to 🏁 React Final Form, please include tests.


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: erikras
patreon: erikras
open_collective: final-form
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with a single custom sponsorship URL


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
<!--

👋 Hey, thanks for taking an interest in 🏁 React Final Form!

-->

### Are you submitting a **bug report** or a **feature request**?

<!-- For support request, please use Stack Overflow instead. This issue tracker is reserved for bugs and features. -->

### What is the current behavior?

<!-- If this is a bug, please include steps to reproduce and a minimal demo of the problem using Sandbox, Plunkr, WebpackBin or JSFiddle. -->

### What is the expected behavior?

### Sandbox Link

<!-- Problems are much easier to understand and debug if they can be demonstrated in a minimal environment.  -->

### What's your environment?

<!-- Include 🏁 React Final Form version, 🏁 Final Form version, OS/browser affected, Node version, etc. -->

### Other information

<!-- Include here any detailed explanation, stacktraces, related issues, links for Stack Overflow, Twitter, etc. -->


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--

👋 Hey, thanks for your interest in contributing to 🏁 React Final Form!

**Please ask first before starting work on any significant new features.**

It's never a fun experience to have your pull request declined after investing a
lot of time and effort into a new feature. To avoid this from happening, we
request that contributors create an issue to first discuss any significant new
features.

Please try to keep your pull request focused in scope and avoid including
unrelated commits.

After you have submitted your pull request, we’ll try to get back to you as soon
as possible. We may suggest some changes or improvements.

Please format the code before submitting your pull request by running:

```
npm run precommit
```

https://github.com/final-form/react-final-form/blob/master/.github/CONTRIBUTING.md

-->


================================================
FILE: .github/workflows/ci.yml
================================================
name: CI

on: [push]

jobs:
  lint:
    name: Lint
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node_version }}
        uses: actions/setup-node@v2
        with:
          node-version: "22"
      - name: Prepare env
        run: yarn install --ignore-scripts --frozen-lockfile
      - name: Run linter
        run: yarn start lint

  prettier:
    name: Prettier Check
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node_version }}
        uses: actions/setup-node@v2
        with:
          node-version: "22"
      - name: Prepare env
        run: yarn install --ignore-scripts --frozen-lockfile
      - name: Run prettier
        run: yarn start prettier

  test:
    name: Unit Tests
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js ${{ matrix.node_version }}
        uses: actions/setup-node@v2
        with:
          node-version: "22"
      - name: Prepare env
        run: yarn install --ignore-scripts --frozen-lockfile
      - name: Run unit tests
        run: yarn start test
      - name: Run code coverage
        uses: codecov/codecov-action@v2.1.0


================================================
FILE: .github/workflows/lock.yml
================================================
name: "Lock Threads"

on:
  schedule:
    - cron: "0 * * * *"
  workflow_dispatch:

permissions:
  issues: write
  pull-requests: write

concurrency:
  group: lock

jobs:
  action:
    runs-on: ubuntu-latest
    steps:
      - uses: dessant/lock-threads@v3
        with:
          issue-inactive-days: "365"
          issue-lock-reason: "resolved"
          pr-inactive-days: "365"
          pr-lock-reason: "resolved"


================================================
FILE: .gitignore
================================================
.vscode
*.iml
.nyc_output
coverage
flow-coverage
node_modules
dist
lib
es
npm-debug.log
.DS_Store
.yalc
yalc.lock


================================================
FILE: .prettierignore
================================================
coverage
dist
node_modules

================================================
FILE: .prettierrc
================================================
{
  "trailingComma": "all"
}


================================================
FILE: .travis.yml
================================================
sudo: false
language: node_js
before_install:
  - npm install -g npm@6.4.0
cache:
  directories:
    - node_modules
notifications:
  email: false
node_js:
  - "10"
  - "12"
  - "14"
script:
  - npm start validate
after_success:
  - npx codecov
branches:
  only:
    - main


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017 Erik Rasmussen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: MIGRATION_V7.md
================================================
# Migration Guide: react-final-form v6 → v7

## Overview

Version 7.0.0 includes a complete TypeScript rewrite (migrated from Flow). While the runtime behavior remains largely unchanged, there are several TypeScript-specific breaking changes you need to be aware of.

## Breaking Changes

### 1. FormState Properties Now Optional

In v7.0.0, most FormState boolean properties can be `undefined`:

**❌ Before (v6.x):**

```typescript
const { dirty, pristine, valid } = formState;
if (dirty && !pristine) { // Works fine
  // ...
}
```

**✅ After (v7.0.0):**

```typescript
const { dirty, pristine, valid } = formState;
if ((dirty ?? false) && !(pristine ?? true)) { // Must handle undefined
  // ...
}
```

**Affected properties:**
- `dirty`, `pristine`, `valid`, `invalid`
- `dirtySinceLastSubmit`, `modifiedSinceLastSubmit`
- `submitFailed`, `submitSucceeded`, `submitting`, `validating`
- `hasSubmitErrors`, `hasValidationErrors`

**Note:** `values` is still guaranteed to be defined.

### 2. FieldMetaState Type No Longer Exported

**❌ Before (v6.x):**

```typescript
import { FieldMetaState } from 'react-final-form';

const meta: FieldMetaState = { /* ... */ };
```

**✅ After (v7.0.0):**

```typescript
import { FieldRenderProps } from 'react-final-form';

const meta: FieldRenderProps<any>['meta'] = { /* ... */ };

// Or define it locally:
type FieldMetaState = {
  active?: boolean;
  data?: Record<string, any>;
  dirty?: boolean;
  // ... etc
};
```

### 3. AnyObject Type No Longer Exported

**❌ Before (v6.x):**

```typescript
import { AnyObject } from 'react-final-form';
```

**✅ After (v7.0.0):**

```typescript
// Define locally:
type AnyObject = Record<string, any>;
```

### 4. UseFieldConfig No Longer Generic

**❌ Before (v6.x):**

```typescript
const config: UseFieldConfig<string> = {
  validate: (value) => value ? undefined : 'Required'
};
```

**✅ After (v7.0.0):**

```typescript
const config: UseFieldConfig = {
  validate: (value) => value ? undefined : 'Required'
};
```

### 5. FormProps No Longer Accepts Arbitrary Props

In v6.x, you could pass arbitrary props (like `style`, `className`) directly to `<Form>`. In v7.0.0, this is no longer supported due to stricter TypeScript typing.

**❌ Before (v6.x):**

```tsx
<Form
  onSubmit={handleSubmit}
  style={{ padding: '20px' }}
  className="my-form"
>
  {/* ... */}
</Form>
```

**✅ After (v7.0.0):**

```tsx
<Form onSubmit={handleSubmit}>
  {({ handleSubmit }) => (
    <form onSubmit={handleSubmit} style={{ padding: '20px' }} className="my-form">
      {/* ... */}
    </form>
  )}
</Form>

// Or wrap in a div:
<div style={{ padding: '20px' }} className="my-form">
  <Form onSubmit={handleSubmit}>
    {/* ... */}
  </Form>
</div>
```

## final-form v5.0.0 Changes

If you're also upgrading final-form to v5.0.0, be aware of these changes:

### 1. InternalFormState Requires asyncErrors

**❌ Before (v4.x):**

```typescript
const mockFormState: InternalFormState = {
  values: {},
  // ...
};
```

**✅ After (v5.0.0):**

```typescript
const mockFormState: InternalFormState = {
  values: {},
  asyncErrors: {}, // Now required
  // ...
};
```

### 2. Mutator Type Signature Changed

**❌ Before (v4.x):**

```typescript
const mutator: Mutator = (args, state, tools) => {
  // ...
};
```

**✅ After (v5.0.0):**

```typescript
// If you get type errors with existing mutators:
const mutator = ((args, state, tools) => {
  // ...
}) as unknown as Mutator;
```

## Migration Strategy

For a medium to large codebase, expect to modify 100+ files. Here's a recommended approach:

1. **Update dependencies:**

   ```bash
   npm install react-final-form@^7.0.0 final-form@^5.0.0
   ```

2. **Fix compilation errors in this order:**
   - Handle optional boolean properties (use `?? false` or `?? true`)
   - Replace `FieldMetaState` imports with `FieldRenderProps['meta']`
   - Replace `AnyObject` imports with local type definition
   - Remove generic from `UseFieldConfig<T>` → `UseFieldConfig`
   - Fix `<Form>` props (move styling to wrapper or inner `<form>`)

3. **Test thoroughly:**
   - All form submissions
   - Validation behavior
   - Field state management
   - Meta information display

4. **Update mocks/tests:**
   - Add `asyncErrors: {}` to InternalFormState mocks
   - Cast mutators if needed

## Need Help?

If you encounter issues during migration:

1. Check the [TypeScript examples](https://github.com/final-form/react-final-form/tree/main/examples/typescript)
2. Review [closed issues](https://github.com/final-form/react-final-form/issues?q=is%3Aissue+typescript)
3. Open a [new issue](https://github.com/final-form/react-final-form/issues/new) with a reproduction

## Benefits of v7.0.0

Despite the migration effort, v7.0.0 brings significant benefits:

- **Better TypeScript support** - First-class TypeScript instead of generated types from Flow
- **Improved type inference** - Better autocomplete and type checking
- **Modern codebase** - Easier for contributors to work with
- **Long-term maintainability** - TypeScript ecosystem is more active than Flow

---

**Version**: 7.0.0  
**Last Updated**: 2026-02-13


================================================
FILE: README.md
================================================
# 🏁 React Final Form

[![React Final Form](banner.png)](https://final-form.org/react)

[![Backers on Open Collective](https://opencollective.com/final-form/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/final-form/sponsors/badge.svg)](#sponsors) [![NPM Version](https://img.shields.io/npm/v/react-final-form.svg?style=flat)](https://www.npmjs.com/package/react-final-form)
[![NPM Downloads](https://img.shields.io/npm/dm/react-final-form.svg?style=flat)](https://www.npmjs.com/package/react-final-form)
[![Build Status](https://travis-ci.org/final-form/react-final-form.svg?branch=master)](https://travis-ci.org/final-form/react-final-form)
[![codecov.io](https://codecov.io/gh/final-form/react-final-form/branch/master/graph/badge.svg)](https://codecov.io/gh/final-form/react-final-form)
[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)

✅ Zero dependencies (that affect your bundle size)

✅ Only peer dependencies: React and
[🏁 Final Form](https://github.com/final-form/final-form#-final-form)

✅ Opt-in subscriptions - only update on the state you need!

✅ 💥 [**3.0k gzipped**](https://bundlephobia.com/result?p=react-final-form) 💥

---

[<img align="right" src="docs/sencha.svg" height="100"/>](https://www.sencha.com/)

### React Final Form is sponsored by [Sencha](https://www.sencha.com/).

Comprehensive JS framework and UI components for building enterprise-grade web apps.

---

## 💬 [Give Feedback on React Final Form](https://goo.gl/forms/dxdfxKNy64DLb99z2) 💬

In the interest of making 🏁 React Final Form the best library it can be, we'd love your thoughts and feedback.

[Take a quick survey](https://goo.gl/forms/dxdfxKNy64DLb99z2).

---

React Final Form is a thin React wrapper for [Final Form](https://final-form.org), which is a subscriptions-based form state management library that uses the [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern), so only the components that need updating are re-rendered as the form's state changes.

## [Getting Started](https://final-form.org/docs/react-final-form/getting-started)

## 🔄 Upgrading from v6 to v7?

See the [Migration Guide](./MIGRATION_V7.md) for TypeScript-specific breaking changes and how to handle them.

## [Philosophy](https://final-form.org/docs/react-final-form/philosophy)

## [Examples](https://final-form.org/docs/react-final-form/examples)

## [API](https://final-form.org/docs/react-final-form/api)

## [FAQ](https://final-form.org/docs/react-final-form/faq)

<img src="https://static.scarf.sh/a.png?x-pxid=8feec529-43ac-4b78-8ad9-17c280b4f2d9" />


================================================
FILE: docs/api/Field.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/Field). Links may not work on Github.com.

# `<Field/>`

```ts
import { Field } from 'react-final-form'
```

A component that registers a field with the containing form, subscribes to field state, and injects both field state and callback functions, `onBlur`, `onChange`, and `onFocus` via a render prop.

The `<Field/>` will rerender any time the field state it is subscribed to changes. By default it subscribes to _all_ field state. You can control which field state it subscribes to with the `subscription` prop.

## Props

`<Field/>` accepts [`FieldProps`](../types/FieldProps) and will call the render function with [`FieldRenderProps`](../types/FieldRenderProps).

The only two required props are [`name`](../types/FieldProps#name) and one of [`component`](../types/FieldProps#component), [`render`](../types/FieldProps#render), or [`children`](../types/FieldProps#children).

## Basic Usage

You need to do three things when using `<Field/>`:

### 1. Provide a `name` prop

The name of the field can be a reference to a "deep" value via [dot-and-bracket syntax](/docs/final-form/field-names), e.g. `'clients[0].address.street'`.

### 2. Provide a way to render the field

There are four ways to render a `<Field/>` component:

| Prop                 | Type                               |
| -------------------- | ---------------------------------- |
| `<Field component/>` | `'input' or 'select' or 'textarea'` |
| `<Field component/>` | `React.ComponentType`              |
| `<Field render/>`    | `Function`                         |
| `<Field children/>`  | `Function`                         |

The only important distinction is that if you pass a component to the `component` prop, it will be rendered with [`React.createElement()`](https://reactjs.org/docs/react-api.html#createelement), resulting in your component actually being in the React node tree, i.e. inspectable in [DevTools](https://github.com/facebook/react-devtools#react-developer-tools-).

### 3. Connect the callbacks to your input

If you are using `component="input"` (or `select` or `textarea`), `<Field/>` will do this step for you.

```tsx
<Field name="myField" component="input" />
```

But if you are using a custom component or a render prop, you will need to do this yourself.

`<Field/>` makes this as easy as possible by bundling all of the props that your input component needs into one object prop, called `input`, which contains [`name`](../types/FieldRenderProps#inputname), [`onBlur`](../types/FieldRenderProps#inputonblur), [`onChange`](../types/FieldRenderProps#inputonchange), [`onFocus`](../types/FieldRenderProps#inputonfocus), and [`value`](../types/FieldRenderProps#inputvalue).

#### HTML Inputs

If you're going to be using one of the standard HTML inputs, `<input>`, `<select>`, or `<textarea>`, it's just a matter of using [the spread operator](https://reactjs.org/docs/jsx-in-depth.html#spread-attributes) to populate the props of the input.

```tsx
<Field name="myField">
  {props => (
    <div>
      <input {...props.input} />
    </div>
  )}
</Field>
```

#### Custom Inputs

The only thing a custom input needs to do to be compatible with React Final Form is to accept a `value` prop and somehow call the `onChange` callback to change the value.

```tsx
import TextField from '@material-ui/core/TextField'

...

<Field name="myField">
  {props => (
    <div>
      <TextField
        name={props.input.name}
        value={props.input.value}
        onChange={props.input.onChange}
      />
    </div>
  )}
</Field>
```


Note: To use an `array` for the values (with another field type, like a tags-input component), you can do `value={[...props.input.value]}` to avoid "Invalid prop type of 'string' warning"

Now, [let's look at some examples](../examples)!


================================================
FILE: docs/api/Form.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/Form). Links may not work on Github.com.

# `<Form/>`

```ts
import { Form } from 'react-final-form'
```

A component that surrounds your entire form and manages the form state. It can inject form state and functionality, e.g. a `handleSubmit` function for you to pass to your `<form>` element, via render props.

On mount, `<Form/>` creates a Final Form [`form` instance](/docs/final-form/types/FormApi), subscribes to changes on that `form`, and places it into the [React Context](https://reactjs.org/docs/context.html) so that the [`<Field/>`](Field) and [`<FormSpy/>`](FormSpy) components can see it.

The `<Form/>` will rerender any time the form state it is subscribed to changes. By default it subscribes to _all_ form state. You can control which form state it subscribes to with the `subscription` prop.

## Props

`<Form/>` accepts [`FormProps`](../types/FormProps) and will call the render function with [`FormRenderProps`](../types/FormRenderProps).

The only two required props are [`onSubmit`](../types/FormProps#onsubmit) and one of [`component`](../types/FormProps#component), [`render`](../types/FormProps#render), or [`children`](../types/FormProps#children).

## Basic Usage

You need to do three things when using `<Form/>`:

### 1. Provide an `onSubmit` prop

`onSubmit` is a function that will be called with the values of your form when the user submits the form _and_ all validation passes. Your `onSubmit` function will not be called if there are validation errors.

### 2. Provide a way to render the form

There are three ways to render a `<Form/>` component:

| Prop                | Type                  |
| ------------------- | --------------------- |
| `<Form component/>` | `React.ComponentType` |
| `<Form render/>`    | `Function`            |
| `<Form children/>`  | `Function`            |

The only important distinction is that if you pass a `component` prop, it will be rendered with [`React.createElement()`](https://reactjs.org/docs/react-api.html#createelement), resulting in your component actually being in the React node tree, i.e. inspectable in [DevTools](https://github.com/facebook/react-devtools#react-developer-tools-).

While using `component` might feel easiest if you are migrating from [Redux Form's Higher Order Component](https://redux-form.com/8.2.2/docs/api/reduxform.md/) model, best practice recommends using a render prop.

### 3. Do something with `handleSubmit`

The most important thing that `<Form/>` will pass to your render function is the `handleSubmit` function. `handleSubmit` is a convenience method designed to be passed as the `onSubmit` prop to an HTML `<form>` component. `handleSubmit` will call `event.preventDefault()` to stop the default browser submission process.

In practice, your form will always look something like this:

<!-- prettier-ignore -->
```jsx
<Form onSubmit={onSubmit}>
  {props => (
    <form onSubmit={props.handleSubmit}>

      ... fields go here...

      <button type="submit">Submit</button>
    </form>
  )}
</Form>
```

Now, [let's look at adding some `<Field/>`](Field) components!


================================================
FILE: docs/api/FormSpy.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/FormSpy). Links may not work on Github.com.

# `<FormSpy/>`

```ts
import { FormSpy } from 'react-final-form'
```

A component that subscribes to form state, and injects both form state and the `form` instance via a render prop.

The `<FormSpy/>` will rerender any time the form state it is subscribed to changes. By default it subscribes to _all_ form state. You can control which form state it subscribes to with the `subscription` prop.

By providing an `onChange` prop, `<FormSpy/>` can also be used to execute code when a particular part of form state changes.

## Props

`<FormSpy/>` accepts [`FormSpyProps`](../types/FormSpyProps) and will call the render function with [`FormSpyRenderProps`](../types/FormSpyRenderProps).

The only required prop is one of `onChange`, `component`, `render`, or `children`.

## Basic Usage

It should be noted that `<FormSpy/>` is for very advanced use cases.

**If you are not restricting your form state by providing a `subscription` prop to `<Form/>`, you probably do not need `<FormSpy/>`!** Just use the form state injected by `<Form/>`.

You need to do _one_ of two things when using `<FormSpy/>`:

### 1. Provide a way to render the form state

There are three ways to render a `<FormSpy/>` component:

| Prop                   | Type                  |
| ---------------------- | --------------------- |
| `<FormSpy component/>` | `React.ComponentType` |
| `<FormSpy render/>`    | `Function`            |
| `<FormSpy children/>`  | `Function`            |

The only important distinction is that if you pass a `component` prop, it will be rendered with [`React.createElement()`](https://reactjs.org/docs/react-api.html#createelement), resulting in your component actually being in the React node tree, i.e. inspectable in [DevTools](https://github.com/facebook/react-devtools#react-developer-tools-).

```tsx
// Render a reset button that will be
// disabled when the form is pristine
<FormSpy subscription={{ pristine: true }}>
  {props => (
    <button
      type="button"
      disabled={props.pristine}
      onClick={() => props.form.reset()}
    >
      Reset
    </button>
  )}
</FormSpy>
```

### 2. Pass an `onChange` callback

`<FormSpy/>` can sometimes be useful to execute code when a particular part of form state changes. This is what the `onChange` callback is for.

**If you pass `onChange`, nothing will be rendered.**

```tsx
<FormSpy
  subscription={{ valid: true }}
  onChange={props => {
    console.log('Form validity changed to', props.valid)
  }}
/>
```


================================================
FILE: docs/api/useField.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/useField). Links may not work on Github.com.

# `useField()`

```ts
import { useField } from 'react-final-form'
```

<!-- prettier-ignore -->
```ts
(name: string, config: UseFieldConfig) => FieldRenderProps
```

The `useField()` hook takes two parameters:

### `name`

```ts
string
```

**Required**

The name of the field.

### `config`

```ts
UseFieldConfig
```

Optional.

An object that looks just like [`FieldProps`](../types/FieldProps), except without the name.

`useField()` returns [`FieldRenderProps`](../types/FieldRenderProps). It will manage the rerendering of any component you use it in, i.e. the component will only rerender if the field state subscribed to via `useField()` changes.

`useField()` is used internally inside [`<Field/>`](Field).


================================================
FILE: docs/api/useForm.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/useForm). Links may not work on Github.com.

# `useForm()`

```ts
import { useForm } from 'react-final-form'
```

<!-- prettier-ignore -->
```ts
() => FormApi
```

The `useForm()` hook plucks the [`FormApi`](/docs/final-form/types/FormApi) out of the React context for you. It will throw an exception if you try to use it outside of a [`<Form/>`](Form) component.

`useForm()` is used internally inside [`useField()`](useField), [`<Field/>`](Field), and [`<FormSpy/>`](FormSpy).


================================================
FILE: docs/api/useFormState.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/useFormState). Links may not work on Github.com.

# `useFormState`

```ts
import { useFormState } from 'react-final-form'
```

The `useFormState()` hook takes one optional parameter, which matches the exact shape of [`FormSpyProps`](../types/FormSpyProps) (except without the render props). It returns a [`FormState`](/docs/final-form/types/FormState).

`useFormState()` is used internally inside [`<FormSpy/>`](FormSpy).


================================================
FILE: docs/api.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api). Links may not work on Github.com.

# API

The API for React Final Form consists of three components and three hooks:

## Components

### [`<Form/>`](api/Form)

A component that surrounds your entire form and manages the form state. It can inject form state and functionality, e.g. a `handleSubmit` function for you to pass to your `<form>` element, via render props.

### [`<Field/>`](api/Field)

A component that lives inside your `<Form/>` and creates a "field". It register itself with the surrounding `<Form/>` tag and manages all the state for a particular field, providing input callbacks (e.g. `onBlur`, `onChange`, and `onFocus`) as well as the value of the form and myriad metadata about the state of the field.

### [`<FormSpy/>`](api/FormSpy)

_[Advanced Usage]_ A component that can tap into form-wide state from inside your `<Form/>`. It's primarily only for advanced usage when form renders are being restricted via the `subscription` prop.

## Hooks

### [`useField()`](api/useField)

A hook that will convert any of your components into a `<Field/>` component, registering with the surrounding `<Form/>` and providing field state to your component. `useField()` is used internally by `<Field/>`.

### [`useForm()`](api/useForm)

A hook that will pluck the Final Form [`form` instance](/docs/final-form/types/FormApi) out of context.

### [`useFormState()`](api/useFormState)

A hook that will convert any of your components into a `<FormSpy/>` component, allowing fine-grained control over subscribing to parts of the form state.


================================================
FILE: docs/examples/chakra.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/chakra). Links may not work on Github.com.

# Chakra UI Example

Demonstrates how to use [Chakra UI](https://chakra-ui.com) components with React Final Form.

[![Edit react-final-form-chakra-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/chakra)


================================================
FILE: docs/examples/field-level-validation.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/field-level-validation). Links may not work on Github.com.

# Field Level Validation Example

Introduces field-level validation functions and demonstrates how to display errors next to fields using child render functions.

[![Edit react-final-form-field-level-validation-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/field-level-validation)


================================================
FILE: docs/examples/record-level-validation.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/record-level-validation). Links may not work on Github.com.

# Record-Level Example

Introduces a whole-record validation function and demonstrates how to display errors next to fields using child render functions.

[![Edit react-final-form-record-level-validation](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/record-level-validation)


================================================
FILE: docs/examples/simple.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/simple). Links may not work on Github.com.

# Simple Example

Uses the built-in React inputs: input, select, and textarea to build a form with no validation.

[![Edit react-final-form-simple-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/simple)


================================================
FILE: docs/examples/submission-errors.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/submission-errors). Links may not work on Github.com.

# Submission Errors

Demonstrates how to return submission errors from failed submits. Notice that the `Promise` should _resolve_ to the submission error (not reject). Rejection is reserved for communications or server exceptions.

[![Edit react-final-form-submission-errors-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/submission-errors)


================================================
FILE: docs/examples/subscriptions.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/subscriptions). Links may not work on Github.com.

# High Performance Through Subscriptions Example

Demonstrates how, by restricting which parts of form state the form component needs to render, it reduces the number of times the whole form has to rerender. Yet, if some part of form state is needed inside of it, the [`<FormSpy/>`](../api/FormSpy) component can be used to attain it.

[![Edit react-final-form-subscriptions-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/subscriptions)


================================================
FILE: docs/examples/wizard.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/wizard). Links may not work on Github.com.

# Wizard Form Example

Demonstrates how to use React Final Form to create a multi-page "wizard" form, with validation on each page.

[![Edit react-final-form-wizard-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/wizard)


================================================
FILE: docs/examples.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples). Links may not work on Github.com.

# Examples

---

Wanna help? We need to migrate all of these examples from CodeSandbox to [here](https://github.com/final-form/react-final-form/tree/master/examples). PRs to help with that process would be greatly appreciated. 🙏

---

### [Simple Example](examples/simple)

Uses the built-in React inputs: `input`, `select`, and `textarea` to build a form with no validation.

### [Synchronous Record-Level Validation](examples/record-level-validation)

Introduces a whole-record validation function and demonstrates how to display errors next to fields using child render functions.

### [Synchronous Field-Level Validation](examples/field-level-validation)

Introduces field-level validation functions and demonstrates how to display errors next to fields using child render functions.

### [Synchronous Record-Level Validation (with delayed error render)](https://codesandbox.io/s/z2zqr008pm)

Sometimes you want to give your user a chance to make it through a brief invalid value on their way to a valid one, e.g. a date string that needs two numbers on either side of a slash. With a simple delayed rendering component, this becomes easy. Plus, the error will disappear immediately when the user fixes the problem.

### [Asynchronous Field-Level Validation](https://codesandbox.io/s/wy7z7q5zx5)

Demonstrates how field-level validation rules may be asynchronous (return a
`Promise`), as well as how to show a "validating" spinner during the lifetime of
the `Promise`.

### [Hybrid Synchronous/Asynchronous Record-Level Validation](https://codesandbox.io/s/kl9n295n5)

Demonstrates how you can mix synchronous and asynchronous validation patterns at
the record-level, by returning errors synchronously, and falling back to an
asynchronous call (by returning a `Promise`) if sync validation is passing.

### [Submission Errors](examples/submission-errors)

Demonstrates how to return submission errors from failed submits. Notice that the `Promise` should _resolve_ to the submission error (not reject). Rejection is reserved for communications or server exceptions.

### [Third Party Components](https://codesandbox.io/s/40mr0v2r87)

Demonstrates how easy it is to use third party input components. All the third
party component really needs is `value` and `onChange`, but more complex
components can accept things like errors.

### Material-UI

- [Wrapper components](https://github.com/lookfirst/mui-rff) / [Codesandbox demo](https://codesandbox.io/s/react-final-form-material-ui-example-tqv09)

### 💥 [Performance Optimization Through Subscriptions](examples/subscriptions) 💥

Demonstrates how, by restricting which parts of form state the form component needs to render, it reduces the number of times the whole form has to rerender. Yet, if some part of form state is needed inside of it, the [`<FormSpy/>`](api/FormSpy) component can be used to attain it.

### [Strongly Typed Form and Field Values with TypeScript](https://codesandbox.io/s/strongly-typed-form-values-with-react-final-form-26jkd)

Demonstrates how to use JSX generics to strongly type fields, forcing only a component that can accept the type for that field.

### [Independent Error Component (with Render Props)](https://codesandbox.io/s/xoo3xq654p)

Demonstrates how to make an independent Error component to subscribe to and
display the error for any form field.

### [Independent Error Component (with Hooks)](https://codesandbox.io/s/react-final-form-independent-error-component-with-hooks-y1grn)

Demonstrates how to make an independent Error component, using Hooks, to subscribe to and
display the error for any form field.

### [Loading and Initializing Values](https://codesandbox.io/s/91w9ro3x9o)

Demonstrates how a form can be initialized, after fetching data, by passing in
`initialValues` as a prop.

### [Field Arrays](https://codesandbox.io/s/kx8qv67nk5)

Demostrates how to use the `<FieldArray/>` component, from
[`react-final-form-arrays`](https://github.com/final-form/react-final-form-arrays),
to render an array of inputs, as well as use `push`, `pop`, and `remove`
mutations.

### [Fields Component](https://codesandbox.io/s/pyrwplknom)

Wondering how to get field state from multiple fields at once?

People coming from Redux-Form might be wondering where the equivalent of Redux Form's `Fields` component is, as a way to get state from several fields at once. The answer is that it's not included in the library because it's so easy to write one recursively composing `Field` components together.

### [Calculated Fields](https://codesandbox.io/s/oq52p6v96y)

Demonstrates how to use the
[`final-form-calculate`](https://github.com/final-form/final-form-calculate)
decorator to achieve realtime field calculations through easily defined rules.

### [Field Warnings](https://codesandbox.io/s/m5qwxpr6o8)

Demonstrates how the power of subscriptions and mutators can be used to build a
warning engine: logic to display a message next to each field that is _not_ an
error (thus it does _not_ prevent form submission).

### [Reusable Field Groups](https://codesandbox.io/s/8z5jm6x80)

Demonstrates how fields can be grouped into reusable components.

### [Prefixed Fields](https://codesandbox.io/s/react-final-form-prefixed-fields-seiy8)

Demonstrates how the React context API can be used to provide a "prefix wrapper"
around fields to add structure to your form date. It's similar to how Redux Form's
[`FormSection`](https://redux-form.com/8.2.2/docs/api/formsection.md/) component works.
Between this and the [Reusable Field Groups](#reusable-field-groups) example, your
use case, if migrating from `FormSection` should be handled.

### [External Submit](https://codesandbox.io/s/1y7noyrlmq)

Demonstrates how you can use `document.getElementById()` or a closure to trigger
a submit from outside of the form. For more information, see
[How can I trigger a submit from outside the form?](https://final-form.org/docs/react-final-form/faq#how-can-i-trigger-a-submit-from-outside-my-form)

### [Wizard Form](examples/wizard)

Demonstrates how to use React Final Form to create a multi-page "wizard" form, with validation on each page.

### [Parse and Format (and Normalize)](https://codesandbox.io/s/10rzowm323)

Demonstrates how to use 🏁 React Final Form's `parse` and `format` props to control exactly how the data flows from the form state through the input and back to the form state. Notice that you can use `parse` to "normalize" your values.

### [Auto-Save with Debounce](https://codesandbox.io/s/5w4yrpyo7k)

Demonstrates how to use a `FormSpy` component to listen for value changes and automatically submit different values after a debounce period.

### [Auto-Save with Selective Debounce](https://codesandbox.io/s/98j0v46zj4)

Demonstrates how to use a `FormSpy` component to listen for value changes and automatically submit different values after a debounce period, but only does the debounce for certain specified fields, in this case, all the text fields.

### [Auto-Save on Field Blur](https://codesandbox.io/s/7k742qpo36)

Demonstrates how to use a `FormSpy` component to listen for values and active field changes to automatically submit values when fields are blurred.

### [Custom Validation Engine](https://codesandbox.io/s/kxxw4l0p9o)

Demonstrates how incredibly extensible `FormSpy`, the [`setFieldData` mutator](https://github.com/final-form/final-form-set-field-data), and render props are by implementing a custom validation engine completely apart from the built-in validation in 🏁 Final Form, thus allowing for special behaviors, like only validating a single field when that field is blurred.

### [Loading, Normalizing, Saving, and Reinitializing](https://codesandbox.io/s/xr0mvl1904)

Demonstrates how to make a wrapper component to handle loading, normalization of data, saving, and reinitializing of the form, to maintain `pristine`/`dirty` state with saved data.

### [🏎️ Downshift Type-Ahead](https://codesandbox.io/s/qzm43nn2mj)

Demonstrates how to use a [🏎️ Downshift](https://github.com/paypal/downshift) type-ahead component as an input.

### [Redux Example](https://codesandbox.io/s/4xq2qpzw79)

The only reason to keep your 🏁 Final Form form data in Redux is if you need to be able to read it from outside your form. This example demonstrates how to use a `FormSpy` to keep a copy of your form data in the Redux store. Note that the canonical authoritative version of the data still lives in 🏁 Final Form. If you need to _mutate_ your data via dispatching Redux actions, you should probably use [Redux Form](https://redux-form.com).

### [Conditional Fields](https://codesandbox.io/s/lm4p3m92q)

Sometimes you might want to conditionally show or hide some parts of your form depending on values the user has already provided for other form inputs. 🏁 React Final Form makes that very easy to do by creating a `Condition` component out of a `Field` component.

### [Listening for External Changes](https://codesandbox.io/s/3x989zl866)

By wrapping a stateful `ExternalModificationDetector` component in a `Field` component, we can listen for changes to a field's value, and by knowing whether or not the field is active, deduce when a field's value changes due to external influences.

### [Focus On First Error](https://codesandbox.io/s/6174kqr403)

Demonstrates how to incorporate the [🏁 Final Form Focus 🧐](https://github.com/final-form/final-form-focus) decorator to provide this functionality out of the box.

### [Credit Card Example](https://codesandbox.io/s/9y8vkrrx9o)

Demonstrates how to make an awesome credit card UX using [React Credit Cards](https://github.com/amarofashion/react-credit-cards).

### [Async Redux Submission](https://codesandbox.io/s/x71mx66z8w)

Want to use `redux-saga` or `redux-observable` to manage your form submissions? Now you can, using [`react-redux-promise-listener`](https://github.com/erikras/react-redux-promise-listener#react-redux-promise-listener) to convert your dispatched Redux actions into the `Promise` that 🏁 React Final Form is expecting for its `onSubmit` function.

### [Declarative Form Rules](https://codesandbox.io/s/52q597j2p)

What if you could define rules to update fields when other fields change _as components_? This example explores such possibilities. There's also [a Medium post](https://medium.com/@erikras/declarative-form-rules-c5949ea97366) about writing it, and creating a companion library, [`react-final-form-listeners`](https://github.com/final-form/react-final-form-listeners#-react-final-form-listeners).

### [Format String By Pattern](https://codesandbox.io/s/no20p7z3l)

Demonstrates how to use the library `format-string-by-pattern` to create input masks for your 🏁 React Final Form fields.

### [AsyncTypeahead and Redux](https://codesandbox.io/s/5m4w2909k)

Demonstrates creating an `AsyncTypeahead` to select github users, while storing the search results in the redux store and the form state (selected github users) via `react-final-form`. Also makes use of the [`setFieldData` mutator](https://github.com/final-form/final-form-set-field-data).

### [Format On Blur](https://codesandbox.io/s/3rp260ly51)

Demonstrates how to use the `formatOnBlur` prop to postpone the formatting of a form field value until the field loses focus. Very useful for formatting numbers, like currencies.

### [Styling with 🍭 Smooth-UI](https://codesandbox.io/s/40o45po3l4)

Demonstrates how to use the Smooth-UI styling library to make your forms look fabulous! All you really need is a higher order component that adapts The 🍭 Smooth-UI form controls to work with 🏁 React Final Form.

### [Styling with Chakra-UI](examples/chakra)

Demonstrates how to use the [Chakra UI](https://chakra-ui.com) styling library to make your forms look fabulous!

### [CLI Example](https://github.com/final-form/rff-cli-example) 🤯

Yes! You can actually use 🏁 React Final Form in a command line interface! Thanks to packages like [Ink](https://github.com/vadimdemedes/ink) and [Pastel](https://github.com/vadimdemedes/pastel), the power of 🏁 Final Form's form state management works just fine on the command line.


================================================
FILE: docs/faq.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/faq). Links may not work on Github.com.

# FAQ

Below are some frequently asked questions.

## Why not Redux-Form or Formik?

Those are both excellent form libraries. Like all engineering decisions, it depends on your requirements and what trade-offs you wish to make. Both Redux-Form and Formik have considerably larger bundle sizes. Compare [Formik](https://bundlephobia.com/result?p=formik) and [Redux Form](https://bundlephobia.com/result?p=redux-form) to [Final Form](https://bundlephobia.com/result?p=final-form) + [React Final Form](https://bundlephobia.com/result?p=react-final-form).

Redux-Form and React Final Form were both written by [@erikras](https://twitter.com/erikras), who recommends that, unless you _really_ need your form data intimately tied to Redux, you should start any new projects with React Final Form, and try to migrate any older Redux Form projects to it as well.

## Why no HOC?

The only benefit that higher order components provide over render props is access to the injected props from within component lifecycle methods. Plus, it only takes a single line of code to transform a component with a `render` (or `component`) prop into a HOC. If you really want a HOC, you can write your own:

```jsx
import { Form, Field } from 'react-final-form'

class MyForm extends React.Component {
  componentDidMount() {
    const { initialize } = this.props // access to injected props
    ajax.fetch('/myData').then(data => initialize(data))
  }

  render() {
    return <form onSubmit={this.props.handleSubmit}>...some fields...</form>
  }
}

// 👇 THIS LINE IS THE HOC 👇
export default props => <Form {...props} component={MyForm} />
```

Doing a HOC
[properly](https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/withRouter.js),
as a library should, with hoisted statics and `displayName` and `ref`, etc., is
a hassle and would add unnecessary bulk.

## How can I trigger a submit from outside my form?

This is a common question I see from people migrating from `redux-form`. There
are three possible solutions:

### Via the `form` attribute

You can provide the form id to a submit button.


```jsx
<button type="submit" form="myForm">Submit</button>
{/*                   ^^^^^^^^^^^^^ */}

<form id="myForm" onSubmit={handleSubmit}>
{/*   ^^^^^^^^^^^ */}
  ...fields go here...
</form>
```

### Via `document.getElementById()`

You can use the DOM to get a reference to your `<form>` element and dispatch a
submit event on it. Note that you cannot just call `submit()`, as this will not
trigger React's event handlers.

```jsx
<button onClick={() => {
  document.getElementById('myForm').submit() // ❌
}}>Submit</button>

<button onClick={() => {
  document.getElementById('myForm')
  .dispatchEvent(new Event('submit', { cancelable: true, bubbles:true })) // ✅
}}>Submit</button>

<form id="myForm" onSubmit={handleSubmit}>
  ...fields go here...
</form>
```

See [Sandbox Example](https://codesandbox.io/s/1y7noyrlmq).

### Via Closure

If you define a variable outside of your form, you can then set the value of
that variable to the `handleSubmit` function that 🏁 React Final Form gives you,
and then you can call that function from outside of the form.

```jsx
let submit
return (
  <div>
    <button onClick={submit}>Submit</button> // ❌ Not overwritten closure value
    <button onClick={event => submit(event)}>Submit</button> // ✅
    <Form
      onSubmit={onSubmit}
      render={({ handleSubmit }) => {
        submit = handleSubmit
        return <form>...fields go here...</form>
      }}
    />
  </div>
)
```

See [Sandbox Example](https://codesandbox.io/s/1y7noyrlmq).

### Via Redux Dead Drop

If you're already using Redux, you could potentially use the same mechanism that
`redux-form` uses:
[Redux Dead Drop](https://medium.com/@erikras/redux-dead-drop-1b9573705bec).

## Why can't I have numeric keys in an object?

So you want to have value structured like `{ 13: 'Bad Luck', 42: 'Meaning of Everything' }`, but you're getting an error. This is because the `setIn` engine in 🏁 Final Form uses the `isNaN`-ness of keys to determine whether or not it should create an object or an array when constructing deep data structures. Adding checks for `bracket[3]` syntax as opposed to `dot.3` syntax adds a _lot_ of complexity, and has consciously been avoided.

You will need to convert all your keys to `NaN` strings before initializing your form values, and then convert them back to numbers on submit. It's not that hard.

```jsx
const stringifyKeys = values =>
  Object.keys(values).reduce((result, key) => {
    result[`key${key}`] = values[key]
    return result
  }, {})

const destringifyKeys = values =>
  Object.keys(values).reduce((result, key) => {
    result[Number(key.substring(3))] = values[key]
    return result
  }, {})

<Form
  onSubmit={values => onSubmit(destringifyKeys(values))}
  initialValues={stringifyKeys(initialValues)}>
  ...
</Form>
```

## I'm changing form state on first render, e.g. with FormSpy, why are my changes not reflected?

As of `v5`, the only changes that occur during the first render that will cause the form to rerender are if adding field-level validation functions changes the validity of the form. You will need to put your side effect into either a React `useEffect` hook, or just call it in a `setTimeout` to allow the form to finish rendering and setting up its side effects before you go altering the state.


================================================
FILE: docs/getting-started.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/getting-started). Links may not work on Github.com.

# Getting Started

Before we jump right into code, you might want to learn a little bit about the [philosophy](philosophy) and origin story of React Final Form.

## Installation

```bash
npm install --save final-form react-final-form
```

or

```bash
yarn add final-form react-final-form
```

## Architecture

React Final Form is a thin React wrapper for [Final Form](/), which is a subscriptions-based form state management library that uses the [Observer pattern](https://en.wikipedia.org/wiki/Observer_pattern), so only the components that need updating are re-rendered as the form's state changes.

By default, **React Final Form subscribes to _all_ changes**, but if you want to fine tune your form to optimized blazing-fast perfection, you may specify only the form state that you care about for rendering your gorgeous UI. You can think of it a little like GraphQL's feature of only fetching the data your component needs to render, and nothing else.

## Code

Here's what it looks like in your code:

```jsx
import { Form, Field } from 'react-final-form'

const MyForm = () => (
  <Form
    onSubmit={onSubmit}
    validate={validate}
    render={({ handleSubmit }) => (
      <form onSubmit={handleSubmit}>
        <h2>Simple Default Input</h2>
        <div>
          <label>First Name</label>
          <Field name="firstName" component="input" placeholder="First Name" />
        </div>

        <h2>An Arbitrary Reusable Input Component</h2>
        <div>
          <label>Interests</label>
          <Field name="interests" component={InterestPicker} />
        </div>

        <h2>Render Function</h2>
        <Field
          name="bio"
          render={({ input, meta }) => (
            <div>
              <label>Bio</label>
              <textarea {...input} />
              {meta.touched && meta.error && <span>{meta.error}</span>}
            </div>
          )}
        />

        <h2>Render Function as Children</h2>
        <Field name="phone">
          {({ input, meta }) => (
            <div>
              <label>Phone</label>
              <input type="text" {...input} placeholder="Phone" />
              {meta.touched && meta.error && <span>{meta.error}</span>}
            </div>
          )}
        </Field>

        <button type="submit">Submit</button>
      </form>
    )}
  />
)
```

[Let's explore the API...](api)


================================================
FILE: docs/migration/formik.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/migration-guide/formik). Links may not work on Github.com.

# Migration from Formik

Good news! Because both React Final Form and Formik are second generation form libraries, they both copied much of their API from [Redux Form](https://redux-form.com), so, despite working very differently under the hood, there is a lot of overlap in their APIs.

## Props passed to `<Formik/>`

The following props passed to `<Formik/>` are more or less identical to those you can pass to [`<Form/>`](../api/Form):

- [`onSubmit`](../types/FormProps#onsubmit)
- [`initialValues`](../types/FormProps#initialvalues)
- [`validate`](../types/FormProps#validate)

The render props work the same way, except for [what is passed](#props-passed-by-formik).

- [`children`](../types/FormProps#children)
- [`component`](../types/FormProps#component)
- [`render`](../types/FormProps#render)

The only tricky one is:

- [`validateOnBlur`](../types/FormProps#validateonblur)

It's not the same at all. In Formik, `validateOnBlur` defaults to `true` and it allows you to tell Formik _not_ to validate on blur. React Final Form validates on every change by default, and setting `validateOnBlur` to `true` is a way to tell React Final Form to _only_ validate on blur (to _not_ validate on change).

## Props passed by `<Formik/>`

The following props passed into the render functions by `<Formik/>` are identical:

- [`dirty`](/docs/final-form/types/FormState#dirty)
- [`errors`](/docs/final-form/types/FormState#errors)
- [`touched`](/docs/final-form/types/FormState#touched)
- [`handleSubmit`](/docs/final-form/types/FormRenderProps#handlesubmit)

To migrate from Formik, you'd have to search and replace the following:

| Formik              | React Final Form                                            |
| ------------------- | ----------------------------------------------------------- |
| `isSubmitting`      | [`submitting`](/docs/final-form/types/FormState#submitting) |
| `isValid`           | [`valid`](/docs/final-form/types/FormState#valid)           |
| `isValidating`      | [`validating`](/docs/final-form/types/FormState#validating) |
| `resetForm()`       | [`form.reset()`](/docs/final-form/types/FormApi#reset)      |
| `submitForm()`      | [`form.submit()`](/docs/final-form/types/FormApi#submit)    |
| `setFieldTouched()` | [`form.blur()`](/docs/final-form/types/FormApi#blur)        |
| `setFieldValue()`   | [`form.change()`](/docs/final-form/types/FormApi#change)    |

## Props passed to `<Field/>`

The APIs of the [`<Field/>`](../api/Field) components are very similiar. They both have:

- [`name`](../types/FieldProps#name)
- [`children`](../types/FieldProps#children)
- [`component`](../types/FieldProps#component)
- [`render`](../types/FieldProps#render)
- [`validate`](../types/FieldProps#validate)

One difference is that Formik's `<Field/>` will default to `component="input"` if no rendering strategy is provided. React Final Form requires you to specify one of the render strategies.

## Props passed by `<Field/>`

The biggest difference is that Formik puts all the `name`, `onChange`, `onBlur`, and `value` into a prop called `field`, React Final Form puts them into a prop called `input`. So:

Formik:

```jsx
<Field
  name="lastName"
  render={({ field }) => <input {...field} placeholder="Last Name" />}
/>
```

React Final Form:

```jsx
<Field
  name="lastName"
  render={({ input }) => <input {...input} placeholder="Last Name" />}
  //         ^^^^^                  ^^^^^
/>
```

The other difference is that, while Formik just gives your field component the Formik instance to query for information about field state, React Final Form provides your field state for you in the `meta` prop. Things like [`active`](../types/FieldRenderProps#metaactive) (which Formik doesn't even track), [`dirty`](../types/FieldRenderProps#metadirty), [`pristine`](../types/FieldRenderProps#metapristine), [`valid`](../types/FieldRenderProps#metavalid), [`invalid`](../types/FieldRenderProps#metainvalid), [`touched`](../types/FieldRenderProps#metatouched), [`validating`](../types/FieldRenderProps#metavalidating), and [`visited`](../types/FieldRenderProps#metavisited) (also not in Formik).

## Formik's `<Form/>`

React Final Form doesn't provide a similar component, because it just doesn't seem that useful, and it's also trivial to write one yourself.

```jsx
import { useForm } from 'react-final-form'

const FormLikeFormik = props => {
  const form = useForm()
  return (
    <form
      {...props}
      onSubmit={event => {
        event.preventDefault()
        form.submit()
      }}
    />
  )
}
```

## Formik's `<ErrorMessage/>`

This component _does_ seem useful, and writing your own is a great introduction to React Final Form's subscription system.

### With `<Field/>`

```jsx
import { Field } from 'react-final-form'

const ErrorMessage = ({ name }) => (
  <Field name={name} subscription={{ error: true, touched: true }}>
    {({ meta: { error, touched } }) =>
      error && touched ? <span>{error}</span> : null
    }
  </Field>
)
```

...or, if you want to look cool...

### With Hooks

```jsx
import { useField } from 'react-final-form'

const ErrorMessage = ({ name }) => {
  const {
    meta: { error, touched }
  } = useField(name, { subscription: { error: true, touched: true } })
  return error && touched ? <span>{error}</span> : null
}
```

## Formik's `<FastField/>`

React Final Form's [`<Field/>`](../api/Field) has always, from day one, avoided rerenders when parts of the form state change that don't affect the field in question. On top of that, React Final Form's `<Field/>` provides a [`subscription`](../types/FieldProps#subscription) prop that allows you to have even more fine-grain control over _precisely_ which form state will cause your field to rerender.

## Formik's `connect()`

React Final Form has no higher order components, because [it's just not necessary](../faq#why-no-hoc). If you need access to the Final Form instance, you can use the [`useForm()`](../api/useForm) hook.

## A Diff

This is what would need to change to migrate the form on Formik's [Overview](https://jaredpalmer.com/formik/docs/overview#reducing-boilerplate) docs page to React Final Form.

```diff
 import React from 'react'
-import { Formik, Form, Field, ErrorMessage } from 'formik'
+import { Form, Field, useField } from 'react-final-form'

+// Obviously this could be reused across your project
+const ErrorMessage = ({ name, component }) => {
+  const {
+    meta: { error, touched }
+  } = useField(name, { subscription: { error: true, touched: true } })
+  return error && touched
+    ? React.createElement(component, null, error)
+    : null
+}

 const Basic = () => (
   <div>
     <h1>Any place in your app!</h1>
-    <Formik
+    <Form
       initialValues={{ email: '', password: '' }}
       validate={values => {
         let errors = {}
         if (!values.email) {
           errors.email = 'Required'
         } else if (
           !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
         ) {
           errors.email = 'Invalid email address'
         }
         return errors
       }}
-      onSubmit={(values, { setSubmitting }) => {
+      onSubmit={(values) => {
+        // final-form manages submitting status
+        // for you *if* you return a promise
+        return new Promise(resolve =>
         setTimeout(() => {
           alert(JSON.stringify(values, null, 2))
-          setSubmitting(false)
+          resolve()
         }, 400)
+        )
       }}
     >
-      {({ isSubmitting }) => (
-        <Form>
+      {({ handleSubmit, submitting }) => (
+        <form onSubmit={handleSubmit}>
-          <Field type="email" name="email" />
+          <Field type="email" name="email" component="input"/>
           <ErrorMessage name="email" component="div" />
-          <Field type="password" name="password" />
+          <Field type="password" name="password" component="input"/>
           <ErrorMessage name="password" component="div" />
-          <button type="submit" disabled={isSubmitting}>
+          <button type="submit" disabled={submitting}>
             Submit
           </button>
-        </Form>
+        </form>
       )}
-    </Formik>
+    </Form>
   </div>
 )

 export default Basic
```


================================================
FILE: docs/migration/redux-form.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/migration-guide/redux-form). Links may not work on Github.com.

# Migration from Redux Form

Good news! React Final Form was written by the same guy ([@erikras](https://twitter.com/erikras)) that wrote Redux Form, so much of the API is exactly the same. The primary difference is that, rather than "decorate" your form component with a Higher Order Component, you use React Final Form's [`<Form/>`](../api/Form) component to give you all your form state via a render prop. Most of the `config` properties from Redux Form maps directly onto the props to [`<Form/>`](../api/Form), e.g. [`initialValues`](../types/FormProps#initialvalues), [`onSubmit`](../types/FormProps#onsubmit), [`validate`](../types/FormProps#validate), etc.

### Step 1: Change your imports

```diff
 import React from 'react'
-import { reduxForm, Field } from 'redux-form'
+import { Form, Field } from 'react-final-form'
```

### Step 2: Surround your `<form/>` with a `<Form/>`

```diff
 import React from 'react'
 import { Form, Field } from 'react-final-form'

 const MyForm = props => {
   const { handleSubmit, pristine, reset, submitting } = props
   return (
+    <Form>
+      {() => (
         <form onSubmit={handleSubmit}>

           ...fields here...

         </form>
+      )}
+    </Form>
   )
 }
```

### Step 3: Move all your `config` values from `reduxForm()` to be props of `<Form/>`

```diff
 import React from 'react'
 import { Form, Field } from 'react-final-form'

 const MyForm = props => {
   const { handleSubmit, pristine, reset, submitting } = props
   return (
     <Form
+      initialValues={{
+        firstName: 'Dan'
+      }}
+      onSubmit={values => {
+        // send values to the cloud
+      }}
+      validate={values => {
+        // do validation here, and return errors object
+      }}
     >
      {() => (
        <form onSubmit={handleSubmit}>

          ...fields here...

        </form>
       )}
     </Form>
   )
 }

 export default reduxForm({
   form: 'myForm',
-   initialValues: {
-     firstName: 'Dan'
-   },
-   onSubmit: values => {
-     // send values to the cloud
-   },
-   validate: values => {
-     // do validation here, and return errors object
-   }
 })(MyForm)
```

### Step 4: Get form state from `<Form/>`, not as props

```diff
 import React from 'react'
 import { Form, Field } from 'react-final-form'

 const MyForm = props => {
-  const { handleSubmit, pristine, reset, submitting } = props
   return (
     <Form
       initialValues={{
         firstName: 'Dan'
       }}
       onSubmit={values => {
         // send values to the cloud
       }}
       validate={values => {
         // do validation here, and return errors object
       }}
     >
+      {({ handleSubmit, pristine, reset, submitting }) => (
         <form onSubmit={handleSubmit}>

           ...fields here...

         </form>
       )}
     </Form>
   )
 }

 export default reduxForm({
   form: 'myForm'
 })(MyForm)
```

### Step 5: Observe API changes

_Some_ of the API is slightly different. For example, rather than providing a `reset` function, the entire [`FormApi`](/docs/final-form/types/FormApi) object is provided, on which `reset()` is a function.

```diff
 import React from 'react'
 import { Form, Field } from 'react-final-form'

 const MyForm = props => {
   return (
     <Form
      initialValues={{
        firstName: 'Dan'
      }}
      onSubmit={values => {
        // send values to the cloud
      }}
      validate={values => {
        // do validation here, and return errors object
      }}
     >
-     {({ handleSubmit, pristine, reset, submitting }) => (
+     {({ handleSubmit, pristine, form, submitting }) => (
        <form onSubmit={handleSubmit}>

          ...fields here...

          <div>
            <button type="submit" disabled={submitting}>
              Submit
            </button>
            <button
              type="button"
              disabled={pristine || submitting}
-             onClick={reset}
+             onClick={form.reset}
            >
              Clear Values
            </button>
          </div>
        </form>
       )}
     </Form>
   )
 }

 export default reduxForm({
   form: 'myForm'
 })(MyForm)
```

### Step 6: Remove the HOC

Now you can just export your component. No HOC decorator needed! [Why?](../faq#why-no-hoc)

```diff
-export default reduxForm({
-  form: 'myForm'
-})(MyForm)
+export default MyForm
```

### Step 7: Error management

No more `SubmissionError` to throw, error management is made with the return value.
Have a look here to know more: https://final-form.org/docs/react-final-form/types/FormProps#onsubmit

### Step 8: Define your `renderField` functions inline (if you want)

With Redux Form, it was common to have to do something like this:

```jsx
// outside your render() method
const renderField = (field) => (
    <div className="input-row">
      <input {...field.input} type="text"/>
      {field.meta.touched && field.meta.error &&
       <span className="error">{field.meta.error}</span>}
    </div>
  )

// inside your render() method
<Field name="myField" component={renderField}/>
```

With React Final Form, you can define your render logic directly your JSX.

```jsx
// inside your render() method
<Field name="myField">
  {field => (
    <div className="input-row">
      <input {...field.input} type="text" />
      {field.meta.touched && field.meta.error && (
        <span className="error">{field.meta.error}</span>
      )}
    </div>
  )}
</Field>
```

It's a little easier to read, but it's less reusable. Large projects are going to create reusable field render functions. If you're migrating a mature project, you can probably continue to use your existing functions/components. [`<Field/>`](../api/Field) provides the same [`{ input, meta }` shape](../types/FieldRenderProps) that Redux Form does.

### The Full Diff

```diff
 import React from 'react'
-import { reduxForm, Field } from 'redux-form',
+import { Form, Field } from 'react-final-form'

 const MyForm = props => {
-  const { handleSubmit, pristine, reset, submitting } = props
   return (
+    <Form
+      initialValues={{
+        firstName: 'Dan'
+      }}
+      onSubmit={values => {
+        // send values to the cloud
+      }}
+      validate={values => {
+        // do validation here, and return errors object
+      }}
+    >
+      {({ handleSubmit, pristine, form, submitting }) => (
         <form onSubmit={handleSubmit}>
           <div>
             <Field
               name="firstName"
               component="input"
               type="text"
               placeholder="First Name"
             />
           </div>
           <div>
             <label>Last Name</label>
             <Field
               name="lastName"
               component="input"
               type="text"
               placeholder="Last Name"
             />
           </div>
           <div>
             <button type="submit" disabled={submitting}>
               Submit
             </button>
            <button
              type="button"
              disabled={pristine || submitting}
-             onClick={reset}
+             onClick={form.reset}
            >
              Clear Values
            </button>
           </div>
         </form>
+      )}
+    </Form>
   )
 }

-export default reduxForm({
-  form: 'myForm',
-  initialValues: {
-    firstName: 'Dan'
-  },
-  onSubmit: values => {
-    // send values to the cloud
-  },
-  validate: values => {
-    // do validation here, and return errors object
-  }
-})(MyForm)
+export default MyForm
```

### `<Fields/>`

If you're accustomed to being able to get the state of many fields at once using Redux Form's `<Fields/>`, you may be wondering why this library does not include it. The answer is that _most_ people don't need it, but if you do, you can write it yourself recursively, like this:

```tsx
const Fields = ({
  names,
  subscription,
  fieldsState = {},
  children,
  originalRender
}) => {
  if (!names.length) {
    return (originalRender || children)(fieldsState)
  }
  const [name, ...rest] = names
  return (
    <Field name={name} subscription={subscription}>
      {fieldState => (
        <Fields
          names={rest}
          subscription={subscription}
          originalRender={originalRender || children}
          fieldsState={{ ...fieldsState, [name]: fieldState }}
        />
      )}
    </Field>
  )
}
```

Here's a sandbox demonstrating its usage:

[![Edit 🏁React Final Form: Fields Component](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/pyrwplknom?fontsize=14)

### `<FieldArray/>`

React Final Form does not come with field arrays right out of the box. This is because many projects do not need them, and the [philosophy](../philosophy#modularity) of React Final Form is to keep bundle size small, but provide ways to add additional functionality when you need it.

You will need to install two additional packages, `final-form-arrays`, which provides array functionality to the core Final Form instance, and `react-final-form-arrays`, which contains the `<FieldArray/>` component. If you are accustomed to using Redux Form's `<FieldArray/>` component, you already know the API for React Final Form's `<FieldArray/>` component. It injects an "array-like" object called `fields`, which you can `map()` over to get the `string` names for each of the fields in the array. You pass these field names to the `<Field/>` component to render one of the fields in your array. It works just like in Redux Form.

```tsx
import arrayMutators from 'final-form-arrays'
import { FieldArray } from 'react-final-form-arrays'

const MyForm = () => (
  <Form
    onSubmit={onSubmit}
    mutators={{ ...arrayMutators }}
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IMPORTANT!
  >
    {({
      handleSubmit,
      form: {
        mutators: { push, pop } // injected from final-form-arrays above
      }
    }) => (
      <form onSubmit={handleSubmit}>
        ... other fields here maybe ...
        <button type="button" onClick={() => push('customers', undefined)}>
          Add Customer
        </button>
        <button type="button" onClick={() => pop('customers')}>
          Remove Customer
        </button>
        <FieldArray name="customers">
          {({ fields }) =>
            fields.map((name, index) => (
              <div key={name}>
                <label>Cust. #{index + 1}</label>
                <Field
                  name={`${name}.firstName`}
                  component="input"
                  placeholder="First Name"
                />
              </div>
            ))
          }
        </FieldArray>
      </form>
    )}
  </Form>
)
```

Here's a sandbox to demonstrate:

[![Edit 🏁 React Final Form - Field Arrays](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/distracted-bhaskara-kx8qv67nk5?fontsize=14)

### Cheat Code: The Lazy Way

⚠️ NOT RECOMMENDED ⚠️

There's some chance that you could get away with implementing this function that replicates what the `reduxForm()` decorator does:

```jsx
import { Form } from 'react-final-form'

const reactFinalForm = ({ form, ...config }) => component => props => (
  <Form {...config} {...props} component={component} />
)
```

Then you'd only have to change that one thing.

```diff
-export default reduxForm({
+export default reactFinalForm({
   form: 'myForm',
   initialValues: {
     firstName: 'Dan'
   },
   onSubmit: values => {
     // send values to the cloud
   },
   validate: values => {
     // do validation here, and return errors object
   }
 })(MyForm)
```

But cheats like this create technical debt, so do the right thing and refactor your forms to use render props. 😄


================================================
FILE: docs/philosophy.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/philosophy). Links may not work on Github.com.

# Philosophy

For several years, I ([@erikras](https://twitter.com/erikras)) actively maintained the first big form library in the React community, [Redux Form](https://redux-form.com). During those years, I learned many lessons, about open source and React, and saw hundreds of forms use cases from around the world. As Redux Form grew in popularity (and bundle size), I received a lot of feedback from the community. React Final Form is my answer to the concerns of the community.

## Talk

In this talk, I explain the journey through Redux Form to the conception and creation of React Final Form.

[Next Generation Forms with React Final Form – React Alicante 2018, Alicante, Spain](https://youtu.be/WoSzy-4mviQ)

## Goals

React Final Form strives to meet the following goals:

### Strongly Typed

React Final Form provides strong typing via both [Flow](https://flow.org) and [Typescript](https://www.typescriptlang.org) to allow you to catch common bugs _at coding time_.

### Modularity

Just because some forms can be complex doesn't mean that your users should need to download all that code for a simple form! React Final Form and Final Form break out complex functionality into separate packages, so the form state management core doesn't get bloated by complicated use cases. This allows you to _build the form library you need_ for every use case.

Also, this allows for...

### Minimal Bundle Size

React Final Form is a minimal wrapper around the _zero-dependency_ Final Form core. All React Final Form does is know how to get form values out of [`SyntheticEvent`](https://reactjs.org/docs/events.html) and manage field subscriptions to the form.

### High Performance

You probably won't need to fine-tune your form performance, but if your form grows and starts to lag, you'll be glad you've chosen React Final Form. Every bit of form and field state can be chosen _à la carte_ to trigger a rerender in React.

If you're familiar with Redux in React, it's a little bit like how you can use [selectors](https://redux.js.org/recipes/computing-derived-data) to specify exactly which "slice" of state you want your component to be notified about.

The result is that you can streamline your form for maximum performance.

[Ready to get started?](getting-started)


================================================
FILE: docs/types/FieldProps.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FieldProps). Links may not work on Github.com.

# `FieldProps`

These are props that you pass to [`<Field/>`](../api/Field). You must provide one of the ways to render: `component`, `render`, or `children`.

## `afterSubmit`

```ts
() => void
```

Optional.

A callback to notify fields after submission has completed successfully.

## `allowNull`

```ts
boolean
```

Optional. Defaults to `false`.

By default, if your value is `null`, [`<Field/>`](../api/Field) will convert it to `''`, to ensure
[controlled inputs](https://reactjs.org/docs/forms.html#controlled-components).

But if you pass `true` to `allowNull`, [`<Field/>`](..api/Field) will give you a `null` value.

## `beforeSubmit`

```ts
() => void | false
```

Optional.

A function to call just before calling `onSubmit`. If `beforeSubmit` returns `false`, the submission will be aborted. If one of your fields returns `false` on `beforeSubmit`, other fields may not have their `beforeSubmit` called, as the submission is aborted on the first one that returns `false`.

## `children`

```ts
((props: FieldRenderProps) => React.Node) | React.Node`
```

Optional. (if you specify [`component`](#component) or [`render`](#render))

A render function that is given [`FieldRenderProps`](FieldRenderProps), as well as any non-API props passed into the `<Field/>` component. For example, if you did...

```tsx
<Field name="myField" someArbitraryOtherProp={42}>
  {props => {
    console.log(props.someArbitraryOtherProp) // would print 42
    return <input {...props.input}/>
  }}
</Field>
```

Note that if you specify [`render`](#render) or [`component`](#component) _and_ `children`, `render` will be called, with `children` injected as if it were an additional prop. This can be especially useful for doing something like:

```tsx
<Field name="favoriteColor" component="select">
  <option value="FF0000">Red</option>
  <option value="00FF00">Green</option>
  <option value="0000FF">Blue</option>
</Field>
```

Related:

- [`FieldRenderProps`](FieldRenderProps)

## `component`

```ts
React.ComponentType<FieldRenderProps> | 'input' | 'select' | 'textarea'`
```

Optional. If you are not using `'input'`, `'select`' or `'textarea'`, it is recommended that you use [`children`](#children) or [`render`](#render).

Either the `string` name of one of the default HTML inputs, or a component that is given [`FieldRenderProps`](FieldRenderProps) as props, children and render props, as well as any non-API props passed into the `<Field/>` component. For example, if you did...

<!-- prettier-ignore -->
```tsx
<Field
  name="myField"
  someArbitraryOtherProp={42}
  component={MyFieldComp} />

const MyFieldComp = props => {
  console.log(props.someArbitraryOtherProp) // would print 42
  return <input {...props.input} />
}
```

Related:

- [`FieldRenderProps`](FieldRenderProps)

## `data`

```ts
Object
```

Optional.

Initial state for arbitrary values to be placed by mutators.

## `defaultValue`

```ts
any
```

Optional.
⚠️ You probably want [`initialValue`](#initialvalue)! ⚠️

The value of the field upon creation. _**This value is only needed if you want your field be `dirty` upon creation (i.e. for its value to be different from its initial value).**_

## `format`

<!-- prettier-ignore -->
```ts
(value: any, name: string) => any
```

Optional.

A function that takes the value from the form values and the name of the field and formats the value to give to the input. Common use cases include converting javascript `Date` values into a localized date string. Almost always used in conjunction with [`parse`](#parse).

**Note: If you would like to disable the default behavior of converting `undefined` to `''`, you can pass an [identity function](https://en.wikipedia.org/wiki/Identity_function), `v => v`, to `format`. If you do this, making sure your inputs are "controlled" is up to you.**

## `formatOnBlur`

```ts
boolean
```

Optional. Defaults to `false`.

If `true`, the `format` function will only be called when the field is blurred. If `false`, `format` will be called on every render.

## `initialValue`

```ts
any
```

Optional.

The initial value for the field. This value will be used to calculate `dirty` and `pristine` by comparing it to the current value of the field. If you want field to be `dirty` upon creation, you can set one value with `initialValue` and set the value of the field with `defaultValue`.

The value given here will override any `initialValues` given to the entire form.

## `isEqual`

<!-- prettier-ignore -->
```ts
(a: any, b: any) => boolean
```

Optional. Defaults to `===`.

A function to determine if two values are equal.

## `multiple`

```ts
boolean
```

Optional.

Only of use when using `component="select"` and you want a multiselect.

It will be added on your input component, or you may retrieve its value inside the "input" property of your custom components.

## `name`

```ts
string
```

**Required**

The name of your field. Field values may be deeply nested using dot-and-bracket syntax.

[Learn more about Field Names](/docs/final-form/field-names).

## `parse`

<!-- prettier-ignore -->
```ts
(value: any, name: string) => any
```

Optional.

A function that takes the value from the input and name of the field and converts the value into the value you want stored as this field's value in the form. Common usecases include converting strings into `Number`s or parsing localized dates into actual javascript `Date` objects. Almost always used in conjuction with [`format`](#format).

**Note: If would like to override the default behavior of converting `''` to `undefined`, you can pass an [identity function](https://en.wikipedia.org/wiki/Identity_function), `v => v`, to `parse`, thus allowing you to have form values of `''`.**

## `ref`

The `ref` is forwarded to the component provided by the `component` prop.

## `render`

<!-- prettier-ignore -->
```ts
(props: FieldRenderProps) => React.Node
```

Optional. (if you specify [`component`](#component) or [`children`](#children))

A render function that is given [`FieldRenderProps`](FieldRenderProps), as well as any non-API props passed into the `<Field/>` component. For example, if you did...

```tsx
<Field
  name="myField"
  someArbitraryOtherProp={42}
  render={props => {
    console.log(props.someArbitraryOtherProp) // would print 42
    return <input {...props.input} />
  }}
/>
```

Note that if you specify `render` _and_ [`children`](#children), `render` will be called, with `children` injected as if it were an additional prop.

Related:

- [`FieldRenderProps`](FieldRenderProps)

## `subscription`

```ts
{ [string]: boolean }
```

Optional. _Advanced Usage_

An object of the parts of [`FieldState`](/docs/final-form/types/FieldState) to subscribe to. If a subscription is provided, the [`<Field/>`](../api/Field) will only rerender when those parts of field state change.

If no `subscription` is provided, it will default to subscribing to _all_ field state changes. i.e. [`<Field/>`](../api/Field) will rerender whenever any part of the field state changes.

Related:

- [`FieldState`](/docs/final-form/types/FieldState)

## `type`

```ts
string
```

Optional.

If set to `"checkbox"` or `"radio"`, React Final Form will know to manage your values as a checkbox or radio button respectively. Results in a `checked` boolean inside the `input` value given to your render prop.

It will be added on your input component, or you may retrieve its value inside the "input" property of your custom components

## `validate`

```ts
(value: ?any, allValues: Object, meta: ?FieldState) => ?any
```

Optional.

A function that takes the field value, all the values of the form and the `meta` data about the field and returns an error if the value is invalid, or `undefined` if the value is valid.

⚠️ IMPORTANT ⚠️ – By default, in order to allow inline fat-arrow validation functions, the field will not rerender if you change your validation function to an alternate function that has a different behavior. If you need your field to rerender with a new validation function, you will need to update another prop on the `Field`, such as `key`. See the following sandbox for an example:

[![Edit Changing Field Level Validators](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/changing-field-level-validators-zc8ei?fontsize=14)

## `validateFields`

```ts
string[]
```

Optional.

An array of field names to validate when this field changes. If `undefined`,
_every_ field will be validated when this one changes; if `[]`, _only this
field_ will have its field-level validation function called when it changes; if
other field names are specified, those fields _and this one_ will be validated
when this field changes.

⚠️ IMPORTANT ⚠️ – By default, in order to allow inline `[]` syntax, the field will not rerender if you change your `validateFields` prop changes. If you need your field to rerender with a new `validateFields` setting, you will need to update another prop on the `Field`, such as `key`.

## `value`

```ts
any
```

Optional.

**This is only used for checkboxes and radio buttons!**

You must also include a `type="radio"` or `type="checkbox"` prop.

### Radio Buttons

The value of the radio button. The radio button will render as `checked` if and only if the value given here `===` the value for the field in the form.

### Checkboxes

#### With `value`

The checkbox will be `checked` if the value given in `value` is contained in the array that is the value for the field for the form. Checking the box will add the value to the array, and unchecking the checkbox will remove the value from the array.

#### Without `value`

The checkbox will be `checked` if the value is truthy. Checking the box will set the value to `true`, and unchecking the checkbox will set the value to `false`.


================================================
FILE: docs/types/FieldRenderProps.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FieldRenderProps). Links may not work on Github.com.

# `FieldRenderProps`

These are the props that [`<Field/>`](../api/Field) provides to your render function or component.

This object separates out the values and event handlers intended to be given to the input component from the `meta` data about the field. The `input` can be destructured directly into an `<input/>` like so: `<input {...props.input}/>`. Keep in mind that **the values in `meta` are dependent on you having subscribed to them** with the [`subscription`](FieldProps#subscription) prop.

## `input.name`

```ts
string
```

**Required**

The name of the field.

## `input.onBlur`

```ts
(?SyntheticFocusEvent<*>) => void`
```

**Required**

The `onBlur` function can take a `SyntheticFocusEvent` like it would if you had given it directly to an `<input/>` component, but you can also just call it: `props.input.onBlur()` to mark the field as blurred (inactive).

Related:

- [`SyntheticFocusEvent`](https://reactjs.org/docs/events.html#focus-events)

## `input.onChange`

```ts
(SyntheticInputEvent<*> | any) => void
```

**Required**

The `onChange` function can take a `SyntheticInputEvent` like it would if you had given it directly to an `<input/>` component (in which case it will read the value out of `event.target.value`), but you can also just call it: `props.input.onChange(value)` to update the value of the field.

Related:

- [`SyntheticInputEvent`](https://reactjs.org/docs/events.html#form-events)

## `input.onFocus`

```ts
(?SyntheticFocusEvent<*>) => void
```

**Required**

The `onFocus` function can take a `SyntheticFocusEvent` like it would if you had given it directly to an `<input/>` component, but you can also just call it: `props.input.onFocus()` to mark the field as focused (active).

Related:

- [`SyntheticFocusEvent`](https://reactjs.org/docs/events.html#focus-events)

## `input.value`

```ts
any
```

Optional. May not be present if you have not [subscribed](FieldProps#subscription) to `value`.

The current value of the field.

## `meta.active`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `active`.

Whether or not the field currently has focus.

## `meta.data`

A place for arbitrary values to be placed by mutators.

## `meta.dirty`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `dirty`.

`true` when the value of the field is not equal to the initial value (using the [`isEqual`](FieldProps#isequal) comparator provided to `<Field/>`), `false` if the values are equal.

## `meta.dirtySinceLastSubmit`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `dirtySinceLastSubmit`.

`true` when the value of the field is not equal to the value last submitted (using the [`isEqual`](FieldProps#isequal) comparator provided to `<Field/>`), `false` if the values are equal.

## `meta.error`

```ts
any
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `error`.

The current validation error for this field.

## `meta.initial`

```ts
any
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `initial`.

The initial value of the field. `undefined` if it was never initialized.

## `meta.invalid`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `invalid`.

`true` if the field has a validation error or a submission error. `false` otherwise.

## `meta.modified`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `modified`.

`true` if this field's value has ever been changed. `false` otherwise.

Once `true`, it will remain `true` for the lifetime of the field, or until the form is reset.

## `meta.modifiedSinceLastSubmit`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `modifiedSinceLastSubmit`.

`true` if this field's value has ever been changed since last submission. `false` otherwise.

Once `true`, it will remain `true` until the next submit action, or until the form is reset.

## `meta.pristine`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `pristine`.

`true` if the current value is `===` to the initial value, `false` if the values are `!==`.

## `meta.submitError`

```ts
any
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `submitError`.

The submission error for this field.

## `meta.submitFailed`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `submitFailed`.

`true` if a form submission has been tried and failed. `false` otherwise.

## `meta.submitSucceeded`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `submitSucceeded`.

`true` if the form has been successfully submitted. `false` otherwise.

## `meta.submitting`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `submitting`.

`true` if the form is currently being submitted asynchronously. `false` otherwise.

## `meta.touched`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `touched`.

`true` if this field has ever gained and lost focus. `false` otherwise.

Useful for knowing when to display error messages.

## `meta.valid`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `valid`.

`true` if this field has no validation or submission errors. `false` otherwise.

## `meta.validating`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `validating`.

`true` if this field is currently waiting on its asynchronous field-level validation function to resolve. `false` otherwise.

## `meta.visited`

```ts
boolean
```

Optional: May not be present if you have not [subscribed](FieldProps#subscription) to `visited`.

`true` if this field has ever gained focus. `false` otherwise.


================================================
FILE: docs/types/FormProps.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FormProps). Links may not work on Github.com.

# `FormProps`

These are the props that you pass to [`<Form/>`](../api/Form). You must provide one of the ways to render: `component`, `render`, or `children`. The rest are mostly just passed along to Final Form's [`Config`](/docs/final-form/types/Config).

## `children`

```ts
((props: FormRenderProps) => React.Node) | React.Node`
```

Optional. (if you specify [`component`](#component) or [`render`](#render))

A render function that is given [`FormRenderProps`](FormRenderProps), as well as any non-API props passed into the `<Form/>` component. For example, if you did...

```tsx
<Form onSubmit={onSubmit} someArbitraryOtherProp={42}>
  {props => {
    console.log(props.someArbitraryOtherProp) // would print 42
    return <form onSubmit={props.handleSubmit}> ... </form>
  }}
</Form>
```

Note that if you specify [`render`](#render) _and_ `children`, `render` will be called, with `children` injected as if it were an additional prop.

Related:

- [`FormRenderProps`](FormRenderProps)

## `component`

```ts
React.ComponentType<FormRenderProps>
```

Optional. It is recommended that you use [`children`](#children) or [`render`](#render).

A component that is given [`FormRenderProps`](FormRenderProps) as props, as well as any non-API props passed into the [`<Form/>`](../api/Form) component. For example, if you did...

<!-- prettier-ignore -->
```tsx
<Form
  onSubmit={onSubmit}
  component={MyFormComp}
  someArbitraryOtherProp={42} />

const MyFormComp = props => {
  console.log(props.someArbitraryOtherProp) // would print 42
  return <form onSubmit={props.handleSubmit}> ... </form>
}
```

Note that your component will be rendered using [`React.createElement()`](https://reactjs.org/docs/react-api.html#createelement) resulting in your component actually being in the React node tree, i.e. inspectable in [DevTools](https://github.com/facebook/react-devtools#react-developer-tools-).

Related:

- [`FormRenderProps`](FormRenderProps)

## `debug`

```ts
(
  state: FormState,
  fieldStates: { [string]: FieldState }
) => void
```

Optional.

A callback for debugging that receives the form state and the states of
all the fields. It's called _on every state change_. A typical thing to pass in
might be `console.log`.

Related:

- [`FormState`](/docs/final-form/types/FormState)
- [`FieldState`](/docs/final-form/types/FieldState)

## `decorators`

```ts
Decorator[]
```

Optional.

An array of decorators to apply to the form. [`<Form/>`](../api/Form) will undecorate the form on unmount.

Related:

- [`Decorator`](/docs/final-form/types/Decorator)

## `form`

```ts
FormApi
```

Optional. _Advanced Usage_

If you'd like to construct your own Final Form `form` instance using [`createForm()`](/docs/final-form/api#createform), you may do so and pass it into [`<Form/>`](../api/Form) as a prop. Doing so will ignore all the other config props.

Related:

- [`FormApi`](/docs/final-form/types/FormApi)

## `initialValues`

```ts
FormValues | Object
```

Optional.

The initial values of your form. These will also be used to compare against the
current values to calculate `pristine` and `dirty`.

If you are using Typescript, these values must be the same type as the object given to your [`onSubmit`](#onsubmit) function.

## `initialValuesEqual`

```ts
(Object | undefined, Object | undefined) => boolean
```

Optional.

A predicate to determine whether or not the [`initialValues`](#initialvalues) prop has changed, i.e. to know if the form needs to be reinitialized with the new values. Useful for passing in a "deep equals" function if you need to. Defaults to "shallow equals".

## `keepDirtyOnReinitialize`

```ts
boolean
```

Optional.

If `true`, only pristine values will be overwritten when `initialize(newValues)` is called. This can be useful for allowing a user to continue to edit a record while the record is being saved asynchronously, and the form is reinitialized to the saved values when the save is successful. Defaults to `false`.

## `mutators`

```ts
{ [string]: Mutator }
```

Optional.

Named mutator functions.

Related:

- [Mutator](/docs/final-form/types/Mutator)

## `onSubmit`

```ts
(
  values: FormValues,
  form: FormApi,
  callback: ?(errors: ?Object) => void
) => ?Object | Promise<?Object> | void
```

**Required.**

Function to call when the form is submitted. There are three possible ways to
write an `onSubmit` function:

### 1. Synchronous

Returns `undefined` on success, or an `Object` of submission errors on failure.

### 2. Asynchronous with a callback

Returns `undefined`, calls `callback()` with no arguments on success, or with an `Object` of submission errors on failure.

### 3. Asynchronous with a `Promise`

Returns a `Promise<?Object>` that resolves with no value on success or _resolves_ with an `Object` of submission errors on failure. The reason it _resolves_ with errors is to leave rejection for when there is a server or communications error.

### Submission Errors

Submission errors must be in the same shape as the values of the form. You may
return a generic error for the whole form (e.g. `'Login Failed'`) using the
special [`FORM_ERROR`](/docs/final-form/api#form_error) string key.

Related:

- [`FormApi`](/docs/final-form/types/FormApi)

## `render`

<!-- prettier-ignore -->
```ts
(props: FormRenderProps) => React.Node
```

Optional. (if you specify [`component`](#component) or [`children`](#children))

A render function that is given [`FormRenderProps`](FormRenderProps), as well as any non-API props passed into the `<Form/>` component. For example, if you did...

```tsx
<Form
  onSubmit={onSubmit}
  someArbitraryOtherProp={42}
  render={props => {
    console.log(props.someArbitraryOtherProp) // would print 42
    return <form onSubmit={props.handleSubmit}> ... </form>
  }}
/>
```

Note that if you specify `render` _and_ [`children`](#children), `render` will be called, with `children` injected as if it were an additional prop.

Related:

- [`FormRenderProps`](FormRenderProps)

## `subscription`

```ts
{ [string]: boolean }
```

Optional. _Advanced Usage_

An object of the parts of [`FormState`](/docs/final-form/types/FormState) to subscribe to. If a subscription is provided, the [`<Form/>`](../api/Form) will only rerender when those parts of form state change.

If no `subscription` is provided, it will default to subscribing to _all_ form state changes. i.e. [`<Form/>`](../api/Form) will rerender whenever any part of the form state changes.

Related:

- [`FormState`](/docs/final-form/types/FormState)

## `validate`

```ts
(values: FormValues) => Object | Promise<Object>
```

Optional.

A whole-record validation function that takes all the values of the form and returns any validation errors. There are two possible ways to write a `validate` function:

### 1. Synchronous

Returns `{}` or `undefined` when the values are valid, or an `Object` of validation errors when the values are invalid.

### 2. Asynchronous with a `Promise`

Returns a `Promise<?Object>` that resolves with no value on success or _resolves_ with an `Object` of validation errors on failure. The reason it _resolves_ with errors is to leave _rejection_ for when there is a server or communications error.

### Validation Errors

Validation errors must be in the same shape as the values of the form. You may return a generic error for the whole form using the special [`FORM_ERROR`](/docs/final-form/api#form_error) string key.

## `validateOnBlur`

```ts
boolean
```

Optional.

If `true`, validation will happen on blur. If `false`, validation will happen on change. Defaults to `false`.


================================================
FILE: docs/types/FormRenderProps.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FormRenderProps). Links may not work on Github.com.

# `FormRenderProps`

These are the props that [`<Form/>`](../api/Form) provides to your render function or component. Keep in mind that the values you receive here are dependent upon which values of [`FormState`](/docs/final-form/types/FormState) you have subscribed to with the [`subscription` prop](FormProps#subscription).

This object contains everything in Final Form's [`FormState`](/docs/final-form/types/FormState) as well as:

## `form`

```ts
FormApi
```

The Final Form [`FormApi`](/docs/final-form/types/FormApi).

## `handleSubmit`

```ts
(?SyntheticEvent<HTMLFormElement>) => ?Promise<?Object>
```

A function intended for you to give directly to the `<form>` tag:

<!-- prettier-ignore -->
```jsx
<form onSubmit={handleSubmit}>
... fields go here ...
</form>
```

The function's return type depends on the way the [`onSubmit` function is written](../types/FormProps#onsubmit).

Related:

- [`SyntheticEvent`](https://reactjs.org/docs/events.html)


================================================
FILE: docs/types/FormSpyProps.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FormSpyProps). Links may not work on Github.com.

# `FormSpyProps`

These are the props that you pass to [`<FormSpy/>`](../api/FormSpy). If you do not provide an [`onChange`](#onchange) callback, you must provide one of the ways to render: [`component`](#component), [`render`](#render), or [`children`](#children).

## `children`

<!-- prettier-ignore -->
```ts
(props: FormRenderProps) => React.Node
```

Optional. (if you specify [`component`](#component) or [`render`](#render) or [`onChange`](#onchange))

A render function that is given [`FormSpyRenderProps`](FormSpyRenderProps), as well as any non-API props passed into the `<FormSpy/>` component. For example, if you did...

```tsx
<FormSpy someArbitraryOtherProp={42}>
  {props => {
    console.log(props.someArbitraryOtherProp) // would print 42
    return <pre>{JSON.stringify(props.values, undefined, 2)}</pre>
  }}
</FormSpy>
```

Note that if you specify [`render`](#render) _and_ `children`, `render` will be called, with `children` injected as if it were an additional prop.

**Will not be called if an [`onChange`](#onchange) callback is specified.**

Related:

- [`FormSpyRenderProps`](FormSpyRenderProps)

## `component`

```ts
React.ComponentType<FormSpyRenderProps>
```

Optional. It is recommended that you use [`children`](#children) or [`render`](#render).

A component that is given [`FormSpyRenderProps`](FormSpyRenderProps) as props, as well as any non-API props passed into the [`<FormSpy/>`](../api/FormSpy) component. For example, if you did...

<!-- prettier-ignore -->
```tsx
<FormSpy
  component={MyFormSpyComp}
  someArbitraryOtherProp={42} />

const MyFormSpyComp = props => {
  console.log(props.someArbitraryOtherProp) // would print 42
  return <pre>{JSON.stringify(props.values, undefined, 2)}</pre>
}
```

Note that your component will be rendered using [`React.createElement()`](https://reactjs.org/docs/react-api.html#createelement) resulting in your component actually being in the React node tree, i.e. inspectable in [DevTools](https://github.com/facebook/react-devtools#react-developer-tools-).

**Will not be called if an [`onChange`](#onchange) callback is specified.**

Related:

- [`FormSpyRenderProps`](FormSpyRenderProps)

## `onChange`

```ts
(formState: FormState) => void
```

Optional.

A change listener that will be called with form state whenever the form state, as subscribed to by the [`subscription`](#subscription) prop, has changed.

When an `onChange` prop is provided, the [`<FormSpy/>`](../api/FormSpy) will not render anything.

## `render`

<!-- prettier-ignore -->
```ts
(props: FormSpyRenderProps) => React.Node
```

Optional. (if you specify [`component`](#component) or [`children`](#children) or [`onChange`](#onchange))

A render function that is given [`FormSpyRenderProps`](FormSpyRenderProps), as well as any non-API props passed into the `<FormSpy/>` component. For example, if you did...

```tsx
<FormSpy
  someArbitraryOtherProp={42}
  render={props => {
    console.log(props.someArbitraryOtherProp) // would print 42
    return <pre>{JSON.stringify(props.values, undefined, 2)}</pre>
  }}
/>
```

Note that if you specify `render` _and_ [`children`](#children), `render` will be called, with `children` injected as if it were an additional prop.

**Will not be called if an [`onChange`](#onchange) callback is specified.**

Related:

- [`FormSpyRenderProps`](FormSpyRenderProps)

## `subscription`

```ts
{ [string]: boolean }
```

Optional. _Advanced Usage_

An object of the parts of [`FormState`](/docs/final-form/types/FormState) to subscribe to. If a subscription is provided, the [`<FormSpy/>`](../api/FormSpy) will only rerender when those parts of form state change.

If no `subscription` is provided, it will default to subscribing to _all_ form state changes. i.e. [`<FormSpy/>`](../api/FormSpy) will rerender whenever any part of the form state changes.

Related:

- [`FormState`](/docs/final-form/types/FormState)


================================================
FILE: docs/types/FormSpyRenderProps.md
================================================
# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FormSpyRenderProps). Links may not work on Github.com.

# `FormSpyRenderProps`

These are the props that [`<FormSpy/>`](../api/FormSpy) provides to your render function or component. Keep in mind that the values you receive here are dependent upon which values of [`FormState`](/docs/final-form/types/FormState) you have subscribed to with the [`subscription`](FormSpyProps#subscription) prop.

This object contains everything in Final Form's [`FormState`](/docs/final-form/types/FormState) as well as:

## `form`

```ts
FormApi
```

The Final Form [`FormApi`](/docs/final-form/types/FormApi).


================================================
FILE: eslint.config.mjs
================================================
import js from "@eslint/js";
import typescriptParser from "@typescript-eslint/parser";
import typescriptPlugin from "@typescript-eslint/eslint-plugin";
import reactPlugin from "eslint-plugin-react";
import reactHooks from "eslint-plugin-react-hooks";
import jsxA11y from "eslint-plugin-jsx-a11y";

// Manually defined globals to avoid issues with the 'globals' package
const browserGlobals = {
  window: "readonly",
  document: "readonly",
  navigator: "readonly",
  console: "readonly",
  fetch: "readonly",
  setTimeout: "readonly",
  HTMLInputElement: "readonly",
  HTMLElement: "readonly",
};
const nodeGlobals = {
  process: "readonly",
  require: "readonly",
  module: "readonly",
  exports: "writable",
  __dirname: "readonly",
  __filename: "readonly",
  global: "readonly",
  console: "readonly",
};
const jestGlobals = {
  jest: "readonly",
  describe: "readonly",
  it: "readonly",
  expect: "readonly",
  afterEach: "readonly",
  beforeEach: "readonly",
  test: "readonly",
  beforeAll: "readonly",
  afterAll: "readonly",
};

export default [
  // Base config for all JS/TS files (can be overridden)
  {
    ignores: [
      "node_modules/**",
      "dist/**",
      "coverage/**",
      "*.min.js",
      "examples/**",
    ],
  },
  js.configs.recommended, // Apply ESLint recommended rules globally (respecting ignores)

  // Configuration for TypeScript files in src/
  {
    files: ["src/**/*.{ts,tsx}"],
    ignores: ["**/*.test.ts", "**/*.test.tsx"],
    languageOptions: {
      parser: typescriptParser,
      parserOptions: {
        ecmaFeatures: { jsx: true },
        ecmaVersion: "latest",
        sourceType: "module",
        project: "./tsconfig.json", // Project-aware linting for src files
      },
      globals: {
        ...browserGlobals,
        ...nodeGlobals,
        ...jestGlobals,
        es2021: true,
      },
    },
    plugins: {
      "@typescript-eslint": typescriptPlugin,
      react: reactPlugin,
      "react-hooks": reactHooks,
      "jsx-a11y": jsxA11y,
    },
    rules: {
      ...typescriptPlugin.configs.recommended.rules,
      ...reactPlugin.configs.recommended.rules,
      "react/react-in-jsx-scope": "off",
      "react/jsx-uses-react": "off",
      "jsx-a11y/href-no-hash": "off",
      "react-hooks/rules-of-hooks": "error",
      "react-hooks/exhaustive-deps": "warn",
      "@typescript-eslint/no-unused-vars": [
        "warn",
        { argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
      ],
      "@typescript-eslint/no-explicit-any": "off",
      "@typescript-eslint/no-non-null-assertion": "off",
      "@typescript-eslint/explicit-module-boundary-types": "off",
      "@typescript-eslint/no-unsafe-function-type": "off",
      "react/no-children-prop": "off",
      "@typescript-eslint/no-unused-expressions": "off",
      "no-undef": "off", // TypeScript handles this for .ts/.tsx
    },
    settings: {
      react: { version: "detect" },
    },
  },

  // Configuration for TypeScript test files in typescript/ (for dtslint, no project parsing)
  {
    files: ["typescript/**/*.ts", "typescript/**/*.tsx"],
    languageOptions: {
      parser: typescriptParser,
      parserOptions: {
        ecmaFeatures: { jsx: true }, // Allow JSX in .tsx test files
        ecmaVersion: "latest",
        sourceType: "module",
      },
      globals: {
        ...browserGlobals,
        ...nodeGlobals,
        ...jestGlobals,
        es2021: true,
      }, // General globals for TS test files
    },
    plugins: {
      "@typescript-eslint": typescriptPlugin,
      // Add other plugins if relevant for these test files, e.g., react if they use React
    },
    rules: {
      // Lighter ruleset for .d.ts test files or general TS syntax checking
      "@typescript-eslint/no-explicit-any": "off",
      "@typescript-eslint/no-unused-vars": "off",
      "no-unused-vars": "off",
      "no-undef": "off", // Disable no-undef for TypeScript files
    },
  },

  // Configuration for JavaScript files (e.g., .js test files in src/, config files)
  {
    files: ["**/*.js", "**/*.jsx"],
    ignores: ["examples/**"],
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module",
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
      },
      globals: {
        ...browserGlobals,
        ...nodeGlobals,
        ...jestGlobals,
        es2021: true,
      },
    },
    plugins: {
      react: reactPlugin,
    },
    rules: {
      "no-undef": "error",
      "react/jsx-uses-vars": "warn",
      "react/react-in-jsx-scope": "off",
      "no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], // Enforce _ prefix for unused vars in JS files
    },
  },

  // Configuration for .mjs files (ES modules in Node.js environment)
  {
    files: ["**/*.mjs"],
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module",
      globals: {
        ...nodeGlobals,
      },
    },
    rules: {
      "no-undef": "error",
    },
  },

  // Specific overrides for ALL test files (JS and TS)
  {
    files: ["**/*.test.js", "**/*.test.jsx", "**/*.test.ts", "**/*.test.tsx"],
    rules: {
      "no-unused-vars": "off",
      "@typescript-eslint/no-unused-vars": "off",
    },
  },
];


================================================
FILE: examples/async-field-level-validation/Spinner.js
================================================
import styled, { keyframes } from "styled-components";

const rotation = keyframes`
    from {
      -webkit-transform: rotate(0deg);
    }
    to {
      -webkit-transform: rotate(359deg);
    }
`;
export default styled.div`
  height: 12px;
  width: 12px;
  margin-left: 5px;
  position: absolute;
  right: 0;
  top: 0;
  animation: ${rotation} 0.6s infinite linear;
  border-left: 6px solid rgba(0, 174, 239, 0.15);
  border-right: 6px solid rgba(0, 174, 239, 0.15);
  border-bottom: 6px solid rgba(0, 174, 239, 0.15);
  border-top: 6px solid rgba(0, 174, 239, 0.8);
  border-radius: 100%;
`;


================================================
FILE: examples/async-field-level-validation/Styles.js
================================================
import styled, { css } from "styled-components";

const btn = (light, dark) => css`
  white-space: nowrap;
  display: inline-block;
  border-radius: 5px;
  padding: 5px 15px;
  font-size: 16px;
  color: white;
  &:visited {
    color: white;
  }
  background-image: linear-gradient(${light}, ${dark});
  border: 1px solid ${dark};
  &:hover {
    background-image: linear-gradient(${light}, ${dark});
    &[disabled] {
      background-image: linear-gradient(${light}, ${dark});
    }
  }
  &:visited {
    color: black;
  }
  &[disabled] {
    opacity: 0.6;
    cursor: not-allowed;
  }
`;

const btnDefault = css`
  ${btn("#ffffff", "#d5d5d5")} color: #555;
`;

const btnPrimary = btn("#4f93ce", "#285f8f");

export default styled.div`
  font-family: sans-serif;

  h1 {
    text-align: center;
    color: #222;
  }

  h2 {
    text-align: center;
    color: #222;
  }

  & > div {
    text-align: center;
  }

  a {
    display: block;
    text-align: center;
    color: #222;
    margin-bottom: 10px;
  }

  form {
    max-width: 500px;
    margin: 10px auto;
    border: 1px solid #ccc;
    padding: 20px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
    border-radius: 3px;
    position: relative;

    & > div {
      display: flex;
      flex-flow: row nowrap;
      line-height: 2em;
      margin: 5px;
      & > label {
        color: #333;
        width: 110px;
        font-size: 1em;
        line-height: 32px;
      }
      & > input,
      & > select,
      & > textarea {
        flex: 1;
        padding: 3px 5px;
        font-size: 1em;
        margin-left: 15px;
        border: 1px solid #ccc;
        border-radius: 3px;
      }
      & > input[type="checkbox"] {
        margin-top: 7px;
      }
      & > div {
        margin-left: 16px;
        & > label {
          display: block;
          & > input {
            margin-right: 3px;
          }
        }
      }
      & > span {
        line-height: 32px;
        margin-left: 10px;
        color: #800;
        font-weight: bold;
      }
    }
    & > .buttons {
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      margin-top: 15px;
    }
    button {
      margin: 0 10px;
      &[type="submit"] {
        ${btnPrimary};
      }
      &[type="button"] {
        ${btnDefault};
      }
    }
    pre {
      border: 1px solid #ccc;
      background: rgba(0, 0, 0, 0.1);
      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
      padding: 20px;
    }
  }
`;


================================================
FILE: examples/async-field-level-validation/index.js
================================================
import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import Spinner from "./Spinner";
import { Form, Field } from "react-final-form";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const onSubmit = async (values) => {
  await sleep(300);
  window.alert(JSON.stringify(values, undefined, 2));
};

const required = (value) => (value ? undefined : "Required");
const mustBeNumber = (value) => (isNaN(value) ? "Must be a number" : undefined);
const minValue = (min) => (value) =>
  isNaN(value) || value >= min ? undefined : `Should be greater than ${min}`;
const composeValidators =
  (...validators) =>
  (value) =>
    validators.reduce(
      (error, validator) => error || validator(value),
      undefined,
    );

const simpleMemoize = (fn) => {
  let lastArg;
  let lastResult;
  return (arg) => {
    if (arg !== lastArg) {
      lastArg = arg;
      lastResult = fn(arg);
    }
    return lastResult;
  };
};

const usernameAvailable = simpleMemoize(async (value) => {
  if (!value) {
    return "Required";
  }
  await sleep(400);
  if (
    ~["john", "paul", "george", "ringo"].indexOf(value && value.toLowerCase())
  ) {
    return "Username taken!";
  }
});

const App = () => (
  <Styles>
    <h1>
      <span role="img" aria-label="final form flag">
        🏁
      </span>{" "}
      React Final Form Example
    </h1>
    <h2>Asynchronous Field-Level Validation</h2>
    <a href="https://github.com/erikras/react-final-form#-react-final-form">
      Read Docs
    </a>
    <div>Usernames John, Paul, George or Ringo will fail async validation.</div>
    <Form
      onSubmit={onSubmit}
      render={({ handleSubmit, reset, submitting, pristine, values }) => (
        <form onSubmit={handleSubmit}>
          <Field name="username" validate={usernameAvailable}>
            {({ input, meta }) => (
              <div>
                <label>Username</label>
                <input {...input} type="text" placeholder="Username" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
                {meta.validating && <Spinner />}
              </div>
            )}
          </Field>
          <Field name="lastName" validate={required}>
            {({ input, meta }) => (
              <div>
                <label>Last Name</label>
                <input {...input} type="text" placeholder="Last Name" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>
          <Field
            name="age"
            validate={composeValidators(required, mustBeNumber, minValue(18))}
          >
            {({ input, meta }) => (
              <div>
                <label>Age</label>
                <input {...input} type="text" placeholder="Age" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>
          <div className="buttons">
            <button type="submit" disabled={submitting}>
              Submit
            </button>
            <button
              type="button"
              onClick={reset}
              disabled={submitting || pristine}
            >
              Reset
            </button>
          </div>
          <pre>{JSON.stringify(values, 0, 2)}</pre>
        </form>
      )}
    />
  </Styles>
);

render(<App />, document.getElementById("root"));


================================================
FILE: examples/async-field-level-validation/package.json
================================================
{
  "name": "react-final-form-asynchronous-field-level-validation-example",
  "version": "1.0.0",
  "description": "This example demonstrates how field-level validation functions may be asynchronous.",
  "keywords": [
    "react-final-form",
    "final-form",
    "react",
    "validation",
    "asynchronous"
  ],
  "main": "index.js",
  "dependencies": {
    "final-form": "4.20.4",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-final-form": "6.5.3",
    "styled-components": "4.2.0"
  }
}


================================================
FILE: examples/async-field-level-validation/readme.md
================================================
# Asynchronous Field-Level Validation

[![Edit react-final-form-async-field-level-validation-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/wy7z7q5zx5)


================================================
FILE: examples/async-redux-submission/Styles.js
================================================
import styled, { css } from "styled-components";

const btn = (light, dark) => css`
  white-space: nowrap;
  display: inline-block;
  border-radius: 5px;
  padding: 5px 15px;
  font-size: 16px;
  color: white;
  &:visited {
    color: white;
  }
  background-image: linear-gradient(${light}, ${dark});
  border: 1px solid ${dark};
  &:hover {
    background-image: linear-gradient(${light}, ${dark});
    &[disabled] {
      background-image: linear-gradient(${light}, ${dark});
    }
  }
  &:visited {
    color: black;
  }
  &[disabled] {
    opacity: 0.6;
    cursor: not-allowed;
  }
`;

const btnDefault = css`
  ${btn("#ffffff", "#d5d5d5")} color: #555;
`;

const btnPrimary = btn("#4f93ce", "#285f8f");
const btnDanger = btn("#e27c79", "#c9302c");

export default styled.div`
  font-family: sans-serif;

  h1 {
    text-align: center;
    color: #222;
  }

  h2 {
    text-align: center;
    color: #222;
  }

  & > div {
    text-align: center;
  }

  a {
    display: block;
    text-align: center;
    color: #222;
    margin-bottom: 10px;
  }

  p {
    max-width: 500px;
    margin: 10px auto;
    & > a {
      display: inline;
    }
  }

  .loading {
    font-size: 2em;
    font-weight: bold;
    text-align: center;
    margin: 50px;
  }

  form,
  div.form {
    text-align: left;
    max-width: 500px;
    margin: 10px auto;
    border: 1px solid #ccc;
    padding: 20px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
    border-radius: 3px;
    position: relative;

    & > div {
      display: flex;
      flex-flow: row nowrap;
      line-height: 2em;
      position: relative;
      padding: 8px 5px;
      border: 1px solid transparent;
      &.active {
        background-color: paleturquoise;
        border-color: turquoise;
      }
      & > label {
        color: #333;
        width: 110px;
        min-width: 60px;
        font-size: 1em;
        line-height: 32px;
      }
      & > input,
      & > .downshift > input,
      & > select,
      & > textarea {
        flex: 1;
        padding: 6px 9px;
        font-size: 1em;
        margin-left: 15px;
        border: 1px solid #ccc;
        border-radius: 3px;
        &[disabled] {
          background: #eee;
        }
      }
      & > input[type="checkbox"] {
        margin-top: 7px;
      }
      & > div {
        margin-left: 16px;
        & > label {
          margin-left: 0;
          display: block;
          & > input {
            margin-right: 3px;
          }
        }
        &.downshift {
          margin-left: 0;
          padding-left: 15px;
          flex: 1;
          & > input {
            width: 100%;
            padding: 6px 5px;
            font-size: 1em;
            margin-left: 0;
            border: 1px solid #ccc;
            border-radius: 3px;
          }
        }
      }
      & > span {
        line-height: 32px;
        margin-left: 10px;
        color: #800;
        font-weight: bold;
      }
      & > button.remove {
        ${btnDanger};
      }
    }
    & > .buttons {
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      margin-top: 15px;
    }

    .error {
      display: flex;
      font-weight: bold;
      color: #800;
      flex-flow: row nowrap;
      justify-content: center;
    }
    pre {
      position: relative;
      border: 1px solid #ccc;
      background: rgba(0, 0, 0, 0.1);
      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
      padding: 20px;
    }
    .submitting {
      display: block;
      position: absolute;
      top: -5px;
      left: -5px;
      right: -5px;
      padding: 0;
      text-align: center;
      background: rgba(0, 0, 0, 0.4);
      color: white;
      z-index: 10;
      font-weight: bold;
      font-size: 0.8em;
    }
    .saving {
      font-size: 0.8em;
      font-weight: bold;
      color: darkblue;
      margin: 8px 0 0 7px;
    }
  }
  button {
    margin: 0 10px;
    &[type="submit"] {
      ${btnPrimary};
    }
    &[type="button"] {
      ${btnDefault};
    }
  }
  .downshift-options {
    border: 1px solid #ddd;
    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
    & > div {
      padding: 3px 5px;
    }
  }
`;


================================================
FILE: examples/async-redux-submission/asyncSubmissionMiddleware.js
================================================
import { REGISTER, REGISTER_SUCCESS } from "./registrationDuck";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const submit = async (values) => {
  await sleep(200);
  if (values.firstName === "John") {
    throw Error({ firstName: "No John's Allowed!" });
  }
  window.alert(JSON.stringify(values, 0, 2));
};

/** This is to mimic the behavior of one of the various Redux async middlewares */
const asyncSubmissionMiddleware = (store) => (next) => (action) => {
  if (action && action.type === REGISTER) {
    submit(action.payload).then(
      () => store.dispatch({ type: REGISTER_SUCCESS }),
      (errors) => {
        // NOTE!! We are passing REGISTER_SUCCESS here because 🏁 Final Form expects
        // submit errors to come back in a *resolved* promise.
        store.dispatch({ type: REGISTER_SUCCESS, payload: errors });
      },
    );
  }
  return next(action);
};

export default asyncSubmissionMiddleware;


================================================
FILE: examples/async-redux-submission/index.js
================================================
import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";
import store, { promiseListener } from "./store";
import {
  REGISTER,
  REGISTER_SUCCESS,
  REGISTER_FAILURE,
} from "./registrationDuck";
import MakeAsyncFunction from "react-redux-promise-listener";

const SubmitError = ({ name }) => (
  <Field
    name={name}
    subscription={{ submitError: true, dirtySinceLastSubmit: true }}
  >
    {({ meta: { submitError, dirtySinceLastSubmit } }) =>
      submitError && !dirtySinceLastSubmit ? <span>{submitError}</span> : null
    }
  </Field>
);

const App = () => (
  <Provider store={store}>
    <Styles>
      <h1>
        <span role="img" aria-label="final form flag">
          🏁
        </span>{" "}
        React Final Form
      </h1>
      <h2>Async Redux Submission</h2>
      <a href="https://github.com/erikras/react-final-form#-react-final-form">
        Read Docs
      </a>
      <p>
        Demonstrates how to use an async Redux side-effects library, like{" "}
        <code>redux-saga</code> to manage form submissions using{" "}
        <span role="img" aria-label="final form flag">
          🏁
        </span>{" "}
        React Final Form. Uses{" "}
        <a
          href="https://github.com/erikras/redux-promise-listener"
          target="_blank"
          rel="noopener noreferrer"
        >
          <code>redux-promise-listener</code>
        </a>{" "}
        and{" "}
        <a
          href="https://github.com/erikras/react-redux-promise-listener"
          target="_blank"
          rel="noopener noreferrer"
        >
          <code>react-redux-promise-listener</code>
        </a>{" "}
        libraries.
      </p>
      <p>Dispatched Redux actions can be found in the console.</p>
      <p>
        First name <code>John</code> will fail submit validation.
      </p>
      <MakeAsyncFunction
        listener={promiseListener}
        start={REGISTER}
        resolve={REGISTER_SUCCESS}
        reject={REGISTER_FAILURE}
      >
        {(onSubmit) => (
          <Form
            onSubmit={onSubmit}
            render={({ handleSubmit, form, submitting, pristine, values }) => (
              <form onSubmit={handleSubmit}>
                <div>
                  <label>First Name</label>
                  <Field
                    name="firstName"
                    component="input"
                    type="text"
                    placeholder="First Name"
                  />
                  <SubmitError name="firstName" />
                </div>
                <div>
                  <label>Last Name</label>
                  <Field
                    name="lastName"
                    component="input"
                    type="text"
                    placeholder="Last Name"
                  />
                  <SubmitError name="lastName" />
                </div>
                <div>
                  <label>Email</label>
                  <Field
                    name="email"
                    component="input"
                    type="email"
                    placeholder="Email"
                  />
                  <SubmitError name="email" />
                </div>
                <div>
                  <label>Favorite Color</label>
                  <Field name="favoriteColor" component="select">
                    <option />
                    <option value="#ff0000">
                      <span role="img" aria-label="red heart">
                        ❤️
                      </span>{" "}
                      Red
                    </option>
                    <option value="#00ff00">
                      <span role="img" aria-label="green heart">
                        💚
                      </span>{" "}
                      Green
                    </option>
                    <option value="#0000ff">
                      <span role="img" aria-label="blue heart">
                        💙
                      </span>{" "}
                      Blue
                    </option>
                  </Field>
                </div>
                <div className="buttons">
                  <button type="submit" disabled={submitting}>
                    Submit
                  </button>
                  <button
                    type="button"
                    onClick={form.reset}
                    disabled={submitting || pristine}
                  >
                    Reset
                  </button>
                </div>
                <pre>{JSON.stringify(values, 0, 2)}</pre>
              </form>
            )}
          />
        )}
      </MakeAsyncFunction>
    </Styles>
  </Provider>
);

render(<App />, document.getElementById("root"));


================================================
FILE: examples/async-redux-submission/package.json
================================================
{
  "name": "react-final-form-async-redux-submission",
  "version": "1.0.0",
  "description": "Demonstrates how to use react-redux-promise-listener to construct a promise out of Redux actions to give to 🏁 React Final Form's onSubmit.",
  "keywords": [
    "form",
    "redux",
    "async",
    "submit",
    "promise"
  ],
  "homepage": "https://codesandbox.io/s/new",
  "main": "src/index.js",
  "dependencies": {
    "final-form": "4.20.4",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-final-form": "6.5.3",
    "react-redux": "7.0.3",
    "react-redux-promise-listener": "1.0.0",
    "react-scripts": "3.0.1",
    "redux": "4.0.1",
    "redux-promise-listener": "1.1.1",
    "styled-components": "4.2.0"
  },
  "devDependencies": {},
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}


================================================
FILE: examples/async-redux-submission/readme.md
================================================
# Async Redux Submission

[![Edit react-final-form-async-redux-submission-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/x71mx66z8w)


================================================
FILE: examples/async-redux-submission/registrationDuck.js
================================================
// QUACK! This is a duck. https://github.com/erikras/ducks-modular-redux

// Actions
export const REGISTER = "final-form-examples/registration/REGISTER";
export const REGISTER_SUCCESS =
  "final-form-examples/registration/REGISTER_SUCCESS";
export const REGISTER_FAILURE =
  "final-form-examples/registration/REGISTER_FAILURE";

// Reducer
export default function reducer(state = {}, action = {}) {
  switch (action.type) {
    case REGISTER:
      return {
        ...state,
        registering: true,
      };
    case REGISTER_SUCCESS:
      return {
        ...state,
        registering: false,
      };
    case REGISTER_FAILURE:
      return {
        ...state,
        registering: false,
      };
    default:
      return state;
  }
}

// Action Creators

// Selectors


================================================
FILE: examples/async-redux-submission/store.js
================================================
import { createStore, combineReducers, applyMiddleware, compose } from "redux";
import createReduxPromiseListener from "redux-promise-listener";
import registration from "./registrationDuck";
import asyncSubmissionMiddleware from "./asyncSubmissionMiddleware";

const reduxPromiseListener = createReduxPromiseListener();

const logger = (store) => (next) => (action) => {
  console.log(action);
  return next(action);
};

const reducer = combineReducers({
  registration,
});

const composeEnhancers =
  (typeof window !== "undefined" &&
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
  compose;

const store = createStore(
  reducer,
  {},
  composeEnhancers(
    applyMiddleware(
      reduxPromiseListener.middleware,
      asyncSubmissionMiddleware,
      logger,
    ),
  ),
);

export const promiseListener = reduxPromiseListener; // <---------- IMPORTANT

export default store;


================================================
FILE: examples/async-typeahead-redux/GithubUserTypeahead.jsx
================================================
import React, { useCallback } from "react";
import { useSelector, useDispatch } from "react-redux";
import { Field } from "react-final-form";
import { AsyncTypeahead } from "react-bootstrap-typeahead";
import useKeyword from "./useKeyword";
import { compose, propOr, pathOr } from "ramda";
import arrify from "arrify";

import { searchGithubUsers } from "./actions";

const AdaptedTypeahead = ({ input, render, meta, ...rest }) => (
  <AsyncTypeahead {...input} {...rest} selected={input.value} />
);

const GithubUserTypeahead = ({ name, ...props }) => {
  const { keyword, updateKeyword } = useKeyword(name);

  const dispatch = useDispatch();
  const getOptions = useCallback(pathOr([], [keyword, "value"]), [keyword]);
  const isLoading = useCallback(pathOr(false, [keyword, "loading"]), [keyword]);
  const handleOnSearch = useCallback(compose(dispatch, searchGithubUsers), [
    dispatch,
  ]);

  const options = useSelector(getOptions);
  const loading = useSelector(isLoading);

  return (
    <Field
      name={name}
      component={AdaptedTypeahead}
      parse={propOr(null, 0)}
      format={arrify}
      placeholder="Write a github username"
      labelKey="login"
      options={options}
      onSearch={handleOnSearch}
      isLoading={loading}
      onInputChange={updateKeyword}
    />
  );
};

export default GithubUserTypeahead;


================================================
FILE: examples/async-typeahead-redux/Styles.js
================================================
import styled, { css } from "styled-components";

const btn = (light, dark) => css`
  white-space: nowrap;
  display: inline-block;
  border-radius: 5px;
  padding: 5px 15px;
  font-size: 16px;
  color: white;
  &:visited {
    color: white;
  }
  background-image: linear-gradient(${light}, ${dark});
  border: 1px solid ${dark};
  &:hover {
    background-image: linear-gradient(${light}, ${dark});
    &[disabled] {
      background-image: linear-gradient(${light}, ${dark});
    }
  }
  &:visited {
    color: black;
  }
  &[disabled] {
    opacity: 0.6;
    cursor: not-allowed;
  }
`;

const btnDefault = css`
  ${btn("#ffffff", "#d5d5d5")} color: #555;
`;

const btnPrimary = btn("#4f93ce", "#285f8f");
const btnDanger = btn("#e27c79", "#c9302c");

export default styled.div`
  font-family: sans-serif;

  h1 {
    text-align: center;
    color: #222;
  }

  h2 {
    text-align: center;
    color: #222;
  }

  & > div {
    text-align: center;
  }

  a {
    display: block;
    text-align: center;
    color: #222;
    margin-bottom: 10px;
  }

  p {
    max-width: 500px;
    margin: 10px auto;
    & > a {
      display: inline;
    }
  }

  form,
  div.form {
    text-align: left;
    max-width: 500px;
    margin: 10px auto;
    border: 1px solid #ccc;
    padding: 20px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
    border-radius: 3px;
    position: relative;

    .loading {
      text-align: center;
      display: block;
      position: absolute;
      background: url("https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif")
        center center;
      background-size: fill;
      font-size: 2em;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      padding: 50px 0 0 0;
      z-index: 2;
    }

    & > div {
      display: flex;
      flex-flow: row nowrap;
      line-height: 2em;
      margin: 5px;
      position: relative;
      & > label {
        color: #333;
        width: 110px;
        min-width: 60px;
        font-size: 1em;
        line-height: 32px;
      }
      & > input,
      & > select,
      & > textarea {
        flex: 1;
        padding: 3px 5px;
        font-size: 1em;
        margin-left: 15px;
        border: 1px solid #ccc;
        border-radius: 3px;
      }
      & > input[type="checkbox"] {
        margin-top: 7px;
      }
      & > div {
        margin-left: 16px;
        & > label {
          display: block;
          & > input {
            margin-right: 3px;
          }
        }
      }
      & > span {
        line-height: 32px;
        margin-left: 10px;
        color: #800;
        font-weight: bold;
      }
      & > button.remove {
        ${btnDanger};
      }
    }
    & > .buttons {
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      margin-top: 15px;
    }

    .error {
      display: flex;
      font-weight: bold;
      color: #800;
      flex-flow: row nowrap;
      justify-content: center;
    }
    pre {
      position: relative;
      border: 1px solid #ccc;
      background: rgba(0, 0, 0, 0.1);
      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
      padding: 20px;
    }
    .submitting {
      display: block;
      position: absolute;
      top: -5px;
      left: -5px;
      right: -5px;
      padding: 0;
      text-align: center;
      background: rgba(0, 0, 0, 0.4);
      color: white;
      z-index: 10;
      font-weight: bold;
      font-size: 0.8em;
    }
    .saving {
      font-size: 0.8em;
      font-weight: bold;
      color: darkblue;
      margin: 8px 0 0 7px;
    }
  }
  button {
    margin: 0 10px;
    &[type="submit"] {
      ${btnPrimary};
    }
    &[type="button"] {
      ${btnDefault};
    }
  }
`;


================================================
FILE: examples/async-typeahead-redux/actions.js
================================================
export const requestGithubUsers = (query) => ({
  type: "GITHUB_USERS_REQUEST",
  query,
});

export const storeGithubUsers = (query, users) => ({
  type: "GITHUB_USERS_RESPONSE",
  query,
  users,
});

export const searchGithubUsers = (query) => (dispatch) => {
  dispatch(requestGithubUsers(query));

  fetch(`https://api.github.com/search/users?q=${query}`)
    .then((res) => res.json())
    .then(({ items: users }) => dispatch(storeGithubUsers(query, users)));
};


================================================
FILE: examples/async-typeahead-redux/index.js
================================================
import React from "react";
import { render } from "react-dom";
import { Provider } from "react-redux";
import Styles from "./Styles";
import { Form } from "react-final-form";
import setFieldData from "final-form-set-field-data";

import configureStore from "./store";
import GithubUserTypeahead from "./GithubUserTypeahead";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const onSubmit = async (values) => {
  await sleep(300);
  window.alert(JSON.stringify(values, 0, 2));
};

const store = configureStore();

const App = () => (
  <Styles>
    <h1>
      <span role="img" aria-label="final form flag">
        🏁
      </span>{" "}
      React Final Form
    </h1>
    <a href="https://github.com/erikras/react-final-form#-react-final-form">
      Read Docs
    </a>
    <Form
      onSubmit={onSubmit}
      initialValues={{ user1: null, user2: null }}
      mutators={{ setFieldData }}
      render={({ handleSubmit, submitting, pristine, values }) => (
        <form onSubmit={handleSubmit}>
          <div>
            <label>Github users</label>
            <GithubUserTypeahead name="user1" />
          </div>
          <div>
            <label>Github users 2</label>
            <GithubUserTypeahead name="user2" />
          </div>
          <div className="buttons">
            <button type="submit" disabled={submitting || pristine}>
              Submit
            </button>
          </div>
          <pre>{JSON.stringify(values, 0, 2)}</pre>
        </form>
      )}
    />
  </Styles>
);

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root"),
);


================================================
FILE: examples/async-typeahead-redux/package.json
================================================
{
  "name": "react-final-form-github-user-asynctypeahead",
  "version": "1.0.0",
  "description": "Demonstrates how extensible 🏁 React Final Form can be with the combination of FormSpy and setFieldData by creating a totally separate validation engine that runs when a field is blurred.",
  "keywords": [],
  "main": "index.js",
  "dependencies": {
    "arrify": "2.0.1",
    "final-form": "4.20.4",
    "final-form-set-field-data": "1.0.2",
    "ramda": "0.25.0",
    "react": "17.0.2",
    "react-bootstrap-typeahead": "3.1.4",
    "react-dom": "17.0.2",
    "react-final-form": "6.5.3",
    "react-redux": "7.1.0",
    "redux": "4.0.4",
    "redux-thunk": "2.3.0",
    "styled-components": "2.4.0"
  }
}


================================================
FILE: examples/async-typeahead-redux/readme.md
================================================
# Async Typeahead and Redux

[![Edit react-final-form-async-typeahead-and-redux-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/5m4w2909k)


================================================
FILE: examples/async-typeahead-redux/store.js
================================================
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";

const initialState = {};
const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "GITHUB_USERS_REQUEST":
      return {
        ...state,
        [action.query]: {
          ...state[action.query],
          loading: true,
        },
      };
    case "GITHUB_USERS_RESPONSE":
      return {
        ...state,
        [action.query]: {
          value: action.users,
          loading: false,
        },
      };
    default:
      return state;
  }
};

export default () => createStore(reducer, undefined, applyMiddleware(thunk));


================================================
FILE: examples/async-typeahead-redux/useKeyword.js
================================================
import { useForm, useField } from "react-final-form";
import { propOr } from "ramda";

const useKeyword = (name) => {
  const {
    mutators: { setFieldData },
  } = useForm();
  const { meta } = useField(name, { subscription: { data: true } });

  return {
    keyword: propOr(null, "keyword", meta.data),
    updateKeyword: (keyword) => setFieldData(name, { keyword }),
  };
};

export default useKeyword;


================================================
FILE: examples/auto-save-field-blur/AutoSave.js
================================================
import React from "react";
import { FormSpy } from "react-final-form";
import diff from "object-diff";

class AutoSave extends React.Component {
  constructor(props) {
    super(props);
    this.state = { values: props.values, submitting: false };
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.active && this.props.active !== nextProps.active) {
      // blur occurred
      this.save(this.props.active);
    }
  }

  save = async (blurredField) => {
    if (this.promise) {
      await this.promise;
    }
    const { values, setFieldData, save } = this.props;

    // This diff step is totally optional
    const difference = diff(this.state.values, values);
    if (Object.keys(difference).length) {
      // values have changed
      this.setState({ submitting: true, values });
      setFieldData(blurredField, { saving: true });
      this.promise = save(difference);
      await this.promise;
      delete this.promise;
      this.setState({ submitting: false });
      setFieldData(blurredField, { saving: false });
    }
  };

  render() {
    // This component doesn't have to render anything, but it can render
    // submitting state.
    return null;
  }
}

// Make a HOC
// This is not the only way to accomplish auto-save, but it does let us:
// - Use built-in React lifecycle methods to listen for changes
// - Maintain state of when we are submitting
// - Render a message when submitting
// - Pass in save prop nicely
export default (props) => (
  <FormSpy
    {...props}
    subscription={{ active: true, values: true }}
    component={AutoSave}
  />
);


================================================
FILE: examples/auto-save-field-blur/Styles.js
================================================
import styled, { css } from "styled-components";

const btn = (light, dark) => css`
  white-space: nowrap;
  display: inline-block;
  border-radius: 5px;
  padding: 5px 15px;
  font-size: 16px;
  color: white;
  &:visited {
    color: white;
  }
  background-image: linear-gradient(${light}, ${dark});
  border: 1px solid ${dark};
  &:hover {
    background-image: linear-gradient(${light}, ${dark});
    &[disabled] {
      background-image: linear-gradient(${light}, ${dark});
    }
  }
  &:visited {
    color: black;
  }
  &[disabled] {
    opacity: 0.6;
    cursor: not-allowed;
  }
`;

const btnDefault = css`
  ${btn("#ffffff", "#d5d5d5")} color: #555;
`;

const btnPrimary = btn("#4f93ce", "#285f8f");
const btnDanger = btn("#e27c79", "#c9302c");

export default styled.div`
  font-family: sans-serif;

  h1 {
    text-align: center;
    color: #222;
  }

  h2 {
    text-align: center;
    color: #222;
  }

  & > div {
    text-align: center;
  }

  a {
    display: block;
    text-align: center;
    color: #222;
    margin-bottom: 10px;
  }

  p {
    max-width: 500px;
    margin: 10px auto;
    & > a {
      display: inline;
    }
  }

  form,
  div.form {
    text-align: left;
    max-width: 500px;
    margin: 10px auto;
    border: 1px solid #ccc;
    padding: 20px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
    border-radius: 3px;
    position: relative;

    .loading {
      text-align: center;
      display: block;
      position: absolute;
      background: url("https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif")
        center center;
      background-size: fill;
      font-size: 2em;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      padding: 50px 0 0 0;
      z-index: 2;
    }

    & > div {
      display: flex;
      flex-flow: row nowrap;
      line-height: 2em;
      margin: 5px;
      position: relative;
      & > label {
        color: #333;
        width: 110px;
        min-width: 60px;
        font-size: 1em;
        line-height: 32px;
      }
      & > input,
      & > select,
      & > textarea {
        flex: 1;
        padding: 3px 5px;
        font-size: 1em;
        margin-left: 15px;
        border: 1px solid #ccc;
        border-radius: 3px;
      }
      & > input[type="checkbox"] {
        margin-top: 7px;
      }
      & > div {
        margin-left: 16px;
        & > label {
          display: block;
          & > input {
            margin-right: 3px;
          }
        }
      }
      & > span {
        line-height: 32px;
        margin-left: 10px;
        color: #800;
        font-weight: bold;
      }
      & > button.remove {
        ${btnDanger};
      }
    }
    & > .buttons {
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      margin-top: 15px;
    }

    .error {
      display: flex;
      font-weight: bold;
      color: #800;
      flex-flow: row nowrap;
      justify-content: center;
    }
    pre {
      position: relative;
      border: 1px solid #ccc;
      background: rgba(0, 0, 0, 0.1);
      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
      padding: 20px;
    }
    .submitting {
      display: block;
      position: absolute;
      top: -5px;
      left: -5px;
      right: -5px;
      padding: 0;
      text-align: center;
      background: rgba(0, 0, 0, 0.4);
      color: white;
      z-index: 10;
      font-weight: bold;
      font-size: 0.8em;
    }
    .saving {
      font-size: 0.8em;
      font-weight: bold;
      color: darkblue;
      margin: 0 0 0 8px;
    }
  }
  button {
    margin: 0 10px;
    &[type="submit"] {
      ${btnPrimary};
    }
    &[type="button"] {
      ${btnDefault};
    }
  }
`;


================================================
FILE: examples/auto-save-field-blur/index.js
================================================
import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";
import setFieldData from "final-form-set-field-data";
import AutoSave from "./AutoSave";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const save = async (values) => {
  console.log("Saving", values);
  await sleep(1000);
};

const SavingIndicator = ({ name }) => (
  <Field
    name={name}
    subscription={{ data: true }}
    render={({
      meta: {
        data: { saving },
      },
    }) => (saving ? <div className="saving">Saving</div> : null)}
  />
);

const App = () => (
  <Styles>
    <h1>
      <span role="img" aria-label="final form flag">
        🏁
      </span>{" "}
      React Final Form
    </h1>
    <h2>Auto-Save on Field Blur</h2>
    <a href="https://github.com/erikras/react-final-form#-react-final-form">
      Read Docs
    </a>
    <p>
      The <code>AutoSave</code> component uses{" "}
      <a
        href="https://github.com/final-form/react-final-form#formspy--reactcomponenttypeformspyprops"
        target="_blank"
        rel="noopener noreferrer"
      >
        <code>FormSpy</code>
      </a>{" "}
      to listen to changes to values and which field is currently active and
      auto-saves changes when a field is blurred. Look in the console for the
      save events.
    </p>
    <Form
      onSubmit={save /* NOT USED, but required */}
      initialValues={{ employed: true, stooge: "larry" }}
      mutators={{ setFieldData }}
      subscription={{} /* No need to subscribe to anything */}
    >
      {({ form }) => (
        <div className="form">
          {/* Don't even need a <form> tag */}

          {/* 👇 👇 👇 👇 */}
          <AutoSave setFieldData={form.mutators.setFieldData} save={save} />
          {/* ☝️ ️☝️ ️☝️ ️️️️☝️ ️️*/}

          <div>
            <label>First Name</label>
            <Field
              name="firstName"
              component="input"
              type="text"
              placeholder="First Name"
            />
            <SavingIndicator name="firstName" />
          </div>
          <div>
            <label>Last Name</label>
            <Field
              name="lastName"
              component="input"
              type="text"
              placeholder="Last Name"
            />
            <SavingIndicator name="lastName" />
          </div>
          <div>
            <label>Email</label>
            <Field
              name="email"
              component="input"
              type="email"
              placeholder="Email"
            />
            <SavingIndicator name="email" />
          </div>
          <div>
            <label>Favorite Color</label>
            <Field name="favoriteColor" component="select">
              <option />
              <option value="#ff0000">
                <span role="img" aria-label="red heart">
                  ❤️
                </span>{" "}
                Red
              </option>
              <option value="#00ff00">
                <span role="img" aria-label="green heart">
                  💚
                </span>{" "}
                Green
              </option>
              <option value="#0000ff">
                <span role="img" aria-label="blue heart">
                  💙
                </span>{" "}
                Blue
              </option>
            </Field>
            <SavingIndicator name="favoriteColor" />
          </div>
          <div>
            <label>Employed?</label>
            <Field name="employed" component="input" type="checkbox" />
            <SavingIndicator name="employed" />
          </div>
          <div>
            <label>Toppings</label>
            <Field name="toppings" component="select" multiple>
              <option value="ham">
                <span role="img" aria-label="pig head">
                  🐷
                </span>{" "}
                Ham
              </option>
              <option value="mushrooms">
                <span role="img" aria-label="mushroom">
                  🍄
                </span>{" "}
                Mushrooms
              </option>
              <option value="cheese">
                <span role="img" aria-label="cheese">
                  🧀
                </span>{" "}
                Cheese
              </option>
              <option value="chicken">
                <span role="img" aria-label="chicken">
                  🐓
                </span>{" "}
                Chicken
              </option>
              <option value="pineapple">
                <span role="img" aria-label="pineapple">
                  🍍
                </span>{" "}
                Pinapple
              </option>
            </Field>
            <SavingIndicator name="toppings" />
          </div>
          <div>
            <label>Best Stooge?</label>
            <div>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="larry"
                />{" "}
                Larry
              </label>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="moe"
                />{" "}
                Moe
              </label>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="curly"
                />{" "}
                Curly
              </label>
            </div>
            <SavingIndicator name="stooge" />
          </div>
          <div>
            <label>Notes</label>
            <Field name="notes" component="textarea" placeholder="Notes" />
            <SavingIndicator name="notes" />
          </div>
        </div>
      )}
    </Form>
  </Styles>
);

render(<App />, document.getElementById("root"));


================================================
FILE: examples/auto-save-field-blur/package.json
================================================
{
  "name": "react-final-form-auto-save-on-field-blur",
  "version": "1.0.0",
  "description": "Demonstrates how to create an AutoSave component to listen to form state and automatically save data when fields blur.",
  "keywords": [],
  "main": "index.js",
  "dependencies": {
    "final-form": "4.20.4",
    "final-form-set-field-data": "1.0.2",
    "object-diff": "0.0.4",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-final-form": "6.5.3",
    "styled-components": "4.2.0"
  }
}


================================================
FILE: examples/auto-save-field-blur/readme.md
================================================
# Auto-Save on Field Blur

[![Edit react-final-form-auto-save-field-blur-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/7k742qpo36)


================================================
FILE: examples/auto-save-selective-debounce/AutoSave.js
================================================
import React from "react";
import { FormSpy } from "react-final-form";
import diff from "object-diff";

const areObjectsIdentical = (a, b) =>
  Object.keys(diff(a, b)).length === 0 && Object.keys(diff(b, a)).length === 0;

class AutoSave extends React.Component {
  static defaultProps = {
    debounced: [],
  };
  constructor(props) {
    super(props);

    this.state = {
      submitting: false,
      ...this.splitValues(props.values),
    };
  }

  componentDidUpdate() {
    const { values, debounce } = this.props;
    const { debouncedValues, immediateValues } = this.splitValues(values);

    if (!areObjectsIdentical(this.state.immediateValues, immediateValues)) {
      this.save();
    }

    if (!areObjectsIdentical(this.state.debouncedValues, debouncedValues)) {
      if (this.timeout) {
        clearTimeout(this.timeout);
      }
      this.timeout = setTimeout(() => {
        this.save();
      }, debounce);
    }
  }

  splitValues = (values) => {
    const { debounced } = this.props;

    const debouncedValues = {};
    const immediateValues = {};

    Object.keys(values).forEach((key) => {
      if (debounced.includes(key)) {
        debouncedValues[key] = values[key];
      } else {
        immediateValues[key] = values[key];
      }
    });

    return {
      debouncedValues,
      immediateValues,
    };
  };

  save = async () => {
    if (this.promise) {
      await this.promise;
    }
    const { save, values } = this.props;

    const { debouncedValues, immediateValues } = this.splitValues(values);

    this.setState(
      (state) => ({
        submitting: true,
        immediateValues: { ...immediateValues },
        debouncedValues: { ...debouncedValues },
      }),
      async () => {
        this.promise = save({
          ...this.state.immediateValues,
          ...this.state.debouncedValues,
        });

        await this.promise;
        delete this.promise;

        this.setState({ submitting: false });
      },
    );
  };

  render() {
    // This component doesn't have to render anything, but it can render
    // submitting state.
    return (
      this.state.submitting && <div className="submitting">Submitting...</div>
    );
  }
}

// Make a HOC
// This is not the only way to accomplish auto-save, but it does let us:
// - Use built-in React lifecycle methods to listen for changes
// - Maintain state of when we are submitting
// - Render a message when submitting
// - Pass in debounce and save props nicely
export default (props) => (
  <FormSpy {...props} subscription={{ values: true }} component={AutoSave} />
);


================================================
FILE: examples/auto-save-selective-debounce/Styles.js
================================================
import styled, { css } from "styled-components";

const btn = (light, dark) => css`
  white-space: nowrap;
  display: inline-block;
  border-radius: 5px;
  padding: 5px 15px;
  font-size: 16px;
  color: white;
  &:visited {
    color: white;
  }
  background-image: linear-gradient(${light}, ${dark});
  border: 1px solid ${dark};
  &:hover {
    background-image: linear-gradient(${light}, ${dark});
    &[disabled] {
      background-image: linear-gradient(${light}, ${dark});
    }
  }
  &:visited {
    color: black;
  }
  &[disabled] {
    opacity: 0.6;
    cursor: not-allowed;
  }
`;

const btnDefault = css`
  ${btn("#ffffff", "#d5d5d5")} color: #555;
`;

const btnPrimary = btn("#4f93ce", "#285f8f");
const btnDanger = btn("#e27c79", "#c9302c");

export default styled.div`
  font-family: sans-serif;

  h1 {
    text-align: center;
    color: #222;
  }

  h2 {
    text-align: center;
    color: #222;
  }

  & > div {
    text-align: center;
  }

  a {
    display: block;
    text-align: center;
    color: #222;
    margin-bottom: 10px;
  }

  p {
    max-width: 500px;
    margin: 10px auto;
    & > a {
      display: inline;
    }
  }

  form,
  div.form {
    text-align: left;
    max-width: 500px;
    margin: 10px auto;
    border: 1px solid #ccc;
    padding: 20px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
    border-radius: 3px;
    position: relative;

    .loading {
      text-align: center;
      display: block;
      position: absolute;
      background: url("https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif")
        center center;
      background-size: fill;
      font-size: 2em;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      padding: 50px 0 0 0;
      z-index: 2;
    }

    & > div {
      display: flex;
      flex-flow: row nowrap;
      line-height: 2em;
      margin: 5px;
      position: relative;
      & > label {
        color: #333;
        width: 110px;
        min-width: 60px;
        font-size: 1em;
        line-height: 32px;
      }
      & > input,
      & > select,
      & > textarea {
        flex: 1;
        padding: 3px 5px;
        font-size: 1em;
        margin-left: 15px;
        border: 1px solid #ccc;
        border-radius: 3px;
      }
      & > input[type="checkbox"] {
        margin-top: 7px;
      }
      & > div {
        margin-left: 16px;
        & > label {
          display: block;
          & > input {
            margin-right: 3px;
          }
        }
      }
      & > span {
        line-height: 32px;
        margin-left: 10px;
        color: #800;
        font-weight: bold;
      }
      & > button.remove {
        ${btnDanger};
      }
    }
    & > .buttons {
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      margin-top: 15px;
    }

    .error {
      display: flex;
      font-weight: bold;
      color: #800;
      flex-flow: row nowrap;
      justify-content: center;
    }
    pre {
      position: relative;
      border: 1px solid #ccc;
      background: rgba(0, 0, 0, 0.1);
      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
      padding: 20px;
    }
    .submitting {
      display: block;
      position: absolute;
      top: -5px;
      left: -5px;
      right: -5px;
      padding: 0;
      text-align: center;
      background: rgba(0, 0, 0, 0.4);
      color: white;
      z-index: 10;
      font-weight: bold;
      font-size: 0.8em;
    }
  }
  button {
    margin: 0 10px;
    &[type="submit"] {
      ${btnPrimary};
    }
    &[type="button"] {
      ${btnDefault};
    }
  }
`;


================================================
FILE: examples/auto-save-selective-debounce/index.js
================================================
import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";
import AutoSave from "./AutoSave";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const save = async (values) => {
  console.log("Saving", values);
  await sleep(2000);
};

const App = () => (
  <Styles>
    <h1>
      <span role="img" aria-label="final form flag">
        🏁
      </span>{" "}
      React Final Form
    </h1>
    <h2>
      Auto-Save with <em>Selective</em> Debounce
    </h2>
    <a href="https://github.com/erikras/react-final-form#-react-final-form">
      Read Docs
    </a>
    <p>
      The <code>AutoSave</code> component uses{" "}
      <a
        href="https://github.com/final-form/react-final-form#formspy--reactcomponenttypeformspyprops"
        target="_blank"
        rel="noopener noreferrer"
      >
        <code>FormSpy</code>
      </a>{" "}
      to listen to changes to values and auto-save changes. But it only
      debounces changes to a specific list of fields given to the{" "}
      <code>AutoSave</code> component, in this case, all the text inputs. Look
      in the console for the save events.
    </p>
    <Form
      onSubmit={save /* NOT USED, but required */}
      initialValues={{ employed: true, stooge: "larry" }}
      subscription={{} /* No need to subscribe to anything */}
    >
      {() => (
        <div className="form">
          {/* Don't even need a <form> tag */}

          {/* 👇 👇 👇 👇 */}
          <AutoSave
            debounce={2000}
            save={save}
            debounced={["firstName", "lastName", "email", "notes"]}
          />
          {/* ☝️ ️☝️ ️☝️ ️️️️☝️ ️️*/}

          <div>
            <label>First Name</label>
            <Field
              name="firstName"
              component="input"
              type="text"
              placeholder="First Name"
            />
          </div>
          <div>
            <label>Last Name</label>
            <Field
              name="lastName"
              component="input"
              type="text"
              placeholder="Last Name"
            />
          </div>
          <div>
            <label>Email</label>
            <Field
              name="email"
              component="input"
              type="email"
              placeholder="Email"
            />
          </div>
          <div>
            <label>Favorite Color</label>
            <Field name="favoriteColor" component="select">
              <option />
              <option value="#ff0000">
                <span role="img" aria-label="red heart">
                  ❤️
                </span>{" "}
                Red
              </option>
              <option value="#00ff00">
                <span role="img" aria-label="green heart">
                  💚
                </span>{" "}
                Green
              </option>
              <option value="#0000ff">
                <span role="img" aria-label="blue heart">
                  💙
                </span>{" "}
                Blue
              </option>
            </Field>
          </div>
          <div>
            <label>Employed?</label>
            <Field name="employed" component="input" type="checkbox" />
          </div>
          <div>
            <label>Toppings</label>
            <Field name="toppings" component="select" type="select" multiple>
              <option value="ham">
                <span role="img" aria-label="pig head">
                  🐷
                </span>{" "}
                Ham
              </option>
              <option value="mushrooms">
                <span role="img" aria-label="mushroom">
                  🍄
                </span>{" "}
                Mushrooms
              </option>
              <option value="cheese">
                <span role="img" aria-label="cheese">
                  🧀
                </span>{" "}
                Cheese
              </option>
              <option value="chicken">
                <span role="img" aria-label="chicken">
                  🐓
                </span>{" "}
                Chicken
              </option>
              <option value="pineapple">
                <span role="img" aria-label="pineapple">
                  🍍
                </span>{" "}
                Pinapple
              </option>
            </Field>
          </div>
          <div>
            <label>Best Stooge?</label>
            <div>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="larry"
                />{" "}
                Larry
              </label>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="moe"
                />{" "}
                Moe
              </label>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="curly"
                />{" "}
                Curly
              </label>
            </div>
          </div>
          <div>
            <label>Notes</label>
            <Field name="notes" component="textarea" placeholder="Notes" />
          </div>
        </div>
      )}
    </Form>
  </Styles>
);

render(<App />, document.getElementById("root"));


================================================
FILE: examples/auto-save-selective-debounce/package.json
================================================
{
  "name": "react-final-form-auto-save-with-selective-debounce",
  "version": "1.0.0",
  "description": "Demonstrates how to use a FormSpy component to auto-save your form values with a debounce, restricting which fields are debounced.",
  "keywords": [],
  "main": "index.js",
  "dependencies": {
    "final-form": "4.20.4",
    "object-diff": "0.0.4",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-final-form": "6.5.3",
    "styled-components": "4.2.0"
  }
}


================================================
FILE: examples/auto-save-selective-debounce/readme.md
================================================
# Auto-Save with _Selective_ Debounce

[![Edit react-final-form-auto-save-selective-debounce-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/98j0v46zj4)


================================================
FILE: examples/auto-save-with-debounce/AutoSave.js
================================================
import React from "react";
import { FormSpy } from "react-final-form";
import diff from "object-diff";

class AutoSave extends React.Component {
  constructor(props) {
    super(props);
    this.state = { values: props.values, submitting: false };
  }

  componentWillReceiveProps(nextProps) {
    if (this.timeout) {
      clearTimeout(this.timeout);
    }
    this.timeout = setTimeout(this.save, this.props.debounce);
  }

  save = async () => {
    if (this.promise) {
      await this.promise;
    }
    const { values, save } = this.props;

    // This diff step is totally optional
    const difference = diff(this.state.values, values);
    if (Object.keys(difference).length) {
      // values have changed
      this.setState({ submitting: true, values });
      this.promise = save(difference);
      await this.promise;
      delete this.promise;
      this.setState({ submitting: false });
    }
  };

  render() {
    // This component doesn't have to render anything, but it can render
    // submitting state.
    return (
      this.state.submitting && <div className="submitting">Submitting...</div>
    );
  }
}

// Make a HOC
// This is not the only way to accomplish auto-save, but it does let us:
// - Use built-in React lifecycle methods to listen for changes
// - Maintain state of when we are submitting
// - Render a message when submitting
// - Pass in debounce and save props nicely
export default (props) => (
  <FormSpy {...props} subscription={{ values: true }} component={AutoSave} />
);


================================================
FILE: examples/auto-save-with-debounce/Styles.js
================================================
import styled, { css } from "styled-components";

const btn = (light, dark) => css`
  white-space: nowrap;
  display: inline-block;
  border-radius: 5px;
  padding: 5px 15px;
  font-size: 16px;
  color: white;
  &:visited {
    color: white;
  }
  background-image: linear-gradient(${light}, ${dark});
  border: 1px solid ${dark};
  &:hover {
    background-image: linear-gradient(${light}, ${dark});
    &[disabled] {
      background-image: linear-gradient(${light}, ${dark});
    }
  }
  &:visited {
    color: black;
  }
  &[disabled] {
    opacity: 0.6;
    cursor: not-allowed;
  }
`;

const btnDefault = css`
  ${btn("#ffffff", "#d5d5d5")} color: #555;
`;

const btnPrimary = btn("#4f93ce", "#285f8f");
const btnDanger = btn("#e27c79", "#c9302c");

export default styled.div`
  font-family: sans-serif;

  h1 {
    text-align: center;
    color: #222;
  }

  h2 {
    text-align: center;
    color: #222;
  }

  & > div {
    text-align: center;
  }

  a {
    display: block;
    text-align: center;
    color: #222;
    margin-bottom: 10px;
  }

  p {
    max-width: 500px;
    margin: 10px auto;
    & > a {
      display: inline;
    }
  }

  form,
  div.form {
    text-align: left;
    max-width: 500px;
    margin: 10px auto;
    border: 1px solid #ccc;
    padding: 20px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
    border-radius: 3px;
    position: relative;

    .loading {
      text-align: center;
      display: block;
      position: absolute;
      background: url("https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif")
        center center;
      background-size: fill;
      font-size: 2em;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      padding: 50px 0 0 0;
      z-index: 2;
    }

    & > div {
      display: flex;
      flex-flow: row nowrap;
      line-height: 2em;
      margin: 5px;
      position: relative;
      & > label {
        color: #333;
        width: 110px;
        min-width: 60px;
        font-size: 1em;
        line-height: 32px;
      }
      & > input,
      & > select,
      & > textarea {
        flex: 1;
        padding: 3px 5px;
        font-size: 1em;
        margin-left: 15px;
        border: 1px solid #ccc;
        border-radius: 3px;
      }
      & > input[type="checkbox"] {
        margin-top: 7px;
      }
      & > div {
        margin-left: 16px;
        & > label {
          display: block;
          & > input {
            margin-right: 3px;
          }
        }
      }
      & > span {
        line-height: 32px;
        margin-left: 10px;
        color: #800;
        font-weight: bold;
      }
      & > button.remove {
        ${btnDanger};
      }
    }
    & > .buttons {
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      margin-top: 15px;
    }

    .error {
      display: flex;
      font-weight: bold;
      color: #800;
      flex-flow: row nowrap;
      justify-content: center;
    }
    pre {
      position: relative;
      border: 1px solid #ccc;
      background: rgba(0, 0, 0, 0.1);
      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
      padding: 20px;
    }
    .submitting {
      display: block;
      position: absolute;
      top: -5px;
      left: -5px;
      right: -5px;
      padding: 0;
      text-align: center;
      background: rgba(0, 0, 0, 0.4);
      color: white;
      z-index: 10;
      font-weight: bold;
      font-size: 0.8em;
    }
  }
  button {
    margin: 0 10px;
    &[type="submit"] {
      ${btnPrimary};
    }
    &[type="button"] {
      ${btnDefault};
    }
  }
`;


================================================
FILE: examples/auto-save-with-debounce/index.js
================================================
import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";
import AutoSave from "./AutoSave";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const save = async (values) => {
  console.log("Saving", values);
  await sleep(2000);
};

const App = () => (
  <Styles>
    <h1>
      <span role="img" aria-label="final form flag">
        🏁
      </span>{" "}
      React Final Form
    </h1>
    <h2>Auto-Save with Debounce</h2>
    <a href="https://github.com/erikras/react-final-form#-react-final-form">
      Read Docs
    </a>
    <p>
      The <code>AutoSave</code> component uses{" "}
      <a
        href="https://github.com/final-form/react-final-form#formspy--reactcomponenttypeformspyprops"
        target="_blank"
        rel="noopener noreferrer"
      >
        <code>FormSpy</code>
      </a>{" "}
      to listen to changes to values and auto-save changes. Look in the console
      for the save events.
    </p>
    <Form
      onSubmit={save /* NOT USED, but required */}
      initialValues={{ employed: true, stooge: "larry" }}
      subscription={{} /* No need to subscribe to anything */}
    >
      {() => (
        <div className="form">
          {/* Don't even need a <form> tag */}

          {/* 👇 👇 👇 👇 */}
          <AutoSave debounce={1000} save={save} />
          {/* ☝️ ️☝️ ️☝️ ️️️️☝️ ️️*/}

          <div>
            <label>First Name</label>
            <Field
              name="firstName"
              component="input"
              type="text"
              placeholder="First Name"
            />
          </div>
          <div>
            <label>Last Name</label>
            <Field
              name="lastName"
              component="input"
              type="text"
              placeholder="Last Name"
            />
          </div>
          <div>
            <label>Email</label>
            <Field
              name="email"
              component="input"
              type="email"
              placeholder="Email"
            />
          </div>
          <div>
            <label>Favorite Color</label>
            <Field name="favoriteColor" component="select">
              <option />
              <option value="#ff0000">
                <span role="img" aria-label="red heart">
                  ❤️
                </span>{" "}
                Red
              </option>
              <option value="#00ff00">
                <span role="img" aria-label="green heart">
                  💚
                </span>{" "}
                Green
              </option>
              <option value="#0000ff">
                <span role="img" aria-label="blue heart">
                  💙
                </span>{" "}
                Blue
              </option>
            </Field>
          </div>
          <div>
            <label>Employed?</label>
            <Field name="employed" component="input" type="checkbox" />
          </div>
          <div>
            <label>Toppings</label>
            <Field name="toppings" component="select" multiple>
              <option value="ham">
                <span role="img" aria-label="pig head">
                  🐷
                </span>{" "}
                Ham
              </option>
              <option value="mushrooms">
                <span role="img" aria-label="mushroom">
                  🍄
                </span>{" "}
                Mushrooms
              </option>
              <option value="cheese">
                <span role="img" aria-label="cheese">
                  🧀
                </span>{" "}
                Cheese
              </option>
              <option value="chicken">
                <span role="img" aria-label="chicken">
                  🐓
                </span>{" "}
                Chicken
              </option>
              <option value="pineapple">
                <span role="img" aria-label="pineapple">
                  🍍
                </span>{" "}
                Pinapple
              </option>
            </Field>
          </div>
          <div>
            <label>Best Stooge?</label>
            <div>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="larry"
                />{" "}
                Larry
              </label>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="moe"
                />{" "}
                Moe
              </label>
              <label>
                <Field
                  name="stooge"
                  component="input"
                  type="radio"
                  value="curly"
                />{" "}
                Curly
              </label>
            </div>
          </div>
          <div>
            <label>Notes</label>
            <Field name="notes" component="textarea" placeholder="Notes" />
          </div>
        </div>
      )}
    </Form>
  </Styles>
);

render(<App />, document.getElementById("root"));


================================================
FILE: examples/auto-save-with-debounce/package.json
================================================
{
  "name": "react-final-form-auto-save-with-debounce",
  "version": "1.0.0",
  "description": "Demonstrates how to use a FormSpy component to auto-save your form values with a debounce.",
  "keywords": [
    "final-form",
    "autosave",
    "form",
    "debounce",
    "react-final-form"
  ],
  "main": "index.js",
  "dependencies": {
    "final-form": "4.20.4",
    "object-diff": "0.0.4",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-final-form": "6.5.3",
    "styled-components": "4.2.0"
  }
}


================================================
FILE: examples/auto-save-with-debounce/readme.md
================================================
# Auto-Save with Debounce

[![Edit react-final-form-auto-save-with-debounce-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/5w4yrpyo7k)


================================================
FILE: examples/calculated-fields/Styles.js
================================================
import styled, { css } from "styled-components";

const btn = (light, dark) => css`
  white-space: nowrap;
  display: inline-block;
  border-radius: 5px;
  padding: 5px 15px;
  font-size: 16px;
  color: white;
  &:visited {
    color: white;
  }
  background-image: linear-gradient(${light}, ${dark});
  border: 1px solid ${dark};
  &:hover {
    background-image: linear-gradient(${light}, ${dark});
    &[disabled] {
      background-image: linear-gradient(${light}, ${dark});
    }
  }
  &:visited {
    color: black;
  }
  &[disabled] {
    opacity: 0.6;
    cursor: not-allowed;
  }
`;

const btnDefault = css`
  ${btn("#ffffff", "#d5d5d5")} color: #555;
`;

const btnPrimary = btn("#4f93ce", "#285f8f");
const btnDanger = btn("#e27c79", "#c9302c");

export default styled.div`
  font-family: sans-serif;

  h1 {
    text-align: center;
    color: #222;
  }

  h2 {
    text-align: center;
    color: #222;
  }

  & > div {
    text-align: center;
  }

  a {
    display: block;
    text-align: center;
    color: #222;
    margin-bottom: 10px;
  }

  p {
    max-width: 500px;
    margin: 10px auto;
    & > a {
      display: inline;
    }
  }

  form {
    max-width: 500px;
    margin: 10px auto;
    border: 1px solid #ccc;
    padding: 20px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
    border-radius: 3px;
    position: relative;

    .loading {
      text-align: center;
      display: block;
      position: absolute;
      background: url("https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif")
        center center;
      background-size: fill;
      font-size: 2em;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      padding: 50px 0 0 0;
      z-index: 2;
    }

    & > div {
      display: flex;
      flex-flow: row nowrap;
      line-height: 2em;
      margin: 5px;
      position: relative;
      & > label {
        color: #333;
        width: 110px;
        min-width: 60px;
        font-size: 1em;
        line-height: 32px;
      }
      & > input,
      & > select,
      & > textarea {
        flex: 1;
        padding: 3px 5px;
        font-size: 1em;
        margin-left: 15px;
        border: 1px solid #ccc;
        border-radius: 3px;
      }
      & > input[type="checkbox"] {
        margin-top: 7px;
      }
      & > div {
        margin-left: 16px;
        & > label {
          display: block;
          & > input {
            margin-right: 3px;
          }
        }
      }
      & > span {
        line-height: 32px;
        margin-left: 10px;
        color: #800;
        font-weight: bold;
      }
      & > button.remove {
        ${btnDanger};
      }
    }
    & > .buttons {
      display: flex;
      flex-flow: row nowrap;
      justify-content: center;
      margin-top: 15px;
    }
    button {
      margin: 0 10px;
      &[type="submit"] {
        ${btnPrimary};
      }
      &[type="button"] {
        ${btnDefault};
      }
    }
    .error {
      display: flex;
      font-weight: bold;
      color: #800;
      flex-flow: row nowrap;
      justify-content: center;
    }
    pre {
      position: relative;
      border: 1px solid #ccc;
      background: rgba(0, 0, 0, 0.1);
      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);
      padding: 20px;
    }
  }
`;


================================================
FILE: examples/calculated-fields/index.js
================================================
import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";
import createDecorator from "final-form-calculate";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const onSubmit = async (values) => {
  await sleep(300);
  window.alert(JSON.stringify(values, 0, 2));
};

const calculator = createDecorator(
  {
    field: "minimum", // when minimum changes...
    updates: {
      // ...update maximum to the result of this function
      maximum: (minimumValue, allValues) =>
        Math.max(minimumValue || 0, allValues.maximum || 0),
    },
  },
  {
    field: "maximum", // when maximum changes...
    updates: {
      // update minimum to the result of this function
      minimum: (maximumValue, allValues) =>
        Math.min(maximumValue || 0, allValues.minimum || 0),
    },
  },
  {
    field: /day\[\d\]/, // when a field matching this pattern changes...
    updates: {
      // ...update the total to the result of this function
      total: (ignoredValue, allValues) =>
        (allValues.day || []).reduce(
          (sum, value) => sum + Number(value || 0),
          0,
        ),
    },
  },
);

const App = () => (
  <Styles>
    <h1>
      <span role="img" aria-label="final form flag">
        🏁
      </span>{" "}
      React Final Form Example
    </h1>
    <h2>Calculated Fields</h2>
    <a href="https://github.com/erikras/react-final-form#-react-final-form">
      Read Docs
    </a>
    <p>
      Change the minimum and maximum values with the arrow keys and notice that
      the other updates so that minimum is always &lt;= maximum.
    </p>
    <p>
      As you enter numbers for each day of the week, the total is calulated in
      realtime.
    </p>
    <Form
      onSubmit={onSubmit}
      decorators={[calculator]}
      render={({ handleSubmit, reset, submitting, pristine, values }) => (
        <form onSubmit={handleSubmit}>
          <div>
            <label>Minimum</label>
            <Field
              name="minimum"
              component="input"
              type="number"
              placeholder="Minimum"
            />
          </div>
          <div>
            <label>Maximum</label>
            <Field
              name="maximum"
              component="input"
              type="number"
              placeholder="Maximum"
            />
          </div>
          <hr />
          <div>
            <label>Monday</label>
            <Field
              name="day[0]"
              component="input"
              type="number"
              placeholder="Monday"
            />
          </div>
          <div>
            <label>Tuesday</label>
            <Field
              name="day[1]"
              component="input"
              type="number"
              placeholder="Tuesday"
            />
          </div>
          <div>
            <label>Wednesday</label>
            <Field
              name="day[2]"
              component="input"
              type="number"
              placeholder="Wednesday"
            />
          </div>
          <div>
            <label>Thursday</label>
            <Field
              name="day[3]"
              component="input"
              type="number"
              placeholder="Thursday"
            />
          </div>
          <div>
            <label>Friday</label>
            <Field
              name="day[4]"
              component="input"
              type="number"
              placeholder="Friday"
            />
          </div>
          <hr />
          <div>
            <label>Total</label>
            <Field
              name="total"
              component="input"
              type="number"
              readOnly
              placeholder="Total"
            />
          </div>
          <hr />
          <div className="buttons">
            <button type="submit" disabled={submitting}>
              Submit
            </button>
            <button
              type="button"
              onClick={reset}
              disabled={submitting || pristine}
            >
              Reset
            </button>
          </div>
          <pre>{JSON.stringify(values, 0, 2)}</pre>
        </form>
      )}
    />
  </Styles>
);

render(<App />, document.getElementById("root"));


================================================
FILE: examples/calculated-fields/package.json
================================================
{
  "name": "react-final-form-calculated-fields",
  "version": "1.0.0",
  "description": "Demonstrates how to use the final-form-calculate decorator to achieve realtime field calculations.",
  "keywords": [],
  "homepage": "https://codesandbox.io/s/oq52p6v96y",
  "main": "index.js",
  "dependencies": {
    "final-form": "4.20.4",
    "final-form-calculate": "1.3.1",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-final-form": "6.5.3",
    "styled-components": "4.2.0"
  }
}


================================================
FILE: examples/calculated-fields/readme.md
================================================
# Calculated Fields

[![Edit react-final-form-calculated-fields-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/oq52p6v96y)


================================================
FILE: examples/chakra/index.js
================================================
/* eslint-disable jsx-a11y/accessible-emoji */
import React from "react";
import { render } from "react-dom";
import {
  Box,
  Button,
  ButtonGroup,
  CSSReset,
  Heading,
  Icon,
  Link,
  ThemeProvider,
  theme,
  FormControl,
  FormLabel,
  FormErrorMessage,
  Input,
  Checkbox,
  Progress,
  Radio,
  RadioGroup,
  Stack,
  Textarea,
} from "@chakra-ui/core";
import { Form, Field, useField, useForm } from "react-final-form";
import validate from "./validate";

const sleep = (ms) => new Promise((resolve) =
Download .txt
gitextract_z4w9ccys/

├── .babelrc.js
├── .eslintrc
├── .flowconfig
├── .github/
│   ├── CODEOWNERS
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       ├── ci.yml
│       └── lock.yml
├── .gitignore
├── .prettierignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── MIGRATION_V7.md
├── README.md
├── docs/
│   ├── api/
│   │   ├── Field.md
│   │   ├── Form.md
│   │   ├── FormSpy.md
│   │   ├── useField.md
│   │   ├── useForm.md
│   │   └── useFormState.md
│   ├── api.md
│   ├── examples/
│   │   ├── chakra.md
│   │   ├── field-level-validation.md
│   │   ├── record-level-validation.md
│   │   ├── simple.md
│   │   ├── submission-errors.md
│   │   ├── subscriptions.md
│   │   └── wizard.md
│   ├── examples.md
│   ├── faq.md
│   ├── getting-started.md
│   ├── migration/
│   │   ├── formik.md
│   │   └── redux-form.md
│   ├── philosophy.md
│   └── types/
│       ├── FieldProps.md
│       ├── FieldRenderProps.md
│       ├── FormProps.md
│       ├── FormRenderProps.md
│       ├── FormSpyProps.md
│       └── FormSpyRenderProps.md
├── eslint.config.mjs
├── examples/
│   ├── async-field-level-validation/
│   │   ├── Spinner.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── async-redux-submission/
│   │   ├── Styles.js
│   │   ├── asyncSubmissionMiddleware.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   ├── registrationDuck.js
│   │   └── store.js
│   ├── async-typeahead-redux/
│   │   ├── GithubUserTypeahead.jsx
│   │   ├── Styles.js
│   │   ├── actions.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   ├── store.js
│   │   └── useKeyword.js
│   ├── auto-save-field-blur/
│   │   ├── AutoSave.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── auto-save-selective-debounce/
│   │   ├── AutoSave.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── auto-save-with-debounce/
│   │   ├── AutoSave.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── calculated-fields/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── chakra/
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── validate.js
│   ├── conditional-fields/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── pickupTimes.js
│   │   └── readme.md
│   ├── credit-card/
│   │   ├── Card.js
│   │   ├── Styles.js
│   │   ├── cardUtils.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── sandbox.config.json
│   ├── custom-validation-engine/
│   │   ├── OnBlurValidation.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── debounced-record-level-validation/
│   │   ├── ErrorWithDelay.js
│   │   ├── README.md
│   │   ├── Styles.js
│   │   ├── index.js
│   │   └── package.json
│   ├── declarative-form-rules/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── downshift-typeahead/
│   │   ├── DownshiftInput.js
│   │   ├── Styles.js
│   │   ├── fruit.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── external-submit/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── field-arrays/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── field-level-validation/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── field-warnings/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── warning-engine.js
│   ├── fields-component/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── focus-first-error/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── validate.js
│   ├── format-on-blur/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── format-string-by-pattern/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── hybrid-sync-async-record-level-validation/
│   │   ├── Spinner.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── independent-error-component-render-props/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── independent-error-component-with-hooks/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── listening-for-external-changes/
│   │   ├── BooleanDecay.js
│   │   ├── ExternalModificationDetector.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── loading-initializing-values/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── loading-saving-reinitializing/
│   │   ├── LoadSaveReinitializeForm.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── material-ui/
│   │   ├── .prettierrc
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── parse-format/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── prefixed-fields/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── readme.md
│   ├── record-level-validation/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── redux/
│   │   ├── FormStateFromRedux.js
│   │   ├── FormStateToRedux.js
│   │   ├── Styles.js
│   │   ├── finalFormDuck.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── store.js
│   ├── reusable-field-groups/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── simple/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── strongly-typed-values-typescript/
│   │   ├── Styles.tsx
│   │   ├── components/
│   │   │   ├── CheckboxInput.tsx
│   │   │   ├── MultiCheckboxInput.tsx
│   │   │   ├── MultiSelectInput.tsx
│   │   │   ├── NumberInput.tsx
│   │   │   ├── RadioInput.tsx
│   │   │   ├── SelectInput.tsx
│   │   │   ├── TextAreaInput.tsx
│   │   │   └── TextInput.tsx
│   │   ├── index.tsx
│   │   └── readme.md
│   ├── styling-with-smooth-ui/
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── submission-errors/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── subscriptions/
│   │   ├── RenderCount.js
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── readme.md
│   ├── third-party-components/
│   │   ├── Styles.js
│   │   ├── index.js
│   │   ├── package.json
│   │   ├── readme.md
│   │   └── states.js
│   └── wizard/
│       ├── Styles.js
│       ├── Wizard.js
│       ├── index.js
│       ├── package.json
│       └── readme.md
├── package-scripts.js
├── package.json
├── rollup.config.mjs
├── src/
│   ├── Field.test.js
│   ├── Field.tsx
│   ├── FormSpy.test.js
│   ├── FormSpy.tsx
│   ├── ReactFinalForm.test.js
│   ├── ReactFinalForm.tsx
│   ├── context.test.js
│   ├── context.ts
│   ├── getValue.test.js
│   ├── getValue.ts
│   ├── getters.ts
│   ├── index.ts
│   ├── isReactNative.ts
│   ├── isSyntheticEvent.ts
│   ├── renderComponent.test.js
│   ├── renderComponent.ts
│   ├── shallowEqual.test.js
│   ├── shallowEqual.ts
│   ├── testUtils.ts
│   ├── types.ts
│   ├── useConstant.ts
│   ├── useConstantCallback.test.js
│   ├── useConstantCallback.ts
│   ├── useField.dynamic-name-869.test.js
│   ├── useField.test.js
│   ├── useField.ts
│   ├── useForm.test.js
│   ├── useForm.ts
│   ├── useFormState.test.js
│   ├── useFormState.ts
│   ├── useLatest.ts
│   └── useWhenValueChanges.ts
├── tsconfig.build.json
├── tsconfig.json
├── tslint.json
└── typescript/
    ├── Field.test.tsx
    ├── FormSpy.test.tsx
    ├── ReactFinalForm.test.tsx
    ├── index.d.ts
    ├── tsconfig.json
    ├── useField.test.tsx
    └── useFormState.test.tsx
Download .txt
SYMBOL INDEX (131 symbols across 47 files)

FILE: examples/async-redux-submission/registrationDuck.js
  constant REGISTER (line 4) | const REGISTER = "final-form-examples/registration/REGISTER";
  constant REGISTER_SUCCESS (line 5) | const REGISTER_SUCCESS =
  constant REGISTER_FAILURE (line 7) | const REGISTER_FAILURE =
  function reducer (line 11) | function reducer(state = {}, action = {}) {

FILE: examples/auto-save-field-blur/AutoSave.js
  class AutoSave (line 5) | class AutoSave extends React.Component {
    method constructor (line 6) | constructor(props) {
    method componentWillReceiveProps (line 11) | componentWillReceiveProps(nextProps) {
    method render (line 38) | render() {

FILE: examples/auto-save-selective-debounce/AutoSave.js
  class AutoSave (line 8) | class AutoSave extends React.Component {
    method constructor (line 12) | constructor(props) {
    method componentDidUpdate (line 21) | componentDidUpdate() {
    method render (line 87) | render() {

FILE: examples/auto-save-with-debounce/AutoSave.js
  class AutoSave (line 5) | class AutoSave extends React.Component {
    method constructor (line 6) | constructor(props) {
    method componentWillReceiveProps (line 11) | componentWillReceiveProps(nextProps) {
    method render (line 36) | render() {

FILE: examples/credit-card/cardUtils.js
  function clearNumber (line 3) | function clearNumber(value = "") {
  function formatCreditCardNumber (line 7) | function formatCreditCardNumber(value) {
  function formatCVC (line 40) | function formatCVC(value, prevValue, allValues = {}) {
  function formatExpirationDate (line 52) | function formatExpirationDate(value) {

FILE: examples/custom-validation-engine/OnBlurValidation.js
  class OnBlurValidation (line 5) | class OnBlurValidation extends React.Component {
    method componentWillReceiveProps (line 11) | componentWillReceiveProps(nextProps) {
    method render (line 46) | render() {

FILE: examples/listening-for-external-changes/BooleanDecay.js
  class BooleanDecay (line 14) | class BooleanDecay extends React.Component {
    method constructor (line 21) | constructor(props) {
    method startTimer (line 28) | startTimer() {
    method stopTimer (line 35) | stopTimer() {
    method componentDidMount (line 41) | componentDidMount() {
    method componentWillUnmount (line 47) | componentWillUnmount() {
    method componentWillReceiveProps (line 51) | componentWillReceiveProps(nextProps) {
    method render (line 63) | render() {

FILE: examples/listening-for-external-changes/ExternalModificationDetector.js
  class ExternalModificationDetector (line 9) | class ExternalModificationDetector extends React.Component {
    method constructor (line 10) | constructor(props) {
    method componentWillReceiveProps (line 18) | componentWillReceiveProps(nextProps) {
    method render (line 35) | render() {

FILE: examples/loading-initializing-values/index.js
  class App (line 21) | class App extends React.Component {
    method componentDidMount (line 23) | async componentDidMount() {
    method render (line 29) | render() {

FILE: examples/loading-saving-reinitializing/LoadSaveReinitializeForm.js
  class LoadSaveReinitializeForm (line 5) | class LoadSaveReinitializeForm extends React.Component {
    method componentDidMount (line 49) | componentDidMount() {
    method render (line 53) | render() {

FILE: examples/material-ui/index.js
  function App (line 164) | function App() {

FILE: examples/redux/finalFormDuck.js
  constant UPDATE_FORM_STATE (line 4) | const UPDATE_FORM_STATE =
  function reducer (line 8) | function reducer(state = {}, action = {}) {

FILE: examples/strongly-typed-values-typescript/components/CheckboxInput.tsx
  type Props (line 4) | type Props = FieldRenderProps<boolean, any>;

FILE: examples/strongly-typed-values-typescript/components/MultiCheckboxInput.tsx
  type Props (line 4) | type Props = FieldRenderProps<string, any>;

FILE: examples/strongly-typed-values-typescript/components/MultiSelectInput.tsx
  type Props (line 4) | type Props = FieldRenderProps<string[], any>;

FILE: examples/strongly-typed-values-typescript/components/NumberInput.tsx
  type Props (line 4) | type Props = FieldRenderProps<number, any>;

FILE: examples/strongly-typed-values-typescript/components/RadioInput.tsx
  function RadioInput (line 4) | function RadioInput<T extends string>({

FILE: examples/strongly-typed-values-typescript/components/SelectInput.tsx
  type Props (line 4) | type Props = FieldRenderProps<string, any>;

FILE: examples/strongly-typed-values-typescript/components/TextAreaInput.tsx
  type Props (line 4) | type Props = FieldRenderProps<string, any>;

FILE: examples/strongly-typed-values-typescript/components/TextInput.tsx
  type Props (line 4) | type Props = FieldRenderProps<string, any>;

FILE: examples/strongly-typed-values-typescript/index.tsx
  type Stooge (line 17) | type Stooge = "larry" | "moe" | "curly";
  type Values (line 18) | interface Values {

FILE: examples/subscriptions/RenderCount.js
  function RenderCount (line 4) | function RenderCount() {

FILE: examples/wizard/Wizard.js
  class Wizard (line 5) | class Wizard extends React.Component {
    method constructor (line 11) | constructor(props) {
    method render (line 53) | render() {

FILE: src/Field.test.js
  function sleep (line 11) | async function sleep(ms) {

FILE: src/Field.tsx
  function FieldComponent (line 6) | function FieldComponent<

FILE: src/FormSpy.tsx
  function FormSpy (line 7) | function FormSpy<FormValues = Record<string, any>>({

FILE: src/ReactFinalForm.test.js
  function sleep (line 11) | async function sleep(ms) {

FILE: src/ReactFinalForm.tsx
  function ReactFinalForm (line 40) | function ReactFinalForm<FormValues = Record<string, any>>({

FILE: src/index.ts
  function withTypes (line 10) | function withTypes<FormValues = Record<string, any>>() {

FILE: src/renderComponent.test.js
  method a (line 55) | get a() {
  method b (line 59) | get b() {

FILE: src/renderComponent.ts
  function renderComponent (line 6) | function renderComponent<T>(

FILE: src/shallowEqual.test.js
  function Foo (line 48) | function Foo() {

FILE: src/testUtils.ts
  function Toggle (line 11) | function Toggle({
  type ErrorBoundaryProps (line 25) | interface ErrorBoundaryProps {
  class ErrorBoundary (line 30) | class ErrorBoundary extends React.Component<ErrorBoundaryProps> {
    method componentDidCatch (line 31) | componentDidCatch(error: Error) {
    method render (line 35) | render() {

FILE: src/types.ts
  type SupportedInputs (line 12) | type SupportedInputs = "input" | "select" | "textarea";
  type ReactContext (line 14) | interface ReactContext<FormValues = Record<string, any>> {
  type FieldInputProps (line 18) | interface FieldInputProps<
  type FieldRenderProps (line 32) | interface FieldRenderProps<
  type FieldMetaState (line 63) | type FieldMetaState<FieldValue = any> = FieldRenderProps<FieldValue>['me...
  type SubmitEvent (line 65) | interface SubmitEvent {
  type FormRenderProps (line 70) | interface FormRenderProps<FormValues = Record<string, any>>
  type FormSpyRenderProps (line 78) | interface FormSpyRenderProps<FormValues = Record<string, any>>
  type RenderableProps (line 83) | interface RenderableProps<T> {
  type FormProps (line 89) | interface FormProps<FormValues = Record<string, any>>
  type UseFieldAutoConfig (line 102) | interface UseFieldAutoConfig {
  type UseFieldConfig (line 121) | interface UseFieldConfig extends UseFieldAutoConfig {
  type FieldProps (line 125) | interface FieldProps<
  type UseFormStateParams (line 137) | interface UseFormStateParams<FormValues = Record<string, any>> {
  type FormSpyProps (line 142) | interface FormSpyProps<FormValues = Record<string, any>>
  type FormSpyPropsWithForm (line 146) | interface FormSpyPropsWithForm<FormValues = Record<string, any>>

FILE: src/useConstant.ts
  function useConstant (line 15) | function useConstant<T>(init: () => T): T {

FILE: src/useConstantCallback.ts
  function useConstantCallback (line 9) | function useConstantCallback<T extends (...args: any[]) => any>(

FILE: src/useField.ts
  function useField (line 30) | function useField<

FILE: src/useForm.ts
  function useForm (line 5) | function useForm<FormValues = Record<string, any>>(

FILE: src/useFormState.ts
  function useFormState (line 9) | function useFormState<FormValues = Record<string, any>>({

FILE: src/useLatest.ts
  function useLatest (line 3) | function useLatest<T>(value: T): { readonly current: T } {

FILE: src/useWhenValueChanges.ts
  function useWhenValueChanges (line 3) | function useWhenValueChanges(

FILE: typescript/Field.test.tsx
  function FormText1 (line 6) | function FormText1({ input }: FieldRenderProps<string, HTMLInputElement>) {
  function FieldNumberValue (line 13) | function FieldNumberValue() {
  function FieldNumberInputValue (line 23) | function FieldNumberInputValue() {

FILE: typescript/FormSpy.test.tsx
  function submitButtonSpy (line 4) | function submitButtonSpy() {

FILE: typescript/ReactFinalForm.test.tsx
  function basic (line 22) | function basic() {
  function simple (line 43) | function simple() {
  function simpleSubscription (line 77) | function simpleSubscription() {
  function mutated (line 113) | function mutated() {
  type UserForm (line 146) | interface UserForm {
  function withTypedFormData (line 157) | function withTypedFormData() {
  function withTypedDecorator (line 185) | function withTypedDecorator() {

FILE: typescript/index.d.ts
  type SupportedInputs (line 12) | type SupportedInputs = "input" | "select" | "textarea";
  type ReactContext (line 14) | interface ReactContext<FormValues = Record<string, any>> {
  type FieldInputProps (line 18) | interface FieldInputProps<
  type FieldRenderProps (line 32) | interface FieldRenderProps<
  type FieldMetaState (line 63) | type FieldMetaState<FieldValue = any> = FieldRenderProps<FieldValue>['me...
  type SubmitEvent (line 65) | interface SubmitEvent {
  type FormRenderProps (line 70) | interface FormRenderProps<FormValues = Record<string, any>>
  type FormSpyRenderProps (line 78) | interface FormSpyRenderProps<FormValues = Record<string, any>>
  type RenderableProps (line 83) | interface RenderableProps<T> {
  type FormProps (line 89) | interface FormProps<FormValues = Record<string, any>>
  type UseFieldAutoConfig (line 101) | interface UseFieldAutoConfig {
  type UseFieldConfig (line 120) | interface UseFieldConfig extends UseFieldAutoConfig {
  type FieldProps (line 124) | interface FieldProps<
  type UseFormStateParams (line 136) | interface UseFormStateParams<FormValues = Record<string, any>> {
  type FormSpyProps (line 141) | interface FormSpyProps<FormValues = Record<string, any>>
  type FormSpyPropsWithForm (line 145) | interface FormSpyPropsWithForm<FormValues = Record<string, any>>

FILE: typescript/useField.test.tsx
  function NumberFieldValue (line 6) | function NumberFieldValue() {
  function NumberInputValue (line 11) | function NumberInputValue() {
  function MyComponent (line 19) | function MyComponent() {
  function MyTypedComponent (line 24) | function MyTypedComponent() {
  function MyTypedComponentWithElement (line 29) | function MyTypedComponentWithElement() {

FILE: typescript/useFormState.test.tsx
  function Comp1 (line 6) | function Comp1() {
  function MyComponent (line 11) | function MyComponent() {
  function MyTypedComponent (line 16) | function MyTypedComponent() {
Condensed preview — 293 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (822K chars).
[
  {
    "path": ".babelrc.js",
    "chars": 486,
    "preview": "const { NODE_ENV } = process.env;\nconst test = NODE_ENV === \"test\";\nconst loose = true;\n\nmodule.exports = {\n  presets: ["
  },
  {
    "path": ".eslintrc",
    "chars": 239,
    "preview": "{\n  \"extends\": \"react-app\",\n  \"plugins\": [\"react-hooks\"],\n  \"rules\": {\n    \"jsx-a11y/href-no-hash\": 0,\n    \"react-hooks/"
  },
  {
    "path": ".flowconfig",
    "chars": 44,
    "preview": "[ignore]\ndist\n\n[include]\n\n[libs]\n\n[options]\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 11,
    "preview": "* @erikras\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "chars": 3226,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 2594,
    "preview": "# Contributing\n\nThanks for your interest in contributing to 🏁 React Final Form! Please take a\nmoment to review this docu"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 545,
    "preview": "# These are supported funding model platforms\n\ngithub: erikras\npatreon: erikras\nopen_collective: final-form\nko_fi: # Rep"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 883,
    "preview": "<!--\n\n👋 Hey, thanks for taking an interest in 🏁 React Final Form!\n\n-->\n\n### Are you submitting a **bug report** or a **f"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 822,
    "preview": "<!--\n\n👋 Hey, thanks for your interest in contributing to 🏁 React Final Form!\n\n**Please ask first before starting work on"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 1243,
    "preview": "name: CI\n\non: [push]\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout"
  },
  {
    "path": ".github/workflows/lock.yml",
    "chars": 419,
    "preview": "name: \"Lock Threads\"\n\non:\n  schedule:\n    - cron: \"0 * * * *\"\n  workflow_dispatch:\n\npermissions:\n  issues: write\n  pull-"
  },
  {
    "path": ".gitignore",
    "chars": 114,
    "preview": ".vscode\n*.iml\n.nyc_output\ncoverage\nflow-coverage\nnode_modules\ndist\nlib\nes\nnpm-debug.log\n.DS_Store\n.yalc\nyalc.lock\n"
  },
  {
    "path": ".prettierignore",
    "chars": 26,
    "preview": "coverage\ndist\nnode_modules"
  },
  {
    "path": ".prettierrc",
    "chars": 29,
    "preview": "{\n  \"trailingComma\": \"all\"\n}\n"
  },
  {
    "path": ".travis.yml",
    "chars": 273,
    "preview": "sudo: false\nlanguage: node_js\nbefore_install:\n  - npm install -g npm@6.4.0\ncache:\n  directories:\n    - node_modules\nnoti"
  },
  {
    "path": "LICENSE",
    "chars": 1071,
    "preview": "MIT License\n\nCopyright (c) 2017 Erik Rasmussen\n\nPermission is hereby granted, free of charge, to any person obtaining a "
  },
  {
    "path": "MIGRATION_V7.md",
    "chars": 5116,
    "preview": "# Migration Guide: react-final-form v6 → v7\n\n## Overview\n\nVersion 7.0.0 includes a complete TypeScript rewrite (migrated"
  },
  {
    "path": "README.md",
    "chars": 2665,
    "preview": "# 🏁 React Final Form\n\n[![React Final Form](banner.png)](https://final-form.org/react)\n\n[![Backers on Open Collective](ht"
  },
  {
    "path": "docs/api/Field.md",
    "chars": 3885,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/Field). Li"
  },
  {
    "path": "docs/api/Form.md",
    "chars": 3202,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/Form). Lin"
  },
  {
    "path": "docs/api/FormSpy.md",
    "chars": 2637,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/FormSpy). "
  },
  {
    "path": "docs/api/useField.md",
    "chars": 871,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/useField)."
  },
  {
    "path": "docs/api/useForm.md",
    "chars": 589,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/useForm). "
  },
  {
    "path": "docs/api/useFormState.md",
    "chars": 532,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api/useFormSta"
  },
  {
    "path": "docs/api.md",
    "chars": 1658,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/api). Links ma"
  },
  {
    "path": "docs/examples/chakra.md",
    "chars": 461,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/chakr"
  },
  {
    "path": "docs/examples/field-level-validation.md",
    "chars": 557,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/field"
  },
  {
    "path": "docs/examples/record-level-validation.md",
    "chars": 544,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/recor"
  },
  {
    "path": "docs/examples/simple.md",
    "chars": 461,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/simpl"
  },
  {
    "path": "docs/examples/submission-errors.md",
    "chars": 611,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/submi"
  },
  {
    "path": "docs/examples/subscriptions.md",
    "chars": 703,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/subsc"
  },
  {
    "path": "docs/examples/wizard.md",
    "chars": 479,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples/wizar"
  },
  {
    "path": "docs/examples.md",
    "chars": 12256,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/examples). Lin"
  },
  {
    "path": "docs/faq.md",
    "chars": 5552,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/faq). Links ma"
  },
  {
    "path": "docs/getting-started.md",
    "chars": 2519,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/getting-starte"
  },
  {
    "path": "docs/migration/formik.md",
    "chars": 8398,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/migration-guid"
  },
  {
    "path": "docs/migration/redux-form.md",
    "chars": 11857,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/migration-guid"
  },
  {
    "path": "docs/philosophy.md",
    "chars": 2429,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/philosophy). L"
  },
  {
    "path": "docs/types/FieldProps.md",
    "chars": 9949,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FieldPro"
  },
  {
    "path": "docs/types/FieldRenderProps.md",
    "chars": 6350,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FieldRen"
  },
  {
    "path": "docs/types/FormProps.md",
    "chars": 7745,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FormProp"
  },
  {
    "path": "docs/types/FormRenderProps.md",
    "chars": 1127,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FormRend"
  },
  {
    "path": "docs/types/FormSpyProps.md",
    "chars": 4072,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FormSpyP"
  },
  {
    "path": "docs/types/FormSpyRenderProps.md",
    "chars": 706,
    "preview": "# This documentation is meant to be read on [final-form.org](https://final-form.org/docs/react-final-form/types/FormSpyR"
  },
  {
    "path": "eslint.config.mjs",
    "chars": 5211,
    "preview": "import js from \"@eslint/js\";\nimport typescriptParser from \"@typescript-eslint/parser\";\nimport typescriptPlugin from \"@ty"
  },
  {
    "path": "examples/async-field-level-validation/Spinner.js",
    "chars": 595,
    "preview": "import styled, { keyframes } from \"styled-components\";\n\nconst rotation = keyframes`\n    from {\n      -webkit-transform: "
  },
  {
    "path": "examples/async-field-level-validation/Styles.js",
    "chars": 2477,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/async-field-level-validation/index.js",
    "chars": 3448,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport Spinner from \"./Spi"
  },
  {
    "path": "examples/async-field-level-validation/package.json",
    "chars": 507,
    "preview": "{\n  \"name\": \"react-final-form-asynchronous-field-level-validation-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This"
  },
  {
    "path": "examples/async-field-level-validation/readme.md",
    "chars": 196,
    "preview": "# Asynchronous Field-Level Validation\n\n[![Edit react-final-form-async-field-level-validation-example](https://codesandbo"
  },
  {
    "path": "examples/async-redux-submission/Styles.js",
    "chars": 4155,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/async-redux-submission/asyncSubmissionMiddleware.js",
    "chars": 950,
    "preview": "import { REGISTER, REGISTER_SUCCESS } from \"./registrationDuck\";\n\nconst sleep = (ms) => new Promise((resolve) => setTime"
  },
  {
    "path": "examples/async-redux-submission/index.js",
    "chars": 4835,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport { Provider } from \"react-redux\";\nimport Styles fro"
  },
  {
    "path": "examples/async-redux-submission/package.json",
    "chars": 927,
    "preview": "{\n  \"name\": \"react-final-form-async-redux-submission\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use r"
  },
  {
    "path": "examples/async-redux-submission/readme.md",
    "chars": 177,
    "preview": "# Async Redux Submission\n\n[![Edit react-final-form-async-redux-submission-example](https://codesandbox.io/static/img/pla"
  },
  {
    "path": "examples/async-redux-submission/registrationDuck.js",
    "chars": 779,
    "preview": "// QUACK! This is a duck. https://github.com/erikras/ducks-modular-redux\n\n// Actions\nexport const REGISTER = \"final-form"
  },
  {
    "path": "examples/async-redux-submission/store.js",
    "chars": 890,
    "preview": "import { createStore, combineReducers, applyMiddleware, compose } from \"redux\";\nimport createReduxPromiseListener from \""
  },
  {
    "path": "examples/async-typeahead-redux/GithubUserTypeahead.jsx",
    "chars": 1352,
    "preview": "import React, { useCallback } from \"react\";\nimport { useSelector, useDispatch } from \"react-redux\";\nimport { Field } fro"
  },
  {
    "path": "examples/async-typeahead-redux/Styles.js",
    "chars": 3685,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/async-typeahead-redux/actions.js",
    "chars": 470,
    "preview": "export const requestGithubUsers = (query) => ({\n  type: \"GITHUB_USERS_REQUEST\",\n  query,\n});\n\nexport const storeGithubUs"
  },
  {
    "path": "examples/async-typeahead-redux/index.js",
    "chars": 1636,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport { Provider } from \"react-redux\";\nimport Styles fro"
  },
  {
    "path": "examples/async-typeahead-redux/package.json",
    "chars": 706,
    "preview": "{\n  \"name\": \"react-final-form-github-user-asynctypeahead\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how exte"
  },
  {
    "path": "examples/async-typeahead-redux/readme.md",
    "chars": 182,
    "preview": "# Async Typeahead and Redux\n\n[![Edit react-final-form-async-typeahead-and-redux-example](https://codesandbox.io/static/i"
  },
  {
    "path": "examples/async-typeahead-redux/store.js",
    "chars": 650,
    "preview": "import { createStore, applyMiddleware } from \"redux\";\nimport thunk from \"redux-thunk\";\n\nconst initialState = {};\nconst r"
  },
  {
    "path": "examples/async-typeahead-redux/useKeyword.js",
    "chars": 408,
    "preview": "import { useForm, useField } from \"react-final-form\";\nimport { propOr } from \"ramda\";\n\nconst useKeyword = (name) => {\n  "
  },
  {
    "path": "examples/auto-save-field-blur/AutoSave.js",
    "chars": 1592,
    "preview": "import React from \"react\";\nimport { FormSpy } from \"react-final-form\";\nimport diff from \"object-diff\";\n\nclass AutoSave e"
  },
  {
    "path": "examples/auto-save-field-blur/Styles.js",
    "chars": 3683,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/auto-save-field-blur/index.js",
    "chars": 6016,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/auto-save-field-blur/package.json",
    "chars": 497,
    "preview": "{\n  \"name\": \"react-final-form-auto-save-on-field-blur\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to crea"
  },
  {
    "path": "examples/auto-save-field-blur/readme.md",
    "chars": 176,
    "preview": "# Auto-Save on Field Blur\n\n[![Edit react-final-form-auto-save-field-blur-example](https://codesandbox.io/static/img/play"
  },
  {
    "path": "examples/auto-save-selective-debounce/AutoSave.js",
    "chars": 2593,
    "preview": "import React from \"react\";\nimport { FormSpy } from \"react-final-form\";\nimport diff from \"object-diff\";\n\nconst areObjects"
  },
  {
    "path": "examples/auto-save-selective-debounce/Styles.js",
    "chars": 3566,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/auto-save-selective-debounce/index.js",
    "chars": 5511,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/auto-save-selective-debounce/package.json",
    "chars": 477,
    "preview": "{\n  \"name\": \"react-final-form-auto-save-with-selective-debounce\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates h"
  },
  {
    "path": "examples/auto-save-selective-debounce/readme.md",
    "chars": 196,
    "preview": "# Auto-Save with _Selective_ Debounce\n\n[![Edit react-final-form-auto-save-selective-debounce-example](https://codesandbo"
  },
  {
    "path": "examples/auto-save-with-debounce/AutoSave.js",
    "chars": 1520,
    "preview": "import React from \"react\";\nimport { FormSpy } from \"react-final-form\";\nimport diff from \"object-diff\";\n\nclass AutoSave e"
  },
  {
    "path": "examples/auto-save-with-debounce/Styles.js",
    "chars": 3566,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/auto-save-with-debounce/index.js",
    "chars": 5207,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/auto-save-with-debounce/package.json",
    "chars": 515,
    "preview": "{\n  \"name\": \"react-final-form-auto-save-with-debounce\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use "
  },
  {
    "path": "examples/auto-save-with-debounce/readme.md",
    "chars": 179,
    "preview": "# Auto-Save with Debounce\n\n[![Edit react-final-form-auto-save-with-debounce-example](https://codesandbox.io/static/img/p"
  },
  {
    "path": "examples/calculated-fields/Styles.js",
    "chars": 3253,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/calculated-fields/index.js",
    "chars": 4337,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/calculated-fields/package.json",
    "chars": 491,
    "preview": "{\n  \"name\": \"react-final-form-calculated-fields\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use the fi"
  },
  {
    "path": "examples/calculated-fields/readme.md",
    "chars": 167,
    "preview": "# Calculated Fields\n\n[![Edit react-final-form-calculated-fields-example](https://codesandbox.io/static/img/play-codesand"
  },
  {
    "path": "examples/chakra/index.js",
    "chars": 7354,
    "preview": "/* eslint-disable jsx-a11y/accessible-emoji */\nimport React from \"react\";\nimport { render } from \"react-dom\";\nimport {\n "
  },
  {
    "path": "examples/chakra/package.json",
    "chars": 726,
    "preview": "{\n  \"name\": \"Chakra-Example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example form using Chakra UI\",\n  \"keywords\": [\n"
  },
  {
    "path": "examples/chakra/readme.md",
    "chars": 220,
    "preview": "# Chakra UI Example\n\n[![Edit react-final-form-chakra-example](https://codesandbox.io/static/img/play-codesandbox.svg)](h"
  },
  {
    "path": "examples/chakra/validate.js",
    "chars": 799,
    "preview": "const validate = (values) => {\n  const errors = {};\n  if (!values.firstName) {\n    errors.firstName = \"Required\";\n  }\n  "
  },
  {
    "path": "examples/conditional-fields/Styles.js",
    "chars": 3954,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/conditional-fields/index.js",
    "chars": 4878,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/conditional-fields/package.json",
    "chars": 672,
    "preview": "{\n  \"name\": \"react-final-form-conditional-fields\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to condition"
  },
  {
    "path": "examples/conditional-fields/pickupTimes.js",
    "chars": 361,
    "preview": "// This is not the best way to do this. Don't think to hard about this.\nconst now = new Date();\nlet hours = now.getHours"
  },
  {
    "path": "examples/conditional-fields/readme.md",
    "chars": 168,
    "preview": "# Conditional Fields\n\n[![Edit react-final-form-conditional-fields-example](https://codesandbox.io/static/img/play-codesa"
  },
  {
    "path": "examples/credit-card/Card.js",
    "chars": 84807,
    "preview": "import React from \"react\";\nimport styled from \"styled-components\";\nimport Cards from \"react-credit-cards\";\n\nconst Contai"
  },
  {
    "path": "examples/credit-card/Styles.js",
    "chars": 4155,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/credit-card/cardUtils.js",
    "chars": 1368,
    "preview": "import Payment from \"payment\";\n\nfunction clearNumber(value = \"\") {\n  return value.replace(/\\D+/g, \"\");\n}\n\nexport functio"
  },
  {
    "path": "examples/credit-card/index.js",
    "chars": 3057,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/credit-card/package.json",
    "chars": 802,
    "preview": "{\n  \"name\": \"react-final-form-credit-card-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use 🏁 Re"
  },
  {
    "path": "examples/credit-card/readme.md",
    "chars": 163,
    "preview": "# Credit Card Example\n\n[![Edit react-final-form-credit-card-example](https://codesandbox.io/static/img/play-codesandbox."
  },
  {
    "path": "examples/credit-card/sandbox.config.json",
    "chars": 69,
    "preview": "{\n  \"infiniteLoopProtection\": false,\n  \"hardReloadOnChange\": false\n}\n"
  },
  {
    "path": "examples/custom-validation-engine/OnBlurValidation.js",
    "chars": 1493,
    "preview": "import React from \"react\";\nimport { getIn } from \"final-form\";\nimport { FormSpy } from \"react-final-form\";\n\nclass OnBlur"
  },
  {
    "path": "examples/custom-validation-engine/Styles.js",
    "chars": 3685,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/custom-validation-engine/index.js",
    "chars": 4614,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/custom-validation-engine/package.json",
    "chars": 572,
    "preview": "{\n  \"name\": \"react-final-form-custom-validation-engine\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how extens"
  },
  {
    "path": "examples/custom-validation-engine/readme.md",
    "chars": 181,
    "preview": "# Custom Validation Engine\n\n[![Edit react-final-form-custom-validation-engine-example](https://codesandbox.io/static/img"
  },
  {
    "path": "examples/debounced-record-level-validation/ErrorWithDelay.js",
    "chars": 1074,
    "preview": "import React from \"react\";\nimport { Field } from \"react-final-form\";\n\nconst DisplayError = ({ delay, active, dirty, erro"
  },
  {
    "path": "examples/debounced-record-level-validation/README.md",
    "chars": 224,
    "preview": "# Synchronous Record-Level Validation (with debounced errors)\n\n[![Edit react-final-form-debounced-record-level-validatio"
  },
  {
    "path": "examples/debounced-record-level-validation/Styles.js",
    "chars": 2505,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/debounced-record-level-validation/index.js",
    "chars": 3871,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport ErrorWithDelay from"
  },
  {
    "path": "examples/debounced-record-level-validation/package.json",
    "chars": 714,
    "preview": "{\n  \"name\": \"react-final-form-synchronous-errors-debounced\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A DelayedRender com"
  },
  {
    "path": "examples/declarative-form-rules/Styles.js",
    "chars": 4155,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/declarative-form-rules/index.js",
    "chars": 3494,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/declarative-form-rules/package.json",
    "chars": 821,
    "preview": "{\n  \"name\": \"react-final-form-declarative-form-rules\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use R"
  },
  {
    "path": "examples/declarative-form-rules/readme.md",
    "chars": 176,
    "preview": "# Declarative Form Rules\n\n[![Edit react-final-form-declarative-form-rules-example](https://codesandbox.io/static/img/pla"
  },
  {
    "path": "examples/downshift-typeahead/DownshiftInput.js",
    "chars": 1963,
    "preview": "import React from \"react\";\nimport Downshift from \"downshift\";\nimport matchSorter from \"match-sorter\";\n\nconst itemToStrin"
  },
  {
    "path": "examples/downshift-typeahead/Styles.js",
    "chars": 3954,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/downshift-typeahead/fruit.js",
    "chars": 490,
    "preview": "export default [\n  { value: \"Apple\", label: \"🍎 Apple\" },\n  { value: \"Banana\", label: \"🍌 Banana\" },\n  { value: \"Cherry\", "
  },
  {
    "path": "examples/downshift-typeahead/index.js",
    "chars": 2664,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/downshift-typeahead/package.json",
    "chars": 799,
    "preview": "{\n  \"name\": \"react-final-form-downshift-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use a 🏎️ D"
  },
  {
    "path": "examples/downshift-typeahead/readme.md",
    "chars": 173,
    "preview": "# Downshift Type-Ahead\n\n[![Edit react-final-form-downshift-type-ahead-example](https://codesandbox.io/static/img/play-co"
  },
  {
    "path": "examples/external-submit/Styles.js",
    "chars": 3236,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/external-submit/index.js",
    "chars": 3761,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/external-submit/package.json",
    "chars": 513,
    "preview": "{\n  \"name\": \"react-final-form-external-submit-button\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how you can "
  },
  {
    "path": "examples/external-submit/readme.md",
    "chars": 163,
    "preview": "# External Submit\n\n[![Edit react-final-form-external-submit-example](https://codesandbox.io/static/img/play-codesandbox."
  },
  {
    "path": "examples/field-arrays/Styles.js",
    "chars": 2896,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/field-arrays/index.js",
    "chars": 3070,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/field-arrays/package.json",
    "chars": 495,
    "preview": "{\n  \"name\": \"react-final-form-field-arrays\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonstrates how to us"
  },
  {
    "path": "examples/field-arrays/readme.md",
    "chars": 157,
    "preview": "# Field Arrays\n\n[![Edit react-final-form-field-arrays-example](https://codesandbox.io/static/img/play-codesandbox.svg)]("
  },
  {
    "path": "examples/field-level-validation/Styles.js",
    "chars": 2428,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/field-level-validation/index.js",
    "chars": 2762,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/field-level-validation/package.json",
    "chars": 506,
    "preview": "{\n  \"name\": \"React Final Form - Synchronous Field Level Validation\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example "
  },
  {
    "path": "examples/field-level-validation/readme.md",
    "chars": 265,
    "preview": "# Field Level Validation Example\n\n[![Edit react-final-form-field-level-validation-example](https://codesandbox.io/static"
  },
  {
    "path": "examples/field-warnings/Styles.js",
    "chars": 3253,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/field-warnings/index.js",
    "chars": 2848,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { WarningEngine } f"
  },
  {
    "path": "examples/field-warnings/package.json",
    "chars": 465,
    "preview": "{\n  \"name\": \"react-final-form-warnings\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use final-form-set-"
  },
  {
    "path": "examples/field-warnings/readme.md",
    "chars": 182,
    "preview": "# Field Warnings\n\n[![Edit react-final-form-field-warnings-example](https://codesandbox.io/static/img/play-codesandbox.sv"
  },
  {
    "path": "examples/field-warnings/warning-engine.js",
    "chars": 445,
    "preview": "import React from \"react\";\nimport { FormSpy } from \"react-final-form\";\n\nexport const WarningEngine = ({ mutators: { setF"
  },
  {
    "path": "examples/fields-component/Styles.js",
    "chars": 2301,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/fields-component/index.js",
    "chars": 2747,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/fields-component/package.json",
    "chars": 577,
    "preview": "{\n  \"name\": \"react-final-form-fields-component\",\n  \"version\": \"1.0.0\",\n  \"description\": \"One common question from people"
  },
  {
    "path": "examples/fields-component/readme.md",
    "chars": 165,
    "preview": "# Fields Component\n\n[![Edit react-final-form-fields-component-example](https://codesandbox.io/static/img/play-codesandbo"
  },
  {
    "path": "examples/focus-first-error/Styles.js",
    "chars": 4095,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/focus-first-error/index.js",
    "chars": 2941,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/focus-first-error/package.json",
    "chars": 734,
    "preview": "{\n  \"name\": \"react-final-form-focus-on-first-error\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use the"
  },
  {
    "path": "examples/focus-first-error/readme.md",
    "chars": 170,
    "preview": "# Focus on First Error\n\n[![Edit react-final-form-focus-first-error-example](https://codesandbox.io/static/img/play-codes"
  },
  {
    "path": "examples/focus-first-error/validate.js",
    "chars": 385,
    "preview": "export default (values) => {\n  const errors = {};\n  if (!values.firstName) {\n    errors.firstName = \"Required\";\n  }\n  if"
  },
  {
    "path": "examples/format-on-blur/Styles.js",
    "chars": 4447,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/format-on-blur/index.js",
    "chars": 2323,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/format-on-blur/package.json",
    "chars": 773,
    "preview": "{\n  \"name\": \"react-final-form-format-on-blur-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use t"
  },
  {
    "path": "examples/format-on-blur/readme.md",
    "chars": 161,
    "preview": "# Format on Blur\n\n[![Edit react-final-form-format-on-blur-example](https://codesandbox.io/static/img/play-codesandbox.sv"
  },
  {
    "path": "examples/format-string-by-pattern/Styles.js",
    "chars": 3236,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/format-string-by-pattern/index.js",
    "chars": 1821,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/format-string-by-pattern/package.json",
    "chars": 449,
    "preview": "{\n  \"name\": \"format-string-by-pattern-with-react-final-form\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how t"
  },
  {
    "path": "examples/format-string-by-pattern/readme.md",
    "chars": 180,
    "preview": "# Format String by Pattern\n\n[![Edit react-final-form-format-string-by-pattern-example](https://codesandbox.io/static/img"
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/Spinner.js",
    "chars": 595,
    "preview": "import styled, { keyframes } from \"styled-components\";\n\nconst rotation = keyframes`\n    from {\n      -webkit-transform: "
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/Styles.js",
    "chars": 2477,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/index.js",
    "chars": 3336,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport Spinner from \"./Spi"
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/package.json",
    "chars": 570,
    "preview": "{\n  \"name\": \"react-final-form-hybrid-synchronous-asynchronous-record-level-validation-example\",\n  \"version\": \"1.0.0\",\n  "
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/readme.md",
    "chars": 222,
    "preview": "# Hybrid Synchronous/Asynchronous Record-level Validation\n\n[![Edit react-final-form-hybrid-sync-async-record-validation-"
  },
  {
    "path": "examples/independent-error-component-render-props/Styles.js",
    "chars": 3253,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/independent-error-component-render-props/index.js",
    "chars": 2665,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/independent-error-component-render-props/package.json",
    "chars": 417,
    "preview": "{\n  \"name\": \"react-final-form-independent-error-component\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonst"
  },
  {
    "path": "examples/independent-error-component-render-props/readme.md",
    "chars": 230,
    "preview": "# Reusable Independent Error Component (using render props)\n\n[![Edit react-final-form-independent-error-component-render"
  },
  {
    "path": "examples/independent-error-component-with-hooks/Styles.js",
    "chars": 3253,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/independent-error-component-with-hooks/index.js",
    "chars": 2659,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field, useF"
  },
  {
    "path": "examples/independent-error-component-with-hooks/package.json",
    "chars": 428,
    "preview": "{\n  \"name\": \"react-final-form-independent-error-component-with-hooks\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This exam"
  },
  {
    "path": "examples/independent-error-component-with-hooks/readme.md",
    "chars": 272,
    "preview": "# Reusable Independent Error Component (using hooks)\n\n[![Edit react-final-form-independent-error-component-with-hooks-ex"
  },
  {
    "path": "examples/listening-for-external-changes/BooleanDecay.js",
    "chars": 1474,
    "preview": "import React from \"react\";\nimport PropTypes from \"prop-types\";\n\n/**\n * 👋 Hey! Thanks for being curious about what this c"
  },
  {
    "path": "examples/listening-for-external-changes/ExternalModificationDetector.js",
    "chars": 1290,
    "preview": "import React from \"react\";\nimport { Field } from \"react-final-form\";\n\n/**\n * Listens for changes to a field's value, and"
  },
  {
    "path": "examples/listening-for-external-changes/Styles.js",
    "chars": 3954,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/listening-for-external-changes/index.js",
    "chars": 4152,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/listening-for-external-changes/package.json",
    "chars": 825,
    "preview": "{\n  \"name\": \"react-final-form-listening-for-external-changes\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how "
  },
  {
    "path": "examples/listening-for-external-changes/readme.md",
    "chars": 193,
    "preview": "# Listening for External Changes\n\n[![Edit react-final-form-listening-for-external-changes-example](https://codesandbox.i"
  },
  {
    "path": "examples/loading-initializing-values/Styles.js",
    "chars": 3253,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/loading-initializing-values/index.js",
    "chars": 2412,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/loading-initializing-values/package.json",
    "chars": 404,
    "preview": "{\n  \"name\": \"react-final-form-loading-and-initializing\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonstrat"
  },
  {
    "path": "examples/loading-initializing-values/readme.md",
    "chars": 191,
    "preview": "# Loading and Initializing Values\n\n[![Edit react-final-form-loading-initializing-values-example](https://codesandbox.io/"
  },
  {
    "path": "examples/loading-saving-reinitializing/LoadSaveReinitializeForm.js",
    "chars": 1648,
    "preview": "import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { Form } from \"react-final-form\";\n\nexport default "
  },
  {
    "path": "examples/loading-saving-reinitializing/Styles.js",
    "chars": 3431,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/loading-saving-reinitializing/index.js",
    "chars": 4811,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Field } from \"rea"
  },
  {
    "path": "examples/loading-saving-reinitializing/package.json",
    "chars": 582,
    "preview": "{\n  \"name\": \"react-final-form-example-load-save-and-reinitialize\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates "
  },
  {
    "path": "examples/loading-saving-reinitializing/readme.md",
    "chars": 203,
    "preview": "# Loading, Normalizing, Saving, and Reinitializing\n\n[![Edit react-final-form-load-save-reinitialize-example](https://cod"
  },
  {
    "path": "examples/material-ui/.prettierrc",
    "chars": 199,
    "preview": "{\n  \"printWidth\": 80,\n  \"tabWidth\": 2,\n  \"useTabs\": false,\n  \"semi\": true,\n  \"singleQuote\": true,\n  \"trailingComma\": \"al"
  },
  {
    "path": "examples/material-ui/index.js",
    "chars": 5362,
    "preview": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Form } from 'react-final-form';\nimport {\n  TextFie"
  },
  {
    "path": "examples/material-ui/package.json",
    "chars": 835,
    "preview": "{\n  \"name\": \"react-final-form-material-ui-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use Mate"
  },
  {
    "path": "examples/material-ui/readme.md",
    "chars": 159,
    "preview": "# Material-UI 3.0\n\n[![Edit react-final-form-material-ui-example](https://codesandbox.io/static/img/play-codesandbox.svg)"
  },
  {
    "path": "examples/parse-format/Styles.js",
    "chars": 3236,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/parse-format/index.js",
    "chars": 2264,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/parse-format/package.json",
    "chars": 509,
    "preview": "{\n  \"name\": \"react-final-form-parse-and-format\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use parse a"
  },
  {
    "path": "examples/parse-format/readme.md",
    "chars": 177,
    "preview": "# Parse and Format (and Normalize)\n\n[![Edit react-final-form-parse-format-example](https://codesandbox.io/static/img/pla"
  },
  {
    "path": "examples/prefixed-fields/Styles.js",
    "chars": 2293,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/prefixed-fields/index.js",
    "chars": 3386,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/prefixed-fields/package.json",
    "chars": 618,
    "preview": "{\n  \"name\": \"react-final-form-prefixed-fields\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example shows how to use Re"
  },
  {
    "path": "examples/prefixed-fields/readme.md",
    "chars": 191,
    "preview": "# Prefixed Fields\n\n[![Edit react-final-form-prefixed-fields-example](https://codesandbox.io/static/img/play-codesandbox."
  },
  {
    "path": "examples/readme.md",
    "chars": 76,
    "preview": "# [See the Examples](https://final-form.org/docs/react-final-form/examples)\n"
  },
  {
    "path": "examples/record-level-validation/Styles.js",
    "chars": 2428,
    "preview": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: in"
  },
  {
    "path": "examples/record-level-validation/index.js",
    "chars": 2638,
    "preview": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } fro"
  },
  {
    "path": "examples/record-level-validation/package.json",
    "chars": 508,
    "preview": "{\n  \"name\": \"React Final Form - Synchronous Record Level Validation\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example"
  },
  {
    "path": "examples/record-level-validation/readme.md",
    "chars": 268,
    "preview": "# Record Level Validation Example\n\n[![Edit react-final-form-record-level-validation-example](https://codesandbox.io/stat"
  },
  {
    "path": "examples/redux/FormStateFromRedux.js",
    "chars": 323,
    "preview": "import React from \"react\";\nimport { connect } from \"react-redux\";\nimport { getFormState } from \"./finalFormDuck\";\n\nconst"
  }
]

// ... and 93 more files (download for full content)

About this extraction

This page contains the full source code of the final-form/react-final-form GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 293 files (748.1 KB), approximately 233.0k tokens, and a symbol index with 131 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!