[
  {
    "path": ".babelrc.js",
    "content": "const { NODE_ENV } = process.env;\nconst test = NODE_ENV === \"test\";\nconst loose = true;\n\nmodule.exports = {\n  presets: [\n    [\n      \"@babel/preset-env\",\n      {\n        loose,\n        ...(test ? { targets: { node: \"8\" } } : {}),\n      },\n    ],\n    \"@babel/preset-react\",\n    \"@babel/preset-typescript\",\n  ],\n  plugins: [\n    \"@babel/plugin-syntax-dynamic-import\",\n    \"@babel/plugin-syntax-import-meta\",\n    test && \"@babel/plugin-transform-react-jsx-source\",\n  ].filter(Boolean),\n};\n"
  },
  {
    "path": ".eslintrc",
    "content": "{\n  \"extends\": \"react-app\",\n  \"plugins\": [\"react-hooks\"],\n  \"rules\": {\n    \"jsx-a11y/href-no-hash\": 0,\n    \"react-hooks/rules-of-hooks\": \"error\",\n    \"react-hooks/exhaustive-deps\": \"warn\",\n    \"import/no-anonymous-default-export\": 0\n  }\n}\n"
  },
  {
    "path": ".flowconfig",
    "content": "[ignore]\ndist\n\n[include]\n\n[libs]\n\n[options]\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "* @erikras\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, gender identity and expression, level of\nexperience, nationality, personal appearance, race, religion, or sexual identity\nand orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n* Using welcoming and inclusive language\n* Being respectful of differing viewpoints and experiences\n* Gracefully accepting constructive criticism\n* Focusing on what is best for the community\n* Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n* The use of sexualized language or imagery and unwelcome sexual attention or\n  advances\n* Trolling, insulting/derogatory comments, and personal or political attacks\n* Public or private harassment\n* Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n* Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or reject\ncomments, commits, code, wiki edits, issues, and other contributions that are\nnot aligned to this Code of Conduct, or to ban temporarily or permanently any\ncontributor for other behaviors that they deem inappropriate, threatening,\noffensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at rasmussenerik@gmail.com. The project\nteam will review and investigate all complaints, and will respond in a way that\nit deems appropriate to the circumstances. The project team is obligated to\nmaintain confidentiality with regard to the reporter of an incident. Further\ndetails of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage],\nversion 1.4, available at [http://contributor-covenant.org/version/1/4][version]\n\n[homepage]: http://contributor-covenant.org\n[version]: http://contributor-covenant.org/version/1/4/\n"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "content": "# Contributing\n\nThanks for your interest in contributing to 🏁 React Final Form! Please take a\nmoment to review this document **before submitting a pull request**.\n\nWe are open to, and grateful for, any contributions made by the community.\n\n## Reporting issues and asking questions\n\nBefore opening an issue, please search\nthe [issue tracker](https://github.com/final-form/react-final-form/issues) to\nmake sure your issue hasn’t already been reported.\n\n**We use the issue tracker to keep track of bugs and improvements** to 🏁 React\nFinal Form itself, its examples, and the documentation. We encourage you to open\nissues to discuss improvements, architecture, internal implementation, etc. If a\ntopic has been discussed before, we will ask you to join the previous\ndiscussion.\n\nFor support or usage questions, please search and ask on\n[StackOverflow with a `react-final-form` tag](https://stackoverflow.com/questions/tagged/react-final-form).\nWe ask you to do this because StackOverflow has a much better job at keeping\npopular questions visible. Unfortunately good answers get lost and outdated on\nGitHub.\n\n**If you already asked at StackOverflow and still got no answers, post an issue\nwith the question link, so we can either answer it or evolve into a bug/feature\nrequest.**\n\n## Sending a pull request\n\n**Please ask first before starting work on any significant new features.**\n\nIt's never a fun experience to have your pull request declined after investing a\nlot of time and effort into a new feature. To avoid this from happening, we\nrequest that contributors create\n[an issue](https://github.com/final-form/react-final-form/issues) to first\ndiscuss any significant new features.\n\nPlease try to keep your pull request focused in scope and avoid including\nunrelated commits.\n\nAfter you have submitted your pull request, we’ll try to get back to you as soon\nas possible. We may suggest some changes or improvements.\n\nPlease format the code before submitting your pull request by running:\n\n```sh\nnpm run precommit\n```\n\n## Coding standards\n\nOur code formatting rules are defined in\n[.eslintrc](https://github.com/final-form/react-final-form/blob/master/.eslintrc).\nYou can check your code against these standards by running:\n\n```sh\nnpm start lint\n```\n\nTo automatically fix any style violations in your code, you can run:\n\n```sh\nnpm run precommit\n```\n\n## Running tests\n\nYou can run the test suite using the following commands:\n\n```sh\nnpm test\n```\n\nPlease ensure that the tests are passing when submitting a pull request. If\nyou're adding new features to 🏁 React Final Form, please include tests.\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: erikras\npatreon: erikras\nopen_collective: final-form\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: # Replace with a single custom sponsorship URL\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "content": "<!--\n\n👋 Hey, thanks for taking an interest in 🏁 React Final Form!\n\n-->\n\n### Are you submitting a **bug report** or a **feature request**?\n\n<!-- For support request, please use Stack Overflow instead. This issue tracker is reserved for bugs and features. -->\n\n### What is the current behavior?\n\n<!-- If this is a bug, please include steps to reproduce and a minimal demo of the problem using Sandbox, Plunkr, WebpackBin or JSFiddle. -->\n\n### What is the expected behavior?\n\n### Sandbox Link\n\n<!-- Problems are much easier to understand and debug if they can be demonstrated in a minimal environment.  -->\n\n### What's your environment?\n\n<!-- Include 🏁 React Final Form version, 🏁 Final Form version, OS/browser affected, Node version, etc. -->\n\n### Other information\n\n<!-- Include here any detailed explanation, stacktraces, related issues, links for Stack Overflow, Twitter, etc. -->\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\n\n👋 Hey, thanks for your interest in contributing to 🏁 React Final Form!\n\n**Please ask first before starting work on any significant new features.**\n\nIt's never a fun experience to have your pull request declined after investing a\nlot of time and effort into a new feature. To avoid this from happening, we\nrequest that contributors create an issue to first discuss any significant new\nfeatures.\n\nPlease try to keep your pull request focused in scope and avoid including\nunrelated commits.\n\nAfter you have submitted your pull request, we’ll try to get back to you as soon\nas possible. We may suggest some changes or improvements.\n\nPlease format the code before submitting your pull request by running:\n\n```\nnpm run precommit\n```\n\nhttps://github.com/final-form/react-final-form/blob/master/.github/CONTRIBUTING.md\n\n-->\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\n\non: [push]\n\njobs:\n  lint:\n    name: Lint\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js ${{ matrix.node_version }}\n        uses: actions/setup-node@v2\n        with:\n          node-version: \"22\"\n      - name: Prepare env\n        run: yarn install --ignore-scripts --frozen-lockfile\n      - name: Run linter\n        run: yarn start lint\n\n  prettier:\n    name: Prettier Check\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js ${{ matrix.node_version }}\n        uses: actions/setup-node@v2\n        with:\n          node-version: \"22\"\n      - name: Prepare env\n        run: yarn install --ignore-scripts --frozen-lockfile\n      - name: Run prettier\n        run: yarn start prettier\n\n  test:\n    name: Unit Tests\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - name: Use Node.js ${{ matrix.node_version }}\n        uses: actions/setup-node@v2\n        with:\n          node-version: \"22\"\n      - name: Prepare env\n        run: yarn install --ignore-scripts --frozen-lockfile\n      - name: Run unit tests\n        run: yarn start test\n      - name: Run code coverage\n        uses: codecov/codecov-action@v2.1.0\n"
  },
  {
    "path": ".github/workflows/lock.yml",
    "content": "name: \"Lock Threads\"\n\non:\n  schedule:\n    - cron: \"0 * * * *\"\n  workflow_dispatch:\n\npermissions:\n  issues: write\n  pull-requests: write\n\nconcurrency:\n  group: lock\n\njobs:\n  action:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: dessant/lock-threads@v3\n        with:\n          issue-inactive-days: \"365\"\n          issue-lock-reason: \"resolved\"\n          pr-inactive-days: \"365\"\n          pr-lock-reason: \"resolved\"\n"
  },
  {
    "path": ".gitignore",
    "content": ".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",
    "content": "coverage\ndist\nnode_modules"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"trailingComma\": \"all\"\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "sudo: false\nlanguage: node_js\nbefore_install:\n  - npm install -g npm@6.4.0\ncache:\n  directories:\n    - node_modules\nnotifications:\n  email: false\nnode_js:\n  - \"10\"\n  - \"12\"\n  - \"14\"\nscript:\n  - npm start validate\nafter_success:\n  - npx codecov\nbranches:\n  only:\n    - main\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2017 Erik Rasmussen\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "MIGRATION_V7.md",
    "content": "# Migration Guide: react-final-form v6 → v7\n\n## Overview\n\nVersion 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.\n\n## Breaking Changes\n\n### 1. FormState Properties Now Optional\n\nIn v7.0.0, most FormState boolean properties can be `undefined`:\n\n**❌ Before (v6.x):**\n\n```typescript\nconst { dirty, pristine, valid } = formState;\nif (dirty && !pristine) { // Works fine\n  // ...\n}\n```\n\n**✅ After (v7.0.0):**\n\n```typescript\nconst { dirty, pristine, valid } = formState;\nif ((dirty ?? false) && !(pristine ?? true)) { // Must handle undefined\n  // ...\n}\n```\n\n**Affected properties:**\n- `dirty`, `pristine`, `valid`, `invalid`\n- `dirtySinceLastSubmit`, `modifiedSinceLastSubmit`\n- `submitFailed`, `submitSucceeded`, `submitting`, `validating`\n- `hasSubmitErrors`, `hasValidationErrors`\n\n**Note:** `values` is still guaranteed to be defined.\n\n### 2. FieldMetaState Type No Longer Exported\n\n**❌ Before (v6.x):**\n\n```typescript\nimport { FieldMetaState } from 'react-final-form';\n\nconst meta: FieldMetaState = { /* ... */ };\n```\n\n**✅ After (v7.0.0):**\n\n```typescript\nimport { FieldRenderProps } from 'react-final-form';\n\nconst meta: FieldRenderProps<any>['meta'] = { /* ... */ };\n\n// Or define it locally:\ntype FieldMetaState = {\n  active?: boolean;\n  data?: Record<string, any>;\n  dirty?: boolean;\n  // ... etc\n};\n```\n\n### 3. AnyObject Type No Longer Exported\n\n**❌ Before (v6.x):**\n\n```typescript\nimport { AnyObject } from 'react-final-form';\n```\n\n**✅ After (v7.0.0):**\n\n```typescript\n// Define locally:\ntype AnyObject = Record<string, any>;\n```\n\n### 4. UseFieldConfig No Longer Generic\n\n**❌ Before (v6.x):**\n\n```typescript\nconst config: UseFieldConfig<string> = {\n  validate: (value) => value ? undefined : 'Required'\n};\n```\n\n**✅ After (v7.0.0):**\n\n```typescript\nconst config: UseFieldConfig = {\n  validate: (value) => value ? undefined : 'Required'\n};\n```\n\n### 5. FormProps No Longer Accepts Arbitrary Props\n\nIn 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.\n\n**❌ Before (v6.x):**\n\n```tsx\n<Form\n  onSubmit={handleSubmit}\n  style={{ padding: '20px' }}\n  className=\"my-form\"\n>\n  {/* ... */}\n</Form>\n```\n\n**✅ After (v7.0.0):**\n\n```tsx\n<Form onSubmit={handleSubmit}>\n  {({ handleSubmit }) => (\n    <form onSubmit={handleSubmit} style={{ padding: '20px' }} className=\"my-form\">\n      {/* ... */}\n    </form>\n  )}\n</Form>\n\n// Or wrap in a div:\n<div style={{ padding: '20px' }} className=\"my-form\">\n  <Form onSubmit={handleSubmit}>\n    {/* ... */}\n  </Form>\n</div>\n```\n\n## final-form v5.0.0 Changes\n\nIf you're also upgrading final-form to v5.0.0, be aware of these changes:\n\n### 1. InternalFormState Requires asyncErrors\n\n**❌ Before (v4.x):**\n\n```typescript\nconst mockFormState: InternalFormState = {\n  values: {},\n  // ...\n};\n```\n\n**✅ After (v5.0.0):**\n\n```typescript\nconst mockFormState: InternalFormState = {\n  values: {},\n  asyncErrors: {}, // Now required\n  // ...\n};\n```\n\n### 2. Mutator Type Signature Changed\n\n**❌ Before (v4.x):**\n\n```typescript\nconst mutator: Mutator = (args, state, tools) => {\n  // ...\n};\n```\n\n**✅ After (v5.0.0):**\n\n```typescript\n// If you get type errors with existing mutators:\nconst mutator = ((args, state, tools) => {\n  // ...\n}) as unknown as Mutator;\n```\n\n## Migration Strategy\n\nFor a medium to large codebase, expect to modify 100+ files. Here's a recommended approach:\n\n1. **Update dependencies:**\n\n   ```bash\n   npm install react-final-form@^7.0.0 final-form@^5.0.0\n   ```\n\n2. **Fix compilation errors in this order:**\n   - Handle optional boolean properties (use `?? false` or `?? true`)\n   - Replace `FieldMetaState` imports with `FieldRenderProps['meta']`\n   - Replace `AnyObject` imports with local type definition\n   - Remove generic from `UseFieldConfig<T>` → `UseFieldConfig`\n   - Fix `<Form>` props (move styling to wrapper or inner `<form>`)\n\n3. **Test thoroughly:**\n   - All form submissions\n   - Validation behavior\n   - Field state management\n   - Meta information display\n\n4. **Update mocks/tests:**\n   - Add `asyncErrors: {}` to InternalFormState mocks\n   - Cast mutators if needed\n\n## Need Help?\n\nIf you encounter issues during migration:\n\n1. Check the [TypeScript examples](https://github.com/final-form/react-final-form/tree/main/examples/typescript)\n2. Review [closed issues](https://github.com/final-form/react-final-form/issues?q=is%3Aissue+typescript)\n3. Open a [new issue](https://github.com/final-form/react-final-form/issues/new) with a reproduction\n\n## Benefits of v7.0.0\n\nDespite the migration effort, v7.0.0 brings significant benefits:\n\n- **Better TypeScript support** - First-class TypeScript instead of generated types from Flow\n- **Improved type inference** - Better autocomplete and type checking\n- **Modern codebase** - Easier for contributors to work with\n- **Long-term maintainability** - TypeScript ecosystem is more active than Flow\n\n---\n\n**Version**: 7.0.0  \n**Last Updated**: 2026-02-13\n"
  },
  {
    "path": "README.md",
    "content": "# 🏁 React Final Form\n\n[![React Final Form](banner.png)](https://final-form.org/react)\n\n[![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)\n[![NPM Downloads](https://img.shields.io/npm/dm/react-final-form.svg?style=flat)](https://www.npmjs.com/package/react-final-form)\n[![Build Status](https://travis-ci.org/final-form/react-final-form.svg?branch=master)](https://travis-ci.org/final-form/react-final-form)\n[![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)\n[![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)\n\n✅ Zero dependencies (that affect your bundle size)\n\n✅ Only peer dependencies: React and\n[🏁 Final Form](https://github.com/final-form/final-form#-final-form)\n\n✅ Opt-in subscriptions - only update on the state you need!\n\n✅ 💥 [**3.0k gzipped**](https://bundlephobia.com/result?p=react-final-form) 💥\n\n---\n\n[<img align=\"right\" src=\"docs/sencha.svg\" height=\"100\"/>](https://www.sencha.com/)\n\n### React Final Form is sponsored by [Sencha](https://www.sencha.com/).\n\nComprehensive JS framework and UI components for building enterprise-grade web apps.\n\n---\n\n## 💬 [Give Feedback on React Final Form](https://goo.gl/forms/dxdfxKNy64DLb99z2) 💬\n\nIn the interest of making 🏁 React Final Form the best library it can be, we'd love your thoughts and feedback.\n\n[Take a quick survey](https://goo.gl/forms/dxdfxKNy64DLb99z2).\n\n---\n\nReact 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.\n\n## [Getting Started](https://final-form.org/docs/react-final-form/getting-started)\n\n## 🔄 Upgrading from v6 to v7?\n\nSee the [Migration Guide](./MIGRATION_V7.md) for TypeScript-specific breaking changes and how to handle them.\n\n## [Philosophy](https://final-form.org/docs/react-final-form/philosophy)\n\n## [Examples](https://final-form.org/docs/react-final-form/examples)\n\n## [API](https://final-form.org/docs/react-final-form/api)\n\n## [FAQ](https://final-form.org/docs/react-final-form/faq)\n\n<img src=\"https://static.scarf.sh/a.png?x-pxid=8feec529-43ac-4b78-8ad9-17c280b4f2d9\" />\n"
  },
  {
    "path": "docs/api/Field.md",
    "content": "# 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.\n\n# `<Field/>`\n\n```ts\nimport { Field } from 'react-final-form'\n```\n\nA 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.\n\nThe `<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.\n\n## Props\n\n`<Field/>` accepts [`FieldProps`](../types/FieldProps) and will call the render function with [`FieldRenderProps`](../types/FieldRenderProps).\n\nThe 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).\n\n## Basic Usage\n\nYou need to do three things when using `<Field/>`:\n\n### 1. Provide a `name` prop\n\nThe 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'`.\n\n### 2. Provide a way to render the field\n\nThere are four ways to render a `<Field/>` component:\n\n| Prop                 | Type                               |\n| -------------------- | ---------------------------------- |\n| `<Field component/>` | `'input' or 'select' or 'textarea'` |\n| `<Field component/>` | `React.ComponentType`              |\n| `<Field render/>`    | `Function`                         |\n| `<Field children/>`  | `Function`                         |\n\nThe 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-).\n\n### 3. Connect the callbacks to your input\n\nIf you are using `component=\"input\"` (or `select` or `textarea`), `<Field/>` will do this step for you.\n\n```tsx\n<Field name=\"myField\" component=\"input\" />\n```\n\nBut if you are using a custom component or a render prop, you will need to do this yourself.\n\n`<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).\n\n#### HTML Inputs\n\nIf 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.\n\n```tsx\n<Field name=\"myField\">\n  {props => (\n    <div>\n      <input {...props.input} />\n    </div>\n  )}\n</Field>\n```\n\n#### Custom Inputs\n\nThe 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.\n\n```tsx\nimport TextField from '@material-ui/core/TextField'\n\n...\n\n<Field name=\"myField\">\n  {props => (\n    <div>\n      <TextField\n        name={props.input.name}\n        value={props.input.value}\n        onChange={props.input.onChange}\n      />\n    </div>\n  )}\n</Field>\n```\n\n\nNote: 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\"\n\nNow, [let's look at some examples](../examples)!\n"
  },
  {
    "path": "docs/api/Form.md",
    "content": "# 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.\n\n# `<Form/>`\n\n```ts\nimport { Form } from 'react-final-form'\n```\n\nA 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.\n\nOn 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.\n\nThe `<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.\n\n## Props\n\n`<Form/>` accepts [`FormProps`](../types/FormProps) and will call the render function with [`FormRenderProps`](../types/FormRenderProps).\n\nThe 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).\n\n## Basic Usage\n\nYou need to do three things when using `<Form/>`:\n\n### 1. Provide an `onSubmit` prop\n\n`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.\n\n### 2. Provide a way to render the form\n\nThere are three ways to render a `<Form/>` component:\n\n| Prop                | Type                  |\n| ------------------- | --------------------- |\n| `<Form component/>` | `React.ComponentType` |\n| `<Form render/>`    | `Function`            |\n| `<Form children/>`  | `Function`            |\n\nThe 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-).\n\nWhile 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.\n\n### 3. Do something with `handleSubmit`\n\nThe 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.\n\nIn practice, your form will always look something like this:\n\n<!-- prettier-ignore -->\n```jsx\n<Form onSubmit={onSubmit}>\n  {props => (\n    <form onSubmit={props.handleSubmit}>\n\n      ... fields go here...\n\n      <button type=\"submit\">Submit</button>\n    </form>\n  )}\n</Form>\n```\n\nNow, [let's look at adding some `<Field/>`](Field) components!\n"
  },
  {
    "path": "docs/api/FormSpy.md",
    "content": "# 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.\n\n# `<FormSpy/>`\n\n```ts\nimport { FormSpy } from 'react-final-form'\n```\n\nA component that subscribes to form state, and injects both form state and the `form` instance via a render prop.\n\nThe `<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.\n\nBy providing an `onChange` prop, `<FormSpy/>` can also be used to execute code when a particular part of form state changes.\n\n## Props\n\n`<FormSpy/>` accepts [`FormSpyProps`](../types/FormSpyProps) and will call the render function with [`FormSpyRenderProps`](../types/FormSpyRenderProps).\n\nThe only required prop is one of `onChange`, `component`, `render`, or `children`.\n\n## Basic Usage\n\nIt should be noted that `<FormSpy/>` is for very advanced use cases.\n\n**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/>`.\n\nYou need to do _one_ of two things when using `<FormSpy/>`:\n\n### 1. Provide a way to render the form state\n\nThere are three ways to render a `<FormSpy/>` component:\n\n| Prop                   | Type                  |\n| ---------------------- | --------------------- |\n| `<FormSpy component/>` | `React.ComponentType` |\n| `<FormSpy render/>`    | `Function`            |\n| `<FormSpy children/>`  | `Function`            |\n\nThe 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-).\n\n```tsx\n// Render a reset button that will be\n// disabled when the form is pristine\n<FormSpy subscription={{ pristine: true }}>\n  {props => (\n    <button\n      type=\"button\"\n      disabled={props.pristine}\n      onClick={() => props.form.reset()}\n    >\n      Reset\n    </button>\n  )}\n</FormSpy>\n```\n\n### 2. Pass an `onChange` callback\n\n`<FormSpy/>` can sometimes be useful to execute code when a particular part of form state changes. This is what the `onChange` callback is for.\n\n**If you pass `onChange`, nothing will be rendered.**\n\n```tsx\n<FormSpy\n  subscription={{ valid: true }}\n  onChange={props => {\n    console.log('Form validity changed to', props.valid)\n  }}\n/>\n```\n"
  },
  {
    "path": "docs/api/useField.md",
    "content": "# 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.\n\n# `useField()`\n\n```ts\nimport { useField } from 'react-final-form'\n```\n\n<!-- prettier-ignore -->\n```ts\n(name: string, config: UseFieldConfig) => FieldRenderProps\n```\n\nThe `useField()` hook takes two parameters:\n\n### `name`\n\n```ts\nstring\n```\n\n**Required**\n\nThe name of the field.\n\n### `config`\n\n```ts\nUseFieldConfig\n```\n\nOptional.\n\nAn object that looks just like [`FieldProps`](../types/FieldProps), except without the name.\n\n`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.\n\n`useField()` is used internally inside [`<Field/>`](Field).\n"
  },
  {
    "path": "docs/api/useForm.md",
    "content": "# 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.\n\n# `useForm()`\n\n```ts\nimport { useForm } from 'react-final-form'\n```\n\n<!-- prettier-ignore -->\n```ts\n() => FormApi\n```\n\nThe `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.\n\n`useForm()` is used internally inside [`useField()`](useField), [`<Field/>`](Field), and [`<FormSpy/>`](FormSpy).\n"
  },
  {
    "path": "docs/api/useFormState.md",
    "content": "# 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.\n\n# `useFormState`\n\n```ts\nimport { useFormState } from 'react-final-form'\n```\n\nThe `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).\n\n`useFormState()` is used internally inside [`<FormSpy/>`](FormSpy).\n"
  },
  {
    "path": "docs/api.md",
    "content": "# 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.\n\n# API\n\nThe API for React Final Form consists of three components and three hooks:\n\n## Components\n\n### [`<Form/>`](api/Form)\n\nA 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.\n\n### [`<Field/>`](api/Field)\n\nA 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.\n\n### [`<FormSpy/>`](api/FormSpy)\n\n_[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.\n\n## Hooks\n\n### [`useField()`](api/useField)\n\nA 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/>`.\n\n### [`useForm()`](api/useForm)\n\nA hook that will pluck the Final Form [`form` instance](/docs/final-form/types/FormApi) out of context.\n\n### [`useFormState()`](api/useFormState)\n\nA hook that will convert any of your components into a `<FormSpy/>` component, allowing fine-grained control over subscribing to parts of the form state.\n"
  },
  {
    "path": "docs/examples/chakra.md",
    "content": "# 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.\n\n# Chakra UI Example\n\nDemonstrates how to use [Chakra UI](https://chakra-ui.com) components with React Final Form.\n\n[![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)\n"
  },
  {
    "path": "docs/examples/field-level-validation.md",
    "content": "# 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.\n\n# Field Level Validation Example\n\nIntroduces field-level validation functions and demonstrates how to display errors next to fields using child render functions.\n\n[![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)\n"
  },
  {
    "path": "docs/examples/record-level-validation.md",
    "content": "# 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.\n\n# Record-Level Example\n\nIntroduces a whole-record validation function and demonstrates how to display errors next to fields using child render functions.\n\n[![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)\n"
  },
  {
    "path": "docs/examples/simple.md",
    "content": "# 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.\n\n# Simple Example\n\nUses the built-in React inputs: input, select, and textarea to build a form with no validation.\n\n[![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)\n"
  },
  {
    "path": "docs/examples/submission-errors.md",
    "content": "# 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.\n\n# Submission Errors\n\nDemonstrates 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.\n\n[![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)\n"
  },
  {
    "path": "docs/examples/subscriptions.md",
    "content": "# 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.\n\n# High Performance Through Subscriptions Example\n\nDemonstrates 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.\n\n[![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)\n"
  },
  {
    "path": "docs/examples/wizard.md",
    "content": "# 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.\n\n# Wizard Form Example\n\nDemonstrates how to use React Final Form to create a multi-page \"wizard\" form, with validation on each page.\n\n[![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)\n"
  },
  {
    "path": "docs/examples.md",
    "content": "# 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.\n\n# Examples\n\n---\n\nWanna 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. 🙏\n\n---\n\n### [Simple Example](examples/simple)\n\nUses the built-in React inputs: `input`, `select`, and `textarea` to build a form with no validation.\n\n### [Synchronous Record-Level Validation](examples/record-level-validation)\n\nIntroduces a whole-record validation function and demonstrates how to display errors next to fields using child render functions.\n\n### [Synchronous Field-Level Validation](examples/field-level-validation)\n\nIntroduces field-level validation functions and demonstrates how to display errors next to fields using child render functions.\n\n### [Synchronous Record-Level Validation (with delayed error render)](https://codesandbox.io/s/z2zqr008pm)\n\nSometimes 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.\n\n### [Asynchronous Field-Level Validation](https://codesandbox.io/s/wy7z7q5zx5)\n\nDemonstrates how field-level validation rules may be asynchronous (return a\n`Promise`), as well as how to show a \"validating\" spinner during the lifetime of\nthe `Promise`.\n\n### [Hybrid Synchronous/Asynchronous Record-Level Validation](https://codesandbox.io/s/kl9n295n5)\n\nDemonstrates how you can mix synchronous and asynchronous validation patterns at\nthe record-level, by returning errors synchronously, and falling back to an\nasynchronous call (by returning a `Promise`) if sync validation is passing.\n\n### [Submission Errors](examples/submission-errors)\n\nDemonstrates 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.\n\n### [Third Party Components](https://codesandbox.io/s/40mr0v2r87)\n\nDemonstrates how easy it is to use third party input components. All the third\nparty component really needs is `value` and `onChange`, but more complex\ncomponents can accept things like errors.\n\n### Material-UI\n\n- [Wrapper components](https://github.com/lookfirst/mui-rff) / [Codesandbox demo](https://codesandbox.io/s/react-final-form-material-ui-example-tqv09)\n\n### 💥 [Performance Optimization Through Subscriptions](examples/subscriptions) 💥\n\nDemonstrates 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.\n\n### [Strongly Typed Form and Field Values with TypeScript](https://codesandbox.io/s/strongly-typed-form-values-with-react-final-form-26jkd)\n\nDemonstrates how to use JSX generics to strongly type fields, forcing only a component that can accept the type for that field.\n\n### [Independent Error Component (with Render Props)](https://codesandbox.io/s/xoo3xq654p)\n\nDemonstrates how to make an independent Error component to subscribe to and\ndisplay the error for any form field.\n\n### [Independent Error Component (with Hooks)](https://codesandbox.io/s/react-final-form-independent-error-component-with-hooks-y1grn)\n\nDemonstrates how to make an independent Error component, using Hooks, to subscribe to and\ndisplay the error for any form field.\n\n### [Loading and Initializing Values](https://codesandbox.io/s/91w9ro3x9o)\n\nDemonstrates how a form can be initialized, after fetching data, by passing in\n`initialValues` as a prop.\n\n### [Field Arrays](https://codesandbox.io/s/kx8qv67nk5)\n\nDemostrates how to use the `<FieldArray/>` component, from\n[`react-final-form-arrays`](https://github.com/final-form/react-final-form-arrays),\nto render an array of inputs, as well as use `push`, `pop`, and `remove`\nmutations.\n\n### [Fields Component](https://codesandbox.io/s/pyrwplknom)\n\nWondering how to get field state from multiple fields at once?\n\nPeople 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.\n\n### [Calculated Fields](https://codesandbox.io/s/oq52p6v96y)\n\nDemonstrates how to use the\n[`final-form-calculate`](https://github.com/final-form/final-form-calculate)\ndecorator to achieve realtime field calculations through easily defined rules.\n\n### [Field Warnings](https://codesandbox.io/s/m5qwxpr6o8)\n\nDemonstrates how the power of subscriptions and mutators can be used to build a\nwarning engine: logic to display a message next to each field that is _not_ an\nerror (thus it does _not_ prevent form submission).\n\n### [Reusable Field Groups](https://codesandbox.io/s/8z5jm6x80)\n\nDemonstrates how fields can be grouped into reusable components.\n\n### [Prefixed Fields](https://codesandbox.io/s/react-final-form-prefixed-fields-seiy8)\n\nDemonstrates how the React context API can be used to provide a \"prefix wrapper\"\naround fields to add structure to your form date. It's similar to how Redux Form's\n[`FormSection`](https://redux-form.com/8.2.2/docs/api/formsection.md/) component works.\nBetween this and the [Reusable Field Groups](#reusable-field-groups) example, your\nuse case, if migrating from `FormSection` should be handled.\n\n### [External Submit](https://codesandbox.io/s/1y7noyrlmq)\n\nDemonstrates how you can use `document.getElementById()` or a closure to trigger\na submit from outside of the form. For more information, see\n[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)\n\n### [Wizard Form](examples/wizard)\n\nDemonstrates how to use React Final Form to create a multi-page \"wizard\" form, with validation on each page.\n\n### [Parse and Format (and Normalize)](https://codesandbox.io/s/10rzowm323)\n\nDemonstrates 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.\n\n### [Auto-Save with Debounce](https://codesandbox.io/s/5w4yrpyo7k)\n\nDemonstrates how to use a `FormSpy` component to listen for value changes and automatically submit different values after a debounce period.\n\n### [Auto-Save with Selective Debounce](https://codesandbox.io/s/98j0v46zj4)\n\nDemonstrates 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.\n\n### [Auto-Save on Field Blur](https://codesandbox.io/s/7k742qpo36)\n\nDemonstrates how to use a `FormSpy` component to listen for values and active field changes to automatically submit values when fields are blurred.\n\n### [Custom Validation Engine](https://codesandbox.io/s/kxxw4l0p9o)\n\nDemonstrates 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.\n\n### [Loading, Normalizing, Saving, and Reinitializing](https://codesandbox.io/s/xr0mvl1904)\n\nDemonstrates 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.\n\n### [🏎️ Downshift Type-Ahead](https://codesandbox.io/s/qzm43nn2mj)\n\nDemonstrates how to use a [🏎️ Downshift](https://github.com/paypal/downshift) type-ahead component as an input.\n\n### [Redux Example](https://codesandbox.io/s/4xq2qpzw79)\n\nThe 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).\n\n### [Conditional Fields](https://codesandbox.io/s/lm4p3m92q)\n\nSometimes 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.\n\n### [Listening for External Changes](https://codesandbox.io/s/3x989zl866)\n\nBy 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.\n\n### [Focus On First Error](https://codesandbox.io/s/6174kqr403)\n\nDemonstrates how to incorporate the [🏁 Final Form Focus 🧐](https://github.com/final-form/final-form-focus) decorator to provide this functionality out of the box.\n\n### [Credit Card Example](https://codesandbox.io/s/9y8vkrrx9o)\n\nDemonstrates how to make an awesome credit card UX using [React Credit Cards](https://github.com/amarofashion/react-credit-cards).\n\n### [Async Redux Submission](https://codesandbox.io/s/x71mx66z8w)\n\nWant 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.\n\n### [Declarative Form Rules](https://codesandbox.io/s/52q597j2p)\n\nWhat 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).\n\n### [Format String By Pattern](https://codesandbox.io/s/no20p7z3l)\n\nDemonstrates how to use the library `format-string-by-pattern` to create input masks for your 🏁 React Final Form fields.\n\n### [AsyncTypeahead and Redux](https://codesandbox.io/s/5m4w2909k)\n\nDemonstrates 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).\n\n### [Format On Blur](https://codesandbox.io/s/3rp260ly51)\n\nDemonstrates 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.\n\n### [Styling with 🍭 Smooth-UI](https://codesandbox.io/s/40o45po3l4)\n\nDemonstrates 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.\n\n### [Styling with Chakra-UI](examples/chakra)\n\nDemonstrates how to use the [Chakra UI](https://chakra-ui.com) styling library to make your forms look fabulous!\n\n### [CLI Example](https://github.com/final-form/rff-cli-example) 🤯\n\nYes! 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.\n"
  },
  {
    "path": "docs/faq.md",
    "content": "# 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.\n\n# FAQ\n\nBelow are some frequently asked questions.\n\n## Why not Redux-Form or Formik?\n\nThose 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).\n\nRedux-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.\n\n## Why no HOC?\n\nThe 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:\n\n```jsx\nimport { Form, Field } from 'react-final-form'\n\nclass MyForm extends React.Component {\n  componentDidMount() {\n    const { initialize } = this.props // access to injected props\n    ajax.fetch('/myData').then(data => initialize(data))\n  }\n\n  render() {\n    return <form onSubmit={this.props.handleSubmit}>...some fields...</form>\n  }\n}\n\n// 👇 THIS LINE IS THE HOC 👇\nexport default props => <Form {...props} component={MyForm} />\n```\n\nDoing a HOC\n[properly](https://github.com/ReactTraining/react-router/blob/master/packages/react-router/modules/withRouter.js),\nas a library should, with hoisted statics and `displayName` and `ref`, etc., is\na hassle and would add unnecessary bulk.\n\n## How can I trigger a submit from outside my form?\n\nThis is a common question I see from people migrating from `redux-form`. There\nare three possible solutions:\n\n### Via the `form` attribute\n\nYou can provide the form id to a submit button.\n\n\n```jsx\n<button type=\"submit\" form=\"myForm\">Submit</button>\n{/*                   ^^^^^^^^^^^^^ */}\n\n<form id=\"myForm\" onSubmit={handleSubmit}>\n{/*   ^^^^^^^^^^^ */}\n  ...fields go here...\n</form>\n```\n\n### Via `document.getElementById()`\n\nYou can use the DOM to get a reference to your `<form>` element and dispatch a\nsubmit event on it. Note that you cannot just call `submit()`, as this will not\ntrigger React's event handlers.\n\n```jsx\n<button onClick={() => {\n  document.getElementById('myForm').submit() // ❌\n}}>Submit</button>\n\n<button onClick={() => {\n  document.getElementById('myForm')\n  .dispatchEvent(new Event('submit', { cancelable: true, bubbles:true })) // ✅\n}}>Submit</button>\n\n<form id=\"myForm\" onSubmit={handleSubmit}>\n  ...fields go here...\n</form>\n```\n\nSee [Sandbox Example](https://codesandbox.io/s/1y7noyrlmq).\n\n### Via Closure\n\nIf you define a variable outside of your form, you can then set the value of\nthat variable to the `handleSubmit` function that 🏁 React Final Form gives you,\nand then you can call that function from outside of the form.\n\n```jsx\nlet submit\nreturn (\n  <div>\n    <button onClick={submit}>Submit</button> // ❌ Not overwritten closure value\n    <button onClick={event => submit(event)}>Submit</button> // ✅\n    <Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit }) => {\n        submit = handleSubmit\n        return <form>...fields go here...</form>\n      }}\n    />\n  </div>\n)\n```\n\nSee [Sandbox Example](https://codesandbox.io/s/1y7noyrlmq).\n\n### Via Redux Dead Drop\n\nIf you're already using Redux, you could potentially use the same mechanism that\n`redux-form` uses:\n[Redux Dead Drop](https://medium.com/@erikras/redux-dead-drop-1b9573705bec).\n\n## Why can't I have numeric keys in an object?\n\nSo 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.\n\nYou 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.\n\n```jsx\nconst stringifyKeys = values =>\n  Object.keys(values).reduce((result, key) => {\n    result[`key${key}`] = values[key]\n    return result\n  }, {})\n\nconst destringifyKeys = values =>\n  Object.keys(values).reduce((result, key) => {\n    result[Number(key.substring(3))] = values[key]\n    return result\n  }, {})\n\n<Form\n  onSubmit={values => onSubmit(destringifyKeys(values))}\n  initialValues={stringifyKeys(initialValues)}>\n  ...\n</Form>\n```\n\n## I'm changing form state on first render, e.g. with FormSpy, why are my changes not reflected?\n\nAs 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.\n"
  },
  {
    "path": "docs/getting-started.md",
    "content": "# 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.\n\n# Getting Started\n\nBefore we jump right into code, you might want to learn a little bit about the [philosophy](philosophy) and origin story of React Final Form.\n\n## Installation\n\n```bash\nnpm install --save final-form react-final-form\n```\n\nor\n\n```bash\nyarn add final-form react-final-form\n```\n\n## Architecture\n\nReact 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.\n\nBy 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.\n\n## Code\n\nHere's what it looks like in your code:\n\n```jsx\nimport { Form, Field } from 'react-final-form'\n\nconst MyForm = () => (\n  <Form\n    onSubmit={onSubmit}\n    validate={validate}\n    render={({ handleSubmit }) => (\n      <form onSubmit={handleSubmit}>\n        <h2>Simple Default Input</h2>\n        <div>\n          <label>First Name</label>\n          <Field name=\"firstName\" component=\"input\" placeholder=\"First Name\" />\n        </div>\n\n        <h2>An Arbitrary Reusable Input Component</h2>\n        <div>\n          <label>Interests</label>\n          <Field name=\"interests\" component={InterestPicker} />\n        </div>\n\n        <h2>Render Function</h2>\n        <Field\n          name=\"bio\"\n          render={({ input, meta }) => (\n            <div>\n              <label>Bio</label>\n              <textarea {...input} />\n              {meta.touched && meta.error && <span>{meta.error}</span>}\n            </div>\n          )}\n        />\n\n        <h2>Render Function as Children</h2>\n        <Field name=\"phone\">\n          {({ input, meta }) => (\n            <div>\n              <label>Phone</label>\n              <input type=\"text\" {...input} placeholder=\"Phone\" />\n              {meta.touched && meta.error && <span>{meta.error}</span>}\n            </div>\n          )}\n        </Field>\n\n        <button type=\"submit\">Submit</button>\n      </form>\n    )}\n  />\n)\n```\n\n[Let's explore the API...](api)\n"
  },
  {
    "path": "docs/migration/formik.md",
    "content": "# 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.\n\n# Migration from Formik\n\nGood 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.\n\n## Props passed to `<Formik/>`\n\nThe following props passed to `<Formik/>` are more or less identical to those you can pass to [`<Form/>`](../api/Form):\n\n- [`onSubmit`](../types/FormProps#onsubmit)\n- [`initialValues`](../types/FormProps#initialvalues)\n- [`validate`](../types/FormProps#validate)\n\nThe render props work the same way, except for [what is passed](#props-passed-by-formik).\n\n- [`children`](../types/FormProps#children)\n- [`component`](../types/FormProps#component)\n- [`render`](../types/FormProps#render)\n\nThe only tricky one is:\n\n- [`validateOnBlur`](../types/FormProps#validateonblur)\n\nIt'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).\n\n## Props passed by `<Formik/>`\n\nThe following props passed into the render functions by `<Formik/>` are identical:\n\n- [`dirty`](/docs/final-form/types/FormState#dirty)\n- [`errors`](/docs/final-form/types/FormState#errors)\n- [`touched`](/docs/final-form/types/FormState#touched)\n- [`handleSubmit`](/docs/final-form/types/FormRenderProps#handlesubmit)\n\nTo migrate from Formik, you'd have to search and replace the following:\n\n| Formik              | React Final Form                                            |\n| ------------------- | ----------------------------------------------------------- |\n| `isSubmitting`      | [`submitting`](/docs/final-form/types/FormState#submitting) |\n| `isValid`           | [`valid`](/docs/final-form/types/FormState#valid)           |\n| `isValidating`      | [`validating`](/docs/final-form/types/FormState#validating) |\n| `resetForm()`       | [`form.reset()`](/docs/final-form/types/FormApi#reset)      |\n| `submitForm()`      | [`form.submit()`](/docs/final-form/types/FormApi#submit)    |\n| `setFieldTouched()` | [`form.blur()`](/docs/final-form/types/FormApi#blur)        |\n| `setFieldValue()`   | [`form.change()`](/docs/final-form/types/FormApi#change)    |\n\n## Props passed to `<Field/>`\n\nThe APIs of the [`<Field/>`](../api/Field) components are very similiar. They both have:\n\n- [`name`](../types/FieldProps#name)\n- [`children`](../types/FieldProps#children)\n- [`component`](../types/FieldProps#component)\n- [`render`](../types/FieldProps#render)\n- [`validate`](../types/FieldProps#validate)\n\nOne 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.\n\n## Props passed by `<Field/>`\n\nThe 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:\n\nFormik:\n\n```jsx\n<Field\n  name=\"lastName\"\n  render={({ field }) => <input {...field} placeholder=\"Last Name\" />}\n/>\n```\n\nReact Final Form:\n\n```jsx\n<Field\n  name=\"lastName\"\n  render={({ input }) => <input {...input} placeholder=\"Last Name\" />}\n  //         ^^^^^                  ^^^^^\n/>\n```\n\nThe 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).\n\n## Formik's `<Form/>`\n\nReact 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.\n\n```jsx\nimport { useForm } from 'react-final-form'\n\nconst FormLikeFormik = props => {\n  const form = useForm()\n  return (\n    <form\n      {...props}\n      onSubmit={event => {\n        event.preventDefault()\n        form.submit()\n      }}\n    />\n  )\n}\n```\n\n## Formik's `<ErrorMessage/>`\n\nThis component _does_ seem useful, and writing your own is a great introduction to React Final Form's subscription system.\n\n### With `<Field/>`\n\n```jsx\nimport { Field } from 'react-final-form'\n\nconst ErrorMessage = ({ name }) => (\n  <Field name={name} subscription={{ error: true, touched: true }}>\n    {({ meta: { error, touched } }) =>\n      error && touched ? <span>{error}</span> : null\n    }\n  </Field>\n)\n```\n\n...or, if you want to look cool...\n\n### With Hooks\n\n```jsx\nimport { useField } from 'react-final-form'\n\nconst ErrorMessage = ({ name }) => {\n  const {\n    meta: { error, touched }\n  } = useField(name, { subscription: { error: true, touched: true } })\n  return error && touched ? <span>{error}</span> : null\n}\n```\n\n## Formik's `<FastField/>`\n\nReact 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.\n\n## Formik's `connect()`\n\nReact 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.\n\n## A Diff\n\nThis 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.\n\n```diff\n import React from 'react'\n-import { Formik, Form, Field, ErrorMessage } from 'formik'\n+import { Form, Field, useField } from 'react-final-form'\n\n+// Obviously this could be reused across your project\n+const ErrorMessage = ({ name, component }) => {\n+  const {\n+    meta: { error, touched }\n+  } = useField(name, { subscription: { error: true, touched: true } })\n+  return error && touched\n+    ? React.createElement(component, null, error)\n+    : null\n+}\n\n const Basic = () => (\n   <div>\n     <h1>Any place in your app!</h1>\n-    <Formik\n+    <Form\n       initialValues={{ email: '', password: '' }}\n       validate={values => {\n         let errors = {}\n         if (!values.email) {\n           errors.email = 'Required'\n         } else if (\n           !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$/i.test(values.email)\n         ) {\n           errors.email = 'Invalid email address'\n         }\n         return errors\n       }}\n-      onSubmit={(values, { setSubmitting }) => {\n+      onSubmit={(values) => {\n+        // final-form manages submitting status\n+        // for you *if* you return a promise\n+        return new Promise(resolve =>\n         setTimeout(() => {\n           alert(JSON.stringify(values, null, 2))\n-          setSubmitting(false)\n+          resolve()\n         }, 400)\n+        )\n       }}\n     >\n-      {({ isSubmitting }) => (\n-        <Form>\n+      {({ handleSubmit, submitting }) => (\n+        <form onSubmit={handleSubmit}>\n-          <Field type=\"email\" name=\"email\" />\n+          <Field type=\"email\" name=\"email\" component=\"input\"/>\n           <ErrorMessage name=\"email\" component=\"div\" />\n-          <Field type=\"password\" name=\"password\" />\n+          <Field type=\"password\" name=\"password\" component=\"input\"/>\n           <ErrorMessage name=\"password\" component=\"div\" />\n-          <button type=\"submit\" disabled={isSubmitting}>\n+          <button type=\"submit\" disabled={submitting}>\n             Submit\n           </button>\n-        </Form>\n+        </form>\n       )}\n-    </Formik>\n+    </Form>\n   </div>\n )\n\n export default Basic\n```\n"
  },
  {
    "path": "docs/migration/redux-form.md",
    "content": "# 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.\n\n# Migration from Redux Form\n\nGood 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.\n\n### Step 1: Change your imports\n\n```diff\n import React from 'react'\n-import { reduxForm, Field } from 'redux-form'\n+import { Form, Field } from 'react-final-form'\n```\n\n### Step 2: Surround your `<form/>` with a `<Form/>`\n\n```diff\n import React from 'react'\n import { Form, Field } from 'react-final-form'\n\n const MyForm = props => {\n   const { handleSubmit, pristine, reset, submitting } = props\n   return (\n+    <Form>\n+      {() => (\n         <form onSubmit={handleSubmit}>\n\n           ...fields here...\n\n         </form>\n+      )}\n+    </Form>\n   )\n }\n```\n\n### Step 3: Move all your `config` values from `reduxForm()` to be props of `<Form/>`\n\n```diff\n import React from 'react'\n import { Form, Field } from 'react-final-form'\n\n const MyForm = props => {\n   const { handleSubmit, pristine, reset, submitting } = props\n   return (\n     <Form\n+      initialValues={{\n+        firstName: 'Dan'\n+      }}\n+      onSubmit={values => {\n+        // send values to the cloud\n+      }}\n+      validate={values => {\n+        // do validation here, and return errors object\n+      }}\n     >\n      {() => (\n        <form onSubmit={handleSubmit}>\n\n          ...fields here...\n\n        </form>\n       )}\n     </Form>\n   )\n }\n\n export default reduxForm({\n   form: 'myForm',\n-   initialValues: {\n-     firstName: 'Dan'\n-   },\n-   onSubmit: values => {\n-     // send values to the cloud\n-   },\n-   validate: values => {\n-     // do validation here, and return errors object\n-   }\n })(MyForm)\n```\n\n### Step 4: Get form state from `<Form/>`, not as props\n\n```diff\n import React from 'react'\n import { Form, Field } from 'react-final-form'\n\n const MyForm = props => {\n-  const { handleSubmit, pristine, reset, submitting } = props\n   return (\n     <Form\n       initialValues={{\n         firstName: 'Dan'\n       }}\n       onSubmit={values => {\n         // send values to the cloud\n       }}\n       validate={values => {\n         // do validation here, and return errors object\n       }}\n     >\n+      {({ handleSubmit, pristine, reset, submitting }) => (\n         <form onSubmit={handleSubmit}>\n\n           ...fields here...\n\n         </form>\n       )}\n     </Form>\n   )\n }\n\n export default reduxForm({\n   form: 'myForm'\n })(MyForm)\n```\n\n### Step 5: Observe API changes\n\n_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.\n\n```diff\n import React from 'react'\n import { Form, Field } from 'react-final-form'\n\n const MyForm = props => {\n   return (\n     <Form\n      initialValues={{\n        firstName: 'Dan'\n      }}\n      onSubmit={values => {\n        // send values to the cloud\n      }}\n      validate={values => {\n        // do validation here, and return errors object\n      }}\n     >\n-     {({ handleSubmit, pristine, reset, submitting }) => (\n+     {({ handleSubmit, pristine, form, submitting }) => (\n        <form onSubmit={handleSubmit}>\n\n          ...fields here...\n\n          <div>\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              disabled={pristine || submitting}\n-             onClick={reset}\n+             onClick={form.reset}\n            >\n              Clear Values\n            </button>\n          </div>\n        </form>\n       )}\n     </Form>\n   )\n }\n\n export default reduxForm({\n   form: 'myForm'\n })(MyForm)\n```\n\n### Step 6: Remove the HOC\n\nNow you can just export your component. No HOC decorator needed! [Why?](../faq#why-no-hoc)\n\n```diff\n-export default reduxForm({\n-  form: 'myForm'\n-})(MyForm)\n+export default MyForm\n```\n\n### Step 7: Error management\n\nNo more `SubmissionError` to throw, error management is made with the return value.\nHave a look here to know more: https://final-form.org/docs/react-final-form/types/FormProps#onsubmit\n\n### Step 8: Define your `renderField` functions inline (if you want)\n\nWith Redux Form, it was common to have to do something like this:\n\n```jsx\n// outside your render() method\nconst renderField = (field) => (\n    <div className=\"input-row\">\n      <input {...field.input} type=\"text\"/>\n      {field.meta.touched && field.meta.error &&\n       <span className=\"error\">{field.meta.error}</span>}\n    </div>\n  )\n\n// inside your render() method\n<Field name=\"myField\" component={renderField}/>\n```\n\nWith React Final Form, you can define your render logic directly your JSX.\n\n```jsx\n// inside your render() method\n<Field name=\"myField\">\n  {field => (\n    <div className=\"input-row\">\n      <input {...field.input} type=\"text\" />\n      {field.meta.touched && field.meta.error && (\n        <span className=\"error\">{field.meta.error}</span>\n      )}\n    </div>\n  )}\n</Field>\n```\n\nIt'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.\n\n### The Full Diff\n\n```diff\n import React from 'react'\n-import { reduxForm, Field } from 'redux-form',\n+import { Form, Field } from 'react-final-form'\n\n const MyForm = props => {\n-  const { handleSubmit, pristine, reset, submitting } = props\n   return (\n+    <Form\n+      initialValues={{\n+        firstName: 'Dan'\n+      }}\n+      onSubmit={values => {\n+        // send values to the cloud\n+      }}\n+      validate={values => {\n+        // do validation here, and return errors object\n+      }}\n+    >\n+      {({ handleSubmit, pristine, form, submitting }) => (\n         <form onSubmit={handleSubmit}>\n           <div>\n             <Field\n               name=\"firstName\"\n               component=\"input\"\n               type=\"text\"\n               placeholder=\"First Name\"\n             />\n           </div>\n           <div>\n             <label>Last Name</label>\n             <Field\n               name=\"lastName\"\n               component=\"input\"\n               type=\"text\"\n               placeholder=\"Last Name\"\n             />\n           </div>\n           <div>\n             <button type=\"submit\" disabled={submitting}>\n               Submit\n             </button>\n            <button\n              type=\"button\"\n              disabled={pristine || submitting}\n-             onClick={reset}\n+             onClick={form.reset}\n            >\n              Clear Values\n            </button>\n           </div>\n         </form>\n+      )}\n+    </Form>\n   )\n }\n\n-export default reduxForm({\n-  form: 'myForm',\n-  initialValues: {\n-    firstName: 'Dan'\n-  },\n-  onSubmit: values => {\n-    // send values to the cloud\n-  },\n-  validate: values => {\n-    // do validation here, and return errors object\n-  }\n-})(MyForm)\n+export default MyForm\n```\n\n### `<Fields/>`\n\nIf 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:\n\n```tsx\nconst Fields = ({\n  names,\n  subscription,\n  fieldsState = {},\n  children,\n  originalRender\n}) => {\n  if (!names.length) {\n    return (originalRender || children)(fieldsState)\n  }\n  const [name, ...rest] = names\n  return (\n    <Field name={name} subscription={subscription}>\n      {fieldState => (\n        <Fields\n          names={rest}\n          subscription={subscription}\n          originalRender={originalRender || children}\n          fieldsState={{ ...fieldsState, [name]: fieldState }}\n        />\n      )}\n    </Field>\n  )\n}\n```\n\nHere's a sandbox demonstrating its usage:\n\n[![Edit 🏁React Final Form: Fields Component](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/pyrwplknom?fontsize=14)\n\n### `<FieldArray/>`\n\nReact 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.\n\nYou 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.\n\n```tsx\nimport arrayMutators from 'final-form-arrays'\nimport { FieldArray } from 'react-final-form-arrays'\n\nconst MyForm = () => (\n  <Form\n    onSubmit={onSubmit}\n    mutators={{ ...arrayMutators }}\n    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ IMPORTANT!\n  >\n    {({\n      handleSubmit,\n      form: {\n        mutators: { push, pop } // injected from final-form-arrays above\n      }\n    }) => (\n      <form onSubmit={handleSubmit}>\n        ... other fields here maybe ...\n        <button type=\"button\" onClick={() => push('customers', undefined)}>\n          Add Customer\n        </button>\n        <button type=\"button\" onClick={() => pop('customers')}>\n          Remove Customer\n        </button>\n        <FieldArray name=\"customers\">\n          {({ fields }) =>\n            fields.map((name, index) => (\n              <div key={name}>\n                <label>Cust. #{index + 1}</label>\n                <Field\n                  name={`${name}.firstName`}\n                  component=\"input\"\n                  placeholder=\"First Name\"\n                />\n              </div>\n            ))\n          }\n        </FieldArray>\n      </form>\n    )}\n  </Form>\n)\n```\n\nHere's a sandbox to demonstrate:\n\n[![Edit 🏁 React Final Form - Field Arrays](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/distracted-bhaskara-kx8qv67nk5?fontsize=14)\n\n### Cheat Code: The Lazy Way\n\n⚠️ NOT RECOMMENDED ⚠️\n\nThere's some chance that you could get away with implementing this function that replicates what the `reduxForm()` decorator does:\n\n```jsx\nimport { Form } from 'react-final-form'\n\nconst reactFinalForm = ({ form, ...config }) => component => props => (\n  <Form {...config} {...props} component={component} />\n)\n```\n\nThen you'd only have to change that one thing.\n\n```diff\n-export default reduxForm({\n+export default reactFinalForm({\n   form: 'myForm',\n   initialValues: {\n     firstName: 'Dan'\n   },\n   onSubmit: values => {\n     // send values to the cloud\n   },\n   validate: values => {\n     // do validation here, and return errors object\n   }\n })(MyForm)\n```\n\nBut cheats like this create technical debt, so do the right thing and refactor your forms to use render props. 😄\n"
  },
  {
    "path": "docs/philosophy.md",
    "content": "# 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.\n\n# Philosophy\n\nFor 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.\n\n## Talk\n\nIn this talk, I explain the journey through Redux Form to the conception and creation of React Final Form.\n\n[Next Generation Forms with React Final Form – React Alicante 2018, Alicante, Spain](https://youtu.be/WoSzy-4mviQ)\n\n## Goals\n\nReact Final Form strives to meet the following goals:\n\n### Strongly Typed\n\nReact 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_.\n\n### Modularity\n\nJust 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.\n\nAlso, this allows for...\n\n### Minimal Bundle Size\n\nReact 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.\n\n### High Performance\n\nYou 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.\n\nIf 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.\n\nThe result is that you can streamline your form for maximum performance.\n\n[Ready to get started?](getting-started)\n"
  },
  {
    "path": "docs/types/FieldProps.md",
    "content": "# 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.\n\n# `FieldProps`\n\nThese are props that you pass to [`<Field/>`](../api/Field). You must provide one of the ways to render: `component`, `render`, or `children`.\n\n## `afterSubmit`\n\n```ts\n() => void\n```\n\nOptional.\n\nA callback to notify fields after submission has completed successfully.\n\n## `allowNull`\n\n```ts\nboolean\n```\n\nOptional. Defaults to `false`.\n\nBy default, if your value is `null`, [`<Field/>`](../api/Field) will convert it to `''`, to ensure\n[controlled inputs](https://reactjs.org/docs/forms.html#controlled-components).\n\nBut if you pass `true` to `allowNull`, [`<Field/>`](..api/Field) will give you a `null` value.\n\n## `beforeSubmit`\n\n```ts\n() => void | false\n```\n\nOptional.\n\nA 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`.\n\n## `children`\n\n```ts\n((props: FieldRenderProps) => React.Node) | React.Node`\n```\n\nOptional. (if you specify [`component`](#component) or [`render`](#render))\n\nA render function that is given [`FieldRenderProps`](FieldRenderProps), as well as any non-API props passed into the `<Field/>` component. For example, if you did...\n\n```tsx\n<Field name=\"myField\" someArbitraryOtherProp={42}>\n  {props => {\n    console.log(props.someArbitraryOtherProp) // would print 42\n    return <input {...props.input}/>\n  }}\n</Field>\n```\n\nNote 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:\n\n```tsx\n<Field name=\"favoriteColor\" component=\"select\">\n  <option value=\"FF0000\">Red</option>\n  <option value=\"00FF00\">Green</option>\n  <option value=\"0000FF\">Blue</option>\n</Field>\n```\n\nRelated:\n\n- [`FieldRenderProps`](FieldRenderProps)\n\n## `component`\n\n```ts\nReact.ComponentType<FieldRenderProps> | 'input' | 'select' | 'textarea'`\n```\n\nOptional. If you are not using `'input'`, `'select`' or `'textarea'`, it is recommended that you use [`children`](#children) or [`render`](#render).\n\nEither 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...\n\n<!-- prettier-ignore -->\n```tsx\n<Field\n  name=\"myField\"\n  someArbitraryOtherProp={42}\n  component={MyFieldComp} />\n\nconst MyFieldComp = props => {\n  console.log(props.someArbitraryOtherProp) // would print 42\n  return <input {...props.input} />\n}\n```\n\nRelated:\n\n- [`FieldRenderProps`](FieldRenderProps)\n\n## `data`\n\n```ts\nObject\n```\n\nOptional.\n\nInitial state for arbitrary values to be placed by mutators.\n\n## `defaultValue`\n\n```ts\nany\n```\n\nOptional.\n⚠️ You probably want [`initialValue`](#initialvalue)! ⚠️\n\nThe 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).**_\n\n## `format`\n\n<!-- prettier-ignore -->\n```ts\n(value: any, name: string) => any\n```\n\nOptional.\n\nA 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).\n\n**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.**\n\n## `formatOnBlur`\n\n```ts\nboolean\n```\n\nOptional. Defaults to `false`.\n\nIf `true`, the `format` function will only be called when the field is blurred. If `false`, `format` will be called on every render.\n\n## `initialValue`\n\n```ts\nany\n```\n\nOptional.\n\nThe 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`.\n\nThe value given here will override any `initialValues` given to the entire form.\n\n## `isEqual`\n\n<!-- prettier-ignore -->\n```ts\n(a: any, b: any) => boolean\n```\n\nOptional. Defaults to `===`.\n\nA function to determine if two values are equal.\n\n## `multiple`\n\n```ts\nboolean\n```\n\nOptional.\n\nOnly of use when using `component=\"select\"` and you want a multiselect.\n\nIt will be added on your input component, or you may retrieve its value inside the \"input\" property of your custom components.\n\n## `name`\n\n```ts\nstring\n```\n\n**Required**\n\nThe name of your field. Field values may be deeply nested using dot-and-bracket syntax.\n\n[Learn more about Field Names](/docs/final-form/field-names).\n\n## `parse`\n\n<!-- prettier-ignore -->\n```ts\n(value: any, name: string) => any\n```\n\nOptional.\n\nA 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).\n\n**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 `''`.**\n\n## `ref`\n\nThe `ref` is forwarded to the component provided by the `component` prop.\n\n## `render`\n\n<!-- prettier-ignore -->\n```ts\n(props: FieldRenderProps) => React.Node\n```\n\nOptional. (if you specify [`component`](#component) or [`children`](#children))\n\nA render function that is given [`FieldRenderProps`](FieldRenderProps), as well as any non-API props passed into the `<Field/>` component. For example, if you did...\n\n```tsx\n<Field\n  name=\"myField\"\n  someArbitraryOtherProp={42}\n  render={props => {\n    console.log(props.someArbitraryOtherProp) // would print 42\n    return <input {...props.input} />\n  }}\n/>\n```\n\nNote that if you specify `render` _and_ [`children`](#children), `render` will be called, with `children` injected as if it were an additional prop.\n\nRelated:\n\n- [`FieldRenderProps`](FieldRenderProps)\n\n## `subscription`\n\n```ts\n{ [string]: boolean }\n```\n\nOptional. _Advanced Usage_\n\nAn 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.\n\nIf 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.\n\nRelated:\n\n- [`FieldState`](/docs/final-form/types/FieldState)\n\n## `type`\n\n```ts\nstring\n```\n\nOptional.\n\nIf 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.\n\nIt will be added on your input component, or you may retrieve its value inside the \"input\" property of your custom components\n\n## `validate`\n\n```ts\n(value: ?any, allValues: Object, meta: ?FieldState) => ?any\n```\n\nOptional.\n\nA 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.\n\n⚠️ 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:\n\n[![Edit Changing Field Level Validators](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/changing-field-level-validators-zc8ei?fontsize=14)\n\n## `validateFields`\n\n```ts\nstring[]\n```\n\nOptional.\n\nAn array of field names to validate when this field changes. If `undefined`,\n_every_ field will be validated when this one changes; if `[]`, _only this\nfield_ will have its field-level validation function called when it changes; if\nother field names are specified, those fields _and this one_ will be validated\nwhen this field changes.\n\n⚠️ 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`.\n\n## `value`\n\n```ts\nany\n```\n\nOptional.\n\n**This is only used for checkboxes and radio buttons!**\n\nYou must also include a `type=\"radio\"` or `type=\"checkbox\"` prop.\n\n### Radio Buttons\n\nThe 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.\n\n### Checkboxes\n\n#### With `value`\n\nThe 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.\n\n#### Without `value`\n\nThe 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`.\n"
  },
  {
    "path": "docs/types/FieldRenderProps.md",
    "content": "# 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.\n\n# `FieldRenderProps`\n\nThese are the props that [`<Field/>`](../api/Field) provides to your render function or component.\n\nThis 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.\n\n## `input.name`\n\n```ts\nstring\n```\n\n**Required**\n\nThe name of the field.\n\n## `input.onBlur`\n\n```ts\n(?SyntheticFocusEvent<*>) => void`\n```\n\n**Required**\n\nThe `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).\n\nRelated:\n\n- [`SyntheticFocusEvent`](https://reactjs.org/docs/events.html#focus-events)\n\n## `input.onChange`\n\n```ts\n(SyntheticInputEvent<*> | any) => void\n```\n\n**Required**\n\nThe `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.\n\nRelated:\n\n- [`SyntheticInputEvent`](https://reactjs.org/docs/events.html#form-events)\n\n## `input.onFocus`\n\n```ts\n(?SyntheticFocusEvent<*>) => void\n```\n\n**Required**\n\nThe `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).\n\nRelated:\n\n- [`SyntheticFocusEvent`](https://reactjs.org/docs/events.html#focus-events)\n\n## `input.value`\n\n```ts\nany\n```\n\nOptional. May not be present if you have not [subscribed](FieldProps#subscription) to `value`.\n\nThe current value of the field.\n\n## `meta.active`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `active`.\n\nWhether or not the field currently has focus.\n\n## `meta.data`\n\nA place for arbitrary values to be placed by mutators.\n\n## `meta.dirty`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `dirty`.\n\n`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.\n\n## `meta.dirtySinceLastSubmit`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `dirtySinceLastSubmit`.\n\n`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.\n\n## `meta.error`\n\n```ts\nany\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `error`.\n\nThe current validation error for this field.\n\n## `meta.initial`\n\n```ts\nany\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `initial`.\n\nThe initial value of the field. `undefined` if it was never initialized.\n\n## `meta.invalid`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `invalid`.\n\n`true` if the field has a validation error or a submission error. `false` otherwise.\n\n## `meta.modified`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `modified`.\n\n`true` if this field's value has ever been changed. `false` otherwise.\n\nOnce `true`, it will remain `true` for the lifetime of the field, or until the form is reset.\n\n## `meta.modifiedSinceLastSubmit`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `modifiedSinceLastSubmit`.\n\n`true` if this field's value has ever been changed since last submission. `false` otherwise.\n\nOnce `true`, it will remain `true` until the next submit action, or until the form is reset.\n\n## `meta.pristine`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `pristine`.\n\n`true` if the current value is `===` to the initial value, `false` if the values are `!==`.\n\n## `meta.submitError`\n\n```ts\nany\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `submitError`.\n\nThe submission error for this field.\n\n## `meta.submitFailed`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `submitFailed`.\n\n`true` if a form submission has been tried and failed. `false` otherwise.\n\n## `meta.submitSucceeded`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `submitSucceeded`.\n\n`true` if the form has been successfully submitted. `false` otherwise.\n\n## `meta.submitting`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `submitting`.\n\n`true` if the form is currently being submitted asynchronously. `false` otherwise.\n\n## `meta.touched`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `touched`.\n\n`true` if this field has ever gained and lost focus. `false` otherwise.\n\nUseful for knowing when to display error messages.\n\n## `meta.valid`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `valid`.\n\n`true` if this field has no validation or submission errors. `false` otherwise.\n\n## `meta.validating`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `validating`.\n\n`true` if this field is currently waiting on its asynchronous field-level validation function to resolve. `false` otherwise.\n\n## `meta.visited`\n\n```ts\nboolean\n```\n\nOptional: May not be present if you have not [subscribed](FieldProps#subscription) to `visited`.\n\n`true` if this field has ever gained focus. `false` otherwise.\n"
  },
  {
    "path": "docs/types/FormProps.md",
    "content": "# 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.\n\n# `FormProps`\n\nThese 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).\n\n## `children`\n\n```ts\n((props: FormRenderProps) => React.Node) | React.Node`\n```\n\nOptional. (if you specify [`component`](#component) or [`render`](#render))\n\nA render function that is given [`FormRenderProps`](FormRenderProps), as well as any non-API props passed into the `<Form/>` component. For example, if you did...\n\n```tsx\n<Form onSubmit={onSubmit} someArbitraryOtherProp={42}>\n  {props => {\n    console.log(props.someArbitraryOtherProp) // would print 42\n    return <form onSubmit={props.handleSubmit}> ... </form>\n  }}\n</Form>\n```\n\nNote that if you specify [`render`](#render) _and_ `children`, `render` will be called, with `children` injected as if it were an additional prop.\n\nRelated:\n\n- [`FormRenderProps`](FormRenderProps)\n\n## `component`\n\n```ts\nReact.ComponentType<FormRenderProps>\n```\n\nOptional. It is recommended that you use [`children`](#children) or [`render`](#render).\n\nA 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...\n\n<!-- prettier-ignore -->\n```tsx\n<Form\n  onSubmit={onSubmit}\n  component={MyFormComp}\n  someArbitraryOtherProp={42} />\n\nconst MyFormComp = props => {\n  console.log(props.someArbitraryOtherProp) // would print 42\n  return <form onSubmit={props.handleSubmit}> ... </form>\n}\n```\n\nNote 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-).\n\nRelated:\n\n- [`FormRenderProps`](FormRenderProps)\n\n## `debug`\n\n```ts\n(\n  state: FormState,\n  fieldStates: { [string]: FieldState }\n) => void\n```\n\nOptional.\n\nA callback for debugging that receives the form state and the states of\nall the fields. It's called _on every state change_. A typical thing to pass in\nmight be `console.log`.\n\nRelated:\n\n- [`FormState`](/docs/final-form/types/FormState)\n- [`FieldState`](/docs/final-form/types/FieldState)\n\n## `decorators`\n\n```ts\nDecorator[]\n```\n\nOptional.\n\nAn array of decorators to apply to the form. [`<Form/>`](../api/Form) will undecorate the form on unmount.\n\nRelated:\n\n- [`Decorator`](/docs/final-form/types/Decorator)\n\n## `form`\n\n```ts\nFormApi\n```\n\nOptional. _Advanced Usage_\n\nIf 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.\n\nRelated:\n\n- [`FormApi`](/docs/final-form/types/FormApi)\n\n## `initialValues`\n\n```ts\nFormValues | Object\n```\n\nOptional.\n\nThe initial values of your form. These will also be used to compare against the\ncurrent values to calculate `pristine` and `dirty`.\n\nIf you are using Typescript, these values must be the same type as the object given to your [`onSubmit`](#onsubmit) function.\n\n## `initialValuesEqual`\n\n```ts\n(Object | undefined, Object | undefined) => boolean\n```\n\nOptional.\n\nA 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\".\n\n## `keepDirtyOnReinitialize`\n\n```ts\nboolean\n```\n\nOptional.\n\nIf `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`.\n\n## `mutators`\n\n```ts\n{ [string]: Mutator }\n```\n\nOptional.\n\nNamed mutator functions.\n\nRelated:\n\n- [Mutator](/docs/final-form/types/Mutator)\n\n## `onSubmit`\n\n```ts\n(\n  values: FormValues,\n  form: FormApi,\n  callback: ?(errors: ?Object) => void\n) => ?Object | Promise<?Object> | void\n```\n\n**Required.**\n\nFunction to call when the form is submitted. There are three possible ways to\nwrite an `onSubmit` function:\n\n### 1. Synchronous\n\nReturns `undefined` on success, or an `Object` of submission errors on failure.\n\n### 2. Asynchronous with a callback\n\nReturns `undefined`, calls `callback()` with no arguments on success, or with an `Object` of submission errors on failure.\n\n### 3. Asynchronous with a `Promise`\n\nReturns 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.\n\n### Submission Errors\n\nSubmission errors must be in the same shape as the values of the form. You may\nreturn a generic error for the whole form (e.g. `'Login Failed'`) using the\nspecial [`FORM_ERROR`](/docs/final-form/api#form_error) string key.\n\nRelated:\n\n- [`FormApi`](/docs/final-form/types/FormApi)\n\n## `render`\n\n<!-- prettier-ignore -->\n```ts\n(props: FormRenderProps) => React.Node\n```\n\nOptional. (if you specify [`component`](#component) or [`children`](#children))\n\nA render function that is given [`FormRenderProps`](FormRenderProps), as well as any non-API props passed into the `<Form/>` component. For example, if you did...\n\n```tsx\n<Form\n  onSubmit={onSubmit}\n  someArbitraryOtherProp={42}\n  render={props => {\n    console.log(props.someArbitraryOtherProp) // would print 42\n    return <form onSubmit={props.handleSubmit}> ... </form>\n  }}\n/>\n```\n\nNote that if you specify `render` _and_ [`children`](#children), `render` will be called, with `children` injected as if it were an additional prop.\n\nRelated:\n\n- [`FormRenderProps`](FormRenderProps)\n\n## `subscription`\n\n```ts\n{ [string]: boolean }\n```\n\nOptional. _Advanced Usage_\n\nAn 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.\n\nIf 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.\n\nRelated:\n\n- [`FormState`](/docs/final-form/types/FormState)\n\n## `validate`\n\n```ts\n(values: FormValues) => Object | Promise<Object>\n```\n\nOptional.\n\nA 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:\n\n### 1. Synchronous\n\nReturns `{}` or `undefined` when the values are valid, or an `Object` of validation errors when the values are invalid.\n\n### 2. Asynchronous with a `Promise`\n\nReturns 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.\n\n### Validation Errors\n\nValidation 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.\n\n## `validateOnBlur`\n\n```ts\nboolean\n```\n\nOptional.\n\nIf `true`, validation will happen on blur. If `false`, validation will happen on change. Defaults to `false`.\n"
  },
  {
    "path": "docs/types/FormRenderProps.md",
    "content": "# 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.\n\n# `FormRenderProps`\n\nThese 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).\n\nThis object contains everything in Final Form's [`FormState`](/docs/final-form/types/FormState) as well as:\n\n## `form`\n\n```ts\nFormApi\n```\n\nThe Final Form [`FormApi`](/docs/final-form/types/FormApi).\n\n## `handleSubmit`\n\n```ts\n(?SyntheticEvent<HTMLFormElement>) => ?Promise<?Object>\n```\n\nA function intended for you to give directly to the `<form>` tag:\n\n<!-- prettier-ignore -->\n```jsx\n<form onSubmit={handleSubmit}>\n... fields go here ...\n</form>\n```\n\nThe function's return type depends on the way the [`onSubmit` function is written](../types/FormProps#onsubmit).\n\nRelated:\n\n- [`SyntheticEvent`](https://reactjs.org/docs/events.html)\n"
  },
  {
    "path": "docs/types/FormSpyProps.md",
    "content": "# 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.\n\n# `FormSpyProps`\n\nThese 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).\n\n## `children`\n\n<!-- prettier-ignore -->\n```ts\n(props: FormRenderProps) => React.Node\n```\n\nOptional. (if you specify [`component`](#component) or [`render`](#render) or [`onChange`](#onchange))\n\nA render function that is given [`FormSpyRenderProps`](FormSpyRenderProps), as well as any non-API props passed into the `<FormSpy/>` component. For example, if you did...\n\n```tsx\n<FormSpy someArbitraryOtherProp={42}>\n  {props => {\n    console.log(props.someArbitraryOtherProp) // would print 42\n    return <pre>{JSON.stringify(props.values, undefined, 2)}</pre>\n  }}\n</FormSpy>\n```\n\nNote that if you specify [`render`](#render) _and_ `children`, `render` will be called, with `children` injected as if it were an additional prop.\n\n**Will not be called if an [`onChange`](#onchange) callback is specified.**\n\nRelated:\n\n- [`FormSpyRenderProps`](FormSpyRenderProps)\n\n## `component`\n\n```ts\nReact.ComponentType<FormSpyRenderProps>\n```\n\nOptional. It is recommended that you use [`children`](#children) or [`render`](#render).\n\nA 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...\n\n<!-- prettier-ignore -->\n```tsx\n<FormSpy\n  component={MyFormSpyComp}\n  someArbitraryOtherProp={42} />\n\nconst MyFormSpyComp = props => {\n  console.log(props.someArbitraryOtherProp) // would print 42\n  return <pre>{JSON.stringify(props.values, undefined, 2)}</pre>\n}\n```\n\nNote 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-).\n\n**Will not be called if an [`onChange`](#onchange) callback is specified.**\n\nRelated:\n\n- [`FormSpyRenderProps`](FormSpyRenderProps)\n\n## `onChange`\n\n```ts\n(formState: FormState) => void\n```\n\nOptional.\n\nA change listener that will be called with form state whenever the form state, as subscribed to by the [`subscription`](#subscription) prop, has changed.\n\nWhen an `onChange` prop is provided, the [`<FormSpy/>`](../api/FormSpy) will not render anything.\n\n## `render`\n\n<!-- prettier-ignore -->\n```ts\n(props: FormSpyRenderProps) => React.Node\n```\n\nOptional. (if you specify [`component`](#component) or [`children`](#children) or [`onChange`](#onchange))\n\nA render function that is given [`FormSpyRenderProps`](FormSpyRenderProps), as well as any non-API props passed into the `<FormSpy/>` component. For example, if you did...\n\n```tsx\n<FormSpy\n  someArbitraryOtherProp={42}\n  render={props => {\n    console.log(props.someArbitraryOtherProp) // would print 42\n    return <pre>{JSON.stringify(props.values, undefined, 2)}</pre>\n  }}\n/>\n```\n\nNote that if you specify `render` _and_ [`children`](#children), `render` will be called, with `children` injected as if it were an additional prop.\n\n**Will not be called if an [`onChange`](#onchange) callback is specified.**\n\nRelated:\n\n- [`FormSpyRenderProps`](FormSpyRenderProps)\n\n## `subscription`\n\n```ts\n{ [string]: boolean }\n```\n\nOptional. _Advanced Usage_\n\nAn 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.\n\nIf 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.\n\nRelated:\n\n- [`FormState`](/docs/final-form/types/FormState)\n"
  },
  {
    "path": "docs/types/FormSpyRenderProps.md",
    "content": "# 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.\n\n# `FormSpyRenderProps`\n\nThese 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.\n\nThis object contains everything in Final Form's [`FormState`](/docs/final-form/types/FormState) as well as:\n\n## `form`\n\n```ts\nFormApi\n```\n\nThe Final Form [`FormApi`](/docs/final-form/types/FormApi).\n"
  },
  {
    "path": "eslint.config.mjs",
    "content": "import js from \"@eslint/js\";\nimport typescriptParser from \"@typescript-eslint/parser\";\nimport typescriptPlugin from \"@typescript-eslint/eslint-plugin\";\nimport reactPlugin from \"eslint-plugin-react\";\nimport reactHooks from \"eslint-plugin-react-hooks\";\nimport jsxA11y from \"eslint-plugin-jsx-a11y\";\n\n// Manually defined globals to avoid issues with the 'globals' package\nconst browserGlobals = {\n  window: \"readonly\",\n  document: \"readonly\",\n  navigator: \"readonly\",\n  console: \"readonly\",\n  fetch: \"readonly\",\n  setTimeout: \"readonly\",\n  HTMLInputElement: \"readonly\",\n  HTMLElement: \"readonly\",\n};\nconst nodeGlobals = {\n  process: \"readonly\",\n  require: \"readonly\",\n  module: \"readonly\",\n  exports: \"writable\",\n  __dirname: \"readonly\",\n  __filename: \"readonly\",\n  global: \"readonly\",\n  console: \"readonly\",\n};\nconst jestGlobals = {\n  jest: \"readonly\",\n  describe: \"readonly\",\n  it: \"readonly\",\n  expect: \"readonly\",\n  afterEach: \"readonly\",\n  beforeEach: \"readonly\",\n  test: \"readonly\",\n  beforeAll: \"readonly\",\n  afterAll: \"readonly\",\n};\n\nexport default [\n  // Base config for all JS/TS files (can be overridden)\n  {\n    ignores: [\n      \"node_modules/**\",\n      \"dist/**\",\n      \"coverage/**\",\n      \"*.min.js\",\n      \"examples/**\",\n    ],\n  },\n  js.configs.recommended, // Apply ESLint recommended rules globally (respecting ignores)\n\n  // Configuration for TypeScript files in src/\n  {\n    files: [\"src/**/*.{ts,tsx}\"],\n    ignores: [\"**/*.test.ts\", \"**/*.test.tsx\"],\n    languageOptions: {\n      parser: typescriptParser,\n      parserOptions: {\n        ecmaFeatures: { jsx: true },\n        ecmaVersion: \"latest\",\n        sourceType: \"module\",\n        project: \"./tsconfig.json\", // Project-aware linting for src files\n      },\n      globals: {\n        ...browserGlobals,\n        ...nodeGlobals,\n        ...jestGlobals,\n        es2021: true,\n      },\n    },\n    plugins: {\n      \"@typescript-eslint\": typescriptPlugin,\n      react: reactPlugin,\n      \"react-hooks\": reactHooks,\n      \"jsx-a11y\": jsxA11y,\n    },\n    rules: {\n      ...typescriptPlugin.configs.recommended.rules,\n      ...reactPlugin.configs.recommended.rules,\n      \"react/react-in-jsx-scope\": \"off\",\n      \"react/jsx-uses-react\": \"off\",\n      \"jsx-a11y/href-no-hash\": \"off\",\n      \"react-hooks/rules-of-hooks\": \"error\",\n      \"react-hooks/exhaustive-deps\": \"warn\",\n      \"@typescript-eslint/no-unused-vars\": [\n        \"warn\",\n        { argsIgnorePattern: \"^_\", varsIgnorePattern: \"^_\" },\n      ],\n      \"@typescript-eslint/no-explicit-any\": \"off\",\n      \"@typescript-eslint/no-non-null-assertion\": \"off\",\n      \"@typescript-eslint/explicit-module-boundary-types\": \"off\",\n      \"@typescript-eslint/no-unsafe-function-type\": \"off\",\n      \"react/no-children-prop\": \"off\",\n      \"@typescript-eslint/no-unused-expressions\": \"off\",\n      \"no-undef\": \"off\", // TypeScript handles this for .ts/.tsx\n    },\n    settings: {\n      react: { version: \"detect\" },\n    },\n  },\n\n  // Configuration for TypeScript test files in typescript/ (for dtslint, no project parsing)\n  {\n    files: [\"typescript/**/*.ts\", \"typescript/**/*.tsx\"],\n    languageOptions: {\n      parser: typescriptParser,\n      parserOptions: {\n        ecmaFeatures: { jsx: true }, // Allow JSX in .tsx test files\n        ecmaVersion: \"latest\",\n        sourceType: \"module\",\n      },\n      globals: {\n        ...browserGlobals,\n        ...nodeGlobals,\n        ...jestGlobals,\n        es2021: true,\n      }, // General globals for TS test files\n    },\n    plugins: {\n      \"@typescript-eslint\": typescriptPlugin,\n      // Add other plugins if relevant for these test files, e.g., react if they use React\n    },\n    rules: {\n      // Lighter ruleset for .d.ts test files or general TS syntax checking\n      \"@typescript-eslint/no-explicit-any\": \"off\",\n      \"@typescript-eslint/no-unused-vars\": \"off\",\n      \"no-unused-vars\": \"off\",\n      \"no-undef\": \"off\", // Disable no-undef for TypeScript files\n    },\n  },\n\n  // Configuration for JavaScript files (e.g., .js test files in src/, config files)\n  {\n    files: [\"**/*.js\", \"**/*.jsx\"],\n    ignores: [\"examples/**\"],\n    languageOptions: {\n      ecmaVersion: \"latest\",\n      sourceType: \"module\",\n      parserOptions: {\n        ecmaFeatures: {\n          jsx: true,\n        },\n      },\n      globals: {\n        ...browserGlobals,\n        ...nodeGlobals,\n        ...jestGlobals,\n        es2021: true,\n      },\n    },\n    plugins: {\n      react: reactPlugin,\n    },\n    rules: {\n      \"no-undef\": \"error\",\n      \"react/jsx-uses-vars\": \"warn\",\n      \"react/react-in-jsx-scope\": \"off\",\n      \"no-unused-vars\": [\"warn\", { argsIgnorePattern: \"^_\" }], // Enforce _ prefix for unused vars in JS files\n    },\n  },\n\n  // Configuration for .mjs files (ES modules in Node.js environment)\n  {\n    files: [\"**/*.mjs\"],\n    languageOptions: {\n      ecmaVersion: \"latest\",\n      sourceType: \"module\",\n      globals: {\n        ...nodeGlobals,\n      },\n    },\n    rules: {\n      \"no-undef\": \"error\",\n    },\n  },\n\n  // Specific overrides for ALL test files (JS and TS)\n  {\n    files: [\"**/*.test.js\", \"**/*.test.jsx\", \"**/*.test.ts\", \"**/*.test.tsx\"],\n    rules: {\n      \"no-unused-vars\": \"off\",\n      \"@typescript-eslint/no-unused-vars\": \"off\",\n    },\n  },\n];\n"
  },
  {
    "path": "examples/async-field-level-validation/Spinner.js",
    "content": "import styled, { keyframes } from \"styled-components\";\n\nconst rotation = keyframes`\n    from {\n      -webkit-transform: rotate(0deg);\n    }\n    to {\n      -webkit-transform: rotate(359deg);\n    }\n`;\nexport default styled.div`\n  height: 12px;\n  width: 12px;\n  margin-left: 5px;\n  position: absolute;\n  right: 0;\n  top: 0;\n  animation: ${rotation} 0.6s infinite linear;\n  border-left: 6px solid rgba(0, 174, 239, 0.15);\n  border-right: 6px solid rgba(0, 174, 239, 0.15);\n  border-bottom: 6px solid rgba(0, 174, 239, 0.15);\n  border-top: 6px solid rgba(0, 174, 239, 0.8);\n  border-radius: 100%;\n`;\n"
  },
  {
    "path": "examples/async-field-level-validation/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/async-field-level-validation/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport Spinner from \"./Spinner\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, undefined, 2));\n};\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst mustBeNumber = (value) => (isNaN(value) ? \"Must be a number\" : undefined);\nconst minValue = (min) => (value) =>\n  isNaN(value) || value >= min ? undefined : `Should be greater than ${min}`;\nconst composeValidators =\n  (...validators) =>\n  (value) =>\n    validators.reduce(\n      (error, validator) => error || validator(value),\n      undefined,\n    );\n\nconst simpleMemoize = (fn) => {\n  let lastArg;\n  let lastResult;\n  return (arg) => {\n    if (arg !== lastArg) {\n      lastArg = arg;\n      lastResult = fn(arg);\n    }\n    return lastResult;\n  };\n};\n\nconst usernameAvailable = simpleMemoize(async (value) => {\n  if (!value) {\n    return \"Required\";\n  }\n  await sleep(400);\n  if (\n    ~[\"john\", \"paul\", \"george\", \"ringo\"].indexOf(value && value.toLowerCase())\n  ) {\n    return \"Username taken!\";\n  }\n});\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Asynchronous Field-Level Validation</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <div>Usernames John, Paul, George or Ringo will fail async validation.</div>\n    <Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit, reset, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <Field name=\"username\" validate={usernameAvailable}>\n            {({ input, meta }) => (\n              <div>\n                <label>Username</label>\n                <input {...input} type=\"text\" placeholder=\"Username\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n                {meta.validating && <Spinner />}\n              </div>\n            )}\n          </Field>\n          <Field name=\"lastName\" validate={required}>\n            {({ input, meta }) => (\n              <div>\n                <label>Last Name</label>\n                <input {...input} type=\"text\" placeholder=\"Last Name\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <Field\n            name=\"age\"\n            validate={composeValidators(required, mustBeNumber, minValue(18))}\n          >\n            {({ input, meta }) => (\n              <div>\n                <label>Age</label>\n                <input {...input} type=\"text\" placeholder=\"Age\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/async-field-level-validation/package.json",
    "content": "{\n  \"name\": \"react-final-form-asynchronous-field-level-validation-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonstrates how field-level validation functions may be asynchronous.\",\n  \"keywords\": [\n    \"react-final-form\",\n    \"final-form\",\n    \"react\",\n    \"validation\",\n    \"asynchronous\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/async-field-level-validation/readme.md",
    "content": "# Asynchronous Field-Level Validation\n\n[![Edit react-final-form-async-field-level-validation-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/wy7z7q5zx5)\n"
  },
  {
    "path": "examples/async-redux-submission/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      position: relative;\n      padding: 8px 5px;\n      border: 1px solid transparent;\n      &.active {\n        background-color: paleturquoise;\n        border-color: turquoise;\n      }\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > .downshift > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 6px 9px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n        &[disabled] {\n          background: #eee;\n        }\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          margin-left: 0;\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n        &.downshift {\n          margin-left: 0;\n          padding-left: 15px;\n          flex: 1;\n          & > input {\n            width: 100%;\n            padding: 6px 5px;\n            font-size: 1em;\n            margin-left: 0;\n            border: 1px solid #ccc;\n            border-radius: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n  .downshift-options {\n    border: 1px solid #ddd;\n    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);\n    & > div {\n      padding: 3px 5px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/async-redux-submission/asyncSubmissionMiddleware.js",
    "content": "import { REGISTER, REGISTER_SUCCESS } from \"./registrationDuck\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst submit = async (values) => {\n  await sleep(200);\n  if (values.firstName === \"John\") {\n    throw Error({ firstName: \"No John's Allowed!\" });\n  }\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\n/** This is to mimic the behavior of one of the various Redux async middlewares */\nconst asyncSubmissionMiddleware = (store) => (next) => (action) => {\n  if (action && action.type === REGISTER) {\n    submit(action.payload).then(\n      () => store.dispatch({ type: REGISTER_SUCCESS }),\n      (errors) => {\n        // NOTE!! We are passing REGISTER_SUCCESS here because 🏁 Final Form expects\n        // submit errors to come back in a *resolved* promise.\n        store.dispatch({ type: REGISTER_SUCCESS, payload: errors });\n      },\n    );\n  }\n  return next(action);\n};\n\nexport default asyncSubmissionMiddleware;\n"
  },
  {
    "path": "examples/async-redux-submission/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport { Provider } from \"react-redux\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport store, { promiseListener } from \"./store\";\nimport {\n  REGISTER,\n  REGISTER_SUCCESS,\n  REGISTER_FAILURE,\n} from \"./registrationDuck\";\nimport MakeAsyncFunction from \"react-redux-promise-listener\";\n\nconst SubmitError = ({ name }) => (\n  <Field\n    name={name}\n    subscription={{ submitError: true, dirtySinceLastSubmit: true }}\n  >\n    {({ meta: { submitError, dirtySinceLastSubmit } }) =>\n      submitError && !dirtySinceLastSubmit ? <span>{submitError}</span> : null\n    }\n  </Field>\n);\n\nconst App = () => (\n  <Provider store={store}>\n    <Styles>\n      <h1>\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        React Final Form\n      </h1>\n      <h2>Async Redux Submission</h2>\n      <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n        Read Docs\n      </a>\n      <p>\n        Demonstrates how to use an async Redux side-effects library, like{\" \"}\n        <code>redux-saga</code> to manage form submissions using{\" \"}\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        React Final Form. Uses{\" \"}\n        <a\n          href=\"https://github.com/erikras/redux-promise-listener\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          <code>redux-promise-listener</code>\n        </a>{\" \"}\n        and{\" \"}\n        <a\n          href=\"https://github.com/erikras/react-redux-promise-listener\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          <code>react-redux-promise-listener</code>\n        </a>{\" \"}\n        libraries.\n      </p>\n      <p>Dispatched Redux actions can be found in the console.</p>\n      <p>\n        First name <code>John</code> will fail submit validation.\n      </p>\n      <MakeAsyncFunction\n        listener={promiseListener}\n        start={REGISTER}\n        resolve={REGISTER_SUCCESS}\n        reject={REGISTER_FAILURE}\n      >\n        {(onSubmit) => (\n          <Form\n            onSubmit={onSubmit}\n            render={({ handleSubmit, form, submitting, pristine, values }) => (\n              <form onSubmit={handleSubmit}>\n                <div>\n                  <label>First Name</label>\n                  <Field\n                    name=\"firstName\"\n                    component=\"input\"\n                    type=\"text\"\n                    placeholder=\"First Name\"\n                  />\n                  <SubmitError name=\"firstName\" />\n                </div>\n                <div>\n                  <label>Last Name</label>\n                  <Field\n                    name=\"lastName\"\n                    component=\"input\"\n                    type=\"text\"\n                    placeholder=\"Last Name\"\n                  />\n                  <SubmitError name=\"lastName\" />\n                </div>\n                <div>\n                  <label>Email</label>\n                  <Field\n                    name=\"email\"\n                    component=\"input\"\n                    type=\"email\"\n                    placeholder=\"Email\"\n                  />\n                  <SubmitError name=\"email\" />\n                </div>\n                <div>\n                  <label>Favorite Color</label>\n                  <Field name=\"favoriteColor\" component=\"select\">\n                    <option />\n                    <option value=\"#ff0000\">\n                      <span role=\"img\" aria-label=\"red heart\">\n                        ❤️\n                      </span>{\" \"}\n                      Red\n                    </option>\n                    <option value=\"#00ff00\">\n                      <span role=\"img\" aria-label=\"green heart\">\n                        💚\n                      </span>{\" \"}\n                      Green\n                    </option>\n                    <option value=\"#0000ff\">\n                      <span role=\"img\" aria-label=\"blue heart\">\n                        💙\n                      </span>{\" \"}\n                      Blue\n                    </option>\n                  </Field>\n                </div>\n                <div className=\"buttons\">\n                  <button type=\"submit\" disabled={submitting}>\n                    Submit\n                  </button>\n                  <button\n                    type=\"button\"\n                    onClick={form.reset}\n                    disabled={submitting || pristine}\n                  >\n                    Reset\n                  </button>\n                </div>\n                <pre>{JSON.stringify(values, 0, 2)}</pre>\n              </form>\n            )}\n          />\n        )}\n      </MakeAsyncFunction>\n    </Styles>\n  </Provider>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/async-redux-submission/package.json",
    "content": "{\n  \"name\": \"react-final-form-async-redux-submission\",\n  \"version\": \"1.0.0\",\n  \"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.\",\n  \"keywords\": [\n    \"form\",\n    \"redux\",\n    \"async\",\n    \"submit\",\n    \"promise\"\n  ],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-redux\": \"7.0.3\",\n    \"react-redux-promise-listener\": \"1.0.0\",\n    \"react-scripts\": \"3.0.1\",\n    \"redux\": \"4.0.1\",\n    \"redux-promise-listener\": \"1.1.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/async-redux-submission/readme.md",
    "content": "# Async Redux Submission\n\n[![Edit react-final-form-async-redux-submission-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/x71mx66z8w)\n"
  },
  {
    "path": "examples/async-redux-submission/registrationDuck.js",
    "content": "// QUACK! This is a duck. https://github.com/erikras/ducks-modular-redux\n\n// Actions\nexport const REGISTER = \"final-form-examples/registration/REGISTER\";\nexport const REGISTER_SUCCESS =\n  \"final-form-examples/registration/REGISTER_SUCCESS\";\nexport const REGISTER_FAILURE =\n  \"final-form-examples/registration/REGISTER_FAILURE\";\n\n// Reducer\nexport default function reducer(state = {}, action = {}) {\n  switch (action.type) {\n    case REGISTER:\n      return {\n        ...state,\n        registering: true,\n      };\n    case REGISTER_SUCCESS:\n      return {\n        ...state,\n        registering: false,\n      };\n    case REGISTER_FAILURE:\n      return {\n        ...state,\n        registering: false,\n      };\n    default:\n      return state;\n  }\n}\n\n// Action Creators\n\n// Selectors\n"
  },
  {
    "path": "examples/async-redux-submission/store.js",
    "content": "import { createStore, combineReducers, applyMiddleware, compose } from \"redux\";\nimport createReduxPromiseListener from \"redux-promise-listener\";\nimport registration from \"./registrationDuck\";\nimport asyncSubmissionMiddleware from \"./asyncSubmissionMiddleware\";\n\nconst reduxPromiseListener = createReduxPromiseListener();\n\nconst logger = (store) => (next) => (action) => {\n  console.log(action);\n  return next(action);\n};\n\nconst reducer = combineReducers({\n  registration,\n});\n\nconst composeEnhancers =\n  (typeof window !== \"undefined\" &&\n    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||\n  compose;\n\nconst store = createStore(\n  reducer,\n  {},\n  composeEnhancers(\n    applyMiddleware(\n      reduxPromiseListener.middleware,\n      asyncSubmissionMiddleware,\n      logger,\n    ),\n  ),\n);\n\nexport const promiseListener = reduxPromiseListener; // <---------- IMPORTANT\n\nexport default store;\n"
  },
  {
    "path": "examples/async-typeahead-redux/GithubUserTypeahead.jsx",
    "content": "import React, { useCallback } from \"react\";\nimport { useSelector, useDispatch } from \"react-redux\";\nimport { Field } from \"react-final-form\";\nimport { AsyncTypeahead } from \"react-bootstrap-typeahead\";\nimport useKeyword from \"./useKeyword\";\nimport { compose, propOr, pathOr } from \"ramda\";\nimport arrify from \"arrify\";\n\nimport { searchGithubUsers } from \"./actions\";\n\nconst AdaptedTypeahead = ({ input, render, meta, ...rest }) => (\n  <AsyncTypeahead {...input} {...rest} selected={input.value} />\n);\n\nconst GithubUserTypeahead = ({ name, ...props }) => {\n  const { keyword, updateKeyword } = useKeyword(name);\n\n  const dispatch = useDispatch();\n  const getOptions = useCallback(pathOr([], [keyword, \"value\"]), [keyword]);\n  const isLoading = useCallback(pathOr(false, [keyword, \"loading\"]), [keyword]);\n  const handleOnSearch = useCallback(compose(dispatch, searchGithubUsers), [\n    dispatch,\n  ]);\n\n  const options = useSelector(getOptions);\n  const loading = useSelector(isLoading);\n\n  return (\n    <Field\n      name={name}\n      component={AdaptedTypeahead}\n      parse={propOr(null, 0)}\n      format={arrify}\n      placeholder=\"Write a github username\"\n      labelKey=\"login\"\n      options={options}\n      onSearch={handleOnSearch}\n      isLoading={loading}\n      onInputChange={updateKeyword}\n    />\n  );\n};\n\nexport default GithubUserTypeahead;\n"
  },
  {
    "path": "examples/async-typeahead-redux/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/async-typeahead-redux/actions.js",
    "content": "export const requestGithubUsers = (query) => ({\n  type: \"GITHUB_USERS_REQUEST\",\n  query,\n});\n\nexport const storeGithubUsers = (query, users) => ({\n  type: \"GITHUB_USERS_RESPONSE\",\n  query,\n  users,\n});\n\nexport const searchGithubUsers = (query) => (dispatch) => {\n  dispatch(requestGithubUsers(query));\n\n  fetch(`https://api.github.com/search/users?q=${query}`)\n    .then((res) => res.json())\n    .then(({ items: users }) => dispatch(storeGithubUsers(query, users)));\n};\n"
  },
  {
    "path": "examples/async-typeahead-redux/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport { Provider } from \"react-redux\";\nimport Styles from \"./Styles\";\nimport { Form } from \"react-final-form\";\nimport setFieldData from \"final-form-set-field-data\";\n\nimport configureStore from \"./store\";\nimport GithubUserTypeahead from \"./GithubUserTypeahead\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst store = configureStore();\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      initialValues={{ user1: null, user2: null }}\n      mutators={{ setFieldData }}\n      render={({ handleSubmit, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>Github users</label>\n            <GithubUserTypeahead name=\"user1\" />\n          </div>\n          <div>\n            <label>Github users 2</label>\n            <GithubUserTypeahead name=\"user2\" />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(\n  <Provider store={store}>\n    <App />\n  </Provider>,\n  document.getElementById(\"root\"),\n);\n"
  },
  {
    "path": "examples/async-typeahead-redux/package.json",
    "content": "{\n  \"name\": \"react-final-form-github-user-asynctypeahead\",\n  \"version\": \"1.0.0\",\n  \"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.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"arrify\": \"2.0.1\",\n    \"final-form\": \"4.20.4\",\n    \"final-form-set-field-data\": \"1.0.2\",\n    \"ramda\": \"0.25.0\",\n    \"react\": \"17.0.2\",\n    \"react-bootstrap-typeahead\": \"3.1.4\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-redux\": \"7.1.0\",\n    \"redux\": \"4.0.4\",\n    \"redux-thunk\": \"2.3.0\",\n    \"styled-components\": \"2.4.0\"\n  }\n}\n"
  },
  {
    "path": "examples/async-typeahead-redux/readme.md",
    "content": "# Async Typeahead and Redux\n\n[![Edit react-final-form-async-typeahead-and-redux-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/5m4w2909k)\n"
  },
  {
    "path": "examples/async-typeahead-redux/store.js",
    "content": "import { createStore, applyMiddleware } from \"redux\";\nimport thunk from \"redux-thunk\";\n\nconst initialState = {};\nconst reducer = (state = initialState, action) => {\n  switch (action.type) {\n    case \"GITHUB_USERS_REQUEST\":\n      return {\n        ...state,\n        [action.query]: {\n          ...state[action.query],\n          loading: true,\n        },\n      };\n    case \"GITHUB_USERS_RESPONSE\":\n      return {\n        ...state,\n        [action.query]: {\n          value: action.users,\n          loading: false,\n        },\n      };\n    default:\n      return state;\n  }\n};\n\nexport default () => createStore(reducer, undefined, applyMiddleware(thunk));\n"
  },
  {
    "path": "examples/async-typeahead-redux/useKeyword.js",
    "content": "import { useForm, useField } from \"react-final-form\";\nimport { propOr } from \"ramda\";\n\nconst useKeyword = (name) => {\n  const {\n    mutators: { setFieldData },\n  } = useForm();\n  const { meta } = useField(name, { subscription: { data: true } });\n\n  return {\n    keyword: propOr(null, \"keyword\", meta.data),\n    updateKeyword: (keyword) => setFieldData(name, { keyword }),\n  };\n};\n\nexport default useKeyword;\n"
  },
  {
    "path": "examples/auto-save-field-blur/AutoSave.js",
    "content": "import React from \"react\";\nimport { FormSpy } from \"react-final-form\";\nimport diff from \"object-diff\";\n\nclass AutoSave extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = { values: props.values, submitting: false };\n  }\n\n  componentWillReceiveProps(nextProps) {\n    if (this.props.active && this.props.active !== nextProps.active) {\n      // blur occurred\n      this.save(this.props.active);\n    }\n  }\n\n  save = async (blurredField) => {\n    if (this.promise) {\n      await this.promise;\n    }\n    const { values, setFieldData, save } = this.props;\n\n    // This diff step is totally optional\n    const difference = diff(this.state.values, values);\n    if (Object.keys(difference).length) {\n      // values have changed\n      this.setState({ submitting: true, values });\n      setFieldData(blurredField, { saving: true });\n      this.promise = save(difference);\n      await this.promise;\n      delete this.promise;\n      this.setState({ submitting: false });\n      setFieldData(blurredField, { saving: false });\n    }\n  };\n\n  render() {\n    // This component doesn't have to render anything, but it can render\n    // submitting state.\n    return null;\n  }\n}\n\n// Make a HOC\n// This is not the only way to accomplish auto-save, but it does let us:\n// - Use built-in React lifecycle methods to listen for changes\n// - Maintain state of when we are submitting\n// - Render a message when submitting\n// - Pass in save prop nicely\nexport default (props) => (\n  <FormSpy\n    {...props}\n    subscription={{ active: true, values: true }}\n    component={AutoSave}\n  />\n);\n"
  },
  {
    "path": "examples/auto-save-field-blur/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 0 0 0 8px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/auto-save-field-blur/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport setFieldData from \"final-form-set-field-data\";\nimport AutoSave from \"./AutoSave\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst save = async (values) => {\n  console.log(\"Saving\", values);\n  await sleep(1000);\n};\n\nconst SavingIndicator = ({ name }) => (\n  <Field\n    name={name}\n    subscription={{ data: true }}\n    render={({\n      meta: {\n        data: { saving },\n      },\n    }) => (saving ? <div className=\"saving\">Saving</div> : null)}\n  />\n);\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Auto-Save on Field Blur</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      The <code>AutoSave</code> component uses{\" \"}\n      <a\n        href=\"https://github.com/final-form/react-final-form#formspy--reactcomponenttypeformspyprops\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        <code>FormSpy</code>\n      </a>{\" \"}\n      to listen to changes to values and which field is currently active and\n      auto-saves changes when a field is blurred. Look in the console for the\n      save events.\n    </p>\n    <Form\n      onSubmit={save /* NOT USED, but required */}\n      initialValues={{ employed: true, stooge: \"larry\" }}\n      mutators={{ setFieldData }}\n      subscription={{} /* No need to subscribe to anything */}\n    >\n      {({ form }) => (\n        <div className=\"form\">\n          {/* Don't even need a <form> tag */}\n\n          {/* 👇 👇 👇 👇 */}\n          <AutoSave setFieldData={form.mutators.setFieldData} save={save} />\n          {/* ☝️ ️☝️ ️☝️ ️️️️☝️ ️️*/}\n\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n            />\n            <SavingIndicator name=\"firstName\" />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field\n              name=\"lastName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Last Name\"\n            />\n            <SavingIndicator name=\"lastName\" />\n          </div>\n          <div>\n            <label>Email</label>\n            <Field\n              name=\"email\"\n              component=\"input\"\n              type=\"email\"\n              placeholder=\"Email\"\n            />\n            <SavingIndicator name=\"email\" />\n          </div>\n          <div>\n            <label>Favorite Color</label>\n            <Field name=\"favoriteColor\" component=\"select\">\n              <option />\n              <option value=\"#ff0000\">\n                <span role=\"img\" aria-label=\"red heart\">\n                  ❤️\n                </span>{\" \"}\n                Red\n              </option>\n              <option value=\"#00ff00\">\n                <span role=\"img\" aria-label=\"green heart\">\n                  💚\n                </span>{\" \"}\n                Green\n              </option>\n              <option value=\"#0000ff\">\n                <span role=\"img\" aria-label=\"blue heart\">\n                  💙\n                </span>{\" \"}\n                Blue\n              </option>\n            </Field>\n            <SavingIndicator name=\"favoriteColor\" />\n          </div>\n          <div>\n            <label>Employed?</label>\n            <Field name=\"employed\" component=\"input\" type=\"checkbox\" />\n            <SavingIndicator name=\"employed\" />\n          </div>\n          <div>\n            <label>Toppings</label>\n            <Field name=\"toppings\" component=\"select\" multiple>\n              <option value=\"ham\">\n                <span role=\"img\" aria-label=\"pig head\">\n                  🐷\n                </span>{\" \"}\n                Ham\n              </option>\n              <option value=\"mushrooms\">\n                <span role=\"img\" aria-label=\"mushroom\">\n                  🍄\n                </span>{\" \"}\n                Mushrooms\n              </option>\n              <option value=\"cheese\">\n                <span role=\"img\" aria-label=\"cheese\">\n                  🧀\n                </span>{\" \"}\n                Cheese\n              </option>\n              <option value=\"chicken\">\n                <span role=\"img\" aria-label=\"chicken\">\n                  🐓\n                </span>{\" \"}\n                Chicken\n              </option>\n              <option value=\"pineapple\">\n                <span role=\"img\" aria-label=\"pineapple\">\n                  🍍\n                </span>{\" \"}\n                Pinapple\n              </option>\n            </Field>\n            <SavingIndicator name=\"toppings\" />\n          </div>\n          <div>\n            <label>Best Stooge?</label>\n            <div>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"larry\"\n                />{\" \"}\n                Larry\n              </label>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"moe\"\n                />{\" \"}\n                Moe\n              </label>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"curly\"\n                />{\" \"}\n                Curly\n              </label>\n            </div>\n            <SavingIndicator name=\"stooge\" />\n          </div>\n          <div>\n            <label>Notes</label>\n            <Field name=\"notes\" component=\"textarea\" placeholder=\"Notes\" />\n            <SavingIndicator name=\"notes\" />\n          </div>\n        </div>\n      )}\n    </Form>\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/auto-save-field-blur/package.json",
    "content": "{\n  \"name\": \"react-final-form-auto-save-on-field-blur\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to create an AutoSave component to listen to form state and automatically save data when fields blur.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"final-form-set-field-data\": \"1.0.2\",\n    \"object-diff\": \"0.0.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/auto-save-field-blur/readme.md",
    "content": "# Auto-Save on Field Blur\n\n[![Edit react-final-form-auto-save-field-blur-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/7k742qpo36)\n"
  },
  {
    "path": "examples/auto-save-selective-debounce/AutoSave.js",
    "content": "import React from \"react\";\nimport { FormSpy } from \"react-final-form\";\nimport diff from \"object-diff\";\n\nconst areObjectsIdentical = (a, b) =>\n  Object.keys(diff(a, b)).length === 0 && Object.keys(diff(b, a)).length === 0;\n\nclass AutoSave extends React.Component {\n  static defaultProps = {\n    debounced: [],\n  };\n  constructor(props) {\n    super(props);\n\n    this.state = {\n      submitting: false,\n      ...this.splitValues(props.values),\n    };\n  }\n\n  componentDidUpdate() {\n    const { values, debounce } = this.props;\n    const { debouncedValues, immediateValues } = this.splitValues(values);\n\n    if (!areObjectsIdentical(this.state.immediateValues, immediateValues)) {\n      this.save();\n    }\n\n    if (!areObjectsIdentical(this.state.debouncedValues, debouncedValues)) {\n      if (this.timeout) {\n        clearTimeout(this.timeout);\n      }\n      this.timeout = setTimeout(() => {\n        this.save();\n      }, debounce);\n    }\n  }\n\n  splitValues = (values) => {\n    const { debounced } = this.props;\n\n    const debouncedValues = {};\n    const immediateValues = {};\n\n    Object.keys(values).forEach((key) => {\n      if (debounced.includes(key)) {\n        debouncedValues[key] = values[key];\n      } else {\n        immediateValues[key] = values[key];\n      }\n    });\n\n    return {\n      debouncedValues,\n      immediateValues,\n    };\n  };\n\n  save = async () => {\n    if (this.promise) {\n      await this.promise;\n    }\n    const { save, values } = this.props;\n\n    const { debouncedValues, immediateValues } = this.splitValues(values);\n\n    this.setState(\n      (state) => ({\n        submitting: true,\n        immediateValues: { ...immediateValues },\n        debouncedValues: { ...debouncedValues },\n      }),\n      async () => {\n        this.promise = save({\n          ...this.state.immediateValues,\n          ...this.state.debouncedValues,\n        });\n\n        await this.promise;\n        delete this.promise;\n\n        this.setState({ submitting: false });\n      },\n    );\n  };\n\n  render() {\n    // This component doesn't have to render anything, but it can render\n    // submitting state.\n    return (\n      this.state.submitting && <div className=\"submitting\">Submitting...</div>\n    );\n  }\n}\n\n// Make a HOC\n// This is not the only way to accomplish auto-save, but it does let us:\n// - Use built-in React lifecycle methods to listen for changes\n// - Maintain state of when we are submitting\n// - Render a message when submitting\n// - Pass in debounce and save props nicely\nexport default (props) => (\n  <FormSpy {...props} subscription={{ values: true }} component={AutoSave} />\n);\n"
  },
  {
    "path": "examples/auto-save-selective-debounce/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/auto-save-selective-debounce/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport AutoSave from \"./AutoSave\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst save = async (values) => {\n  console.log(\"Saving\", values);\n  await sleep(2000);\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>\n      Auto-Save with <em>Selective</em> Debounce\n    </h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      The <code>AutoSave</code> component uses{\" \"}\n      <a\n        href=\"https://github.com/final-form/react-final-form#formspy--reactcomponenttypeformspyprops\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        <code>FormSpy</code>\n      </a>{\" \"}\n      to listen to changes to values and auto-save changes. But it only\n      debounces changes to a specific list of fields given to the{\" \"}\n      <code>AutoSave</code> component, in this case, all the text inputs. Look\n      in the console for the save events.\n    </p>\n    <Form\n      onSubmit={save /* NOT USED, but required */}\n      initialValues={{ employed: true, stooge: \"larry\" }}\n      subscription={{} /* No need to subscribe to anything */}\n    >\n      {() => (\n        <div className=\"form\">\n          {/* Don't even need a <form> tag */}\n\n          {/* 👇 👇 👇 👇 */}\n          <AutoSave\n            debounce={2000}\n            save={save}\n            debounced={[\"firstName\", \"lastName\", \"email\", \"notes\"]}\n          />\n          {/* ☝️ ️☝️ ️☝️ ️️️️☝️ ️️*/}\n\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n            />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field\n              name=\"lastName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Last Name\"\n            />\n          </div>\n          <div>\n            <label>Email</label>\n            <Field\n              name=\"email\"\n              component=\"input\"\n              type=\"email\"\n              placeholder=\"Email\"\n            />\n          </div>\n          <div>\n            <label>Favorite Color</label>\n            <Field name=\"favoriteColor\" component=\"select\">\n              <option />\n              <option value=\"#ff0000\">\n                <span role=\"img\" aria-label=\"red heart\">\n                  ❤️\n                </span>{\" \"}\n                Red\n              </option>\n              <option value=\"#00ff00\">\n                <span role=\"img\" aria-label=\"green heart\">\n                  💚\n                </span>{\" \"}\n                Green\n              </option>\n              <option value=\"#0000ff\">\n                <span role=\"img\" aria-label=\"blue heart\">\n                  💙\n                </span>{\" \"}\n                Blue\n              </option>\n            </Field>\n          </div>\n          <div>\n            <label>Employed?</label>\n            <Field name=\"employed\" component=\"input\" type=\"checkbox\" />\n          </div>\n          <div>\n            <label>Toppings</label>\n            <Field name=\"toppings\" component=\"select\" type=\"select\" multiple>\n              <option value=\"ham\">\n                <span role=\"img\" aria-label=\"pig head\">\n                  🐷\n                </span>{\" \"}\n                Ham\n              </option>\n              <option value=\"mushrooms\">\n                <span role=\"img\" aria-label=\"mushroom\">\n                  🍄\n                </span>{\" \"}\n                Mushrooms\n              </option>\n              <option value=\"cheese\">\n                <span role=\"img\" aria-label=\"cheese\">\n                  🧀\n                </span>{\" \"}\n                Cheese\n              </option>\n              <option value=\"chicken\">\n                <span role=\"img\" aria-label=\"chicken\">\n                  🐓\n                </span>{\" \"}\n                Chicken\n              </option>\n              <option value=\"pineapple\">\n                <span role=\"img\" aria-label=\"pineapple\">\n                  🍍\n                </span>{\" \"}\n                Pinapple\n              </option>\n            </Field>\n          </div>\n          <div>\n            <label>Best Stooge?</label>\n            <div>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"larry\"\n                />{\" \"}\n                Larry\n              </label>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"moe\"\n                />{\" \"}\n                Moe\n              </label>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"curly\"\n                />{\" \"}\n                Curly\n              </label>\n            </div>\n          </div>\n          <div>\n            <label>Notes</label>\n            <Field name=\"notes\" component=\"textarea\" placeholder=\"Notes\" />\n          </div>\n        </div>\n      )}\n    </Form>\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/auto-save-selective-debounce/package.json",
    "content": "{\n  \"name\": \"react-final-form-auto-save-with-selective-debounce\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use a FormSpy component to auto-save your form values with a debounce, restricting which fields are debounced.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"object-diff\": \"0.0.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/auto-save-selective-debounce/readme.md",
    "content": "# Auto-Save with _Selective_ Debounce\n\n[![Edit react-final-form-auto-save-selective-debounce-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/98j0v46zj4)\n"
  },
  {
    "path": "examples/auto-save-with-debounce/AutoSave.js",
    "content": "import React from \"react\";\nimport { FormSpy } from \"react-final-form\";\nimport diff from \"object-diff\";\n\nclass AutoSave extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = { values: props.values, submitting: false };\n  }\n\n  componentWillReceiveProps(nextProps) {\n    if (this.timeout) {\n      clearTimeout(this.timeout);\n    }\n    this.timeout = setTimeout(this.save, this.props.debounce);\n  }\n\n  save = async () => {\n    if (this.promise) {\n      await this.promise;\n    }\n    const { values, save } = this.props;\n\n    // This diff step is totally optional\n    const difference = diff(this.state.values, values);\n    if (Object.keys(difference).length) {\n      // values have changed\n      this.setState({ submitting: true, values });\n      this.promise = save(difference);\n      await this.promise;\n      delete this.promise;\n      this.setState({ submitting: false });\n    }\n  };\n\n  render() {\n    // This component doesn't have to render anything, but it can render\n    // submitting state.\n    return (\n      this.state.submitting && <div className=\"submitting\">Submitting...</div>\n    );\n  }\n}\n\n// Make a HOC\n// This is not the only way to accomplish auto-save, but it does let us:\n// - Use built-in React lifecycle methods to listen for changes\n// - Maintain state of when we are submitting\n// - Render a message when submitting\n// - Pass in debounce and save props nicely\nexport default (props) => (\n  <FormSpy {...props} subscription={{ values: true }} component={AutoSave} />\n);\n"
  },
  {
    "path": "examples/auto-save-with-debounce/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/auto-save-with-debounce/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport AutoSave from \"./AutoSave\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst save = async (values) => {\n  console.log(\"Saving\", values);\n  await sleep(2000);\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Auto-Save with Debounce</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      The <code>AutoSave</code> component uses{\" \"}\n      <a\n        href=\"https://github.com/final-form/react-final-form#formspy--reactcomponenttypeformspyprops\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        <code>FormSpy</code>\n      </a>{\" \"}\n      to listen to changes to values and auto-save changes. Look in the console\n      for the save events.\n    </p>\n    <Form\n      onSubmit={save /* NOT USED, but required */}\n      initialValues={{ employed: true, stooge: \"larry\" }}\n      subscription={{} /* No need to subscribe to anything */}\n    >\n      {() => (\n        <div className=\"form\">\n          {/* Don't even need a <form> tag */}\n\n          {/* 👇 👇 👇 👇 */}\n          <AutoSave debounce={1000} save={save} />\n          {/* ☝️ ️☝️ ️☝️ ️️️️☝️ ️️*/}\n\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n            />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field\n              name=\"lastName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Last Name\"\n            />\n          </div>\n          <div>\n            <label>Email</label>\n            <Field\n              name=\"email\"\n              component=\"input\"\n              type=\"email\"\n              placeholder=\"Email\"\n            />\n          </div>\n          <div>\n            <label>Favorite Color</label>\n            <Field name=\"favoriteColor\" component=\"select\">\n              <option />\n              <option value=\"#ff0000\">\n                <span role=\"img\" aria-label=\"red heart\">\n                  ❤️\n                </span>{\" \"}\n                Red\n              </option>\n              <option value=\"#00ff00\">\n                <span role=\"img\" aria-label=\"green heart\">\n                  💚\n                </span>{\" \"}\n                Green\n              </option>\n              <option value=\"#0000ff\">\n                <span role=\"img\" aria-label=\"blue heart\">\n                  💙\n                </span>{\" \"}\n                Blue\n              </option>\n            </Field>\n          </div>\n          <div>\n            <label>Employed?</label>\n            <Field name=\"employed\" component=\"input\" type=\"checkbox\" />\n          </div>\n          <div>\n            <label>Toppings</label>\n            <Field name=\"toppings\" component=\"select\" multiple>\n              <option value=\"ham\">\n                <span role=\"img\" aria-label=\"pig head\">\n                  🐷\n                </span>{\" \"}\n                Ham\n              </option>\n              <option value=\"mushrooms\">\n                <span role=\"img\" aria-label=\"mushroom\">\n                  🍄\n                </span>{\" \"}\n                Mushrooms\n              </option>\n              <option value=\"cheese\">\n                <span role=\"img\" aria-label=\"cheese\">\n                  🧀\n                </span>{\" \"}\n                Cheese\n              </option>\n              <option value=\"chicken\">\n                <span role=\"img\" aria-label=\"chicken\">\n                  🐓\n                </span>{\" \"}\n                Chicken\n              </option>\n              <option value=\"pineapple\">\n                <span role=\"img\" aria-label=\"pineapple\">\n                  🍍\n                </span>{\" \"}\n                Pinapple\n              </option>\n            </Field>\n          </div>\n          <div>\n            <label>Best Stooge?</label>\n            <div>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"larry\"\n                />{\" \"}\n                Larry\n              </label>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"moe\"\n                />{\" \"}\n                Moe\n              </label>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"curly\"\n                />{\" \"}\n                Curly\n              </label>\n            </div>\n          </div>\n          <div>\n            <label>Notes</label>\n            <Field name=\"notes\" component=\"textarea\" placeholder=\"Notes\" />\n          </div>\n        </div>\n      )}\n    </Form>\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/auto-save-with-debounce/package.json",
    "content": "{\n  \"name\": \"react-final-form-auto-save-with-debounce\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use a FormSpy component to auto-save your form values with a debounce.\",\n  \"keywords\": [\n    \"final-form\",\n    \"autosave\",\n    \"form\",\n    \"debounce\",\n    \"react-final-form\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"object-diff\": \"0.0.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/auto-save-with-debounce/readme.md",
    "content": "# Auto-Save with Debounce\n\n[![Edit react-final-form-auto-save-with-debounce-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/5w4yrpyo7k)\n"
  },
  {
    "path": "examples/calculated-fields/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/calculated-fields/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport createDecorator from \"final-form-calculate\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst calculator = createDecorator(\n  {\n    field: \"minimum\", // when minimum changes...\n    updates: {\n      // ...update maximum to the result of this function\n      maximum: (minimumValue, allValues) =>\n        Math.max(minimumValue || 0, allValues.maximum || 0),\n    },\n  },\n  {\n    field: \"maximum\", // when maximum changes...\n    updates: {\n      // update minimum to the result of this function\n      minimum: (maximumValue, allValues) =>\n        Math.min(maximumValue || 0, allValues.minimum || 0),\n    },\n  },\n  {\n    field: /day\\[\\d\\]/, // when a field matching this pattern changes...\n    updates: {\n      // ...update the total to the result of this function\n      total: (ignoredValue, allValues) =>\n        (allValues.day || []).reduce(\n          (sum, value) => sum + Number(value || 0),\n          0,\n        ),\n    },\n  },\n);\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Calculated Fields</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      Change the minimum and maximum values with the arrow keys and notice that\n      the other updates so that minimum is always &lt;= maximum.\n    </p>\n    <p>\n      As you enter numbers for each day of the week, the total is calulated in\n      realtime.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      decorators={[calculator]}\n      render={({ handleSubmit, reset, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>Minimum</label>\n            <Field\n              name=\"minimum\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Minimum\"\n            />\n          </div>\n          <div>\n            <label>Maximum</label>\n            <Field\n              name=\"maximum\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Maximum\"\n            />\n          </div>\n          <hr />\n          <div>\n            <label>Monday</label>\n            <Field\n              name=\"day[0]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Monday\"\n            />\n          </div>\n          <div>\n            <label>Tuesday</label>\n            <Field\n              name=\"day[1]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Tuesday\"\n            />\n          </div>\n          <div>\n            <label>Wednesday</label>\n            <Field\n              name=\"day[2]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Wednesday\"\n            />\n          </div>\n          <div>\n            <label>Thursday</label>\n            <Field\n              name=\"day[3]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Thursday\"\n            />\n          </div>\n          <div>\n            <label>Friday</label>\n            <Field\n              name=\"day[4]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Friday\"\n            />\n          </div>\n          <hr />\n          <div>\n            <label>Total</label>\n            <Field\n              name=\"total\"\n              component=\"input\"\n              type=\"number\"\n              readOnly\n              placeholder=\"Total\"\n            />\n          </div>\n          <hr />\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/calculated-fields/package.json",
    "content": "{\n  \"name\": \"react-final-form-calculated-fields\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use the final-form-calculate decorator to achieve realtime field calculations.\",\n  \"keywords\": [],\n  \"homepage\": \"https://codesandbox.io/s/oq52p6v96y\",\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"final-form-calculate\": \"1.3.1\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/calculated-fields/readme.md",
    "content": "# Calculated Fields\n\n[![Edit react-final-form-calculated-fields-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/oq52p6v96y)\n"
  },
  {
    "path": "examples/chakra/index.js",
    "content": "/* eslint-disable jsx-a11y/accessible-emoji */\nimport React from \"react\";\nimport { render } from \"react-dom\";\nimport {\n  Box,\n  Button,\n  ButtonGroup,\n  CSSReset,\n  Heading,\n  Icon,\n  Link,\n  ThemeProvider,\n  theme,\n  FormControl,\n  FormLabel,\n  FormErrorMessage,\n  Input,\n  Checkbox,\n  Progress,\n  Radio,\n  RadioGroup,\n  Stack,\n  Textarea,\n} from \"@chakra-ui/core\";\nimport { Form, Field, useField, useForm } from \"react-final-form\";\nimport validate from \"./validate\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => (\n  <ThemeProvider theme={theme}>\n    <CSSReset />\n    <Box w={500} p={4} m=\"20px auto\">\n      <Heading as=\"h1\" size=\"xl\" textAlign=\"center\">\n        React Final Form\n      </Heading>\n      <Heading as=\"h2\" size=\"l\" textAlign=\"center\" m={5}>\n        Chakra Example\n      </Heading>\n      <Box as=\"p\" textAlign=\"center\">\n        Example using React Final Form and{\" \"}\n        <Link href=\"https://chakra-ui.com\" isExternal>\n          Chakra <Icon name=\"external-link\" mx=\"2px\" />\n        </Link>\n        .\n      </Box>\n      <Box as=\"p\" textAlign=\"center\">\n        <Link href=\"https://final-form.org/react\" isExternal>\n          Read Docs <Icon name=\"view\" mx=\"2px\" />\n        </Link>\n      </Box>\n      <Form\n        onSubmit={onSubmit}\n        validate={validate}\n        render={({\n          handleSubmit,\n          form,\n          errors,\n          submitting,\n          pristine,\n          values,\n        }) => (\n          <Box\n            as=\"form\"\n            p={4}\n            borderWidth=\"1px\"\n            rounded=\"lg\"\n            shadow=\"1px 1px 3px rgba(0,0,0,0.3)\"\n            onSubmit={handleSubmit}\n          >\n            {/* \n            This example uses a mixture of custom field components using useField() \n            and components adapted to take the { input, meta } structure <Field/>\n            provides\n            */}\n            <InputControl name=\"firstName\" label=\"First Name\" />\n            <InputControl name=\"lastName\" label=\"Last Name\" />\n            <CheckboxControl name=\"employed\">Employed</CheckboxControl>\n            <Field\n              name=\"favoriteColor\"\n              component={AdaptedRadioGroup}\n              label=\"Favorite Color\"\n            >\n              <Radio value=\"#ff0000\" color=\"red\">\n                Red\n              </Radio>\n              <Radio value=\"#00ff00\" color=\"green\">\n                Green\n              </Radio>\n              <Radio value=\"#0000ff\" color=\"blue\">\n                Blue\n              </Radio>\n            </Field>\n            <Control name=\"toppings\" my={4}>\n              <FormLabel htmlFor=\"toppings\">Toppings</FormLabel>\n              <Stack pl={6} mt={1} spacing={1}>\n                <CheckboxArrayControl name=\"toppings\" value=\"chicken\">\n                  🐓 Chicken\n                </CheckboxArrayControl>\n                <CheckboxArrayControl name=\"toppings\" value=\"ham\">\n                  🐷 Ham\n                </CheckboxArrayControl>\n                <CheckboxArrayControl name=\"toppings\" value=\"mushrooms\">\n                  🍄 Mushrooms\n                </CheckboxArrayControl>\n                <CheckboxArrayControl name=\"toppings\" value=\"cheese\">\n                  🧀 Cheese\n                </CheckboxArrayControl>\n                <CheckboxArrayControl name=\"toppings\" value=\"tuna\">\n                  🐟 Tuna\n                </CheckboxArrayControl>\n                <CheckboxArrayControl name=\"toppings\" value=\"pineapple\">\n                  🍍 Pineapple\n                </CheckboxArrayControl>\n              </Stack>\n              <Error name=\"toppings\" />\n            </Control>\n            <TextareaControl name=\"notes\" label=\"Notes\" />\n            <PercentComplete size=\"sm\" my={5} hasStripe isAnimated />\n            <ButtonGroup spacing={4}>\n              <Button\n                isLoading={submitting}\n                loadingText=\"Submitting\"\n                variantColor=\"teal\"\n                type=\"submit\"\n              >\n                Submit\n              </Button>\n              <Button\n                variantColor=\"teal\"\n                variant=\"outline\"\n                onClick={form.reset}\n                isDisabled={submitting || pristine}\n              >\n                Reset\n              </Button>\n            </ButtonGroup>\n            <Box as=\"pre\" my={10}>\n              {JSON.stringify(values, 0, 2)}\n            </Box>\n          </Box>\n        )}\n      />\n    </Box>\n  </ThemeProvider>\n);\n\nconst AdaptedTextarea = ({ input, meta, ...rest }) => (\n  <Textarea {...input} {...rest} isInvalid={meta.error && meta.touched} />\n);\n\nconst CheckboxControl = ({ name, value, children }) => {\n  const {\n    input: { checked, ...input },\n    meta: { error, touched, invalid },\n  } = useField(name, {\n    type: \"checkbox\", // important for RFF to manage the checked prop\n  });\n  return (\n    <FormControl isInvalid={touched && invalid} my={4}>\n      <Checkbox {...input} isInvalid={touched && invalid} my={4}>\n        {children}\n      </Checkbox>\n      <FormErrorMessage>{error}</FormErrorMessage>\n    </FormControl>\n  );\n};\n\nconst CheckboxArrayControl = ({ name, value, children }) => {\n  const {\n    input: { checked, ...input },\n    meta: { error, touched },\n  } = useField(name, {\n    type: \"checkbox\", // important for RFF to manage the checked prop\n    value, // important for RFF to manage list of strings\n  });\n  return (\n    <Checkbox {...input} isChecked={checked} isInvalid={error && touched}>\n      {children}\n    </Checkbox>\n  );\n};\n\nconst AdaptedRadioGroup = ({ input, meta, label, children }) => (\n  <FormControl isInvalid={meta.touched && meta.invalid} my={4}>\n    <FormLabel htmlFor={input.name}>{label}</FormLabel>\n    <RadioGroup {...input}>{children}</RadioGroup>\n    <FormErrorMessage>{meta.error}</FormErrorMessage>\n  </FormControl>\n);\n\nconst Control = ({ name, ...rest }) => {\n  const {\n    meta: { error, touched },\n  } = useField(name, { subscription: { touched: true, error: true } });\n  return <FormControl {...rest} isInvalid={error && touched} />;\n};\n\nconst Error = ({ name }) => {\n  const {\n    meta: { error },\n  } = useField(name, { subscription: { error: true } });\n  return <FormErrorMessage>{error}</FormErrorMessage>;\n};\n\nconst InputControl = ({ name, label }) => {\n  const { input, meta } = useField(name);\n  return (\n    <Control name={name} my={4}>\n      <FormLabel htmlFor={name}>{label}</FormLabel>\n      <Input\n        {...input}\n        isInvalid={meta.error && meta.touched}\n        id={name}\n        placeholder={label}\n      />\n      <Error name={name} />\n    </Control>\n  );\n};\n\nconst TextareaControl = ({ name, label }) => (\n  <Control name={name} my={4}>\n    <FormLabel htmlFor={name}>{label}</FormLabel>\n    <Field\n      name={name}\n      component={AdaptedTextarea}\n      placeholder={label}\n      id={name}\n    />\n    <Error name={name} />\n  </Control>\n);\n\nconst PercentComplete = (props) => {\n  const form = useForm();\n  const numFields = form.getRegisteredFields().length;\n  const numErrors = Object.keys(form.getState().errors).length;\n  return (\n    <Progress\n      value={numFields === 0 ? 0 : ((numFields - numErrors) / numFields) * 100}\n      {...props}\n    />\n  );\n};\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/chakra/package.json",
    "content": "{\n  \"name\": \"Chakra-Example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example form using Chakra UI\",\n  \"keywords\": [\n    \"state management\",\n    \"react-final-form\",\n    \"form\",\n    \"final-form\",\n    \"react\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"@chakra-ui/core\": \"^0.2.6\",\n    \"@emotion/core\": \"^10.0.17\",\n    \"@emotion/styled\": \"^10.0.17\",\n    \"emotion-theming\": \"^10.0.17\",\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"3.2.0\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\"\n  },\n  \"browserslist\": [\n    \">0.2%\",\n    \"not dead\",\n    \"not ie <= 11\",\n    \"not op_mini all\"\n  ]\n}\n"
  },
  {
    "path": "examples/chakra/readme.md",
    "content": "# Chakra UI Example\n\n[![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?fontsize=14)\n"
  },
  {
    "path": "examples/chakra/validate.js",
    "content": "const validate = (values) => {\n  const errors = {};\n  if (!values.firstName) {\n    errors.firstName = \"Required\";\n  }\n  if (!values.lastName) {\n    errors.lastName = \"Required\";\n  }\n  if (values.employed) {\n    errors.employed = \"We're only accepted unemployed applicants at the moment\";\n  }\n  if (!values.favoriteColor) {\n    errors.favoriteColor = \"Required\";\n  } else if (values.favoriteColor === \"#00ff00\") {\n    errors.favoriteColor = \"Not green! Gross!\";\n  }\n  if (!values.toppings || values.toppings.length < 2) {\n    errors.toppings = \"You need at least two toppings\";\n  } else if (values.toppings && values.toppings.length > 3) {\n    errors.toppings = \"No more than three toppings\";\n  }\n  if (!values.notes) {\n    errors.notes = \"Required\";\n  }\n  return errors;\n};\nexport default validate;\n"
  },
  {
    "path": "examples/conditional-fields/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > .downshift > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          margin-left: 0;\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n        &.downshift {\n          margin-left: 0;\n          padding-left: 15px;\n          flex: 1;\n          & > input {\n            width: 100%;\n            padding: 6px 5px;\n            font-size: 1em;\n            margin-left: 0;\n            border: 1px solid #ccc;\n            border-radius: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n  .downshift-options {\n    border: 1px solid #ddd;\n    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);\n    & > div {\n      padding: 3px 5px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/conditional-fields/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport pickupTimes from \"./pickupTimes\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst Error = ({ name }) => (\n  <Field name={name} subscription={{ error: true, touched: true }}>\n    {({ meta: { error, touched } }) =>\n      error && touched ? <span>{error}</span> : null\n    }\n  </Field>\n);\n\nconst Condition = ({ when, is, children }) => (\n  <Field name={when} subscription={{ value: true }}>\n    {({ input: { value } }) => (value === is ? children : null)}\n  </Field>\n);\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Conditional Fields</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      Sometimes you might want to conditionally show or hide some parts of your\n      form depending on values the user has already provided for other form\n      inputs.{\" \"}\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form makes that very easy to do by creating a{\" \"}\n      <code>Condition</code> component out of a <code>Field</code> component.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      initialValues={{ employed: true, stooge: \"larry\" }}\n      validate={(values) => {\n        const errors = {};\n        if (!values.firstName) {\n          errors.firstName = \"Required\";\n        }\n        if (!values.reception) {\n          errors.reception = \"Required\";\n        }\n        if (values.reception === \"delivery\") {\n          if (!values.street) {\n            errors.street = \"Required\";\n          }\n        } else if (values.reception === \"pickup\") {\n          if (!values.pickupTime) {\n            errors.pickupTime = \"Required\";\n          }\n        }\n        return errors;\n      }}\n    >\n      {({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n            />\n            <Error name=\"firstName\" />\n          </div>\n          <div>\n            <label>Transport</label>\n            <div>\n              <label>\n                <Field\n                  name=\"reception\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"delivery\"\n                />{\" \"}\n                Delivery\n              </label>\n              <label>\n                <Field\n                  name=\"reception\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"pickup\"\n                />{\" \"}\n                Pickup\n              </label>\n            </div>\n            <Error name=\"reception\" />\n          </div>\n          <Condition when=\"reception\" is=\"delivery\">\n            <div>\n              <label>Street</label>\n              <Field\n                name=\"street\"\n                component=\"input\"\n                type=\"text\"\n                placeholder=\"Street Address\"\n              />\n              <Error name=\"street\" />\n            </div>\n          </Condition>\n          <Condition when=\"reception\" is=\"pickup\">\n            <div>\n              <label>Pickup Time</label>\n              <Field name=\"pickupTime\" component=\"select\">\n                <option />$\n                {pickupTimes.map((time) => (\n                  <option key={time} value={time}>\n                    {time}\n                  </option>\n                ))}\n              </Field>\n              <Error name=\"pickupTime\" />\n            </div>\n          </Condition>\n          <div>\n            <label>Is it a gift?</label>\n            <Field name=\"gift\" component=\"input\" type=\"checkbox\" />\n          </div>\n          <Condition when=\"gift\" is={true}>\n            <div>\n              <label>Gift Message</label>\n              <Field\n                name=\"message\"\n                component=\"textarea\"\n                placeholder=\"Gift Message\"\n              />\n              <Error name=\"message\" />\n            </div>\n          </Condition>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button type=\"button\" onClick={form.reset} disabled={submitting}>\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    </Form>\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/conditional-fields/package.json",
    "content": "{\n  \"name\": \"react-final-form-conditional-fields\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to conditionally show or hide fields based on the values of other fields.\",\n  \"keywords\": [],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"3.0.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/conditional-fields/pickupTimes.js",
    "content": "// This is not the best way to do this. Don't think to hard about this.\nconst now = new Date();\nlet hours = now.getHours();\nconst times = [];\nif (now.getMinutes() < 30) {\n  times.push(`${++hours}:30`);\n} else {\n  hours++;\n}\nwhile (times.length < 6) {\n  times.push(`${hours}:00`);\n  times.push(`${hours}:30`);\n  hours = (hours + 1) % 24;\n}\nexport default times;\n"
  },
  {
    "path": "examples/conditional-fields/readme.md",
    "content": "# Conditional Fields\n\n[![Edit react-final-form-conditional-fields-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/lm4p3m92q)\n"
  },
  {
    "path": "examples/credit-card/Card.js",
    "content": "import React from \"react\";\nimport styled from \"styled-components\";\nimport Cards from \"react-credit-cards\";\n\nconst Container = styled.div`\n  .rccs {\n    margin: 0 auto;\n    -webkit-perspective: 1000px;\n    perspective: 1000px;\n    width: 290px;\n  }\n  .rccs__card {\n    height: 182.873px;\n    margin: 0 auto;\n    position: relative;\n    -webkit-transform-style: preserve-3d;\n    transform-style: preserve-3d;\n    -webkit-transition: all 0.4s linear;\n    transition: all 0.4s linear;\n    width: 290px;\n  }\n  .rccs__card--front,\n  .rccs__card--back {\n    -webkit-backface-visibility: hidden;\n    backface-visibility: hidden;\n    background: linear-gradient(25deg, #939393, #717171);\n    border-radius: 14.5px;\n    color: #fff;\n    height: 100%;\n    left: 0;\n    overflow: hidden;\n    position: absolute;\n    top: 0;\n    -webkit-transform-style: preserve-3d;\n    transform-style: preserve-3d;\n    width: 100%;\n    -webkit-box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);\n    box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);\n  }\n  .rccs__card--front {\n    z-index: 20;\n  }\n  .rccs__card--back {\n    -webkit-transform: rotateY(180deg);\n    transform: rotateY(180deg);\n  }\n  .rccs__card--back .rccs__issuer {\n    background-position: bottom center;\n    bottom: 5%;\n    left: 50%;\n    opacity: 0.6;\n    right: auto;\n    top: auto;\n    -webkit-transform: translateX(-50%);\n    transform: translateX(-50%);\n  }\n  .rccs__card__background {\n    height: 200%;\n    left: -170%;\n    position: absolute;\n    top: -60%;\n    -webkit-transform: rotate(25deg);\n    transform: rotate(25deg);\n    -webkit-transition: all 0.5s ease-out;\n    transition: all 0.5s ease-out;\n    width: 150%;\n    left: -170%;\n  }\n  .rccs__card--flipped {\n    -webkit-transform: rotateY(180deg);\n    transform: rotateY(180deg);\n  }\n  .rccs__card--flipped .rccs__card--front {\n    z-index: 10;\n  }\n  .rccs__card--flipped .rccs__card--back {\n    z-index: 20;\n  }\n  .rccs__card--unknown > div {\n    background: linear-gradient(25deg, #999, #999);\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n  .rccs__card--unknown .rccs__issuer {\n    visibility: hidden;\n  }\n  .rccs__card:not(.rccs__card--unknown) .rccs__card__background {\n    left: -22%;\n  }\n  .rccs__card--amex .rccs__card__background {\n    background: linear-gradient(25deg, #308c67, #a3f2cf);\n  }\n  .rccs__card--amex .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxkZWZzPjxyYWRpYWxHcmFkaWVudCBjeD0iMTcuNTQxJSIgY3k9IjE3LjQ2NiUiIGZ4PSIxNy41NDElIiBmeT0iMTcuNDY2JSIgcj0iOTEuMjM3JSIgaWQ9ImEiPjxzdG9wIHN0b3AtY29sb3I9IiM2NUJDRjEiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjMjNBREUzIiBvZmZzZXQ9IjQ1LjQ2JSIvPjxzdG9wIHN0b3AtY29sb3I9IiMwREE2RTAiIG9mZnNldD0iNTAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iIzA1NTFDMyIgb2Zmc2V0PSIxMDAlIi8+PC9yYWRpYWxHcmFkaWVudD48L2RlZnM+PHBhdGggZmlsbD0idXJsKCNhKSIgZD0iTTAgMGg1MTJ2NTEyaC01MTJ6Ii8+PHBhdGggZD0iTTQ1Ljc5MSAyMjAuOTM1bC05Ljc3My0yMy44MTMtOS43MTcgMjMuODEzaDE5LjQ4OXptMjE1LjI4OS05LjQ4M2MtMS45NjIgMS4xOTEtNC4yODMgMS4yMzEtNy4wNjMgMS4yMzFoLTE3LjM0NXYtMTMuMjY4aDE3LjU4MWMyLjQ4OCAwIDUuMDg0LjExMiA2Ljc3MSAxLjA3NyAxLjg1Mi44NyAyLjk5OCAyLjcyMiAyLjk5OCA1LjI4MSAwIDIuNjExLTEuMDkgNC43MTItMi45NDIgNS42Nzl6bTEyMy43MzkgOS40ODNsLTkuODgxLTIzLjgxMy05LjgyNyAyMy44MTNoMTkuNzA3em0tMjMwLjY1OCAyNS43NzZoLTE0LjYzN2wtLjA1NC00Ni43ODQtMjAuNzA0IDQ2Ljc4NGgtMTIuNTM2bC0yMC43NTgtNDYuODI1djQ2LjgyNWgtMjkuMDRsLTUuNDg2LTEzLjMyNGgtMjkuNzI5bC01LjU0MiAxMy4zMjRoLTE1LjUwN2wyNS41NjgtNTkuNzM1aDIxLjIxNGwyNC4yODQgNTYuNTU2di01Ni41NTZoMjMuMzA0bDE4LjY4NiA0MC41MjMgMTcuMTY1LTQwLjUyM2gyMy43NzJ2NTkuNzM1aC4wMDJ6bTU4LjMzOCAwaC00Ny42OTd2LTU5LjczNWg0Ny42OTd2MTIuNDM5aC0zMy40MTl2MTAuNzY3aDMyLjYxN3YxMi4yNDVoLTMyLjYxN3YxMS45MjloMzMuNDE5djEyLjM1NHptNjcuMjUxLTQzLjY0N2MwIDkuNTI0LTYuMzU3IDE0LjQ0NC0xMC4wNjEgMTUuOTIyIDMuMTI0IDEuMTg5IDUuNzkzIDMuMjkgNy4wNjMgNS4wMyAyLjAxNiAyLjk3MSAyLjM2NCA1LjYyNSAyLjM2NCAxMC45NnYxMS43MzVoLTE0LjQwMWwtLjA1NC03LjUzM2MwLTMuNTk0LjM0NC04Ljc2NC0yLjI1NC0xMS42MzctMi4wODYtMi4xMDEtNS4yNjYtMi41NTctMTAuNDA3LTIuNTU3aC0xNS4zMjd2MjEuNzI3aC0xNC4yNzd2LTU5LjczNWgzMi44NGM3LjI5NyAwIDEyLjY3My4xOTMgMTcuMjg5IDIuODYxIDQuNTE3IDIuNjY4IDcuMjI1IDYuNTY0IDcuMjI1IDEzLjIyN3ptMjIuODUgNDMuNjQ3aC0xNC41Njl2LTU5LjczNWgxNC41Njl2NTkuNzM1em0xNjkuMDE3IDBoLTIwLjIzM2wtMjcuMDY0LTQ0LjgzNHY0NC44MzRoLTI5LjA3OGwtNS41NTctMTMuMzI0aC0yOS42NmwtNS4zOTEgMTMuMzI0aC0xNi43MDdjLTYuOTQgMC0xNS43MjctMS41MzUtMjAuNzA0LTYuNjA3LTUuMDE4LTUuMDcyLTcuNjI5LTExLjk0Mi03LjYyOS0yMi44MDUgMC04Ljg1OSAxLjU2LTE2Ljk1OCA3LjY5Ny0yMy4zNTggNC42MTYtNC43NjcgMTEuODQ1LTYuOTY1IDIxLjY4NC02Ljk2NWgxMy44MjN2MTIuNzk5aC0xMy41MzNjLTUuMjExIDAtOC4xNTMuNzc1LTEwLjk4NyAzLjUzOS0yLjQzNCAyLjUxNS00LjEwNCA3LjI3LTQuMTA0IDEzLjUzMSAwIDYuNCAxLjI3MiAxMS4wMTQgMy45MjYgMTQuMDI4IDIuMTk4IDIuMzY0IDYuMTkzIDMuMDgxIDkuOTUxIDMuMDgxaDYuNDEybDIwLjEyNC00Ni45NzdoMjEuMzk0bDI0LjE3NCA1Ni41di01Ni41aDIxLjc0bDI1LjA5OCA0MS42MDJ2LTQxLjYwMmgxNC42MjV2NTkuNzMzem0tNDcxLjYxNiAxMS43MzNoMjQuMzk1bDUuNTAxLTEzLjI2OGgxMi4zMTVsNS40ODYgMTMuMjY4aDQ4di0xMC4xNDRsNC4yODUgMTAuMTg3aDI0LjkxOGw0LjI4NS0xMC4zMzh2MTAuMjk1aDExOS4yODlsLS4wNTYtMjEuNzc5aDIuMzA4YzEuNjE2LjA1NiAyLjA4OC4yMDUgMi4wODggMi44NzR2MTguOTA2aDYxLjY5N3YtNS4wN2M0Ljk3NiAyLjY2NyAxMi43MTcgNS4wNyAyMi45MDIgNS4wN2gyNS45NTZsNS41NTUtMTMuMjY4aDEyLjMxNWw1LjQzMiAxMy4yNjhoNTAuMDE4di0xMi42MDNsNy41NzQgMTIuNjAzaDQwLjA4MXYtODMuMzEyaC0zOS42Njd2OS44MzlsLTUuNTU1LTkuODM5aC00MC43MDN2OS44MzlsLTUuMTAxLTkuODM5aC01NC45OGMtOS4yMDMgMC0xNy4yOTMgMS4yODUtMjMuODI4IDQuODY1di00Ljg2NWgtMzcuOTQxdjQuODY1Yy00LjE1OC0zLjY5LTkuODI1LTQuODY1LTE2LjEyNS00Ljg2NWgtMTM4LjYxM2wtOS4zMDEgMjEuNTE4LTkuNTUxLTIxLjUxOGgtNDMuNjZ2OS44MzlsLTQuNzk2LTkuODM5aC0zNy4yMzVsLTE3LjI5MSAzOS42MTF2NDMuNzAxaC4wMDJ6TTUxMiAzMDIuMDE0aC0yNi4wMzljLTIuNiAwLTQuMzI3LjA5Ny01Ljc4MiAxLjA4LTEuNTA3Ljk2OC0yLjA4OCAyLjQwNS0yLjA4OCA0LjMwMiAwIDIuMjU1IDEuMjczIDMuNzkgMy4xMjQgNC40NTMgMS41MDcuNTI1IDMuMTI2LjY3OCA1LjUwNi42NzhsNy43NDMuMjA3YzcuODE0LjE5MyAxMy4wMjkgMS41MzYgMTYuMjA5IDQuODEyLjU3OS40NTYuOTI3Ljk2OCAxLjMyNSAxLjQ4di0xNy4wMTJ6bTAgMzkuNDE2Yy0zLjQ3IDUuMDc1LTEwLjIzMyA3LjY0OC0xOS4zODggNy42NDhoLTI3LjU5MXYtMTIuODJoMjcuNDc5YzIuNzI2IDAgNC42MzMtLjM1OSA1Ljc4Mi0xLjQ4Ljk5NS0uOTI1IDEuNjg5LTIuMjY4IDEuNjg5LTMuOSAwLTEuNzQyLS42OTQtMy4xMjQtMS43NDUtMy45NTQtMS4wMzctLjkxMi0yLjU0Ni0xLjMyNy01LjAzNC0xLjMyNy0xMy40MTUtLjQ1Ni0zMC4xNTEuNDE1LTMwLjE1MS0xOC41MDQgMC04LjY3MiA1LjUwNi0xNy44IDIwLjQ5OC0xNy44aDI4LjQ1OHYtMTEuODk1aC0yNi40NDFjLTcuOTc5IDAtMTMuNzc2IDEuOTExLTE3Ljg4MSA0Ljg4MnYtNC44ODJoLTM5LjEwOWMtNi4yNTQgMC0xMy41OTUgMS41NS0xNy4wNjggNC44ODJ2LTQuODgyaC02OS44Mzl2NC44ODJjLTUuNTU4LTQuMDEtMTQuOTM3LTQuODgyLTE5LjI2NS00Ljg4MmgtNDYuMDY2djQuODgyYy00LjM5Ny00LjI1OC0xNC4xNzYtNC44ODItMjAuMTM2LTQuODgyaC01MS41NTZsLTExLjc5OCAxMi43NjgtMTEuMDUtMTIuNzY4aC03Ny4wMTR2ODMuNDIxaDc1LjU2NWwxMi4xNTctMTIuOTcgMTEuNDUyIDEyLjk3IDQ2LjU3OC4wNDF2LTE5LjYyNGg0LjU3OWM2LjE4LjA5NiAxMy40NjktLjE1MyAxOS45LTIuOTMzdjIyLjUxNGgzOC40MTl2LTIxLjc0MmgxLjg1M2MyLjM2NSAwIDIuNTk4LjA5NyAyLjU5OCAyLjQ2MXYxOS4yOGgxMTYuNzA5YzcuNDEgMCAxNS4xNTUtMS44OTcgMTkuNDQ0LTUuMzM4djUuMzM4aDM3LjAyYzcuNzA0IDAgMTUuMjI3LTEuMDggMjAuOTUxLTMuODQ1di0xNS41NDF6bS01Ni45OS0yMy44ODRjMi43ODIgMi44NzkgNC4yNzMgNi41MTQgNC4yNzMgMTIuNjY3IDAgMTIuODYyLTguMDM1IDE4Ljg2NS0yMi40NDQgMTguODY1aC0yNy44Mjd2LTEyLjgyaDI3LjcxNWMyLjcxIDAgNC42MzItLjM1OSA1LjgzNi0xLjQ4Ljk4My0uOTI1IDEuNjg3LTIuMjY4IDEuNjg3LTMuOSAwLTEuNzQyLS43NjMtMy4xMjQtMS43NDMtMy45NTQtMS4wOTMtLjkxMi0yLjYtMS4zMjctNS4wODgtMS4zMjctMTMuMzYxLS40NTYtMzAuMDkzLjQxNS0zMC4wOTMtMTguNTA0IDAtOC42NzIgNS40NDgtMTcuOCAyMC40MjYtMTcuOGgyOC42NDJ2MTIuNzI1aC0yNi4yMDhjLTIuNTk4IDAtNC4yODcuMDk3LTUuNzI0IDEuMDgtMS41NjUuOTY4LTIuMTQ1IDIuNDA1LTIuMTQ1IDQuMzAyIDAgMi4yNTUgMS4zMjkgMy43OSAzLjEyNiA0LjQ1MyAxLjUwNy41MjUgMy4xMjYuNjc4IDUuNTYuNjc4bDcuNjkxLjIwN2M3Ljc1Ni4xODkgMTMuMDggMS41MzEgMTYuMzE2IDQuODA4em0tMTI4LjkxOC0zLjY5MmMtMS45MTEgMS4xMzQtNC4yNzUgMS4yMzEtNy4wNTUgMS4yMzFoLTE3LjM1NnYtMTMuNDI4aDE3LjU5MmMyLjU0NCAwIDUuMDg5LjA1NCA2LjgxOCAxLjA4IDEuODUyLjk2OCAyLjk1OCAyLjgyIDIuOTU4IDUuMzc4IDAgMi41NTgtMS4xMDcgNC42MTktMi45NTggNS43Mzh6bTguNjI4IDcuNDRjMy4xOCAxLjE3NCA1Ljc4IDMuMjc4IDYuOTk5IDUuMDE5IDIuMDE3IDIuOTE5IDIuMzA5IDUuNjQzIDIuMzY3IDEwLjkxM3YxMS44NTJoLTE0LjM0M3YtNy40OGMwLTMuNTk3LjM0Ni04LjkyMi0yLjMwOS0xMS43MDItMi4wODgtMi4xNDItNS4yNy0yLjY1NC0xMC40ODItMi42NTRoLTE1LjI2OHYyMS44MzZoLTE0LjM1NnYtNTkuNzg2aDMyLjk4NWM3LjIzMyAwIDEyLjUwMS4zMTkgMTcuMTkgMi44MjEgNC41MDkgMi43MjQgNy4zNDUgNi40NTYgNy4zNDUgMTMuMjc2LS4wMDIgOS41NDItNi4zNjYgMTQuNDEyLTEwLjEyNyAxNS45MDV6bTE4LjA0OC0zMi4wMDJoNDcuNjg0djEyLjM2NGgtMzMuNDU1djEwLjg2OWgzMi42Mzl2MTIuMTk4aC0zMi42Mzl2MTEuODk1bDMzLjQ1NS4wNTR2MTIuNDA1aC00Ny42ODR2LTU5Ljc4NnptLTk2LjM5MyAyNy41OTFoLTE4LjQ2M3YtMTUuMjI1aDE4LjYyOWM1LjE1OCAwIDguNzM4IDIuMTAyIDguNzM4IDcuMzMgMCA1LjE3MS0zLjQxNSA3Ljg5NS04LjkwNCA3Ljg5NXptLTMyLjY5MyAyNi43NThsLTIxLjkzNS0yNC4zNTMgMjEuOTM1LTIzLjU3OXY0Ny45MzJ6bS01Ni42NDctNy4wMjJoLTM1LjEyN3YtMTEuODk1aDMxLjM2NnYtMTIuMTk4aC0zMS4zNjZ2LTEwLjg2OWgzNS44MTlsMTUuNjI3IDE3LjQyMy0xNi4zMTkgMTcuNTR6bTExMy41ODMtMjcuNjNjMCAxNi42MDgtMTIuMzkxIDIwLjAzNy0yNC44NzkgMjAuMDM3aC0xNy44Mjd2MjAuMDUzaC0yNy43NjlsLTE3LjU5Mi0xOS43OTItMTguMjgzIDE5Ljc5MmgtNTYuNTkxdi01OS43ODZoNTcuNDYybDE3LjU3OCAxOS41OTcgMTguMTczLTE5LjU5N2g0NS42NTJjMTEuMzM4IDAgMjQuMDc3IDMuMTM5IDI0LjA3NyAxOS42OTZ6IiBmaWxsPSIjZmZmIi8+PC9zdmc+\");\n  }\n  .rccs__card--amex .rccs__cvc__front {\n    opacity: 0.5;\n    visibility: visible;\n  }\n  .rccs__card--dankort .rccs__card__background {\n    background: linear-gradient(25deg, #ccc, #999);\n  }\n  .rccs__card--dankort .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjMwOCIgdmlld0JveD0iMCAwIDUxMiAzMDgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxkZWZzPjxsaW5lYXJHcmFkaWVudCB4MT0iNTAlIiB5MT0iMCUiIHgyPSI1MCUiIHkyPSIxMDAlIiBpZD0iYSI+PHN0b3Agc3RvcC1jb2xvcj0iI0Y1MDkxQSIgb2Zmc2V0PSIwJSIvPjxzdG9wIHN0b3AtY29sb3I9IiM5RTBDMTciIG9mZnNldD0iMTAwJSIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxwYXRoIGQ9Ik0zNTguNDA3IDBoLTIwNC43OTVjLTg0Ljg0MiAwLTE1My42MTIgNjguNzcxLTE1My42MTIgMTUzLjU5MyAwIDg0Ljg1MSA2OC43NyAxNTMuNjA2IDE1My42MTIgMTUzLjYwNmgyMDQuNzk1Yzg0LjgyMiAwIDE1My41OTMtNjguNzU1IDE1My41OTMtMTUzLjYwNiAwLTg0LjgyMS02OC43Ny0xNTMuNTkzLTE1My41OTMtMTUzLjU5MyIgZmlsbD0iI0ZFRkVGRSIvPjxwYXRoIGQ9Ik0zOTUuNTkxIDE0NC40ODZsNjguMzI4IDgxLjI2MWMxNC4xNTEtMjAuNDUxIDIyLjQ2Mi00NS4yNDIgMjIuNDYyLTcxLjk0NSAwLTI4LjE4My05LjI1OS01NC4yNDgtMjQuODg0LTc1LjMxNWwtNjUuOTA2IDY1Ljk5OXptLTI0MS4zOTctMTE3LjM4NmMtMzguNTQ3IDAtNzMuMTIxIDE3LjI5My05Ni4zODMgNDQuNTI4aDE0NC4xNTljNTEuMDI3IDAgODkuNDc0IDEyLjk4MyA5My40MzEgNTUuOTc0bDUzLjcwMi01NS45ODFoMTA2LjkzMWMtMjMuMjYzLTI3LjIyNy01Ny44MzEtNDQuNTItOTYuMzYxLTQ0LjUyaC0yMDUuNDc5em0yOS4yMzYgMjA1LjQ3OWgtMTI4LjQyOWMyMy4yMzMgMjkuMTkzIDU5LjA2MiA0Ny45NDYgOTkuMTk0IDQ3Ljk0NmgyMDUuNDc5YzQwLjExNyAwIDc1LjkzNy0xOC43NDUgOTkuMTcxLTQ3LjkzOWgtMTA5LjI5NWwtNTYuNzk2LTcxLjc3NmMtMTAuNTA2IDQ4LjkzOS00NC44ODEgNzEuNzY5LTEwOS4zMjMgNzEuNzY5ek0xMTguNDQgMTI1Ljk5N2wtMTguMjIyIDUwLjFoNzMuNTE3YzIxLjczMyAwIDI4LjMxLTguOTk4IDMzLjE3My0yNi4zMTkgNC44MTUtMTcuMTMxLTcuMjc3LTIzLjc4LTIyLjEyOS0yMy43OGgtNjYuMzM5eiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg==\");\n  }\n  .rccs__card--dinersclub > div {\n    color: #555;\n  }\n  .rccs__card--dinersclub .rccs__card__background {\n    background: linear-gradient(25deg, #fff, #eee);\n  }\n  .rccs__card--dinersclub .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjEzNCIgdmlld0JveD0iMCAwIDUxMiAxMzQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxwYXRoIGQ9Ik05OS4yODUgMTMzLjg2YzM2LjQ0Ni4xNzcgNjkuNzE1LTI5LjY1OSA2OS43MTUtNjUuOTU1IDAtMzkuNjg5LTMzLjI2OS02Ny4xMjItNjkuNzE1LTY3LjExMWgtMzEuMzY1Yy0zNi44ODItLjAxMS02Ny4yNDEgMjcuNDI5LTY3LjI0MSA2Ny4xMTEgMCAzNi4zMDUgMzAuMzU4IDY2LjEzMyA2Ny4yNDEgNjUuOTU1aDMxLjM2NSIgZmlsbD0iIzAwNjA5NSIvPjxwYXRoIGQ9Ik04MS45MDkgMTAzLjI0N3YtNzIuMDcyYzE0LjUxNyA1LjU1NyAyNC44MjMgMTkuNTgzIDI0Ljg0NyAzNi4wMzMtLjAyNCAxNi40NTQtMTAuMzMgMzAuNDcxLTI0Ljg0NyAzNi4wMzhtLTUyLjUyMi0zNi4wMzhjLjAzMy0xNi40NDEgMTAuMzIyLTMwLjQ1OCAyNC44MzEtMzYuMDMydjcyLjA1NWMtMTQuNTA5LTUuNTY5LTI0Ljc5OC0xOS41NzgtMjQuODMxLTM2LjAyNG0zOC42NzktNjAuOTE1Yy0zMy43MDIuMDExLTYxLjAxMSAyNy4yNzMtNjEuMDIgNjAuOTE1LjAwOCAzMy42MzkgMjcuMzE4IDYwLjg5NSA2MS4wMiA2MC45MDUgMzMuNzEzLS4wMSA2MS4wMjgtMjcuMjY2IDYxLjAzMy02MC45MDUtLjAwNS0zMy42NDItMjcuMzE5LTYwLjkwNC02MS4wMzMtNjAuOTE1IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTE5MC4zNzMgMjkuNDIxYzAtNi4yOTQtMy4yOTEtNS44ODEtNi40NDQtNS45NDd2LTEuODE5YzIuNzMzLjEzMyA1LjUzNi4xMzMgOC4yNzUuMTMzIDIuOTQzIDAgNi45NDEtLjEzMyAxMi4xMzMtLjEzMyAxOC4xNTcgMCAyOC4wNDIgMTIuMTAzIDI4LjA0MiAyNC40OTYgMCA2LjkyOS00LjA2MyAyNC4zNTMtMjguODg4IDI0LjM1My0zLjU3MyAwLTYuODc0LS4xMzgtMTAuMTY3LS4xMzgtMy4xNTMgMC02LjI0Mi4wNjctOS4zOTUuMTM4di0xLjgyYzQuMjAzLS40MjEgNi4yNDItLjU2MSA2LjQ0NC01LjMydi0zMy45NDN6bTYuODczIDMyLjgyNWMwIDUuMzg4IDMuODYxIDYuMDE3IDcuMjk0IDYuMDE3IDE1LjE0OSAwIDIwLjEyNC0xMS40MDcgMjAuMTI0LTIxLjgzNiAwLTEzLjA4My04LjQxNS0yMi41My0yMS45NDctMjIuNTMtMi44NzkgMC00LjIwMy4yMDUtNS40NzIuMjh2MzguMDY4em0zNy41OTIgNi40NGgxLjMzMWMxLjk2MSAwIDMuMzY1IDAgMy4zNjUtMi4zMTV2LTE4Ljk2MmMwLTMuMDc3LTEuMDUtMy41MDQtMy42NDgtNC44OTZ2LTEuMTIyYzMuMjk2LS45ODUgNy4yMjYtMi4zMDggNy41MDMtMi41MTguNDkzLS4yOC45MTItLjM1NCAxLjI2NC0uMzU0LjM0NyAwIC40OTIuNDIxLjQ5Mi45ODV2MjYuODY2YzAgMi4zMTUgMS41NDIgMi4zMTUgMy41MDggMi4zMTVoMS4xODl2MS44MmMtMi4zODYgMC00Ljg0Mi0uMTQtNy4zNi0uMTQtMi41MjYgMC01LjA1Mi4wNjgtNy42NDMuMTR2LTEuODJ6bTcuNTAzLTQwLjk0Yy0xLjgyNyAwLTMuNDM2LTEuNjc5LTMuNDM2LTMuNDk5IDAtMS43NTIgMS42ODYtMy4zNjYgMy40MzYtMy4zNjYgMS44MTcgMCAzLjQzNSAxLjQ3NiAzLjQzNSAzLjM2NiAwIDEuODkyLTEuNTQ2IDMuNDk5LTMuNDM1IDMuNDk5em0xNC4xNjIgMjAuMDgyYzAtMi41ODgtLjc3NS0zLjI4NS00LjA2My00LjYxNXYtMS4zM2MzLjAxMS0uOTc4IDUuODg0LTEuODkyIDkuMjU0LTMuMzYzLjIwOCAwIC40MTQuMTQzLjQxNC42OTl2NC41NTFjNC4wMDMtMi44NjYgNy40NDEtNS4yNSAxMi4xNDQtNS4yNSA1Ljk1NiAwIDguMDU4IDQuMzQgOC4wNTggOS44djE4LjA1MmMwIDIuMzE1IDEuNTQxIDIuMzE1IDMuNTA2IDIuMzE1aDEuMjYydjEuODJjLTIuNDU5IDAtNC45MTMtLjE0LTcuNDMxLS4xNC0yLjUyOCAwLTUuMDUzLjA2OC03LjU3Ni4xNHYtMS44MmgxLjI2MWMxLjk2NyAwIDMuMzYzIDAgMy4zNjMtMi4zMTV2LTE4LjEyYzAtMy45OTQtMi40NDMtNS45NDktNi40NDYtNS45NDktMi4yNDMgMC01LjgxOSAxLjgxNy04LjE0MSAzLjM1OHYyMC43MTFjMCAyLjMxNSAxLjU1MiAyLjMxNSAzLjUxNiAyLjMxNWgxLjI2MXYxLjgyYy0yLjQ1NCAwLTQuOTEyLS4xNC03LjQzNi0uMTQtMi41MjEgMC01LjA1LjA2OC03LjU3MS4xNHYtMS44MmgxLjI2NWMxLjk2MiAwIDMuMzYxIDAgMy4zNjEtMi4zMTV2LTE4LjU0NHptMzUuOTA3IDMuMzY1Yy0uMTQ1LjYzMS0uMTQ1IDEuNjc3IDAgNC4wNTkuNDEyIDYuNjQ2IDQuNzAyIDEyLjEwMyAxMC4zMDIgMTIuMTAzIDMuODYzIDAgNi44ODItMi4xIDkuNDctNC42ODZsLjk4Ljk4Yy0zLjIyNiA0LjI3LTcuMjI0IDcuOTA4LTEyLjk2OCA3LjkwOC0xMS4xNTQgMC0xMy4zOTUtMTAuNzgtMTMuMzk1LTE1LjI1NiAwLTEzLjcxOCA5LjI1Mi0xNy43NzkgMTQuMTU3LTE3Ljc3OSA1LjY4NSAwIDExLjc5MSAzLjU2OCAxMS44NTMgMTAuOTg2IDAgLjQyNiAwIC44NC0uMDYyIDEuMjY1bC0uNjM3LjQyMWgtMTkuNzAxem0xMi40MTMtMi4yNDFjMS43NTIgMCAxLjk1Ni0uOTEyIDEuOTU2LTEuNzUxIDAtMy41NjgtMi4xNzEtNi40MzctNi4xMDEtNi40MzctNC4yNzUgMC03LjIxOSAzLjE0Mi04LjA2IDguMTg3aDEyLjIwNXptOS42MDQgMTkuNzM2aDEuODk0YzEuOTU2IDAgMy4zNiAwIDMuMzYtMi4zMTV2LTE5LjY2MWMwLTIuMTY4LTIuNTkxLTIuNTkxLTMuNjQ1LTMuMTV2LTEuMDQ3YzUuMTE5LTIuMTcyIDcuOTI1LTMuOTk0IDguNTY1LTMuOTk0LjQxMiAwIC42Mi4yMS42Mi45MTN2Ni4yOTdoLjE1YzEuNzQ2LTIuNzI5IDQuNjk3LTcuMjEgOC45NzItNy4yMSAxLjc1NCAwIDMuOTk1IDEuMTg4IDMuOTk1IDMuNzA5IDAgMS44OS0xLjMyOSAzLjU3NC0zLjI5MSAzLjU3NC0yLjE4MiAwLTIuMTgyLTEuNjg0LTQuNjMzLTEuNjg0LTEuMTk0IDAtNS4xMTkgMS42MTEtNS4xMTkgNS44MTJ2MTYuNDM5YzAgMi4zMTUgMS4zOTkgMi4zMTUgMy4zNjUgMi4zMTVoMy45MjV2MS44MmMtMy44NTgtLjA3Mi02Ljc5My0uMTQtOS44MTItLjE0LTIuODc0IDAtNS44MjEuMDY4LTguMzQ1LjE0di0xLjgyem0yNi45OTUtNy45MTFjLjkxNCA0LjYxOCAzLjcxNiA4LjU0IDguODM4IDguNTQgNC4xMyAwIDUuNjcyLTIuNTE5IDUuNjcyLTQuOTY3IDAtOC4yNi0xNS4yODEtNS42MDMtMTUuMjgxLTE2Ljg2NyAwLTMuOTIyIDMuMTU5LTguOTYxIDEwLjg2OS04Ljk2MSAyLjI0MSAwIDUuMjU1LjYzMiA3Ljk4OCAyLjAzM2wuNDk1IDcuMTMyaC0xLjYxNGMtLjctNC40MDUtMy4xNTMtNi45MjQtNy42NDMtNi45MjQtMi44MDggMC01LjQ2OSAxLjYwOS01LjQ2OSA0LjYxOCAwIDguMTk0IDE2LjI2OCA1LjY2OSAxNi4yNjggMTYuNjU1IDAgNC42MTgtMy43MTYgOS41MjItMTIuMDYzIDkuNTIyLTIuODA0IDAtNi4xMDEtLjk4Mi04LjU1Mi0yLjM4bC0uNzc0LTguMDQ5IDEuMjY0LS4zNTN6bTgzLjQ0Mi0yNi40NTVoLTEuNzQ5Yy0xLjMzNS04LjE4Mi03LjE1Ni0xMS40NzUtMTUuMDA2LTExLjQ3NS04LjA2OCAwLTE5Ljc4MSA1LjM4Ny0xOS43ODEgMjIuMTgyIDAgMTQuMTQ0IDEwLjEwNSAyNC4yODggMjAuOSAyNC4yODggNi45MzkgMCAxMi42OTUtNC43NTggMTQuMDk5LTEyLjEwOWwxLjYwOS40MTktMS42MDkgMTAuMjE3Yy0yLjk0NiAxLjgyNS0xMC44NzEgMy43MTItMTUuNTAyIDMuNzEyLTE2LjQwMyAwLTI2Ljc3OS0xMC41NjgtMjYuNzc5LTI2LjMxNSAwLTE0LjM0NyAxMi44MjgtMjQuNjM4IDI2LjU3Mi0yNC42MzggNS42NzcgMCAxMS4xNDkgMS44MjUgMTYuNTQ2IDMuNzE2bC43IDEwLjAwM3ptMi41MjkgMzQuMzY2aDEuMzI2YzEuOTY5IDAgMy4zNzMgMCAzLjM3My0yLjMxNXYtMzguOTc0YzAtNC41NTMtMS4wNTItNC42OTMtMy43MTYtNS40NjF2LTEuMTJjMi44MDMtLjkwOSA1Ljc0OS0yLjE2OCA3LjIyMS0zLjAxMi43NjUtLjQxNiAxLjMzMS0uNzcyIDEuNTM3LS43NzIuNDI3IDAgLjU2OC40MjQuNTY4Ljk4NXY0OC4zNTRjMCAyLjMxNSAxLjU0MSAyLjMxNSAzLjUwNiAyLjMxNWgxLjE4NHYxLjgyYy0yLjM3NiAwLTQuODMyLS4xNC03LjM1Ni0uMTQtMi41MjMgMC01LjA0Ny4wNjgtNy42NDMuMTR2LTEuODJ6bTQ1LjAyMi0yLjAzM2MwIDEuMjY1Ljc2OSAxLjMzMSAxLjk1OSAxLjMzMWwyLjgwNi0uMDY3djEuNDczYy0zLjAxOS4yNzgtOC43NjcgMS43NDctMTAuMSAyLjE2N2wtLjM1My0uMjExdi01LjY2NmMtNC4yIDMuNDI4LTcuNDMxIDUuODc3LTEyLjQxNSA1Ljg3Ny0zLjc4MyAwLTcuNzEtMi40NDktNy43MS04LjMyNXYtMTcuOTJjMC0xLjgyLS4yNzgtMy41NzEtNC4yMDItMy45MTl2LTEuMzMxYzIuNTI4LS4wNjggOC4xMjgtLjQ4OCA5LjA0My0uNDg4Ljc3NyAwIC43NzcuNDg4Ljc3NyAyLjAyOHYxOC4wNTJjMCAyLjEwMyAwIDguMTIgNi4wOTYgOC4xMiAyLjM4NCAwIDUuNTM5LTEuODE5IDguNDgtNC4yNjN2LTE4LjgzM2MwLTEuMzk2LTMuMzYzLTIuMTYzLTUuODgyLTIuODY0di0xLjI2YzYuMzA0LS40MjMgMTAuMjM3LS45OCAxMC45MzQtLjk4LjU2NyAwIC41NjcuNDg4LjU2NyAxLjI2MXYyNS44MTh6bTEzLjk1Mi0yMy4wOTJjMi44MDEtMi4zOCA2LjU4OS01LjA0IDEwLjQ0OS01LjA0IDguMTM1IDAgMTMuMDM3IDcuMDc0IDEzLjAzNyAxNC42OTggMCA5LjE2Ny02LjcyOCAxOC4zMzgtMTYuNzYxIDE4LjMzOC01LjE4NCAwLTcuOTE4LTEuNjgyLTkuNzQ0LTIuNDQ5bC0yLjEwMSAxLjYwNi0xLjQ2Ny0uNzY3Yy42Mi00LjEyOS45NzktOC4xODkuOTc5LTEyLjQ1N3YtMzAuMDkxYzAtNC41NTMtMS4wNTctNC42OTMtMy43Mi01LjQ2MXYtMS4xMmMyLjgxMS0uOTA5IDUuNzQ5LTIuMTY4IDcuMjI0LTMuMDEyLjc3LS40MTYgMS4zMjctLjc3MiAxLjU0Ni0uNzcyLjQyIDAgLjU1OS40MjQuNTU5Ljk4NXYyNS41NDN6bTAgMTkuMDMzYzAgMi42NTkgMi41MjMgNy4xNDQgNy4yMjEgNy4xNDQgNy41MDQgMCAxMC42NTctNy4zNTIgMTAuNjU3LTEzLjU4MyAwLTcuNTU2LTUuNzQ0LTEzLjg1Mi0xMS4yMTYtMTMuODUyLTIuNjAxIDAtNC43NyAxLjY4MS02LjY2MyAzLjI5MXYxN3ptLTMwMi41MTggNDguNjAxaC41MzdjMS4zNzEgMCAyLjgyMS0uMTg1IDIuODIxLTIuMTY4di0xOS45NDhjMC0xLjk4Ni0xLjQ0OS0yLjE3NS0yLjgyMS0yLjE3NWgtLjUzN3YtMS4xNDNjMS40ODkgMCAzLjc3OC4xNSA1LjY1My4xNSAxLjkwNSAwIDQuMTkyLS4xNSA1Ljk4NS0uMTV2MS4xNDNoLS41MzZjLTEuMzY4IDAtMi44MjEuMTg5LTIuODIxIDIuMTc1djE5Ljk0OGMwIDEuOTgzIDEuNDUzIDIuMTY4IDIuODIxIDIuMTY4aC41MzZ2MS4xNDhjLTEuODMxIDAtNC4xMjUtLjE1LTYuMDI2LS4xNS0xLjg3MSAwLTQuMTI0LjE1LTUuNjEyLjE1di0xLjE0OHptMzcuODUxLTYuMzU5bC4wNzctLjA3NXYtMTQuMjc3YzAtMy4xMjQtMi4xNzctMy41ODEtMy4zMjEtMy41ODFoLS44NHYtMS4xNDNsNS4zNDIuMTUxIDQuNjk0LS4xNTF2MS4xNDNoLS41NjhjLTEuNjA3IDAtMy40LjMwNi0zLjQgNC44MzZ2MTcuMzNjMCAxLjMzMS4wMzkgMi42NjIuMjI2IDMuODQyaC0xLjQ0OWwtMTkuNjQ3LTIxLjg2djE1LjY5MmMwIDMuMzEzLjY0MyA0LjQ1MiAzLjU4NSA0LjQ1MmguNjQ3djEuMTQ4bC00LjkyLS4xNS01LjE4Ny4xNXYtMS4xNDhoLjUzNGMyLjYzMiAwIDMuNDMxLTEuNzg2IDMuNDMxLTQuODI5di0xNi4wMzljMC0yLjEyOS0xLjc1OS0zLjQyMy0zLjQ2OS0zLjQyM2gtLjQ5N3YtMS4xNDNsNC4zODMuMTUxIDMuMzk5LS4xNTEgMTYuOTgzIDE5LjA3NnptMTEuNjY2LTE3LjE3MmMtMi44NjYgMC0yLjk3NC42ODYtMy41NDcgMy40NjJoLTEuMTQzYy4xNDgtMS4wNjUuMzQyLTIuMTI5LjQ1OC0zLjIzNi4xNTUtMS4wNjguMjI4LTIuMTI5LjIyOC0zLjIzM2guOTE1Yy4zMDggMS4xNDQgMS4yNjEgMS4xMDQgMi4yOTYgMS4xMDRoMTkuNjgxYzEuMDMzIDAgMS45ODQtLjAzNyAyLjA2My0xLjE4MmwuOTEuMTUzYy0uMTQ4IDEuMDI5LS4zMDMgMi4wNTUtLjQxOSAzLjA4NS0uMDcgMS4wMjktLjA3IDIuMDU4LS4wNyAzLjA4M2wtMS4xNDcuNDIzYy0uMDc4LTEuNDA4LS4yNy0zLjY1OS0yLjgyNC0zLjY1OWgtNi4yNTd2MjAuMjU5YzAgMi45MzcgMS4zMzcgMy4yNzIgMy4xNjQgMy4yNzJoLjcyNXYxLjE0OGMtMS40ODcgMC00LjE1OS0uMTUtNi4yMTYtLjE1LTIuMjkgMC00Ljk2Mi4xNS02LjQ1Mi4xNXYtMS4xNDhoLjcyNWMyLjEwNiAwIDMuMTY4LS4xODcgMy4xNjgtMy4xOTJ2LTIwLjMzOWgtNi4yNTl6bTIzLjA4MiAyMy41MzFoLjUzNmMxLjM3MyAwIDIuODI0LS4xODUgMi44MjQtMi4xNjh2LTE5Ljk0OGMwLTEuOTg2LTEuNDUxLTIuMTc1LTIuODI0LTIuMTc1aC0uNTM2di0xLjE0M2MyLjMyMiAwIDYuMjk5LjE1IDkuNDk4LjE1IDMuMjEgMCA3LjE3Mi0uMTUgOS43NjUtLjE1LS4wNjUgMS42MzUtLjAyOCA0LjE1My4wODMgNS44MjdsLTEuMTUuMzA2Yy0uMTg0LTIuNDc0LS42NC00LjQ1NC00LjY1LTQuNDU0aC01LjI5OHY5Ljk3M2g0LjUzNGMyLjI4OCAwIDIuNzg4LTEuMjkxIDMuMDE0LTMuMzUyaDEuMTQyYy0uMDc1IDEuNDg5LS4xMTQgMi45NzMtLjExNCA0LjQ1NSAwIDEuNDUxLjAzOSAyLjg5Ni4xMTQgNC4zNDNsLTEuMTQyLjIyNmMtLjIyNi0yLjI4Mi0uMzQyLTMuNzY4LTIuOTc5LTMuNzY4aC00LjU3djguODcxYzAgMi40NzUgMi4yMDMgMi40NzUgNC42NDYgMi40NzUgNC41ODEgMCA2LjYwMS0uMzA3IDcuNzQ3LTQuNjQybDEuMDY3LjI2MmMtLjQ5OCAyLjAyNC0uOTU0IDQuMDM2LTEuMjkzIDYuMDU4LTIuNDQ2IDAtNi44MzQtLjE1LTEwLjI2My0uMTUtMy40MzggMC03Ljk3OC4xNS0xMC4xNTMuMTV2LTEuMTQ4em0yNi44NTktMjEuNGMwLTIuNzc4LTEuNTI2LTIuODkyLTIuNzEyLTIuODkyaC0uNjg3di0xLjE0NGMxLjIyMSAwIDMuNTg2LjE1MyA1LjkxNS4xNTMgMi4yODcgMCA0LjEyLS4xNTMgNi4xNDEtLjE1MyA0LjgwNCAwIDkuMDgzIDEuMjk0IDkuMDgzIDYuNzA2IDAgMy40MjEtMi4yODggNS41MTctNS4zMDMgNi43MDNsNi41MjIgOS43NDFjMS4wNyAxLjYxMSAxLjgyOSAyLjA2MyAzLjcwMiAyLjI4NHYxLjE0OWwtMy43MzktLjE1LTMuNTg0LjE1Yy0yLjkzOC0zLjg0Ni01LjQ2Mi03Ljk1OC03LjkzOS0xMi4zNDNoLTIuNTEzdjguMTUzYzAgMi45MzUgMS4zNyAzLjA0MSAzLjEyMiAzLjA0MWguNjg5djEuMTQ5bC02LjU2Mi0uMTVjLTEuODM0IDAtMy42MjcuMTUtNS41MzQuMTV2LTEuMTQ5aC42ODdjMS40MTcgMCAyLjcxMi0uNjM5IDIuNzEyLTIuMDV2LTE5LjM0OXptNC44ODYgOC44MzJoMS44NjNjMy44MTkgMCA1Ljg3NC0xLjQ0MyA1Ljg3NC01LjkzOSAwLTMuMzg0LTIuMTczLTUuNTU2LTUuNTcxLTUuNTU2LTEuMTQ3IDAtMS42MzUuMTE3LTIuMTY2LjE1MXYxMS4zNDR6bTQzLjY4IDYuMjA5bC4wNjgtLjA3NXYtMTQuMjc3YzAtMy4xMjQtMi4xNzEtMy41ODEtMy4zMTQtMy41ODFoLS44Mzd2LTEuMTQzbDUuMzQuMTUxIDQuNy0uMTUxdjEuMTQzaC0uNTc3Yy0xLjYwMSAwLTMuMzk2LjMwNi0zLjM5NiA0LjgzNnYxNy4zM2MwIDEuMzMxLjAzNiAyLjY2Mi4yMjUgMy44NDJoLTEuNDQ2bC0xOS42NDktMjEuODZ2MTUuNjkyYzAgMy4zMTMuNjQ3IDQuNDUyIDMuNTg0IDQuNDUyaC42NDh2MS4xNDhsLTQuOTE4LS4xNS01LjE5Mi4xNXYtMS4xNDhoLjUyOWMyLjYzNyAwIDMuNDM4LTEuNzg2IDMuNDM4LTQuODI5di0xNi4wMzljMC0yLjEyOS0xLjc1Ni0zLjQyMy0zLjQ3LTMuNDIzaC0uNDk3di0xLjE0M2w0LjM4OS4xNTEgMy4zOTQtLjE1MSAxNi45OCAxOS4wNzZ6bTEyLjA5MiAyLjA2MWMtLjM4OCAxLjI5Mi0uODQ3IDIuMjg5LS44NDcgMi45NjggMCAxLjE0NCAxLjYwNCAxLjMzIDIuODYgMS4zM2guNDI3djEuMTQ4Yy0xLjUyOS0uMDgzLTMuMDg4LS4xNDgtNC42MjUtLjE0OC0xLjM3MSAwLTIuNzM2LjA2NS00LjExNS4xNDh2LTEuMTQ4aC4yMzFjMS40ODcgMCAyLjc0OS0uODc0IDMuMzEzLTIuNDc3bDYuMTEyLTE3LjQ3MWMuNDktMS40MDkgMS4xODQtMy4zMTQgMS40MTQtNC43MjggMS4yMTUtLjQxMyAyLjc0NC0xLjE3NCAzLjQ2OS0xLjYzMi4xMTctLjA0MS4xODQtLjA4LjMwNS0uMDguMTE0IDAgLjE4NCAwIC4yNy4xMTcuMTE0LjMwNC4yMjEuNjQ3LjM0NS45NTFsNy4wMTkgMTkuOTE4Yy40NTYgMS4zMzEuOTEgMi43MzkgMS40MDQgMy44ODYuNDYzIDEuMDY2IDEuMjY0IDEuNTE2IDIuNTI0IDEuNTE2aC4yMjh2MS4xNDhjLTEuNzE3LS4wODMtMy40MzYtLjE0OC01LjI2NC0uMTQ4LTEuODY4IDAtMy43ODIuMDY1LTUuNzI4LjE0OHYtMS4xNDhoLjQyM2MuODczIDAgMi4zNjYtLjE0OCAyLjM2Ni0xLjEwMiAwLS40OTItLjM0NC0xLjUyLS43Ny0yLjc0MmwtMS40ODQtNC40MTZoLTguNjYxbC0xLjIxNyAzLjk2M3ptNS41NjgtMTYuODcyaC0uMDc4bC0zLjU0OSAxMC43NzhoNy4xM2wtMy41MDMtMTAuNzc4em0xNi40NDQtMi4zNjJjLTIuODYzIDAtMi45NzcuNjg2LTMuNTUgMy40NjJoLTEuMTQ3Yy4xNS0xLjA2NS4zNDQtMi4xMjkuNDYzLTMuMjM2LjE1MS0xLjA2OC4yMjMtMi4xMjkuMjIzLTMuMjMzaC45MmMuMzAzIDEuMTQ0IDEuMjYxIDEuMTA0IDIuMjg3IDEuMTA0aDE5LjY5MWMxLjAyNiAwIDEuOTc5LS4wMzcgMi4wNTctMS4xODJsLjkxNC4xNTNjLS4xNDcgMS4wMjktLjMgMi4wNTUtLjQxNCAzLjA4NS0uMDg1IDEuMDI5LS4wODUgMi4wNTgtLjA4NSAzLjA4M2wtMS4xNDIuNDIzYy0uMDctMS40MDgtLjI2Mi0zLjY1OS0yLjgxOS0zLjY1OWgtNi4yNTl2MjAuMjU5YzAgMi45MzcgMS4zMzkgMy4yNzIgMy4xNjYgMy4yNzJoLjcyNnYxLjE0OGMtMS40ODkgMC00LjE1OC0uMTUtNi4yMi0uMTUtMi4yODUgMC00Ljk2Mi4xNS02LjQ0OS4xNXYtMS4xNDhoLjcyNWMyLjEwMiAwIDMuMTY5LS4xODcgMy4xNjktMy4xOTJ2LTIwLjMzOWgtNi4yNTd6bTIzLjI2NCAyMy41MzFoLjUzNGMxLjM3OCAwIDIuODIxLS4xODUgMi44MjEtMi4xNjh2LTE5Ljk0OGMwLTEuOTg2LTEuNDQzLTIuMTc1LTIuODIxLTIuMTc1aC0uNTM0di0xLjE0M2MxLjQ5MiAwIDMuNzc3LjE1IDUuNjQzLjE1IDEuOTE0IDAgNC4yMDItLjE1IDUuOTk4LS4xNXYxLjE0M2gtLjUzNGMtMS4zNzYgMC0yLjgyOS4xODktMi44MjkgMi4xNzV2MTkuOTQ4YzAgMS45ODMgMS40NTMgMi4xNjggMi44MjkgMi4xNjhoLjUzNHYxLjE0OGMtMS44MzQgMC00LjEyNC0uMTUtNi4wMjktLjE1LTEuODczIDAtNC4xMi4xNS01LjYxMi4xNXYtMS4xNDh6bTI2Ljg1Ny0yNi4wMDNjOC4xMzUgMCAxNC42MTYgNS4wMjkgMTQuNjE2IDEzLjE0IDAgOC43NTktNi4yOTYgMTQuNTgxLTE0LjQxOSAxNC41ODEtOC4wOTYgMC0xNC4yNzMtNS40ODItMTQuMjczLTEzLjY3IDAtNy45MTkgNi4xNDEtMTQuMDUyIDE0LjA3Ni0xNC4wNTJ6bS41NzcgMjYuMDQ1YzcuNDA0IDAgOC42OTItNi41MTYgOC42OTItMTIuMDY3IDAtNS41NjktMy4wMDUtMTIuMzA2LTkuMzQyLTEyLjMwNi02LjY3OSAwLTguNjYxIDUuOTQyLTguNjYxIDExLjA0IDAgNi44MTcgMy4xMjggMTMuMzMzIDkuMzExIDEzLjMzM3ptMzkuNzUtNi40MDFsLjA3OC0uMDc1di0xNC4yNzdjMC0zLjEyNC0yLjE4MS0zLjU4MS0zLjMyNi0zLjU4MWgtLjgyN3YtMS4xNDNsNS4zMy4xNTEgNC43MDItLjE1MXYxLjE0M2gtLjU3N2MtMS41OTkgMC0zLjM5Ni4zMDYtMy4zOTYgNC44MzZ2MTcuMzNjMCAxLjMzMS4wMzYgMi42NjIuMjMgMy44NDJoLTEuNDQ4bC0xOS42NTQtMjEuODZ2MTUuNjkyYzAgMy4zMTMuNjUgNC40NTIgMy41ODQgNC40NTJoLjY1MXYxLjE0OGwtNC45Mi0uMTUtNS4xOTUuMTV2LTEuMTQ4aC41MzljMi42MzcgMCAzLjQzLTEuNzg2IDMuNDMtNC44Mjl2LTE2LjAzOWMwLTIuMTI5LTEuNzQ2LTMuNDIzLTMuNDctMy40MjNoLS40OTh2LTEuMTQzbDQuMzg5LjE1MSAzLjM5Ni0uMTUxIDE2Ljk4MSAxOS4wNzZ6bTEyLjA4NyAyLjA2MWMtLjM3NSAxLjI5Mi0uODM3IDIuMjg5LS44MzcgMi45NjggMCAxLjE0NCAxLjYwNyAxLjMzIDIuODU4IDEuMzNoLjQyN3YxLjE0OGMtMS41MjgtLjA4My0zLjA5NC0uMTQ4LTQuNjItLjE0OC0xLjM3OCAwLTIuNzQ2LjA2NS00LjExNC4xNDh2LTEuMTQ4aC4yMTdjMS40OTMgMCAyLjc1Ny0uODc0IDMuMzIxLTIuNDc3bDYuMTE0LTE3LjQ3MWMuNDkzLTEuNDA5IDEuMTg0LTMuMzE0IDEuNDA1LTQuNzI4IDEuMjIzLS40MTMgMi43NDctMS4xNzQgMy40NzktMS42MzIuMTA5LS4wNDEuMTg2LS4wOC4zMDEtLjA4LjExNCAwIC4xODcgMCAuMjY0LjExN2wuMzQ5Ljk1MSA3LjAxNiAxOS45MThjLjQ1OCAxLjMzMS45MTQgMi43MzkgMS40MTUgMy44ODYuNDU4IDEuMDY2IDEuMjYyIDEuNTE2IDIuNTE4IDEuNTE2aC4yMzN2MS4xNDhjLTEuNzItLjA4My0zLjQzOC0uMTQ4LTUuMjcyLS4xNDgtMS44NjUgMC0zLjc3Ny4wNjUtNS43MjMuMTQ4di0xLjE0OGguNDIyYy44NzEgMCAyLjM3LS4xNDggMi4zNy0xLjEwMiAwLS40OTItLjM0Ny0xLjUyLS43NzItMi43NDJsLTEuNDgyLTQuNDE2aC04LjY2MmwtMS4yMjUgMy45NjN6bTUuNTc2LTE2Ljg3MmgtLjA3N2wtMy41NTQgMTAuNzc4aDcuMTQxbC0zLjUxMS0xMC43Nzh6bTI0LjM4MSAxOC41ODNjMCAxLjUyNiAxLjA2IDEuOTggMi4yODIgMi4xMzYgMS41NjUuMTE1IDMuMjgyLjExNSA1LjA0Mi0uMDc4IDEuNTk5LS4xOTIgMi45NzItMS4xMDQgMy42NTgtMi4wNTguNjA5LS44MzkuOTUxLTEuOTAzIDEuMTg0LTIuNzQyaDEuMTA2Yy0uNDE5IDIuMTctLjk1NCA0LjMwNy0xLjQxNSA2LjQ3NmwtMTAuMDY2LS4xNDgtMTAuMDc0LjE0OHYtMS4xNDhoLjUyNmMxLjM3OSAwIDIuODcxLS4xODUgMi44NzEtMi41NDl2LTE5LjU3YzAtMS45ODUtMS40OTItMi4xNzMtMi44NzEtMi4xNzNoLS41MjZ2LTEuMTQzbDYuMDI0LjE1MSA1LjgwNC0uMTUxdjEuMTQzaC0uOTU5Yy0xLjQ0NiAwLTIuNTg1LjA0Mi0yLjU4NSAyLjA1NnYxOS42NDl6IiBmaWxsPSIjMUExOTE4Ii8+PC9zdmc+\");\n  }\n  .rccs__card--discover > div {\n    color: #555;\n  }\n  .rccs__card--discover .rccs__card__background {\n    background: linear-gradient(25deg, #fff, #eee);\n  }\n  .rccs__card--discover .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9Ijg2IiB2aWV3Qm94PSIwIDAgNTEyIDg2IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCI+PGRlZnM+PGxpbmVhckdyYWRpZW50IHgxPSIyMC40NDIlIiB5MT0iMTAuNTk5JSIgeDI9Ijg5LjI0NSUiIHkyPSI4My41MyUiIGlkPSJhIj48c3RvcCBzdG9wLWNvbG9yPSIjRTI1NDI5IiBvZmZzZXQ9IjAlIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0Y5OUQzRSIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48cGF0aCBkPSJNMjcwLjM1Ni4zNjVjLTIzLjk4MiAwLTQzLjQ0IDE4LjczNS00My40NCA0MS44NTggMCAyNC41ODMgMTguNjEyIDQyLjk2IDQzLjQ0IDQyLjk2IDI0LjIwOCAwIDQzLjMyMS0xOC42MiA0My4zMjEtNDIuNDc4IDAtMjMuNzE2LTE4Ljk4Ni00Mi4zNC00My4zMjEtNDIuMzR6IiBpZD0iYiIvPjxmaWx0ZXIgeD0iLTUwJSIgeT0iLTUwJSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94IiBpZD0iYyI+PGZlTW9ycGhvbG9neSByYWRpdXM9IjIiIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJzaGFkb3dTcHJlYWRJbm5lcjEiLz48ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIyLjUiIGluPSJzaGFkb3dTcHJlYWRJbm5lcjEiIHJlc3VsdD0ic2hhZG93Qmx1cklubmVyMSIvPjxmZU9mZnNldCBkeD0iMiIgZHk9IjIiIGluPSJzaGFkb3dCbHVySW5uZXIxIiByZXN1bHQ9InNoYWRvd09mZnNldElubmVyMSIvPjxmZUNvbXBvc2l0ZSBpbj0ic2hhZG93T2Zmc2V0SW5uZXIxIiBpbjI9IlNvdXJjZUFscGhhIiBvcGVyYXRvcj0iYXJpdGhtZXRpYyIgazI9Ii0xIiBrMz0iMSIgcmVzdWx0PSJzaGFkb3dJbm5lcklubmVyMSIvPjxmZUNvbG9yTWF0cml4IHZhbHVlcz0iMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMC4zMDE2NTg3NDEgMCIgaW49InNoYWRvd0lubmVySW5uZXIxIi8+PC9maWx0ZXI+PC9kZWZzPjx1c2UgZmlsbD0idXJsKCNhKSIgZmlsbC1ydWxlPSJldmVub2RkIiB4bGluazpocmVmPSIjYiIvPjx1c2UgZmlsdGVyPSJ1cmwoI2MpIiB4bGluazpocmVmPSIjYiIvPjxwYXRoIGQ9Ik0yMy43NDYgMS44OTFoLTIzLjM1M3Y4MS40NTRoMjMuMjMyYzEyLjMyNSAwIDIxLjI0LTIuOTIxIDI5LjA1OS05LjM5OCA5LjI3OC03LjY5NSAxNC43ODEtMTkuMjk4IDE0Ljc4MS0zMS4yODkgMC0yNC4wNDgtMTcuOTY1LTQwLjc2Ni00My43MTktNDAuNzY2em0xOC41NzMgNjEuMTc2Yy01LjAyMiA0LjUzMS0xMS40ODYgNi40ODgtMjEuNzYgNi40ODhoLTQuMjY4di01My44NzNoNC4yNjhjMTAuMjc0IDAgMTYuNDkxIDEuODM0IDIxLjc2IDYuNTkzIDUuNDk1IDQuODg2IDguNzcyIDEyLjQ1MiA4Ljc3MiAyMC4yNjUgMCA3LjgyOS0zLjI3NyAxNS42Ni04Ljc3MiAyMC41Mjd6bTMyLjQ4IDIwLjI3OGgxNS44NzF2LTgxLjQ1NGgtMTUuODcxdjgxLjQ1NHptNTQuNzI3LTUwLjIwOWMtOS41MzktMy41MzQtMTIuMzQ2LTUuODY1LTEyLjM0Ni0xMC4yNDcgMC01LjEzNCA0Ljk5OC05LjAzOSAxMS44NDktOS4wMzkgNC43NjMgMCA4LjY3MSAxLjk1MyAxMi44MzYgNi41OGw4LjI5NC0xMC44NTJjLTYuODM5LTUuOTk4LTE1LjAyMS05LjA0Ny0yMy45NDYtOS4wNDctMTQuMzk4IDAtMjUuMzk5IDEwLjAyLTI1LjM5OSAyMy4zMiAwIDExLjI0NyA1LjEyNiAxNi45ODEgMjAuMDMxIDIyLjM2OSA2LjIzMyAyLjE4OCA5LjQwMSAzLjY0NiAxMC45OTMgNC42NDMgMy4xNzUgMi4wNzcgNC43NjkgNC45OTggNC43NjkgOC40MTYgMCA2LjYwNS01LjI1NyAxMS40ODMtMTIuMzUxIDExLjQ4My03LjU3NCAwLTEzLjY3NC0zLjc4Mi0xNy4zNDEtMTAuODY1bC0xMC4yNDcgOS45MDVjNy4zMTMgMTAuNzMzIDE2LjEwOSAxNS41MTEgMjguMjE0IDE1LjUxMSAxNi40ODggMCAyOC4wODQtMTEuMDA3IDI4LjA4NC0yNi43NTggMC0xMi45NDgtNS4zNjEtMTguODE1LTIzLjQ0My0yNS40MTl6bTI4LjQ0OSA5LjUyMWMwIDIzLjk2NSAxOC44MTUgNDIuNTI1IDQzLjAwNiA0Mi41MjUgNi44MzkgMCAxMi43MDEtMS4zNTIgMTkuOTE1LTQuNzU4di0xOC42OTdjLTYuMzYxIDYuMzU4LTExLjk4IDguOTE2LTE5LjE4OSA4LjkxNi0xNS45OTcgMC0yNy4zNjQtMTEuNjA2LTI3LjM2NC0yOC4xMDIgMC0xNS42MjYgMTEuNzIxLTI3Ljk2NSAyNi42MzgtMjcuOTY1IDcuNTYxIDAgMTMuMzExIDIuNjg2IDE5LjkxNSA5LjE1OXYtMTguNjk2Yy02Ljk2Mi0zLjUzMS0xMi43MTItNC45ODUtMTkuNTUyLTQuOTg1LTI0LjA2NyAwLTQzLjM2OSAxOC45MzUtNDMuMzY5IDQyLjYwNHptMTkxLjY1MSAxMy45NDhsLTIxLjc0My01NC43MTVoLTE3LjM0NmwzNC41NzkgODMuNTM0aDguNTQzbDM1LjE4My04My41MzRoLTE3LjIxOGwtMjIgNTQuNzE1em00Ni40MzkgMjYuNzM5aDQ1LjA2NnYtMTMuNzg5aC0yOS4xODh2LTIyLjAwMWgyOC4wNzJ2LTEzLjc5MmgtMjguMDcydi0xOC4wNzloMjkuMTg4di0xMy43OTJoLTQ1LjA2NnY4MS40NTR6bTEwNy45NTUtNTcuNDE1YzAtMTUuMjU5LTEwLjQ5LTI0LjAzOS0yOC44MjMtMjQuMDM5aC0yMy41Nzd2ODEuNDU0aDE1Ljg5NXYtMzIuNzM3aDIuMDhsMjEuOTc1IDMyLjczN2gxOS41NDRsLTI1LjY2Ny0zNC4zMTFjMTEuOTg4LTIuNDUxIDE4LjU3My0xMC42MzggMTguNTczLTIzLjEwNHptLTMxLjg4MiAxMy40NTJoLTQuNjIzdi0yNC42ODNoNC44NzdjOS45MTYgMCAxNS4yODcgNC4xNjUgMTUuMjg3IDEyLjA5MiAwIDguMTc4LTUuMzcyIDEyLjU5LTE1LjU0MSAxMi41OXoiIGZpbGw9IiMwQjEwMTUiLz48L3N2Zz4=\");\n  }\n  .rccs__card--elo .rccs__card__background {\n    background: linear-gradient(25deg, #211c18, #aaa7a2);\n  }\n  .rccs__card--elo .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNMjU2IDBjMTQxLjM4NSAwIDI1NiAxMTQuNjE1IDI1NiAyNTYgMCAxNDEuMzg2LTExNC42MTUgMjU2LTI1NiAyNTZzLTI1Ni0xMTQuNjE0LTI1Ni0yNTZjMC0xNDEuMzg1IDExNC42MTUtMjU2IDI1Ni0yNTYiIGZpbGw9IiMwRTBFMTEiLz48cGF0aCBkPSJNMTgwLjA0MiAyMzcuNTgzbC03OC41MjQgMzMuODM3Yy0uMTIyLTEuMzUzLS4xODktMi43MjEtLjE4OS00LjEwNiAwLTI0LjgzOSAyMC4xMzUtNDQuOTc0IDQ0Ljk3NC00NC45NzQgMTMuNDM4IDAgMjUuNDk5IDUuODk4IDMzLjczOSAxNS4yNDN6bS0zMy43MzktNDguODc2YzM3LjA1MyAwIDY4LjExMiAyNS42MzggNzYuNDIgNjAuMTQzbC0zMS42ODIgMTMuODUzLS4wMDctLjA2Ni0zMi40MTMgMTQuMjQxLTc3Ljc1NSAzMy45OTdjLTguMzE4LTEyLjQ3LTEzLjE3LTI3LjQ0OC0xMy4xNy00My41NjEgMC00My40MTQgMzUuMTkzLTc4LjYwNyA3OC42MDctNzguNjA3em01NC45MjggMTM0LjgzOGMtMjguMTQ1IDI2LjcxMy02NS4zNzkgMjkuMzM1LTk4LjA5NiA5LjQ3M2wxOC40ODUtMjguMTA0YzE4LjYxNyAxMS4xMjggMzcuMzE5IDkuMzIzIDU2LjEwNy01LjQyOGwyMy41MDQgMjQuMDZ6bTMyLjAwNy0xOS40NTdsLS4xOTgtMTQ4LjY1MmgyOC4xNjN2MTQ0LjYzOGMwIDEuMzg4LjE3MiAyLjYxIDEuOTkyIDMuMzE3bDI0LjUgOS41MjgtMTEuMDM4IDI4LjctMjguNy0xMi4xNDNjLTEwLjg4My00LjYwNS0xNC43LTExLjI3Ny0xNC43MTktMjUuMzg5eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zMzkuMjggMzAxLjU4N2MtMTAuNTU3LTguMjA4LTE3LjM1NC0yMS4wMTgtMTcuMzU0LTM1LjQyNiAwLTEyLjgwOSA1LjM3Ny0yNC4zNTQgMTMuOTg1LTMyLjUyOWwtMTguMTktMjkuNDhjLTE4LjI4NSAxNC40ODctMzAuMDI4IDM2Ljg3LTMwLjAyOCA2Mi4wMDkgMCAyNy4wOTYgMTMuNjMyIDUxLjAwMiAzNC40MDcgNjUuMjU0bDE3LjE3OS0yOS44MjgiIGZpbGw9IiMyMDkxQzMiLz48cGF0aCBkPSJNMzUxLjYxIDIyMy45MzhjNC43NC0xLjcwNSA5Ljg1LTIuNjM5IDE1LjE3OC0yLjYzOSAxOS4yMDggMCAzNS41ODggMTIuMDc3IDQxLjk4NSAyOS4wNDhsMzQuODU2LTIuOTEyYy04LjQxNC0zNC42NC0zOS42MTMtNjAuMzY2LTc2Ljg0MS02MC4zNjYtMTAuNTE5IDAtMjAuNTQ5IDIuMDcxLTI5LjczIDUuNzk5bDE0LjU1MiAzMS4wNzEiIGZpbGw9IiNGQUVDMzIiLz48cGF0aCBkPSJNNDExLjU5NSAyNjguMzM1Yy0xLjEzNSAyMy43NjYtMjAuNzYgNDIuNjg4LTQ0LjgwNyA0Mi42ODgtMy43NyAwLTcuNDI4LS40NzItMTAuOTI1LTEuMzQ3bC0xMy42NzMgMzEuNjU3YzcuNzQ1IDIuNTMxIDE2LjAwNyAzLjkyIDI0LjU5OCAzLjkyIDQyLjU5MSAwIDc3LjMwMi0zMy42NyA3OS4wMDktNzUuODQybC0zNC4yMDMtMS4wNzciIGZpbGw9IiNEMDM1MkEiLz48L2c+PC9zdmc+\");\n  }\n  .rccs__card--hipercard .rccs__card__background {\n    background: linear-gradient(25deg, #8b181b, #de1f27);\n  }\n  .rccs__card--hipercard .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjEyMyIgdmlld0JveD0iMCAwIDUxMiAxMjMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxwYXRoIGQ9Ik0zNzQuMTE4IDgwLjg0MmMtNi45NDMgNi43OTctMjYuNDM0IDguNzI4LTI0LjQ0LTcuNTIgMS42NTYtMTMuNDk1IDE2LjM0OC0xNi4zNjMgMzIuMjczLTE0LjQxNC0xLjE4NCA3LjM4MS0yLjU0MiAxNi43NTUtNy44MzMgMjEuOTM0em0tMjEuOTM0LTUyLjY0MWMtLjY2MyAzLjcyMy0xLjY4MSA3LjA5Mi0yLjUwNiAxMC42NTMgNy45NTEtMS45OTMgMzIuNzA5LTguMTA1IDM1LjA5NSAyLjUwNi43OTIgMy41MjYtLjU3NCA3LjI3Mi0xLjU2NyAxMC4wMjgtMjIuMzg5LTIuMTIxLTQwLjYzNiAxLjU5OS00NS40MzUgMTcuNTQ3LTMuMjE0IDEwLjY4Mi4zNiAyMS4xOTQgNy4yMDcgMjQuMTI5IDEzLjE4NyA1LjY0OSAyOS4yMjgtLjgyMiAzNC43ODEtOS43MTQtLjU3NyAzLjA3OC0xLjEyMyA2LjE4Ny0uOTQgMTAuMDI2aDExLjU5NGMuMTIzLTExLjEwMyAxLjczOS0yMC4wOTEgMy40NDctMzAuMDgyIDEuNDU2LTguNTA4IDQuMTk1LTE2LjkzMSAzLjc1OS0yNC40NC0uOTk1LTE3LjE5Ny0yOS40ODYtMTEuMTE0LTQ1LjQzNC0xMC42NTN6bTExNi4yNDkgNTcuOTY4Yy05LjA3LjE5NS0xMy41OC01LjQxOS0xMy43ODctMTQuNzI2LS4zNjEtMTYuMzAxIDYuNzg5LTM0LjQxMSAyMS4zMDctMzYuMDM1IDYuNzYtLjc1NiAxMS42NTQuODE2IDE2LjYwNyAyLjUwOC00LjU0NyAxOC4zMS0yLjkwNSA0Ny43OTktMjQuMTI4IDQ4LjI1NHptMzAuMDgxLTg2LjE2OWMtMS4xNTUgMTAuMTI1LTIuNjk5IDE5Ljg2Mi00LjY5OSAyOS4xNC0zMy4wNTEtMTAuNDYxLTUzLjMyIDEzLjg1NS01Mi45NTYgNDMuODY4LjA3MiA1LjgwNSAxLjA3MSAxMS41NjEgNC43MDEgMTUuNjY3IDYuMjU2IDcuMDc2IDI0LjE3IDguNzY4IDMzLjIxNCAyLjgyMSAxLjc1Mi0xLjE1MSAzLjU0LTMuMjQ2IDQuNzAxLTQuNy44NzEtMS4wOTUgMi4yNTYtMy45NTkgMi41MDUtMy4xMzUtLjQ3NCAzLjE4Mi0xLjE4NSA2LjEyNy0xLjI1MiA5LjcxNWgxMi4yMmMyLjM1NC0zMy43ODQgOS42MzctNjIuNjQxIDE1LjA0LTkzLjM3NmgtMTMuNDc1em0tMzQ0Ljk4OSA4MS4xNTZjLTcuMjA5IDcuNjM1LTI0LjkzMSA3LjUxOC0yNi4zMi01LjMyOC0uNjA2LTUuNTg5IDEuNDc3LTExLjQ1IDIuNTA2LTE3LjIzMyAxLjA0MS01Ljg1MyAxLjc5MS0xMS40NjkgMi44MTktMTYuNjA5IDcuMS04LjY3IDI3Ljk2NS05LjcxNiAzMC4wODIgNC43MDEgMS44MzcgMTIuNTE3LTMuMTE3IDI4LjE0NS05LjA4NyAzNC40Njh6bTEwLjY1NC01Mi45NTVjLTExLjQwNC00LjI4NC0yNS4zMDMuODMtMzEuMzI4IDUuNjk0LjAyMS4yMTQtLjE0NC4yNDMtLjMyMS4yNTlsLjMyMS0uMjU5LS4wMDctLjA1NC45NC01LjY0aC0xMS41OTRjLTQuODMxIDMyLjE0My0xMC41NjEgNjMuMzg3LTE2LjYwNyA5NC4zMTZoMTMuNDczYzEuOTUtMTIuMDQ2IDMuMjM5LTI0Ljc1MyA1Ljk1NC0zNi4wMzQgMy4wNzcgMTEuODY1IDIzLjE2OSA5LjU5NyAzMS42NDcgNS4wMTQgMTcuNDk0LTkuNDYgMzAuOTg3LTU0LjQ4MSA3LjUyMS02My4yOTZ6bTYzLjkyMSAyMi41NjFoLTMxLjY0N2MxLjAwMS03LjI3NiA3LjU0Ny0xNS4yNzMgMTcuODU5LTE1LjY2NyA5LjcwNy0uMzcxIDE2LjY1NiAzLjU2NCAxMy43ODcgMTUuNjY3em0tMTIuODQ3LTIzLjgxNGMtOS43MzYuNzQ5LTE3Ljk2NSAzLjU1MS0yMy44MTQgOS43MTMtNy4xNzMgNy41NTgtMTIuOTgzIDI0LjI2Ni0xMS4yODEgMzkuNDgyIDIuNDI4IDIxLjcwOCAyOS40NTcgMjAuOTI5IDUxLjA3NSAxNS42NjcuMzY3LTMuODA5IDEuMjktNy4wNjYgMS44OC0xMC42NTMtOC45MDYgMy4zMzItMjQuMzY4IDcuOTg0LTMzLjUyOCAyLjE5NC02LjkxNS00LjM3My02Ljk1Ni0xNS40NDYtNC43LTI1LjA2OCAxNC41MjktLjQ2MiAyOS42MzEtLjM3NCA0NC4xODEgMCAuOTIzLTYuODIxIDMuNTY1LTE0LjI1NyAxLjI1My0yMC45OTMtMy4wNDktOC44OTQtMTMuOTYxLTExLjE5Ni0yNS4wNjctMTAuMzR6bS0xMTguNDQzIDEuMjUzYy0uMzY1LjA1Mi0uMzQxLjQ5NS0uMzE0LjkzOS0yLjk2OSAyMi4yMDMtNi45ODYgNDMuMzU4LTExLjI4IDY0LjIzNmgxMy40NzNjMy4yMzgtMjIuMzUyIDYuOTQ2LTQ0LjIzMyAxMS41OTQtNjUuMTc1aC0xMy40NzN6bTM1MS41Ny4zMTNjLTExLjkwOS01Ljk1My0yMS44MjIgNC4wMzctMjUuNjkzIDEwLjAyNyAxLjEwMi0zLjA3MyAxLjE2Ni03LjE4OCAyLjE5Mi0xMC4zMzloLTExLjkwN2MtMy4yMSAyMi4zNzktNy4wODEgNDQuMDk4LTExLjU5NCA2NS4xNzVoMTMuNzg3Yy4wODgtOC42MzggMS43ODQtMTUuMDI4IDMuMTMzLTIzLjUwMSAyLjg4Mi0xOC4wODggNy4xMTEtMzcuOTI2IDI4LjIwMi0zMS45Ni43LTMuMDYuOTktNi41MyAxLjg4LTkuNDAxem0tMTUxLjM0NSA0OS41MDhjLTEuMjQxLTMuMjA4LTEuNTYzLTguNTA3LTEuMjUzLTEyLjUzNC42OTctOS4wNTQgMy45OTYtMjAuMDc3IDkuMDg3LTI1LjA2NyA3LjAyNi02Ljg4OCAyMC44OTctNS43NDggMzEuOTYtMS44ODEuMzQzLTMuNzI5IDEuMDkzLTcuMDU0IDEuNTY3LTEwLjY1Mi0xOC4xNDUtMi45NjQtMzUuMzY1LTEuMTIxLTQ0LjQ5NCA4LjQ1OS04LjkzNiA5LjM3OC0xNC43OTYgMzAuOTMyLTEwLjY1NCA0NC40OTQgNC44NDggMTUuODcgMjYuNTgzIDE2LjczMyA0NC4xODMgMTAuNjU0Ljc3Ny0zLjE5IDEuMTktNi43NDYgMS44OC0xMC4wMjgtOS42MTYgNC45OTctMjguMDAxIDcuNTkzLTMyLjI3Ni0zLjQ0N3ptLTcuNTE5LTQ5LjgyMWMtMTEuOTQ4LTQuODI1LTIxLjMzOSAzLjMyOS0yNS42OTMgMTAuOTY3Ljk4Ny0zLjM5OCAxLjM5NC03LjM3OCAyLjE5Mi0xMC45NjdoLTExLjkwN2MtMi45MSAyMi41NzUtNy4yMDEgNDMuNzY5LTExLjI4IDY1LjE3NWgxMy40NzVjMS44ODgtMTIuNzA3IDIuNzAzLTI5LjgzNCA2Ljg5Mi00MS45ODggMy4zNDgtOS43MTMgMTIuMTExLTE3Ljk4NyAyNC43NTQtMTMuNDczLjE3OC0zLjU4MyAxLjIwMy02LjMxOCAxLjU2Ny05LjcxNHptLTIxNy4xNDYtMjYuMzIxYy0xLjkyNSAxMi40ODktNC4wOTMgMjQuNzM1LTYuMjY3IDM2Ljk3NC0xMy45NTkuMTQ3LTI4LjIxMS42OS00MS42NzQtLjMxNCAyLjU0My0xMS45NzMgNC4zNjctMjQuNjY4IDYuODkyLTM2LjY2aC0xNS4wMzljLTUuMzg1IDMwLjU0Ny0xMC4yODIgNjEuNTc5LTE2LjI5NCA5MS40OTdoMTUuMzUzYzIuNDA5LTE1LjM0OCA0LjY2MS0zMC44NTIgNy44MzMtNDUuNDM1IDEzLjA5MS0uMzIyIDI4Ljc4MS0uODg1IDQxLjM2Mi4zMTQtMi41OTQgMTUuMTYyLTUuNzI4IDI5Ljc4My04LjE0NyA0NS4xMjFoMTUuMzU0YzQuOTMyLTMwLjk5NyAxMC4xMzEtNjEuNzI4IDE2LjI5NC05MS40OTdoLTE1LjY2N3ptMzguMjI3IDEzLjc4N2MyLjY4Ni0xLjg0OSA2LjE0NS0xMC4yNzggMi4xOTQtMTMuNzg3LTEuMjUyLTEuMTExLTMuMzQ3LTEuNDMzLTYuMjY3LS45MzktMi43MS40NTctNC4yNjggMS4zNzctNS4zMjcgMi44MTktMS43MDMgMi4zMTktMy4yNjMgOS4zMS0uNjI4IDExLjkwNyAyLjU2NyAyLjUyOSA4LjMxOCAxLjE3NyAxMC4wMjggMHoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=\");\n  }\n  .rccs__card--jcb .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjM5NSIgdmlld0JveD0iMCAwIDUxMiAzOTUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxkZWZzPjxsaW5lYXJHcmFkaWVudCB4MT0iLTU3LjUyNyUiIHkxPSI1MC4xMjQlIiB4Mj0iMjMyLjM5MSUiIHkyPSI1MC4xMjQlIiBpZD0iYSI+PHN0b3Agc3RvcC1jb2xvcj0iIzAwNzk0MCIgb2Zmc2V0PSIwJSIvPjxzdG9wIHN0b3AtY29sb3I9IiMwMDg3M0YiIG9mZnNldD0iMjIuODUlIi8+PHN0b3Agc3RvcC1jb2xvcj0iIzQwQTczNyIgb2Zmc2V0PSI3NC4zMyUiLz48c3RvcCBzdG9wLWNvbG9yPSIjNUNCNTMxIiBvZmZzZXQ9IjEwMCUiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCB4MT0iLjE4MyUiIHkxPSI0OS45NiUiIHgyPSIxMDAuMjczJSIgeTI9IjQ5Ljk2JSIgaWQ9ImIiPjxzdG9wIHN0b3AtY29sb3I9IiMwMDc5NDAiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjMDA4NzNGIiBvZmZzZXQ9IjIyLjg1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiM0MEE3MzciIG9mZnNldD0iNzQuMzMlIi8+PHN0b3Agc3RvcC1jb2xvcj0iIzVDQjUzMSIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgeDE9Ii02Mi44MDIlIiB5MT0iNDkuODU4JSIgeDI9IjI1My42NzElIiB5Mj0iNDkuODU4JSIgaWQ9ImMiPjxzdG9wIHN0b3AtY29sb3I9IiMwMDc5NDAiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjMDA4NzNGIiBvZmZzZXQ9IjIyLjg1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiM0MEE3MzciIG9mZnNldD0iNzQuMzMlIi8+PHN0b3Agc3RvcC1jb2xvcj0iIzVDQjUzMSIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgeDE9Ii4xNzYlIiB5MT0iNTAuMDA2JSIgeDI9IjEwMS44MDglIiB5Mj0iNTAuMDA2JSIgaWQ9ImQiPjxzdG9wIHN0b3AtY29sb3I9IiMxRjI4NkYiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjMDA0RTk0IiBvZmZzZXQ9IjQ3LjUxJSIvPjxzdG9wIHN0b3AtY29sb3I9IiMwMDY2QjEiIG9mZnNldD0iODIuNjElIi8+PHN0b3Agc3RvcC1jb2xvcj0iIzAwNkZCQyIgb2Zmc2V0PSIxMDAlIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgeDE9Ii0uNTc2JSIgeTE9IjQ5LjkxNCUiIHgyPSI5OC4xMzMlIiB5Mj0iNDkuOTE0JSIgaWQ9ImUiPjxzdG9wIHN0b3AtY29sb3I9IiM2QzJDMkYiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjODgyNzMwIiBvZmZzZXQ9IjE3LjM1JSIvPjxzdG9wIHN0b3AtY29sb3I9IiNCRTE4MzMiIG9mZnNldD0iNTcuMzElIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0RDMDQzNiIgb2Zmc2V0PSI4NS44NSUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRTYwMDM5IiBvZmZzZXQ9IjEwMCUiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cGF0aCBkPSJNNTEyIDMxNC44MzZjMCA0My44MTQtMzUuNjc3IDc5LjQ5MS03OS40OTEgNzkuNDkxaC00MzIuNTA5di0zMTQuODM2YzAtNDMuODE0IDM1LjY3Ny03OS40OTEgNzkuNDkxLTc5LjQ5MWg0MzIuNTA5djMxNC44MzZ6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTM3MS4xNjkgMjM0LjA5M2gzMi44NjFsNC4wNjgtLjMxM2M2LjI1OS0xLjI1MiAxMS41NzktNi44ODUgMTEuNTc5LTE0LjcwOSAwLTcuNTExLTUuMzItMTMuMTQ0LTExLjU3OS0xNC43MDktLjkzOS0uMzEzLTIuODE3LS4zMTMtNC4wNjgtLjMxM2gtMzIuODYxdjMwLjA0NHoiIGZpbGw9InVybCgjYSkiLz48cGF0aCBkPSJNNDAwLjI3NCAyNi42MDFjLTMxLjI5NiAwLTU2Ljk1OCAyNS4zNS01Ni45NTggNTYuOTU4djU5LjE0OWg4MC40M2MxLjg3OCAwIDQuMDY4IDAgNS42MzMuMzEzIDE4LjE1Mi45MzkgMzEuNjA5IDEwLjMyOCAzMS42MDkgMjYuNjAxIDAgMTIuODMxLTkuMDc2IDIzLjc4NS0yNS45NzYgMjUuOTc2di42MjZjMTguNDY1IDEuMjUyIDMyLjU0OCAxMS41NzkgMzIuNTQ4IDI3LjU0IDAgMTcuMjEzLTE1LjY0OCAyOC40NzktMzYuMzAzIDI4LjQ3OWgtODguMjU0djExNS43OTVoODMuNTZjMzEuMjk2IDAgNTYuOTU4LTI1LjM1IDU2Ljk1OC01Ni45NTh2LTI4NC40NzloLTgzLjI0N3oiIGZpbGw9InVybCgjYikiLz48cGF0aCBkPSJNNDE1LjYwOSAxNzMuMzc5YzAtNy41MTEtNS4zMi0xMi41MTgtMTEuNTc5LTEzLjQ1Ny0uNjI2IDAtMi4xOTEtLjMxMy0zLjEzLS4zMTNoLTI5LjczMXYyNy41NGgyOS43MzFjLjkzOSAwIDIuODE3IDAgMy4xMy0uMzEzIDYuMjU5LS45MzkgMTEuNTc5LTUuOTQ2IDExLjU3OS0xMy40NTd6IiBmaWxsPSJ1cmwoI2MpIi8+PHBhdGggZD0iTTg1LjQzOCAyNi42MDFjLTMxLjI5NiAwLTU2Ljk1OCAyNS4zNS01Ni45NTggNTYuOTU4djE0MC41MThjMTUuOTYxIDcuODI0IDMyLjU0OCAxMi44MzEgNDkuMTM0IDEyLjgzMSAxOS43MTYgMCAzMC4zNTctMTEuODkyIDMwLjM1Ny0yOC4xNjZ2LTY2LjM0N2g0OC44MjJ2NjYuMDM0YzAgMjUuNjYzLTE1Ljk2MSA0Ni42MzEtNzAuMTAzIDQ2LjYzMS0zMi44NjEgMC01OC41MjMtNy4xOTgtNTguNTIzLTcuMTk4djExOS44NjNoODMuNTZjMzEuMjk2IDAgNTYuOTU4LTI1LjM1IDU2Ljk1OC01Ni45NTh2LTI4NC4xNjZoLTgzLjI0N3oiIGZpbGw9InVybCgjZCkiLz48cGF0aCBkPSJNMjQyLjg1NiAyNi42MDFjLTMxLjI5NiAwLTU2Ljk1OCAyNS4zNS01Ni45NTggNTYuOTU4djc0LjQ4NGMxNC4zOTYtMTIuMjA1IDM5LjQzMy0yMC4wMjkgNzkuODA0LTE4LjE1MiAyMS41OTQuOTM5IDQ0Ljc1MyA2Ljg4NSA0NC43NTMgNi44ODV2MjQuMDk4Yy0xMS41NzktNS45NDYtMjUuMzUtMTEuMjY3LTQzLjE4OC0xMi41MTgtMzAuNjctMi4xOTEtNDkuMTM0IDEyLjgzMS00OS4xMzQgMzkuMTIgMCAyNi42MDEgMTguNDY1IDQxLjYyMyA0OS4xMzQgMzkuMTIgMTcuODM5LTEuMjUyIDMxLjYwOS02Ljg4NSA0My4xODgtMTIuNTE4djI0LjA5OHMtMjIuODQ2IDUuOTQ2LTQ0Ljc1MyA2Ljg4NWMtNDAuMzcyIDEuODc4LTY1LjQwOC01Ljk0Ni03OS44MDQtMTguMTUydjEzMS40NDNoODMuNTZjMzEuMjk2IDAgNTYuOTU4LTI1LjM1IDU2Ljk1OC01Ni45NTh2LTI4NC43OTJoLTgzLjU2eiIgZmlsbD0idXJsKCNlKSIvPjwvc3ZnPg==\");\n  }\n  .rccs__card--laser .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjM2OCIgdmlld0JveD0iMCAwIDUxMiAzNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxwYXRoIGZpbGw9IiMyODM0N0QiIGQ9Ik0wIDM2Ny4yMTJoNTEydi0zNjcuMjExaC01MTJ6Ii8+PHBhdGggZD0iTTI1My45MSAyOTEuMDQzaC0yNTMuOTF2Mi4wOTZoMjUyLjY5bC4xMTYgNy42MjIgNC43NjQtNy42MjJoMjU0LjQzdi0yLjA5NmgtMjUzLjI3MWwzLjY2My02LjExMi04LjQ4MiA2LjExMnptMi41NTYtMjAuMDg0aC0yNTYuNDY2djIuMDk2aDI1NS40Mmw5LjE0NyA4LjM5OCA1LjExMi04LjM5OGgyNDIuMzIxdi0yLjA5NmgtMjQxLjA0NWw0LjY3Ny03LjY4NC0xOS4xNjYgNy42ODR6bTIuMTUtMjAuMDgzaC0yNTguNjE2djIuMDk2aDI1NS45OTlsMjAuODgyIDguMjUyIDUuMDIyLTguMjUyaDIzMC4wOTd2LTIuMDk2aC0yMjguODJsNC4xMS02Ljc1Mi0yOC42NzQgNi43NTJ6bS02Ljk3Mi0yMC4wODNoLTI1MS42NDR2Mi4wOTZoMjUwLjAxN2wzOS4zNDIgNy44MzYgNC43Ny03LjgzNmgyMTcuODcxdi0yLjA5NmgtMjE2LjU5NGw0LjEzNC03LjI1Mi00Ny44OTYgNy4yNTJ6bS0yMi43NzUtMTcuMDU3aC0yMjguODY4djIuMDk2aDIzNy43bDYzLjEgNS45OTYgMy43MTEtNS45OTZoMjA3LjQ4OXYtMi4wOTZoLTIwNi4yMTRsNS4xMy04LjMyNC04Mi4wNDggOC4zMjR6bS0zLjMxLTIwLjA4M2gtMjI1LjU1OHYyLjA5NmgyMjYuMDgxbDg2Ljg4OSA2LjExMiAzLjc2Ni02LjExMmgxOTUuMjY0di0yLjA5NmgtMTkzLjk4OGw0LjUzNS03LjQ1MS05Ni45ODkgNy40NTF6bS0zLjEzOC0yMC4wODNoLTIyMi40MnYyLjA5NmgyMjEuOTU1bDEwMy4xMjEgNi4zNDQgMy44ODYtNi4zNDRoMTgzLjAzOHYtMi4wOTZoLTE4MS43NjNsNC40MzQtNy4yMTgtMTEyLjI1MSA3LjIxOHptLTguNzcyLTIwLjA4M2gtMjEzLjY0N3YyLjA5NWgyMTMuMjk4bDEyMy40ODIgNy42NjcgNC42MDUtNy42NjdoMTcwLjYxNXYtMi4wOTVoLTE2OS4zNTZsNC4wNzgtNi43ODgtMTMzLjA3NSA2Ljc4OHptLTE5LjA1Ny0xNy4yODloLTE5NC41OTF2Mi4wOTZoMTk0LjQxNmwxNTMuNjY3IDYuMTM4IDMuNjg5LTYuMTM4aDE2MC4yMjh2LTIuMDk2aC0xNTguOTdsNC42MzEtNy43MDktMTYzLjA3IDcuNzA5em00Ljc2NS0yMC4wODRoLTE5OS4zNTV2Mi4wOTZoMTk4LjMwOGwxNjEuNDQzIDYuODEgNC4wODQtNi44MWgxNDguMTY1di0yLjA5NmgtMTQ2LjkwNmw0LjAxNS02LjY4NC0xNjkuNzU0IDYuNjg0em0tMTEuMzMtMjAuMDgzaC0xODguMDI1djIuMDk2aDE4Ni45NzlsMTg0LjY3NiA3LjEwMiA0LjI0NC03LjEwMmgxMzYuMTAxdi0yLjA5NmgtMTM0Ljg0MmwzLjY3Ny02LjE3MS0xOTIuODEgNi4xNzF6bS04Ljg4OS0yMC4wODNoLTE3OS4xMzZ2Mi4wOTZoMTY0Ljg0NGwyMTkuMDg2IDYuNzEzIDQuMDMzLTYuNzEzaDEyNC4wMzd2LTIuMDk2aC0xMjIuNzc4bDMuNjc4LTYuMTIxLTIxMy43NjQgNi4xMjF6bS0xLjIyLTIwLjA4M2gtMTc3LjkxNnYyLjA5NmgxNzUuNjVsMjE5Ljc0OCA3LjcwNiA0LjYzLTcuNzA2aDExMS45NzJ2LTIuMDk2aC0xMTAuNzE0bDMuOTIyLTYuNTItMjI3LjI5MiA2LjUyem0tMTIuMzc1LTIwLjA4M2gtMTY1LjU0MXYyLjA5NWgxMzIuNTQybDI3NS4yOTkgNy4wNzggNC4yNTEtNy4wNzhoOTkuOTA4di0yLjA5NWgtOTguNjQ5bDMuODE3LTYuMzU2LTI1MS42MjcgNi4zNTZ6bS04Mi4yMjctMTYuNjQ5aC04My4zMTR2Mi4wOTZoMjAwLjA1MmwyMTkuNTU0IDQuMTM4IDIuNDg3LTQuMTM4aDg5LjkwN3YtMi4wOTZoLTg4LjY0OGw1LjU4OC05LjMwMy0zNDUuNjI1IDkuMzAzeiIgZmlsbD0iI0VCMEQ3RiIvPjxwYXRoIGQ9Ik0xMzQuNzEgMzQ5LjE0MXYtMzcuNjE4aDcuNjQzdjMxLjIyN2gxOS4wMDV2Ni4zOTFoLTI2LjY0OHptODMuMTU1IDBoLTguMzE0bC0zLjMwNi04LjYxNWgtMTUuMTMybC0zLjEyNCA4LjYxNWgtOC4xMDhsMTQuNzQ0LTM3LjkyOWg4LjA4MmwxNS4xNTcgMzcuOTI5em0tMTQuMDczLTE1LjAwNmwtNS4yMTYtMTQuMDc1LTUuMTEzIDE0LjA3NWgxMC4zMjl6bTMzLjExMiAyLjY2NWw3LjQzNi0uNzI1Yy40NDcgMi41MDIgMS4zNTYgNC4zMzkgMi43MjUgNS41MTEgMS4zNjggMS4xNzQgMy4yMTUgMS43NTkgNS41MzkgMS43NTkgMi40NiAwIDQuMzE3LS41MjEgNS41NjQtMS41NjYgMS4yNDgtMS4wNDIgMS44NzItMi4yNjMgMS44NzItMy42NiAwLS44OTYtLjI2My0xLjY2LS43ODctMi4yOS0uNTI1LS42MjktMS40NDQtMS4xNzYtMi43NTItMS42NDItLjg5NC0uMzExLTIuOTM1LS44NjItNi4xMTktMS42NTYtNC4wOTctMS4wMTctNi45NzEtMi4yNjctOC42MjQtMy43NTItMi4zMjMtMi4wODYtMy40ODUtNC42MzEtMy40ODUtNy42MzIgMC0xLjkzMS41NDYtMy43MzkgMS42MzktNS40MTkgMS4wOTMtMS42ODMgMi42NjgtMi45NjQgNC43MjYtMy44NDMgMi4wNTctLjg4IDQuNTM5LTEuMzE5IDcuNDUtMS4zMTkgNC43NTEgMCA4LjMyOCAxLjA0NCAxMC43MjggMy4xMyAyLjQwMyAyLjA4NyAzLjY2MSA0Ljg3NCAzLjc4NCA4LjM1NmwtNy42NDMuMzM3Yy0uMzI5LTEuOTQ4LTEuMDMxLTMuMzUtMi4xMDQtNC4yMDUtMS4wNzctLjg1Mi0yLjY5MS0xLjI4LTQuODQ0LTEuMjgtMi4yMjEgMC0zLjk1OS40NTgtNS4yMTYgMS4zNzEtLjgwOS41ODctMS4yMTQgMS4zNzItMS4yMTQgMi4zNTUgMCAuODk3LjM3OCAxLjY2NSAxLjEzNyAyLjMwMi45NjMuODEyIDMuMzA1IDEuNjU2IDcuMDI0IDIuNTM2IDMuNzE4Ljg3OSA2LjQ2OCAxLjc4OSA4LjI0OSAyLjczIDEuNzgzLjkzOSAzLjE3OCAyLjIyNSA0LjE4MyAzLjg1MyAxLjAwOCAxLjYzMiAxLjUxMSAzLjY0NiAxLjUxMSA2LjA0MiAwIDIuMTc0LS42MDMgNC4yMDktMS44MDcgNi4xMDYtMS4yMDcgMS44OTgtMi45MSAzLjMwOC01LjExMiA0LjIzMS0yLjIwNS45MjItNC45NSAxLjM4NC04LjIzOSAxLjM4NC00Ljc4NiAwLTguNDYtMS4xMDktMTEuMDI1LTMuMzI2LTIuNTY1LTIuMjE1LTQuMDk3LTUuNDQ1LTQuNTk2LTkuNjg4em01NC4xMzIgMTIuMzQxdi0zNy45MjloMjguMDY5djYuNDE3aC0yMC40MjZ2OC40MDhoMTkuMDA1djYuMzkxaC0xOS4wMDV2MTAuMzIyaDIxLjE0OXY2LjM5MWgtMjguNzkyem01Mi4yMiAwdi0zNy45MjloMTYuMDg3YzQuMDQ1IDAgNi45ODQuMzQgOC44MTkgMS4wMjEgMS44MzIuNjgzIDMuMzAxIDEuODk1IDQuNDAyIDMuNjM2IDEuMTAxIDEuNzQzIDEuNjUzIDMuNzM1IDEuNjUzIDUuOTc3IDAgMi44NDUtLjgzNiA1LjE5Ni0yLjUwNSA3LjA0OS0xLjY3IDEuODU1LTQuMTY3IDMuMDI1LTcuNDg4IDMuNTA2IDEuNjUzLjk2NyAzLjAxNyAyLjAyOCA0LjA5NCAzLjE4MyAxLjA3NSAxLjE1NiAyLjUyNCAzLjIwOCA0LjM1MSA2LjE1N2w0LjYyMSA3LjRoLTkuMTRsLTUuNTI2LTguMjU0Yy0xLjk2Mi0yLjk0OS0zLjMwNS00LjgwOC00LjAyOC01LjU3Ni0uNzIzLS43NjYtMS40ODktMS4yOTMtMi4yOTktMS41NzctLjgwOS0uMjg2LTIuMDkxLS40MjctMy44NDYtLjQyN2gtMS41NXYxNS44MzRoLTcuNjQzem03LjY0My0yMS44ODhoNS42NTVjMy42NjcgMCA1Ljk1NS0uMTU1IDYuODY5LS40NjYuOTEyLS4zMSAxLjYyNy0uODQ0IDIuMTQ0LTEuNjA0LjUxNi0uNzU5Ljc3NC0xLjcwNy43NzQtMi44NDYgMC0xLjI3Ni0uMzQtMi4zMDctMS4wMTktMy4wOTEtLjY4Mi0uNzg1LTEuNjQxLTEuMjgxLTIuODgtMS40ODgtLjYyLS4wODYtMi40NzgtLjEzLTUuNTc3LS4xM2gtNS45NjV2OS42MjV6IiBmaWxsPSIjZmZmIi8+PC9zdmc+\");\n  }\n  .rccs__card--maestro .rccs__card__background,\n  .rccs__card--mastercard .rccs__card__background {\n    background: linear-gradient(25deg, #f37b26, #fdb731);\n  }\n  .rccs__card--maestro .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjM5OCIgdmlld0JveD0iMCAwIDUxMiAzOTgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxwYXRoIGZpbGw9IiM2QzZCQkQiIGQ9Ik0zMjUuMjIzIDI4Mi42MjloLTEzOC40NDV2LTI0OC44MDNoMTM4LjQ0NXoiLz48cGF0aCBkPSJNMTk1LjU2NSAxNTguMjMzYzAtNTAuNDcxIDIzLjYzMS05NS40MjkgNjAuNDMtMTI0LjQwMS0yNi45MS0yMS4xODYtNjAuODczLTMzLjgzMi05Ny43ODMtMzMuODMyLTg3LjM4MSAwLTE1OC4yMTMgNzAuODQyLTE1OC4yMTMgMTU4LjIzM3M3MC44MzIgMTU4LjIzMyAxNTguMjEzIDE1OC4yMzNjMzYuOTEgMCA3MC44NzItMTIuNjQ1IDk3Ljc4My0zMy44MzItMzYuNzk5LTI4Ljk3My02MC40My03My45MzEtNjAuNDMtMTI0LjQwMSIgZmlsbD0iI0QzMjAxMSIvPjxwYXRoIGQ9Ik01MTIgMTU4LjIzM2MwIDg3LjM5MS03MC44MzIgMTU4LjIzMy0xNTguMjEzIDE1OC4yMzMtMzYuOTEgMC03MC44NzItMTIuNjQ1LTk3Ljc5My0zMy44MzIgMzYuODA5LTI4Ljk3MyA2MC40NC03My45MzEgNjAuNDQtMTI0LjQwMSAwLTUwLjQ3MS0yMy42MzEtOTUuNDI5LTYwLjQ0LTEyNC40MDEgMjYuOTItMjEuMTg2IDYwLjg4My0zMy44MzIgOTcuNzkzLTMzLjgzMiA4Ny4zODEgMCAxNTguMjEzIDcwLjg0MiAxNTguMjEzIDE1OC4yMzMiIGZpbGw9IiMwMDk5REYiLz48cGF0aCBkPSJNMzcyLjA2NSAzNTIuOTM0YzEuODQxIDAgNC40ODcuMzUyIDYuNTA5IDEuMTQ3bC0yLjgxNyA4LjYxMWMtMS45MzItLjc5NS0zLjg2My0xLjA1Ni01LjcxNC0xLjA1Ni01Ljk3NiAwLTguOTYzIDMuODYzLTguOTYzIDEwLjgwNHYyMy41NmgtOS4xNDR2LTQyLjAxaDkuMDU0djUuMWMyLjM3NC0zLjY5MiA1LjgwNS02LjE1NyAxMS4wNzYtNi4xNTd6bS0zMy43ODEgOS40MDZoLTE0LjkzOXYxOC45ODNjMCA0LjIxNSAxLjQ4OSA3LjAzMiA2LjA2NiA3LjAzMiAyLjM3NCAwIDUuMzYyLS43OTUgOC4wNzgtMi4zNzRsMi42MzYgNy44MTdjLTIuODk3IDIuMDIyLTcuNDY0IDMuMjU5LTExLjQxOCAzLjI1OS0xMC44MTQgMC0xNC41ODctNS44MDUtMTQuNTg3LTE1LjU2M3YtMTkuMTU0aC04LjUzMXYtOC4zNWg4LjUzMXYtMTIuNzQ2aDkuMjI1djEyLjc0NmgxNC45Mzl2OC4zNXptLTExNi45ODcgOC45NjNjLjk3Ni02LjA2NiA0LjY1OC0xMC4yMDEgMTEuMTY3LTEwLjIwMSA1Ljg4NSAwIDkuNjY4IDMuNjkyIDEwLjYzMyAxMC4yMDFoLTIxLjh6bTMxLjI5NyAzLjY5MmMtLjA5MS0xMy4wOTgtOC4xNzktMjIuMDYxLTE5Ljk1OS0yMi4wNjEtMTIuMzAzIDAtMjAuOTE1IDguOTYzLTIwLjkxNSAyMi4wNjEgMCAxMy4zNSA4Ljk2MyAyMi4wNTEgMjEuNTM4IDIyLjA1MSA2LjMyOCAwIDEyLjEyMi0xLjU3OSAxNy4yMjMtNS44ODVsLTQuNDg3LTYuNzdjLTMuNTExIDIuODE3LTcuOTk4IDQuMzk2LTEyLjIxMyA0LjM5Ni01Ljg4NSAwLTExLjI0Ny0yLjcyNi0xMi41NjUtMTAuMjgxaDMxLjE5NmMuMDkxLTEuMTQ3LjE4MS0yLjI4NC4xODEtMy41MTF6bTQwLjE1OS0xMC4yODFjLTIuNTQ1LTEuNTg5LTcuNzI2LTMuNjEyLTEzLjA4OC0zLjYxMi01LjAxIDAtNy45OTggMS44NTEtNy45OTggNC45MjkgMCAyLjgwNyAzLjE1OSAzLjYwMSA3LjExMiA0LjEyNWw0LjMwNi42MTRjOS4xNDQgMS4zMjggMTQuNjc3IDUuMTkxIDE0LjY3NyAxMi41NzUgMCA3Ljk5OC03LjAzMiAxMy43MTItMTkuMTU0IDEzLjcxMi02Ljg2MSAwLTEzLjE4OS0xLjc2LTE4LjE5OC01LjQ1Mmw0LjMwNi03LjEyMmMzLjA3OCAyLjM3NCA3LjY1NiA0LjM5NiAxMy45ODMgNC4zOTYgNi4yMzcgMCA5LjU3Ny0xLjg0MSA5LjU3Ny01LjEgMC0yLjM2NC0yLjM3NC0zLjY5Mi03LjM4NC00LjM4NmwtNC4zMDYtLjYxNGMtOS40MDYtMS4zMjgtMTQuNTA2LTUuNTQzLTE0LjUwNi0xMi4zOTQgMC04LjM1IDYuODYxLTEzLjQ1IDE3LjQ5NC0xMy40NSA2LjY4IDAgMTIuNzQ2IDEuNDk5IDE3LjEzMiA0LjM5NmwtMy45NTQgNy4zODR6bTExMi43MjItMy4wOThjLTEuODgxIDAtMy42MjIuMzMyLTUuMjQxLjk4Ni0xLjYxLjY2NC0zLjAwOCAxLjU4OS00LjE4NSAyLjc3Ny0xLjE3NyAxLjE4Ny0yLjEwMyAyLjYxNi0yLjc3NyA0LjI3NS0uNjc0IDEuNjYtMS4wMDYgMy40OTEtMS4wMDYgNS40ODMgMCAyLjAwMi4zMzIgMy44MjMgMS4wMDYgNS40ODMuNjc0IDEuNjYgMS42IDMuMDg4IDIuNzc3IDQuMjc1IDEuMTc3IDEuMTg3IDIuNTc1IDIuMTEzIDQuMTg1IDIuNzc3IDEuNjIuNjY0IDMuMzYuOTg2IDUuMjQxLjk4NiAxLjg4MSAwIDMuNjMyLS4zMjIgNS4yNDEtLjk4NiAxLjYyLS42NjQgMy4wMjgtMS41ODkgNC4yMDUtMi43NzcgMS4xOTctMS4xODcgMi4xMjMtMi42MTYgMi44MDctNC4yNzUuNjc0LTEuNjYgMS4wMDYtMy40ODEgMS4wMDYtNS40ODMgMC0xLjk5Mi0uMzMyLTMuODIzLTEuMDA2LTUuNDgzLS42ODQtMS42Ni0xLjYxLTMuMDg4LTIuODA3LTQuMjc1LTEuMTc3LTEuMTg3LTIuNTg1LTIuMTEzLTQuMjA1LTIuNzc3LTEuNjEtLjY1NC0zLjM2LS45ODYtNS4yNDEtLjk4NnptMC04LjY4MmMzLjI1OSAwIDYuMjc3LjU2MyA5LjA1NCAxLjcgMi43NzcgMS4xMjcgNS4xODEgMi42ODYgNy4yMDMgNC42NjggMi4wMzIgMS45ODIgMy42MTIgNC4zMjYgNC43NTggNy4wMjIgMS4xNDcgMi43MDYgMS43MiA1LjY0NCAxLjcyIDguODEzIDAgMy4xNjktLjU3MyA2LjEwNi0xLjcyIDguODEzLTEuMTQ3IDIuNjk2LTIuNzI2IDUuMDUtNC43NTggNy4wMzItMi4wMjIgMS45ODItNC40MjYgMy41MzEtNy4yMDMgNC42NjgtMi43NzcgMS4xMjctNS43OTUgMS42OS05LjA1NCAxLjY5LTMuMjU5IDAtNi4yNzctLjU2My05LjA1NC0xLjY5LTIuNzc3LTEuMTM3LTUuMTYxLTIuNjg2LTcuMTczLTQuNjY4LTIuMDEyLTEuOTgyLTMuNTkxLTQuMzM2LTQuNzM4LTcuMDMyLTEuMTQ3LTIuNzA2LTEuNzItNS42NDQtMS43Mi04LjgxMyAwLTMuMTY5LjU3My02LjEwNiAxLjcyLTguODEzIDEuMTQ3LTIuNjk2IDIuNzI2LTUuMDQgNC43MzgtNy4wMjIgMi4wMTItMS45ODIgNC4zOTYtMy41NDEgNy4xNzMtNC42NjggMi43NzctMS4xMzcgNS43OTUtMS43IDkuMDU0LTEuN3ptLTIzNy41NzYgMjIuMDYxYzAtNy4zODQgNC44MzktMTMuNDUgMTIuNzQ2LTEzLjQ1IDcuNTU1IDAgMTIuNjU1IDUuODA1IDEyLjY1NSAxMy40NSAwIDcuNjQ2LTUuMSAxMy40NC0xMi42NTUgMTMuNDQtNy45MDcgMC0xMi43NDYtNi4wNTYtMTIuNzQ2LTEzLjQ0em0zNC4wMTMgMHYtMjEuMDA1aC05LjEzNHY1LjFjLTIuOTA3LTMuNzgzLTcuMjkzLTYuMTU3LTEzLjI2OS02LjE1Ny0xMS43OCAwLTIxLjAwNSA5LjIyNS0yMS4wMDUgMjIuMDYxIDAgMTIuODI2IDkuMjI1IDIyLjA2MSAyMS4wMDUgMjIuMDYxIDUuOTc2IDAgMTAuMzYyLTIuMzc0IDEzLjI2OS02LjE1N3Y1LjFoOS4xMzR2LTIxLjAwNXptLTUxLjQ5NyAyMS4wMDV2LTI2LjM2N2MwLTkuOTI5LTYuMzI4LTE2LjYwOS0xNi41MTgtMTYuNy01LjM2Mi0uMDkxLTEwLjkwNSAxLjU3OS0xNC43NjggNy40NzUtMi44OTctNC42NTgtNy40NzUtNy40NzUtMTMuODkzLTcuNDc1LTQuNDc3IDAtOC44NzMgMS4zMTgtMTIuMzAzIDYuMjM3di01LjE4MWgtOS4xMzR2NDIuMDFoOS4yMjV2LTIzLjI4OWMwLTcuMjkzIDQuMDQ0LTExLjE2NyAxMC4yODEtMTEuMTY3IDYuMDY2IDAgOS4xNDQgMy45NTQgOS4xNDQgMTEuMDc2djIzLjM3OWg5LjIyNXYtMjMuMjg5YzAtNy4yOTMgNC4yMjUtMTEuMTY3IDEwLjI4MS0xMS4xNjcgNi4yNDcgMCA5LjIzNSAzLjk1NCA5LjIzNSAxMS4wNzZ2MjMuMzc5aDkuMjI1eiIgZmlsbD0iIzExMEYwRCIvPjwvc3ZnPg==\");\n  }\n  .rccs__card--mastercard .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjM5NyIgdmlld0JveD0iMCAwIDUxMiAzOTciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxwYXRoIGQ9Ik05My4wNzkgMzk2LjAyM3YtMjYuMzQzYzAtMTAuMDk4LTYuMTQ3LTE2LjY4NC0xNi42ODQtMTYuNjg0LTUuMjY5IDAtMTAuOTc2IDEuNzU2LTE0LjkyOCA3LjQ2NC0zLjA3My00LjgzLTcuNDY0LTcuNDY0LTE0LjA1LTcuNDY0LTQuMzkgMC04Ljc4MSAxLjMxNy0xMi4yOTMgNi4xNDd2LTUuMjY5aC05LjIydjQyLjE0OWg5LjIydi0yMy4yN2MwLTcuNDY0IDMuOTUxLTEwLjk3NiAxMC4wOTgtMTAuOTc2czkuMjIgMy45NTEgOS4yMiAxMC45NzZ2MjMuMjdoOS4yMnYtMjMuMjdjMC03LjQ2NCA0LjM5LTEwLjk3NiAxMC4wOTgtMTAuOTc2IDYuMTQ3IDAgOS4yMiAzLjk1MSA5LjIyIDEwLjk3NnYyMy4yN2gxMC4wOTh6bTEzNi41NDQtNDIuMTQ5aC0xNC45Mjh2LTEyLjczMmgtOS4yMnYxMi43MzJoLTguMzQydjguMzQyaDguMzQydjE5LjMxOGMwIDkuNjU5IDMuOTUxIDE1LjM2NyAxNC40ODkgMTUuMzY3IDMuOTUxIDAgOC4zNDItMS4zMTcgMTEuNDE1LTMuMDczbC0yLjYzNC03LjkwM2MtMi42MzQgMS43NTYtNS43MDggMi4xOTUtNy45MDMgMi4xOTUtNC4zOSAwLTYuMTQ3LTIuNjM0LTYuMTQ3LTcuMDI1di0xOC44NzloMTQuOTI4di04LjM0MnptNzguMTUxLS44NzhjLTUuMjY5IDAtOC43ODEgMi42MzQtMTAuOTc2IDYuMTQ3di01LjI2OWgtOS4yMnY0Mi4xNDloOS4yMnYtMjMuNzA5YzAtNy4wMjUgMy4wNzMtMTAuOTc2IDguNzgxLTEwLjk3NiAxLjc1NiAwIDMuOTUxLjQzOSA1LjcwOC44NzhsMi42MzQtOC43ODFjLTEuNzU2LS40MzktNC4zOS0uNDM5LTYuMTQ3LS40Mzl6bS0xMTguMTA0IDQuMzljLTQuMzktMy4wNzMtMTAuNTM3LTQuMzktMTcuMTIzLTQuMzktMTAuNTM3IDAtMTcuNTYyIDUuMjY5LTE3LjU2MiAxMy42MTEgMCA3LjAyNSA1LjI2OSAxMC45NzYgMTQuNDg5IDEyLjI5M2w0LjM5LjQzOWM0LjgzLjg3OCA3LjQ2NCAyLjE5NSA3LjQ2NCA0LjM5IDAgMy4wNzMtMy41MTIgNS4yNjktOS42NTkgNS4yNjlzLTEwLjk3Ni0yLjE5NS0xNC4wNS00LjM5bC00LjM5IDcuMDI1YzQuODMgMy41MTIgMTEuNDE1IDUuMjY5IDE4LjAwMSA1LjI2OSAxMi4yOTMgMCAxOS4zMTgtNS43MDggMTkuMzE4LTEzLjYxMSAwLTcuNDY0LTUuNzA4LTExLjQxNS0xNC40ODktMTIuNzMybC00LjM5LS40MzljLTMuOTUxLS40MzktNy4wMjUtMS4zMTctNy4wMjUtMy45NTEgMC0zLjA3MyAzLjA3My00LjgzIDcuOTAzLTQuODMgNS4yNjkgMCAxMC41MzcgMi4xOTUgMTMuMTcxIDMuNTEybDMuOTUxLTcuNDY0em0yNDQuOTktNC4zOWMtNS4yNjkgMC04Ljc4MSAyLjYzNC0xMC45NzYgNi4xNDd2LTUuMjY5aC05LjIydjQyLjE0OWg5LjIydi0yMy43MDljMC03LjAyNSAzLjA3My0xMC45NzYgOC43ODEtMTAuOTc2IDEuNzU2IDAgMy45NTEuNDM5IDUuNzA4Ljg3OGwyLjYzNC04Ljc4MWMtMS43NTYtLjQzOS00LjM5LS40MzktNi4xNDctLjQzOXptLTExNy42NjUgMjEuOTUyYzAgMTIuNzMyIDguNzgxIDIxLjk1MiAyMi4zOTIgMjEuOTUyIDYuMTQ3IDAgMTAuNTM3LTEuMzE3IDE0LjkyOC00LjgzbC00LjM5LTcuNDY0Yy0zLjUxMiAyLjYzNC03LjAyNSAzLjk1MS0xMC45NzYgMy45NTEtNy40NjQgMC0xMi43MzItNS4yNjktMTIuNzMyLTEzLjYxMSAwLTcuOTAzIDUuMjY5LTEzLjE3MSAxMi43MzItMTMuNjExIDMuOTUxIDAgNy40NjQgMS4zMTcgMTAuOTc2IDMuOTUxbDQuMzktNy40NjRjLTQuMzktMy41MTItOC43ODEtNC44My0xNC45MjgtNC44My0xMy42MTEgMC0yMi4zOTIgOS4yMi0yMi4zOTIgMjEuOTUyem04NS4xNzYgMHYtMjEuMDc0aC05LjIydjUuMjY5Yy0zLjA3My0zLjk1MS03LjQ2NC02LjE0Ny0xMy4xNzEtNi4xNDctMTEuODU0IDAtMjEuMDc0IDkuMjItMjEuMDc0IDIxLjk1MiAwIDEyLjczMiA5LjIyIDIxLjk1MiAyMS4wNzQgMjEuOTUyIDYuMTQ3IDAgMTAuNTM3LTIuMTk1IDEzLjE3MS02LjE0N3Y1LjI2OWg5LjIydi0yMS4wNzR6bS0zMy44MDcgMGMwLTcuNDY0IDQuODMtMTMuNjExIDEyLjczMi0xMy42MTEgNy40NjQgMCAxMi43MzIgNS43MDggMTIuNzMyIDEzLjYxMSAwIDcuNDY0LTUuMjY5IDEzLjYxMS0xMi43MzIgMTMuNjExLTcuOTAzLS40MzktMTIuNzMyLTYuMTQ3LTEyLjczMi0xMy42MTF6bS0xMTAuMjAxLTIxLjk1MmMtMTIuMjkzIDAtMjEuMDc0IDguNzgxLTIxLjA3NCAyMS45NTIgMCAxMy4xNzEgOC43ODEgMjEuOTUyIDIxLjUxMyAyMS45NTIgNi4xNDcgMCAxMi4yOTMtMS43NTYgMTcuMTIzLTUuNzA4bC00LjM5LTYuNTg2Yy0zLjUxMiAyLjYzNC03LjkwMyA0LjM5LTEyLjI5MyA0LjM5LTUuNzA4IDAtMTEuNDE1LTIuNjM0LTEyLjczMi0xMC4wOThoMzEuMTczdi0zLjUxMmMuNDM5LTEzLjYxMS03LjQ2NC0yMi4zOTItMTkuMzE4LTIyLjM5MnptMCA3LjkwM2M1LjcwOCAwIDkuNjU5IDMuNTEyIDEwLjUzNyAxMC4wOThoLTIxLjk1MmMuODc4LTUuNzA4IDQuODMtMTAuMDk4IDExLjQxNS0xMC4wOTh6bTIyOC43NDUgMTQuMDV2LTM3Ljc1OGgtOS4yMnYyMS45NTJjLTMuMDczLTMuOTUxLTcuNDY0LTYuMTQ3LTEzLjE3MS02LjE0Ny0xMS44NTQgMC0yMS4wNzQgOS4yMi0yMS4wNzQgMjEuOTUyIDAgMTIuNzMyIDkuMjIgMjEuOTUyIDIxLjA3NCAyMS45NTIgNi4xNDcgMCAxMC41MzctMi4xOTUgMTMuMTcxLTYuMTQ3djUuMjY5aDkuMjJ2LTIxLjA3NHptLTMzLjgwNyAwYzAtNy40NjQgNC44My0xMy42MTEgMTIuNzMyLTEzLjYxMSA3LjQ2NCAwIDEyLjczMiA1LjcwOCAxMi43MzIgMTMuNjExIDAgNy40NjQtNS4yNjkgMTMuNjExLTEyLjczMiAxMy42MTEtNy45MDMtLjQzOS0xMi43MzItNi4xNDctMTIuNzMyLTEzLjYxMXptLTMwOC4yMTMgMHYtMjEuMDc0aC05LjIydjUuMjY5Yy0zLjA3My0zLjk1MS03LjQ2NC02LjE0Ny0xMy4xNzEtNi4xNDctMTEuODU0IDAtMjEuMDc0IDkuMjItMjEuMDc0IDIxLjk1MiAwIDEyLjczMiA5LjIyIDIxLjk1MiAyMS4wNzQgMjEuOTUyIDYuMTQ3IDAgMTAuNTM3LTIuMTk1IDEzLjE3MS02LjE0N3Y1LjI2OWg5LjIydi0yMS4wNzR6bS0zNC4yNDYgMGMwLTcuNDY0IDQuODMtMTMuNjExIDEyLjczMi0xMy42MTEgNy40NjQgMCAxMi43MzIgNS43MDggMTIuNzMyIDEzLjYxMSAwIDcuNDY0LTUuMjY5IDEzLjYxMS0xMi43MzIgMTMuNjExLTcuOTAzLS40MzktMTIuNzMyLTYuMTQ3LTEyLjczMi0xMy42MTF6Ii8+PHBhdGggZmlsbD0iI0ZGNUYwMCIgZD0iTTE4Ni41OTYgMzMuODA3aDEzOC4zMDF2MjQ4LjUwMmgtMTM4LjMwMXoiLz48cGF0aCBkPSJNMTk1LjM3NyAxNTguMDU4YzAtNTAuNDkxIDIzLjcwOS05NS4yNzQgNjAuMTUtMTI0LjI1MS0yNi43ODItMjEuMDc0LTYwLjU4OS0zMy44MDctOTcuNDY5LTMzLjgwNy04Ny4zNzEgMC0xNTguMDU4IDcwLjY4Ny0xNTguMDU4IDE1OC4wNThzNzAuNjg3IDE1OC4wNTggMTU4LjA1OCAxNTguMDU4YzM2Ljg4IDAgNzAuNjg3LTEyLjczMiA5Ny40NjktMzMuODA3LTM2LjQ0MS0yOC41MzgtNjAuMTUtNzMuNzYtNjAuMTUtMTI0LjI1MXoiIGZpbGw9IiNFQjAwMUIiLz48cGF0aCBkPSJNNTExLjQ5MyAxNTguMDU4YzAgODcuMzcxLTcwLjY4NyAxNTguMDU4LTE1OC4wNTggMTU4LjA1OC0zNi44OCAwLTcwLjY4Ny0xMi43MzItOTcuNDY5LTMzLjgwNyAzNi44OC0yOC45NzcgNjAuMTUtNzMuNzYgNjAuMTUtMTI0LjI1MXMtMjMuNzA5LTk1LjI3NC02MC4xNS0xMjQuMjUxYzI2Ljc4Mi0yMS4wNzQgNjAuNTg5LTMzLjgwNyA5Ny40NjktMzMuODA3IDg3LjM3MSAwIDE1OC4wNTggNzEuMTI2IDE1OC4wNTggMTU4LjA1OHoiIGZpbGw9IiNGNzlFMUIiLz48L3N2Zz4=\");\n  }\n  .rccs__card--unionpay .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjMyMCIgdmlld0JveD0iMCAwIDUxMiAzMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPjxwYXRoIGQ9Ik0xMDAuMDgzLjAwMWgxMjcuNTU3YzE3LjgwNiAwIDI4Ljg4IDE0LjUxMyAyNC43MjcgMzIuMzc4bC01OS4zODcgMjU0Ljk3MWMtNC4xOTEgMTcuODAzLTIyLjAxOSAzMi4zMjgtMzkuODM3IDMyLjMyOGgtMTI3LjU0NWMtMTcuNzgxIDAtMjguODgtMTQuNTI2LTI0LjcyNy0zMi4zMjhsNTkuNDEyLTI1NC45NzFjNC4xNTQtMTcuODY1IDIxLjk3Mi0zMi4zNzggMzkuOC0zMi4zNzgiIGZpbGw9IiNFMjE4MzYiLz48cGF0aCBkPSJNMjE3LjAyNy4wMDFoMTQ2LjY4N2MxNy44MDMgMCA5Ljc3NSAxNC41MTMgNS41ODcgMzIuMzc4bC01OS4zNzggMjU0Ljk3MWMtNC4xNjYgMTcuODAzLTIuODY3IDMyLjMyOC0yMC43MDcgMzIuMzI4aC0xNDYuNjg3Yy0xNy44NCAwLTI4Ljg4LTE0LjUyNi0yNC42ODktMzIuMzI4bDU5LjM3NS0yNTQuOTcxYzQuMjE2LTE3Ljg2NSAyMS45OTctMzIuMzc4IDM5LjgxMi0zMi4zNzgiIGZpbGw9IiMwMDQ0N0MiLz48cGF0aCBkPSJNMzU3Ljg5Ni4wMDFoMTI3LjU1N2MxNy44MzEgMCAyOC45MDUgMTQuNTEzIDI0LjcxNyAzMi4zNzhsLTU5LjM3OCAyNTQuOTcxYy00LjE5MSAxNy44MDMtMjIuMDMxIDMyLjMyOC0zOS44NTkgMzIuMzI4aC0xMjcuNDk4Yy0xNy44NCAwLTI4LjkwNS0xNC41MjYtMjQuNzI3LTMyLjMyOGw1OS4zODctMjU0Ljk3MWM0LjE1NC0xNy44NjUgMjEuOTYtMzIuMzc4IDM5LjgtMzIuMzc4IiBmaWxsPSIjMDA3Qjg0Ii8+PHBhdGggZD0iTTEzMy4zOTcgODEuNzEyYy0xMy4xMTcuMTM0LTE2Ljk5MSAwLTE4LjIyOS0uMjkyLS40NzYgMi4yNi05LjMyNyA0My4wOTItOS4zNTIgNDMuMTI2LTEuOTA2IDguMjYxLTMuMjkzIDE0LjE1LTguMDAzIDE3Ljk1Mi0yLjY3NCAyLjIxMS01Ljc5NSAzLjI3Ny05LjQxNCAzLjI3Ny01LjgxNyAwLTkuMjA2LTIuODg4LTkuNzc1LTguMzY3bC0uMTA5LTEuODgxczEuNzcyLTExLjA2NSAxLjc3Mi0xMS4xMjdjMCAwIDkuMjktMzcuMjEgMTAuOTUzLTQyLjEyOC4wODctLjI4LjExMi0uNDI2LjEzNC0uNTYtMTguMDgzLjE1OS0yMS4yODggMC0yMS41MDktLjI5Mi0uMTIxLjQwMS0uNTY5IDIuNzA4LS41NjkgMi43MDhsLTkuNDg2IDQxLjkzOS0uODE1IDMuNTU3LTEuNTc2IDExLjYzNGMwIDMuNDUxLjY3OCA2LjI2OCAyLjAyNyA4LjY1IDQuMzIyIDcuNTUyIDE2LjY0OSA4LjY4NCAyMy42MjMgOC42ODQgOC45ODUgMCAxNy40MTQtMS45MDkgMjMuMTEtNS4zOTQgOS44ODctNS44NDIgMTIuNDc0LTE0Ljk3MyAxNC43ODEtMjMuMDg4bDEuMDctNC4xNjNzOS41Ny0zOC42NDYgMTEuMTk2LTQzLjY3NGMuMDYyLS4yOC4wODctLjQyNi4xNzEtLjU2em0zMi41NjEgMzEuMTc2Yy0yLjMwNyAwLTYuNTIzLjU2LTEwLjMxIDIuNDE2LTEuMzc0LjcwNi0yLjY3NCAxLjUyLTQuMDQ1IDIuMzMybDEuMjM3LTQuNDY4LS42NzgtLjc1MmMtOC4wMzEgMS42MjYtOS44MjggMS44NDQtMTcuMjQ2IDIuODg4bC0uNjIyLjQxNGMtLjg2MSA3LjE0Mi0xLjYyNiAxMi41MTEtNC44MTkgMjYuNTQ5LTEuMjE2IDUuMTc0LTIuNDc4IDEwLjM5Ny0zLjc0MyAxNS41NThsLjM0Mi42NTZjNy42MDItLjQwMSA5LjkwOS0uNDAxIDE2LjUxNi0uMjkybC41MzUtLjU4MWMuODM5LTQuMy45NDgtNS4zMDcgMi44MDgtMTQuMDE2Ljg3NC00LjEyOSAyLjY5Ni0xMy4yMDEgMy41OTQtMTYuNDMyIDEuNjUxLS43NjUgMy4yOC0xLjUxNyA0LjgzNS0xLjUxNyAzLjcwMyAwIDMuMjUyIDMuMjMgMy4xMDkgNC41MTgtLjE1OSAyLjE2MS0xLjUwOCA5LjIxOC0yLjg5MSAxNS4yNzhsLS45MjMgMy45MTFjLS42NDQgMi44ODgtMS4zNDkgNS42OTYtMS45OTMgOC41NTlsLjI4LjU3MmM3LjQ5My0uNDAxIDkuNzc4LS40MDEgMTYuMTc3LS4yOTJsLjc1Mi0uNTgxYzEuMTU3LTYuNzE2IDEuNDk1LTguNTEzIDMuNTQ3LTE4LjI5MWwxLjAzMi00LjQ5M2MyLjAwNS04Ljc5MyAzLjAxMy0xMy4yNTEgMS40OTUtMTYuODgyLTEuNjA0LTQuMDctNS40NTMtNS4wNTItOC45ODgtNS4wNTJ6bTM2LjM3NCA5LjIwNmMtMy45ODMuNzY1LTYuNTIzIDEuMjc1LTkuMDQ3IDEuNjA0LTIuNTAzLjQwMS00Ljk0My43NjUtOC43OTMgMS4zbC0uMzA1LjI3Ny0uMjguMjIxYy0uNDAxIDIuODY3LS42ODEgNS4zNDUtMS4yMTMgOC4yNTgtLjQ1MSAzLjAxMy0xLjE0NCA2LjQzNi0yLjI3MyAxMS4zNTQtLjg3NCAzLjc2NS0xLjMyNCA1LjA3Ny0xLjgyMiA2LjQwMi0uNDg1IDEuMzI0LTEuMDIgMi42MTItMi4wMDIgNi4zMTVsLjIzLjM0Mi4xOTMuMzE0YzMuNTk3LS4xNzEgNS45NTEtLjI5MiA4LjM3LS4zMTQgMi40MTYtLjA4NyA0LjkxOSAwIDguNzkzLjAyMmwuMzM5LS4yNzcuMzY0LS4zMDVjLjU2LTMuMzM5LjY0NC00LjIzOC45ODYtNS44NjcuMzM5LTEuNzQ3LjkyMy00LjE2NiAyLjM1Ny0xMC42MjcuNjc4LTMuMDM0IDEuNDMzLTYuMDYgMi4xMzYtOS4xNTYuNzMxLTMuMDg0IDEuNDk1LTYuMTIyIDIuMjIzLTkuMTU2bC0uMTA5LS4zNjctLjE0Ni0uMzM5em0uMDg1LTEyLjQxMmMtMy42MTktMi4xMzYtOS45NzEtMS40NTgtMTQuMjQ2IDEuNDkyLTQuMjYzIDIuODkxLTQuNzQ4IDYuOTk1LTEuMTQxIDkuMTU5IDMuNTU3IDIuMDc3IDkuOTM0IDEuNDU4IDE0LjE3MS0xLjUxNyA0LjI1My0yLjk1NCA0Ljc4NS03LjAyIDEuMjE2LTkuMTM1em0yMS44ODcgNDkuNDY3YzcuMzIyIDAgMTQuODI3LTIuMDE4IDIwLjQ3Ny04LjAwNiA0LjM0Ny00Ljg1NiA2LjMzOS0xMi4wODIgNy4wMy0xNS4wNTcgMi4yNDgtOS44NjIuNDk3LTE0LjQ2Ny0xLjcwMS0xNy4yNzEtMy4zMzktNC4yNzUtOS4yNC01LjY0Ni0xNS4zNjItNS42NDYtMy42ODEgMC0xMi40NDkuMzY0LTE5LjI5OCA2LjY3OC00LjkxOSA0LjU1NS03LjE5MSAxMC43MzYtOC41NjIgMTYuNjYyLTEuMzg0IDYuMDM4LTIuOTc1IDE2LjkwNyA3LjAyIDIwLjk1MiAzLjA4NCAxLjMyNCA3LjUzIDEuNjg4IDEwLjM5NyAxLjY4OHptLS41NzItMjIuMTljMS42ODgtNy40NjggMy42ODEtMTMuNzM2IDguNzY4LTEzLjczNiAzLjk4NiAwIDQuMjc1IDQuNjY0IDIuNTAzIDEyLjE1Ny0uMzE3IDEuNjYzLTEuNzcyIDcuODQ3LTMuNzQgMTAuNDgxLTEuMzc0IDEuOTQzLTMgMy4xMjItNC43OTcgMy4xMjItLjUzNSAwLTMuNzE1IDAtMy43NjUtNC43MjMtLjAyNS0yLjMzMi40NTEtNC43MTMgMS4wMzItNy4zem00Ni4zODIgMjEuMjI5bC41NzItLjU4MWMuODExLTQuMy45NDUtNS4zMSAyLjc0Mi0xNC4wMTYuODk5LTQuMTI5IDIuNzU4LTEzLjIwMSAzLjYzMS0xNi40MzIgMS42NTQtLjc2OCAzLjI1NS0xLjUyIDQuODYtMS41MiAzLjY3OCAwIDMuMjMgMy4yMyAzLjA4NCA0LjUxOC0uMTM0IDIuMTY0LTEuNDgzIDkuMjE4LTIuODkxIDE1LjI3OGwtLjg3NCAzLjkxMWMtLjY2OCAyLjg5MS0xLjM5NiA1LjY5Ni0yLjA0IDguNTYybC4yOC41NzJjNy41MTgtLjQwMSA5LjcxNi0uNDAxIDE2LjE1Mi0uMjkybC43NzctLjU4MWMxLjEyOS02LjcxOSAxLjQzMy04LjUxNiAzLjU0Ny0xOC4yOTFsMS4wMDctNC40OTZjMi4wMTUtOC43OTMgMy4wMzQtMTMuMjQ4IDEuNTQyLTE2Ljg3OS0xLjY1MS00LjA3LTUuNTI1LTUuMDUyLTkuMDEtNS4wNTItMi4zMSAwLTYuNTQ4LjU1Ny0xMC4zMTMgMi40MTYtMS4zNDYuNzA2LTIuNjk2IDEuNTE3LTQuMDIgMi4zMzJsMS4xNTMtNC40NjgtLjYxOS0uNzU2Yy04LjAyOCAxLjYyOS05Ljg2MiAxLjg0Ny0xNy4yNzEgMi44OTFsLS41NjkuNDE0Yy0uODk5IDcuMTQyLTEuNjI5IDEyLjUwOC00LjgyMiAyNi41NDktMS4yMTYgNS4xNzQtMi40NzggMTAuMzk3LTMuNzQgMTUuNTU4bC4zMzkuNjU2YzcuNjE0LS40MDEgOS44ODctLjQwMSAxNi40ODEtLjI5MnptNTUuMjM1LjI5MWMuNDczLTIuMzA3IDMuMjgtMTUuOTgxIDMuMzA1LTE1Ljk4MSAwIDAgMi4zOTEtMTAuMDMzIDIuNTM3LTEwLjM5NyAwIDAgLjc1Mi0xLjA0NSAxLjUwNS0xLjQ1OGgxLjEwN2MxMC40NDMgMCAyMi4yMzYgMCAzMS40OC02LjggNi4yOS00LjY2NCAxMC41OS0xMS41NSAxMi41MDgtMTkuOTIuNDk3LTIuMDUyLjg2NC00LjQ5My44NjQtNi45MzMgMC0zLjIwNS0uNjQ0LTYuMzc3LTIuNTAzLTguODU1LTQuNzEzLTYuNTk0LTE0LjEtNi43MTYtMjQuOTM1LTYuNzY1bC01LjM0MS4wNWMtMTMuODcuMTcxLTE5LjQzMi4xMjEtMjEuNzE3LS4xNTktLjE5MyAxLjAxLS41NTcgMi44MDgtLjU1NyAyLjgwOHMtNC45NjggMjMuMDI2LTQuOTY4IDIzLjA2M2MwIDAtMTEuODg5IDQ4Ljk1Ni0xMi40NDkgNTEuMjYzIDEyLjExLS4xNDYgMTcuMDc1LS4xNDYgMTkuMTY1LjA4NHptOS4yMDYtNDAuOTAzczUuMjgyLTIyLjk3OSA1LjI1Ny0yMi44OTJsLjE3MS0xLjE3OC4wNzUtLjg5OSAyLjExMS4yMThzMTAuODk0LjkzNiAxMS4xNDkuOTYxYzQuMyAxLjY2MyA2LjA3MiA1Ljk1MSA0LjgzNSAxMS41NDctMS4xMjkgNS4xMTQtNC40NDYgOS40MTQtOC43MDkgMTEuNDkxLTMuNTEgMS43Ni03LjgxIDEuOTA2LTEyLjI0MSAxLjkwNmgtMi44NjdsLjIxOC0xLjE1M3ptMzIuODg5IDE5LjgwOWMtMS4zOTYgNS45NTEtMyAxNi44MiA2Ljk0NiAyMC42OTQgMy4xNzEgMS4zNDkgNi4wMTMgMS43NSA4LjkwMSAxLjYwNCAzLjA1LS4xNjUgNS44NzYtMS42OTQgOC40OTQtMy44OTZsLS43MDkgMi43MTcuNDUxLjU4MWM3LjE1NC0uMzAyIDkuMzc0LS4zMDIgMTcuMTI1LS4yNDNsLjcwMy0uNTM1YzEuMTMyLTYuNjUzIDIuMTk4LTEzLjExNCA1LjEzOS0yNS44NDMgMS40MzMtNi4wOTcgMi44NjMtMTIuMTM1IDQuMzM0LTE4LjIwN2wtLjIzLS42NjhjLTguMDAzIDEuNDgzLTEwLjE0MiAxLjgtMTcuODQgMi44OTFsLS41ODUuNDc2LS4yMzMgMS44MDZjLTEuMTk3LTEuOTM0LTIuOTMyLTMuNTg1LTUuNjA5LTQuNjE0LTMuNDIzLTEuMzQ2LTExLjQ2My4zODktMTguMzc1IDYuNjgxLTQuODU2IDQuNDkzLTcuMTg4IDEwLjY0OS04LjUxMyAxNi41NTN6bTE2LjgwOC4zNjRjMS43MTMtNy4zMzQgMy42ODEtMTMuNTQgOC43OC0xMy41NCAzLjIyNCAwIDQuOTIyIDIuOTc1IDQuNTc3IDguMDQ5LS4yNzQgMS4yNjUtLjU2OSAyLjU5OS0uOTIgNC4xMDctLjUxIDIuMTc5LTEuMDYzIDQuMzQtMS42MDEgNi41MDQtLjU0NyAxLjQ4LTEuMTg1IDIuODc2LTEuODg0IDMuODA2LTEuMzEyIDEuODU5LTQuNDM0IDMuMDEzLTYuMjMxIDMuMDEzLS41MSAwLTMuNjU2IDAtMy43NjUtNC42MzktLjAyNS0yLjMxLjQ1MS00LjY4OSAxLjA0NS03LjN6bTg3Ljc3Mi0yNC4yMTdsLS42MTktLjcwNmMtNy45MTkgMS42MDQtOS4zNTIgMS44NTktMTYuNjI3IDIuODQybC0uNTM1LjUzNS0uMDg0LjM0Mi0uMDI1LS4xMjFjLTUuNDE2IDEyLjQ5NS01LjI1NyA5LjgtOS42NjYgMTkuNjM3bC0uMDUtMS4yMDMtMS4xMDQtMjEuMzI1LS42OTMtLjcwNmMtOC4yOTUgMS42MDQtOC40OTEgMS44NTktMTYuMTUyIDIuODQybC0uNTk3LjUzNWMtLjA4NC4yNTUtLjA4NC41MzUtLjEzNC44MzlsLjA1LjEwOWMuOTU4IDQuODk0LjcyOCAzLjgwMiAxLjY4OCAxMS41MjUuNDQ4IDMuNzkgMS4wNDUgNy42MDIgMS40OTIgMTEuMzQ1Ljc1NiA2LjI2NSAxLjE3OCA5LjM0OSAyLjEwMiAxOC45MS01LjE3NCA4LjUzOC02LjM5OSAxMS43NjgtMTEuMzc5IDE5LjI2MWwuMDM0LjA3NS0zLjUwNyA1LjU0N2MtLjQwMS41ODUtLjc2NS45ODYtMS4yNzUgMS4xNTctLjU2LjI3Ny0xLjI4Ny4zMjYtMi4yOTguMzI2aC0xLjk0M2wtMi44ODggOS42MDcgOS45MDkuMTcxYzUuODE3LS4wMjUgOS40NzMtMi43NDUgMTEuNDQxLTYuNDAybDYuMjMxLTEwLjY3N2gtLjA5OWwuNjU2LS43NTJjNC4xOTEtOS4wMjMgMzYuMDcyLTYzLjcxMiAzNi4wNzItNjMuNzEyem0tMTA0LjU4IDEyNi4xNzVoLTQuMjA0bDE1LjU1OC01MS40NTloNS4xNjFsMS42MzgtNS4zMDEuMTU5IDUuODk1Yy0uMTkzIDMuNjQ0IDIuNjc0IDYuODc0IDEwLjIwNCA2LjMzOWg4LjcwOWwyLjk5Ny05LjkwOWgtMy4yNzdjLTEuODg0IDAtMi43NTgtLjQ3Ni0yLjY0OS0xLjQ5NWwtLjE1OS01Ljk5N2gtMTYuMTI3di4wMzFjLTUuMjE0LjEwOS0yMC43ODQuNTAxLTIzLjkzNyAxLjM0LTMuODE1Ljk4Mi03LjgzNSAzLjg3NC03LjgzNSAzLjg3NGwxLjU3OS01LjMwN2gtMTUuMDg1bC0zLjE0MyAxMC41MzEtMTUuNzY2IDUyLjI0NWgtMy4wNTlsLTMgOS44MzdoMzAuMDQ2bC0xLjAwNyAzLjI4aDE0LjgwNmwuOTgyLTMuMjhoNC4xNTRsMy4yNTUtMTAuNjI0em0tMTIuMzI4LTQxLjAwM2MtMi40MTYuNjY4LTYuOTEyIDIuNjk2LTYuOTEyIDIuNjk2bDMuOTk4LTEzLjE1MmgxMS45ODZsLTIuODkxIDkuNTgycy0zLjcwMy4yMTgtNi4xODEuODc0em0uMjMgMTguNzg4cy0zLjc2NS40NzMtNi4yNDMgMS4wMzJjLTIuNDQxLjc0LTcuMDE3IDMuMDcyLTcuMDE3IDMuMDcybDQuMTI5LTEzLjY4NmgxMi4wNDhsLTIuOTE2IDkuNTgyem0tNi43MTYgMjIuMzM2aC0xMi4wMjNsMy40ODUtMTEuNTVoMTEuOTg2bC0zLjQ0OCAxMS41NXptMjguOTU0LTMxLjkxOGgxNy4zM2wtMi40OSA4LjA2NWgtMTcuNTZsLTIuNjM3IDguODE3aDE1LjM2NWwtMTEuNjM0IDE2LjM4MmMtLjgxNSAxLjIwMy0xLjU0NSAxLjYyOS0yLjM1NyAxLjk2OC0uODE1LjQxNC0xLjg4NC44OTktMy4xMjIuODk5aC00LjI2M2wtMi45MjkgOS42NTdoMTEuMTQ5YzUuNzk1IDAgOS4yMTgtMi42MzcgMTEuNzQ2LTYuMDk3bDcuOTc4LTEwLjkxOSAxLjcxMyAxMS4wODdjLjM2NCAyLjA3NyAxLjg1NiAzLjI5MyAyLjg2NyAzLjc2NSAxLjExNi41NiAyLjI3IDEuNTIgMy44OTkgMS42NjMgMS43NDcuMDc1IDMuMDEuMTM0IDMuODQ5LjEzNGg1LjQ3OGwzLjI4OS0xMC44MDdoLTIuMTYxYy0xLjI0MSAwLTMuMzc2LS4yMDgtMy43NC0uNTk3LS4zNjQtLjQ3My0uMzY0LTEuMi0uNTYtMi4zMDdsLTEuNzM4LTExLjExMmgtNy4xMTdsMy4xMjItMy43MTVoMTcuNTI2bDIuNjk2LTguODE3aC0xNi4yMjZsMi41MjgtOC4wNjVoMTYuMTc3bDMtOS45NDZoLTQ4LjIyOGwtMi45NTEgOS45NDZ6bS0xNDYuMzcxIDM0LjE2NGw0LjA0NS0xMy40NTZoMTYuNjI0bDMuMDM4LTEwLjAwOGgtMTYuNjRsMi41NC04LjI4M2gxNi4yNjFsMy4wMTMtOS42OTFoLTQwLjY4NmwtMi45NTEgOS42OTFoOS4yNDNsLTIuNDY2IDguMjgzaC05LjI2OGwtMy4wNzIgMTAuMTc5aDkuMjRsLTUuMzkxIDE3LjgwM2MtLjcyOCAyLjM1Ny4zNDIgMy4yNTUgMS4wMiA0LjM1LjY5MyAxLjA2NiAxLjM5NiAxLjc3MiAyLjk3NSAyLjE3MyAxLjYyOS4zNjQgMi43NDUuNTgxIDQuMjYzLjU4MWgxOC43NDJsMy4zMzktMTEuMDg3LTguMzA4IDEuMTQxYy0xLjYwNCAwLTYuMDQ3LS4xOTMtNS41NjItMS42NzZ6bTEuOTA3LTY0LjQxN2wtNC4yMTMgNy42MTRjLS45MDIgMS42NjMtMS43MTMgMi42OTYtMi40NDQgMy4xNzEtLjY0NC40MDEtMS45MTguNTY5LTMuNzY1LjU2OWgtMi4xOThsLTIuOTM4IDkuNzQxaDcuM2MzLjUxIDAgNi4yMDYtMS4yODcgNy40OTMtMS45MzEgMS4zODQtLjc0IDEuNzQ3LS4zMTcgMi44MTctMS4zNDlsMi40NjYtMi4xMzZoMjIuNzk2bDMuMDI1LTEwLjE0MmgtMTYuNjg3bDIuOTEzLTUuNTM3aC0xNi41NjV6bTMzLjY1NCA2NC42MTJjLS4zODktLjU2LS4xMDktMS41NDUuNDg1LTMuNTk3bDYuMjMxLTIwLjYyM2gyMi4xNjVjMy4yMy0uMDQ3IDUuNTYyLS4wODQgNy4wNzktLjE5MyAxLjYyOS0uMTcxIDMuNDAxLS43NTIgNS4zMzItMS43OTcgMS45OTMtMS4wOTQgMy4wMTMtMi4yNDggMy44NzQtMy41NzIuOTYxLTEuMzIxIDIuNTAzLTQuMjEzIDMuODI3LTguNjcxbDcuODMyLTI2LjA5OC0yMy4wMDEuMTM0cy03LjA4MyAxLjA0NS0xMC4yMDEgMi4xOThjLTMuMTQ2IDEuMjg3LTcuNjQyIDQuODgxLTcuNjQyIDQuODgxbDIuMDc3LTcuMTU0aC0xNC4yMDlsLTE5Ljg5MiA2NS45NzJjLS43MDYgMi41NjItMS4xNzggNC40MjEtMS4yODcgNS41MzctLjAzNyAxLjIwMyAxLjUxNyAyLjM5NCAyLjUyNSAzLjI5MyAxLjE5MS44OTkgMi45NTEuNzUyIDQuNjM5Ljg5OSAxLjc3NS4xMzQgNC4zLjIxOCA3Ljc4NS4yMThoMTAuOTE5bDMuMzUyLTExLjMxNy05Ljc3NS45MjNjLTEuMDQ1IDAtMS44LS41Ni0yLjExNC0xLjAzMnptMTAuNzM2LTM4LjE0OWgyMy4yODFsLTEuNDggNC42MzljLS4yMDguMTA5LS43MDYtLjIzLTMuMDc1LjA1aC0yMC4xNTlsMS40MzMtNC42ODl6bTQuNjY0LTE1LjU1OGgyMy40NzdsLTEuNjg4IDUuNTg3cy0xMS4wNjUtLjEwOS0xMi44MzcuMjE4Yy03Ljc5OCAxLjM0OS0xMi4zNTIgNS41MTYtMTIuMzUyIDUuNTE2bDMuNDAxLTExLjMyem0xNy42NTggMzUuNzMxYy0uMTkzLjY5My0uNDk3IDEuMTE2LS45MjMgMS40MzMtLjQ3My4zMDUtMS4yMzcuNDE0LTIuMzc4LjQxNGgtMy4zMTdsLjE5Ni01LjY0OWgtMTMuNzk4bC0uNTYgMjcuNjE4Yy0uMDIyIDEuOTkzLjE3MSAzLjE0NiAxLjYyOSA0LjA3IDEuNDU4IDEuMTUzIDUuOTUxIDEuMyAxMS45OTggMS4zaDguNjQ2bDMuMTIyLTEwLjMzOC03LjUyNy40MTQtMi41MDMuMTQ2Yy0uMzQyLS4xNDYtLjY2OC0uMjgtMS4wMzItLjY0NC0uMzE3LS4zMTQtLjg1Mi0uMTIxLS43NjUtMi4xMTRsLjA1OS03LjA3OSA3Ljg5NC0uMzI2YzQuMjYzIDAgNi4wODUtMS4zODcgNy42MzktMi43MDggMS40ODMtMS4yNjUgMS45NjgtMi43MiAyLjUyOC00LjY4OWwxLjMyNC02LjI2OGgtMTAuODQ4bC0xLjM4NCA0LjQyMXoiIGZpbGw9IiNGRUZFRkUiLz48L3N2Zz4=\");\n  }\n  .rccs__card--visa .rccs__card__background,\n  .rccs__card--visaelectron .rccs__card__background {\n    background: linear-gradient(25deg, #0f509e, #1399cd);\n  }\n  .rccs__card--visa .rccs__issuer,\n  .rccs__card--visaelectron .rccs__issuer {\n    background-size: 75%;\n  }\n  .rccs__card--visa .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSIxNjZweCIgdmlld0JveD0iMCAwIDUxMiAxNjYiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgICA8Zz4gICAgICAgIDxwYXRoIGQ9Ik0yNjQuNzk0MTg3LDExMi40Nzk0OTEgQzI2NC41MDIwNzIsODkuNDQ4NTYxNiAyODUuMzE5MDgsNzYuNTk1NTE5OCAzMDEuMDAxMDIxLDY4Ljk1NDQxNzIgQzMxNy4xMTM0NDcsNjEuMTEzNDQ2NiAzMjIuNTI1MjU0LDU2LjA4NjAwMDggMzIyLjQ2Mzc1Niw0OS4wNzUyNTA3IEMzMjIuMzQwNzYsMzguMzQzODgzMyAzMDkuNjEwNzE0LDMzLjYwODU1MiAyOTcuNjk1NTE0LDMzLjQyNDA1ODYgQzI3Ni45MDkyNTUsMzMuMTAxMTk1MSAyNjQuODI0OTM1LDM5LjAzNTczMzYgMjU1LjIxNTkwMyw0My41MjUwNzM2IEwyNDcuNzI4NTQ1LDguNDg2Njk3NSBDMjU3LjM2ODMyNiw0LjA0MzQ4MDg3IDI3NS4yMTgwNjUsMC4xNjkxMTg5NzIgMjkzLjcyODkwNSwtMS40MjEwODU0N2UtMTQgQzMzNy4xNzcxMDYsLTEuNDIxMDg1NDdlLTE0IDM2NS42MDQ0NjgsMjEuNDQ3MzYwNSAzNjUuNzU4MjEzLDU0LjcwMjMwMDIgQzM2NS45MjczMzIsOTYuOTA1MTcwOSAzMDcuMzgxNDE5LDk5LjI0MjA4NzYgMzA3Ljc4MTE1NCwxMTguMTA2NTQgQzMwNy45MTk1MjQsMTIzLjgyNTgzNiAzMTMuMzc3NDU1LDEyOS45Mjk0OTQgMzI1LjMzODc3OCwxMzEuNDgyMzEzIEMzMzEuMjU3OTQyLDEzMi4yNjY0MSAzNDcuNjAwOTg1LDEzMi44NjYwMTQgMzY2LjEyNzIsMTI0LjMzMzE5MyBMMzczLjM5OTMxNSwxNTguMjMzODYgQzM2My40MzY2NywxNjEuODYyMjMgMzUwLjYyOTc1MiwxNjUuMzM2ODU3IDMzNC42ODY0NDUsMTY1LjMzNjg1NyBDMjkzLjc5MDQwMywxNjUuMzM2ODU3IDI2NS4wMjQ4MDMsMTQzLjU5NzM4MiAyNjQuNzk0MTg3LDExMi40Nzk0OTEgTTQ0My4yNzYyLDE2Mi40MTU3MTEgQzQzNS4zNDI5ODIsMTYyLjQxNTcxMSA0MjguNjU1MDk2LDE1Ny43ODgwMDEgNDI1LjY3MjQ1MiwxNTAuNjg1MDA0IEwzNjMuNjA1Nzg5LDIuNDkwNjYxMjIgTDQwNy4wMjMyNDIsMi40OTA2NjEyMiBMNDE1LjY2MzY4NCwyNi4zNjcxODUyIEw0NjguNzIwOTE4LDI2LjM2NzE4NTIgTDQ3My43MzI5ODksMi40OTA2NjEyMiBMNTEyLDIuNDkwNjYxMjIgTDQ3OC42MDY2OSwxNjIuNDE1NzExIEw0NDMuMjc2MiwxNjIuNDE1NzExIE00NDkuMzQ5MTA4LDExOS4yMTM1MDEgTDQ2MS44NzkyODcsNTkuMTYwODkxMiBMNDI3LjU2MzUxLDU5LjE2MDg5MTIgTDQ0OS4zNDkxMDgsMTE5LjIxMzUwMSBNMjEyLjE1MjA2MywxNjIuNDE1NzExIEwxNzcuOTI4NTMzLDIuNDkwNjYxMjIgTDIxOS4zMDExODMsMi40OTA2NjEyMiBMMjUzLjUwOTMzOSwxNjIuNDE1NzExIEwyMTIuMTUyMDYzLDE2Mi40MTU3MTEgTTE1MC45NDYzNywxNjIuNDE1NzExIEwxMDcuODgyNTMsNTMuNTY0NTkwNyBMOTAuNDYzMjc1NSwxNDYuMTE4NzkyIEM4OC40MTg0NzM0LDE1Ni40NTA0MjMgODAuMzQ2ODg2MSwxNjIuNDE1NzExIDcxLjM4MzU4MDYsMTYyLjQxNTcxMSBMMC45ODM5NjQ5MjcsMTYyLjQxNTcxMSBMMCwxNTcuNzcyNjI2IEMxNC40NTE5ODQ5LDE1NC42MzYyMzggMzAuODcxODk5NiwxNDkuNTc4MDQzIDQwLjgxOTE3LDE0NC4xNjYyMzYgQzQ2LjkwNzQ1MywxNDAuODYwNzI5IDQ4LjY0NDc2NjEsMTM3Ljk3MDMzMiA1MC42NDM0NDQ4LDEzMC4xMTM5ODcgTDgzLjYzNzAxODgsMi40OTA2NjEyMiBMMTI3LjM2MTk2LDIuNDkwNjYxMjIgTDE5NC4zOTQ1NzEsMTYyLjQxNTcxMSBMMTUwLjk0NjM3LDE2Mi40MTU3MTEiIGZpbGw9IiNGRkZGRkYiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI1Ni4wMDAwMDAsIDgyLjY2ODQyOCkgc2NhbGUoMSwgLTEpIHRyYW5zbGF0ZSgtMjU2LjAwMDAwMCwgLTgyLjY2ODQyOCkgIj48L3BhdGg+ICAgIDwvZz48L3N2Zz4=\");\n  }\n  .rccs__card--visaelectron .rccs__issuer {\n    background-image: url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSI1MTJweCIgaGVpZ2h0PSIyMjhweCIgdmlld0JveD0iMCAwIDUxMiAyMjgiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiPiAgICA8Zz4gICAgICAgIDxwYXRoIGQ9Ik0xOTQuMzkzMDEyLDIuOTE5MzQ0MTMgTDEyNy4zNjI1MTcsMTYyLjgzNTk4MSBMODMuNjI3OTMwNywxNjIuODM1OTgxIEw1MC42MzkwMTUyLDM1LjIwODY2MzIgQzQ4LjY0MTU2OTIsMjcuMzY1OTkwNyA0Ni45MDIzODU1LDI0LjQ3OTMzOCA0MC44MTUyNDI0LDIxLjE2NDQyNzYgQzMwLjg2NzI0MjIsMTUuNzYwNTM1MyAxNC40Mzk4MDE4LDEwLjcwNjQ0MTIgMCw3LjU2MTUyNjI4IEwwLjk3NDIwNDQyNCwyLjkxOTM0NDEzIEw3MS4zODE3MjM1LDIuOTE5MzQ0MTMgQzgwLjM0MjQ0MjcsMi45MTkzNDQxMyA4OC40MTA2ODYsOC44ODU1Mjg5NCA5MC40NjA0MzgzLDE5LjIxNjAxODggTDEwNy44OTE1MDUsMTExLjc2MjE3IEwxNTAuOTIzMjI2LDIuOTE5MzQ0MTMgTDE5NC4zOTMwMTIsMi45MTkzNDQxMyBaIE0yNTMuNTE1NDUyLDIuOTE5MzQ0MTMgTDIxOS4zMDcxNDYsMTYyLjgzNTk4MSBMMTc3LjkzMjg4LDE2Mi44MzU5ODEgTDIxMi4xNDExODYsMi45MTkzNDQxMyBMMjUzLjUxNTQ1MiwyLjkxOTM0NDEzIFogTTMwNy43Nzk5NDYsNDcuMjI5Mjk5NyBDMzA3LjkyMDUxOSw0MS40OTg0OTMxIDMxMy4zNzk5ODcsMzUuMzk1MDA0MyAzMjUuMzMxOTcxLDMzLjgzNTYyMzQgQzMzMS4yNTIzODgsMzMuMDcwNjQ0MSAzNDcuNjA3OTA3LDMyLjQ1OTMxNDUgMzY2LjEzNDEzNyw0MC45OTUwNDUyIEwzNzMuMzgxODI2LDcuMDY0NjE2NjQgQzM2My40MjcyODcsMy40NjUyOTA5IDM1MC42MTg3ODcsMCAzMzQuNjg0OTg3LDAgQzI5My43ODQ3NDcsMCAyNjUuMDEzMDI1LDIxLjcyMzQ1MSAyNjQuNzg0MTg2LDUyLjg1NTQ5MzcgQzI2NC41MTYxMTYsNzUuODgzMzMyNSAyODUuMzM0MDE0LDg4LjcxNzk4NTQgMzAwLjk4OTkzNyw5Ni4zODczOTM0IEMzMTcuMTE2NjE2LDEwNC4yMjAyNTggMzIyLjUyMzc3OCwxMDkuMjU0NzM4IDMyMi40NDg1ODgsMTE2LjI1Mzk3MSBDMzIyLjMzNDE2OCwxMjYuOTgzMjk3IDMwOS41NzE0MzYsMTMxLjczMzM2MSAyOTcuNzA0NDQ5LDEzMS45MDk4OTQgQzI3Ni44OTYzNTgsMTMyLjI0MDA3OCAyNjQuODMzMjIzLDEyNi4yODY5NjkgMjU1LjIxMjEzNywxMjEuODA0OTc1IEwyNDcuNzAyOTE3LDE1Ni44NTk5ODkgQzI1Ny4zODI4NDcsMTYxLjI5NjIxNSAyNzUuMjIyNTU3LDE2NS4xNTA1MzQgMjkzLjY5OTc1LDE2NS4zNDY2ODIgQzMzNy4xNzkzNDMsMTY1LjM0NjY4MiAzNjUuNjE3NjEzLDE0My44NzE2ODYgMzY1Ljc0NTEwOSwxMTAuNjI0NTA4IEMzNjUuOTE4Mzc0LDY4LjQyNjQxODggMzA3LjM5NzQ1Niw2Ni4wODU3MTI4IDMwNy43Nzk5NDYsNDcuMjI5Mjk5NyBaIE00NzMuNzQ3NzY1LDE2Mi44MzU5ODEgTDUxMiwxNjIuODM1OTgxIEw0NzguNTc5NTU4LDIuOTE5MzQ0MTMgTDQ0My4yODU4OTcsMi45MTkzNDQxMyBDNDM1LjMyNTUzNSwyLjkxOTM0NDEzIDQyOC42MzY4Nyw3LjUzODY0MjI4IDQyNS42Njg0ODksMTQuNjQyNDg4NiBMMzYzLjU4NzQ3NSwxNjIuODM1OTgxIEw0MDcuMDM0Mzc3LDE2Mi44MzU5ODEgTDQxNS42NTE4MzYsMTM4Ljk0ODM1OCBMNDY4LjczMjkwMSwxMzguOTQ4MzU4IEw0NzMuNzQ3NzY1LDE2Mi44MzU5ODEgWiBNNDI3LjU2NDU5MSwxMDYuMTc4NDc1IEw0NDkuMzUwMTU2LDQ2LjEyNDMyOTYgTDQ2MS44NjQ0MzMsMTA2LjE3ODQ3NSBMNDI3LjU2NDU5MSwxMDYuMTc4NDc1IFogTTMwNi40NjQ3NywyMDYuODU0MzI5IEwyODkuNjU0ODQsMjA2Ljg1NDMyOSBMMjg5LjY1NDg0LDIyMi41MDA0NDQgTDMwOC40NTg5NDcsMjIyLjUwMDQ0NCBMMzA4LjQ1ODk0NywyMjcuMjA0NzQgTDI4My45ODk0MTYsMjI3LjIwNDc0IEwyODMuOTg5NDE2LDE4My43OTcwNjggTDMwNy40OTQ1NSwxODMuNzk3MDY4IEwzMDcuNDk0NTUsMTg4LjUwMTM2NCBMMjg5LjY1NDg0LDE4OC41MDEzNjQgTDI4OS42NTQ4NCwyMDIuMjE1NDE2IEwzMDYuNDY0NzcsMjAyLjIxNTQxNiBMMzA2LjQ2NDc3LDIwNi44NTQzMjkgWiBNMzE3LjE0MzQyMywxODEuNDgxMjA4IEwzMjIuODA4ODQ3LDE4MS40ODEyMDggTDMyMi44MDg4NDcsMjI3LjIwMzQzMyBMMzE3LjE0MzQyMywyMjcuMjAzNDMzIEwzMTcuMTQzNDIzLDE4MS40ODEyMDggWiBNMzQ3Ljc4NzM4MywyMjMuNDY5MDkxIEMzNTEuODQ3NjU4LDIyMy40NjkwOTEgMzU0LjM1ODM1OSwyMjIuNzU5Njg3IDM1Ni40MjExODgsMjIxLjg2MDY3MyBMMzU3LjQ1MDk2OCwyMjUuOTE3Njc5IEMzNTUuNDUzNTIyLDIyNi44MTY2OTMgMzUxLjk3ODQyNCwyMjcuOTExODU2IDM0Ny4wMTU4NjYsMjI3LjkxMTg1NiBDMzM3LjQyNDIwMiwyMjcuOTExODU2IDMzMS42OTMzOTUsMjIxLjUzNzAyOCAzMzEuNjkzMzk1LDIxMi4xMzQ5NzUgQzMzMS42OTMzOTUsMjAyLjczMjkyMSAzMzcuMjI4MDUzLDE5NS4zOTA0MjggMzQ2LjMwOTczMSwxOTUuMzkwNDI4IEMzNTYuNTQ4Njg1LDE5NS4zOTA0MjggMzU5LjE5MDE1MiwyMDQuMjc5MjI2IDM1OS4xOTAxNTIsMjEwLjAxMDAzMiBDMzU5LjE5MDE1MiwyMTEuMTY3MzA5IDM1OS4xMjQ3NjksMjEyLjAwNDIwOSAzNTguOTk0MDAzLDIxMi42NDgyMyBMMzM3LjEwMDU1NywyMTIuNjQ4MjMgQzMzNy4yMjgwNTMsMjIwLjMxNDM2OSAzNDIuMDU5ODQ2LDIyMy40NjkwOTEgMzQ3Ljc4NzM4MywyMjMuNDY5MDkxIFogTTM1My43MTQzMzgsMjA4LjU5MTIyNCBDMzUzLjc3OTcyMSwyMDUuMDUwNzQzIDM1Mi4yMzM0MTcsMTk5LjQ0NzQzMyAzNDUuODU4NTg5LDE5OS40NDc0MzMgQzM0MC4wNjI0LDE5OS40NDc0MzMgMzM3LjYxMzgxMiwyMDQuNjY0OTg0IDMzNy4xNjI2NywyMDguNTkxMjI0IEwzNTMuNzE0MzM4LDIwOC41OTEyMjQgWiBNMzkwLjAyMjc0MSwyMjYuMTA4NTk3IEMzODguNTQxODE5LDIyNi44MTgwMDEgMzg1LjI1NjMzMSwyMjcuOTEzMTYzIDM4MS4wNzE4MjksMjI3LjkxMzE2MyBDMzcxLjY2OTc3NiwyMjcuOTEzMTYzIDM2NS41NTMyMSwyMjEuNTM4MzM2IDM2NS41NTMyMSwyMTIuMDA1NTE3IEMzNjUuNTUzMjEsMjAyLjQxMDU4NCAzNzIuMTE3NjQ4LDE5NS4zOTE3MzUgMzgyLjI5NDQ4OCwxOTUuMzkxNzM1IEMzODUuNjQyMDksMTk1LjM5MTczNSAzODguNjAzOTMzLDE5Ni4yMjUzNjcgMzkwLjE1MDIzOCwxOTcuMDY1NTM2IEwzODguODY1NDY1LDIwMS4zODA4MDQgQzM4Ny41MDg3NywyMDAuNjcxNCAzODUuMzgzODI4LDE5OS44OTY2MTMgMzgyLjI5NDQ4OCwxOTkuODk2NjEzIEMzNzUuMTQ0ODc0LDE5OS44OTY2MTMgMzcxLjI4NDAxNywyMDUuMjQxNjYxIDM3MS4yODQwMTcsMjExLjY4NTE0MSBDMzcxLjI4NDAxNywyMTguODk2ODY5IDM3NS45MTk2NjEsMjIzLjMzOTYzMyAzODIuMTAxNjA5LDIyMy4zMzk2MzMgQzM4NS4zMjE3MTQsMjIzLjMzOTYzMyAzODcuNDQ2NjU3LDIyMi41NjgxMTYgMzg5LjA1NTA3NSwyMjEuODU4NzEyIEwzOTAuMDIyNzQxLDIyNi4xMDg1OTcgWiBNNDA1LjkxODI5MiwxODguNTY0NDU4IEw0MDUuOTE4MjkyLDE5Ni4wMzQ0NDkgTDQxNC4wMjkwMzQsMTk2LjAzNDQ0OSBMNDE0LjAyOTAzNCwyMDAuMzQ2NDQ3IEw0MDUuOTE4MjkyLDIwMC4zNDY0NDcgTDQwNS45MTgyOTIsMjE3LjE1NjM3NyBDNDA1LjkxODI5MiwyMjEuMDIzNzczIDQwNy4wMTM0NTUsMjIzLjIxMDgyOSA0MTAuMTY4MTc3LDIyMy4yMTA4MjkgQzQxMS43MTEyMTIsMjIzLjIxMDgyOSA0MTIuNjE2NzY1LDIyMy4wODMzMzIgNDEzLjQ1MzY2NSwyMjIuODIxODAxIEw0MTMuNzExOTI3LDIyNy4xNDAzMzggQzQxMi42MTY3NjUsMjI3LjUyNjA5NyA0MTAuODc3NTgxLDIyNy45MTE4NTYgNDA4LjY4NzI1NSwyMjcuOTExODU2IEM0MDYuMDQ1Nzg4LDIyNy45MTE4NTYgNDAzLjkyMDg0NiwyMjcuMDA5NTcyIDQwMi41NzA2OSwyMjUuNTMxOTIgQzQwMS4wMjQzODYsMjIzLjc4OTQ2NyA0MDAuMzgwMzY1LDIyMS4wMjM3NzMgNDAwLjM4MDM2NSwyMTcuMzUyNTI2IEw0MDAuMzgwMzY1LDIwMC4zNDY0NDcgTDM5NS41NDg1NzIsMjAwLjM0NjQ0NyBMMzk1LjU0ODU3MiwxOTYuMDM0NDQ5IEw0MDAuMzgwMzY1LDE5Ni4wMzQ0NDkgTDQwMC4zODAzNjUsMTkwLjIzODI1OSBMNDA1LjkxODI5MiwxODguNTY0NDU4IFogTTQyMS45NDQ5MzUsMjA1Ljc1OTQ5MyBDNDIxLjk0NDkzNSwyMDIuMDg4MjQ2IDQyMS44NzYyODMsMTk4LjkzMzUyNCA0MjEuNjg2NjczLDE5Ni4wMzM3OTUgTDQyNi42NDU5NjIsMTk2LjAzMzc5NSBMNDI2LjkwNDIyNCwyMDIuMjE1NzQzIEw0MjcuMDkzODM1LDIwMi4yMTU3NDMgQzQyOC41MTI2NDIsMTk4LjAzMTI0MSA0MzEuOTg3NzQxLDE5NS4zODk3NzQgNDM1Ljc4NjQ4NCwxOTUuMzg5Nzc0IEM0MzYuMzY4MzkxLDE5NS4zODk3NzQgNDM2LjgxOTUzMywxOTUuNDU1MTU3IDQzNy4zMzYwNTgsMTk1LjUxNzI3IEw0MzcuMzM2MDU4LDIwMC44NjU1ODcgQzQzNi43NTQxNSwyMDAuNzM0ODIxIDQzNi4xNzg3ODEsMjAwLjczNDgyMSA0MzUuNDAwNzI1LDIwMC43MzQ4MjEgQzQzMS40MTIzNzIsMjAwLjczNDgyMSA0MjguNTc0NzU2LDIwMy42OTY2NjQgNDI3LjgwMzIzOCwyMDcuOTQ5ODE5IEM0MjcuNjc1NzQyLDIwOC43MjEzMzYgNDI3LjYxMDM1OSwyMDkuNjg1NzMzIDQyNy42MTAzNTksMjEwLjU5MTI4NiBMNDI3LjYxMDM1OSwyMjcuMjA1MDY3IEw0MjEuOTQ0OTM1LDIyNy4yMDUwNjcgTDQyMS45NDQ5MzUsMjA1Ljc1OTQ5MyBaIE00NzIuMTY2NDgxLDIxMS4zNjExNjkgQzQ3Mi4xNjY0ODEsMjIyLjg4ODE2NSA0NjQuMTE0NTgzLDIyNy45MTI4MzYgNDU2LjY0NDU5MywyMjcuOTEyODM2IEM0NDguMjcyMzIsMjI3LjkxMjgzNiA0NDEuNzA3ODgyLDIyMS43Mjc2MTkgNDQxLjcwNzg4MiwyMTEuODc3NjkzIEM0NDEuNzA3ODgyLDIwMS41MDc5NzQgNDQ4LjU5NTk2NSwxOTUuMzkxNDA4IDQ1Ny4xNjExMTgsMTk1LjM5MTQwOCBDNDY2LjExMjAyOSwxOTUuMzkxNDA4IDQ3Mi4xNjY0ODEsMjAxLjg5MzczMiA0NzIuMTY2NDgxLDIxMS4zNjExNjkgWiBNNDQ3LjUwMDgwMiwyMTEuNjg0ODE0IEM0NDcuNTAwODAyLDIxOC41MTA3ODMgNDUxLjM2NDkyOCwyMjMuNjYyOTUxIDQ1Ni45MDI4NTUsMjIzLjY2Mjk1MSBDNDYyLjMxMzI4NiwyMjMuNjYyOTUxIDQ2Ni4zNjcwMjMsMjE4LjU3Mjg5NyA0NjYuMzY3MDIzLDIxMS41NTQwNDggQzQ2Ni4zNjcwMjMsMjA2LjI3NDM4MyA0NjMuNzI4ODI1LDE5OS42MzgwMjQgNDU3LjAzMDM1MiwxOTkuNjM4MDI0IEM0NTAuNDAwNTMxLDE5OS42MzgwMjQgNDQ3LjUwMDgwMiwyMDUuODIzMjQyIDQ0Ny41MDA4MDIsMjExLjY4NDgxNCBaIE00ODAuODQ5OTc3LDIwNC40Njk0OSBDNDgwLjg0OTk3NywyMDEuMTg3MjcxIDQ4MC43ODEzMjUsMTk4LjYxMTE4NyA0ODAuNTkxNzE1LDE5Ni4wMzUxMDIgTDQ4NS42MTMxMTcsMTk2LjAzNTEwMiBMNDg1LjkzNjc2MywyMDEuMTg3MjcxIEw0ODYuMDY0MjU5LDIwMS4xODcyNzEgQzQ4Ny42MTA1NjMsMTk4LjI4NzU0MiA0OTEuMjE2NDI3LDE5NS4zOTEwODEgNDk2LjM2ODU5NiwxOTUuMzkxMDgxIEM1MDAuNjgwNTk1LDE5NS4zOTEwODEgNTA3LjM3OTA2NywxOTcuOTY3MTY2IDUwNy4zNzkwNjcsMjA4LjY1Mzk5MiBMNTA3LjM3OTA2NywyMjcuMjAzMTA2IEw1MDEuNzEzNjQ0LDIyNy4yMDMxMDYgTDUwMS43MTM2NDQsMjA5LjIzNTg5OSBDNTAxLjcxMzY0NCwyMDQuMjE0NDk3IDQ5OS44NDY5NjMsMjAwLjAyNjcyNSA0OTQuNTAxOTE2LDIwMC4wMjY3MjUgQzQ5MC44MzA2NjksMjAwLjAyNjcyNSA0ODcuOTMwOTM5LDIwMi42NjgxOTIgNDg2LjkwNDQyOSwyMDUuODIyOTE1IEM0ODYuNjQyODk3LDIwNi41MzIzMTkgNDg2LjUxNTQwMSwyMDcuNDk2NzE2IDQ4Ni41MTU0MDEsMjA4LjQ2NDM4MiBMNDg2LjUxNTQwMSwyMjcuMjAzMTA2IEw0ODAuODQ5OTc3LDIyNy4yMDMxMDYgTDQ4MC44NDk5NzcsMjA0LjQ2OTQ5IFoiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4gICAgPC9nPjwvc3ZnPg==\");\n  }\n  .rccs__number {\n    clear: both;\n    font-family: Consolas, Courier, monospace;\n    font-size: 20px;\n    left: 10%;\n    position: absolute;\n    top: 45%;\n  }\n  .rccs__number.rccs__number--large {\n    font-size: 17px;\n  }\n  .rccs__name {\n    bottom: 15%;\n    font-family: Consolas, Courier, monospace;\n    font-size: 17px;\n    left: 10%;\n    line-height: 1;\n    overflow: hidden;\n    position: absolute;\n    text-align: left;\n    text-overflow: ellipsis;\n    text-transform: uppercase;\n    width: 60%;\n  }\n  .rccs__expiry {\n    bottom: 15%;\n    font-size: 0;\n    line-height: 1;\n    position: absolute;\n    right: 10%;\n  }\n  .rccs__expiry > * {\n    vertical-align: middle;\n  }\n  .rccs__expiry__valid {\n    font-size: 10px;\n    margin-bottom: 5px;\n  }\n  .rccs__expiry__value {\n    font-family: Consolas, Courier, monospace;\n    font-size: 16px;\n  }\n  .rccs__number,\n  .rccs__name,\n  .rccs__expiry,\n  .rccs__cvc {\n    opacity: 0.5;\n    -webkit-transition: opacity 0.3s;\n    transition: opacity 0.3s;\n  }\n  .rccs__chip {\n    background-image: url(\"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwIiBoZWlnaHQ9Ijc2IiB2aWV3Qm94PSIwIDAgMTAwIDc2IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj48ZGVmcz48bGluZWFyR3JhZGllbnQgeDE9IjEwMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSIgaWQ9ImEiPjxzdG9wIHN0b3AtY29sb3I9IiNGM0QwOEYiIG9mZnNldD0iMCUiLz48c3RvcCBzdG9wLWNvbG9yPSIjRkFENzY2IiBvZmZzZXQ9IjEwMCUiLz48L2xpbmVhckdyYWRpZW50PjwvZGVmcz48cGF0aCBkPSJNOTIuNzI3IDc1LjQ1NWgtODUuNDU1Yy00IDAtNy4yNzMtMy4yNzMtNy4yNzMtNy4yNzN2LTYwLjkwOWMwLTQgMy4yNzMtNy4yNzMgNy4yNzMtNy4yNzNoODUuNDU1YzQgMCA3LjI3MyAzLjI3MyA3LjI3MyA3LjI3M3Y2MC45MDljMCA0LTMuMjczIDcuMjczLTcuMjczIDcuMjczIiBmaWxsPSJ1cmwoI2EpIi8+PHBhdGggZD0iTTcyLjEyMyAyOC40ODVoMjcuODc4di0xLjgxOGgtMjkuNjQ4Yy0uOTY1IDAtMS44MzIuNjAxLTIuMTcyIDEuNTA0LTIuMjg3IDYuMDcyLTIuNDMzIDEyLjU5NC0uNDM4IDE5Ljg0Mi40NTUgMS42NTQuNDM1IDMuNC0uMSA1LjAzLTIuMDM2IDYuMTk1LTcuNzc5IDE5Ljk4OC0xOC41NTEgMTkuOTg4LTExLjAwOCAwLTE2LjA5Ni0xNS42OTktMTcuMzM0LTIxLjk1Mi0uMTU1LS43ODQtLjEyMi0xLjU5Mi4xMDctMi4zNTcgMS42OTUtNS42NDggMi4wOTQtMTAuNjQtLjAxNi0xOS41OS0uMjA1LS44Ny0uMTgyLTEuNzgzLjA0OC0yLjY0NiA0LjQ4LTE2Ljc1NSAxMi44ODItMjAuMTQ3IDEyLjk2NS0yMC4xNzkuMzU2LS4xMzIuNTkzLS40NzIuNTkzLS44NTJ2LTUuNDU1aC0xLjgxOHYzLjc3NmMwIC42NS0uMzMyIDEuMjUyLS44ODQgMS41OTYtMi44MDMgMS43NDItOC45MDQgNi45MzYtMTIuNTU3IDIwLjQ1Ni0uMTguNjY4LS43ODEgMS4xMzYtMS40NzMgMS4xMzNsLTI4LjcyMi0uMTM5djEuODE4bDI3LjQxNi4xMzNjMS40NjguMDA3IDIuNzM1IDEuMDQxIDMuMDM3IDIuNDc4IDEuNDE2IDYuNzQxIDEuMjE5IDExLjAzOS4wODIgMTUuNDU4LS4zMTYgMS4yMy0xLjQyIDIuMDk2LTIuNjkgMi4xMDlsLTI3Ljg0NC4yN3YxLjgxOWwyOC42MDUtLjI3OGMuNjkzLS4wMDcgMS4yOTYuNDczIDEuNDM1IDEuMTUyIDEuNDQyIDcuMDQxIDYuODg3IDIzLjA3IDE5LjA1IDIzLjA3IDYuMzY4IDAgMTIuMDYyLTQuMjUgMTYuNDY3LTEyLjI5IDIuNjQ0LTQuODI4IDQuMDY3LTkuNTkxIDQuNTQxLTExLjM0NmgyOS45MDF2LTEuODE4aC0yOC4wMTZjLTEuMTU4IDAtMi4xODMtLjc3Mi0yLjQ4OS0xLjg4OS0xLjY5Mi02LjE2NC0xLjc2MS0xMS43NTUtLjItMTYuOTU5LjM3MS0xLjIzNSAxLjUzOC0yLjA2MSAyLjgyNy0yLjA2MXptLTE3LjE1LTIxLjkxNGMuMDQ1LjAyMiA0LjUxOSAyLjMyMiA5LjI1MyAxMC4wNDEuMTcyLjI4LjQ3LjQzNC43NzYuNDM0LjE5OCAwIC4zOTktLjA2NC41NzEtLjIwMi4zNjUtLjI5Mi40MTYtLjgzNy4xNzItMS4yMzUtMy41Ny01LjgwNS03LjAyNC04LjcxLTguNzc1LTkuOTMxLS40My0uMjk5LS42OC0uNzkyLS42OC0xLjMxNXYtNC4zNjNoLTEuODE4djUuNzU4YzAgLjM0NS4xOTUuNjU5LjUwMi44MTN6IiBmaWxsPSIjMEMwMjAwIi8+PC9zdmc+\");\n    background-repeat: no-repeat;\n    background-size: contain;\n    height: 26.36364px;\n    left: 10%;\n    position: absolute;\n    top: 10%;\n    width: 41.42857px;\n  }\n  .rccs__issuer {\n    background-position: top right;\n    background-repeat: no-repeat;\n    background-size: contain;\n    height: 23%;\n    position: absolute;\n    right: 10%;\n    top: 10%;\n    width: 40%;\n  }\n  .rccs__stripe {\n    background-color: #2a1d16;\n    height: 22%;\n    left: 0;\n    position: absolute;\n    top: 9%;\n    width: 100%;\n  }\n  .rccs__signature {\n    background: repeating-linear-gradient(\n      0.1deg,\n      #fff 20%,\n      #fff 40%,\n      #fea 40%,\n      #fea 44%,\n      #fff 44%\n    );\n    height: 18%;\n    left: 5%;\n    position: absolute;\n    top: 35%;\n    width: 75%;\n  }\n  .rccs__cvc {\n    color: #222;\n    font-family: Consolas, Courier, monospace;\n    font-size: 14px;\n    left: 67%;\n    line-height: 1;\n    position: absolute;\n    top: 42%;\n  }\n  .rccs__cvc__front {\n    font-family: Consolas, Courier, monospace;\n    font-size: 11.9px;\n    opacity: 0;\n    position: absolute;\n    right: 10%;\n    top: 38%;\n    visibility: hidden;\n  }\n  .rccs--filled {\n    opacity: 0.8 !important;\n  }\n  .rccs--focused {\n    font-weight: 700;\n    opacity: 1 !important;\n  }\n`;\n\nexport default (props) => (\n  <Container>\n    <Cards {...props} />\n  </Container>\n);\n"
  },
  {
    "path": "examples/credit-card/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      position: relative;\n      padding: 8px 5px;\n      border: 1px solid transparent;\n      &.active {\n        background-color: paleturquoise;\n        border-color: turquoise;\n      }\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > .downshift > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 6px 9px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n        &[disabled] {\n          background: #eee;\n        }\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          margin-left: 0;\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n        &.downshift {\n          margin-left: 0;\n          padding-left: 15px;\n          flex: 1;\n          & > input {\n            width: 100%;\n            padding: 6px 5px;\n            font-size: 1em;\n            margin-left: 0;\n            border: 1px solid #ccc;\n            border-radius: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n  .downshift-options {\n    border: 1px solid #ddd;\n    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);\n    & > div {\n      padding: 3px 5px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/credit-card/cardUtils.js",
    "content": "import Payment from \"payment\";\n\nfunction clearNumber(value = \"\") {\n  return value.replace(/\\D+/g, \"\");\n}\n\nexport function formatCreditCardNumber(value) {\n  if (!value) {\n    return value;\n  }\n\n  const issuer = Payment.fns.cardType(value);\n  const clearValue = clearNumber(value);\n  let nextValue;\n\n  switch (issuer) {\n    case \"amex\":\n      nextValue = `${clearValue.slice(0, 4)} ${clearValue.slice(\n        4,\n        10,\n      )} ${clearValue.slice(10, 15)}`;\n      break;\n    case \"dinersclub\":\n      nextValue = `${clearValue.slice(0, 4)} ${clearValue.slice(\n        4,\n        10,\n      )} ${clearValue.slice(10, 14)}`;\n      break;\n    default:\n      nextValue = `${clearValue.slice(0, 4)} ${clearValue.slice(\n        4,\n        8,\n      )} ${clearValue.slice(8, 12)} ${clearValue.slice(12, 19)}`;\n      break;\n  }\n\n  return nextValue.trim();\n}\n\nexport function formatCVC(value, prevValue, allValues = {}) {\n  const clearValue = clearNumber(value);\n  let maxLength = 4;\n\n  if (allValues.number) {\n    const issuer = Payment.fns.cardType(allValues.number);\n    maxLength = issuer === \"amex\" ? 4 : 3;\n  }\n\n  return clearValue.slice(0, maxLength);\n}\n\nexport function formatExpirationDate(value) {\n  const clearValue = clearNumber(value);\n\n  if (clearValue.length >= 3) {\n    return `${clearValue.slice(0, 2)}/${clearValue.slice(2, 4)}`;\n  }\n\n  return clearValue;\n}\n"
  },
  {
    "path": "examples/credit-card/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport Card from \"./Card\";\nimport {\n  formatCreditCardNumber,\n  formatCVC,\n  formatExpirationDate,\n} from \"./cardUtils\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Credit Card Example</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      This example demonstrates how to use the amazing{\" \"}\n      <a\n        href=\"https://github.com/amarofashion/react-credit-cards\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        React Credit Cards\n      </a>{\" \"}\n      library with your form.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      render={({\n        handleSubmit,\n        form,\n        submitting,\n        pristine,\n        values,\n        active,\n      }) => {\n        return (\n          <form onSubmit={handleSubmit}>\n            <Card\n              number={values.number || \"\"}\n              name={values.name || \"\"}\n              expiry={values.expiry || \"\"}\n              cvc={values.cvc || \"\"}\n              focused={active}\n            />\n            <div>\n              <Field\n                name=\"number\"\n                component=\"input\"\n                type=\"text\"\n                pattern=\"[\\d| ]{16,22}\"\n                placeholder=\"Card Number\"\n                format={formatCreditCardNumber}\n              />\n            </div>\n            <div>\n              <Field\n                name=\"name\"\n                component=\"input\"\n                type=\"text\"\n                placeholder=\"Name\"\n              />\n            </div>\n            <div>\n              <Field\n                name=\"expiry\"\n                component=\"input\"\n                type=\"text\"\n                pattern=\"\\d\\d/\\d\\d\"\n                placeholder=\"Valid Thru\"\n                format={formatExpirationDate}\n              />\n              <Field\n                name=\"cvc\"\n                component=\"input\"\n                type=\"text\"\n                pattern=\"\\d{3,4}\"\n                placeholder=\"CVC\"\n                format={formatCVC}\n              />\n            </div>\n            <div className=\"buttons\">\n              <button type=\"submit\" disabled={submitting}>\n                Submit\n              </button>\n              <button\n                type=\"button\"\n                onClick={form.reset}\n                disabled={submitting || pristine}\n              >\n                Reset\n              </button>\n            </div>\n            <h2>Values</h2>\n            <pre>{JSON.stringify(values, 0, 2)}</pre>\n          </form>\n        );\n      }}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/credit-card/package.json",
    "content": "{\n  \"name\": \"react-final-form-credit-card-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use 🏁 React Final Form with the React Credit Cards library.\",\n  \"keywords\": [\n    \"final-form\",\n    \"react-final-form\",\n    \"react-credit-cards\",\n    \"payment\",\n    \"credit cards\"\n  ],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-credit-cards\": \"0.7.0\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"3.0.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/credit-card/readme.md",
    "content": "# Credit Card Example\n\n[![Edit react-final-form-credit-card-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/9y8vkrrx9o)\n"
  },
  {
    "path": "examples/credit-card/sandbox.config.json",
    "content": "{\n  \"infiniteLoopProtection\": false,\n  \"hardReloadOnChange\": false\n}\n"
  },
  {
    "path": "examples/custom-validation-engine/OnBlurValidation.js",
    "content": "import React from \"react\";\nimport { getIn } from \"final-form\";\nimport { FormSpy } from \"react-final-form\";\n\nclass OnBlurValidation extends React.Component {\n  state = {\n    withError: {},\n    validating: false,\n  };\n\n  componentWillReceiveProps(nextProps) {\n    const field = this.props.active;\n    if (field && field !== nextProps.active) {\n      // blur occurred\n      const {\n        rules,\n        form: { mutators },\n        values,\n      } = nextProps;\n      const rule = rules[field];\n      if (rule) {\n        const value = getIn(values, field);\n        let isSync = false;\n        const setError = (error) => {\n          mutators.setFieldData(field, { error, validating: false });\n          isSync = true;\n          this.setState((state) => ({\n            withError: {\n              ...state.withError,\n              [field]: !!error,\n            },\n            validating: false,\n          }));\n        };\n        rule(value, setError);\n        if (!isSync) {\n          mutators.setFieldData(field, { validating: true });\n          this.setState({\n            validating: true,\n          });\n        }\n      }\n    }\n  }\n\n  render() {\n    const { withError, validating } = this.state;\n    const hasErrors = Object.keys(withError).some((key) => withError[key]);\n    return this.props.render({ hasErrors, validating });\n  }\n}\n\n// Make a HOC\nexport default (props) => (\n  <FormSpy\n    {...props}\n    subscription={{ active: true, values: true }}\n    component={OnBlurValidation}\n  />\n);\n"
  },
  {
    "path": "examples/custom-validation-engine/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/custom-validation-engine/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport Icon from \"react-fontawesome\";\nimport OnBlurValidation from \"./OnBlurValidation\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\nconst isBeatle = (value) =>\n  ~[\"john\", \"paul\", \"george\", \"ringo\"].indexOf(value.toLowerCase());\n\nconst Error = ({ name }) => (\n  <Field\n    name={name}\n    subscription={{ data: true }}\n    render={({ meta: { data } }) =>\n      data.error ? <span>{data.error}</span> : null\n    }\n  />\n);\nconst AsyncIndicator = ({ name }) => (\n  <Field\n    name={name}\n    subscription={{ data: true }}\n    render={({ meta: { data } }) =>\n      data.validating ? <Icon name=\"cog\" spin /> : null\n    }\n  />\n);\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Custom Validation Engine</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      This example includes a special <code>OnBlurValidation</code> component\n      that manages its own set of validation rules, completely apart from{\" \"}\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>\n      Final Form's validation engine. This allows the rules to be run only on\n      blur, and maintains \"validating\" state for asynchronous validations. The\n      function then injects the <code>hasErrors</code> state into a render\n      function to render the rest of the form, thus allowing submission to be\n      halted if errors are present.\n    </p>\n    <p>\n      Any first name value of <code>John</code>, <code>Paul</code>,{\" \"}\n      <code>George</code>, or <code>Ringo</code> will fail asynchronous\n      validation.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <OnBlurValidation\n          rules={{\n            firstName: (value, setError) => {\n              if (!value) {\n                // return synchronously\n                setError(\"Required\");\n              } else {\n                // return asynchronously\n                setTimeout(() => {\n                  if (isBeatle(value)) {\n                    setError(\"No Beatles\");\n                  } else {\n                    setError(undefined);\n                  }\n                }, 1000);\n              }\n            },\n            lastName: (value, setError) =>\n              setError(value ? undefined : \"Required\"),\n          }}\n          render={({ hasErrors, validating }) => (\n            <form\n              onSubmit={(event) => {\n                event.preventDefault();\n                if (!hasErrors && !validating) handleSubmit();\n              }}\n            >\n              <div>\n                <label>First Name</label>\n                <Field\n                  name=\"firstName\"\n                  component=\"input\"\n                  type=\"text\"\n                  placeholder=\"First Name\"\n                />\n                <AsyncIndicator name=\"firstName\" />\n                <Error name=\"firstName\" />\n              </div>\n              <div>\n                <label>Last Name</label>\n                <Field\n                  name=\"lastName\"\n                  component=\"input\"\n                  type=\"text\"\n                  placeholder=\"Last Name\"\n                />\n                <AsyncIndicator name=\"lastName\" />\n                <Error name=\"lastName\" />\n              </div>\n              <div>\n                <label>Email</label>\n                <Field\n                  name=\"email\"\n                  component=\"input\"\n                  type=\"email\"\n                  placeholder=\"Email\"\n                />\n                <AsyncIndicator name=\"email\" />\n                <Error name=\"email\" />\n              </div>\n              <div className=\"buttons\">\n                <button type=\"submit\" disabled={submitting || pristine}>\n                  Submit\n                </button>\n                <button\n                  type=\"button\"\n                  onClick={form.reset}\n                  disabled={submitting || pristine}\n                >\n                  Reset\n                </button>\n              </div>\n              <pre>{JSON.stringify(values, 0, 2)}</pre>\n            </form>\n          )}\n        />\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/custom-validation-engine/package.json",
    "content": "{\n  \"name\": \"react-final-form-custom-validation-engine\",\n  \"version\": \"1.0.0\",\n  \"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.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"final-form-set-field-data\": \"1.0.2\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-fontawesome\": \"1.6.1\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/custom-validation-engine/readme.md",
    "content": "# Custom Validation Engine\n\n[![Edit react-final-form-custom-validation-engine-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/kxxw4l0p9o)\n"
  },
  {
    "path": "examples/debounced-record-level-validation/ErrorWithDelay.js",
    "content": "import React from \"react\";\nimport { Field } from \"react-final-form\";\n\nconst DisplayError = ({ delay, active, dirty, error, touched, children }) => {\n  const [show, setShow] = React.useState(false);\n  React.useEffect(() => {\n    let timeout;\n    if (active && error && dirty) {\n      console.info(\"setting timeout\");\n      timeout = setTimeout(() => setShow(true), delay);\n    }\n    return () => {\n      console.info(\"clearing timeout\");\n      clearTimeout(timeout);\n    };\n  }, [delay, error, active, dirty]);\n\n  return error && ((touched && !active) || (touched && !show && active) || show)\n    ? children(error)\n    : null;\n};\n\nconst ErrorWithDelay = ({ name, children, delay }) => (\n  <Field\n    name={name}\n    subscription={{ active: true, error: true, dirty: true, touched: true }}\n  >\n    {({ meta: { active, dirty, error, touched } }) => (\n      <DisplayError\n        delay={delay}\n        active={active}\n        dirty={dirty}\n        error={error}\n        touched={touched}\n        children={children}\n      />\n    )}\n  </Field>\n);\n\nexport default ErrorWithDelay;\n"
  },
  {
    "path": "examples/debounced-record-level-validation/README.md",
    "content": "# Synchronous Record-Level Validation (with debounced errors)\n\n[![Edit react-final-form-debounced-record-level-validation-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/z2zqr008pm)"
  },
  {
    "path": "examples/debounced-record-level-validation/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n  h2 {\n    text-align: center;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n  }\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > span {\n        color: #800;\n        font-weight: bold;\n        line-height: 32px;\n        margin-left: 10px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/debounced-record-level-validation/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport ErrorWithDelay from \"./ErrorWithDelay\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Synchronous Record-Level Validation (with debounced errors)</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      The important feature of this demo is that the errors <em>disappear</em>{\" \"}\n      instantly when they are fixed, appear instantly when blurred, but{\" \"}\n      <em>appear</em> on a delay when the field is active. Notice that the delay\n      mechanism is entirely separate from Final Form, encapsulated into a{\" \"}\n      <code>ErrorWithDelay</code> component.\n    </p>\n    <p>\n      Things to try:\n      <ul>\n        <li>Tab through all fields and watch errors appear on blur.</li>\n        <li>\n          Remove first name value and notice how it doesn't complain for a\n          second.\n        </li>\n        <li>\n          Notice how you can type \"44\" as your age without the error for \"4\"\n          being an illegal value being displayed.\n        </li>\n      </ul>\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      initialValues={{ firstName: \"Bob\" }}\n      validate={(values) => {\n        const errors = {};\n        if (!values.firstName) {\n          errors.firstName = \"Required\";\n        }\n        if (!values.lastName) {\n          errors.lastName = \"Required\";\n        }\n        if (!values.age) {\n          errors.age = \"Required\";\n        } else if (isNaN(values.age)) {\n          errors.age = \"Must be a number\";\n        } else if (values.age < 18) {\n          errors.age = \"Must be >18\";\n        }\n        return errors;\n      }}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <Field name=\"firstName\">\n            {({ input, meta }) => (\n              <div>\n                <label>First Name</label>\n                <input {...input} type=\"text\" placeholder=\"First Name\" />\n                <ErrorWithDelay name=\"firstName\" delay={1000}>\n                  {(error) => <span>{error}</span>}\n                </ErrorWithDelay>\n              </div>\n            )}\n          </Field>\n          <Field name=\"lastName\">\n            {({ input, meta }) => (\n              <div>\n                <label>Last Name</label>\n                <input {...input} type=\"text\" placeholder=\"Last Name\" />\n                <ErrorWithDelay name=\"lastName\" delay={1000}>\n                  {(error) => <span>{error}</span>}\n                </ErrorWithDelay>\n              </div>\n            )}\n          </Field>\n          <Field name=\"age\">\n            {({ input, meta }) => (\n              <div>\n                <label>Age</label>\n                <input {...input} type=\"text\" placeholder=\"Age\" />\n                <ErrorWithDelay name=\"age\" delay={1000}>\n                  {(error) => <span>{error}</span>}\n                </ErrorWithDelay>\n              </div>\n            )}\n          </Field>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/debounced-record-level-validation/package.json",
    "content": "{\n  \"name\": \"react-final-form-synchronous-errors-debounced\",\n  \"version\": \"1.0.0\",\n  \"description\": \"A DelayedRender component is provided to not show the error immediately.\",\n  \"keywords\": [],\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"2.0.3\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  },\n  \"browserslist\": [\n    \">0.2%\",\n    \"not dead\",\n    \"not ie <= 11\",\n    \"not op_mini all\"\n  ]\n}\n"
  },
  {
    "path": "examples/declarative-form-rules/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      position: relative;\n      padding: 8px 5px;\n      border: 1px solid transparent;\n      &.active {\n        background-color: paleturquoise;\n        border-color: turquoise;\n      }\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > .downshift > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n        &[disabled] {\n          background: #eee;\n        }\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          margin-left: 0;\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n        &.downshift {\n          margin-left: 0;\n          padding-left: 15px;\n          flex: 1;\n          & > input {\n            width: 100%;\n            padding: 6px 5px;\n            font-size: 1em;\n            margin-left: 0;\n            border: 1px solid #ccc;\n            border-radius: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n  .downshift-options {\n    border: 1px solid #ddd;\n    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);\n    & > div {\n      padding: 3px 5px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/declarative-form-rules/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport { OnChange } from \"react-final-form-listeners\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst WhenFieldChanges = ({ field, becomes, set, to }) => (\n  <Field name={set} subscription={{}}>\n    {(\n      // No subscription. We only use Field to get to the change function\n      { input: { onChange } },\n    ) => (\n      <OnChange name={field}>\n        {(value) => {\n          if (value === becomes) {\n            onChange(to);\n          }\n        }}\n      </OnChange>\n    )}\n  </Field>\n);\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Declarative Form Rules</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      This example demonstrates how to use{\" \"}\n      <a\n        href=\"https://github.com/final-form/react-final-form-listeners#-react-final-form-listeners\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        React Final Form Listeners\n      </a>{\" \"}\n      to listen to the change of one field to then update the value of other\n      fields.\n    </p>\n    <p>\n      When you uncheck \"Is this a gift?\", the other two fields are cleared and\n      disabled.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      initialValues={{ gift: true }}\n      render={({\n        handleSubmit,\n        form,\n        submitting,\n        pristine,\n        values,\n        errors,\n      }) => {\n        return (\n          <form onSubmit={handleSubmit}>\n            <WhenFieldChanges\n              field=\"gift\"\n              becomes={false}\n              set=\"giftWrap\"\n              to={false}\n            />\n            <WhenFieldChanges\n              field=\"gift\"\n              becomes={false}\n              set=\"giftCardMessage\"\n              to={undefined}\n            />\n            <div>\n              <label>Is this a gift?</label>\n              <Field name=\"gift\" component=\"input\" type=\"checkbox\" />\n            </div>\n            <div>\n              <label>Gift wrap?</label>\n              <Field\n                name=\"giftWrap\"\n                component=\"input\"\n                type=\"checkbox\"\n                disabled={!values.gift}\n              />\n            </div>\n            <div>\n              <label>Message</label>\n              <Field\n                name=\"giftCardMessage\"\n                component=\"textarea\"\n                disabled={!values.gift}\n                placeholder=\"What do you want the card to say?\"\n              />\n            </div>\n            <div className=\"buttons\">\n              <button type=\"submit\" disabled={submitting}>\n                Submit\n              </button>\n              <button\n                type=\"button\"\n                onClick={form.reset}\n                disabled={submitting || pristine}\n              >\n                Reset\n              </button>\n            </div>\n            <h2>Data</h2>\n            <pre>{JSON.stringify(values, 0, 2)}</pre>\n          </form>\n        );\n      }}\n    />\n  </Styles>\n);\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/declarative-form-rules/package.json",
    "content": "{\n  \"name\": \"react-final-form-declarative-form-rules\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use React Final Form Listeners to listen to the change of one field to update another.\",\n  \"keywords\": [\n    \"react\",\n    \"forms\",\n    \"final-form\",\n    \"react-final-form\",\n    \"listener\"\n  ],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-final-form-listeners\": \"1.0.2\",\n    \"react-scripts\": \"3.0.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/declarative-form-rules/readme.md",
    "content": "# Declarative Form Rules\n\n[![Edit react-final-form-declarative-form-rules-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/52q597j2p)\n"
  },
  {
    "path": "examples/downshift-typeahead/DownshiftInput.js",
    "content": "import React from \"react\";\nimport Downshift from \"downshift\";\nimport matchSorter from \"match-sorter\";\n\nconst itemToString = (item) => (item ? item : \"\");\n\nconst DownshiftInput = ({ input, meta, placeholder, items, ...rest }) => (\n  <Downshift\n    {...input}\n    onInputValueChange={(inputValue) => {\n      input.onChange(inputValue);\n    }}\n    itemToString={itemToString}\n    selectedItem={input.value}\n  >\n    {({\n      getInputProps,\n      getItemProps,\n      getLabelProps,\n      isOpen,\n      inputValue,\n      highlightedIndex,\n      selectedItem,\n    }) => {\n      const filteredItems = matchSorter(items, inputValue, {\n        keys: [\"label\"],\n        maxRanking: matchSorter.rankings.STARTS_WITH,\n      });\n      return (\n        <div className=\"downshift\" style={{ position: \"relative\" }}>\n          <input\n            {...getInputProps({\n              name: input.name,\n              placeholder,\n            })}\n          />\n          {isOpen && !!filteredItems.length && (\n            <div\n              className=\"downshift-options\"\n              style={{\n                background: \"white\",\n                position: \"absolute\",\n                top: \"100%\",\n                left: 15,\n                right: 0,\n                zIndex: 4,\n              }}\n            >\n              {filteredItems.map(({ value, label }, index) => (\n                <div\n                  {...getItemProps({\n                    key: value,\n                    index,\n                    item: value,\n                    style: {\n                      backgroundColor:\n                        highlightedIndex === index ? \"lightgray\" : \"white\",\n                      fontWeight: selectedItem === value ? \"bold\" : \"normal\",\n                    },\n                  })}\n                >\n                  {label}\n                </div>\n              ))}\n            </div>\n          )}\n        </div>\n      );\n    }}\n  </Downshift>\n);\n\nexport default DownshiftInput;\n"
  },
  {
    "path": "examples/downshift-typeahead/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > .downshift > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          margin-left: 0;\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n        &.downshift {\n          margin-left: 0;\n          padding-left: 15px;\n          flex: 1;\n          & > input {\n            width: 100%;\n            padding: 6px 5px;\n            font-size: 1em;\n            margin-left: 0;\n            border: 1px solid #ccc;\n            border-radius: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n  .downshift-options {\n    border: 1px solid #ddd;\n    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);\n    & > div {\n      padding: 3px 5px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/downshift-typeahead/fruit.js",
    "content": "export default [\n  { value: \"Apple\", label: \"🍎 Apple\" },\n  { value: \"Banana\", label: \"🍌 Banana\" },\n  { value: \"Cherry\", label: \"🍒 Cherry\" },\n  { value: \"Grape\", label: \"🍇 Grape\" },\n  { value: \"Kiwi\", label: \"🥝 Kiwi\" },\n  { value: \"Orange\", label: \"🍊 Orange\" },\n  { value: \"Peach\", label: \"🍑 Peach\" },\n  { value: \"Pear\", label: \"🍐 Pear\" },\n  { value: \"Pineapple\", label: \"🍍 Pineapple\" },\n  { value: \"Strawberry\", label: \"🍓 Strawberry\" },\n  { value: \"Watermelon\", label: \"🍉 Watermelon\" },\n];\n"
  },
  {
    "path": "examples/downshift-typeahead/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport DownshiftInput from \"./DownshiftInput\";\nimport fruit from \"./fruit\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\nconst validate = (values) => {\n  const errors = {};\n  if (!values.firstName) {\n    errors.firstName = \"Required\";\n  }\n  if (!values.fruit) {\n    errors.fruit = \"Required\";\n  }\n  return errors;\n};\nconst Error = ({ name }) => (\n  <Field\n    name={name}\n    subscribe={{ touched: true, error: true }}\n    render={({ meta: { touched, error } }) =>\n      touched && error ? <span>{error}</span> : null\n    }\n  />\n);\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>\n      <span role=\"img\" aria-label=\"racecar\">\n        🏎️\n      </span>{\" \"}\n      Downshift Example\n    </h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      This example demonstrates using a{\" \"}\n      <a href=\"https://github.com/paypal/downshift\">\n        <span role=\"img\" aria-label=\"racecar\">\n          🏎️\n        </span>{\" \"}\n        Downshift\n      </a>{\" \"}\n      type-ahead component.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      validate={validate}\n      render={({ handleSubmit, form, pristine, submitting, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n            />\n            <Error name=\"firstName\" />\n          </div>\n          <div>\n            <label>Favorite Fruit</label>\n            <Field\n              name=\"fruit\"\n              items={fruit}\n              component={DownshiftInput}\n              placeholder=\"Favorite Fruit\"\n            />\n            <Error name=\"fruit\" />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/downshift-typeahead/package.json",
    "content": "{\n  \"name\": \"react-final-form-downshift-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use a 🏎️ Downshift type-ahead component as an input.\",\n  \"keywords\": [\n    \"final-form\",\n    \"downshift\",\n    \"typeahead\",\n    \"react-final-form\",\n    \"form\"\n  ],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"downshift\": \"1.28.0\",\n    \"final-form\": \"4.20.4\",\n    \"match-sorter\": \"3.0.0\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"3.0.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/downshift-typeahead/readme.md",
    "content": "# Downshift Type-Ahead\n\n[![Edit react-final-form-downshift-type-ahead-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/qzm43nn2mj)\n"
  },
  {
    "path": "examples/external-submit/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/external-submit/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => {\n  let submit;\n  return (\n    <Styles>\n      <h1>\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        React Final Form Example\n      </h1>\n      <h2>External Submit</h2>\n      <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n        Read Docs\n      </a>\n      <div className=\"buttons\">\n        <button\n          type=\"submit\"\n          onClick={() =>\n            // { cancelable: true } required for Firefox\n            // https://github.com/facebook/react/issues/12639#issuecomment-382519193\n            document\n              .getElementById(\"exampleForm\")\n              .dispatchEvent(\n                new Event(\"submit\", { cancelable: true, bubbles: true }),\n              )\n          }\n        >\n          External Submit via <code>document.getElementById()</code>\n        </button>\n        <button\n          type=\"submit\"\n          onClick={(event) => {\n            submit(event);\n          }}\n          style={{ marginTop: 10 }}\n        >\n          External Submit via closure\n        </button>\n        <button type=\"submit\" form=\"exampleForm\" style={{ marginTop: 10 }}>\n          External Submit via form attribute\n        </button>\n      </div>\n      <Form\n        onSubmit={onSubmit}\n        render={({ handleSubmit, form, submitting, pristine, values }) => {\n          submit = handleSubmit;\n          return (\n            <form id=\"exampleForm\" onSubmit={handleSubmit}>\n              <div>\n                <label>First Name</label>\n                <Field\n                  name=\"firstName\"\n                  component=\"input\"\n                  type=\"text\"\n                  placeholder=\"First Name\"\n                />\n              </div>\n              <div>\n                <label>Last Name</label>\n                <Field\n                  name=\"lastName\"\n                  component=\"input\"\n                  type=\"text\"\n                  placeholder=\"Last Name\"\n                />\n              </div>\n              <div>\n                <label>Favorite Color</label>\n                <Field name=\"favoriteColor\" component=\"select\">\n                  <option />\n                  <option value=\"#ff0000\">\n                    <span role=\"img\" aria-label=\"red heart\">\n                      ❤️\n                    </span>{\" \"}\n                    Red\n                  </option>\n                  <option value=\"#00ff00\">\n                    <span role=\"img\" aria-label=\"green heart\">\n                      💚\n                    </span>{\" \"}\n                    Green\n                  </option>\n                  <option value=\"#0000ff\">\n                    <span role=\"img\" aria-label=\"blue heart\">\n                      💙\n                    </span>{\" \"}\n                    Blue\n                  </option>\n                </Field>\n              </div>\n              <div className=\"buttons\">\n                <button type=\"submit\" disabled={submitting || pristine}>\n                  Submit\n                </button>\n                <button\n                  type=\"button\"\n                  onClick={form.reset}\n                  disabled={submitting || pristine}\n                >\n                  Reset\n                </button>\n              </div>\n              <pre>{JSON.stringify(values, 0, 2)}</pre>\n            </form>\n          );\n        }}\n      />\n    </Styles>\n  );\n};\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/external-submit/package.json",
    "content": "{\n  \"name\": \"react-final-form-external-submit-button\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how you can use document.getElementById() or  a closure to trigger a submit from outside the form.\",\n  \"keywords\": [\n    \"final-form\",\n    \"react\",\n    \"submit\",\n    \"external submit\",\n    \"react-final-form\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/external-submit/readme.md",
    "content": "# External Submit\n\n[![Edit react-final-form-external-submit-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/1y7noyrlmq)\n"
  },
  {
    "path": "examples/field-arrays/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 600px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/field-arrays/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport arrayMutators from \"final-form-arrays\";\nimport { FieldArray } from \"react-final-form-arrays\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form - Array Fields\n    </h1>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      mutators={{\n        ...arrayMutators,\n      }}\n      render={({\n        handleSubmit,\n        form: {\n          mutators: { push, pop },\n        }, // injected from final-form-arrays above\n        pristine,\n        form,\n        submitting,\n        values,\n      }) => {\n        return (\n          <form onSubmit={handleSubmit}>\n            <div>\n              <label>Company</label>\n              <Field name=\"company\" component=\"input\" />\n            </div>\n            <div className=\"buttons\">\n              <button\n                type=\"button\"\n                onClick={() => push(\"customers\", undefined)}\n              >\n                Add Customer\n              </button>\n              <button type=\"button\" onClick={() => pop(\"customers\")}>\n                Remove Customer\n              </button>\n            </div>\n            <FieldArray name=\"customers\">\n              {({ fields }) =>\n                fields.map((name, index) => (\n                  <div key={name}>\n                    <label>Cust. #{index + 1}</label>\n                    <Field\n                      name={`${name}.firstName`}\n                      component=\"input\"\n                      placeholder=\"First Name\"\n                    />\n                    <Field\n                      name={`${name}.lastName`}\n                      component=\"input\"\n                      placeholder=\"Last Name\"\n                    />\n                    <span\n                      onClick={() => fields.remove(index)}\n                      style={{ cursor: \"pointer\" }}\n                      role=\"img\"\n                      aria-label=\"remove customer icon\"\n                    >\n                      ❌\n                    </span>\n                  </div>\n                ))\n              }\n            </FieldArray>\n\n            <div className=\"buttons\">\n              <button type=\"submit\" disabled={submitting || pristine}>\n                Submit\n              </button>\n              <button\n                type=\"button\"\n                onClick={form.reset}\n                disabled={submitting || pristine}\n              >\n                Reset\n              </button>\n            </div>\n            <pre>{JSON.stringify(values, 0, 2)}</pre>\n          </form>\n        );\n      }}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/field-arrays/package.json",
    "content": "{\n  \"name\": \"react-final-form-field-arrays\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonstrates how to use helper packages final-form-arrays and react-final-form-arrays to manage array fields.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"5.0.0-0\",\n    \"final-form-arrays\": \"1.1.2\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-final-form-arrays\": \"2.0.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/field-arrays/readme.md",
    "content": "# Field Arrays\n\n[![Edit react-final-form-field-arrays-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/kx8qv67nk5)\n"
  },
  {
    "path": "examples/field-level-validation/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/field-level-validation/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst mustBeNumber = (value) => (isNaN(value) ? \"Must be a number\" : undefined);\nconst minValue = (min) => (value) =>\n  isNaN(value) || value >= min ? undefined : `Should be greater than ${min}`;\nconst composeValidators =\n  (...validators) =>\n  (value) =>\n    validators.reduce(\n      (error, validator) => error || validator(value),\n      undefined,\n    );\n\nconst App = () => (\n  <Styles>\n    <h1>React Final Form Example</h1>\n    <h2>Synchronous Field-Level Validation</h2>\n    <a\n      href=\"https://final-form.org/react\"\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <Field name=\"firstName\" validate={required}>\n            {({ input, meta }) => (\n              <div>\n                <label>First Name</label>\n                <input {...input} type=\"text\" placeholder=\"First Name\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <Field name=\"lastName\" validate={required}>\n            {({ input, meta }) => (\n              <div>\n                <label>Last Name</label>\n                <input {...input} type=\"text\" placeholder=\"Last Name\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <Field\n            name=\"age\"\n            validate={composeValidators(required, mustBeNumber, minValue(18))}\n          >\n            {({ input, meta }) => (\n              <div>\n                <label>Age</label>\n                <input {...input} type=\"text\" placeholder=\"Age\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/field-level-validation/package.json",
    "content": "{\n  \"name\": \"React Final Form - Synchronous Field Level Validation\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example of a form with synchronous field-level validation created with React Final Form\",\n  \"keywords\": [\n    \"state management\",\n    \"react-final-form\",\n    \"form\",\n    \"final-form\",\n    \"react\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"styled-components\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react\": \"latest\",\n    \"react-dom\": \"latest\",\n    \"final-form\": \"4.20.4\"\n  }\n}\n"
  },
  {
    "path": "examples/field-level-validation/readme.md",
    "content": "# Field Level Validation Example\n\n[![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?fontsize=14)\n"
  },
  {
    "path": "examples/field-warnings/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/field-warnings/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { WarningEngine } from \"./warning-engine\";\nimport { Form, Field } from \"react-final-form\";\nimport setFieldData from \"final-form-set-field-data\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>\n      <span role=\"img\" aria-label=\"final form flag\">\n        ⚠️\n      </span>{\" \"}\n      Warnings{\" \"}\n      <span role=\"img\" aria-label=\"final form flag\">\n        ⚠️\n      </span>\n    </h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      Warnings, in this example, are defined as: suggestions to the user, like\n      validation errors, but that do not prevent submission. Note that the{\" \"}\n      <code>&lt;WarningEngine/&gt;</code> component must be at the bottom of the\n      form to guarantee that all the fields have registered.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      mutators={{ setFieldData }}\n      render={({\n        handleSubmit,\n        form: { mutators, reset },\n        submitting,\n        pristine,\n        values,\n      }) => {\n        return (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"firstName\">\n              {({ input, meta }) => (\n                <div>\n                  <label>First Name</label>\n                  <input {...input} placeholder=\"First Name\" />\n                  {meta.touched && meta.data.warning && (\n                    <span>{meta.data.warning}</span>\n                  )}\n                </div>\n              )}\n            </Field>\n            <Field name=\"lastName\">\n              {({ input, meta }) => (\n                <div>\n                  <label>Last Name</label>\n                  <input {...input} placeholder=\"Last Name\" />\n                  {meta.touched && meta.data.warning && (\n                    <span>{meta.data.warning}</span>\n                  )}\n                </div>\n              )}\n            </Field>\n            <div className=\"buttons\">\n              <button type=\"submit\" disabled={submitting}>\n                Submit\n              </button>\n              <button\n                type=\"button\"\n                onClick={reset}\n                disabled={submitting || pristine}\n              >\n                Reset\n              </button>\n            </div>\n            <pre>{JSON.stringify(values, 0, 2)}</pre>\n            <WarningEngine mutators={mutators} />\n          </form>\n        );\n      }}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/field-warnings/package.json",
    "content": "{\n  \"name\": \"react-final-form-warnings\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use final-form-set-field-data to set warnings on fields.\",\n  \"keywords\": [],\n  \"homepage\": \"https://codesandbox.io/s/m5qwxpr6o8\",\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"styled-components\": \"2.2.4\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-dom\": \"17.0.2\",\n    \"react\": \"17.0.2\",\n    \"final-form-set-field-data\": \"1.0.0\",\n    \"final-form\": \"4.20.4\"\n  }\n}\n"
  },
  {
    "path": "examples/field-warnings/readme.md",
    "content": "# Field Warnings\n\n[![Edit react-final-form-field-warnings-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-final-form-warnings-0nimt)\n"
  },
  {
    "path": "examples/field-warnings/warning-engine.js",
    "content": "import React from \"react\";\nimport { FormSpy } from \"react-final-form\";\n\nexport const WarningEngine = ({ mutators: { setFieldData } }) => (\n  <FormSpy\n    subscription={{ values: true }}\n    onChange={({ values }) => {\n      setFieldData(\"firstName\", {\n        warning: values.firstName ? undefined : \"Recommended\",\n      });\n      setFieldData(\"lastName\", {\n        warning: values.lastName ? undefined : \"Recommended\",\n      });\n    }}\n  />\n);\n"
  },
  {
    "path": "examples/fields-component/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/fields-component/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst Fields = ({\n  names,\n  subscription,\n  fieldsState = {},\n  children,\n  originalRender,\n}) => {\n  if (!names.length) {\n    return (originalRender || children)(fieldsState);\n  }\n  const [name, ...rest] = names;\n  return (\n    <Field name={name} subscription={subscription}>\n      {(fieldState) => (\n        <Fields\n          names={rest}\n          subscription={subscription}\n          originalRender={originalRender || children}\n          fieldsState={{ ...fieldsState, [name]: fieldState }}\n        />\n      )}\n    </Field>\n  );\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Fields Component</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      initialValues={{ employed: false }}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n            />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field\n              name=\"lastName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Last Name\"\n            />\n          </div>\n          <div>\n            <label>Employed</label>\n            <Field name=\"employed\" component=\"input\" type=\"checkbox\" />\n          </div>\n          <div>\n            <label>Notes</label>\n            <Field name=\"notes\" component=\"textarea\" placeholder=\"Notes\" />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <Fields names={[\"firstName\", \"lastName\", \"employed\", \"notes\"]}>\n            {(fieldsState) => (\n              <pre>{JSON.stringify(fieldsState, undefined, 2)}</pre>\n            )}\n          </Fields>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/fields-component/package.json",
    "content": "{\n  \"name\": \"react-final-form-fields-component\",\n  \"version\": \"1.0.0\",\n  \"description\": \"One common question from people migrating from Redux-Form is: Where's the Fields component?\\n\\nThe answer is that it's so easy to write one that one needn't ship with the library itself.\",\n  \"keywords\": [],\n  \"homepage\": \"https://codesandbox.io/s/ww40y2m595\",\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"styled-components\": \"latest\",\n    \"react-fontawesome\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-dom\": \"latest\",\n    \"react\": \"latest\",\n    \"final-form\": \"4.20.4\"\n  }\n}\n"
  },
  {
    "path": "examples/fields-component/readme.md",
    "content": "# Fields Component\n\n[![Edit react-final-form-fields-component-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/pyrwplknom)\n"
  },
  {
    "path": "examples/focus-first-error/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      position: relative;\n      padding: 8px 5px;\n      border: 1px solid transparent;\n      &.active {\n        background-color: paleturquoise;\n        border-color: turquoise;\n      }\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > .downshift > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          margin-left: 0;\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n        &.downshift {\n          margin-left: 0;\n          padding-left: 15px;\n          flex: 1;\n          & > input {\n            width: 100%;\n            padding: 6px 5px;\n            font-size: 1em;\n            margin-left: 0;\n            border: 1px solid #ccc;\n            border-radius: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n  .downshift-options {\n    border: 1px solid #ddd;\n    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);\n    & > div {\n      padding: 3px 5px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/focus-first-error/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport createDecorator from \"final-form-focus\";\nimport validate from \"./validate\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\nconst InputRow = ({ label, type, input, meta: { active, error, touched } }) => (\n  <div className={active ? \"active\" : \"\"}>\n    <label>{label}</label>\n    <input {...input} type={type} placeholder={label} />\n    {error && touched && <span>{error}</span>}\n  </div>\n);\n\nconst focusOnError = createDecorator();\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Focus On First Error</h2>\n    <a href=\"https://github.com/final-form/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      Demonstrates how to use the{\" \"}\n      <a\n        href=\"https://github.com/final-form/final-form-focus\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        Final Form Focus{\" \"}\n        <span role=\"img\" aria-label=\"face with monocle\">\n          🧐\n        </span>\n      </a>{\" \"}\n      library as a pluggable{\" \"}\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      Final Form decorator to provide \"focus on first error\" functionality.\n      Notice what when you click the Submit button, the focus is placed on the\n      first field with an error.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      decorators={[focusOnError]}\n      validate={validate}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <Field\n            name=\"firstName\"\n            label=\"First Name\"\n            type=\"text\"\n            component={InputRow}\n          />\n          <Field\n            name=\"lastName\"\n            label=\"Last Name\"\n            type=\"text\"\n            component={InputRow}\n          />\n          <Field\n            name=\"street\"\n            label=\"Street\"\n            type=\"text\"\n            component={InputRow}\n          />\n          <Field name=\"age\" label=\"Age\" type=\"number\" component={InputRow} />\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/focus-first-error/package.json",
    "content": "{\n  \"name\": \"react-final-form-focus-on-first-error\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use the 🏁 Final Form Focus 🧐 decorator to focus on the first input with an error upon submission.\",\n  \"keywords\": [],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"final-form-focus\": \"1.1.2\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"3.0.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/focus-first-error/readme.md",
    "content": "# Focus on First Error\n\n[![Edit react-final-form-focus-first-error-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/6174kqr403)\n"
  },
  {
    "path": "examples/focus-first-error/validate.js",
    "content": "export default (values) => {\n  const errors = {};\n  if (!values.firstName) {\n    errors.firstName = \"Required\";\n  }\n  if (!values.lastName) {\n    errors.lastName = \"Required\";\n  }\n  if (!values.street) {\n    errors.street = \"Required\";\n  }\n  if (!values.age) {\n    errors.age = \"Required\";\n  } else if (isNaN(values.age)) {\n    errors.age = \"Must be a number\";\n  }\n  return errors;\n};\n"
  },
  {
    "path": "examples/format-on-blur/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      position: relative;\n      padding: 8px 5px;\n      border: 1px solid transparent;\n      &.active {\n        background-color: paleturquoise;\n        border-color: turquoise;\n      }\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > .downshift > input,\n      & > select,\n      & > textarea {\n        font-family: monospace, monospace;\n        flex: 1;\n        padding: 6px 9px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n        &[disabled] {\n          background: #eee;\n        }\n      }\n      & > .jsonInput {\n        flex: 1;\n        font-size: 1em;\n        margin-left: 15px;\n        textarea {\n          width: 100%;\n          padding: 6px 9px;\n          height: 150px;\n          font-family: monospace, monospace;\n        }\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          margin-left: 0;\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n        &.downshift {\n          margin-left: 0;\n          padding-left: 15px;\n          flex: 1;\n          & > input {\n            width: 100%;\n            padding: 6px 5px;\n            font-size: 1em;\n            margin-left: 0;\n            border: 1px solid #ccc;\n            border-radius: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n  .downshift-options {\n    border: 1px solid #ddd;\n    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);\n    & > div {\n      padding: 3px 5px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/format-on-blur/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport numeral from \"numeral\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst formatPrice = (value) =>\n  value === undefined\n    ? \"\" // make controlled\n    : numeral(value).format(\"$0,0.00\");\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Format On Blur Example</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      By default the <code>format</code> function given to <code>Field</code> is\n      called every time the component is rendered. But that can lead to a\n      difficult UX for some types of values. That's why there is a{\" \"}\n      <code>formatOnBlur</code> flag that will prevent the <code>format</code>{\" \"}\n      function from being called until the field is blurred.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>Product Name</label>\n            <Field\n              name=\"name\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Product Name\"\n            />\n          </div>\n          <div>\n            <label>Price</label>\n            <Field\n              name=\"price\"\n              component=\"input\"\n              type=\"text\"\n              format={formatPrice}\n              formatOnBlur\n              placeholder=\"$0.00\"\n            />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/format-on-blur/package.json",
    "content": "{\n  \"name\": \"react-final-form-format-on-blur-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use the formatOnBlur prop to postpone the formatting of a form field value until the field loses focus.\",\n  \"keywords\": [\n    \"react-final-form\",\n    \"final-form\",\n    \"format\",\n    \"form\",\n    \"currency\"\n  ],\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"numeral\": \"2.0.6\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"3.0.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/format-on-blur/readme.md",
    "content": "# Format on Blur\n\n[![Edit react-final-form-format-on-blur-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/3rp260ly51)\n"
  },
  {
    "path": "examples/format-string-by-pattern/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/format-string-by-pattern/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport formatString from \"format-string-by-pattern\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst masks = [\n  { name: \"phone-1\", parse: \"999-999-9999\" },\n  { name: \"phone-2\", parse: \"(999) 999-9999\" },\n  { name: \"phone-3\", parse: \"+49 (AAAA) BBBBBB\" },\n  { name: \"cep 🇧🇷\", parse: \"12345-678\" },\n  { name: \"cpf 🇧🇷\", parse: \"XXX.XXX.XXX-XX\" },\n  { name: \"cnpj 🇧🇷\", parse: \"XX.XXX.XXX/XXXX-XX\" },\n];\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit, reset, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          {masks.map((mask) => (\n            <div key={mask.name}>\n              <label>{mask.name}</label>\n              <Field\n                component=\"input\"\n                name={mask.name}\n                parse={formatString(mask.parse)}\n                placeholder={mask.parse}\n              />\n            </div>\n          ))}\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/format-string-by-pattern/package.json",
    "content": "{\n  \"name\": \"format-string-by-pattern-with-react-final-form\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use the parse  prop to format the inputs using format-string-by-pattern.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"format-string-by-pattern\": \"1.1.1\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/format-string-by-pattern/readme.md",
    "content": "# Format String by Pattern\n\n[![Edit react-final-form-format-string-by-pattern-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/no20p7z3l)\n"
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/Spinner.js",
    "content": "import styled, { keyframes } from \"styled-components\";\n\nconst rotation = keyframes`\n    from {\n      -webkit-transform: rotate(0deg);\n    }\n    to {\n      -webkit-transform: rotate(359deg);\n    }\n`;\nexport default styled.div`\n  height: 12px;\n  width: 12px;\n  margin-left: 5px;\n  position: absolute;\n  right: 0;\n  top: 0;\n  animation: ${rotation} 0.6s infinite linear;\n  border-left: 6px solid rgba(0, 174, 239, 0.15);\n  border-right: 6px solid rgba(0, 174, 239, 0.15);\n  border-bottom: 6px solid rgba(0, 174, 239, 0.15);\n  border-top: 6px solid rgba(0, 174, 239, 0.8);\n  border-radius: 100%;\n`;\n"
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport Spinner from \"./Spinner\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst verifyUsername = async (values) => {\n  await sleep(400);\n  if (\n    ~[\"john\", \"paul\", \"george\", \"ringo\"].indexOf(\n      values.username && values.username.toLowerCase(),\n    )\n  ) {\n    return { username: \"Username taken!\" };\n  }\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Hybrid Synchronous/Asynchronous Record-Level Validation</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <div>Usernames John, Paul, George or Ringo will fail async validation.</div>\n    <Form\n      onSubmit={onSubmit}\n      validate={(values) => {\n        const errors = {};\n        if (!values.username) {\n          errors.username = \"Required\";\n        }\n        if (!values.password) {\n          errors.password = \"Required\";\n        }\n        if (!values.confirm) {\n          errors.confirm = \"Required\";\n        } else if (values.confirm !== values.password) {\n          errors.confirm = \"Does not match\";\n        }\n        return Object.keys(errors).length ? errors : verifyUsername(values);\n      }}\n      render={({\n        handleSubmit,\n        form,\n        submitting,\n        pristine,\n        validating,\n        values,\n      }) => (\n        <form onSubmit={handleSubmit}>\n          {validating && <Spinner />}\n          <Field name=\"username\">\n            {({ input, meta }) => (\n              <div>\n                <label>Username</label>\n                <input {...input} type=\"text\" placeholder=\"Username\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <Field name=\"password\">\n            {({ input, meta }) => (\n              <div>\n                <label>Password</label>\n                <input {...input} type=\"password\" placeholder=\"Password\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <Field name=\"confirm\">\n            {({ input, meta }) => (\n              <div>\n                <label>Confirm</label>\n                <input\n                  {...input}\n                  type=\"password\"\n                  placeholder=\"Confirm password\"\n                />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || validating}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/package.json",
    "content": "{\n  \"name\": \"react-final-form-hybrid-synchronous-asynchronous-record-level-validation-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonstrates how you can mix synchronous and asynchronous validation in the same record-level validation function.\",\n  \"keywords\": [\n    \"react-final-form\",\n    \"form\",\n    \"final-form\",\n    \"asynchronous\",\n    \"validation\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/hybrid-sync-async-record-level-validation/readme.md",
    "content": "# Hybrid Synchronous/Asynchronous Record-level Validation\n\n[![Edit react-final-form-hybrid-sync-async-record-validation-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/kl9n295n5)\n"
  },
  {
    "path": "examples/independent-error-component-render-props/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/independent-error-component-render-props/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst Error = ({ name }) => (\n  <Field\n    name={name}\n    subscription={{ touched: true, error: true }}\n    render={({ meta: { touched, error } }) =>\n      touched && error ? <span>{error}</span> : null\n    }\n  />\n);\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Reusable Independent Error Component</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      validate={(values) => {\n        const errors = {};\n        if (!values.firstName) {\n          errors.firstName = \"Required\";\n        }\n        if (!values.lastName) {\n          errors.lastName = \"Required\";\n        }\n        if (!values.age) {\n          errors.age = \"Required\";\n        } else if (isNaN(values.age)) {\n          errors.age = \"Must be a number\";\n        } else if (values.age < 18) {\n          errors.age = \"No kids allowed\";\n        }\n        return errors;\n      }}\n      render={({ handleSubmit, reset, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              placeholder=\"First Name\"\n            />\n            <Error name=\"firstName\" />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field name=\"lastName\" component=\"input\" placeholder=\"Last Name\" />\n            <Error name=\"lastName\" />\n          </div>\n          <div>\n            <label>Age</label>\n            <Field\n              name=\"age\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Age\"\n            />\n            <Error name=\"age\" />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/independent-error-component-render-props/package.json",
    "content": "{\n  \"name\": \"react-final-form-independent-error-component\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonstrates how to make a special Error component to display the error for any form field.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.1\"\n  }\n}\n"
  },
  {
    "path": "examples/independent-error-component-render-props/readme.md",
    "content": "# Reusable Independent Error Component (using render props)\n\n[![Edit react-final-form-independent-error-component-render-props-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/xoo3xq654p)\n"
  },
  {
    "path": "examples/independent-error-component-with-hooks/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/independent-error-component-with-hooks/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field, useField } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst Error = ({ name }) => {\n  const {\n    meta: { touched, error },\n  } = useField(name, { subscription: { touched: true, error: true } });\n  return touched && error ? <span>{error}</span> : null;\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Reusable Independent Error Component</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      validate={(values) => {\n        const errors = {};\n        if (!values.firstName) {\n          errors.firstName = \"Required\";\n        }\n        if (!values.lastName) {\n          errors.lastName = \"Required\";\n        }\n        if (!values.age) {\n          errors.age = \"Required\";\n        } else if (isNaN(values.age)) {\n          errors.age = \"Must be a number\";\n        } else if (values.age < 18) {\n          errors.age = \"No kids allowed\";\n        }\n        return errors;\n      }}\n      render={({ handleSubmit, reset, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              placeholder=\"First Name\"\n            />\n            <Error name=\"firstName\" />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field name=\"lastName\" component=\"input\" placeholder=\"Last Name\" />\n            <Error name=\"lastName\" />\n          </div>\n          <div>\n            <label>Age</label>\n            <Field\n              name=\"age\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Age\"\n            />\n            <Error name=\"age\" />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/independent-error-component-with-hooks/package.json",
    "content": "{\n  \"name\": \"react-final-form-independent-error-component-with-hooks\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonstrates how to make a special Error component to display the error for any form field.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.1\"\n  }\n}\n"
  },
  {
    "path": "examples/independent-error-component-with-hooks/readme.md",
    "content": "# Reusable Independent Error Component (using hooks)\n\n[![Edit react-final-form-independent-error-component-with-hooks-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-final-form-independent-error-component-with-hooks-y1grn)\n"
  },
  {
    "path": "examples/listening-for-external-changes/BooleanDecay.js",
    "content": "import React from \"react\";\nimport PropTypes from \"prop-types\";\n\n/**\n * 👋 Hey! Thanks for being curious about what this component does!\n * It's pretty simple. Have you ever seen those boxes where, when you\n * flip the switch, it activates a motor that causes a little hand to\n * come out and flip the switch back off? THAT'S what this component does.\n *\n * Examples: https://giphy.com/search/useless-box\n *\n * The value prop will be flipped back to false after the delay.\n */\nexport default class BooleanDecay extends React.Component {\n  static propTypes = {\n    children: PropTypes.func.isRequired,\n    delay: PropTypes.number.isRequired,\n    value: PropTypes.bool.isRequired,\n  };\n\n  constructor(props) {\n    super(props);\n    this.state = {\n      value: props.value,\n    };\n  }\n\n  startTimer() {\n    this.stopTimer();\n    this.timeout = setTimeout(() => {\n      this.setState({ value: false });\n    }, this.props.delay);\n  }\n\n  stopTimer() {\n    if (this.timeout) {\n      clearTimeout(this.timeout);\n    }\n  }\n\n  componentDidMount() {\n    if (this.state.value) {\n      this.startTimer();\n    }\n  }\n\n  componentWillUnmount() {\n    this.stopTimer();\n  }\n\n  componentWillReceiveProps(nextProps) {\n    const { value } = nextProps;\n    if (value !== this.state.value) {\n      this.setState({ value });\n      if (value) {\n        this.startTimer();\n      } else {\n        this.stopTimer();\n      }\n    }\n  }\n\n  render() {\n    return this.props.children(this.state.value);\n  }\n}\n"
  },
  {
    "path": "examples/listening-for-external-changes/ExternalModificationDetector.js",
    "content": "import React from \"react\";\nimport { Field } from \"react-final-form\";\n\n/**\n * Listens for changes to a field's value, and, if the value changes\n * when the field is NOT active, it sets an externallyModified flag\n * which is passed to the children render function.\n */\nclass ExternalModificationDetector extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      externallyModified: false,\n      value: props.input.value,\n    };\n  }\n\n  componentWillReceiveProps(nextProps) {\n    const {\n      input: { value },\n      meta: { active },\n    } = nextProps;\n    if (value !== this.state.value) {\n      this.setState({\n        value,\n        externallyModified: !active,\n      });\n    } else if (this.state.externallyModified) {\n      this.setState({\n        externallyModified: false,\n      });\n    }\n  }\n\n  render() {\n    const { children } = this.props;\n    const { externallyModified } = this.state;\n    return children(externallyModified);\n  }\n}\n\n// Wrap the ExternalModificationDetector in a Field\nexport default ({ name, children }) => (\n  <Field\n    name={name}\n    subscription={{ value: true, active: true }}\n    render={(props) => (\n      <ExternalModificationDetector {...props}>\n        {children}\n      </ExternalModificationDetector>\n    )}\n  />\n);\n"
  },
  {
    "path": "examples/listening-for-external-changes/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > .downshift > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          margin-left: 0;\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n        &.downshift {\n          margin-left: 0;\n          padding-left: 15px;\n          flex: 1;\n          & > input {\n            width: 100%;\n            padding: 6px 5px;\n            font-size: 1em;\n            margin-left: 0;\n            border: 1px solid #ccc;\n            border-radius: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n  .downshift-options {\n    border: 1px solid #ddd;\n    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);\n    & > div {\n      padding: 3px 5px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/listening-for-external-changes/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport createDecorator from \"final-form-calculate\";\nimport ExternalModificationDetector from \"./ExternalModificationDetector\";\nimport BooleanDecay from \"./BooleanDecay\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst calculator = createDecorator({\n  field: /day\\[\\d\\]/, // when a field matching this pattern changes...\n  updates: {\n    // ...update the total to the result of this function\n    total: (ignoredValue, allValues) =>\n      (allValues.day || []).reduce((sum, value) => sum + Number(value || 0), 0),\n  },\n});\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Listening for External Changes</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      By wrapping a stateful <code>ExternalModificationDetector</code> component\n      in a <code>Field</code> component, we can listen for changes to a field's\n      value, and by knowing whether or not the field is active, deduce when a\n      field's value changes due to external influences.\n    </p>\n    <p>\n      As you enter numbers for each day of the week, the total is calulated in\n      realtime.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      decorators={[calculator]}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>Monday</label>\n            <Field\n              name=\"day[0]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Monday\"\n            />\n          </div>\n          <div>\n            <label>Tuesday</label>\n            <Field\n              name=\"day[1]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Tuesday\"\n            />\n          </div>\n          <div>\n            <label>Wednesday</label>\n            <Field\n              name=\"day[2]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Wednesday\"\n            />\n          </div>\n          <div>\n            <label>Thursday</label>\n            <Field\n              name=\"day[3]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Thursday\"\n            />\n          </div>\n          <div>\n            <label>Friday</label>\n            <Field\n              name=\"day[4]\"\n              component=\"input\"\n              type=\"number\"\n              placeholder=\"Friday\"\n            />\n          </div>\n          <hr />\n          <div>\n            <label>Total</label>\n            <ExternalModificationDetector name=\"total\">\n              {(externallyModified) => (\n                <BooleanDecay value={externallyModified} delay={1000}>\n                  {(highlight) => (\n                    <Field\n                      name=\"total\"\n                      component=\"input\"\n                      type=\"number\"\n                      placeholder=\"Total\"\n                      style={{\n                        transition: \"background 500ms ease-in-out\",\n                        background: highlight ? \"yellow\" : \"none\",\n                      }}\n                    />\n                  )}\n                </BooleanDecay>\n              )}\n            </ExternalModificationDetector>\n          </div>\n          <hr />\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/listening-for-external-changes/package.json",
    "content": "{\n  \"name\": \"react-final-form-listening-for-external-changes\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use a stateful component wrapped in a Field to listen for external changes to that field.\",\n  \"keywords\": [\n    \"react\",\n    \"final-form\",\n    \"react-final-form\",\n    \"form\",\n    \"listener\"\n  ],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"final-form-calculate\": \"1.3.1\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"3.0.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/listening-for-external-changes/readme.md",
    "content": "# Listening for External Changes\n\n[![Edit react-final-form-listening-for-external-changes-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/3x989zl866)\n"
  },
  {
    "path": "examples/loading-initializing-values/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/loading-initializing-values/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst load = async () => {\n  await sleep(2000);\n  return {\n    username: \"erikras\",\n    firstName: \"Erik\",\n  };\n};\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nclass App extends React.Component {\n  state = { data: {} };\n  async componentDidMount() {\n    this.setState({ loading: true });\n    const data = await load();\n    this.setState({ loading: false, data });\n  }\n\n  render() {\n    return (\n      <Styles>\n        <h1>\n          <span role=\"img\" aria-label=\"final form flag\">\n            🏁\n          </span>{\" \"}\n          React Final Form - Loading and Initializing Values\n        </h1>\n        <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n          Read Docs\n        </a>\n        <Form\n          onSubmit={onSubmit}\n          initialValues={this.state.data}\n          render={({ handleSubmit, pristine, form, submitting, values }) => {\n            return (\n              <form onSubmit={handleSubmit}>\n                {this.state.loading && <div className=\"loading\" />}\n                <div>\n                  <label>Username</label>\n                  <Field\n                    name=\"username\"\n                    component=\"input\"\n                    placeholder=\"Username\"\n                  />\n                </div>\n                <div>\n                  <label>First Name</label>\n                  <Field\n                    name=\"firstName\"\n                    component=\"input\"\n                    placeholder=\"First Name\"\n                  />\n                </div>\n                <div className=\"buttons\">\n                  <button type=\"submit\" disabled={submitting || pristine}>\n                    Submit\n                  </button>\n                  <button\n                    type=\"button\"\n                    onClick={form.reset}\n                    disabled={submitting || pristine}\n                  >\n                    Reset\n                  </button>\n                </div>\n                <pre>{JSON.stringify(values, 0, 2)}</pre>\n              </form>\n            );\n          }}\n        />\n      </Styles>\n    );\n  }\n}\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/loading-initializing-values/package.json",
    "content": "{\n  \"name\": \"react-final-form-loading-and-initializing\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example demonstrates how you can initialize a form by passing in initialValues as a prop.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/loading-initializing-values/readme.md",
    "content": "# Loading and Initializing Values\n\n[![Edit react-final-form-loading-initializing-values-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/91w9ro3x9o)\n"
  },
  {
    "path": "examples/loading-saving-reinitializing/LoadSaveReinitializeForm.js",
    "content": "import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { Form } from \"react-final-form\";\n\nexport default class LoadSaveReinitializeForm extends React.Component {\n  static propTypes = {\n    load: PropTypes.func.isRequired,\n    loading: PropTypes.node.isRequired,\n    postLoadFormat: PropTypes.func,\n    preSaveFormat: PropTypes.func,\n    save: PropTypes.func.isRequired,\n  };\n\n  state = {\n    isLoading: false,\n    originalValues: undefined,\n    initialValues: undefined,\n  };\n\n  load = async () => {\n    const { load, postLoadFormat } = this.props;\n    this.setState({ isLoading: true });\n    const originalValues = await load();\n    const initialValues = postLoadFormat\n      ? postLoadFormat(originalValues)\n      : originalValues;\n    this.setState({\n      isLoading: false,\n      originalValues,\n      initialValues,\n    });\n  };\n\n  save = async (values) => {\n    const { postLoadFormat, preSaveFormat, save } = this.props;\n    let valuesToSave = preSaveFormat\n      ? preSaveFormat(values, this.state.originalValues)\n      : values;\n    const result = await save(valuesToSave);\n    this.setState({\n      originalValues: valuesToSave,\n      initialValues: postLoadFormat\n        ? postLoadFormat(valuesToSave)\n        : valuesToSave,\n    });\n    return result;\n  };\n\n  componentDidMount() {\n    this.load();\n  }\n\n  render() {\n    const { load, loading, postLoadFormat, preSaveFormat, save, ...rest } =\n      this.props;\n    const { isLoading, initialValues } = this.state;\n    return isLoading || !initialValues ? (\n      loading\n    ) : (\n      <Form {...rest} initialValues={initialValues} onSubmit={this.save} />\n    );\n  }\n}\n"
  },
  {
    "path": "examples/loading-saving-reinitializing/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/loading-saving-reinitializing/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Field } from \"react-final-form\";\nimport LoadSaveReinitializeForm from \"./LoadSaveReinitializeForm\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nlet record = {\n  primaryKey: 42,\n  phone: \"2045551234\",\n  name: \"John Doe\",\n  email: \"john.doe@final-form.org\",\n  otherExtraneousInfo: {\n    creditScore: 800,\n  },\n};\n\nconst load = async () => {\n  console.info(\"Loading...\");\n  await sleep(1500);\n  console.info(\"Loaded...\");\n  return record;\n};\n\nconst save = async (values) => {\n  console.info(\"Saving\", values);\n  await sleep(1500);\n  record = values;\n};\n\nconst postLoadFormat = (values) => {\n  const { name, email, phone } = values;\n  const [firstName, lastName] = name.split(/ /, 2);\n  return {\n    firstName,\n    lastName,\n    email,\n    phone: phone\n      ? `${phone.slice(0, 3)}-${phone.slice(3, 6)}-${phone.slice(6, 10)}`\n      : \"\",\n  };\n};\n\nconst preSaveFormat = (values, originalValues) => {\n  return {\n    ...originalValues,\n    name: `${values.firstName || \"\"} ${values.lastName || \"\"}`,\n    email: values.email,\n    phone: values.phone.replace(/-/g, \"\"),\n  };\n};\n\nconst Error = ({ name }) => (\n  <Field\n    name={name}\n    subscription={{ error: true, touched: true }}\n    render={({ meta: { error, touched } }) =>\n      touched && error ? <span>{error}</span> : null\n    }\n  />\n);\n\nconst loading = <div className=\"loading\">Loading...</div>;\n\nconst validate = (values) => {\n  const errors = {};\n  if (!values.firstName) {\n    errors.firstName = \"Required\";\n  }\n  if (!values.lastName) {\n    errors.lastName = \"Required\";\n  }\n  if (!values.email) {\n    errors.email = \"Required\";\n  }\n  if (!values.phone) {\n    errors.phone = \"Required\";\n  }\n  return errors;\n};\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Load, Save, and Reinitialize</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      <code>LoadSaveReinitializeForm</code> is a wrapper for a{\" \"}\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form component. On mount, it loads a record from the\n      database/API, and formats it to the shape of the form inputs. On submit,\n      it converts the data back to the format that the database/API wants\n      (including the original primary key), saves the data to the database/API,\n      and then re-initializes the form so that it is pristine again with the\n      canonical data.\n    </p>\n    <LoadSaveReinitializeForm\n      load={load}\n      loading={loading}\n      postLoadFormat={postLoadFormat}\n      preSaveFormat={preSaveFormat}\n      save={save}\n      validate={validate}\n    >\n      {({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n              disabled={submitting}\n            />\n            <Error name=\"firstName\" />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field\n              name=\"lastName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Last Name\"\n              disabled={submitting}\n            />\n            <Error name=\"lastName\" />\n          </div>\n          <div>\n            <label>Email</label>\n            <Field\n              name=\"email\"\n              component=\"input\"\n              type=\"email\"\n              placeholder=\"Email\"\n              disabled={submitting}\n            />\n            <Error name=\"email\" />\n          </div>\n          <div>\n            <label>Phone</label>\n            <Field\n              name=\"phone\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Phone\"\n              disabled={submitting}\n            />\n            <Error name=\"phone\" />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <h3>Form Values</h3>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n          <h3>Database Record</h3>\n          <pre>{JSON.stringify(record, 0, 2)}</pre>\n        </form>\n      )}\n    </LoadSaveReinitializeForm>\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/loading-saving-reinitializing/package.json",
    "content": "{\n  \"name\": \"react-final-form-example-load-save-and-reinitialize\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to make a wrapper component to handle, loading, normalization of data, saving, and reinitializing of the form.\",\n  \"keywords\": [\n    \"react-final-form\",\n    \"final-form\",\n    \"loading\",\n    \"initialization\",\n    \"asynchronous\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-fontawesome\": \"1.6.1\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/loading-saving-reinitializing/readme.md",
    "content": "# Loading, Normalizing, Saving, and Reinitializing\n\n[![Edit react-final-form-load-save-reinitialize-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/xr0mvl1904)\n"
  },
  {
    "path": "examples/material-ui/.prettierrc",
    "content": "{\n  \"printWidth\": 80,\n  \"tabWidth\": 2,\n  \"useTabs\": false,\n  \"semi\": true,\n  \"singleQuote\": true,\n  \"trailingComma\": \"all\",\n  \"bracketSpacing\": true,\n  \"jsxBracketSameLine\": false,\n  \"fluid\": false\n}"
  },
  {
    "path": "examples/material-ui/index.js",
    "content": "import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Form } from 'react-final-form';\nimport {\n  TextField,\n  Checkboxes,\n  Radios,\n  Select,\n  DatePicker,\n  TimePicker,\n} from 'mui-rff';\nimport {\n  Typography,\n  Paper,\n  Link,\n  Grid,\n  Button,\n  CssBaseline,\n  MenuItem,\n} from '@material-ui/core';\n// Picker\nimport DateFnsUtils from '@date-io/date-fns';\n\nconst onSubmit = async (values) => {\n  const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst validate = (values) => {\n  const errors = {};\n  if (!values.firstName) {\n    errors.firstName = 'Required';\n  }\n  if (!values.lastName) {\n    errors.lastName = 'Required';\n  }\n  if (!values.email) {\n    errors.email = 'Required';\n  }\n  return errors;\n};\n\nconst formFields = [\n  {\n    size: 6,\n    field: (\n      <TextField\n        label=\"First Name\"\n        name=\"firstName\"\n        margin=\"none\"\n        required={true}\n      />\n    ),\n  },\n  {\n    size: 6,\n    field: (\n      <TextField\n        label=\"Last Name\"\n        name=\"lastName\"\n        margin=\"none\"\n        required={true}\n      />\n    ),\n  },\n  {\n    size: 12,\n    field: (\n      <TextField\n        type=\"email\"\n        label=\"Email\"\n        name=\"email\"\n        margin=\"none\"\n        required={true}\n      />\n    ),\n  },\n  {\n    size: 12,\n    field: (\n      <Checkboxes\n        name=\"employed\"\n        formControlProps={{ margin: 'none' }}\n        data={{ label: 'Employed', value: true }}\n      />\n    ),\n  },\n  {\n    size: 12,\n    field: (\n      <Radios\n        label=\"Best Stooge\"\n        name=\"stooge\"\n        formControlProps={{ margin: 'none' }}\n        radioGroupProps={{ row: true }}\n        data={[\n          { label: 'Larry', value: 'larry' },\n          { label: 'Moe', value: 'moe' },\n          { label: 'Curly', value: 'curly' },\n        ]}\n      />\n    ),\n  },\n  {\n    size: 12,\n    field: (\n      <Checkboxes\n        label=\"Sauces\"\n        name=\"sauces\"\n        formControlProps={{ margin: 'none' }}\n        formGroupProps={{ row: true }}\n        data={[\n          { label: 'Ketchup', value: 'ketchup' },\n          { label: 'Mustard', value: 'mustard' },\n          { label: 'Salsa', value: 'salsa' },\n          { label: 'Guacamole 🥑', value: 'guacamole' },\n        ]}\n      />\n    ),\n  },\n  {\n    size: 12,\n    field: <TextField name=\"notes\" multiline label=\"Notes\" margin=\"none\" />,\n  },\n  {\n    size: 12,\n    field: (\n      <Select\n        name=\"city\"\n        label=\"Select a City\"\n        formControlProps={{ margin: 'none' }}\n      >\n        <MenuItem value=\"London\">London</MenuItem>\n        <MenuItem value=\"Paris\">Paris</MenuItem>\n        <MenuItem value=\"Budapest\">A city with a very long Name</MenuItem>\n      </Select>\n    ),\n  },\n  {\n    size: 6,\n    field: (\n      <DatePicker\n        name=\"rendez-vous\"\n        margin=\"normal\"\n        label=\"Rendez-vous\"\n        dateFunsUtils={DateFnsUtils}\n      />\n    ),\n  },\n  {\n    size: 6,\n    field: (\n      <TimePicker\n        name=\"alarm\"\n        margin=\"normal\"\n        label=\"Alarm\"\n        dateFunsUtils={DateFnsUtils}\n      />\n    ),\n  },\n];\n\nfunction App() {\n  return (\n    <div style={{ padding: 16, margin: 'auto', maxWidth: 600 }}>\n      <CssBaseline />\n      <Typography variant=\"h4\" align=\"center\" component=\"h1\" gutterBottom>\n        <span role=\"img\" aria-label=\"flag\">\n          🏁\n        </span>{' '}\n        React Final Form\n      </Typography>\n      <Typography variant=\"h5\" align=\"center\" component=\"h2\" gutterBottom>\n        Material-UI Example\n      </Typography>\n      <Typography paragraph>\n        <Link href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n          Read Docs\n        </Link>\n        . This example demonstrates using{' '}\n        <Link href=\"https://material-ui.com/demos/text-fields/\">\n          Material-UI\n        </Link>{' '}\n        form controls.\n      </Typography>\n      <Form\n        onSubmit={onSubmit}\n        initialValues={{ employed: true, stooge: 'larry' }}\n        validate={validate}\n        render={({ handleSubmit, reset, submitting, pristine, values }) => (\n          <form onSubmit={handleSubmit} noValidate>\n            <Paper style={{ padding: 16 }}>\n              <Grid container alignItems=\"flex-start\" spacing={2}>\n                {formFields.map((item, idx) => (\n                  <Grid item xs={item.size} key={idx}>\n                    {item.field}\n                  </Grid>\n                ))}\n                <Grid item style={{ marginTop: 16 }}>\n                  <Button\n                    type=\"button\"\n                    variant=\"contained\"\n                    onClick={reset}\n                    disabled={submitting || pristine}\n                  >\n                    Reset\n                  </Button>\n                </Grid>\n                <Grid item style={{ marginTop: 16 }}>\n                  <Button\n                    variant=\"contained\"\n                    color=\"primary\"\n                    type=\"submit\"\n                    disabled={submitting}\n                  >\n                    Submit\n                  </Button>\n                </Grid>\n              </Grid>\n            </Paper>\n            <pre>{JSON.stringify(values, 0, 2)}</pre>\n          </form>\n        )}\n      />\n    </div>\n  );\n}\n\nReactDOM.render(<App />, document.querySelector('#root'));\n"
  },
  {
    "path": "examples/material-ui/package.json",
    "content": "{\n  \"name\": \"react-final-form-material-ui-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use Material-UI form controls.\",\n  \"keywords\": [\n    \"material-ui\"\n  ],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"@date-io/date-fns\": \"latest\",\n    \"@material-ui/core\": \"latest\",\n    \"@material-ui/lab\": \"latest\",\n    \"@material-ui/pickers\": \"latest\",\n    \"date-fns\": \"next\",\n    \"final-form\": \"4.20.4\",\n    \"mui-rff\": \"latest\",\n    \"react\": \"latest\",\n    \"react-dom\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"latest\",\n    \"tslib\": \"latest\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/material-ui/readme.md",
    "content": "# Material-UI 3.0\n\n[![Edit react-final-form-material-ui-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/9ywq085k9w)\n"
  },
  {
    "path": "examples/parse-format/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/parse-format/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst normalizePhone = (value) => {\n  if (!value) return value;\n  const onlyNums = value.replace(/[^\\d]/g, \"\");\n  if (onlyNums.length <= 3) return onlyNums;\n  if (onlyNums.length <= 7)\n    return `(${onlyNums.slice(0, 3)}) ${onlyNums.slice(3, 7)}`;\n  return `(${onlyNums.slice(0, 3)}) ${onlyNums.slice(3, 6)}-${onlyNums.slice(\n    6,\n    10,\n  )}`;\n};\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Parse and Format</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      initialValues={{}}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>Username</label>\n            <Field\n              name=\"username\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Username\"\n              parse={(value) => value && value.toUpperCase()}\n              format={(value) => (value ? value.toLowerCase() : \"\")}\n            />\n          </div>\n          <div>\n            <label>Phone</label>\n            <Field\n              name=\"phone\"\n              component=\"input\"\n              type=\"text\"\n              parse={normalizePhone}\n              placeholder=\"(999) 999-9999\"\n            />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/parse-format/package.json",
    "content": "{\n  \"name\": \"react-final-form-parse-and-format\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use parse and format props to control how values are shown in the input and saved into the form state.\",\n  \"keywords\": [\n    \"parse\",\n    \"react\",\n    \"react-final-form\",\n    \"format\",\n    \"final-form\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/parse-format/readme.md",
    "content": "# Parse and Format (and Normalize)\n\n[![Edit react-final-form-parse-format-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/10rzowm323)\n"
  },
  {
    "path": "examples/prefixed-fields/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1,\n  h2,\n  h3 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n  }\n  p a {\n    display: inline;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/prefixed-fields/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\n/************ IMPORTANT CODE STARTS HERE **************/\nconst FieldPrefixContext = React.createContext();\nconst FieldPrefix = ({ prefix, children }) => (\n  <FieldPrefixContext.Provider value={prefix}>\n    {children}\n  </FieldPrefixContext.Provider>\n);\nconst PrefixedField = ({ name, ...props }) => (\n  <FieldPrefixContext.Consumer>\n    {(prefix) => <Field name={`${prefix}.${name}`} {...props} />}\n  </FieldPrefixContext.Consumer>\n);\n/************* IMPORTANT CODE ENDS HERE ***************/\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Prefixed Fields Example</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      This example shows how to use React Context to create sections of your\n      form that have their fields' names prefixed, to structure the resulting\n      form data. This provides similar functionality to Redux Form's{\" \"}\n      <a\n        href=\"https://redux-form.com/8.2.2/docs/api/formsection.md/\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n      >\n        <code>FormSection</code>\n      </a>{\" \"}\n      component.\n    </p>\n    <Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <h3>Shipping</h3>\n          <FieldPrefix prefix=\"shipping\">\n            <div>\n              <label>Street</label>\n              <PrefixedField\n                name=\"street\"\n                component=\"input\"\n                type=\"text\"\n                placeholder=\"Street\"\n              />\n            </div>\n            <div>\n              <label>City</label>\n              <PrefixedField\n                name=\"city\"\n                component=\"input\"\n                type=\"text\"\n                placeholder=\"City\"\n              />\n            </div>\n          </FieldPrefix>\n          <h3>Billing</h3>\n          <FieldPrefix prefix=\"billing\">\n            <div>\n              <label>Street</label>\n              <PrefixedField\n                name=\"street\"\n                component=\"input\"\n                type=\"text\"\n                placeholder=\"Street\"\n              />\n            </div>\n            <div>\n              <label>City</label>\n              <PrefixedField\n                name=\"city\"\n                component=\"input\"\n                type=\"text\"\n                placeholder=\"City\"\n              />\n            </div>\n          </FieldPrefix>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/prefixed-fields/package.json",
    "content": "{\n  \"name\": \"react-final-form-prefixed-fields\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example shows how to use React Context to create sections of your form that have their fields' names prefixed, to structure the resulting form data. This provides similar functionality to Redux Form's FormSection component.\",\n  \"keywords\": [],\n  \"homepage\": \"https://codesandbox.io/s/ww40y2m595\",\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"styled-components\": \"latest\",\n    \"react-fontawesome\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-dom\": \"latest\",\n    \"react\": \"latest\",\n    \"final-form\": \"4.20.4\"\n  }\n}\n"
  },
  {
    "path": "examples/prefixed-fields/readme.md",
    "content": "# Prefixed Fields\n\n[![Edit react-final-form-prefixed-fields-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-final-form-prefixed-fields-seiy8)\n"
  },
  {
    "path": "examples/readme.md",
    "content": "# [See the Examples](https://final-form.org/docs/react-final-form/examples)\n"
  },
  {
    "path": "examples/record-level-validation/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/record-level-validation/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => (\n  <Styles>\n    <h1>React Final Form Example</h1>\n    <h2>Password / Confirm Validation</h2>\n    <a\n      href=\"https://final-form.org/react\"\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      validate={(values) => {\n        const errors = {};\n        if (!values.username) {\n          errors.username = \"Required\";\n        }\n        if (!values.password) {\n          errors.password = \"Required\";\n        }\n        if (!values.confirm) {\n          errors.confirm = \"Required\";\n        } else if (values.confirm !== values.password) {\n          errors.confirm = \"Must match\";\n        }\n        return errors;\n      }}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <Field name=\"username\">\n            {({ input, meta }) => (\n              <div>\n                <label>Username</label>\n                <input {...input} type=\"text\" placeholder=\"Username\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <Field name=\"password\">\n            {({ input, meta }) => (\n              <div>\n                <label>Password</label>\n                <input {...input} type=\"password\" placeholder=\"Password\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <Field name=\"confirm\">\n            {({ input, meta }) => (\n              <div>\n                <label>Confirm</label>\n                <input {...input} type=\"password\" placeholder=\"Confirm\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/record-level-validation/package.json",
    "content": "{\n  \"name\": \"React Final Form - Synchronous Record Level Validation\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example of a form with synchronous record-level validation created with React Final Form\",\n  \"keywords\": [\n    \"state management\",\n    \"react-final-form\",\n    \"form\",\n    \"final-form\",\n    \"react\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"styled-components\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react\": \"latest\",\n    \"react-dom\": \"latest\",\n    \"final-form\": \"4.20.4\"\n  }\n}\n"
  },
  {
    "path": "examples/record-level-validation/readme.md",
    "content": "# Record Level Validation Example\n\n[![Edit react-final-form-record-level-validation-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/final-form/react-final-form/tree/master/examples/record-level-validation?fontsize=14)\n"
  },
  {
    "path": "examples/redux/FormStateFromRedux.js",
    "content": "import React from \"react\";\nimport { connect } from \"react-redux\";\nimport { getFormState } from \"./finalFormDuck\";\n\nconst FormStateFromRedux = ({ state }) => (\n  <pre>{JSON.stringify(state, 0, 2)}</pre>\n);\n\nexport default connect((state, ownProps) => ({\n  state: getFormState(state, ownProps.form),\n}))(FormStateFromRedux);\n"
  },
  {
    "path": "examples/redux/FormStateToRedux.js",
    "content": "import React from \"react\";\nimport { connect } from \"react-redux\";\nimport { FormSpy } from \"react-final-form\";\nimport { updateFormState } from \"./finalFormDuck\";\n\nconst FormStateToRedux = ({ form, updateFormState }) => (\n  <FormSpy onChange={(state) => updateFormState(form, state)} />\n);\n\nexport default connect(undefined, { updateFormState })(FormStateToRedux);\n"
  },
  {
    "path": "examples/redux/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  .loading {\n    font-size: 2em;\n    font-weight: bold;\n    text-align: center;\n    margin: 50px;\n  }\n\n  form,\n  div.form {\n    text-align: left;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n    .submitting {\n      display: block;\n      position: absolute;\n      top: -5px;\n      left: -5px;\n      right: -5px;\n      padding: 0;\n      text-align: center;\n      background: rgba(0, 0, 0, 0.4);\n      color: white;\n      z-index: 10;\n      font-weight: bold;\n      font-size: 0.8em;\n    }\n    .saving {\n      font-size: 0.8em;\n      font-weight: bold;\n      color: darkblue;\n      margin: 8px 0 0 7px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/redux/finalFormDuck.js",
    "content": "// QUACK! This is a duck. https://github.com/erikras/ducks-modular-redux\n\n// Actions\nconst UPDATE_FORM_STATE =\n  \"final-form-redux-example/finalForm/UPDATE_FORM_STATE\";\n\n// Reducer\nexport default function reducer(state = {}, action = {}) {\n  switch (action.type) {\n    case UPDATE_FORM_STATE:\n      return {\n        ...state,\n        [action.form]: action.payload,\n      };\n    default:\n      return state;\n  }\n}\n\n// Action Creators\nexport const updateFormState = (form, state) => ({\n  type: UPDATE_FORM_STATE,\n  form,\n  payload: state,\n});\n\n// Selectors\nexport const getFormState = (state, form) =>\n  (state && state.finalForm && state.finalForm[form]) || {};\n"
  },
  {
    "path": "examples/redux/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport { Provider } from \"react-redux\";\nimport store from \"./store\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport FormStateToRedux from \"./FormStateToRedux\";\nimport FormStateFromRedux from \"./FormStateFromRedux\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => (\n  <Provider store={store}>\n    <Styles>\n      <h1>\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        React Final Form\n      </h1>\n      <h2>Redux Example</h2>\n      <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n        Read Docs\n      </a>\n      <p>\n        The only reason to keep your{\" \"}\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        Final Form form data in Redux is if you need to be able to read it from\n        outside your form. This example demonstrates how to use a{\" \"}\n        <code>FormSpy</code> to keep a copy of your form data in the Redux\n        store. Note that the canonical authoritative version of the data still\n        lives in{\" \"}\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        Final Form. If you need to <em>mutate</em> your data via dispatching\n        Redux actions, you should probably use{\" \"}\n        <a href=\"https://redux-form.com\">Redux Form</a>.\n      </p>\n      <Form\n        onSubmit={onSubmit}\n        initialValues={{ employed: true, stooge: \"larry\" }}\n        subscription={{ submitting: true, pristine: true }}\n      >\n        {({ handleSubmit, form, submitting, pristine }) => (\n          <form onSubmit={handleSubmit}>\n            <FormStateToRedux form=\"example\" />\n            <div>\n              <label>First Name</label>\n              <Field\n                name=\"firstName\"\n                component=\"input\"\n                type=\"text\"\n                placeholder=\"First Name\"\n              />\n            </div>\n            <div>\n              <label>Last Name</label>\n              <Field\n                name=\"lastName\"\n                component=\"input\"\n                type=\"text\"\n                placeholder=\"Last Name\"\n              />\n            </div>\n            <div>\n              <label>Email</label>\n              <Field\n                name=\"email\"\n                component=\"input\"\n                type=\"email\"\n                placeholder=\"Email\"\n              />\n            </div>\n            <div>\n              <label>Favorite Color</label>\n              <Field name=\"favoriteColor\" component=\"select\">\n                <option />\n                <option value=\"#ff0000\">\n                  <span role=\"img\" aria-label=\"red heart\">\n                    ❤️\n                  </span>{\" \"}\n                  Red\n                </option>\n                <option value=\"#00ff00\">\n                  <span role=\"img\" aria-label=\"green heart\">\n                    💚\n                  </span>{\" \"}\n                  Green\n                </option>\n                <option value=\"#0000ff\">\n                  <span role=\"img\" aria-label=\"blue heart\">\n                    💙\n                  </span>{\" \"}\n                  Blue\n                </option>\n              </Field>\n            </div>\n            <div>\n              <label>Employed?</label>\n              <Field name=\"employed\" component=\"input\" type=\"checkbox\" />\n            </div>\n            <div>\n              <label>Toppings</label>\n              <Field name=\"toppings\" component=\"select\" multiple>\n                <option value=\"ham\">\n                  <span role=\"img\" aria-label=\"pig head\">\n                    🐷\n                  </span>{\" \"}\n                  Ham\n                </option>\n                <option value=\"mushrooms\">\n                  <span role=\"img\" aria-label=\"mushroom\">\n                    🍄\n                  </span>{\" \"}\n                  Mushrooms\n                </option>\n                <option value=\"cheese\">\n                  <span role=\"img\" aria-label=\"cheese\">\n                    🧀\n                  </span>{\" \"}\n                  Cheese\n                </option>\n                <option value=\"chicken\">\n                  <span role=\"img\" aria-label=\"chicken\">\n                    🐓\n                  </span>{\" \"}\n                  Chicken\n                </option>\n                <option value=\"pineapple\">\n                  <span role=\"img\" aria-label=\"pineapple\">\n                    🍍\n                  </span>{\" \"}\n                  Pinapple\n                </option>\n              </Field>\n            </div>\n            <div>\n              <label>Best Stooge?</label>\n              <div>\n                <label>\n                  <Field\n                    name=\"stooge\"\n                    component=\"input\"\n                    type=\"radio\"\n                    value=\"larry\"\n                  />{\" \"}\n                  Larry\n                </label>\n                <label>\n                  <Field\n                    name=\"stooge\"\n                    component=\"input\"\n                    type=\"radio\"\n                    value=\"moe\"\n                  />{\" \"}\n                  Moe\n                </label>\n                <label>\n                  <Field\n                    name=\"stooge\"\n                    component=\"input\"\n                    type=\"radio\"\n                    value=\"curly\"\n                  />{\" \"}\n                  Curly\n                </label>\n              </div>\n            </div>\n            <div>\n              <label>Sauces</label>\n              <div>\n                <label>\n                  <Field\n                    name=\"sauces\"\n                    component=\"input\"\n                    type=\"checkbox\"\n                    value=\"ketchup\"\n                  />{\" \"}\n                  Ketchup\n                </label>\n                <label>\n                  <Field\n                    name=\"sauces\"\n                    component=\"input\"\n                    type=\"checkbox\"\n                    value=\"mustard\"\n                  />{\" \"}\n                  Mustard\n                </label>\n                <label>\n                  <Field\n                    name=\"sauces\"\n                    component=\"input\"\n                    type=\"checkbox\"\n                    value=\"salsa\"\n                  />{\" \"}\n                  Salsa\n                </label>\n                <label>\n                  <Field\n                    name=\"sauces\"\n                    component=\"input\"\n                    type=\"checkbox\"\n                    value=\"guacamole\"\n                  />{\" \"}\n                  Guacamole{\" \"}\n                  <span role=\"img\" aria-label=\"guacamole\">\n                    🥑\n                  </span>\n                </label>\n              </div>\n            </div>\n            <div>\n              <label>Notes</label>\n              <Field name=\"notes\" component=\"textarea\" placeholder=\"Notes\" />\n            </div>\n            <div className=\"buttons\">\n              <button type=\"submit\" disabled={submitting || pristine}>\n                Submit\n              </button>\n              <button\n                type=\"button\"\n                onClick={form.reset}\n                disabled={submitting || pristine}\n              >\n                Reset\n              </button>\n            </div>\n            <h3>Form State from Redux</h3>\n            <FormStateFromRedux form=\"example\" />\n          </form>\n        )}\n      </Form>\n    </Styles>\n  </Provider>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/redux/package.json",
    "content": "{\n  \"name\": \"🏁 React Final Form - Redux Example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to store a copy of your form data in the Redux store for easy access outside your form.\",\n  \"keywords\": [\n    \"redux\",\n    \"form\",\n    \"react-final-form\",\n    \"final-form\",\n    \"forms\"\n  ],\n  \"homepage\": \"https://codesandbox.io/s/new\",\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-redux\": \"7.0.3\",\n    \"react-scripts\": \"3.0.1\",\n    \"redux\": \"4.0.1\",\n    \"styled-components\": \"4.2.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/redux/readme.md",
    "content": "# Redux Example\n\n[![Edit react-final-form-redux-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/4xq2qpzw79)\n"
  },
  {
    "path": "examples/redux/store.js",
    "content": "import { createStore, combineReducers } from \"redux\";\nimport finalFormReducer from \"./finalFormDuck\";\n\nconst reducer = combineReducers({\n  finalForm: finalFormReducer,\n});\nconst store = (\n  typeof window !== \"undefined\" && window.devToolsExtension\n    ? window.devToolsExtension()(createStore)\n    : createStore\n)(reducer);\n\nexport default store;\n"
  },
  {
    "path": "examples/reusable-field-groups/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 180px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/reusable-field-groups/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst Address = ({ name, label }) => (\n  <React.Fragment>\n    <div>\n      <label>{label} Street</label>\n      <Field\n        name={`${name}.street`}\n        component=\"input\"\n        placeholder={`${label} Street`}\n      />\n    </div>\n    <div>\n      <label>{label} City</label>\n      <Field\n        name={`${name}.city`}\n        component=\"input\"\n        placeholder={`${label} City`}\n      />\n    </div>\n    <div>\n      <label>{label} Postal Code</label>\n      <Field\n        name={`${name}.postalCode`}\n        component=\"input\"\n        placeholder={`${label} Postal Code`}\n      />\n    </div>\n  </React.Fragment>\n);\n\nconst App = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form Example\n    </h1>\n    <h2>Reusable Field Groups</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>Name</label>\n            <Field name=\"name\" component=\"input\" placeholder=\"Name\" />\n          </div>\n          <Address name=\"billing\" label=\"Billing\" />\n          <Address name=\"shipping\" label=\"Shipping\" />\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/reusable-field-groups/package.json",
    "content": "{\n  \"name\": \"react-final-form-reusable-field-groups\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how fields can be grouped into a reusable component.\",\n  \"keywords\": [],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/reusable-field-groups/readme.md",
    "content": "# Reusable Field Groups\n\n[![Edit react-final-form-reusable-field-groups-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/8z5jm6x80)\n"
  },
  {
    "path": "examples/simple/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/simple/index.js",
    "content": "/* eslint-disable jsx-a11y/accessible-emoji */\nimport React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst App = () => (\n  <Styles>\n    <h1>React Final Form - Simple Example</h1>\n    <a\n      href=\"https://final-form.org/react\"\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      initialValues={{ stooge: \"larry\", employed: false }}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n            />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field\n              name=\"lastName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"Last Name\"\n            />\n          </div>\n          <div>\n            <label>Employed</label>\n            <Field name=\"employed\" component=\"input\" type=\"checkbox\" />\n          </div>\n          <div>\n            <label>Favorite Color</label>\n            <Field name=\"favoriteColor\" component=\"select\">\n              <option />\n              <option value=\"#ff0000\">❤️ Red</option>\n              <option value=\"#00ff00\">💚 Green</option>\n              <option value=\"#0000ff\">💙 Blue</option>\n            </Field>\n          </div>\n          <div>\n            <label>Toppings</label>\n            <Field name=\"toppings\" component=\"select\" multiple>\n              <option value=\"chicken\">🐓 Chicken</option>\n              <option value=\"ham\">🐷 Ham</option>\n              <option value=\"mushrooms\">🍄 Mushrooms</option>\n              <option value=\"cheese\">🧀 Cheese</option>\n              <option value=\"tuna\">🐟 Tuna</option>\n              <option value=\"pineapple\">🍍 Pineapple</option>\n            </Field>\n          </div>\n          <div>\n            <label>Sauces</label>\n            <div>\n              <label>\n                <Field\n                  name=\"sauces\"\n                  component=\"input\"\n                  type=\"checkbox\"\n                  value=\"ketchup\"\n                />{\" \"}\n                Ketchup\n              </label>\n              <label>\n                <Field\n                  name=\"sauces\"\n                  component=\"input\"\n                  type=\"checkbox\"\n                  value=\"mustard\"\n                />{\" \"}\n                Mustard\n              </label>\n              <label>\n                <Field\n                  name=\"sauces\"\n                  component=\"input\"\n                  type=\"checkbox\"\n                  value=\"mayonnaise\"\n                />{\" \"}\n                Mayonnaise\n              </label>\n              <label>\n                <Field\n                  name=\"sauces\"\n                  component=\"input\"\n                  type=\"checkbox\"\n                  value=\"guacamole\"\n                />{\" \"}\n                Guacamole 🥑\n              </label>\n            </div>\n          </div>\n          <div>\n            <label>Best Stooge</label>\n            <div>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"larry\"\n                />{\" \"}\n                Larry\n              </label>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"moe\"\n                />{\" \"}\n                Moe\n              </label>\n              <label>\n                <Field\n                  name=\"stooge\"\n                  component=\"input\"\n                  type=\"radio\"\n                  value=\"curly\"\n                />{\" \"}\n                Curly\n              </label>\n            </div>\n          </div>\n          <div>\n            <label>Notes</label>\n            <Field name=\"notes\" component=\"textarea\" placeholder=\"Notes\" />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/simple/package.json",
    "content": "{\n  \"name\": \"React Final Form - Simple Example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example of a simple form created with React Final Form\",\n  \"keywords\": [\n    \"state management\",\n    \"react-final-form\",\n    \"form\",\n    \"final-form\",\n    \"react\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"styled-components\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react\": \"latest\",\n    \"react-dom\": \"latest\",\n    \"final-form\": \"4.20.4\",\n    \"prop-types\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "examples/simple/readme.md",
    "content": "# Simple Example\n\n[![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?fontsize=14)\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/Styles.tsx",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light: string, dark: string) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  p {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/components/CheckboxInput.tsx",
    "content": "import React from \"react\";\nimport { FieldRenderProps } from \"react-final-form\";\n\ntype Props = FieldRenderProps<boolean, any>;\n\nconst CheckboxInput: React.FC<Props> = ({\n  input: { value, ...input },\n}: Props) => <input {...input} type=\"checkbox\" checked={!!value} />;\n\nexport default CheckboxInput;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/components/MultiCheckboxInput.tsx",
    "content": "import React from \"react\";\nimport { FieldRenderProps } from \"react-final-form\";\n\ntype Props = FieldRenderProps<string, any>;\n\nconst MultiCheckboxInput: React.FC<Props> = ({\n  input: { value, ...input },\n}: Props) => <input {...input} type=\"checkbox\" />;\n\nexport default MultiCheckboxInput;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/components/MultiSelectInput.tsx",
    "content": "import React from \"react\";\nimport { FieldRenderProps } from \"react-final-form\";\n\ntype Props = FieldRenderProps<string[], any>;\n\nconst MultiSelectInput: React.FC<Props> = ({ input, meta, ...rest }: Props) => (\n  <select {...input} {...rest} multiple value={input.value || []} />\n);\n\nexport default MultiSelectInput;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/components/NumberInput.tsx",
    "content": "import React from \"react\";\nimport { FieldRenderProps } from \"react-final-form\";\n\ntype Props = FieldRenderProps<number, any>;\n\nconst NumberInput: React.FC<Props> = ({ input, meta, ...rest }: Props) => (\n  <input {...input} {...rest} type=\"number\" />\n);\n\nexport default NumberInput;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/components/RadioInput.tsx",
    "content": "import React from \"react\";\nimport { FieldRenderProps } from \"react-final-form\";\n\nfunction RadioInput<T extends string>({\n  input,\n  meta,\n  ...rest\n}: FieldRenderProps<T, any>) {\n  return <input type=\"radio\" {...input} {...rest} />;\n}\n\nexport default RadioInput;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/components/SelectInput.tsx",
    "content": "import React from \"react\";\nimport { FieldRenderProps } from \"react-final-form\";\n\ntype Props = FieldRenderProps<string, any>;\n\nconst SelectInput: React.FC<Props> = ({ input, meta, ...rest }: Props) => (\n  <select {...input} {...rest} />\n);\n\nexport default SelectInput;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/components/TextAreaInput.tsx",
    "content": "import React from \"react\";\nimport { FieldRenderProps } from \"react-final-form\";\n\ntype Props = FieldRenderProps<string, any>;\n\nconst TextAreaInput: React.FC<Props> = ({ input, meta, ...rest }: Props) => (\n  <textarea {...input} {...rest} />\n);\n\nexport default TextAreaInput;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/components/TextInput.tsx",
    "content": "import React from \"react\";\nimport { FieldRenderProps } from \"react-final-form\";\n\ntype Props = FieldRenderProps<string, any>;\n\nconst TextInput: React.FC<Props> = ({ input, meta, ...rest }: Props) => (\n  <input type=\"text\" {...input} {...rest} />\n);\n\nexport default TextInput;\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/index.tsx",
    "content": "/* eslint-disable jsx-a11y/accessible-emoji */\nimport React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport CheckboxInput from \"./components/CheckboxInput\";\nimport RadioInput from \"./components/RadioInput\";\nimport TextInput from \"./components/TextInput\";\nimport NumberInput from \"./components/NumberInput\";\nimport TextAreaInput from \"./components/TextAreaInput\";\nimport SelectInput from \"./components/SelectInput\";\nimport MultiSelectInput from \"./components/MultiSelectInput\";\nimport MultiCheckboxInput from \"./components/MultiCheckboxInput\";\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\ntype Stooge = \"larry\" | \"moe\" | \"curly\";\ninterface Values {\n  firstName?: string;\n  lastName?: string;\n  employed: boolean;\n  favoriteColor?: string;\n  toppings?: string[];\n  sauces?: string[];\n  stooge: Stooge;\n  notes?: string;\n}\n\nconst onSubmit = async (values: Values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, undefined, 2));\n};\n\nconst App: React.FC = () => (\n  <Styles>\n    <h1>\n      <span role=\"img\" aria-label=\"final form flag\">\n        🏁\n      </span>{\" \"}\n      React Final Form\n    </h1>\n    <h2>Strongly Typed Values with TypeScript</h2>\n    <p>\n      Strongly Typed form values and field values. Each input requires a\n      specific type, which is provided by a JSX generic specification on the\n      Field component.\n    </p>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <Form\n      onSubmit={onSubmit}\n      initialValues={{ stooge: \"larry\", employed: false }}\n      render={({ handleSubmit, form, submitting, pristine, values }) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field<string>\n              name=\"firstName\"\n              component={TextInput}\n              placeholder=\"First Name\"\n            />\n          </div>\n          <div>\n            <label>Last Name</label>\n            <Field<string>\n              name=\"lastName\"\n              component={TextInput}\n              placeholder=\"Last Name\"\n            />\n          </div>\n          <div>\n            <label>Age</label>\n            <Field<number>\n              name=\"age\"\n              component={NumberInput}\n              placeholder=\"Age\"\n            />\n          </div>\n          <div>\n            <label>Employed</label>\n            <Field<boolean>\n              name=\"employed\"\n              type=\"checkbox\"\n              component={CheckboxInput}\n            />\n          </div>\n          <div>\n            <label>Favorite Color</label>\n            <Field<string> name=\"favoriteColor\" component={SelectInput}>\n              <option />\n              <option value=\"#ff0000\">❤️ Red</option>\n              <option value=\"#00ff00\">💚 Green</option>\n              <option value=\"#0000ff\">💙 Blue</option>\n            </Field>\n          </div>\n          <div>\n            <label>Toppings</label>\n            <Field<string[]> name=\"toppings\" component={MultiSelectInput}>\n              <option value=\"chicken\">🐓 Chicken</option>\n              <option value=\"ham\">🐷 Ham</option>\n              <option value=\"mushrooms\">🍄 Mushrooms</option>\n              <option value=\"cheese\">🧀 Cheese</option>\n              <option value=\"tuna\">🐟 Tuna</option>\n              <option value=\"pineapple\">🍍 Pineapple</option>\n            </Field>\n          </div>\n          <div>\n            <label>Sauces</label>\n            <div>\n              <label>\n                <Field<string>\n                  name=\"sauces\"\n                  component={MultiCheckboxInput}\n                  type=\"checkbox\"\n                  value=\"ketchup\"\n                />{\" \"}\n                Ketchup\n              </label>\n              <label>\n                <Field<string>\n                  name=\"sauces\"\n                  component=\"input\"\n                  type=\"checkbox\"\n                  value=\"mustard\"\n                />{\" \"}\n                Mustard\n              </label>\n              <label>\n                <Field<string>\n                  name=\"sauces\"\n                  component=\"input\"\n                  type=\"checkbox\"\n                  value=\"mayonnaise\"\n                />{\" \"}\n                Mayonnaise\n              </label>\n              <label>\n                <Field<string>\n                  name=\"sauces\"\n                  component=\"input\"\n                  type=\"checkbox\"\n                  value=\"guacamole\"\n                />{\" \"}\n                Guacamole 🥑\n              </label>\n            </div>\n          </div>\n          <div>\n            <label>Best Stooge</label>\n            <div>\n              <label>\n                <Field<Stooge>\n                  name=\"stooge\"\n                  component={RadioInput}\n                  type=\"radio\"\n                  value=\"larry\"\n                />{\" \"}\n                Larry\n              </label>\n              <label>\n                <Field<Stooge>\n                  name=\"stooge\"\n                  component={RadioInput}\n                  type=\"radio\"\n                  value=\"moe\"\n                />{\" \"}\n                Moe\n              </label>\n              <label>\n                <Field<Stooge>\n                  name=\"stooge\"\n                  component={RadioInput}\n                  type=\"radio\"\n                  value=\"curly\"\n                />{\" \"}\n                Curly\n              </label>\n            </div>\n          </div>\n          <div>\n            <label>Notes</label>\n            <Field name=\"notes\" component={TextAreaInput} placeholder=\"Notes\" />\n          </div>\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting || pristine}>\n              Submit\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, undefined, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nconst rootElement = document.getElementById(\"root\");\nrender(<App />, rootElement);\n"
  },
  {
    "path": "examples/strongly-typed-values-typescript/readme.md",
    "content": "# Strongly Typed Form and Field Values with TypeScript\n\n[![Edit react-final-form-strongly-typed-values-typescript-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/strongly-typed-form-values-with-react-final-form-26jkd)\n"
  },
  {
    "path": "examples/styling-with-smooth-ui/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport { Form, Field } from \"react-final-form\";\nimport {\n  Box,\n  Button,\n  Checkbox,\n  Col,\n  ControlFeedback,\n  FormCheck,\n  FormCheckLabel,\n  FormGroup,\n  Input,\n  Label,\n  Radio,\n  RadioGroup,\n  Row,\n  Select,\n  Textarea,\n  Typography,\n} from \"smooth-ui\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\n// ****************************************\n//⬇️ THIS IS WHERE ALL THE MAGIC HAPPENS ⬇️\n// ****************************************\nconst adapt /* ⬅️ this is a HOC */ =\n  (Component) =>\n  ({ input, meta: { valid }, ...rest }) => (\n    <Component {...input} {...rest} valid={valid} />\n  );\nconst AdaptedInput = adapt(Input);\nconst AdaptedCheckbox = adapt(Checkbox);\nconst AdaptedRadio = adapt(Radio);\nconst AdaptedSelect = adapt(Select);\nconst AdaptedTextarea = adapt(Textarea);\n\nconst Error = ({ name }) => (\n  <Field name={name} subscription={{ error: true, touched: true }}>\n    {({ meta: { touched, error } }) =>\n      touched && error ? (\n        <ControlFeedback valid={!error}>{error}</ControlFeedback>\n      ) : null\n    }\n  </Field>\n);\n// ****************************************\n//⬆️ THIS IS WHERE ALL THE MAGIC HAPPENS ⬆️\n// ****************************************\n\nconst required = (value) => (value ? undefined : \"Required\");\nconst App = () => (\n  <Row>\n    <Col />\n    <Col xs={8}>\n      <Typography variant=\"h1\">\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        React Final Form\n      </Typography>\n      <Typography variant=\"h2\">\n        <span role=\"img\" aria-label=\"lollipop\">\n          🍭\n        </span>{\" \"}\n        Smooth-UI Example\n      </Typography>\n      <p>\n        This example demonstrates how to use{\" \"}\n        <a\n          href=\"https://smooth-ui.smooth-code.com\"\n          target=\"_blank\"\n          rel=\"noopener noreferrer\"\n        >\n          <span role=\"img\" aria-label=\"lollipop\">\n            🍭\n          </span>{\" \"}\n          Smooth-UI\n        </a>{\" \"}\n        to make your forms look fabulous. All you really need is the\n        higher-order component that adapts the{\" \"}\n        <span role=\"img\" aria-label=\"lollipop\">\n          🍭\n        </span>{\" \"}\n        Smooth-UI form components to be compatible with{\" \"}\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        React Final Form.\n      </p>\n      <Form\n        onSubmit={onSubmit}\n        initialValues={{ stooge: \"larry\", employed: true }}\n        render={({ handleSubmit, form, submitting, pristine, values }) => (\n          <form onSubmit={handleSubmit}>\n            <FormGroup>\n              <Label>First Name</Label>\n              <Field\n                name=\"firstName\"\n                component={AdaptedInput}\n                placeholder=\"First Name\"\n                validate={required}\n                control\n              />\n              <Error name=\"firstName\" />\n            </FormGroup>\n            <FormGroup>\n              <Label>Last Name</Label>\n              <Field\n                name=\"lastName\"\n                component={AdaptedInput}\n                placeholder=\"Last Name\"\n                validate={required}\n                control\n              />\n              <Error name=\"lastName\" />\n            </FormGroup>\n            <FormCheck>\n              <Field\n                name=\"employed\"\n                component={AdaptedCheckbox}\n                type=\"checkbox\"\n                id=\"employed\"\n              />\n              <FormCheckLabel htmlFor=\"employed\">Employed</FormCheckLabel>\n            </FormCheck>\n            <FormGroup>\n              <Label>Favorite Color</Label>\n              <Field\n                name=\"favoriteColor\"\n                component={AdaptedSelect}\n                validate={required}\n                options={[\n                  {},\n                  { value: \"#ff0000\", label: \"❤️ Red\" },\n                  { value: \"#00ff00\", label: \"💚 Green\" },\n                  { value: \"#0000ff\", label: \"💙 Blue\" },\n                ]}\n                control\n              />\n              <Error name=\"favoriteColor\" />\n            </FormGroup>\n            <FormGroup>\n              <Label>Toppings</Label>\n              <Field\n                name=\"toppings\"\n                component={AdaptedSelect}\n                validate={required}\n                multiple\n                arrow={false}\n                options={[\n                  { value: \"chicken\", label: \"🐓 Chicken\" },\n                  { value: \"ham\", label: \"🐷 Ham\" },\n                  { value: \"mushrooms\", label: \"🍄 Mushrooms\" },\n                  { value: \"cheese\", label: \"🧀 Cheese\" },\n                  { value: \"tuna\", label: \"🐟 Tuna\" },\n                  { value: \"pineapple\", label: \"🍍 Pineapple\" },\n                ]}\n                control\n              />\n              <Error name=\"toppings\" />\n            </FormGroup>\n            <FormGroup>\n              <Label>Sauces</Label>\n              <FormCheck>\n                <Field\n                  name=\"sauces\"\n                  component={AdaptedCheckbox}\n                  id=\"ketchup\"\n                  type=\"checkbox\"\n                  value=\"ketchup\"\n                />\n                <FormCheckLabel htmlFor=\"ketchup\">Ketchup</FormCheckLabel>\n              </FormCheck>\n              <FormCheck>\n                <Field\n                  name=\"sauces\"\n                  component={AdaptedCheckbox}\n                  id=\"mayonnaise\"\n                  type=\"checkbox\"\n                  value=\"mayonnaise\"\n                />\n                <FormCheckLabel htmlFor=\"mayonnaise\">Mayonnaise</FormCheckLabel>\n              </FormCheck>\n              <FormCheck>\n                <Field\n                  name=\"sauces\"\n                  component={AdaptedCheckbox}\n                  id=\"guacamole\"\n                  type=\"checkbox\"\n                  value=\"guacamole\"\n                />\n                <FormCheckLabel htmlFor=\"guacamole\">\n                  Guacamole{\" \"}\n                  <span role=\"img\" aria-label=\"guacamole\">\n                    🥑\n                  </span>\n                </FormCheckLabel>\n              </FormCheck>\n            </FormGroup>\n\n            <FormGroup>\n              <Label>Best Stooge</Label>\n              <RadioGroup>\n                <FormCheck>\n                  <Field\n                    name=\"stooge\"\n                    component={AdaptedRadio}\n                    type=\"radio\"\n                    id=\"larry\"\n                    value=\"larry\"\n                  />\n                  <FormCheckLabel htmlFor=\"larry\">Larry</FormCheckLabel>\n                </FormCheck>\n                <FormCheck>\n                  <Field\n                    name=\"stooge\"\n                    component={AdaptedRadio}\n                    type=\"radio\"\n                    id=\"moe\"\n                    value=\"moe\"\n                  />\n                  <FormCheckLabel htmlFor=\"moe\">Moe</FormCheckLabel>\n                </FormCheck>\n                <FormCheck>\n                  <Field\n                    name=\"stooge\"\n                    component={AdaptedRadio}\n                    type=\"radio\"\n                    id=\"curly\"\n                    value=\"curly\"\n                  />\n                  <FormCheckLabel htmlFor=\"curly\">Curly</FormCheckLabel>\n                </FormCheck>\n              </RadioGroup>\n            </FormGroup>\n            <FormGroup>\n              <Label>Notes</Label>\n              <Field\n                name=\"notes\"\n                component={AdaptedTextarea}\n                placeholder=\"Notes\"\n                validate={required}\n                control\n              />\n              <Error name=\"notes\" />\n            </FormGroup>\n            <Box justifyContent=\"space-around\">\n              <Button\n                type=\"submit\"\n                disabled={submitting || pristine}\n                variant=\"primary\"\n              >\n                Submit\n              </Button>\n              <Button\n                type=\"button\"\n                onClick={form.reset}\n                disabled={submitting || pristine}\n                variant=\"secondary\"\n              >\n                Reset\n              </Button>\n            </Box>\n            <pre\n              style={{\n                border: \"1px solid #ccc\",\n                background: \"rgba(0, 0, 0, 0.1)\",\n                boxShadow: \"inset 1px 1px 3px rgba(0, 0, 0, 0.2)\",\n                padding: \"20px\",\n              }}\n            >\n              {JSON.stringify(values, 0, 2)}\n            </pre>\n          </form>\n        )}\n      />\n    </Col>\n    <Col />\n  </Row>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/styling-with-smooth-ui/package.json",
    "content": "{\n  \"name\": \"react-final-form-smooth-ui-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"Demonstrates how to use the 🍭 Smooth UI styling library to make your forms gorgeous in 🏁 React Final Form.\",\n  \"keywords\": [\n    \"react-final-form\",\n    \"final-form\",\n    \"smooth-ui\",\n    \"styling\",\n    \"forms\"\n  ],\n  \"main\": \"src/index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"react\": \"17.0.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-scripts\": \"3.0.1\",\n    \"smooth-ui\": \"4.3.2\",\n    \"styled-components\": \"3.4.10\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\",\n    \"test\": \"react-scripts test --env=jsdom\",\n    \"eject\": \"react-scripts eject\"\n  }\n}\n"
  },
  {
    "path": "examples/styling-with-smooth-ui/readme.md",
    "content": "# Styling with Smooth-UI\n\n[![Edit react-final-form-styling-with-smooth-ui-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/40o45po3l4)\n"
  },
  {
    "path": "examples/submission-errors/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/submission-errors/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport { FORM_ERROR } from \"final-form\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  if (values.username !== \"erikras\") {\n    return { username: \"Unknown username\" };\n  }\n  if (values.password !== \"finalformrocks\") {\n    return { [FORM_ERROR]: \"Login Failed\" };\n  }\n  window.alert(\"LOGIN SUCCESS!\");\n};\n\nconst App = () => (\n  <Styles>\n    <h1>React Final Form Example</h1>\n    <h2>Submission Errors</h2>\n    <a\n      href=\"https://final-form.org/react\"\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      Read Docs\n    </a>\n    <div>\n      Only successful credentials are <code>erikras</code> and{\" \"}\n      <code>finalformrocks</code>.\n    </div>\n    <Form\n      onSubmit={onSubmit}\n      validate={(values) => {\n        const errors = {};\n        if (!values.username) {\n          errors.username = \"Required\";\n        }\n        if (!values.password) {\n          errors.password = \"Required\";\n        }\n        return errors;\n      }}\n      render={({\n        submitError,\n        handleSubmit,\n        form,\n        submitting,\n        pristine,\n        values,\n      }) => (\n        <form onSubmit={handleSubmit}>\n          <Field name=\"username\">\n            {({ input, meta }) => (\n              <div>\n                <label>Username</label>\n                <input {...input} type=\"text\" placeholder=\"Username\" />\n                {(meta.error || meta.submitError) && meta.touched && (\n                  <span>{meta.error || meta.submitError}</span>\n                )}\n              </div>\n            )}\n          </Field>\n          <Field name=\"password\">\n            {({ input, meta }) => (\n              <div>\n                <label>Password</label>\n                <input {...input} type=\"password\" placeholder=\"Password\" />\n                {meta.error && meta.touched && <span>{meta.error}</span>}\n              </div>\n            )}\n          </Field>\n          {submitError && <div className=\"error\">{submitError}</div>}\n          <div className=\"buttons\">\n            <button type=\"submit\" disabled={submitting}>\n              Log In\n            </button>\n            <button\n              type=\"button\"\n              onClick={form.reset}\n              disabled={submitting || pristine}\n            >\n              Reset\n            </button>\n          </div>\n          <pre>{JSON.stringify(values, 0, 2)}</pre>\n        </form>\n      )}\n    />\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/submission-errors/package.json",
    "content": "{\n  \"name\": \"React Final Form - Submission Errors\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example of a form with submission errors created with React Final Form\",\n  \"keywords\": [\n    \"state management\",\n    \"react-final-form\",\n    \"form\",\n    \"final-form\",\n    \"react\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"styled-components\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react\": \"latest\",\n    \"react-dom\": \"latest\",\n    \"final-form\": \"4.20.4\"\n  }\n}\n"
  },
  {
    "path": "examples/submission-errors/readme.md",
    "content": "# Submission Errors Example\n\n[![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?fontsize=14)\n"
  },
  {
    "path": "examples/subscriptions/RenderCount.js",
    "content": "import React from \"react\";\nimport styled from \"styled-components\";\n\nexport default function RenderCount() {\n  const renders = React.useRef(0);\n\n  return <Circle>{++renders.current}</Circle>;\n}\n\nconst size = 30;\nconst Circle = styled.i`\n  position: absolute;\n  top: 0;\n  right: 0;\n  font-style: normal;\n  text-align: center;\n  height: ${size}px;\n  width: ${size}px;\n  line-height: ${size}px;\n  border-radius: ${size / 2}px;\n  border: 1px solid #ddd;\n  background: #eee;\n`;\n"
  },
  {
    "path": "examples/subscriptions/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1,\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n  }\n\n  form {\n    position: relative;\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n\n    & > div {\n      position: relative;\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      & > label {\n        color: #333;\n        width: 110px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/subscriptions/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field, FormSpy } from \"react-final-form\";\nimport RenderCount from \"./RenderCount\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\nconst required = (value) => (value ? undefined : \"Required\");\n\nconst App = () => (\n  <Styles>\n    <h1>React Final Form Example</h1>\n    <h2>Performance Optimization Through Subscriptions</h2>\n    <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n      Read Docs\n    </a>\n    <p>\n      In this example, the numbers in the circles are the number of times that\n      component has been rendered.\n    </p>\n    <p>\n      The top form, with no specified subscription, rerenders the whole form and\n      every input on every change.\n    </p>\n    <MyForm />\n    <p>\n      The bottom form subscribes only to the changes it needs to update. By not\n      rerendering the whole form on every change, the fields, too, become\n      independent. Notice that we must now use a <code>FormSpy</code> component\n      to show the values in realtime.\n    </p>\n    <MyForm subscription={{ submitting: true, pristine: true }} />\n  </Styles>\n);\n\nconst MyForm = ({ subscription }) => (\n  <Form\n    onSubmit={onSubmit}\n    subscription={subscription}\n    render={({ handleSubmit, form, submitting, pristine, values }) => (\n      <form onSubmit={handleSubmit}>\n        <RenderCount />\n        <Field name=\"firstName\" validate={required}>\n          {({ input, meta }) => (\n            <div>\n              <RenderCount />\n              <label>First Name</label>\n              <input {...input} placeholder=\"First Name\" />\n              {meta.touched && meta.error && <span>{meta.error}</span>}\n            </div>\n          )}\n        </Field>\n        <Field name=\"lastName\" validate={required}>\n          {({ input, meta }) => (\n            <div>\n              <RenderCount />\n              <label>Last Name</label>\n              <input {...input} placeholder=\"Last Name\" />\n              {meta.touched && meta.error && <span>{meta.error}</span>}\n            </div>\n          )}\n        </Field>\n        <div className=\"buttons\">\n          <button type=\"submit\" disabled={submitting}>\n            Submit\n          </button>\n          <button\n            type=\"button\"\n            onClick={form.reset}\n            disabled={submitting || pristine}\n          >\n            Reset\n          </button>\n        </div>\n        {values ? (\n          <pre>\n            <RenderCount />\n            {JSON.stringify(values, 0, 2)}\n          </pre>\n        ) : (\n          <FormSpy subscription={{ values: true }}>\n            {({ values }) => (\n              <pre>\n                <RenderCount />\n                {JSON.stringify(values, 0, 2)}\n              </pre>\n            )}\n          </FormSpy>\n        )}\n      </form>\n    )}\n  />\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/subscriptions/package.json",
    "content": "{\n  \"name\": \"React Final Form - Subscriptions Example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example of controlling rerenders using subscriptions\",\n  \"keywords\": [\n    \"state management\",\n    \"react-final-form\",\n    \"form\",\n    \"final-form\",\n    \"react\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"styled-components\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react\": \"latest\",\n    \"react-dom\": \"latest\",\n    \"final-form\": \"4.20.4\"\n  }\n}\n"
  },
  {
    "path": "examples/subscriptions/readme.md",
    "content": "# Subscriptions Example\n\n[![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?fontsize=14)\n"
  },
  {
    "path": "examples/third-party-components/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  & > a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n    button {\n      margin: 0 10px;\n      &[type=\"submit\"] {\n        ${btnPrimary};\n      }\n      &[type=\"button\"] {\n        ${btnDefault};\n      }\n    }\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    .Select {\n      width: 100%;\n    }\n    pre {\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/third-party-components/index.js",
    "content": "import React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Form, Field } from \"react-final-form\";\nimport MuiThemeProvider from \"material-ui/styles/MuiThemeProvider\";\nimport getMuiTheme from \"material-ui/styles/getMuiTheme\";\nimport TextField from \"material-ui/TextField\";\nimport Toggle from \"material-ui/Toggle\";\nimport Select from \"react-select\";\nimport states from \"./states\";\n\nconst TextFieldAdapter = ({ input, meta, ...rest }) => (\n  <TextField\n    {...input}\n    {...rest}\n    onChange={(event, value) => input.onChange(value)}\n    errorText={meta.touched ? meta.error : \"\"}\n  />\n);\n\nconst ToggleAdapter = ({ input: { onChange, value }, label, ...rest }) => (\n  <Toggle\n    label={label}\n    toggled={!!value}\n    onToggle={(event, isInputChecked) => onChange(isInputChecked)}\n    {...rest}\n  />\n);\n\nconst ReactSelectAdapter = ({ input, ...rest }) => (\n  <Select {...input} {...rest} searchable />\n);\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\nconst required = (value) => (value ? undefined : \"Required\");\n\nconst App = () => (\n  <MuiThemeProvider muiTheme={getMuiTheme()}>\n    <Styles>\n      <h1>\n        <span role=\"img\" aria-label=\"final form flag\">\n          🏁\n        </span>{\" \"}\n        React Final Form Example\n      </h1>\n      <h2>Third Party Components</h2>\n      <a href=\"https://github.com/erikras/react-final-form#-react-final-form\">\n        Read Docs\n      </a>\n      <div>\n        This example uses{\" \"}\n        <a href=\"https://github.com/JedWatson/react-select\">React Select</a> and{\" \"}\n        <a href=\"http://www.material-ui.com\">Material UI</a>.\n      </div>\n      <Form\n        onSubmit={onSubmit}\n        render={({ handleSubmit, form, submitting, pristine, values }) => (\n          <form onSubmit={handleSubmit}>\n            <div>\n              <Field\n                name=\"firstName\"\n                component={TextFieldAdapter}\n                validate={required}\n                hintText=\"First Name\"\n                floatingLabelText=\"First Name\"\n              />\n            </div>\n            <div>\n              <Field\n                name=\"state\"\n                component={ReactSelectAdapter}\n                options={states}\n              />\n            </div>\n            <div>\n              <Field\n                name=\"employed\"\n                label=\"Employed?\"\n                component={ToggleAdapter}\n                labelPosition=\"right\"\n              />\n            </div>\n            <div className=\"buttons\">\n              <button type=\"submit\" disabled={submitting}>\n                Log In\n              </button>\n              <button\n                type=\"button\"\n                onClick={form.reset}\n                disabled={submitting || pristine}\n              >\n                Reset\n              </button>\n            </div>\n            <pre>{JSON.stringify(values, 0, 2)}</pre>\n          </form>\n        )}\n      />\n    </Styles>\n  </MuiThemeProvider>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/third-party-components/package.json",
    "content": "{\n  \"name\": \"react-final-form-third-party-components-example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"This example 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.\",\n  \"keywords\": [\n    \"react\",\n    \"inputs\",\n    \"react-final-form\",\n    \"material-ui\",\n    \"final-form\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"final-form\": \"4.20.4\",\n    \"material-ui\": \"0.20.2\",\n    \"react\": \"17.0.2\",\n    \"react-addons-shallow-compare\": \"15.6.2\",\n    \"react-dom\": \"17.0.2\",\n    \"react-final-form\": \"6.5.3\",\n    \"react-select\": \"2.4.3\",\n    \"styled-components\": \"4.2.0\"\n  }\n}\n"
  },
  {
    "path": "examples/third-party-components/readme.md",
    "content": "# Third Party Components\n\n[![Edit react-final-form-third-party-components-example](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/40mr0v2r87)\n"
  },
  {
    "path": "examples/third-party-components/states.js",
    "content": "const states = {\n  AL: \"Alabama\",\n  AK: \"Alaska\",\n  AS: \"American Samoa\",\n  AZ: \"Arizona\",\n  AR: \"Arkansas\",\n  CA: \"California\",\n  CO: \"Colorado\",\n  CT: \"Connecticut\",\n  DE: \"Delaware\",\n  DC: \"District Of Columbia\",\n  FM: \"Federated States Of Micronesia\",\n  FL: \"Florida\",\n  GA: \"Georgia\",\n  GU: \"Guam\",\n  HI: \"Hawaii\",\n  ID: \"Idaho\",\n  IL: \"Illinois\",\n  IN: \"Indiana\",\n  IA: \"Iowa\",\n  KS: \"Kansas\",\n  KY: \"Kentucky\",\n  LA: \"Louisiana\",\n  ME: \"Maine\",\n  MH: \"Marshall Islands\",\n  MD: \"Maryland\",\n  MA: \"Massachusetts\",\n  MI: \"Michigan\",\n  MN: \"Minnesota\",\n  MS: \"Mississippi\",\n  MO: \"Missouri\",\n  MT: \"Montana\",\n  NE: \"Nebraska\",\n  NV: \"Nevada\",\n  NH: \"New Hampshire\",\n  NJ: \"New Jersey\",\n  NM: \"New Mexico\",\n  NY: \"New York\",\n  NC: \"North Carolina\",\n  ND: \"North Dakota\",\n  MP: \"Northern Mariana Islands\",\n  OH: \"Ohio\",\n  OK: \"Oklahoma\",\n  OR: \"Oregon\",\n  PW: \"Palau\",\n  PA: \"Pennsylvania\",\n  PR: \"Puerto Rico\",\n  RI: \"Rhode Island\",\n  SC: \"South Carolina\",\n  SD: \"South Dakota\",\n  TN: \"Tennessee\",\n  TX: \"Texas\",\n  UT: \"Utah\",\n  VT: \"Vermont\",\n  VI: \"Virgin Islands\",\n  VA: \"Virginia\",\n  WA: \"Washington\",\n  WV: \"West Virginia\",\n  WI: \"Wisconsin\",\n  WY: \"Wyoming\",\n};\nexport default Object.keys(states).map((value) => ({\n  value,\n  label: states[value],\n}));\n"
  },
  {
    "path": "examples/wizard/Styles.js",
    "content": "import styled, { css } from \"styled-components\";\n\nconst btn = (light, dark) => css`\n  white-space: nowrap;\n  display: inline-block;\n  border-radius: 5px;\n  padding: 5px 15px;\n  font-size: 16px;\n  color: white;\n  &:visited {\n    color: white;\n  }\n  background-image: linear-gradient(${light}, ${dark});\n  border: 1px solid ${dark};\n  &:hover {\n    background-image: linear-gradient(${light}, ${dark});\n    &[disabled] {\n      background-image: linear-gradient(${light}, ${dark});\n    }\n  }\n  &:visited {\n    color: black;\n  }\n  &[disabled] {\n    opacity: 0.6;\n    cursor: not-allowed;\n  }\n`;\n\nconst btnDefault = css`\n  ${btn(\"#ffffff\", \"#d5d5d5\")} color: #555;\n`;\n\nconst btnPrimary = btn(\"#4f93ce\", \"#285f8f\");\nconst btnDanger = btn(\"#e27c79\", \"#c9302c\");\n\nexport default styled.div`\n  font-family: sans-serif;\n\n  h1 {\n    text-align: center;\n    color: #222;\n  }\n\n  h2 {\n    text-align: center;\n    color: #222;\n  }\n\n  & > div {\n    text-align: center;\n  }\n\n  a {\n    display: block;\n    text-align: center;\n    color: #222;\n    margin-bottom: 10px;\n  }\n\n  p {\n    max-width: 500px;\n    margin: 10px auto;\n    & > a {\n      display: inline;\n    }\n  }\n\n  form {\n    max-width: 500px;\n    margin: 10px auto;\n    border: 1px solid #ccc;\n    padding: 20px;\n    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);\n    border-radius: 3px;\n    position: relative;\n\n    .loading {\n      text-align: center;\n      display: block;\n      position: absolute;\n      background: url(\"https://media.giphy.com/media/130AxGoOaR6t0I/giphy.gif\")\n        center center;\n      background-size: fill;\n      font-size: 2em;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding: 50px 0 0 0;\n      z-index: 2;\n    }\n\n    & > div {\n      display: flex;\n      flex-flow: row nowrap;\n      line-height: 2em;\n      margin: 5px;\n      position: relative;\n      & > label {\n        color: #333;\n        width: 110px;\n        min-width: 60px;\n        font-size: 1em;\n        line-height: 32px;\n      }\n      & > input,\n      & > select,\n      & > textarea {\n        flex: 1;\n        padding: 3px 5px;\n        font-size: 1em;\n        margin-left: 15px;\n        border: 1px solid #ccc;\n        border-radius: 3px;\n      }\n      & > input[type=\"checkbox\"] {\n        margin-top: 7px;\n      }\n      & > div {\n        margin-left: 16px;\n        & > label {\n          display: block;\n          & > input {\n            margin-right: 3px;\n          }\n        }\n      }\n      & > span {\n        line-height: 32px;\n        margin-left: 10px;\n        color: #800;\n        font-weight: bold;\n      }\n      & > button.remove {\n        ${btnDanger};\n      }\n    }\n    & > .buttons {\n      display: flex;\n      flex-flow: row nowrap;\n      justify-content: center;\n      margin-top: 15px;\n    }\n\n    .error {\n      display: flex;\n      font-weight: bold;\n      color: #800;\n      flex-flow: row nowrap;\n      justify-content: center;\n    }\n    pre {\n      position: relative;\n      border: 1px solid #ccc;\n      background: rgba(0, 0, 0, 0.1);\n      box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.2);\n      padding: 20px;\n    }\n  }\n  button {\n    margin: 0 10px;\n    &[type=\"submit\"] {\n      ${btnPrimary};\n    }\n    &[type=\"button\"] {\n      ${btnDefault};\n    }\n  }\n`;\n"
  },
  {
    "path": "examples/wizard/Wizard.js",
    "content": "import React from \"react\";\nimport PropTypes from \"prop-types\";\nimport { Form } from \"react-final-form\";\n\nexport default class Wizard extends React.Component {\n  static propTypes = {\n    onSubmit: PropTypes.func.isRequired,\n  };\n  static Page = ({ children }) => children;\n\n  constructor(props) {\n    super(props);\n    this.state = {\n      page: 0,\n      values: props.initialValues || {},\n    };\n  }\n  next = (values) =>\n    this.setState((state) => ({\n      page: Math.min(state.page + 1, this.props.children.length - 1),\n      values,\n    }));\n\n  previous = () =>\n    this.setState((state) => ({\n      page: Math.max(state.page - 1, 0),\n    }));\n\n  /**\n   * NOTE: Both validate and handleSubmit switching are implemented\n   * here because 🏁 Redux Final Form does not accept changes to those\n   * functions once the form has been defined.\n   */\n\n  validate = (values) => {\n    const activePage = React.Children.toArray(this.props.children)[\n      this.state.page\n    ];\n    return activePage.props.validate ? activePage.props.validate(values) : {};\n  };\n\n  handleSubmit = (values) => {\n    const { children, onSubmit } = this.props;\n    const { page } = this.state;\n    const isLastPage = page === React.Children.count(children) - 1;\n    if (isLastPage) {\n      return onSubmit(values);\n    } else {\n      this.next(values);\n    }\n  };\n\n  render() {\n    const { children } = this.props;\n    const { page, values } = this.state;\n    const activePage = React.Children.toArray(children)[page];\n    const isLastPage = page === React.Children.count(children) - 1;\n    return (\n      <Form\n        initialValues={values}\n        validate={this.validate}\n        onSubmit={this.handleSubmit}\n      >\n        {({ handleSubmit, submitting, values }) => (\n          <form onSubmit={handleSubmit}>\n            {activePage}\n            <div className=\"buttons\">\n              {page > 0 && (\n                <button type=\"button\" onClick={this.previous}>\n                  « Previous\n                </button>\n              )}\n              {!isLastPage && <button type=\"submit\">Next »</button>}\n              {isLastPage && (\n                <button type=\"submit\" disabled={submitting}>\n                  Submit\n                </button>\n              )}\n            </div>\n\n            <pre>{JSON.stringify(values, 0, 2)}</pre>\n          </form>\n        )}\n      </Form>\n    );\n  }\n}\n"
  },
  {
    "path": "examples/wizard/index.js",
    "content": "/* eslint-disable jsx-a11y/accessible-emoji */\nimport React from \"react\";\nimport { render } from \"react-dom\";\nimport Styles from \"./Styles\";\nimport { Field } from \"react-final-form\";\nimport Wizard from \"./Wizard\";\n\nconst sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\n\nconst onSubmit = async (values) => {\n  await sleep(300);\n  window.alert(JSON.stringify(values, 0, 2));\n};\n\nconst Error = ({ name }) => (\n  <Field\n    name={name}\n    subscription={{ touched: true, error: true }}\n    render={({ meta: { touched, error } }) =>\n      touched && error ? <span>{error}</span> : null\n    }\n  />\n);\n\nconst required = (value) => (value ? undefined : \"Required\");\n\nconst App = () => (\n  <Styles>\n    <h1>React Final Form Example</h1>\n    <h2>Wizard Form</h2>\n    <a\n      href=\"https://final-form.org/react\"\n      target=\"_blank\"\n      rel=\"noopener noreferrer\"\n    >\n      Read Docs\n    </a>\n    <p>\n      Notice the mixture of field-level and record-level (or <em>page-level</em>{\" \"}\n      in this case) validation.\n    </p>\n    <Wizard\n      initialValues={{ employed: true, stooge: \"larry\" }}\n      onSubmit={onSubmit}\n    >\n      <Wizard.Page>\n        <div>\n          <label>First Name</label>\n          <Field\n            name=\"firstName\"\n            component=\"input\"\n            type=\"text\"\n            placeholder=\"First Name\"\n            validate={required}\n          />\n          <Error name=\"firstName\" />\n        </div>\n        <div>\n          <label>Last Name</label>\n          <Field\n            name=\"lastName\"\n            component=\"input\"\n            type=\"text\"\n            placeholder=\"Last Name\"\n            validate={required}\n          />\n          <Error name=\"lastName\" />\n        </div>\n      </Wizard.Page>\n      <Wizard.Page\n        validate={(values) => {\n          const errors = {};\n          if (!values.email) {\n            errors.email = \"Required\";\n          }\n          if (!values.favoriteColor) {\n            errors.favoriteColor = \"Required\";\n          }\n          return errors;\n        }}\n      >\n        <div>\n          <label>Email</label>\n          <Field\n            name=\"email\"\n            component=\"input\"\n            type=\"email\"\n            placeholder=\"Email\"\n          />\n          <Error name=\"email\" />\n        </div>\n        <div>\n          <label>Favorite Color</label>\n          <Field name=\"favoriteColor\" component=\"select\">\n            <option />\n            <option value=\"#ff0000\">❤️ Red</option>\n            <option value=\"#00ff00\">💚 Green</option>\n            <option value=\"#0000ff\">💙 Blue</option>\n          </Field>\n          <Error name=\"favoriteColor\" />\n        </div>\n      </Wizard.Page>\n      <Wizard.Page\n        validate={(values) => {\n          const errors = {};\n          if (!values.toppings) {\n            errors.toppings = \"Required\";\n          } else if (values.toppings.length < 2) {\n            errors.toppings = \"Choose more\";\n          }\n          return errors;\n        }}\n      >\n        <div>\n          <label>Employed?</label>\n          <Field name=\"employed\" component=\"input\" type=\"checkbox\" />\n        </div>\n        <div>\n          <label>Toppings</label>\n          <Field name=\"toppings\" component=\"select\" multiple>\n            <option value=\"ham\">🐷 Ham</option>\n            <option value=\"mushrooms\">🍄 Mushrooms</option>\n            <option value=\"cheese\">🧀 Cheese</option>\n            <option value=\"chicken\">🐓 Chicken</option>\n            <option value=\"pineapple\">🍍 Pinapple</option>\n          </Field>\n          <Error name=\"toppings\" />\n        </div>\n      </Wizard.Page>\n      <Wizard.Page\n        validate={(values) => {\n          const errors = {};\n          if (!values.notes) {\n            errors.notes = \"Required\";\n          }\n          return errors;\n        }}\n      >\n        <div>\n          <label>Best Stooge?</label>\n          <div>\n            <label>\n              <Field\n                name=\"stooge\"\n                component=\"input\"\n                type=\"radio\"\n                value=\"larry\"\n              />{\" \"}\n              Larry\n            </label>\n            <label>\n              <Field name=\"stooge\" component=\"input\" type=\"radio\" value=\"moe\" />{\" \"}\n              Moe\n            </label>\n            <label>\n              <Field\n                name=\"stooge\"\n                component=\"input\"\n                type=\"radio\"\n                value=\"curly\"\n              />{\" \"}\n              Curly\n            </label>\n          </div>\n        </div>\n        <div>\n          <label>Notes</label>\n          <Field name=\"notes\" component=\"textarea\" placeholder=\"Notes\" />\n          <Error name=\"notes\" />\n        </div>\n      </Wizard.Page>\n    </Wizard>\n  </Styles>\n);\n\nrender(<App />, document.getElementById(\"root\"));\n"
  },
  {
    "path": "examples/wizard/package.json",
    "content": "{\n  \"name\": \"Wizard-Example\",\n  \"version\": \"1.0.0\",\n  \"description\": \"An example of a wizard form created with React Final Form\",\n  \"keywords\": [\n    \"state management\",\n    \"react-final-form\",\n    \"form\",\n    \"final-form\",\n    \"react\"\n  ],\n  \"main\": \"index.js\",\n  \"dependencies\": {\n    \"prop-types\": \"latest\",\n    \"styled-components\": \"latest\",\n    \"react-final-form\": \"6.5.3\",\n    \"react\": \"latest\",\n    \"react-dom\": \"latest\",\n    \"react-scripts\": \"3.0.1\",\n    \"final-form\": \"4.20.4\",\n    \"prop-types\": \"latest\"\n  },\n  \"scripts\": {\n    \"start\": \"react-scripts start\",\n    \"build\": \"react-scripts build\"\n  },\n  \"browserslist\": [\n    \">0.2%\",\n    \"not dead\",\n    \"not ie <= 11\",\n    \"not op_mini all\"\n  ]\n}\n"
  },
  {
    "path": "examples/wizard/readme.md",
    "content": "# Wizard Form Example\n\n[![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?fontsize=14)\n"
  },
  {
    "path": "package-scripts.js",
    "content": "const npsUtils = require(\"nps-utils\");\n\nconst series = npsUtils.series;\nconst concurrent = npsUtils.concurrent;\nconst rimraf = npsUtils.rimraf;\nconst crossEnv = npsUtils.crossEnv;\n\nmodule.exports = {\n  scripts: {\n    test: {\n      default: crossEnv(\"NODE_ENV=test jest --coverage\"),\n      update: crossEnv(\"NODE_ENV=test jest --coverage --updateSnapshot\"),\n      watch: crossEnv(\"NODE_ENV=test jest --watch\"),\n      codeCov: crossEnv(\n        \"cat ./coverage/lcov.info | ./node_modules/codecov.io/bin/codecov.io.js\",\n      ),\n      size: {\n        description: \"check the size of the bundle\",\n        script: \"size-limit\",\n      },\n    },\n    build: {\n      description: \"delete the dist directory and run all builds\",\n      default: series(\n        rimraf(\"dist\"),\n        concurrent.nps(\n          \"build.es\",\n          \"build.cjs\",\n          \"build.umd.main\",\n          \"build.umd.min\",\n        ),\n        \"tsc --project tsconfig.build.json\",\n        'echo \\'{\"name\":\"react-final-form\",\"main\":\"react-final-form.cjs.js\",\"module\":\"react-final-form.es.js\",\"types\":\"index.d.ts\"}\\' > dist/package.json',\n      ),\n      es: {\n        description: \"run the build with rollup (uses rollup.config.js)\",\n        script: \"rollup --config --environment FORMAT:es\",\n      },\n      cjs: {\n        description: \"run rollup build with CommonJS format\",\n        script: \"rollup --config --environment FORMAT:cjs\",\n      },\n      umd: {\n        min: {\n          description: \"run the rollup build with sourcemaps\",\n          script: \"rollup --config --sourcemap --environment MINIFY,FORMAT:umd\",\n        },\n        main: {\n          description: \"builds the cjs and umd files\",\n          script: \"rollup --config --sourcemap --environment FORMAT:umd\",\n        },\n      },\n      andTest: series.nps(\"build\", \"test.size\"),\n    },\n    docs: {\n      description: \"Generates table of contents in README\",\n      script: \"doctoc README.md\",\n    },\n    prettier: {\n      description: \"Runs prettier on everything\",\n      script: 'prettier --write \"**/*.([jt]s*)\"',\n    },\n    lint: {\n      description: \"lint the entire project\",\n      script: \"eslint .\",\n    },\n    typescript: {\n      default: {\n        description: \"typescript type checking\",\n        script: \"tsc --noEmit\",\n      },\n      definitions: {\n        description: \"typescript definition tests\",\n        script: \"cd typescript && tsc --noEmit --skipLibCheck\",\n      },\n    },\n    validate: {\n      description:\n        \"This runs several scripts to make sure things look good before committing or on clean install\",\n      default: series(\n        \"nps build.andTest\",\n        concurrent.nps(\"lint\", \"typescript\", \"typescript.definitions\", \"test\"),\n      ),\n    },\n  },\n  options: {\n    silent: false,\n  },\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"react-final-form\",\n  \"version\": \"7.0.0\",\n  \"description\": \"🏁 High performance subscription-based form state management for React\",\n  \"main\": \"dist/react-final-form.cjs.js\",\n  \"jsnext:main\": \"dist/react-final-form.es.js\",\n  \"module\": \"dist/react-final-form.es.js\",\n  \"typings\": \"dist/index.d.ts\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"start\": \"nps\",\n    \"test\": \"nps test\",\n    \"precommit\": \"lint-staged && npm start validate\",\n    \"build\": \"yarn start build\",\n    \"prepublish\": \"yarn start validate\",\n    \"setup\": \"yarn install\"\n  },\n  \"author\": \"Erik Rasmussen <rasmussenerik@gmail.com> (http://github.com/erikras)\",\n  \"license\": \"MIT\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/final-form/react-final-form.git\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/final-form/react-final-form/issues\"\n  },\n  \"homepage\": \"https://github.com/final-form/react-final-form#readme\",\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.27.1\",\n    \"@babel/plugin-syntax-dynamic-import\": \"^7.8.3\",\n    \"@babel/plugin-syntax-import-meta\": \"^7.10.4\",\n    \"@babel/plugin-transform-react-jsx-source\": \"^7.27.1\",\n    \"@babel/plugin-transform-runtime\": \"^7.27.1\",\n    \"@babel/preset-env\": \"^7.27.2\",\n    \"@babel/preset-react\": \"^7.27.1\",\n    \"@babel/preset-typescript\": \"^7.27.1\",\n    \"@rollup/plugin-babel\": \"^6.0.4\",\n    \"@rollup/plugin-commonjs\": \"^25.0.8\",\n    \"@rollup/plugin-json\": \"^6.1.0\",\n    \"@rollup/plugin-node-resolve\": \"^15.2.4\",\n    \"@rollup/plugin-replace\": \"^5.0.7\",\n    \"@rollup/plugin-terser\": \"^0.4.4\",\n    \"@testing-library/dom\": \"^10.4.0\",\n    \"@testing-library/jest-dom\": \"^6.6.3\",\n    \"@testing-library/react\": \"^16.3.0\",\n    \"@types/node\": \"^20.17.50\",\n    \"@types/react\": \"^19.1.5\",\n    \"@types/react-dom\": \"^19.1.5\",\n    \"@typescript-eslint/eslint-plugin\": \"^8.32.1\",\n    \"@typescript-eslint/parser\": \"^8.32.1\",\n    \"babel-core\": \"^7.0.0-bridge.0\",\n    \"babel-eslint\": \"^10.1.0\",\n    \"babel-jest\": \"^29.7.0\",\n    \"@size-limit/preset-small-lib\": \"^11.1.6\",\n    \"size-limit\": \"^11.1.6\",\n    \"doctoc\": \"^2.2.1\",\n    \"dtslint\": \"^4.2.1\",\n    \"eslint\": \"^9.27.0\",\n    \"eslint-config-react-app\": \"^7.0.1\",\n    \"eslint-plugin-babel\": \"^5.3.1\",\n    \"eslint-plugin-import\": \"^2.31.0\",\n    \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n    \"eslint-plugin-react\": \"^7.37.5\",\n    \"eslint-plugin-react-hooks\": \"^5.2.0\",\n    \"fast-deep-equal\": \"^3.1.3\",\n    \"final-form\": \"5.0.0\",\n    \"husky\": \"^9.1.7\",\n    \"jest\": \"^29.7.0\",\n    \"jest-environment-jsdom\": \"^29.7.0\",\n    \"jest-mock-console\": \"^2.0.0\",\n    \"lint-staged\": \"^15.2.11\",\n    \"nps\": \"^5.10.0\",\n    \"nps-utils\": \"^1.7.0\",\n    \"opencollective\": \"^1.0.3\",\n    \"prettier\": \"^3.5.3\",\n    \"prettier-eslint-cli\": \"^8.0.1\",\n    \"react\": \"^19.1.0\",\n    \"react-dom\": \"^19.1.0\",\n    \"rollup\": \"^3.29.5\",\n    \"tar\": \"^7.4.3\",\n    \"ts-essentials\": \"^10.0.4\",\n    \"tslint\": \"^6.1.3\",\n    \"typescript\": \"^5.8.3\"\n  },\n  \"peerDependencies\": {\n    \"final-form\": \"^5.0.0\",\n    \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\n  },\n  \"lint-staged\": {\n    \"*.{js*,ts*,json,md,css}\": [\n      \"prettier --write\",\n      \"git add\"\n    ]\n  },\n  \"jest\": {\n    \"testEnvironment\": \"jsdom\",\n    \"testPathIgnorePatterns\": [\n      \"/node_modules/\",\n      \"/typescript/\"\n    ]\n  },\n  \"size-limit\": [\n    {\n      \"path\": \"dist/react-final-form.umd.min.js\",\n      \"limit\": \"4kB\"\n    },\n    {\n      \"path\": \"dist/react-final-form.es.js\",\n      \"limit\": \"4kB\"\n    },\n    {\n      \"path\": \"dist/react-final-form.cjs.js\",\n      \"limit\": \"4kB\"\n    }\n  ],\n  \"collective\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/final-form\"\n  },\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/final-form\"\n  },\n  \"dependencies\": {\n    \"@babel/runtime\": \"^7.15.4\"\n  }\n}\n"
  },
  {
    "path": "rollup.config.mjs",
    "content": "import { nodeResolve } from \"@rollup/plugin-node-resolve\";\nimport babel from \"@rollup/plugin-babel\";\nimport commonjs from \"@rollup/plugin-commonjs\";\nimport json from \"@rollup/plugin-json\";\nimport terser from \"@rollup/plugin-terser\";\nimport replace from \"@rollup/plugin-replace\";\n// import pkg from \"./package.json\" assert { type: \"json\" };\n// Hardcode version to avoid import issues\nconst pkg = {\n  version: \"6.5.9\",\n  dependencies: {\n    \"@babel/runtime\": \"^7.15.4\",\n  },\n  peerDependencies: {\n    \"final-form\": \"^5.0.0-0\",\n    react: \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\",\n  },\n};\n\nconst makeExternalPredicate = (externalArr) => {\n  if (externalArr.length === 0) {\n    return () => false;\n  }\n  const pattern = new RegExp(`^(${externalArr.join(\"|\")})($|/)`);\n  return (id) => pattern.test(id);\n};\n\nconst minify = process.env.MINIFY;\nconst format = process.env.FORMAT;\nconst es = format === \"es\";\nconst umd = format === \"umd\";\nconst cjs = format === \"cjs\";\n\nlet output;\n\nif (es) {\n  output = { file: `dist/react-final-form.es.js`, format: \"es\" };\n} else if (umd) {\n  if (minify) {\n    output = {\n      file: `dist/react-final-form.umd.min.js`,\n      format: \"umd\",\n    };\n  } else {\n    output = { file: `dist/react-final-form.umd.js`, format: \"umd\" };\n  }\n} else if (cjs) {\n  output = { file: `dist/react-final-form.cjs.js`, format: \"cjs\" };\n} else if (format) {\n  throw new Error(`invalid format specified: \"${format}\".`);\n} else {\n  throw new Error(\"no format specified. --environment FORMAT:xxx\");\n}\n\nexport default {\n  input: \"src/index.ts\",\n  output: Object.assign(\n    {\n      name: \"react-final-form\",\n      exports: \"named\",\n      globals: {\n        react: \"React\",\n        \"final-form\": \"FinalForm\",\n      },\n    },\n    output,\n  ),\n\n  external: makeExternalPredicate(\n    umd\n      ? Object.keys(pkg.peerDependencies || {})\n      : [\n          ...Object.keys(pkg.dependencies || {}),\n          ...Object.keys(pkg.peerDependencies || {}),\n        ],\n  ),\n  plugins: [\n    nodeResolve({\n      extensions: [\".js\", \".jsx\", \".ts\", \".tsx\"],\n    }),\n    json(),\n    commonjs(),\n    babel({\n      exclude: \"node_modules/**\",\n      extensions: [\".js\", \".jsx\", \".ts\", \".tsx\"],\n      plugins: [[\"@babel/plugin-transform-runtime\", { useESModules: !cjs }]],\n      babelHelpers: \"runtime\",\n    }),\n    umd\n      ? replace({\n          \"process.env.NODE_ENV\": JSON.stringify(\n            minify ? \"production\" : \"development\",\n          ),\n          preventAssignment: true,\n        })\n      : null,\n    minify ? terser() : null,\n  ].filter(Boolean),\n};\n"
  },
  {
    "path": "src/Field.test.js",
    "content": "import React from \"react\";\nimport { render, fireEvent, cleanup, act } from \"@testing-library/react\";\nimport \"@testing-library/jest-dom\";\nimport { ErrorBoundary, Toggle, wrapWith } from \"./testUtils\";\nimport Form from \"./ReactFinalForm\";\nimport Field from \"./Field\";\n\nconst onSubmitMock = (_values) => {};\n\nconst timeout = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\nasync function sleep(ms) {\n  await act(async () => {\n    await timeout(ms);\n  });\n}\n\ndescribe(\"Field\", () => {\n  afterEach(cleanup);\n\n  it(\"should warn if not used inside a form\", () => {\n    jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const errorSpy = jest.fn();\n    render(\n      <ErrorBoundary spy={errorSpy}>\n        <Field name=\"name\" component=\"input\" />\n      </ErrorBoundary>,\n    );\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0].message).toBe(\n      \"useField must be used inside of a <Form> component\",\n    );\n    console.error.mockRestore();\n  });\n\n  it(\"should resubscribe if name changes\", () => {\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(isCat) => (\n          <Form\n            onSubmit={onSubmitMock}\n            initialValues={{ dog: \"Odie\", cat: \"Garfield\" }}\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field\n                  name={isCat ? \"cat\" : \"dog\"}\n                  component=\"input\"\n                  data-testid=\"name\"\n                />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"Odie\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"name\").value).toBe(\"Garfield\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"name\").value).toBe(\"Odie\");\n  });\n\n  it(\"should render via children render function\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\">\n              {({ input }) => <input {...input} data-testid=\"name\" />}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\")).toBeDefined();\n  });\n\n  it(\"should render via render prop function\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field\n              name=\"name\"\n              render={({ input }) => <input {...input} data-testid=\"name\" />}\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\")).toBeDefined();\n  });\n\n  it(\"should include children when rendering via render prop function\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field\n              name=\"color\"\n              render={({ input, children }) => (\n                <select {...input} data-testid=\"color\">\n                  {children}\n                </select>\n              )}\n            >\n              <option value=\"red\" data-testid=\"red\">\n                Red\n              </option>\n              <option value=\"green\" data-testid=\"green\">\n                Green\n              </option>\n              <option value=\"blue\" data-testid=\"blue\">\n                Blue\n              </option>\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"color\")).toBeDefined();\n    expect(getByTestId(\"red\")).toBeDefined();\n    expect(getByTestId(\"green\")).toBeDefined();\n    expect(getByTestId(\"blue\")).toBeDefined();\n  });\n\n  it(\"should unsubscribe on unmount\", () => {\n    // This is mainly here for code coverage. 🧐\n    const { getByText } = render(\n      <Toggle>\n        {(hidden) => (\n          <Form\n            onSubmit={onSubmitMock}\n            initialValues={{ dog: \"Odie\", cat: \"Garfield\" }}\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                {!hidden && (\n                  <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n                )}\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    fireEvent.click(getByText(\"Toggle\"));\n  });\n\n  it(\"should focus, change, and blur\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{}}>\n        {() => (\n          <form>\n            <Field name=\"name\">\n              {wrapWith(spy, ({ input }) => (\n                <input {...input} data-testid=\"name\" />\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0].meta.active).toBe(false);\n    expect(spy.mock.calls[0][0].input.value).toBe(\"\");\n    fireEvent.focus(getByTestId(\"name\"));\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0].meta.active).toBe(true);\n    expect(spy.mock.calls[2][0].input.value).toBe(\"\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[3][0].meta.active).toBe(true);\n    expect(spy.mock.calls[3][0].input.value).toBe(\"erikras\");\n    fireEvent.blur(getByTestId(\"name\"));\n    expect(spy).toHaveBeenCalledTimes(5);\n    expect(spy.mock.calls[4][0].meta.active).toBe(false);\n    expect(spy.mock.calls[4][0].input.value).toBe(\"erikras\");\n  });\n\n  it(\"should convert '' to undefined on change\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {wrapWith(spy, () => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n          </form>\n        ))}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0].values).toEqual({});\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0].values).toEqual({ name: \"erikras\" });\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"\" } });\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[3][0].values).toEqual({});\n  });\n\n  it(\"should accept an identity parse prop to preserve empty strings\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {wrapWith(spy, () => (\n          <form>\n            <Field name=\"name\" parse={(v) => v}>\n              {({ input: { value, ...props } }) => (\n                <input\n                  {...props}\n                  value={value === null ? \"\" : value}\n                  data-testid=\"name\"\n                />\n              )}\n            </Field>\n          </form>\n        ))}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0].values).toEqual({});\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0].values).toEqual({ name: \"erikras\" });\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"\" } });\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[3][0].values).toEqual({ name: \"\" });\n  });\n\n  it(\"should accept a format function prop\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {wrapWith(spy, () => (\n          <form>\n            <Field\n              name=\"name\"\n              component=\"input\"\n              format={(value) => (value ? value.toUpperCase() : \"\")}\n              data-testid=\"name\"\n            />\n          </form>\n        ))}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0].values).toEqual({});\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0].values).toEqual({ name: \"erikras\" });\n    expect(getByTestId(\"name\").value).toBe(\"ERIKRAS\");\n  });\n\n  it(\"should only format on blur if formatOnBlur is true\", () => {\n    const format = jest.fn((value) => (value ? value.toUpperCase() : \"\"));\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {() => (\n          <form>\n            <Field\n              name=\"name\"\n              component=\"input\"\n              format={format}\n              formatOnBlur\n              data-testid=\"name\"\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    fireEvent.focus(getByTestId(\"name\"));\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    expect(format).not.toHaveBeenCalled();\n    fireEvent.blur(getByTestId(\"name\"));\n    expect(format).toHaveBeenCalled();\n    expect(format).toHaveBeenCalledTimes(1);\n    expect(getByTestId(\"name\").value).toBe(\"ERIKRAS\");\n  });\n\n  it(\"should `formatOnBlur` most updated value\", () => {\n    const format = jest.fn((value) => (value ? value.trim() : \"\"));\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {() => (\n          <form>\n            <Field name=\"name\" format={format} formatOnBlur initialValue=\"\">\n              {({ input }) => (\n                <input\n                  {...input}\n                  data-testid=\"name\"\n                  onBlur={(e) => {\n                    input.onChange(\n                      e.target.value && e.target.value.toUpperCase(),\n                    );\n                    input.onBlur(e);\n                  }}\n                />\n              )}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    const inputText = \"   erikras\";\n    fireEvent.focus(getByTestId(\"name\"));\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: inputText } });\n    expect(getByTestId(\"name\").value).toBe(inputText);\n    fireEvent.blur(getByTestId(\"name\"));\n    expect(format.mock.calls[0][0]).toBe(inputText.toUpperCase());\n    expect(getByTestId(\"name\").value).toBe(inputText.trim().toUpperCase());\n  });\n\n  it(\"should not format value at all when formatOnBlur and render prop\", () => {\n    const format = jest.fn((value) => (value ? value.toUpperCase() : \"\"));\n    render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {() => (\n          <form>\n            <Field name=\"name\" format={format} formatOnBlur data-testid=\"name\">\n              {({ input }) => {\n                expect(input.value).toBeUndefined();\n                expect(format).not.toHaveBeenCalled();\n                return <input {...input} value={input.value || \"\"} />;\n              }}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n  });\n\n  it(\"should accept an identity format prop to preserve undefined values\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {() => (\n          <form>\n            <Field name=\"name\" format={(v) => v}>\n              {wrapWith(spy, ({ input: { value, ...props } }) => (\n                <input\n                  {...props}\n                  value={value === undefined ? \"\" : value}\n                  data-testid=\"name\"\n                />\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0].input.value).toBeUndefined();\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0].input.value).toBe(\"erikras\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"\" } });\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[3][0].input.value).toBeUndefined();\n  });\n\n  it(\"should provide a value of [] when empty on a select multiple\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"select\" multiple data-testid=\"name\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    // This test is mostly for code coverage. Is there a way to assure that the value prop\n    // passed to the <select> is []?\n    expect(getByTestId(\"name\").value).toBe(\"\");\n  });\n\n  it(\"should pass multiple through to custom components\", () => {\n    const CustomSelect = jest.fn(({ input }) => (\n      <select\n        {...input}\n        value={input.multiple ? input.value || [] : input.value}\n      />\n    ));\n    render(\n      <Form\n        onSubmit={onSubmitMock}\n        initialValues={{ name: [] }}\n        subscription={{ values: true }}\n      >\n        {() => (\n          <form>\n            <Field name=\"name\" component={CustomSelect} multiple />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(CustomSelect).toHaveBeenCalled();\n    expect(CustomSelect).toHaveBeenCalledTimes(2);\n    expect(CustomSelect.mock.calls[0][0].input.multiple).toBe(true);\n  });\n\n  it(\"should pass ref through to the input\", () => {\n    const ref = React.createRef();\n    render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" ref={ref} />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(ref.current).not.toBe(null);\n    expect(ref.current instanceof HTMLInputElement).toBe(true);\n  });\n\n  it(\"should not pass an undefined type through to the input\", () => {\n    const MyInput = jest.fn(({ input }) => <input {...input} />);\n    render(\n      <Form onSubmit={onSubmitMock} subscription={{ values: true }}>\n        {() => (\n          <form>\n            <Field name=\"name\" component={MyInput} multiple />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(MyInput).toHaveBeenCalled();\n    expect(MyInput).toHaveBeenCalledTimes(2);\n    expect(MyInput.mock.calls[0][0].input).not.toHaveProperty(\"type\");\n  });\n\n  it(\"should optionally allow null values\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        initialValues={{ name: null }}\n        subscription={{ values: true }}\n      >\n        {() => (\n          <form>\n            <Field name=\"name\" allowNull>\n              {wrapWith(spy, ({ input: { value, ...props } }) => (\n                <input\n                  {...props}\n                  value={value === null ? \"\" : value}\n                  data-testid=\"name\"\n                />\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0].input.value).toBe(null); // Check second render pass for correct state\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0].input.value).toBe(\"erikras\");\n    act(() => {\n      spy.mock.calls[2][0].input.onChange(null);\n    });\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[3][0].input.value).toBe(null);\n  });\n\n  it(\"should not allow null values when allowNull not true\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        initialValues={{ name: null }}\n        subscription={{ values: true }}\n      >\n        {() => (\n          <form>\n            <Field name=\"name\">\n              {wrapWith(spy, ({ input: { value, ...props } }) => (\n                <input\n                  {...props}\n                  value={value === null ? \"\" : value}\n                  data-testid=\"name\"\n                />\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0].input.value).toBe(\"\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0].input.value).toBe(\"erikras\");\n    act(() => {\n      spy.mock.calls[2][0].input.onChange(null);\n    });\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[3][0].input.value).toBe(\"\");\n  });\n\n  it(\"should not let validate prop bleed through\", () => {\n    const spy = jest.fn();\n    render(\n      <Form onSubmit={onSubmitMock} subscription={{}}>\n        {() => (\n          <form>\n            <Field name=\"name\">\n              {wrapWith(spy, ({ input }) => (\n                <input {...input} data-testid=\"name\" />\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0].validate).toBeUndefined();\n  });\n\n  it(\"should not let subscription prop bleed through\", () => {\n    const spy = jest.fn();\n    render(\n      <Form onSubmit={onSubmitMock} subscription={{}}>\n        {() => (\n          <form>\n            <Field name=\"name\" subscription={{ value: true }}>\n              {wrapWith(spy, ({ input }) => (\n                <input {...input} data-testid=\"name\" />\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0].subscription).toBeUndefined();\n  });\n\n  it(\"should allow changing field-level validation function\", () => {\n    const simpleValidate = (value) => (value ? undefined : \"Required\");\n    const complexValidate = (value) => {\n      if (value) {\n        if (value !== value.toUpperCase()) {\n          return \"SHOULD BE UPPERCASE!\";\n        }\n      } else {\n        return \"Required\";\n      }\n    };\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(useComplexValidation) => (\n          <Form onSubmit={onSubmitMock}>\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field\n                  name=\"name\"\n                  validate={\n                    useComplexValidation ? complexValidate : simpleValidate\n                  }\n                  key={useComplexValidation ? 1 : 0}\n                >\n                  {({ input, meta }) => (\n                    <div>\n                      <input {...input} data-testid=\"name\" />\n                      <div data-testid=\"error\">{meta.error}</div>\n                    </div>\n                  )}\n                </Field>\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"error\")).toHaveTextContent(\"Required\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(getByTestId(\"error\")).toHaveTextContent(\"\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"error\")).toHaveTextContent(\"SHOULD BE UPPERCASE!\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"ERIKRAS\" } });\n    expect(getByTestId(\"error\")).toHaveTextContent(\"\");\n  });\n\n  /**\n   * Allow me to explain this. If we allow field level validation functions\n   * to be swapped, it means that we'd have to run _ALL_ the validation\n   * every time a new field was removed regardless of whether or\n   * not it was using field-level validation. To avoid this overhead, we must\n   * accept some inconsistency when swapping of field-level validation functions.\n   * In this test, swapping from no validation to \"required\" validation\n   * does work because the field-level validation function is called on mount,\n   * but the error does not clear when we switch back to no validation function\n   * because in order for Final Form to determine if the 'Required' error came\n   * from the newly unmounted Field, it would need to run validation on the entire\n   * form.\n   */\n  it(\"should ignore changes field-level validation function\", () => {\n    const createValidator = (isRequired) =>\n      isRequired ? (value) => (value ? undefined : \"Required\") : undefined;\n\n    const Error = ({ name }) => (\n      <Field name={name} subscription={{ error: true }}>\n        {({ meta: { error } }) => <div data-testid=\"error2\">{error}</div>}\n      </Field>\n    );\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(isRequired) => (\n          <Form onSubmit={onSubmitMock}>\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field\n                  name=\"name\"\n                  validate={createValidator(isRequired)}\n                  key={isRequired ? 1 : 0}\n                >\n                  {({ input, meta }) => (\n                    <div>\n                      <input {...input} data-testid=\"name\" />\n                      <div data-testid=\"error\">{meta.error}</div>\n                    </div>\n                  )}\n                </Field>\n                <Error name=\"name\" />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"error\")).toBeEmptyDOMElement();\n    expect(getByTestId(\"error2\")).toBeEmptyDOMElement();\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"error\")).toHaveTextContent(\"Required\");\n    expect(getByTestId(\"error2\")).toHaveTextContent(\"Required\");\n    fireEvent.click(getByText(\"Toggle\"));\n    // ERROR IS NOT CLEARED (see comment above)\n    expect(getByTestId(\"error\")).toHaveTextContent(\"Required\");\n    expect(getByTestId(\"error2\")).toHaveTextContent(\"Required\");\n  });\n\n  it(\"should not rerender if validateFields is !== every time\", () => {\n    // https://github.com/final-form/react-final-form/issues/502\n    const required = (value) => (value ? undefined : \"Required\");\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"name\" validate={required} validateFields={[]}>\n              {wrapWith(spy, ({ input, meta }) => (\n                <div>\n                  <input {...input} data-testid=\"name\" />\n                  <div data-testid=\"error\">{meta.error}</div>\n                </div>\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    // first render registered validation, second contains error\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(getByTestId(\"error\")).toHaveTextContent(\"Required\");\n  });\n\n  it(\"should pass along type prop\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"checkbox\"\n              component=\"input\"\n              type=\"checkbox\"\n              data-testid=\"checkbox\"\n            />\n            <Field\n              name=\"password\"\n              component=\"input\"\n              type=\"password\"\n              data-testid=\"password\"\n            />\n            <Field\n              name=\"radio\"\n              component=\"input\"\n              type=\"radio\"\n              data-testid=\"radio\"\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"checkbox\").type).toBe(\"checkbox\");\n    expect(getByTestId(\"password\").type).toBe(\"password\");\n    expect(getByTestId(\"radio\").type).toBe(\"radio\");\n  });\n\n  it(\"should render checkboxes with checked prop\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"employed\"\n              component=\"input\"\n              type=\"checkbox\"\n              data-testid=\"employed\"\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"employed\").type).toBe(\"checkbox\");\n    expect(getByTestId(\"employed\").checked).toBe(false);\n    fireEvent.change(getByTestId(\"employed\"), { target: { checked: true } });\n    expect(getByTestId(\"employed\").checked).toBe(true);\n  });\n\n  it('should render \"array\" checkboxes with checked prop when value is included in array', () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ colors: [\"red\", \"blue\"] }}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"colors\"\n              component=\"input\"\n              type=\"checkbox\"\n              value=\"red\"\n              data-testid=\"red\"\n            />\n            <Field\n              name=\"colors\"\n              component=\"input\"\n              type=\"checkbox\"\n              value=\"green\"\n              data-testid=\"green\"\n            />\n            <Field\n              name=\"colors\"\n              component=\"input\"\n              type=\"checkbox\"\n              value=\"blue\"\n              data-testid=\"blue\"\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"red\").checked).toBe(true);\n    expect(getByTestId(\"green\").checked).toBe(false);\n    expect(getByTestId(\"blue\").checked).toBe(true);\n  });\n\n  it('should render \"array\" custom checkboxes with checked prop when value is included in array', () => {\n    const red = jest.fn();\n    const green = jest.fn();\n    const blue = jest.fn();\n    render(\n      <Form onSubmit={onSubmitMock} initialValues={{ colors: [\"red\", \"blue\"] }}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"colors\" type=\"checkbox\" value=\"red\">\n              {wrapWith(red, ({ input }) => (\n                <input {...input} />\n              ))}\n            </Field>\n            <Field name=\"colors\" type=\"checkbox\" value=\"green\">\n              {wrapWith(green, ({ input }) => (\n                <input {...input} />\n              ))}\n            </Field>\n            <Field name=\"colors\" type=\"checkbox\" value=\"blue\">\n              {wrapWith(blue, ({ input }) => (\n                <input {...input} />\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(red).toHaveBeenCalled();\n    expect(red).toHaveBeenCalledTimes(2);\n    // After fix #1050, initialValues work on first render\n    expect(red.mock.calls[0][0].input.checked).toBe(true); // Correctly true for \"red\" from initialValues\n    expect(red.mock.calls[1][0].input.checked).toBe(true);\n    expect(green).toHaveBeenCalled();\n    expect(green).toHaveBeenCalledTimes(2);\n    expect(green.mock.calls[0][0].input.checked).toBe(false);\n    expect(green.mock.calls[1][0].input.checked).toBe(false); // Correctly false for \"green\"\n    expect(blue).toHaveBeenCalled();\n    expect(blue).toHaveBeenCalledTimes(2);\n    // After fix #1050, initialValues work on first render\n    expect(blue.mock.calls[0][0].input.checked).toBe(true); // Correctly true for \"blue\" from initialValues\n    expect(blue.mock.calls[1][0].input.checked).toBe(true);\n  });\n\n  it(\"should render radio buttons with checked prop\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ color: \"green\" }}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"color\"\n              component=\"input\"\n              type=\"radio\"\n              value=\"red\"\n              data-testid=\"red\"\n            />\n            <Field\n              name=\"color\"\n              component=\"input\"\n              type=\"radio\"\n              value=\"green\"\n              data-testid=\"green\"\n            />\n            <Field\n              name=\"color\"\n              component=\"input\"\n              type=\"radio\"\n              value=\"blue\"\n              data-testid=\"blue\"\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"red\").type).toBe(\"radio\");\n    expect(getByTestId(\"red\").checked).toBe(false);\n    expect(getByTestId(\"green\").type).toBe(\"radio\");\n    expect(getByTestId(\"green\").checked).toBe(true);\n    expect(getByTestId(\"blue\").type).toBe(\"radio\");\n    expect(getByTestId(\"blue\").checked).toBe(false);\n  });\n\n  it(\"should render custom radio component with checked prop\", () => {\n    const red = jest.fn();\n    const green = jest.fn();\n    const blue = jest.fn();\n    render(\n      <Form onSubmit={onSubmitMock} initialValues={{ color: \"green\" }}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"color\" type=\"radio\" value=\"red\">\n              {wrapWith(red, ({ input }) => (\n                <input {...input} />\n              ))}\n            </Field>\n            <Field name=\"color\" type=\"radio\" value=\"green\">\n              {wrapWith(green, ({ input }) => (\n                <input {...input} />\n              ))}\n            </Field>\n            <Field name=\"color\" type=\"radio\" value=\"blue\">\n              {wrapWith(blue, ({ input }) => (\n                <input {...input} />\n              ))}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(red).toHaveBeenCalled();\n    expect(red).toHaveBeenCalledTimes(2);\n    expect(red.mock.calls[0][0].input.checked).toBe(false);\n    expect(red.mock.calls[1][0].input.checked).toBe(false); // Correctly false for \"red\" radio\n    expect(green).toHaveBeenCalled();\n    expect(green).toHaveBeenCalledTimes(2);\n    // After fix #1050, initialValues work on first render\n    expect(green.mock.calls[0][0].input.checked).toBe(true); // Correctly true for \"green\" from initialValues\n    expect(green.mock.calls[1][0].input.checked).toBe(true);\n    expect(blue).toHaveBeenCalled();\n    expect(blue).toHaveBeenCalledTimes(2);\n    expect(blue.mock.calls[0][0].input.checked).toBe(false);\n    expect(blue.mock.calls[1][0].input.checked).toBe(false); // Correctly false for \"blue\" radio\n  });\n\n  it(\"should use isEqual to calculate dirty/pristine\", () => {\n    const isEqual = (a, b) => (a && a.toUpperCase()) === (b && b.toUpperCase());\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ name: \"bob\" }}>\n        {() => (\n          <form>\n            <Field name=\"name\" isEqual={isEqual}>\n              {({ input, meta }) => (\n                <div>\n                  <div data-testid=\"dirty\">\n                    {meta.dirty ? \"Dirty\" : \"Pristine\"}\n                  </div>\n                  <input {...input} data-testid=\"input\" />\n                </div>\n              )}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"input\").value).toBe(\"bob\");\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Pristine\");\n    fireEvent.change(getByTestId(\"input\"), { target: { value: \"bobby\" } });\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Dirty\");\n    fireEvent.change(getByTestId(\"input\"), { target: { value: \"BOB\" } });\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Pristine\");\n  });\n\n  it(\"should be able to use inline isEqual to calculate dirty/pristine without falling into infinite rerender loop\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ name: \"bob\" }}>\n        {() => (\n          <form>\n            <Field\n              name=\"name\"\n              isEqual={(a, b) =>\n                (a && a.toUpperCase()) === (b && b.toUpperCase())\n              }\n            >\n              {({ input, meta }) => (\n                <div>\n                  <div data-testid=\"dirty\">\n                    {meta.dirty ? \"Dirty\" : \"Pristine\"}\n                  </div>\n                  <input {...input} data-testid=\"input\" />\n                </div>\n              )}\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"input\").value).toBe(\"bob\");\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Pristine\");\n    fireEvent.change(getByTestId(\"input\"), { target: { value: \"bobby\" } });\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Dirty\");\n    fireEvent.change(getByTestId(\"input\"), { target: { value: \"BOB\" } });\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Pristine\");\n  });\n\n  it(\"should only call each field-level validation once upon initial mount\", () => {\n    const fooValidate = jest.fn();\n    const barValidate = jest.fn();\n    const bazValidate = jest.fn();\n    render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"foo\" component=\"input\" validate={fooValidate} />\n            <Field name=\"bar\" component=\"input\" validate={barValidate} />\n            <Field name=\"baz\" component=\"input\" validate={bazValidate} />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(fooValidate).toHaveBeenCalledTimes(1);\n    expect(barValidate).toHaveBeenCalledTimes(1);\n    expect(bazValidate).toHaveBeenCalledTimes(1);\n  });\n\n  it(\"should warn when used without type prop and rendering radio, checkbox or multiple select indirectly\", () => {\n    const errorSpy = jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ selectMultipleInput: [] }}>\n        {() => (\n          <form>\n            <Field name=\"checkboxInput\" value=\"checkboxValue\">\n              {({ input }) => (\n                <input type=\"checkbox\" {...input} data-testid=\"checkbox\" />\n              )}\n            </Field>\n            <Field name=\"radioInput\" value=\"radioValue\">\n              {({ input }) => (\n                <input type=\"radio\" {...input} data-testid=\"radio\" />\n              )}\n            </Field>\n            <Field name=\"selectMultipleInput\">\n              {({ input }) => (\n                <select multiple {...input} data-testid=\"select\">\n                  <option>{\"Option\"}</option>\n                </select>\n              )}\n            </Field>\n            <Field\n              name=\"selectMultipleWithoutRenderProp\"\n              component=\"select\"\n              data-testid=\"selectMultipleWithoutRenderProp\"\n              multiple\n            >\n              <option>{\"Option\"}</option>\n            </Field>\n          </form>\n        )}\n      </Form>,\n    );\n\n    // After fix #1050, initialValues work on first render, so select multiple\n    // correctly gets the array value from initialValues and no longer triggers\n    // React's \"must be an array\" warning\n    expect(errorSpy).toHaveBeenCalledTimes(0);\n\n    // Reset the spy to test the actual Field warnings\n    errorSpy.mockClear();\n    fireEvent.click(getByTestId(\"checkbox\"), {\n      target: { type: \"checkbox\", checked: true },\n    });\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0]).toBe(\n      'You must pass `type=\"checkbox\"` prop to your Field(checkboxInput) component.\\n' +\n        'Without it we don\\'t know how to unpack your `value` prop - \"checkboxValue\".',\n    );\n    fireEvent.click(getByTestId(\"radio\"), {\n      target: { type: \"radio\", value: \"radio value\" },\n    });\n    expect(errorSpy).toHaveBeenCalledTimes(2);\n    expect(errorSpy.mock.calls[1][0]).toBe(\n      'You must pass `type=\"radio\"` prop to your Field(radioInput) component.\\n' +\n        'Without it we don\\'t know how to unpack your `value` prop - \"radioValue\".',\n    );\n    fireEvent.change(getByTestId(\"select\"), {\n      target: { value: [\"some value\"] },\n    });\n    expect(errorSpy).toHaveBeenCalledTimes(3);\n    expect(errorSpy.mock.calls[2][0]).toBe(\n      'You must pass `type=\"select\"` prop to your Field(selectMultipleInput) component.\\n' +\n        \"Without it we don't know how to unpack your `value` prop - [].\",\n    );\n    fireEvent.change(getByTestId(\"selectMultipleWithoutRenderProp\"), {\n      target: { value: [\"some value\"] },\n    });\n    // error not given, since we can deduce that it's a \"select\"\n    expect(errorSpy).toHaveBeenCalledTimes(3);\n    errorSpy.mockRestore();\n  });\n\n  it(\"should formatOnBlur on submit\", () => {\n    const onSubmit = jest.fn();\n    const { getByTestId, getByText } = render(\n      <Form onSubmit={onSubmit}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"name\"\n              component=\"input\"\n              format={(value) => value && value.toUpperCase()}\n              formatOnBlur\n              data-testid=\"name\"\n            />\n            <button type=\"submit\">Submit</button>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    fireEvent.focus(getByTestId(\"name\"));\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erik\" } });\n    expect(getByTestId(\"name\").value).toBe(\"erik\");\n    fireEvent.blur(getByTestId(\"name\"));\n    expect(getByTestId(\"name\").value).toBe(\"ERIK\");\n\n    fireEvent.focus(getByTestId(\"name\"));\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"ERIKras\" } });\n    expect(getByTestId(\"name\").value).toBe(\"ERIKras\");\n\n    expect(onSubmit).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Submit\"));\n    expect(onSubmit).toHaveBeenCalled();\n    expect(onSubmit).toHaveBeenCalledTimes(1);\n    expect(onSubmit.mock.calls[0][0]).toEqual({ name: \"ERIKRAS\" });\n\n    // submit again with no need for format\n    fireEvent.click(getByText(\"Submit\"));\n    expect(onSubmit).toHaveBeenCalledTimes(2);\n    expect(onSubmit.mock.calls[1][0]).toEqual({ name: \"ERIKRAS\" });\n  });\n\n  it(\"should allow submission to be cancelled in beforeSubmit\", () => {\n    const onSubmit = jest.fn();\n    const beforeSubmit = jest.fn(() => false);\n    const { getByTestId, getByText } = render(\n      <Form onSubmit={onSubmit}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"name\"\n              component=\"input\"\n              beforeSubmit={beforeSubmit}\n              data-testid=\"name\"\n            />\n            <button type=\"submit\">Submit</button>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    fireEvent.focus(getByTestId(\"name\"));\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erik\" } });\n\n    expect(onSubmit).not.toHaveBeenCalled();\n    expect(beforeSubmit).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Submit\"));\n    expect(onSubmit).not.toHaveBeenCalled();\n    expect(beforeSubmit).toHaveBeenCalled();\n  });\n\n  it(\"update validating flag on async field-level validation\", async () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"name\"\n              component=\"input\"\n              validate={async (value) => {\n                await timeout(5);\n                return value === \"erikras\" ? \"Username taken\" : undefined;\n              }}\n              data-testid=\"name\"\n            />\n            <Field name=\"name\" subscription={{ validating: true }}>\n              {({ meta: { validating } }) => (\n                <div data-testid=\"validating\">\n                  {validating === true ? \"Spinner\" : \"Not Validating\"}\n                </div>\n              )}\n            </Field>\n            <button type=\"submit\">Submit</button>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"validating\")).toHaveTextContent(\"Spinner\");\n\n    await sleep(6);\n\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    fireEvent.focus(getByTestId(\"name\"));\n    expect(getByTestId(\"validating\")).toHaveTextContent(\"Not Validating\");\n\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erik\" } });\n    expect(getByTestId(\"validating\")).toHaveTextContent(\"Spinner\");\n\n    await sleep(6);\n\n    expect(getByTestId(\"validating\")).toHaveTextContent(\"Not Validating\");\n\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(getByTestId(\"validating\")).toHaveTextContent(\"Spinner\");\n\n    await sleep(6);\n\n    expect(getByTestId(\"validating\")).toHaveTextContent(\"Not Validating\");\n  });\n\n  it(\"not call record-level validation on Field mount\", () => {\n    const validate = jest.fn();\n    const { getByText } = render(\n      <Toggle>\n        {(showOtherFields) => (\n          <Form onSubmit={onSubmitMock} validate={validate}>\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"firstName\" component=\"input\" />\n                <Field name=\"lastName\" component=\"input\" />\n                <Field name=\"email\" component=\"input\" />\n                <Field name=\"street\" component=\"input\" />\n                <Field name=\"city\" component=\"input\" />\n                {showOtherFields && (\n                  <React.Fragment>\n                    <Field name=\"friend.firstName\" component=\"input\" />\n                    <Field name=\"friend.lastName\" component=\"input\" />\n                    <Field name=\"friend.email\" component=\"input\" />\n                    <Field name=\"friend.street\" component=\"input\" />\n                    <Field name=\"friend.city\" component=\"input\" />\n                  </React.Fragment>\n                )}\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(validate).toHaveBeenCalledTimes(1);\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(validate).toHaveBeenCalledTimes(1);\n  });\n\n  it(\"submit should not throw when field with enabled `formatOnBlur` changes name `prop`\", () => {\n    const onSubmit = jest.fn();\n\n    const trim = (value) => value && value.trim();\n\n    const { getByTestId, getByText } = render(\n      <Form onSubmit={onSubmit}>\n        {({ handleSubmit }) => (\n          <Toggle>\n            {(newFieldName) => (\n              <form onSubmit={handleSubmit}>\n                <Field\n                  name={newFieldName ? \"newName\" : \"oldName\"}\n                  component=\"input\"\n                  formatOnBlur={true}\n                  format={trim}\n                  data-testid=\"field\"\n                />\n                <button type=\"submit\">Submit</button>\n              </form>\n            )}\n          </Toggle>\n        )}\n      </Form>,\n    );\n\n    fireEvent.click(getByText(\"Toggle\"));\n    fireEvent.change(getByTestId(\"field\"), {\n      target: { value: \"trailing space \" },\n    });\n    fireEvent.click(getByText(\"Submit\"));\n    expect(onSubmit).toHaveBeenCalled();\n    expect(onSubmit.mock.calls[0][0]).toEqual({ newName: \"trailing space\" });\n  });\n\n  it(\"should throw an error if name prop is undefined\", () => {\n    const consoleError = console.error;\n    console.error = jest.fn(); // Suppress React error boundary warning\n    expect(() => {\n      render(\n        <Form onSubmit={onSubmitMock}>\n          {() => <Field name={undefined} render={() => <input />} />}\n        </Form>,\n      );\n    }).toThrow(\"prop name cannot be undefined in <Field> component\");\n    console.error = consoleError;\n  });\n\n  it(\"should support using format/parse with radio controls\", () => {\n    const format = (value) => value && value.toString();\n    const parse = (value) => value && parseInt(value, 10);\n\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ number: 20 }}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"number\"\n              component=\"input\"\n              type=\"radio\"\n              value={10}\n              data-testid=\"ten\"\n              parse={parse}\n              format={format}\n            />\n            <Field\n              name=\"number\"\n              component=\"input\"\n              type=\"radio\"\n              value={20}\n              data-testid=\"twenty\"\n              parse={parse}\n              format={format}\n            />\n            <Field\n              name=\"number\"\n              component=\"input\"\n              type=\"radio\"\n              value={30}\n              data-testid=\"thirty\"\n              parse={parse}\n              format={format}\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"ten\").checked).toBe(false);\n    expect(getByTestId(\"twenty\").checked).toBe(true);\n    expect(getByTestId(\"thirty\").checked).toBe(false);\n  });\n\n  it(\"should support using format/parse with checkbox controls\", () => {\n    const format = (value) => value && value.map((x) => x.toString());\n    const parse = (value) => value && value.map((x) => parseInt(x, 10));\n\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ number: [20, 30] }}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"number\"\n              component=\"input\"\n              type=\"checkbox\"\n              value={10}\n              data-testid=\"ten\"\n              parse={parse}\n              format={format}\n            />\n            <Field\n              name=\"number\"\n              component=\"input\"\n              type=\"checkbox\"\n              value={20}\n              data-testid=\"twenty\"\n              parse={parse}\n              format={format}\n            />\n            <Field\n              name=\"number\"\n              component=\"input\"\n              type=\"checkbox\"\n              value={30}\n              data-testid=\"thirty\"\n              parse={parse}\n              format={format}\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"ten\").checked).toBe(false);\n    expect(getByTestId(\"twenty\").checked).toBe(true);\n    expect(getByTestId(\"thirty\").checked).toBe(true);\n  });\n});\n\ndescribe(\"Field.nodeName issue #871\", () => {\n  it(\"should not crash when field name is 'nodeName'\", () => {\n    const onSubmit = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmit}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field\n              name=\"nodeName\"\n              component=\"input\"\n              data-testid=\"nodeName-input\"\n            />\n            <button type=\"submit\" data-testid=\"submit\">\n              Submit\n            </button>\n          </form>\n        )}\n      </Form>,\n    );\n\n    const input = getByTestId(\"nodeName-input\");\n    const submit = getByTestId(\"submit\");\n\n    // Should not crash when interacting with the field\n    expect(() => {\n      fireEvent.change(input, { target: { value: \"test\" } });\n      fireEvent.blur(input);\n      fireEvent.click(submit);\n    }).not.toThrow();\n\n    // Verify the field value was set correctly\n    expect(onSubmit).toHaveBeenCalledWith(\n      { nodeName: \"test\" },\n      expect.any(Object),\n      expect.any(Function),\n    );\n  });\n});\n"
  },
  {
    "path": "src/Field.tsx",
    "content": "import * as React from \"react\";\nimport type { FieldProps, FieldRenderProps } from \"./types\";\nimport renderComponent from \"./renderComponent\";\nimport useField from \"./useField\";\n\nfunction FieldComponent<\n  FieldValue = any,\n  T extends HTMLElement = HTMLElement,\n  FormValues = Record<string, any>,\n>(\n  {\n    afterSubmit,\n    allowNull,\n    beforeSubmit,\n    children,\n    component,\n    data,\n    defaultValue,\n    format,\n    formatOnBlur,\n    initialValue,\n    input,\n    isEqual,\n    multiple,\n    name,\n    parse,\n    subscription,\n    type,\n    validate,\n    validateFields,\n    value,\n    ...rest\n  }: FieldProps<FieldValue, T, FormValues>,\n  ref: React.Ref<T>,\n) {\n  const field: FieldRenderProps<FieldValue, T> = useField(name, {\n    afterSubmit,\n    allowNull,\n    beforeSubmit,\n    component,\n    data,\n    defaultValue,\n    format,\n    formatOnBlur,\n    initialValue,\n    isEqual,\n    multiple,\n    parse,\n    subscription,\n    type,\n    validate,\n    validateFields,\n    value,\n  });\n\n  // Merge provided input prop with field.input\n  const mergedField = input\n    ? { ...field, input: { ...field.input, ...input } }\n    : field;\n\n  if (typeof children === \"function\") {\n    return (\n      children as (\n        props: FieldRenderProps<FieldValue, T> & typeof rest,\n      ) => React.ReactNode\n    )({ ...mergedField, ...rest });\n  }\n\n  if (typeof component === \"string\") {\n    // ignore meta, combine input with any other props\n    const { name: inputName, ...restInputProps } = mergedField.input;\n\n    // Ensure multiple select has array value\n    if (\n      component === \"select\" &&\n      multiple &&\n      !Array.isArray(restInputProps.value)\n    ) {\n      restInputProps.value = [] as any;\n    }\n\n    return React.createElement(component, {\n      name: inputName, // Pass name explicitly to avoid shadowing DOM properties\n      ...restInputProps,\n      children,\n      ref,\n      ...rest,\n    });\n  }\n\n  if (!name) {\n    throw new Error(\"prop name cannot be undefined in <Field> component\");\n  }\n\n  return renderComponent(\n    { children, component, ...rest, ...mergedField },\n    {},\n    `Field(${name})`,\n  );\n}\n\n// Create a properly typed forwardRef component that preserves generics\nconst Field = React.forwardRef(FieldComponent as any) as <\n  FieldValue = any,\n  T extends HTMLElement = HTMLElement,\n  FormValues = Record<string, any>,\n>(\n  props: FieldProps<FieldValue, T, FormValues> & { ref?: React.Ref<T> },\n) => React.ReactElement | null;\n\nexport default Field;\n"
  },
  {
    "path": "src/FormSpy.test.js",
    "content": "import React from \"react\";\nimport { render, fireEvent, cleanup } from \"@testing-library/react\";\nimport \"@testing-library/jest-dom\";\nimport { ErrorBoundary, Toggle, wrapWith } from \"./testUtils\";\nimport Form from \"./ReactFinalForm\";\nimport Field from \"./Field\";\nimport FormSpy from \"./FormSpy\";\n\nconst onSubmitMock = (_values) => {};\nconst hasFormApi = (props) => {\n  expect(props.form).toBeDefined();\n  expect(typeof props.form.batch).toBe(\"function\");\n  expect(typeof props.form.blur).toBe(\"function\");\n  expect(typeof props.form.change).toBe(\"function\");\n  expect(typeof props.form.focus).toBe(\"function\");\n  expect(typeof props.form.initialize).toBe(\"function\");\n  expect(typeof props.form.reset).toBe(\"function\");\n};\n\ndescribe(\"FormSpy\", () => {\n  afterEach(cleanup);\n\n  it(\"should warn if not used inside a form\", () => {\n    jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const errorSpy = jest.fn();\n    render(\n      <ErrorBoundary spy={errorSpy}>\n        <FormSpy render={() => <div />} />\n      </ErrorBoundary>,\n    );\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0].message).toBe(\n      \"FormSpy must be used inside of a <Form> component\",\n    );\n    console.error.mockRestore();\n  });\n\n  it(\"should allow subscribing to everything\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <FormSpy\n              render={wrapWith(spy, () => (\n                <div />\n              ))}\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    // All forms without restricted subscriptions render twice at first because they\n    // need to update their validation and touched/modified/visited maps every time\n    // new fields are registered.\n    expect(spy).toHaveBeenCalledTimes(2);\n    hasFormApi(spy.mock.calls[0][0]);\n    expect(spy.mock.calls[0][0].dirty).toBe(false);\n    expect(spy.mock.calls[0][0].errors).toEqual({});\n    expect(spy.mock.calls[0][0].invalid).toBe(false);\n    expect(spy.mock.calls[0][0].pristine).toBe(true);\n    expect(spy.mock.calls[0][0].submitFailed).toBe(false);\n    expect(spy.mock.calls[0][0].submitSucceeded).toBe(false);\n    expect(spy.mock.calls[0][0].submitting).toBe(false);\n    expect(spy.mock.calls[0][0].valid).toBe(true);\n    expect(spy.mock.calls[0][0].validating).toBe(false);\n    expect(spy.mock.calls[0][0].values).toEqual({});\n    hasFormApi(spy.mock.calls[1][0]);\n    expect(spy.mock.calls[1][0].dirty).toBe(false);\n    expect(spy.mock.calls[1][0].errors).toEqual({});\n    expect(spy.mock.calls[1][0].invalid).toBe(false);\n    expect(spy.mock.calls[1][0].pristine).toBe(true);\n    expect(spy.mock.calls[1][0].submitFailed).toBe(false);\n    expect(spy.mock.calls[1][0].submitSucceeded).toBe(false);\n    expect(spy.mock.calls[1][0].submitting).toBe(false);\n    expect(spy.mock.calls[1][0].valid).toBe(true);\n    expect(spy.mock.calls[1][0].validating).toBe(false);\n    expect(spy.mock.calls[1][0].values).toEqual({});\n\n    // change value\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n\n    expect(spy).toHaveBeenCalledTimes(3);\n    hasFormApi(spy.mock.calls[2][0]);\n    expect(spy.mock.calls[2][0].dirty).toBe(true);\n    expect(spy.mock.calls[2][0].errors).toEqual({});\n    expect(spy.mock.calls[2][0].invalid).toBe(false);\n    expect(spy.mock.calls[2][0].pristine).toBe(false);\n    expect(spy.mock.calls[2][0].submitFailed).toBe(false);\n    expect(spy.mock.calls[2][0].submitSucceeded).toBe(false);\n    expect(spy.mock.calls[2][0].submitting).toBe(false);\n    expect(spy.mock.calls[2][0].valid).toBe(true);\n    expect(spy.mock.calls[2][0].validating).toBe(false);\n    expect(spy.mock.calls[2][0].values).toEqual({ name: \"erikras\" });\n  });\n\n  it(\"should NOT resubscribe if subscription changes\", () => {\n    const firstSubscription = { values: true, pristine: true };\n    const secondSubscription = { dirty: true, submitting: true };\n    const spy = jest.fn();\n    const { getByText } = render(\n      <Toggle>\n        {(useAlternateSubscription) => (\n          <Form\n            onSubmit={onSubmitMock}\n            initialValues={{ dog: \"Odie\", cat: \"Garfield\" }}\n          >\n            {() => (\n              <form>\n                <Field name=\"dog\" component=\"input\" />\n                <Field name=\"cat\" component=\"input\" />\n                <FormSpy\n                  subscription={\n                    useAlternateSubscription\n                      ? secondSubscription\n                      : firstSubscription\n                  }\n                >\n                  {wrapWith(spy, (props) => (\n                    <div />\n                  ))}\n                </FormSpy>\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(spy).toHaveBeenCalled();\n    // All forms without restricted subscriptions render twice at first because they\n    // need to update their validation and touched/modified/visited maps every time\n    // new fields are registered.\n    expect(spy).toHaveBeenCalledTimes(2);\n    hasFormApi(spy.mock.calls[0][0]);\n    expect(spy.mock.calls[0][0].dirty).toBe(false);\n    expect(spy.mock.calls[0][0].errors).toEqual({});\n    expect(spy.mock.calls[0][0].invalid).toBe(false);\n    expect(spy.mock.calls[0][0].pristine).toBe(true);\n    expect(spy.mock.calls[0][0].submitFailed).toBe(false);\n    expect(spy.mock.calls[0][0].submitSucceeded).toBe(false);\n    expect(spy.mock.calls[0][0].submitting).toBe(false);\n    expect(spy.mock.calls[0][0].valid).toBe(true);\n    expect(spy.mock.calls[0][0].validating).toBe(false);\n    expect(spy.mock.calls[0][0].values).toEqual({\n      dog: \"Odie\",\n      cat: \"Garfield\",\n    });\n    // Reinstate check for spy.mock.calls[1][0] as there are two initial calls\n    hasFormApi(spy.mock.calls[1][0]);\n    expect(spy.mock.calls[1][0].dirty).toBeUndefined();\n    expect(spy.mock.calls[1][0].errors).toBeUndefined();\n    expect(spy.mock.calls[1][0].invalid).toBeUndefined();\n    expect(spy.mock.calls[1][0].pristine).toBe(true);\n    expect(spy.mock.calls[1][0].submitFailed).toBeUndefined();\n    expect(spy.mock.calls[1][0].submitSucceeded).toBeUndefined();\n    expect(spy.mock.calls[1][0].submitting).toBeUndefined();\n    expect(spy.mock.calls[1][0].valid).toBeUndefined();\n    expect(spy.mock.calls[1][0].validating).toBeUndefined();\n    expect(spy.mock.calls[1][0].values).toEqual({\n      dog: \"Odie\",\n      cat: \"Garfield\",\n    });\n\n    fireEvent.click(getByText(\"Toggle\"));\n\n    // If FormSpy correctly does not re-render for subscription prop change alone,\n    // count should remain 3.\n    expect(spy).toHaveBeenCalledTimes(3);\n  });\n\n  it(\"should hear changes\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <FormSpy subscription={{ dirty: true, values: true }}>\n              {wrapWith(spy, (props) => (\n                <div />\n              ))}\n            </FormSpy>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    // All forms without restricted subscriptions render twice at first because they\n    // need to update their validation and touched/modified/visited maps every time\n    // new fields are registered.\n    expect(spy).toHaveBeenCalledTimes(2);\n    hasFormApi(spy.mock.calls[0][0]);\n    expect(spy.mock.calls[0][0].dirty).toBe(false);\n    expect(spy.mock.calls[0][0].errors).toEqual({});\n    expect(spy.mock.calls[0][0].invalid).toBe(false);\n    expect(spy.mock.calls[0][0].pristine).toBe(true);\n    expect(spy.mock.calls[0][0].submitFailed).toBe(false);\n    expect(spy.mock.calls[0][0].submitSucceeded).toBe(false);\n    expect(spy.mock.calls[0][0].submitting).toBe(false);\n    expect(spy.mock.calls[0][0].valid).toBe(true);\n    expect(spy.mock.calls[0][0].values).toEqual({}); // Default/empty for first call\n\n    // Check second initial call\n    hasFormApi(spy.mock.calls[1][0]);\n    expect(spy.mock.calls[1][0].dirty).toBe(false);\n    expect(spy.mock.calls[1][0].errors).toBeUndefined();\n    expect(spy.mock.calls[1][0].invalid).toBeUndefined();\n    expect(spy.mock.calls[1][0].pristine).toBeUndefined();\n    expect(spy.mock.calls[1][0].values).toEqual({});\n\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"bob\" } });\n\n    expect(spy).toHaveBeenCalledTimes(3); // Called again for the change\n    hasFormApi(spy.mock.calls[2][0]);\n    expect(spy.mock.calls[2][0].dirty).toBe(true);\n    expect(spy.mock.calls[2][0].errors).toBeUndefined();\n    expect(spy.mock.calls[2][0].invalid).toBeUndefined();\n    expect(spy.mock.calls[2][0].pristine).toBeUndefined();\n    expect(spy.mock.calls[2][0].submitFailed).toBeUndefined();\n    expect(spy.mock.calls[2][0].submitSucceeded).toBeUndefined();\n    expect(spy.mock.calls[2][0].submitting).toBeUndefined();\n    expect(spy.mock.calls[2][0].valid).toBeUndefined();\n    expect(spy.mock.calls[2][0].values).toEqual({ name: \"bob\" });\n  });\n\n  it(\"should unsubscribe on unmount\", () => {\n    // This is mainly here for code coverage. 🧐\n    const spy = jest.fn();\n    const { getByText } = render(\n      <Toggle>\n        {(hidden) => (\n          <Form onSubmit={onSubmitMock}>\n            {() => (\n              <form>\n                <Field name=\"name\" component=\"input\" />\n                {!hidden && (\n                  <FormSpy>\n                    {wrapWith(spy, (props) => (\n                      <div />\n                    ))}\n                  </FormSpy>\n                )}\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(spy).toHaveBeenCalled();\n    // All forms without restricted subscriptions render twice at first because they\n    // need to update their validation and touched/modified/visited maps every time\n    // new fields are registered.\n    expect(spy).toHaveBeenCalledTimes(2);\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(spy).toHaveBeenCalledTimes(2);\n  });\n\n  it(\"should call onChange\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <FormSpy\n              subscription={{ dirty: true, values: true }}\n              onChange={spy}\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(1);\n    expect(spy.mock.calls[0][0].dirty).toBe(false);\n    expect(spy.mock.calls[0][0].errors).toBeUndefined();\n    expect(spy.mock.calls[0][0].invalid).toBeUndefined();\n    expect(spy.mock.calls[0][0].pristine).toBeUndefined();\n    expect(spy.mock.calls[0][0].submitFailed).toBeUndefined();\n    expect(spy.mock.calls[0][0].submitSucceeded).toBeUndefined();\n    expect(spy.mock.calls[0][0].submitting).toBeUndefined();\n    expect(spy.mock.calls[0][0].valid).toBeUndefined();\n    expect(spy.mock.calls[0][0].validating).toBeUndefined();\n    expect(spy.mock.calls[0][0].values).toEqual({});\n\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0].dirty).toBe(true);\n    expect(spy.mock.calls[1][0].values).toEqual({ name: \"erikras\" });\n  });\n\n  it(\"should not rerender when onChange changes, but SHOULD use latest onChange passed\", () => {\n    const spy = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {({ values }) => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <FormSpy\n              subscription={{ values: true }}\n              onChange={(formState) => {\n                spy(values.name, formState.values.name);\n              }}\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(1);\n    expect(spy.mock.calls[0]).toEqual([undefined, undefined]);\n\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1]).toEqual([\"erikras\", \"erikras\"]);\n\n    fireEvent.change(getByTestId(\"name\"), {\n      target: { value: \"erikras rulez\" },\n    });\n\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2]).toEqual([\"erikras rulez\", \"erikras rulez\"]);\n  });\n\n  it(\"should not render with render prop when given onChange\", () => {\n    const spy = jest.fn();\n    const renderSpy = jest.fn();\n    render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <FormSpy\n              subscription={{ dirty: true, values: true }}\n              onChange={spy}\n              render={renderSpy}\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(spy).toHaveBeenCalled();\n    expect(spy).toHaveBeenCalledTimes(1);\n    expect(renderSpy).not.toHaveBeenCalled();\n  });\n\n  it(\"should ignore SyntheticEvents on form reset \", () => {\n    const { getByTestId, getByText } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        subscription={{}}\n        initialValues={{ name: \"erikras\" }}\n      >\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <FormSpy subscription={{}}>\n              {({ form }) => (\n                <button type=\"button\" onClick={form.reset}>\n                  Reset\n                </button>\n              )}\n            </FormSpy>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    fireEvent.change(getByTestId(\"name\"), {\n      target: { value: \"erikrasmussen\" },\n    });\n    expect(getByTestId(\"name\").value).toBe(\"erikrasmussen\");\n    fireEvent.click(getByText(\"Reset\"));\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n  });\n\n  it(\"should accept new initial values on form reset \", () => {\n    const { getByTestId, getByText } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        subscription={{}}\n        initialValues={{ name: \"erikras\" }}\n      >\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <FormSpy subscription={{}}>\n              {({ form }) => (\n                <button\n                  type=\"button\"\n                  onClick={() => form.reset({ name: \"bob\" })}\n                >\n                  Reset\n                </button>\n              )}\n            </FormSpy>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    fireEvent.change(getByTestId(\"name\"), {\n      target: { value: \"erikrasmussen\" },\n    });\n    expect(getByTestId(\"name\").value).toBe(\"erikrasmussen\");\n    fireEvent.click(getByText(\"Reset\"));\n    expect(getByTestId(\"name\").value).toBe(\"bob\");\n  });\n\n  it(\"should allow subscription to be undefined\", () => {\n    // Implementation of this test case is not provided in the original file or the code block\n    // This test case is assumed to exist based on the code block\n  });\n\n  it(\"should not throw error when subscribing to active (fix #1055)\", () => {\n    // Issue #1055: Cannot set property active of #<Object> which has only a getter\n    // This was caused by spreading lazy state with getter-only properties into renderProps\n    const spy = jest.fn();\n    const { container, getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <FormSpy\n              subscription={{ active: true, values: true }}\n              render={wrapWith(spy, (props) => {\n                // Verify that we can access active and values without error\n                const { active, values } = props;\n                return <div data-testid=\"spy\">active={String(active)} values={JSON.stringify(values)}</div>;\n              })}\n            />\n          </form>\n        )}\n      </Form>,\n    );\n    \n    // Should render without throwing \"Cannot set property active\" error\n    expect(container).toBeTruthy();\n    expect(spy).toHaveBeenCalled();\n    \n    // Verify that active and values properties exist and can be accessed\n    const props = spy.mock.calls[spy.mock.calls.length - 1][0];\n    expect(\"active\" in props).toBe(true);\n    expect(\"values\" in props).toBe(true);\n    \n    // Active should be undefined initially (no field focused)\n    expect(props.active).toBeUndefined();\n    \n    // Values should be defined (empty object initially)\n    expect(props.values).toBeDefined();\n    expect(props.values).toEqual({});\n    \n    // When we focus a field, active should be the field name\n    fireEvent.focus(getByTestId(\"name\"));\n    expect(spy.mock.calls[spy.mock.calls.length - 1][0].active).toBe(\"name\");\n  });\n});\n"
  },
  {
    "path": "src/FormSpy.tsx",
    "content": "import renderComponent from \"./renderComponent\";\nimport type { FormSpyProps, FormSpyRenderProps } from \"./types\";\nimport isSyntheticEvent from \"./isSyntheticEvent\";\nimport useForm from \"./useForm\";\nimport useFormState from \"./useFormState\";\n\nfunction FormSpy<FormValues = Record<string, any>>({\n  onChange,\n  subscription,\n  ...rest\n}: FormSpyProps<FormValues>): React.ReactElement | null {\n  const reactFinalForm = useForm<FormValues>(\"FormSpy\");\n  const state = useFormState({ onChange, subscription });\n  if (onChange) {\n    return null;\n  }\n\n  const renderProps: FormSpyRenderProps<FormValues> = {\n    form: {\n      ...reactFinalForm,\n      reset: (eventOrValues?: any) => {\n        if (isSyntheticEvent(eventOrValues)) {\n          // it's a React SyntheticEvent, call reset with no arguments\n          reactFinalForm.reset();\n        } else {\n          reactFinalForm.reset(eventOrValues);\n        }\n      },\n    },\n  } as FormSpyRenderProps<FormValues>;\n  return renderComponent(\n    {\n      ...rest,\n      ...renderProps,\n    },\n    state,\n    \"FormSpy\",\n  ) as React.ReactElement;\n}\n\nexport default FormSpy;\n"
  },
  {
    "path": "src/ReactFinalForm.test.js",
    "content": "import React from \"react\";\nimport { render, fireEvent, cleanup, act } from \"@testing-library/react\";\nimport \"@testing-library/jest-dom\";\nimport deepEqual from \"fast-deep-equal\";\nimport { ErrorBoundary, Toggle, wrapWith } from \"./testUtils\";\nimport { createForm } from \"final-form\";\nimport { Form, Field, version, withTypes } from \".\";\n\nconst onSubmitMock = (_values) => {};\nconst timeout = (ms) => new Promise((resolve) => setTimeout(resolve, ms));\nasync function sleep(ms) {\n  await act(async () => {\n    await timeout(ms);\n  });\n}\n\ndescribe(\"ReactFinalForm\", () => {\n  afterEach(cleanup);\n\n  it(\"should export version\", () => {\n    expect(version).toBeDefined();\n  });\n\n  it(\"should export withTypes\", () => {\n    // mostly for code coverage\n    expect(withTypes).toBeDefined();\n    expect(withTypes()).toBeDefined();\n  });\n\n  it(\"should render with render function\", () => {\n    const { getByTestId } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        render={() => <div data-testid=\"myDiv\" />}\n      />,\n    );\n    expect(getByTestId(\"myDiv\")).toBeDefined();\n  });\n\n  it(\"should render with children render function\", () => {\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>{() => <div data-testid=\"myDiv\" />}</Form>,\n    );\n    expect(getByTestId(\"myDiv\")).toBeDefined();\n  });\n\n  it(\"should print a warning with no render or children specified\", () => {\n    jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const errorSpy = jest.fn();\n    render(\n      <ErrorBoundary spy={errorSpy}>\n        <Form onSubmit={onSubmitMock} />\n      </ErrorBoundary>,\n    );\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0].message).toBe(\n      \"Must specify either a render prop, a render function as children, or a component prop to ReactFinalForm\",\n    );\n    console.error.mockRestore();\n  });\n\n  it(\"should print a warning with no onSubmit specified\", () => {\n    jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const errorSpy = jest.fn();\n    render(\n      <ErrorBoundary spy={errorSpy}>\n        <Form render={() => <div data-testid=\"myDiv\" />} />\n      </ErrorBoundary>,\n    );\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0].message).toBe(\n      \"No onSubmit function specified\",\n    );\n    console.error.mockRestore();\n  });\n\n  it(\"should allow render to be a component\", () => {\n    const Component = () => <div data-testid=\"myDiv\" />;\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} component={Component} />,\n    );\n    expect(getByTestId(\"myDiv\")).toBeDefined();\n  });\n\n  it(\"should unsubscribe on unmount\", () => {\n    // This is mainly here for code coverage. 🧐\n    const Container = () => {\n      const [shown, setShown] = React.useState(true);\n      return (\n        <div>\n          {shown && <Form onSubmit={onSubmitMock} render={() => <form />} />}\n          <button type=\"button\" onClick={() => setShown(false)}>\n            Unmount\n          </button>\n        </div>\n      );\n    };\n    const { getByText } = render(\n      <Form onSubmit={onSubmitMock} component={Container} />,\n    );\n    fireEvent.click(getByText(\"Unmount\"));\n  });\n\n  it(\"should render with a field\", () => {\n    const formRender = jest.fn();\n    const fieldRender = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {wrapWith(formRender, () => (\n          <form>\n            <Field name=\"firstName\">\n              {wrapWith(fieldRender, ({ input, meta }) => (\n                <>\n                  <div data-testid=\"firstNameActive\">\n                    {meta.active ? \"active\" : \"inactive\"}\n                  </div>\n                  <input data-testid=\"firstName\" {...input} />\n                </>\n              ))}\n            </Field>\n          </form>\n        ))}\n      </Form>,\n    );\n    const firstName = getByTestId(\"firstName\");\n    const active = getByTestId(\"firstNameActive\");\n    expect(firstName).toBeDefined();\n    expect(active).toBeDefined();\n    expect(firstName.value).toBe(\"\");\n    expect(active).toHaveTextContent(\"inactive\");\n    // All forms render twice at first because they need to update their validation\n    // and touched/modified/visited maps every time new fields are registered.\n    expect(formRender).toHaveBeenCalledTimes(2);\n    expect(fieldRender).toHaveBeenCalledTimes(2);\n    fireEvent.focus(firstName);\n    expect(formRender).toHaveBeenCalledTimes(3);\n    expect(fieldRender).toHaveBeenCalledTimes(3);\n    expect(active).toHaveTextContent(\"active\");\n    fireEvent.change(firstName, { target: { value: \"E\" } });\n    expect(formRender).toHaveBeenCalledTimes(4);\n    expect(fieldRender).toHaveBeenCalledTimes(4);\n    expect(firstName.value).toBe(\"E\");\n    fireEvent.change(firstName, { target: { value: \"Er\" } });\n    expect(formRender).toHaveBeenCalledTimes(5);\n    expect(fieldRender).toHaveBeenCalledTimes(5);\n    fireEvent.change(firstName, { target: { value: \"Eri\" } });\n    expect(formRender).toHaveBeenCalledTimes(6);\n    expect(fieldRender).toHaveBeenCalledTimes(6);\n    fireEvent.change(firstName, { target: { value: \"Erik\" } });\n    expect(formRender).toHaveBeenCalledTimes(7);\n    expect(fieldRender).toHaveBeenCalledTimes(7);\n    expect(active).toHaveTextContent(\"active\");\n    fireEvent.blur(firstName);\n    expect(formRender).toHaveBeenCalledTimes(8);\n    expect(fieldRender).toHaveBeenCalledTimes(8);\n    expect(active).toHaveTextContent(\"inactive\");\n  });\n\n  it(\"should render with a field with a limited subscription\", () => {\n    const formRender = jest.fn();\n    const fieldRender = jest.fn();\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} subscription={{}}>\n        {wrapWith(formRender, () => (\n          <form>\n            <Field name=\"firstName\" subscription={{ value: true }}>\n              {wrapWith(fieldRender, ({ input, meta }) => (\n                <>\n                  <div data-testid=\"firstNameActive\">\n                    {meta.active ? \"active\" : \"inactive\"}\n                  </div>\n                  <input data-testid=\"firstName\" {...input} />\n                </>\n              ))}\n            </Field>\n          </form>\n        ))}\n      </Form>,\n    );\n    const firstName = getByTestId(\"firstName\");\n    const active = getByTestId(\"firstNameActive\");\n    expect(firstName).toBeDefined();\n    expect(active).toBeDefined();\n    expect(firstName.value).toBe(\"\");\n    expect(active).toHaveTextContent(\"inactive\");\n    expect(formRender).toHaveBeenCalledTimes(2);\n    expect(fieldRender).toHaveBeenCalledTimes(2);\n    fireEvent.focus(firstName);\n    // not subscribing to active, so no rerender!\n    expect(formRender).toHaveBeenCalledTimes(2);\n    expect(fieldRender).toHaveBeenCalledTimes(2);\n    expect(active).toHaveTextContent(\"inactive\");\n    fireEvent.change(firstName, { target: { value: \"E\" } });\n    expect(formRender).toHaveBeenCalledTimes(2);\n    expect(fieldRender).toHaveBeenCalledTimes(3);\n    expect(firstName.value).toBe(\"E\");\n    fireEvent.change(firstName, { target: { value: \"Er\" } });\n    expect(formRender).toHaveBeenCalledTimes(2);\n    expect(fieldRender).toHaveBeenCalledTimes(4);\n    fireEvent.change(firstName, { target: { value: \"Eri\" } });\n    expect(formRender).toHaveBeenCalledTimes(2);\n    expect(fieldRender).toHaveBeenCalledTimes(5);\n    fireEvent.change(firstName, { target: { value: \"Erik\" } });\n    expect(formRender).toHaveBeenCalledTimes(2);\n    expect(fieldRender).toHaveBeenCalledTimes(6);\n    expect(active).toHaveTextContent(\"inactive\");\n    fireEvent.blur(firstName);\n    // no rerender\n    expect(formRender).toHaveBeenCalledTimes(2);\n    expect(fieldRender).toHaveBeenCalledTimes(6);\n    expect(active).toHaveTextContent(\"inactive\");\n  });\n\n  it(\"should call onSubmit when form is submitted\", () => {\n    const onSubmit = jest.fn();\n    const { getByTestId, getByText } = render(\n      <Form onSubmit={onSubmit}>\n        {({ handleSubmit }) => (\n          <form data-testid=\"form\" onSubmit={handleSubmit}>\n            <Field name=\"firstName\" component=\"input\" data-testid=\"firstName\" />\n            <Field name=\"lastName\" component=\"input\" data-testid=\"lastName\" />\n            <button type=\"submit\">Submit</button>\n          </form>\n        )}\n      </Form>,\n    );\n    fireEvent.change(getByTestId(\"firstName\"), { target: { value: \"Erik\" } });\n    fireEvent.change(getByTestId(\"lastName\"), {\n      target: { value: \"Rasmussen\" },\n    });\n    expect(onSubmit).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Submit\"));\n    expect(onSubmit).toHaveBeenCalled();\n    expect(onSubmit).toHaveBeenCalledTimes(1);\n    expect(onSubmit.mock.calls[0][0]).toEqual({\n      firstName: \"Erik\",\n      lastName: \"Rasmussen\",\n    });\n  });\n\n  // it('should not throw when handleSubmit is called with no event', () => {\n  //   const onSubmit = jest.fn()\n  //   const { getByTestId, getByText } = render(\n  //     <Form onSubmit={onSubmit}>\n  //       {({ handleSubmit }) => (\n  //         <form\n  //           data-testid=\"form\"\n  //           onSubmit={values => {\n  //             handleSubmit(values)\n  //           }}\n  //         >\n  // <Field name=\"firstName\" component=\"input\" data-testid=\"firstName\"/>\n  // <Field name=\"lastName\" component=\"input\" data-testid=\"lastName\"/>\n  //           <button type=\"submit\">Submit</button>\n  //         </form>\n  //       )}\n  //     </Form>\n  //   )\n  //   fireEvent.change(getByTestId('firstName'), { target: { value: 'Erik' } })\n  //   fireEvent.change(getByTestId('lastName'), {\n  //     target: { value: 'Rasmussen' }\n  //   })\n  //   expect(onSubmit).not.toHaveBeenCalled()\n  //   fireEvent.click(getByText('Submit'))\n  //   expect(onSubmit).toHaveBeenCalled()\n  //   expect(onSubmit).toHaveBeenCalledTimes(1)\n  //   expect(onSubmit.mock.calls[0][0]).toEqual({\n  //     firstName: 'Erik',\n  //     lastName: 'Rasmussen'\n  //   })\n  // })\n\n  it(\"should reinitialize when initialValues prop changes\", () => {\n    const initialValues = {\n      name: \"Dr. Jekyll\",\n    };\n    const alternateInitialValues = {\n      name: \"Mr. Hyde\",\n    };\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(useAlternateInitialValues) => (\n          <Form\n            onSubmit={onSubmitMock}\n            initialValues={\n              useAlternateInitialValues ? alternateInitialValues : initialValues\n            }\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Jekyll\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"Dr. Watson\" } });\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Watson\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"name\").value).toBe(\"Mr. Hyde\");\n  });\n\n  it(\"should NOT reinitialize when initialValues prop doesn't change (shallowly) but rerendered\", () => {\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(useAlternateInitialValues) => (\n          <Form\n            onSubmit={onSubmitMock}\n            initialValues={{\n              name: \"Dr. Jekyll\",\n            }}\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Jekyll\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"Dr. Watson\" } });\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Watson\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Watson\");\n  });\n\n  it(\"should reinitialize when initialValues prop changes, deeply\", () => {\n    const initialValues = {\n      professor: {\n        name: \"Dr. Jekyll\",\n      },\n    };\n    const alternateInitialValues = {\n      professor: {\n        name: \"Mr. Hyde\",\n      },\n    };\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(useAlternateInitialValues) => (\n          <Form\n            onSubmit={onSubmitMock}\n            initialValues={\n              useAlternateInitialValues ? alternateInitialValues : initialValues\n            }\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field\n                  name=\"professor.name\"\n                  component=\"input\"\n                  data-testid=\"name\"\n                />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Jekyll\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"Dr. Watson\" } });\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Watson\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"name\").value).toBe(\"Mr. Hyde\");\n  });\n\n  it(\"should not reinitialize if initialValues prop is deep equal\", () => {\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(useAlternateInitialValues) => (\n          <Form\n            onSubmit={onSubmitMock}\n            initialValues={{\n              professor: {\n                name: \"Dr. Jekyll\",\n              },\n            }}\n            initialValuesEqual={deepEqual}\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field\n                  name=\"professor.name\"\n                  component=\"input\"\n                  data-testid=\"name\"\n                />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Jekyll\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"Dr. Watson\" } });\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Watson\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Watson\");\n  });\n\n  it(\"should respect keepDirtyOnReinitialize prop when initialValues prop changes\", () => {\n    const initialValues = {\n      name: \"Dr. Jekyll\",\n    };\n    const alternateInitialValues = {\n      name: \"Mr. Hyde\",\n    };\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(useAlternateInitialValues) => (\n          <Form\n            onSubmit={onSubmitMock}\n            keepDirtyOnReinitialize\n            initialValues={\n              useAlternateInitialValues ? alternateInitialValues : initialValues\n            }\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Jekyll\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"Dr. Watson\" } });\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Watson\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"name\").value).toBe(\"Dr. Watson\");\n  });\n\n  it(\"should update when onSubmit changes\", () => {\n    const firstOnSubmit = jest.fn();\n    const secondOnSubmit = jest.fn();\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(useAlternateOnSubmit) => (\n          <Form\n            onSubmit={useAlternateOnSubmit ? secondOnSubmit : firstOnSubmit}\n          >\n            {({ handleSubmit }) => (\n              <form data-testid=\"form\" onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n                <button type=\"submit\">Submit</button>\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"Erik\" } });\n    expect(firstOnSubmit).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Submit\"));\n    expect(firstOnSubmit).toHaveBeenCalled();\n    expect(firstOnSubmit).toHaveBeenCalledTimes(1);\n    expect(firstOnSubmit.mock.calls[0][0]).toEqual({\n      name: \"Erik\",\n    });\n    expect(secondOnSubmit).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(firstOnSubmit).toHaveBeenCalledTimes(1);\n    expect(secondOnSubmit).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Submit\"));\n    expect(firstOnSubmit).toHaveBeenCalledTimes(1);\n    expect(secondOnSubmit).toHaveBeenCalled();\n    expect(secondOnSubmit).toHaveBeenCalledTimes(1);\n    expect(secondOnSubmit.mock.calls[0][0]).toEqual({\n      name: \"Erik\",\n    });\n  });\n\n  it(\"should warn if decorators change\", () => {\n    const decoratorA = (form) => () => {};\n    const decoratorB = (form) => () => {};\n    const decoratorC = (form) => () => {};\n    const oldDecorators = [decoratorA, decoratorB];\n    const newDecorators = [decoratorA, decoratorB, decoratorC];\n    const errorSpy = jest.spyOn(console, \"error\").mockImplementation(() => {});\n\n    const { getByText } = render(\n      <Toggle>\n        {(useAlternateDecorators) => (\n          <Form\n            onSubmit={onSubmitMock}\n            decorators={useAlternateDecorators ? newDecorators : oldDecorators}\n          >\n            {({ handleSubmit }) => (\n              <form data-testid=\"form\" onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n                <button type=\"submit\">Submit</button>\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(errorSpy).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledWith(\n      \"Form decorators should not change from one render to the next as new values will be ignored\",\n    );\n    errorSpy.mockRestore();\n  });\n\n  it(\"should return a promise from handleSubmit when submission is async\", () => {\n    const { getByTestId, getByText } = render(\n      <Form\n        onSubmit={async () => {\n          await timeout(2);\n        }}\n      >\n        {({ handleSubmit }) => (\n          <form\n            data-testid=\"form\"\n            onSubmit={(event) => {\n              const promise = handleSubmit(event);\n              expect(promise).toBeDefined();\n              expect(typeof promise.then).toBe(\"function\");\n            }}\n          >\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <button type=\"submit\">Submit</button>\n          </form>\n        )}\n      </Form>,\n    );\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"Erik\" } });\n    fireEvent.click(getByText(\"Submit\"));\n  });\n\n  it(\"should ignore SyntheticEvents on form reset \", () => {\n    const { getByTestId, getByText } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ name: \"John\" }}>\n        {({ handleSubmit, form }) => (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <button type=\"button\" onClick={form.reset}>\n              Reset\n            </button>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"John\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"Paul\" } });\n    expect(getByTestId(\"name\").value).toBe(\"Paul\");\n    fireEvent.click(getByText(\"Reset\"));\n    expect(getByTestId(\"name\").value).toBe(\"John\");\n  });\n\n  it(\"should accept new initial values on form reset \", () => {\n    const { getByTestId, getByText } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        subscription={{}}\n        initialValues={{ name: \"erikras\" }}\n      >\n        {({ form }) => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <button type=\"button\" onClick={() => form.reset({ name: \"bob\" })}>\n              Reset\n            </button>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    fireEvent.change(getByTestId(\"name\"), {\n      target: { value: \"erikrasmussen\" },\n    });\n    expect(getByTestId(\"name\").value).toBe(\"erikrasmussen\");\n    fireEvent.click(getByText(\"Reset\"));\n    expect(getByTestId(\"name\").value).toBe(\"bob\");\n  });\n\n  it(\"should use decorators, and unsubscribe them on unmount\", () => {\n    const unsubscribe = jest.fn();\n    const decorator = jest.fn(() => unsubscribe);\n    const { getByText } = render(\n      <Toggle>\n        {(hideForm) =>\n          !hideForm && (\n            <Form onSubmit={onSubmitMock} decorators={[decorator]}>\n              {({ handleSubmit }) => (\n                <form onSubmit={handleSubmit}>\n                  <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n                </form>\n              )}\n            </Form>\n          )\n        }\n      </Toggle>,\n    );\n    expect(decorator).toHaveBeenCalled();\n    expect(decorator).toHaveBeenCalledTimes(1);\n    expect(unsubscribe).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(unsubscribe).toHaveBeenCalled();\n  });\n\n  it(\"should all record level validation function to change\", () => {\n    const simpleValidation = (values) => {\n      const errors = {};\n      if (!values.name) {\n        errors.name = \"Required\";\n      }\n      return errors;\n    };\n    const complexValidation = (values) => {\n      const errors = {};\n      if (!values.name) {\n        errors.name = \"Required\";\n      } else if (values.name.toUpperCase() !== values.name) {\n        errors.name = \"SHOULD BE SHOUTING\";\n      }\n      return errors;\n    };\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(useComplexValidation) => (\n          <Form\n            onSubmit={onSubmitMock}\n            subscription={{}}\n            validate={\n              useComplexValidation ? complexValidation : simpleValidation\n            }\n          >\n            {() => (\n              <form>\n                <Field name=\"name\" component=\"input\">\n                  {({ input, meta }) => (\n                    <div>\n                      <input {...input} data-testid=\"name\" />\n                      <div data-testid=\"error\">{meta.error}</div>\n                    </div>\n                  )}\n                </Field>\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    expect(getByTestId(\"error\")).toHaveTextContent(\"Required\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(getByTestId(\"error\")).toHaveTextContent(\"\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"error\")).toHaveTextContent(\"SHOULD BE SHOUTING\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"ERIKRAS\" } });\n    expect(getByTestId(\"error\")).toHaveTextContent(\"\");\n  });\n\n  it(\"should show form as invalid on second rerender if field-level validation errors are present\", () => {\n    // Debugging https://github.com/final-form/react-final-form/issues/196\n    const spy = jest.fn();\n    render(\n      <Form\n        onSubmit={onSubmitMock}\n        subscription={{ invalid: true }}\n        initialValues={{ name: \"erik\" }}\n      >\n        {({ handleSubmit, invalid }) => {\n          spy(invalid);\n          return (\n            <form onSubmit={handleSubmit}>\n              <Field\n                name=\"name\"\n                component=\"input\"\n                validate={() => \"Required\"}\n              />\n            </form>\n          );\n        }}\n      </Form>,\n    );\n    // On first render, we cannot know about any field level validation rules\n    // because none of the fields have yet had a chance to render and register.\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0]).toBe(false);\n    expect(spy.mock.calls[1][0]).toBe(true);\n  });\n\n  it(\"should work with server-side rendering\", () => {\n    const errorSpy = jest.spyOn(console, \"error\").mockImplementation(() => {});\n    render(\n      <Form\n        onSubmit={onSubmitMock}\n        render={() => (\n          <form>\n            <Field name=\"foo\" component=\"input\" type=\"text\" />\n          </form>\n        )}\n      />,\n    );\n    expect(errorSpy).not.toHaveBeenCalled();\n    errorSpy.mockRestore();\n  });\n\n  it(\"should allow change to debug flag\", () => {\n    // this is mostly for code coverage 😰\n    const debugMock = jest.fn();\n    const { getByText } = render(\n      <Toggle>\n        {(debug) => (\n          <Form onSubmit={onSubmitMock} debug={debug ? debugMock : undefined}>\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    fireEvent.click(getByText(\"Toggle\"));\n  });\n\n  it(\"should allow change to destroyOnUnregister flag\", () => {\n    // this is mostly for code coverage 😰\n    const { getByText } = render(\n      <Toggle>\n        {(destroyOnUnregister) => (\n          <Form\n            onSubmit={onSubmitMock}\n            destroyOnUnregister={destroyOnUnregister}\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    fireEvent.click(getByText(\"Toggle\"));\n  });\n\n  it(\"should allow change to keepDirtyOnReinitialize flag\", () => {\n    // this is mostly for code coverage 😰\n    const { getByText } = render(\n      <Toggle>\n        {(keepDirtyOnReinitialize) => (\n          <Form\n            onSubmit={onSubmitMock}\n            keepDirtyOnReinitialize={keepDirtyOnReinitialize}\n          >\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    fireEvent.click(getByText(\"Toggle\"));\n  });\n\n  it(\"should allow change to validateOnBlur flag\", () => {\n    // this is mostly for code coverage 😰\n    const { getByText } = render(\n      <Toggle>\n        {(validateOnBlur) => (\n          <Form onSubmit={onSubmitMock} validateOnBlur={validateOnBlur}>\n            {({ handleSubmit }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n              </form>\n            )}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    fireEvent.click(getByText(\"Toggle\"));\n  });\n\n  it(\"should allow change to mutators\", () => {\n    // this is mostly for code coverage 😰\n    const oldMutators = undefined;\n    const newMutators = {\n      clearField: ([name], state, { changeValue }) => {\n        changeValue(state, name, () => undefined);\n      },\n    };\n    const spy = jest.fn();\n    const { getByTestId, getByText } = render(\n      <Toggle>\n        {(swapMutators) => (\n          <Form\n            onSubmit={onSubmitMock}\n            mutators={swapMutators ? newMutators : oldMutators}\n          >\n            {wrapWith(spy, ({ handleSubmit, form }) => (\n              <form onSubmit={handleSubmit}>\n                <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n                <button\n                  type=\"button\"\n                  onClick={() => form.mutators.clearField(\"name\")}\n                >\n                  Clear Name\n                </button>\n              </form>\n            ))}\n          </Form>\n        )}\n      </Toggle>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    fireEvent.click(getByText(\"Clear Name\"));\n    expect(getByTestId(\"name\").value).toBe(\"\");\n  });\n\n  it(\"should allow handleSubmit to be called with an object that's not an event\", () => {\n    const onSubmitMock = jest.fn();\n    const { getByText } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ name: \"erikras\" }}>\n        {({ handleSubmit }) => (\n          <form\n            onSubmit={(event) => {\n              handleSubmit({});\n              event.preventDefault(); // so react-testing-library doesn't freak out\n            }}\n          >\n            <Field name=\"name\" component=\"input\" />\n            <button type=\"submit\">Submit</button>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(onSubmitMock).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Submit\"));\n    expect(onSubmitMock).toHaveBeenCalled();\n    expect(onSubmitMock).toHaveBeenCalledTimes(1);\n    expect(onSubmitMock.mock.calls[0][0]).toEqual({ name: \"erikras\" });\n  });\n\n  it(\"should allow handleSubmit to be called with no parameters\", () => {\n    const onSubmitMock = jest.fn();\n    const { getByText } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ name: \"erikras\" }}>\n        {({ handleSubmit }) => (\n          <form\n            onSubmit={(event) => {\n              handleSubmit();\n              event.preventDefault(); // so react-testing-library doesn't freak out\n            }}\n          >\n            <Field name=\"name\" component=\"input\" />\n            <button type=\"submit\">Submit</button>\n          </form>\n        )}\n      </Form>,\n    );\n    expect(onSubmitMock).not.toHaveBeenCalled();\n    fireEvent.click(getByText(\"Submit\"));\n    expect(onSubmitMock).toHaveBeenCalled();\n    expect(onSubmitMock).toHaveBeenCalledTimes(1);\n    expect(onSubmitMock.mock.calls[0][0]).toEqual({ name: \"erikras\" });\n  });\n\n  it(\"should set submitting back to false after submit\", async () => {\n    const onSubmit = jest.fn(async () => {\n      await timeout(1);\n    });\n    const recordSubmitting = jest.fn();\n    const { getByText } = render(\n      <Form onSubmit={onSubmit} subscription={{ submitting: true }}>\n        {({ handleSubmit, submitting }) => {\n          recordSubmitting(submitting);\n          return (\n            <form onSubmit={handleSubmit}>\n              <Field name=\"name\" component=\"input\" />\n              <button type=\"submit\">Submit</button>\n            </form>\n          );\n        }}\n      </Form>,\n    );\n    expect(onSubmit).not.toHaveBeenCalled();\n    expect(recordSubmitting).toHaveBeenCalled();\n    expect(recordSubmitting).toHaveBeenCalledTimes(2);\n    expect(recordSubmitting.mock.calls[0][0]).toBe(false);\n\n    fireEvent.click(getByText(\"Submit\"));\n\n    expect(onSubmit).toHaveBeenCalled();\n    expect(onSubmit).toHaveBeenCalledTimes(1);\n    expect(recordSubmitting).toHaveBeenCalledTimes(3);\n    expect(recordSubmitting.mock.calls[2][0]).toBe(true);\n\n    await sleep(5);\n\n    expect(recordSubmitting).toHaveBeenCalledTimes(4);\n    expect(recordSubmitting.mock.calls[3][0]).toBe(false);\n  });\n\n  it(\"should allow an alternative form api to be passed in\", () => {\n    const onSubmit = jest.fn();\n    const form = createForm({ onSubmit: onSubmit });\n    const formMock = jest.spyOn(form, \"registerField\");\n    render(\n      <Form form={form}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"name\" component=\"input\" />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(formMock).toHaveBeenCalled();\n\n    // called once on first render to get initial state, and then again to subscribe\n    expect(formMock).toHaveBeenCalledTimes(1);\n    expect(formMock.mock.calls[0][0]).toBe(\"name\");\n    expect(formMock.mock.calls[0][2].active).toBe(true); // default subscription\n  });\n\n  it(\"should not destroy on unregister on initial unregister\", () => {\n    // https://github.com/final-form/react-final-form/issues/523\n    const { getByTestId } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        initialValues={{ name: \"erikras\" }}\n        destroyOnUnregister\n      >\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(getByTestId(\"name\")).toBeDefined();\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    fireEvent.focus(getByTestId(\"name\"));\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n  });\n\n  it(\"should not destroy on unregister on initial register/unregister of new field\", () => {\n    // https://github.com/final-form/react-final-form/issues/523\n    const { getByTestId, queryByTestId, getByText } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        initialValues={{ name: \"erikras\", password: \"f1nal-f0rm-RULEZ\" }}\n        destroyOnUnregister\n      >\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <Toggle>\n              {(showPassword) =>\n                showPassword && (\n                  <Field\n                    name=\"password\"\n                    component=\"input\"\n                    type=\"password\"\n                    data-testid=\"password\"\n                  />\n                )\n              }\n            </Toggle>\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(getByTestId(\"name\")).toBeDefined();\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    fireEvent.focus(getByTestId(\"name\"));\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    expect(queryByTestId(\"password\")).toBe(null);\n    fireEvent.click(getByText(\"Toggle\"));\n    expect(getByTestId(\"password\").value).toBe(\"f1nal-f0rm-RULEZ\");\n    fireEvent.focus(getByTestId(\"password\"));\n    expect(getByTestId(\"password\").value).toBe(\"f1nal-f0rm-RULEZ\");\n  });\n\n  it(\"should set submitting back to false when onSubmit returns Promise.resolve() immediately (#903)\", async () => {\n    // Regression test for: https://github.com/final-form/react-final-form/issues/903\n    // When onSubmit is an async function with no awaits (returns Promise<void>),\n    // submitting should reset to false after the promise resolves.\n    const onSubmit = jest.fn(async () => {\n      // async with no await — resolves in the next microtask, no real async delay\n    });\n    const recordSubmitting = jest.fn();\n    const { getByText } = render(\n      <Form onSubmit={onSubmit} subscription={{ submitting: true }}>\n        {({ handleSubmit, submitting }) => {\n          recordSubmitting(submitting);\n          return (\n            <form onSubmit={handleSubmit}>\n              <Field name=\"name\" component=\"input\" />\n              <button type=\"submit\">Submit</button>\n            </form>\n          );\n        }}\n      </Form>,\n    );\n\n    fireEvent.click(getByText(\"Submit\"));\n\n    // Wait for the microtask Promise to resolve and React to update\n    await act(async () => {});\n\n    // submitting should have gone true then back to false\n    const calls = recordSubmitting.mock.calls.map((c) => c[0]);\n    expect(calls).toContain(true);  // was submitting at some point\n    expect(calls[calls.length - 1]).toBe(false); // ends as not submitting\n  });\n\n  it(\"should set submitting back to false when onSubmit returns Promise.resolve() (#903)\", async () => {\n    const onSubmit = jest.fn(() => Promise.resolve());\n    const recordSubmitting = jest.fn();\n    const { getByText } = render(\n      <Form onSubmit={onSubmit} subscription={{ submitting: true }}>\n        {({ handleSubmit, submitting }) => {\n          recordSubmitting(submitting);\n          return (\n            <form onSubmit={handleSubmit}>\n              <Field name=\"name\" component=\"input\" />\n              <button type=\"submit\">Submit</button>\n            </form>\n          );\n        }}\n      </Form>,\n    );\n\n    fireEvent.click(getByText(\"Submit\"));\n    await act(async () => {});\n\n    const calls = recordSubmitting.mock.calls.map((c) => c[0]);\n    expect(calls[calls.length - 1]).toBe(false);\n  });\n});\n\ndescribe(\"Issue #914 – nested Field with validator causing Maximum update depth\", () => {\n  it(\"should not throw Maximum update depth exceeded when nesting Fields with validators\", () => {\n    // https://github.com/final-form/react-final-form/issues/914\n    const required = (value) => (value ? undefined : \"Required\");\n\n    expect(() => {\n      render(\n        <Form onSubmit={onSubmitMock}>\n          {({ handleSubmit }) => (\n            <form onSubmit={handleSubmit}>\n              <Field name=\"outer\" validate={required}>\n                {({ input }) => (\n                  <div>\n                    <input {...input} data-testid=\"outer\" />\n                    <Field name=\"inner\" validate={required}>\n                      {({ input: innerInput }) => (\n                        <input {...innerInput} data-testid=\"inner\" />\n                      )}\n                    </Field>\n                  </div>\n                )}\n              </Field>\n            </form>\n          )}\n        </Form>,\n      );\n    }).not.toThrow();\n  });\n});\n\ndescribe(\"Issue #850 – Cannot update component while rendering different component\", () => {\n  it(\"should not warn about updating during render when conditionally rendering Field with initialValue\", async () => {\n    // https://github.com/final-form/react-final-form/issues/850\n    const warnSpy = jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const Toggle = ({ children }) => {\n      const [show, setShow] = React.useState(false);\n      return (\n        <div>\n          <button onClick={() => setShow((s) => !s)}>Toggle</button>\n          {show && children}\n        </div>\n      );\n    };\n\n    const { getByText } = render(\n      <Form onSubmit={onSubmitMock} subscription={{}}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Field name=\"name\" component=\"input\" initialValue=\"erik\" />\n            <Toggle>\n              <Field name=\"message\" component=\"input\" initialValue=\"hello\" />\n            </Toggle>\n          </form>\n        )}\n      </Form>,\n    );\n\n    // Toggle the conditional field\n    await act(async () => {\n      fireEvent.click(getByText(\"Toggle\"));\n    });\n\n    // Should not have any \"Cannot update component while rendering\" warnings\n    const updateWhileRenderingWarnings = warnSpy.mock.calls.filter(\n      (call) =>\n        call[0] &&\n        typeof call[0] === \"string\" &&\n        call[0].includes(\"Cannot update\"),\n    );\n    expect(updateWhileRenderingWarnings).toHaveLength(0);\n    warnSpy.mockRestore();\n  });\n});\n"
  },
  {
    "path": "src/ReactFinalForm.tsx",
    "content": "import * as React from \"react\";\nimport {\n  createForm,\n  formSubscriptionItems,\n  version as ffVersion,\n} from \"final-form\";\nimport type {\n  FormApi,\n  Config,\n  FormSubscription,\n  FormState,\n  Unsubscribe,\n} from \"final-form\";\nimport type { FormProps, SubmitEvent } from \"./types\";\nimport renderComponent from \"./renderComponent\";\nimport useWhenValueChanges from \"./useWhenValueChanges\";\nimport useConstant from \"./useConstant\";\nimport shallowEqual from \"./shallowEqual\";\nimport isSyntheticEvent from \"./isSyntheticEvent\";\nimport type { FormRenderProps } from \"./types\";\nimport ReactFinalFormContext from \"./context\";\nimport { addLazyFormState } from \"./getters\";\nimport { version } from \"../package.json\";\n\nexport { version };\n\nconst versions = {\n  \"final-form\": ffVersion,\n  \"react-final-form\": version,\n};\n\nexport const all = formSubscriptionItems.reduce<FormSubscription>(\n  (result: FormSubscription, key: keyof FormSubscription) => {\n    result[key] = true;\n    return result;\n  },\n  {},\n);\n\nfunction ReactFinalForm<FormValues = Record<string, any>>({\n  debug,\n  decorators = [],\n  destroyOnUnregister,\n  form: alternateFormApi,\n  initialValues,\n  initialValuesEqual,\n  keepDirtyOnReinitialize,\n  mutators,\n  onSubmit,\n  subscription = all,\n  validate,\n  validateOnBlur,\n  ...rest\n}: FormProps<FormValues>) {\n  const config: Config<FormValues> = {\n    debug,\n    destroyOnUnregister,\n    initialValues,\n    keepDirtyOnReinitialize,\n    mutators,\n    onSubmit,\n    validate,\n    validateOnBlur,\n  };\n\n  const form: FormApi<FormValues> = useConstant(() => {\n    const f = alternateFormApi || createForm<FormValues>(config);\n    // pause validation until children register all fields on first render (unpaused in useEffect() below)\n    f.pauseValidation();\n    return f;\n  });\n\n  // Get initial state without triggering callbacks during render\n  const [state, setState] = React.useState<FormState<FormValues>>(() => {\n    // Get initial state synchronously but without callbacks\n    return form.getState();\n  });\n\n  // save a copy of state that can break through the closure\n  // on the shallowEqual() line below.\n  const stateRef = React.useRef<FormState<FormValues>>(state);\n  stateRef.current = state;\n\n  React.useEffect(() => {\n    // We have rendered, so all fields are now registered, so we can unpause validation\n    form.isValidationPaused() && form.resumeValidation();\n    const unsubscriptions: Unsubscribe[] = [\n      form.subscribe((s) => {\n        setState((prevState) => {\n          if (!shallowEqual(s, prevState)) {\n            return s;\n          }\n          return prevState;\n        });\n      }, subscription),\n      ...(decorators ? decorators.map((decorator) => decorator(form)) : []),\n    ];\n\n    return () => {\n      form.pauseValidation(); // pause validation so we don't revalidate on every field deregistration\n      unsubscriptions.reverse().forEach((unsubscribe) => unsubscribe());\n      // don't need to resume validation here; either unmounting, or will re-run this hook with new deps\n    };\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  // warn about decorator changes\n  // istanbul ignore next\n  if (process.env.NODE_ENV !== \"production\") {\n    // You're never supposed to use hooks inside a conditional, but in this\n    // case we can be certain that you're not going to be changing your\n    // NODE_ENV between renders, so this is safe.\n\n    // eslint-disable-next-line react-hooks/rules-of-hooks\n    useWhenValueChanges(\n      decorators,\n      () => {\n        console.error(\n          \"Form decorators should not change from one render to the next as new values will be ignored\",\n        );\n      },\n      shallowEqual,\n    );\n  }\n\n  // allow updatable config\n  useWhenValueChanges(debug, () => {\n    form.setConfig(\"debug\", debug);\n  });\n  useWhenValueChanges(destroyOnUnregister, () => {\n    form.destroyOnUnregister = !!destroyOnUnregister;\n  });\n  useWhenValueChanges(keepDirtyOnReinitialize, () => {\n    form.setConfig(\"keepDirtyOnReinitialize\", keepDirtyOnReinitialize);\n  });\n  useWhenValueChanges(\n    initialValues,\n    () => {\n      form.setConfig(\"initialValues\", initialValues);\n    },\n    initialValuesEqual || shallowEqual,\n  );\n  useWhenValueChanges(mutators, () => {\n    form.setConfig(\"mutators\", mutators);\n  });\n  useWhenValueChanges(onSubmit, () => {\n    form.setConfig(\"onSubmit\", onSubmit);\n  });\n  useWhenValueChanges(validate, () => {\n    form.setConfig(\"validate\", validate);\n  });\n  useWhenValueChanges(validateOnBlur, () => {\n    form.setConfig(\"validateOnBlur\", validateOnBlur);\n  });\n\n  const handleSubmit = (event?: SubmitEvent) => {\n    if (event) {\n      // sometimes not true, e.g. React Native\n      if (typeof event.preventDefault === \"function\") {\n        event.preventDefault();\n      }\n      if (typeof event.stopPropagation === \"function\") {\n        // prevent any outer forms from receiving the event too\n        event.stopPropagation();\n      }\n    }\n    return form.submit();\n  };\n\n  const renderProps: FormRenderProps<FormValues> = {\n    form: {\n      ...form,\n      reset: (eventOrValues?: any) => {\n        if (isSyntheticEvent(eventOrValues)) {\n          // it's a React SyntheticEvent, call reset with no arguments\n          form.reset();\n        } else {\n          form.reset(eventOrValues);\n        }\n      },\n    },\n    handleSubmit,\n  } as FormRenderProps<FormValues>;\n  addLazyFormState(renderProps, state);\n  return React.createElement(\n    ReactFinalFormContext.Provider,\n    { value: form },\n    renderComponent(\n      {\n        ...rest,\n        __versions: versions,\n      },\n      renderProps,\n      \"ReactFinalForm\",\n    ),\n  );\n}\n\nexport default ReactFinalForm;\n"
  },
  {
    "path": "src/context.test.js",
    "content": "import * as React from \"react\";\nimport { render } from \"@testing-library/react\";\nimport FormContext from \"./context\";\nimport ReactFinalForm from \"./ReactFinalForm\";\n\ndescribe(\"FormContext\", () => {\n  it(\"should provide form context to children\", () => {\n    const spy = jest.fn();\n    const TestComponent = () => {\n      const form = React.useContext(FormContext);\n      spy(form);\n      return null;\n    };\n\n    render(\n      <ReactFinalForm onSubmit={() => {}}>\n        {({ form }) => (\n          <FormContext.Provider value={form}>\n            <TestComponent />\n          </FormContext.Provider>\n        )}\n      </ReactFinalForm>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(1);\n    expect(spy.mock.calls[0][0]).toBeDefined();\n    expect(typeof spy.mock.calls[0][0].registerField).toBe(\"function\");\n  });\n\n  it(\"should have undefined as default value\", () => {\n    const spy = jest.fn();\n    const TestComponent = () => {\n      const form = React.useContext(FormContext);\n      spy(form);\n      return null;\n    };\n\n    render(<TestComponent />);\n\n    expect(spy).toHaveBeenCalledTimes(1);\n    expect(spy.mock.calls[0][0]).toBeUndefined();\n  });\n});\n"
  },
  {
    "path": "src/context.ts",
    "content": "import * as React from \"react\";\nimport type { FormApi } from \"final-form\";\n\nexport default React.createContext<FormApi<any> | undefined>(undefined);\n"
  },
  {
    "path": "src/getValue.test.js",
    "content": "import { noop } from \"lodash\";\nimport getValue from \"./getValue\";\n\ndescribe(\"getValue\", () => {\n  it(\"should return event.nativeEvent.text if defined and not react-native\", () => {\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          nativeEvent: {\n            text: \"foo\",\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(\"foo\");\n  });\n\n  it(\"should return event.nativeEvent.text if react-native\", () => {\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          nativeEvent: {\n            text: \"foo\",\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(\"foo\");\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          nativeEvent: {\n            text: undefined,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(undefined);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          nativeEvent: {\n            text: null,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(null);\n  });\n\n  it(\"should return event.target.checked if checkbox with no value parameter\", () => {\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: true,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(true);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: true,\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(true);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: undefined,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(false);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: undefined,\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(false);\n  });\n\n  it(\"should return add or remove the value to an array if checkbox with value parameter\", () => {\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: true,\n          },\n        },\n        undefined,\n        \"foo\",\n        false,\n      ),\n    ).toEqual([\"foo\"]);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: true,\n          },\n        },\n        [\"A\", \"B\"],\n        \"C\",\n        false,\n      ),\n    ).toEqual([\"A\", \"B\", \"C\"]);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: false,\n          },\n        },\n        [\"foo\"],\n        \"foo\",\n        false,\n      ),\n    ).toEqual([]);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: false,\n          },\n        },\n        [\"A\", \"B\", \"C\"],\n        \"B\",\n        false,\n      ),\n    ).toEqual([\"A\", \"C\"]);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: false,\n          },\n        },\n        [\"A\", \"B\", \"C\"],\n        \"F\",\n        false,\n      ),\n    ).toEqual([\"A\", \"B\", \"C\"]);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"checkbox\",\n            checked: false,\n          },\n        },\n        undefined,\n        \"F\",\n        false,\n      ),\n    ).toBeUndefined();\n  });\n\n  it(\"should return a number type for numeric inputs, when a value is set\", () => {\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"number\",\n            value: \"3.1415\",\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(\"3.1415\");\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"range\",\n            value: \"2.71828\",\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(\"2.71828\");\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"number\",\n            value: \"3\",\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(\"3\");\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"range\",\n            value: \"3.1415\",\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(\"3.1415\");\n\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"range\",\n            value: \"\",\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(\"\");\n  });\n\n  it(\"should return selected options if is a multiselect\", () => {\n    const options = [\n      { selected: true, value: \"foo\" },\n      { selected: true, value: \"bar\" },\n      { selected: false, value: \"baz\" },\n    ];\n    const expected = options\n      .filter((option) => option.selected)\n      .map((option) => option.value);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"select-multiple\",\n            options,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toEqual(expected);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"select-multiple\",\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toEqual([]); // no options specified\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            type: \"select-multiple\",\n            options,\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toEqual(expected);\n  });\n\n  it(\"should return event.target.value if not file or checkbox\", () => {\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: undefined,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(undefined);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: undefined,\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(undefined);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: null,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(null);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: null,\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(null);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: true,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(true);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: true,\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(true);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: false,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(false);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: false,\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(false);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: 42,\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(42);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: 42,\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(42);\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: \"foo\",\n          },\n        },\n        undefined,\n        undefined,\n        true,\n      ),\n    ).toBe(\"foo\");\n    expect(\n      getValue(\n        {\n          preventDefault: noop,\n          stopPropagation: noop,\n          target: {\n            value: \"foo\",\n          },\n        },\n        undefined,\n        undefined,\n        false,\n      ),\n    ).toBe(\"foo\");\n  });\n});\n"
  },
  {
    "path": "src/getValue.ts",
    "content": "const getSelectedValues = (options: any) => {\n  const result = [];\n  if (options) {\n    for (let index = 0; index < options.length; index++) {\n      const option = options[index];\n      if (option.selected) {\n        result.push(option.value);\n      }\n    }\n  }\n  return result;\n};\n\nconst getValue = (\n  event: React.ChangeEvent<any>,\n  currentValue: any,\n  valueProp: any,\n  isReactNative: boolean,\n) => {\n  if (\n    !isReactNative &&\n    (event as any).nativeEvent &&\n    ((event as any).nativeEvent as any).text !== undefined\n  ) {\n    return ((event as any).nativeEvent as any).text;\n  }\n  if (isReactNative && (event as any).nativeEvent) {\n    return ((event as any).nativeEvent as any).text;\n  }\n  const detypedEvent: any = event;\n  const {\n    target: { type, value, checked },\n  } = detypedEvent;\n  switch (type) {\n    case \"checkbox\":\n      if (valueProp !== undefined) {\n        // we are maintaining an array, not just a boolean\n        if (checked) {\n          // add value to current array value\n          return Array.isArray(currentValue)\n            ? currentValue.concat(valueProp)\n            : [valueProp];\n        } else {\n          // remove value from current array value\n          if (!Array.isArray(currentValue)) {\n            return currentValue;\n          }\n          const index = currentValue.indexOf(valueProp);\n          if (index < 0) {\n            return currentValue;\n          } else {\n            return currentValue\n              .slice(0, index)\n              .concat(currentValue.slice(index + 1));\n          }\n        }\n      } else {\n        // it's just a boolean\n        return !!checked;\n      }\n    case \"select-multiple\":\n      return getSelectedValues((event.target as any).options);\n    default:\n      return value;\n  }\n};\n\nexport default getValue;\n"
  },
  {
    "path": "src/getters.ts",
    "content": "import type { FormState, FieldState } from \"final-form\";\n\nconst addLazyState = (\n  dest: Record<string, any>,\n  state: Record<string, any>,\n  keys: string[],\n): void => {\n  keys.forEach((key) => {\n    Object.defineProperty(dest, key, {\n      get: () => state[key],\n      enumerable: true,\n    });\n  });\n};\n\nexport const addLazyFormState = (\n  dest: Record<string, any>,\n  state: FormState<any>,\n): void =>\n  addLazyState(dest, state, [\n    \"active\",\n    \"dirty\",\n    \"dirtyFields\",\n    \"dirtySinceLastSubmit\",\n    \"dirtyFieldsSinceLastSubmit\",\n    \"error\",\n    \"errors\",\n    \"hasSubmitErrors\",\n    \"hasValidationErrors\",\n    \"initialValues\",\n    \"invalid\",\n    \"modified\",\n    \"modifiedSinceLastSubmit\",\n    \"pristine\",\n    \"submitError\",\n    \"submitErrors\",\n    \"submitFailed\",\n    \"submitSucceeded\",\n    \"submitting\",\n    \"touched\",\n    \"valid\",\n    \"validating\",\n    \"values\",\n    \"visited\",\n  ]);\n\nexport const addLazyFieldMetaState = (\n  dest: Record<string, any>,\n  state: FieldState<any>,\n): void =>\n  addLazyState(dest, state, [\n    \"active\",\n    \"data\",\n    \"dirty\",\n    \"dirtySinceLastSubmit\",\n    \"error\",\n    \"initial\",\n    \"invalid\",\n    \"length\",\n    \"modified\",\n    \"modifiedSinceLastSubmit\",\n    \"pristine\",\n    \"submitError\",\n    \"submitFailed\",\n    \"submitSucceeded\",\n    \"submitting\",\n    \"touched\",\n    \"valid\",\n    \"validating\",\n    \"visited\",\n  ]);\n"
  },
  {
    "path": "src/index.ts",
    "content": "import * as React from \"react\";\nimport Form from \"./ReactFinalForm\";\nimport FormSpy from \"./FormSpy\";\nexport { default as Field } from \"./Field\";\nexport { default as Form, version } from \"./ReactFinalForm\";\nexport { default as FormSpy } from \"./FormSpy\";\nexport { default as useField } from \"./useField\";\nexport { default as useFormState } from \"./useFormState\";\nexport { default as useForm } from \"./useForm\";\nexport function withTypes<FormValues = Record<string, any>>() {\n  return {\n    Form: Form as React.ComponentType<import(\"./types\").FormProps<FormValues>>,\n    FormSpy: FormSpy as React.ComponentType<\n      import(\"./types\").FormSpyProps<FormValues>\n    >,\n  };\n}\n\nexport * from \"./types\";\n"
  },
  {
    "path": "src/isReactNative.ts",
    "content": "const isReactNative: boolean = !!(\n  typeof window !== \"undefined\" &&\n  window.navigator &&\n  window.navigator.product &&\n  window.navigator.product === \"ReactNative\"\n);\n\nexport default isReactNative;\n"
  },
  {
    "path": "src/isSyntheticEvent.ts",
    "content": "const isSyntheticEvent = (candidate: any): boolean =>\n  !!(candidate && typeof candidate.stopPropagation === \"function\");\n\nexport default isSyntheticEvent;\n"
  },
  {
    "path": "src/renderComponent.test.js",
    "content": "import renderComponent from \"./renderComponent\";\n\ndescribe(\"renderComponent\", () => {\n  it(\"should pass both render and children prop\", () => {\n    const children = \"some children\";\n    const render = () => {};\n    const props = {\n      component: () => null,\n      children,\n      render,\n    };\n    const name = \"TestComponent\";\n    const result = renderComponent(props, {}, name);\n    expect(result.props).toEqual({ children, render });\n  });\n\n  it(\"should include children when rendering with render\", () => {\n    const children = \"some children\";\n    const render = jest.fn();\n    const props = {\n      children,\n      render,\n    };\n    const name = \"TestComponent\";\n    renderComponent(props, {}, name);\n    expect(render).toHaveBeenCalled();\n    expect(render).toHaveBeenCalledTimes(1);\n    expect(render.mock.calls[0][0].children).toBe(children);\n  });\n\n  it(\"should throw error if no render strategy is provided\", () => {\n    const children = \"some children\";\n    const props = {\n      children,\n    };\n    const name = \"TestComponent\";\n    expect(() => renderComponent(props, {}, name)).toThrow(\n      `Must specify either a render prop, a render function as children, or a component prop to ${name}`,\n    );\n  });\n\n  it(\"should not evaluate any of the keys given in the second argument\", () => {\n    const children = \"some children\";\n    const render = jest.fn();\n    const props = {\n      children,\n      render,\n    };\n    const getA = jest.fn();\n    const getB = jest.fn();\n    const name = \"TestComponent\";\n    renderComponent(\n      props,\n      {\n        get a() {\n          getA();\n          return 1;\n        },\n        get b() {\n          getB();\n          return 2;\n        },\n      },\n      name,\n    );\n    expect(render).toHaveBeenCalled();\n    expect(render).toHaveBeenCalledTimes(1);\n    expect(render.mock.calls[0][0].children).toBe(children);\n    expect(getA).not.toHaveBeenCalled();\n    expect(getB).not.toHaveBeenCalled();\n  });\n\n  it(\"should not overwrite getter-only properties when using component prop\", () => {\n    // This test reproduces issue #1055\n    // When lazyProps has getter-only properties (like 'active'), and props contains\n    // a property with the same name, it should not attempt to overwrite the getter\n    const Component = () => null;\n    const props = {\n      component: Component,\n      active: \"value-from-props\", // This would cause \"Cannot set property active\" error\n      customProp: \"custom\",\n    };\n    const lazyProps = {};\n    Object.defineProperty(lazyProps, \"active\", {\n      get: () => \"value-from-getter\",\n      enumerable: true,\n      // Note: no setter - this is getter-only\n    });\n    const name = \"TestComponent\";\n\n    // Should not throw \"Cannot set property active\"\n    let result;\n    expect(() => {\n      result = renderComponent(props, lazyProps, name);\n    }).not.toThrow();\n\n    // Check the React element was created with correct props\n    expect(result.type).toBe(Component);\n    \n    // The getter-only property should remain and use the getter value\n    expect(result.props.active).toBe(\"value-from-getter\");\n\n    // Custom props should still be passed through\n    expect(result.props.customProp).toBe(\"custom\");\n  });\n\n  it(\"should handle getter-only properties in all render paths\", () => {\n    const lazyProps = {};\n    Object.defineProperty(lazyProps, \"active\", {\n      get: () => \"getter-value\",\n      enumerable: true,\n    });\n\n    // Test with render prop\n    const render = jest.fn();\n    renderComponent(\n      { render, active: \"prop-value\" },\n      lazyProps,\n      \"TestComponent\",\n    );\n    expect(render).toHaveBeenCalled();\n    expect(render.mock.calls[0][0].active).toBe(\"getter-value\");\n\n    // Test with children function\n    const children = jest.fn();\n    renderComponent(\n      { children, active: \"prop-value\" },\n      lazyProps,\n      \"TestComponent\",\n    );\n    expect(children).toHaveBeenCalled();\n    expect(children.mock.calls[0][0].active).toBe(\"getter-value\");\n\n    // Test with component prop\n    const Component = () => null;\n    const result = renderComponent(\n      { component: Component, active: \"prop-value\" },\n      lazyProps,\n      \"TestComponent\",\n    );\n    expect(result.type).toBe(Component);\n    expect(result.props.active).toBe(\"getter-value\");\n  });\n});\n"
  },
  {
    "path": "src/renderComponent.ts",
    "content": "import * as React from \"react\";\nimport type { RenderableProps } from \"./types\";\n\n// shared logic between components that use either render prop,\n// children render function, or component prop\nexport default function renderComponent<T>(\n  props: RenderableProps<T> & Partial<T> & Record<string, any>,\n  lazyProps: Record<string, any>,\n  name: string,\n): React.ReactNode {\n  const { render, children, component, ...rest } = props;\n  if (component) {\n    // FIX: Don't use Object.assign which tries to overwrite getters\n    // Instead, create a new object with lazyProps descriptors first,\n    // then add non-conflicting properties from rest\n    const result = {} as any;\n    Object.defineProperties(result, Object.getOwnPropertyDescriptors(lazyProps));\n    const restDescriptors = Object.getOwnPropertyDescriptors(rest);\n    for (const key in restDescriptors) {\n      if (!(key in result)) {\n        Object.defineProperty(result, key, restDescriptors[key]);\n      }\n    }\n    result.children = children;\n    result.render = render;\n    return React.createElement(component, result);\n  }\n  if (render) {\n    const result = {} as T;\n    Object.defineProperties(\n      result,\n      Object.getOwnPropertyDescriptors(lazyProps),\n    );\n    // Only add properties from rest that don't already exist\n    const restDescriptors = Object.getOwnPropertyDescriptors(rest);\n    for (const key in restDescriptors) {\n      if (!(key in (result as any))) {\n        Object.defineProperty(result as any, key, restDescriptors[key]);\n      }\n    }\n    if (children !== undefined) {\n      (result as any).children = children;\n    }\n    return render(result);\n  }\n  if (typeof children !== \"function\") {\n    throw new Error(\n      `Must specify either a render prop, a render function as children, or a component prop to ${name}`,\n    );\n  }\n  const result = {} as T;\n  Object.defineProperties(result, Object.getOwnPropertyDescriptors(lazyProps));\n  // Only add properties from rest that don't already exist\n  const restDescriptors = Object.getOwnPropertyDescriptors(rest);\n  for (const key in restDescriptors) {\n    if (!(key in (result as any))) {\n      Object.defineProperty(result as any, key, restDescriptors[key]);\n    }\n  }\n  return children(result);\n}\n"
  },
  {
    "path": "src/shallowEqual.test.js",
    "content": "import shallowEqual from \"./shallowEqual\";\n\ndescribe(\"shallowEqual\", () => {\n  it(\"returns false if either argument is null\", () => {\n    expect(shallowEqual(null, {})).toBe(false);\n    expect(shallowEqual({}, null)).toBe(false);\n  });\n\n  it(\"returns true if both arguments are null or undefined\", () => {\n    expect(shallowEqual(null, null)).toBe(true);\n    expect(shallowEqual(undefined, undefined)).toBe(true);\n  });\n\n  it(\"returns true if arguments are shallow equal\", () => {\n    expect(shallowEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2, c: 3 })).toBe(true);\n  });\n\n  it(\"returns false if arguments are not objects and not equal\", () => {\n    expect(shallowEqual(1, 2)).toBe(false);\n  });\n\n  it(\"returns false if only one argument is not an object\", () => {\n    expect(shallowEqual(1, {})).toBe(false);\n  });\n\n  it(\"returns false if first argument has too many keys\", () => {\n    expect(shallowEqual({ a: 1, b: 2, c: 3 }, { a: 1, b: 2 })).toBe(false);\n  });\n\n  it(\"returns false if second argument has too many keys\", () => {\n    expect(shallowEqual({ a: 1, b: 2 }, { a: 1, b: 2, c: 3 })).toBe(false);\n  });\n\n  it(\"returns true if values are not primitives but are ===\", () => {\n    let obj = {};\n    expect(shallowEqual({ a: 1, b: 2, c: obj }, { a: 1, b: 2, c: obj })).toBe(\n      true,\n    );\n  });\n\n  it(\"returns false if arguments are not shallow equal\", () => {\n    expect(shallowEqual({ a: 1, b: 2, c: {} }, { a: 1, b: 2, c: {} })).toBe(\n      false,\n    );\n  });\n\n  it(\"should treat objects created by `Object.create(null)` like any other plain object\", () => {\n    function Foo() {\n      this.a = 1;\n    }\n    Foo.prototype.constructor = null;\n\n    const object2 = { a: 1 };\n    expect(shallowEqual(new Foo(), object2)).toBe(true);\n\n    const object1 = Object.create(null);\n    object1.a = 1;\n    expect(shallowEqual(object1, object2)).toBe(true);\n  });\n});\n"
  },
  {
    "path": "src/shallowEqual.ts",
    "content": "const shallowEqual = (a: any, b: any): boolean => {\n  if (a === b) {\n    return true;\n  }\n  if (typeof a !== \"object\" || !a || typeof b !== \"object\" || !b) {\n    return false;\n  }\n  var keysA = Object.keys(a);\n  var keysB = Object.keys(b);\n  if (keysA.length !== keysB.length) {\n    return false;\n  }\n  var bHasOwnProperty = Object.prototype.hasOwnProperty.bind(b);\n  for (var idx = 0; idx < keysA.length; idx++) {\n    var key = keysA[idx];\n    if (!bHasOwnProperty(key) || a[key] !== b[key]) {\n      return false;\n    }\n  }\n  return true;\n};\n\nexport default shallowEqual;\n"
  },
  {
    "path": "src/testUtils.ts",
    "content": "import React from \"react\";\n\nexport const wrapWith =\n  <T extends any[]>(mock: (...args: T) => void, fn: (...args: T) => any) =>\n  (...args: T) => {\n    mock(...args);\n    return fn(...args);\n  };\n\n/** A simple container component that allows boolean to be toggled with a button */\nexport function Toggle({\n  children,\n}: {\n  children: (on: boolean) => React.ReactNode;\n}) {\n  const [on, setOn] = React.useState(false);\n  return React.createElement(\n    \"div\",\n    null,\n    children(on),\n    React.createElement(\"button\", { onClick: () => setOn(!on) }, \"Toggle\"),\n  );\n}\n\ninterface ErrorBoundaryProps {\n  spy: (error: Error) => void;\n  children: React.ReactNode;\n}\n\nexport class ErrorBoundary extends React.Component<ErrorBoundaryProps> {\n  componentDidCatch(error: Error) {\n    this.props.spy(error);\n  }\n\n  render() {\n    return this.props.children;\n  }\n}\n"
  },
  {
    "path": "src/types.ts",
    "content": "import * as React from \"react\";\nimport type {\n  FormApi,\n  Config,\n  Decorator,\n  FormState,\n  FormSubscription,\n  FieldSubscription,\n  FieldValidator,\n} from \"final-form\";\n\ntype SupportedInputs = \"input\" | \"select\" | \"textarea\";\n\nexport interface ReactContext<FormValues = Record<string, any>> {\n  reactFinalForm: FormApi<FormValues>;\n}\n\nexport interface FieldInputProps<\n  FieldValue = any,\n  T = any,\n> {\n  name: string;\n  onBlur: (event?: React.FocusEvent<T>) => void;\n  onChange: (event: React.ChangeEvent<T> | any) => void;\n  onFocus: (event?: React.FocusEvent<T>) => void;\n  value: FieldValue;\n  checked?: boolean;\n  multiple?: boolean;\n  type?: string;\n}\n\nexport interface FieldRenderProps<\n  FieldValue = any,\n  T = any,\n  _FormValues = any,\n> {\n  input: FieldInputProps<FieldValue, T>;\n  meta: {\n    active?: boolean;\n    data?: Record<string, any>;\n    dirty?: boolean;\n    dirtySinceLastSubmit?: boolean;\n    error?: any;\n    initial?: any;\n    invalid?: boolean;\n    length?: number;\n    modified?: boolean;\n    modifiedSinceLastSubmit?: boolean;\n    pristine?: boolean;\n    submitError?: any;\n    submitFailed?: boolean;\n    submitSucceeded?: boolean;\n    submitting?: boolean;\n    touched?: boolean;\n    valid?: boolean;\n    validating?: boolean;\n    visited?: boolean;\n  };\n}\n\n// Re-export of FieldMetaState for backwards compatibility\n// (removed from original sources in v7.0.0 but re-exported here)\nexport type FieldMetaState<FieldValue = any> = FieldRenderProps<FieldValue>['meta'];\n\nexport interface SubmitEvent {\n  preventDefault?: () => void;\n  stopPropagation?: () => void;\n}\n\nexport interface FormRenderProps<FormValues = Record<string, any>>\n  extends FormState<FormValues> {\n  handleSubmit: (\n    event?: SubmitEvent,\n  ) => Promise<Record<string, any> | undefined> | undefined;\n  form: FormApi<FormValues>;\n}\n\nexport interface FormSpyRenderProps<FormValues = Record<string, any>>\n  extends FormState<FormValues> {\n  form: FormApi<FormValues>;\n}\n\nexport interface RenderableProps<T> {\n  component?: React.ComponentType<any> | SupportedInputs;\n  children?: ((props: T) => React.ReactNode) | React.ReactNode;\n  render?: (props: T) => React.ReactNode;\n}\n\nexport interface FormProps<FormValues = Record<string, any>>\n  extends Config<FormValues>,\n    RenderableProps<FormRenderProps<FormValues>> {\n  subscription?: FormSubscription;\n  decorators?: Decorator<FormValues>[];\n  form?: FormApi<FormValues>;\n  initialValuesEqual?: (\n    a?: Record<string, any>,\n    b?: Record<string, any>,\n  ) => boolean;\n  __versions?: Record<string, string>;\n}\n\nexport interface UseFieldAutoConfig {\n  afterSubmit?: () => void;\n  allowNull?: boolean;\n  beforeSubmit?: () => void | false;\n  component?: RenderableProps<any>[\"component\"];\n  data?: Record<string, any>;\n  defaultValue?: any;\n  format?: (value: any, name: string) => any;\n  formatOnBlur?: boolean;\n  initialValue?: any;\n  isEqual?: (a: any, b: any) => boolean;\n  multiple?: boolean;\n  parse?: (value: any, name: string) => any;\n  type?: string;\n  validate?: FieldValidator<any>;\n  validateFields?: string[];\n  value?: any;\n}\n\nexport interface UseFieldConfig extends UseFieldAutoConfig {\n  subscription?: FieldSubscription;\n}\n\nexport interface FieldProps<\n  FieldValue = any,\n  T = any,\n  _FormValues = Record<string, any>,\n> extends UseFieldConfig,\n    Omit<RenderableProps<FieldRenderProps<FieldValue, T>>, \"children\"> {\n  name: string;\n  children?: RenderableProps<FieldRenderProps<FieldValue, T>>[\"children\"];\n  input?: Partial<FieldInputProps<FieldValue, T>>; // Allow overriding input props\n  [key: string]: any; // Allow additional props for HTML elements\n}\n\nexport interface UseFormStateParams<FormValues = Record<string, any>> {\n  onChange?: (formState: FormState<FormValues>) => void;\n  subscription?: FormSubscription;\n}\n\nexport interface FormSpyProps<FormValues = Record<string, any>>\n  extends UseFormStateParams<FormValues>,\n    RenderableProps<FormSpyRenderProps<FormValues>> {}\n\nexport interface FormSpyPropsWithForm<FormValues = Record<string, any>>\n  extends FormSpyProps<FormValues> {\n  reactFinalForm: FormApi<FormValues>;\n}\n"
  },
  {
    "path": "src/useConstant.ts",
    "content": "import React from \"react\";\n\n/**\n * A simple hook to create a constant value that lives for\n * the lifetime of the component.\n *\n * Plagiarized from https://github.com/Andarist/use-constant\n *\n * Do NOT reuse this code unless you know what you're doing.\n * Use Andarist's hook; it's more fault tolerant to things like\n * falsy values.\n *\n * @param init - A function to generate the value\n */\nexport default function useConstant<T>(init: () => T): T {\n  const ref = React.useRef<T | undefined>(undefined);\n  if (!ref.current) {\n    ref.current = init();\n  }\n  return ref.current;\n}\n"
  },
  {
    "path": "src/useConstantCallback.test.js",
    "content": "import * as React from \"react\";\nimport { render, cleanup, act } from \"@testing-library/react\";\nimport \"@testing-library/jest-dom\";\nimport useConstantCallback from \"./useConstantCallback\";\n\ndescribe(\"useConstantCallback\", () => {\n  afterEach(cleanup);\n\n  it(\"should give the same instance on every render, even as params/deps change\", () => {\n    const callback = jest.fn();\n    const MyComponent = () => {\n      const [name, setName] = React.useState(\"John\");\n      const [age, setAge] = React.useState(20);\n      const [isAdmin, setAdmin] = React.useState(false);\n      const constantCallback = useConstantCallback((time) => {\n        expect(typeof time).toBe(\"number\");\n        callback(name, age, isAdmin);\n      });\n      const callbackRef = React.useRef(constantCallback);\n      expect(callbackRef.current).toBe(constantCallback);\n      return (\n        <div>\n          <button\n            data-testid=\"call\"\n            onClick={() => constantCallback(Date.now())}\n          >\n            Call\n          </button>\n          <button data-testid=\"changeName\" onClick={() => setName(\"Paul\")}>\n            {name}\n          </button>\n          <button data-testid=\"changeAge\" onClick={() => setAge(25)}>\n            {age}\n          </button>\n          <button data-testid=\"changeAdmin\" onClick={() => setAdmin(true)}>\n            {isAdmin ? \"Yes\" : \"No\"}\n          </button>\n        </div>\n      );\n    };\n    const { getByTestId } = render(<MyComponent />);\n    const call = getByTestId(\"call\");\n    const changeName = getByTestId(\"changeName\");\n    const changeAge = getByTestId(\"changeAge\");\n    const changeAdmin = getByTestId(\"changeAdmin\");\n\n    expect(changeName).toHaveTextContent(\"John\");\n    expect(changeAge).toHaveTextContent(20);\n    expect(changeAdmin).toHaveTextContent(\"No\");\n    expect(callback).not.toHaveBeenCalled();\n\n    call.click();\n\n    expect(callback).toHaveBeenCalled();\n    expect(callback).toHaveBeenCalledTimes(1);\n    expect(callback.mock.calls[0][0]).toBe(\"John\");\n    expect(callback.mock.calls[0][1]).toBe(20);\n    expect(callback.mock.calls[0][2]).toBe(false);\n    expect(changeName).toHaveTextContent(\"John\");\n    expect(changeAge).toHaveTextContent(20);\n    expect(changeAdmin).toHaveTextContent(\"No\");\n\n    act(() => {\n      changeName.click();\n    });\n\n    expect(callback).toHaveBeenCalledTimes(1);\n    expect(changeName).toHaveTextContent(\"Paul\");\n    expect(changeAge).toHaveTextContent(20);\n    expect(changeAdmin).toHaveTextContent(\"No\");\n\n    call.click();\n\n    expect(callback).toHaveBeenCalledTimes(2);\n    expect(callback.mock.calls[1][0]).toBe(\"Paul\");\n    expect(callback.mock.calls[1][1]).toBe(20);\n    expect(callback.mock.calls[1][2]).toBe(false);\n\n    act(() => {\n      changeAge.click();\n    });\n\n    expect(callback).toHaveBeenCalledTimes(2);\n    expect(changeName).toHaveTextContent(\"Paul\");\n    expect(changeAge).toHaveTextContent(25);\n    expect(changeAdmin).toHaveTextContent(\"No\");\n\n    call.click();\n\n    expect(callback).toHaveBeenCalledTimes(3);\n    expect(callback.mock.calls[2][0]).toBe(\"Paul\");\n    expect(callback.mock.calls[2][1]).toBe(25);\n    expect(callback.mock.calls[2][2]).toBe(false);\n\n    act(() => {\n      changeAdmin.click();\n    });\n\n    expect(callback).toHaveBeenCalledTimes(3);\n    expect(changeName).toHaveTextContent(\"Paul\");\n    expect(changeAge).toHaveTextContent(25);\n    expect(changeAdmin).toHaveTextContent(\"Yes\");\n\n    call.click();\n\n    expect(callback).toHaveBeenCalledTimes(4);\n    expect(callback.mock.calls[3][0]).toBe(\"Paul\");\n    expect(callback.mock.calls[3][1]).toBe(25);\n    expect(callback.mock.calls[3][2]).toBe(true);\n  });\n});\n"
  },
  {
    "path": "src/useConstantCallback.ts",
    "content": "import * as React from \"react\";\n\n/**\n * Creates a callback, even with closures, that will be\n * instance === for the lifetime of the component, always\n * calling the most recent version of the function and its\n * closures.\n */\nexport default function useConstantCallback<T extends (...args: any[]) => any>(\n  callback: T,\n): T {\n  const ref = React.useRef(callback);\n  React.useEffect(() => {\n    ref.current = callback;\n  });\n  return React.useCallback(\n    (...args: any[]) => ref.current.apply(null, args),\n    [],\n  ) as T;\n}\n"
  },
  {
    "path": "src/useField.dynamic-name-869.test.js",
    "content": "/**\n * @jest-environment jsdom\n */\n// Tests for dynamic Field name changes (issue #869).\n// Covers text inputs, checkboxes, and radio buttons.\nimport React from 'react'\nimport { render, cleanup, act } from '@testing-library/react'\nimport '@testing-library/jest-dom'\nimport Form from './ReactFinalForm'\nimport Field from './Field'\n\ndescribe('useField - Dynamic Name (Issue #869)', () => {\n  afterEach(cleanup)\n\n  it('should keep name and value in sync when field name changes', () => {\n    const renderSpy = jest.fn()\n    \n    const TestComponent = ({ fieldName }) => {\n      return (\n        <Form\n          onSubmit={() => {}}\n          initialValues={{ a: 'value-a', b: 'value-b' }}\n        >\n          {() => (\n            <Field name={fieldName}>\n              {({ input }) => {\n                // Log every render to track name/value sync\n                renderSpy(input.name, input.value)\n                return <input {...input} data-testid=\"field\" />\n              }}\n            </Field>\n          )}\n        </Form>\n      )\n    }\n\n    const { rerender } = render(<TestComponent fieldName=\"a\" />)\n    \n    // Initial render - field 'a'\n    expect(renderSpy).toHaveBeenCalledWith('a', 'value-a')\n    \n    renderSpy.mockClear()\n    \n    // Change field name from 'a' to 'b'\n    act(() => {\n      rerender(<TestComponent fieldName=\"b\" />)\n    })\n    \n    // Verify all renders after name change have name='b' and value='value-b'\n    const calls = renderSpy.mock.calls\n    \n    // Ensure Field actually rendered\n    expect(calls.length).toBeGreaterThan(0)\n    \n    // After rerender with fieldName=\"b\", ALL calls should be for field 'b'\n    calls.forEach(call => {\n      const [name, value] = call\n      expect(name).toBe('b')\n      expect(value).toBe('value-b')\n    })\n  })\n\n  it('should have correct value immediately after name change (no stale renders)', () => {\n    const TestComponent = ({ fieldName }) => {\n      return (\n        <Form\n          onSubmit={() => {}}\n          initialValues={{ a: 'value-a', b: 'value-b' }}\n        >\n          {() => (\n            <Field name={fieldName}>\n              {({ input }) => (\n                <div>\n                  <span data-testid=\"name\">{input.name}</span>\n                  <span data-testid=\"value\">{input.value}</span>\n                </div>\n              )}\n            </Field>\n          )}\n        </Form>\n      )\n    }\n\n    const { rerender, getByTestId } = render(<TestComponent fieldName=\"a\" />)\n    \n    expect(getByTestId('name')).toHaveTextContent('a')\n    expect(getByTestId('value')).toHaveTextContent('value-a')\n    \n    // Change field name\n    act(() => {\n      rerender(<TestComponent fieldName=\"b\" />)\n    })\n    \n    // Immediately after rerender, name and value should be in sync\n    expect(getByTestId('name')).toHaveTextContent('b')\n    expect(getByTestId('value')).toHaveTextContent('value-b')\n  })\n\n  it('should keep name and checked in sync when checkbox field name changes', () => {\n    const renderSpy = jest.fn()\n    \n    const TestComponent = ({ fieldName }) => {\n      return (\n        <Form\n          onSubmit={() => {}}\n          initialValues={{ a: true, b: false }}\n        >\n          {() => (\n            <Field name={fieldName} type=\"checkbox\">\n              {({ input }) => {\n                // Log every render to track name/checked sync\n                renderSpy(input.name, input.checked)\n                return <input {...input} data-testid=\"field\" />\n              }}\n            </Field>\n          )}\n        </Form>\n      )\n    }\n\n    const { rerender } = render(<TestComponent fieldName=\"a\" />)\n    \n    // Initial render - field 'a' checked\n    expect(renderSpy).toHaveBeenCalledWith('a', true)\n    \n    renderSpy.mockClear()\n    \n    // Change field name from 'a' to 'b'\n    act(() => {\n      rerender(<TestComponent fieldName=\"b\" />)\n    })\n    \n    // Verify all renders after name change have name='b' and checked=false\n    const calls = renderSpy.mock.calls\n    \n    // Ensure Field actually rendered\n    expect(calls.length).toBeGreaterThan(0)\n    \n    // After rerender with fieldName=\"b\", ALL calls should be for field 'b'\n    calls.forEach(call => {\n      const [name, checked] = call\n      expect(name).toBe('b')\n      expect(checked).toBe(false)\n    })\n  })\n\n  it('should have correct checked immediately after checkbox name change', () => {\n    const TestComponent = ({ fieldName }) => {\n      return (\n        <Form\n          onSubmit={() => {}}\n          initialValues={{ a: true, b: false }}\n        >\n          {() => (\n            <Field name={fieldName} type=\"checkbox\">\n              {({ input }) => (\n                <div>\n                  <span data-testid=\"name\">{input.name}</span>\n                  <span data-testid=\"checked\">{String(input.checked)}</span>\n                </div>\n              )}\n            </Field>\n          )}\n        </Form>\n      )\n    }\n\n    const { rerender, getByTestId } = render(<TestComponent fieldName=\"a\" />)\n    \n    expect(getByTestId('name')).toHaveTextContent('a')\n    expect(getByTestId('checked')).toHaveTextContent('true')\n    \n    // Change field name\n    act(() => {\n      rerender(<TestComponent fieldName=\"b\" />)\n    })\n    \n    // Immediately after rerender, name and checked should be in sync\n    expect(getByTestId('name')).toHaveTextContent('b')\n    expect(getByTestId('checked')).toHaveTextContent('false')\n  })\n\n  it('should keep name and checked in sync when radio field name changes', () => {\n    const renderSpy = jest.fn()\n    \n    const TestComponent = ({ fieldName }) => {\n      return (\n        <Form\n          onSubmit={() => {}}\n          initialValues={{ a: 'option1', b: 'option2' }}\n        >\n          {() => (\n            <Field name={fieldName} type=\"radio\" value=\"option2\">\n              {({ input }) => {\n                // Log every render to track name/checked sync\n                renderSpy(input.name, input.checked)\n                return <input {...input} data-testid=\"field\" />\n              }}\n            </Field>\n          )}\n        </Form>\n      )\n    }\n\n    const { rerender } = render(<TestComponent fieldName=\"a\" />)\n    \n    // Initial render - field 'a' has value 'option1', not checked for 'option2'\n    expect(renderSpy).toHaveBeenCalledWith('a', false)\n    \n    renderSpy.mockClear()\n    \n    // Change field name from 'a' to 'b'\n    act(() => {\n      rerender(<TestComponent fieldName=\"b\" />)\n    })\n    \n    // Verify all renders after name change have name='b' and checked=true\n    const calls = renderSpy.mock.calls\n    \n    // Ensure Field actually rendered\n    expect(calls.length).toBeGreaterThan(0)\n    \n    // After rerender with fieldName=\"b\", ALL calls should be for field 'b'\n    // Field 'b' has value 'option2', so radio with value=\"option2\" should be checked\n    calls.forEach(call => {\n      const [name, checked] = call\n      expect(name).toBe('b')\n      expect(checked).toBe(true)\n    })\n  })\n\n  it('should have correct checked immediately after radio name change', () => {\n    const TestComponent = ({ fieldName }) => {\n      return (\n        <Form\n          onSubmit={() => {}}\n          initialValues={{ a: 'option1', b: 'option2' }}\n        >\n          {() => (\n            <Field name={fieldName} type=\"radio\" value=\"option2\">\n              {({ input }) => (\n                <div>\n                  <span data-testid=\"name\">{input.name}</span>\n                  <span data-testid=\"checked\">{String(input.checked)}</span>\n                </div>\n              )}\n            </Field>\n          )}\n        </Form>\n      )\n    }\n\n    const { rerender, getByTestId } = render(<TestComponent fieldName=\"a\" />)\n    \n    expect(getByTestId('name')).toHaveTextContent('a')\n    expect(getByTestId('checked')).toHaveTextContent('false')\n    \n    // Change field name\n    act(() => {\n      rerender(<TestComponent fieldName=\"b\" />)\n    })\n    \n    // Immediately after rerender, name and checked should be in sync\n    expect(getByTestId('name')).toHaveTextContent('b')\n    expect(getByTestId('checked')).toHaveTextContent('true')\n  })\n})\n"
  },
  {
    "path": "src/useField.test.js",
    "content": "import * as React from \"react\";\nimport { render, fireEvent, cleanup } from \"@testing-library/react\";\nimport \"@testing-library/jest-dom\";\nimport { ErrorBoundary } from \"./testUtils\";\nimport Form from \"./ReactFinalForm\";\nimport Field from \"./Field\";\nimport { useField } from \"./index\";\nimport { act } from \"react\";\n\nconst onSubmitMock = (_values) => {};\n\ndescribe(\"useField\", () => {\n  afterEach(cleanup);\n\n  // Most of the functionality of useField is tested in Field.test.js\n  // This file is only for testing its use as a hook in other components\n\n  it(\"should warn if not used inside a form\", () => {\n    jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const errorSpy = jest.fn();\n    const MyFieldComponent = () => {\n      useField(\"name\");\n      return <div />;\n    };\n    render(\n      <ErrorBoundary spy={errorSpy}>\n        <MyFieldComponent />\n      </ErrorBoundary>,\n    );\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0].message).toBe(\n      \"useField must be used inside of a <Form> component\",\n    );\n    console.error.mockRestore();\n  });\n\n  it(\"should subscribe to all by default\", () => {\n    const MyFieldListener = () => {\n      const { input, meta } = useField(\"name\");\n      expect(meta.active).toBe(false);\n      expect(meta.data).toEqual({});\n      expect(meta.dirty).toBe(false);\n      expect(meta.dirtySinceLastSubmit).toBe(false);\n      expect(meta.error).toBeUndefined();\n      expect(meta.initial).toBeUndefined();\n      expect(meta.invalid).toBe(false);\n      expect(meta.length).toBeUndefined();\n      expect(meta.modified).toBe(false);\n      expect(meta.modifiedSinceLastSubmit).toBe(false);\n      expect(meta.pristine).toBe(true);\n      expect(meta.submitError).toBeUndefined();\n      expect(meta.submitFailed).toBe(false);\n      expect(meta.submitSucceeded).toBe(false);\n      expect(meta.submitting).toBe(false);\n      expect(meta.touched).toBe(false);\n      expect(meta.valid).toBe(true);\n      expect(meta.validating).toBe(false);\n      expect(meta.visited).toBe(false);\n      expect(input.value).toBe(\"\");\n      return null;\n    };\n    render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <MyFieldListener />\n          </form>\n        )}\n      </Form>,\n    );\n  });\n\n  it(\"should track field state\", () => {\n    const spy = jest.fn();\n    const MyFieldListener = () => {\n      spy(useField(\"name\").input.value);\n      return null;\n    };\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <MyFieldListener />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    // All forms without restricted subscriptions render twice at first because they\n    // need to update their validation and touched/modified/visited maps every time\n    // new fields are registered.\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[0][0]).toBe(\"\");\n    expect(spy.mock.calls[1][0]).toBe(\"\");\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    expect(getByTestId(\"name\").value).toBe(\"erikras\");\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0]).toBe(\"erikras\");\n  });\n\n  it(\"should allow for creation of render-controlled components\", () => {\n    const spy = jest.fn();\n    const MemoizedDirtyDisplay = React.memo(({ dirty }) => {\n      spy(dirty);\n      return <div data-testid=\"dirty\">{dirty ? \"Dirty\" : \"Pristine\"}</div>;\n    });\n    const MyFieldListener = () => {\n      const field = useField(\"name\", { subscription: { dirty: true } });\n      return <MemoizedDirtyDisplay dirty={field.meta.dirty} />;\n    };\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <Field name=\"name\" component=\"input\" data-testid=\"name\" />\n            <MyFieldListener />\n          </form>\n        )}\n      </Form>,\n    );\n    expect(getByTestId(\"name\").value).toBe(\"\");\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Pristine\");\n    expect(spy).toHaveBeenCalledTimes(1);\n    expect(spy.mock.calls[0][0]).toBe(false);\n    // simulate typing\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"e\" } });\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Dirty\");\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0]).toBe(true);\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"er\" } });\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"eri\" } });\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erik\" } });\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikr\" } });\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikra\" } });\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"erikras\" } });\n    // dirty flag hasn't changed since the first character\n    expect(spy).toHaveBeenCalledTimes(2);\n    // make pristine again\n    fireEvent.change(getByTestId(\"name\"), { target: { value: \"\" } });\n    expect(getByTestId(\"dirty\")).toHaveTextContent(\"Pristine\");\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0]).toBe(false);\n  });\n\n  it(\"should give same instance of handlers as value changes\", () => {\n    const spy = jest.fn();\n    const MyField = ({ name }) => {\n      const { input } = useField(name, { subscription: { value: true } });\n      const { onChange, onFocus, onBlur } = input;\n      spy(onChange, onFocus, onBlur);\n      return <input {...input} />;\n    };\n    render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0]).toBe(spy.mock.calls[0][0]); // onChange\n    expect(spy.mock.calls[1][1]).toBe(spy.mock.calls[0][1]); // onFocus\n    expect(spy.mock.calls[1][2]).toBe(spy.mock.calls[0][2]); // onBlur\n\n    const [onChange, onFocus, onBlur] = spy.mock.calls[0];\n    const setValue = (value) => {\n      act(() => {\n        onFocus();\n        onChange(value);\n        onBlur();\n      });\n    };\n\n    setValue(\"dog\");\n    expect(spy).toHaveBeenCalledTimes(3);\n    expect(spy.mock.calls[2][0]).toBe(spy.mock.calls[1][0]); // onChange\n    expect(spy.mock.calls[2][1]).toBe(spy.mock.calls[1][1]); // onFocus\n    expect(spy.mock.calls[2][2]).toBe(spy.mock.calls[1][2]); // onBlur\n\n    setValue(\"cat\");\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[2][0]); // onChange\n    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[2][1]); // onFocus\n    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[2][2]); // onBlur\n  });\n\n  it(\"should give same instance of handlers as name changes\", () => {\n    const spy = jest.fn();\n    const MyField = ({ name }) => {\n      const { input } = useField(name, { subscription: { value: true } });\n      const { onChange, onFocus, onBlur } = input;\n      spy(onChange, onFocus, onBlur);\n      return <input {...input} />;\n    };\n    const { rerender } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0]).toBe(spy.mock.calls[0][0]); // onChange\n    expect(spy.mock.calls[1][1]).toBe(spy.mock.calls[0][1]); // onFocus\n    expect(spy.mock.calls[1][2]).toBe(spy.mock.calls[0][2]); // onBlur\n\n    rerender(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <MyField name=\"dog\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[2][0]).toBe(spy.mock.calls[1][0]); // onChange\n    expect(spy.mock.calls[2][1]).toBe(spy.mock.calls[1][1]); // onFocus\n    expect(spy.mock.calls[2][2]).toBe(spy.mock.calls[1][2]); // onBlur\n    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[2][0]); // onChange\n    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[2][1]); // onFocus\n    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[2][2]); // onBlur\n  });\n\n  it(\"should give same instance of handlers as type changes\", () => {\n    const spy = jest.fn();\n    const MyField = ({ name, type }) => {\n      const { input } = useField(name, { subscription: { value: true }, type });\n      const { onChange, onFocus, onBlur } = input;\n      spy(onChange, onFocus, onBlur);\n      return <input {...input} />;\n    };\n    const { rerender } = render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0]).toBe(spy.mock.calls[0][0]); // onChange\n    expect(spy.mock.calls[1][1]).toBe(spy.mock.calls[0][1]); // onFocus\n    expect(spy.mock.calls[1][2]).toBe(spy.mock.calls[0][2]); // onBlur\n\n    rerender(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <MyField name=\"dog\" type=\"search\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[2][0]).toBe(spy.mock.calls[1][0]); // onChange\n    expect(spy.mock.calls[2][1]).toBe(spy.mock.calls[1][1]); // onFocus\n    expect(spy.mock.calls[2][2]).toBe(spy.mock.calls[1][2]); // onBlur\n    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[2][0]); // onChange\n    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[2][1]); // onFocus\n    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[2][2]); // onBlur\n  });\n\n  it(\"should give same instance of handlers as formatOnBlur changes\", () => {\n    const spy = jest.fn();\n    const MyField = ({ name, formatOnBlur }) => {\n      const { input } = useField(name, {\n        subscription: { value: true },\n        formatOnBlur,\n        defaultValue: \"\",\n      });\n      const { onChange, onFocus, onBlur } = input;\n      spy(onChange, onFocus, onBlur);\n      return <input {...input} value={input.value || \"\"} />;\n    };\n    const { rerender } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"\", dog: \"\" }}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0]).toBe(spy.mock.calls[0][0]); // onChange\n    expect(spy.mock.calls[1][1]).toBe(spy.mock.calls[0][1]); // onFocus\n    expect(spy.mock.calls[1][2]).toBe(spy.mock.calls[0][2]); // onBlur\n\n    rerender(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"\", dog: \"\" }}>\n        {() => (\n          <form>\n            <MyField name=\"dog\" formatOnBlur />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[2][0]).toBe(spy.mock.calls[1][0]); // onChange\n    expect(spy.mock.calls[2][1]).toBe(spy.mock.calls[1][1]); // onFocus\n    expect(spy.mock.calls[2][2]).toBe(spy.mock.calls[1][2]); // onBlur\n    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[2][0]); // onChange\n    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[2][1]); // onFocus\n    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[2][2]); // onBlur\n  });\n\n  it(\"should give same instance of handlers as parse changes\", () => {\n    const spy = jest.fn();\n    const MyField = ({ name, parse }) => {\n      const { input } = useField(name, {\n        subscription: { value: true },\n        parse,\n        defaultValue: \"\",\n      });\n      const { onChange, onFocus, onBlur } = input;\n      spy(onChange, onFocus, onBlur);\n      return <input {...input} value={input.value || \"\"} />;\n    };\n    const { rerender } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"\", dog: \"\" }}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0]).toBe(spy.mock.calls[0][0]); // onChange\n    expect(spy.mock.calls[1][1]).toBe(spy.mock.calls[0][1]); // onFocus\n    expect(spy.mock.calls[1][2]).toBe(spy.mock.calls[0][2]); // onBlur\n\n    rerender(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"\", dog: \"\" }}>\n        {() => (\n          <form>\n            <MyField name=\"dog\" parse={(x) => x} />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[2][0]).toBe(spy.mock.calls[1][0]); // onChange\n    expect(spy.mock.calls[2][1]).toBe(spy.mock.calls[1][1]); // onFocus\n    expect(spy.mock.calls[2][2]).toBe(spy.mock.calls[1][2]); // onBlur\n    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[2][0]); // onChange\n    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[2][1]); // onFocus\n    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[2][2]); // onBlur\n  });\n\n  it(\"should give same instance of handlers as format changes\", () => {\n    const spy = jest.fn();\n    const MyField = ({ name, format }) => {\n      const { input } = useField(name, {\n        subscription: { value: true },\n        format,\n        defaultValue: \"\",\n      });\n      const { onChange, onFocus, onBlur } = input;\n      spy(onChange, onFocus, onBlur);\n      return <input {...input} value={input.value || \"\"} />;\n    };\n    const { rerender } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"\", dog: \"\" }}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0]).toBe(spy.mock.calls[0][0]); // onChange\n    expect(spy.mock.calls[1][1]).toBe(spy.mock.calls[0][1]); // onFocus\n    expect(spy.mock.calls[1][2]).toBe(spy.mock.calls[0][2]); // onBlur\n\n    rerender(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"\", dog: \"\" }}>\n        {() => (\n          <form>\n            <MyField name=\"dog\" format={(x) => x} />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[2][0]).toBe(spy.mock.calls[1][0]); // onChange\n    expect(spy.mock.calls[2][1]).toBe(spy.mock.calls[1][1]); // onFocus\n    expect(spy.mock.calls[2][2]).toBe(spy.mock.calls[1][2]); // onBlur\n    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[2][0]); // onChange\n    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[2][1]); // onFocus\n    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[2][2]); // onBlur\n  });\n\n  it(\"should give same instance of handlers as component changes\", () => {\n    const spy = jest.fn();\n    const MyField = ({ name, component }) => {\n      const { input } = useField(name, {\n        subscription: { value: true },\n        component,\n        defaultValue: \"\",\n      });\n      const { onChange, onFocus, onBlur } = input;\n      spy(onChange, onFocus, onBlur);\n      return <input {...input} value={input.value || \"\"} />;\n    };\n    const { rerender } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"\", dog: \"\" }}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(2);\n    expect(spy.mock.calls[1][0]).toBe(spy.mock.calls[0][0]); // onChange\n    expect(spy.mock.calls[1][1]).toBe(spy.mock.calls[0][1]); // onFocus\n    expect(spy.mock.calls[1][2]).toBe(spy.mock.calls[0][2]); // onBlur\n\n    rerender(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"\", dog: \"\" }}>\n        {() => (\n          <form>\n            <MyField name=\"dog\" component=\"select\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    expect(spy).toHaveBeenCalledTimes(4);\n    expect(spy.mock.calls[2][0]).toBe(spy.mock.calls[1][0]); // onChange\n    expect(spy.mock.calls[2][1]).toBe(spy.mock.calls[1][1]); // onFocus\n    expect(spy.mock.calls[2][2]).toBe(spy.mock.calls[1][2]); // onBlur\n    expect(spy.mock.calls[3][0]).toBe(spy.mock.calls[2][0]); // onChange\n    expect(spy.mock.calls[3][1]).toBe(spy.mock.calls[2][1]); // onFocus\n    expect(spy.mock.calls[3][2]).toBe(spy.mock.calls[2][2]); // onBlur\n  });\n\n  it(\"should handle null values correctly with allowNull\", () => {\n    const spy = jest.fn();\n    const MyField = ({ name }) => {\n      const { input } = useField(name, {\n        subscription: { value: true },\n        allowNull: true,\n      });\n      spy(input.value);\n      // Convert null to empty string for the input element to avoid React warnings\n      return (\n        <input {...input} value={input.value === null ? \"\" : input.value} />\n      );\n    };\n    const { rerender } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: null }}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    // Change to non-null value\n    rerender(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: \"test\" }}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    // Change back to null\n    rerender(\n      <Form onSubmit={onSubmitMock} initialValues={{ myField: null }}>\n        {() => (\n          <form>\n            <MyField name=\"myField\" />\n          </form>\n        )}\n      </Form>,\n    );\n\n    const calls = spy.mock.calls.map((call) => call[0]);\n    expect(calls).toContain(null); // At least one call with null\n    expect(calls).toContain(\"test\"); // At least one call with 'test'\n    expect(calls[calls.length - 1]).toBe(null); // Last call is null\n  });\n\n  it(\"should return Form initialValues on first render (fix #1050)\", () => {\n    const renderSpy = jest.fn();\n    const MyField = () => {\n      const { input } = useField(\"username\");\n      renderSpy(input.value);\n      return <input {...input} data-testid=\"username\" />;\n    };\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ username: \"erikras\" }}>\n        {() => (\n          <form>\n            <MyField />\n          </form>\n        )}\n      </Form>,\n    );\n    // Critical: on the FIRST render, value should be \"erikras\" not undefined\n    expect(renderSpy.mock.calls[0][0]).toBe(\"erikras\");\n    expect(getByTestId(\"username\").value).toBe(\"erikras\");\n  });\n\n  it(\"should use field initialValue when Form initialValues doesn't have that field (fix #1050)\", () => {\n    const renderSpy = jest.fn();\n    const MyField = () => {\n      const { input } = useField(\"username\", { initialValue: \"fieldLevel\" });\n      renderSpy(input.value);\n      return <input {...input} data-testid=\"username\" />;\n    };\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock} initialValues={{ other: \"value\" }}>\n        {() => (\n          <form>\n            <MyField />\n          </form>\n        )}\n      </Form>,\n    );\n    // Field-level initialValue should be used as fallback\n    expect(renderSpy.mock.calls[0][0]).toBe(\"fieldLevel\");\n    expect(getByTestId(\"username\").value).toBe(\"fieldLevel\");\n  });\n\n  it(\"should handle nested field paths in Form initialValues (fix #1050)\", () => {\n    const renderSpy = jest.fn();\n    const MyField = () => {\n      const { input } = useField(\"user.name\");\n      renderSpy(input.value);\n      return <input {...input} data-testid=\"nested\" />;\n    };\n    const { getByTestId } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        initialValues={{ user: { name: \"erikras\" } }}\n      >\n        {() => (\n          <form>\n            <MyField />\n          </form>\n        )}\n      </Form>,\n    );\n    // Should correctly resolve nested path on first render\n    expect(renderSpy.mock.calls[0][0]).toBe(\"erikras\");\n    expect(getByTestId(\"nested\").value).toBe(\"erikras\");\n  });\n\n  it(\"should handle array field paths in Form initialValues (fix #1050)\", () => {\n    const renderSpy = jest.fn();\n    const MyField = () => {\n      const { input } = useField(\"items[0].name\");\n      renderSpy(input.value);\n      return <input {...input} data-testid=\"array\" />;\n    };\n    const { getByTestId } = render(\n      <Form\n        onSubmit={onSubmitMock}\n        initialValues={{ items: [{ name: \"Apple\" }] }}\n      >\n        {() => (\n          <form>\n            <MyField />\n          </form>\n        )}\n      </Form>,\n    );\n    // Should correctly resolve array path on first render\n    expect(renderSpy.mock.calls[0][0]).toBe(\"Apple\");\n    expect(getByTestId(\"array\").value).toBe(\"Apple\");\n  });\n\n  it(\"should default undefined value to [] for select multiple with type prop (fix react-final-form-arrays #185)\", () => {\n    const renderSpy = jest.fn();\n    const MySelectField = () => {\n      const { input } = useField(\"scopes\", { type: \"select\", multiple: true });\n      renderSpy(input.value);\n      return (\n        <select {...input} multiple data-testid=\"select\">\n          <option value=\"read\">Read</option>\n          <option value=\"write\">Write</option>\n        </select>\n      );\n    };\n    render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <MySelectField />\n          </form>\n        )}\n      </Form>,\n    );\n    // When no initial value is provided, should default to [] not undefined\n    // This prevents React warning: \"The `value` prop supplied to <select> must be an array if `multiple` is true\"\n    expect(renderSpy.mock.calls[0][0]).toEqual([]);\n  });\n\n  it(\"should default undefined value to [] for select multiple with component prop\", () => {\n    const renderSpy = jest.fn();\n    const MySelectField = () => {\n      const { input } = useField(\"scopes\", { component: \"select\", multiple: true });\n      renderSpy(input.value);\n      return (\n        <select {...input} multiple data-testid=\"select\">\n          <option value=\"read\">Read</option>\n          <option value=\"write\">Write</option>\n        </select>\n      );\n    };\n    render(\n      <Form onSubmit={onSubmitMock}>\n        {() => (\n          <form>\n            <MySelectField />\n          </form>\n        )}\n      </Form>,\n    );\n    // When no initial value is provided, should default to [] not undefined\n    // This prevents React warning: \"The `value` prop supplied to <select> must be an array if `multiple` is true\"\n    expect(renderSpy.mock.calls[0][0]).toEqual([]);\n  });\n\n  it(\"should ensure select multiple value is always an array\", () => {\n    const renderSpy = jest.fn();\n    const MySelectField = () => {\n      const { input } = useField(\"scopes\", { type: \"select\", multiple: true });\n      renderSpy(input.value);\n      return (\n        <select {...input} multiple data-testid=\"select\">\n          <option value=\"read\">Read</option>\n          <option value=\"write\">Write</option>\n        </select>\n      );\n    };\n    render(\n      <Form onSubmit={onSubmitMock} initialValues={{ scopes: null }}>\n        {() => (\n          <form>\n            <MySelectField />\n          </form>\n        )}\n      </Form>,\n    );\n    // Even if the form value is null/undefined, input.value should be []\n    expect(Array.isArray(renderSpy.mock.calls[0][0])).toBe(true);\n  });\n});\n"
  },
  {
    "path": "src/useField.ts",
    "content": "import * as React from \"react\";\nimport { fieldSubscriptionItems, getIn } from \"final-form\";\nimport type { FieldSubscription, FieldState, FormApi } from \"final-form\";\nimport type {\n  UseFieldConfig,\n  FieldInputProps,\n  FieldRenderProps,\n} from \"./types\";\nimport isReactNative from \"./isReactNative\";\nimport getValue from \"./getValue\";\nimport useForm from \"./useForm\";\nimport useLatest from \"./useLatest\";\nimport { addLazyFieldMetaState } from \"./getters\";\nimport useConstantCallback from \"./useConstantCallback\";\nimport shallowEqual from \"./shallowEqual\";\n\nconst all: FieldSubscription = fieldSubscriptionItems.reduce(\n  (result: any, key) => {\n    result[key] = true;\n    return result;\n  },\n  {},\n);\n\nconst defaultFormat = (value: any, _name: string) =>\n  value === undefined ? \"\" : value;\nconst defaultParse = (value: any, _name: string) =>\n  value === \"\" ? undefined : value;\n\nfunction useField<\n  FieldValue = any,\n  T extends HTMLElement = HTMLElement,\n  FormValues = Record<string, any>,\n>(name: string, config: UseFieldConfig = {}): FieldRenderProps<FieldValue, T> {\n  const {\n    afterSubmit,\n    allowNull,\n    component,\n    data,\n    defaultValue,\n    format = defaultFormat,\n    formatOnBlur,\n    initialValue,\n    multiple,\n    parse = defaultParse,\n    subscription = all,\n    type,\n    validateFields,\n    value: _value,\n  } = config;\n  const form: FormApi<FormValues> = useForm<FormValues>(\"useField\");\n\n  const configRef = useLatest(config);\n\n  const register = (\n    callback: (state: FieldState<any>) => void,\n    silent: boolean,\n  ) =>\n    // avoid using `state` const in any closures created inside `register`\n    // because they would refer `state` from current execution context\n    // whereas actual `state` would defined in the subsequent `useField` hook\n    // execution\n    // (that would be caused by `setState` call performed in `register` callback)\n    form.registerField(name as keyof FormValues, callback, subscription, {\n      afterSubmit,\n      beforeSubmit: () => {\n        const {\n          beforeSubmit,\n          formatOnBlur,\n          format = defaultFormat,\n        } = configRef.current;\n\n        if (formatOnBlur) {\n          const fieldState = form.getFieldState(name as keyof FormValues);\n          if (fieldState) {\n            const { value } = fieldState;\n            const formatted = format(value, name);\n\n            if (formatted !== value) {\n              form.change(name as keyof FormValues, formatted);\n            }\n          }\n        }\n\n        return beforeSubmit && beforeSubmit();\n      },\n      data,\n      defaultValue,\n      getValidator: () => configRef.current.validate,\n      initialValue,\n      isEqual: configRef.current.isEqual,\n      silent,\n      validateFields,\n    });\n\n  // Initialize state with proper field state from Final Form without callbacks\n  const [state, setState] = React.useState<FieldState<any>>(() => {\n    // Get the current field state from Final Form without registering callbacks\n    const existingFieldState = form.getFieldState(name as keyof FormValues);\n\n    if (existingFieldState) {\n      // If allowNull is true and the initial value was null, preserve it\n      // (and its formatted version is not null, meaning it was formatted away)\n      if (allowNull && existingFieldState.initial === null && existingFieldState.value !== null) {\n        return {\n          ...existingFieldState,\n          value: null,   // Force value back to null\n          initial: null, // Ensure our local state's 'initial' also reflects this\n        };\n      }\n      return existingFieldState;\n    }\n\n    // FIX #1050: Check Form initialValues before falling back to field initialValue\n    // If no existing state, create a proper initial state\n    const formState = form.getState();\n    // Use getIn to support nested field paths like \"user.name\" or \"items[0].id\"\n    const formInitialValue = formState.initialValues ? getIn(formState.initialValues, name) : undefined;\n    \n    // Use Form initialValues if available, otherwise use field initialValue\n    let initialStateValue = formInitialValue !== undefined ? formInitialValue : initialValue;\n    \n    if ((component === \"select\" || type === \"select\") && multiple && initialStateValue === undefined) {\n      initialStateValue = [];\n    }\n\n    return {\n      active: false,\n      blur: () => { },\n      change: () => { },\n      data: data || {},\n      dirty: false,\n      dirtySinceLastSubmit: false,\n      error: undefined,\n      focus: () => { },\n      initial: initialStateValue,\n      invalid: false,\n      length: undefined,\n      modified: false,\n      modifiedSinceLastSubmit: false,\n      name,\n      pristine: true,\n      submitError: undefined,\n      submitFailed: false,\n      submitSucceeded: false,\n      submitting: false,\n      touched: false,\n      valid: true,\n      validating: false,\n      value: initialStateValue,\n      visited: false,\n    };\n  });\n\n  React.useEffect(() => {\n    // Check if field state exists in the form before registering\n    const existingFieldState = form.getFieldState(name as keyof FormValues);\n    \n    // If field doesn't exist in form state, it means the field was destroyed \n    // (e.g., by destroyOnUnregister in StrictMode). In this case, we need to \n    // explicitly set the value before registering to ensure the initial value \n    // is applied, even if form thinks initialValues haven't changed.\n    if (!existingFieldState) {\n      const formState = form.getState();\n      const formInitialValue = formState.initialValues ? getIn(formState.initialValues, name) : undefined;\n      const valueToSet = formInitialValue !== undefined ? formInitialValue : initialValue;\n      if (valueToSet !== undefined) {\n        form.change(name as keyof FormValues, valueToSet);\n      }\n    }\n\n    // Register field after the initial render to avoid setState during render\n    const unregister = register((newState) => {\n      setState((prevState) => {\n        // Only update if the state actually changed\n        if (!shallowEqual(newState, prevState)) {\n          return newState;\n        }\n        return prevState;\n      });\n    }, false);\n\n    return unregister;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, [name, data, defaultValue, initialValue]);\n\n  const meta: any = {};\n  addLazyFieldMetaState(meta, state);\n  const getInputValue = () => {\n    // Fix #869: If name changed but state hasn't updated yet (effect hasn't run),\n    // get the value directly from form values to avoid returning stale value\n    let value = state.name !== name\n      ? getIn(form.getState().values, name)\n      : state.value;\n\n    // Handle null values first\n    if (value === null && !allowNull) {\n      value = \"\";\n    }\n\n    if (formatOnBlur) {\n      if (component === \"input\") {\n        value = defaultFormat(value, name);\n      }\n    } else {\n      // Only format if value is not null when allowNull is true\n      if (!(allowNull && value === null)) {\n        value = format(value, name);\n      }\n    }\n\n    if ((component === \"select\" || type === \"select\") && multiple) {\n      return Array.isArray(value) ? value : [];\n    }\n    // For checkboxes and radios, the `value` prop on the input element itself\n    // is not the array of selected values or the single selected radio value,\n    // but rather the specific value this input represents if selected.\n    // The `checked` prop handles the actual selection state.\n    // So, for `input.value`, we should return `_value` if provided (for individual inputs in a group)\n    // or the formatted field value otherwise (for standalone inputs).\n    if ((type === \"checkbox\" || type === \"radio\") && _value !== undefined) {\n      return _value;\n    }\n    return value;\n  };\n\n  const getInputChecked = () => {\n    // Fix #869: Same as getInputValue - sync with current name\n    let value = state.name !== name\n      ? getIn(form.getState().values, name)\n      : state.value;\n    if (type === \"checkbox\") {\n      value = parse(value, name);\n      if (_value === undefined) {\n        return !!value;\n      } else {\n        return !!(Array.isArray(value) && ~value.indexOf(_value));\n      }\n    } else if (type === \"radio\") {\n      return parse(value, name) === _value;\n    }\n    return undefined;\n  };\n\n  const input: FieldInputProps<FieldValue, T> = {\n    name,\n    onBlur: useConstantCallback((_event?: React.FocusEvent<any>) => {\n      state.blur();\n      if (formatOnBlur) {\n        /**\n         * Here we must fetch the value directly from Final Form because we cannot\n         * trust that our `state` closure has the most recent value. This is a problem\n         * if-and-only-if the library consumer has called `onChange()` immediately\n         * before calling `onBlur()`, but before the field has had a chance to receive\n         * the value update from Final Form.\n         */\n        const fieldState = form.getFieldState(state.name as keyof FormValues);\n        if (fieldState) {\n          state.change(format(fieldState.value, state.name));\n        }\n      }\n    }),\n    onChange: useConstantCallback((event: React.ChangeEvent<any> | any) => {\n      // istanbul ignore next\n      if (process.env.NODE_ENV !== \"production\" && event && event.target) {\n        const targetType = event.target.type;\n        const unknown =\n          ~[\"checkbox\", \"radio\", \"select-multiple\"].indexOf(targetType) &&\n          !type &&\n          component !== \"select\";\n\n        const value: any =\n          targetType === \"select-multiple\" ? state.value : _value;\n\n        if (unknown) {\n          console.error(\n            `You must pass \\`type=\"${targetType === \"select-multiple\" ? \"select\" : targetType\n            }\"\\` prop to your Field(${name}) component.\\n` +\n            `Without it we don't know how to unpack your \\`value\\` prop - ${Array.isArray(value) ? `[${value}]` : `\"${value}\"`\n            }.`,\n          );\n        }\n      }\n\n      const value: any =\n        event && event.target\n          ? getValue(event, state.value, _value, isReactNative)\n          : event;\n      state.change(parse(value, name));\n    }),\n    onFocus: useConstantCallback((_event?: React.FocusEvent<any>) =>\n      state.focus(),\n    ),\n    get value() {\n      return getInputValue();\n    },\n    get checked() {\n      return getInputChecked();\n    },\n  };\n\n  if (multiple) {\n    input.multiple = multiple;\n  }\n  if (type !== undefined) {\n    input.type = type;\n  }\n\n  const renderProps: FieldRenderProps<FieldValue, T> = { input, meta }; // assign to force type check\n  return renderProps;\n}\n\nexport default useField;\n"
  },
  {
    "path": "src/useForm.test.js",
    "content": "import React from \"react\";\nimport { render, cleanup } from \"@testing-library/react\";\nimport \"@testing-library/jest-dom\";\nimport { ErrorBoundary } from \"./testUtils\";\nimport Form from \"./ReactFinalForm\";\nimport { useForm } from \"./index\";\n\nconst onSubmitMock = (values) => {};\n\ndescribe(\"useForm\", () => {\n  afterEach(cleanup);\n\n  it(\"should warn if not used inside a form\", () => {\n    jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const errorSpy = jest.fn();\n    const MyFormConsumer = () => {\n      useForm();\n      return <div />;\n    };\n    render(\n      <ErrorBoundary spy={errorSpy}>\n        <MyFormConsumer />\n      </ErrorBoundary>,\n    );\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0].message).toBe(\n      \"useForm must be used inside of a <Form> component\",\n    );\n    console.error.mockRestore();\n  });\n\n  it(\"should warn with component name if not used inside a form\", () => {\n    jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const errorSpy = jest.fn();\n    const MyFormConsumer = () => {\n      useForm(\"MyFormConsumer\");\n      return <div />;\n    };\n    render(\n      <ErrorBoundary spy={errorSpy}>\n        <MyFormConsumer />\n      </ErrorBoundary>,\n    );\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0].message).toBe(\n      \"MyFormConsumer must be used inside of a <Form> component\",\n    );\n    console.error.mockRestore();\n  });\n\n  it(\"should produce form if used inside <Form>\", () => {\n    const MyFormConsumer = () => {\n      const form = useForm();\n      expect(form).toBeDefined();\n      expect(typeof form.change).toBe(\"function\");\n      expect(typeof form.reset).toBe(\"function\");\n      return (\n        <div data-testid=\"formCheck\">{form ? \"Got a form!\" : \"No form!\"}</div>\n      );\n    };\n    const { getByTestId } = render(\n      <Form onSubmit={onSubmitMock}>{() => <MyFormConsumer />}</Form>,\n    );\n    expect(getByTestId(\"formCheck\")).toHaveTextContent(\"Got a form!\");\n  });\n});\n"
  },
  {
    "path": "src/useForm.ts",
    "content": "import * as React from \"react\";\nimport type { FormApi } from \"final-form\";\nimport ReactFinalFormContext from \"./context\";\n\nfunction useForm<FormValues = Record<string, any>>(\n  componentName?: string,\n): FormApi<FormValues> {\n  const form: FormApi<FormValues> | undefined = React.useContext(\n    ReactFinalFormContext,\n  );\n  if (!form) {\n    throw new Error(\n      `${componentName || \"useForm\"} must be used inside of a <Form> component`,\n    );\n  }\n  return form;\n}\n\nexport default useForm;\n"
  },
  {
    "path": "src/useFormState.test.js",
    "content": "import React from \"react\";\nimport { render, cleanup } from \"@testing-library/react\";\nimport { ErrorBoundary } from \"./testUtils\";\nimport { useFormState, Form } from \"./index\";\n\ndescribe(\"useField\", () => {\n  afterEach(cleanup);\n\n  // Most of the functionality of useFormState is tested in FormSpy.test.js\n  // This file is only for testing its use as a hook in other components\n\n  it(\"should warn if not used inside a form\", () => {\n    jest.spyOn(console, \"error\").mockImplementation(() => {});\n    const errorSpy = jest.fn();\n    const MyFormStateComponent = () => {\n      useFormState();\n      return <div />;\n    };\n    render(\n      <ErrorBoundary spy={errorSpy}>\n        <MyFormStateComponent />\n      </ErrorBoundary>,\n    );\n    expect(errorSpy).toHaveBeenCalled();\n    expect(errorSpy).toHaveBeenCalledTimes(1);\n    expect(errorSpy.mock.calls[0][0].message).toBe(\n      \"useFormState must be used inside of a <Form> component\",\n    );\n    console.error.mockRestore();\n  });\n\n  it(\"state should be enumerable\", () => {\n    const Test = () => {\n      const state = useFormState();\n      expect(Object.keys(state).length > 0).toBe(true);\n      return <div>It worked</div>;\n    };\n    render(\n      <Form onSubmit={() => {}}>\n        {({ handleSubmit }) => (\n          <form onSubmit={handleSubmit}>\n            <Test />\n          </form>\n        )}\n      </Form>,\n    );\n  });\n});\n"
  },
  {
    "path": "src/useFormState.ts",
    "content": "import * as React from \"react\";\nimport type { UseFormStateParams } from \"./types\";\nimport type { FormState, FormApi } from \"final-form\";\nimport { all } from \"./ReactFinalForm\";\nimport useForm from \"./useForm\";\nimport { addLazyFormState } from \"./getters\";\nimport shallowEqual from \"./shallowEqual\";\n\nfunction useFormState<FormValues = Record<string, any>>({\n  onChange,\n  subscription = all,\n}: UseFormStateParams<FormValues> = {}): FormState<FormValues> {\n  const form: FormApi<FormValues> = useForm<FormValues>(\"useFormState\");\n  const onChangeRef = React.useRef(onChange);\n  onChangeRef.current = onChange;\n\n  // Initialize with current form state WITHOUT triggering callbacks during render.\n  // We intentionally use getState() here so render-prop consumers (e.g. <FormSpy>{...})\n  // can read a fully-populated initial state on first render.\n  const [state, setState] = React.useState<FormState<FormValues>>(() =>\n    form.getState(),\n  );\n\n  // We want `onChange` to be called AFTER render (fixes #809) and only with the\n  // subscription-filtered state.\n  const firstSubscriptionRef = React.useRef(true);\n  const pendingOnChangeRef = React.useRef<FormState<FormValues> | null>(null);\n  const lastOnChangeRef = React.useRef<FormState<FormValues> | null>(null);\n\n  React.useEffect(() => {\n    const unsubscribe = form.subscribe((newState) => {\n      // Ensure we set state at least once from the subscription, even if equal,\n      // so that `onChange` can be fired from an effect after the first render.\n      const isFirst = firstSubscriptionRef.current;\n      if (isFirst) {\n        firstSubscriptionRef.current = false;\n      }\n\n      pendingOnChangeRef.current = newState;\n\n      setState((prevState) => {\n        if (isFirst || !shallowEqual(newState, prevState)) {\n          return newState;\n        }\n        return prevState;\n      });\n    }, subscription);\n\n    return unsubscribe;\n    // eslint-disable-next-line react-hooks/exhaustive-deps\n  }, []);\n\n  React.useEffect(() => {\n    const pending = pendingOnChangeRef.current;\n    if (!pending || !onChangeRef.current) {\n      return;\n    }\n\n    // Only fire when the subscription has produced a new state and it differs\n    // from what we've already emitted.\n    if (lastOnChangeRef.current === null || !shallowEqual(pending, lastOnChangeRef.current)) {\n      onChangeRef.current(pending);\n      lastOnChangeRef.current = pending;\n    }\n\n    // Clear pending once we've handled it.\n    pendingOnChangeRef.current = null;\n  }, [state]);\n\n  const lazyState = {};\n  addLazyFormState(lazyState, state);\n  return lazyState as FormState<FormValues>;\n}\n\nexport default useFormState;\n"
  },
  {
    "path": "src/useLatest.ts",
    "content": "import React from \"react\";\n\nexport default function useLatest<T>(value: T): { readonly current: T } {\n  const ref = React.useRef(value);\n\n  React.useEffect(() => {\n    ref.current = value;\n  });\n\n  return ref;\n}\n"
  },
  {
    "path": "src/useWhenValueChanges.ts",
    "content": "import React from \"react\";\n\nexport default function useWhenValueChanges(\n  value: any,\n  callback: () => void,\n  isEqual: (a: any, b: any) => boolean = (a, b) => a === b,\n) {\n  const previous = React.useRef(value);\n  React.useEffect(() => {\n    if (!isEqual(value, previous.current)) {\n      callback();\n      previous.current = value;\n    }\n  });\n}\n"
  },
  {
    "path": "tsconfig.build.json",
    "content": "{\n  \"extends\": \"./tsconfig.json\",\n  \"compilerOptions\": {\n    \"noEmit\": false,\n    \"declaration\": true,\n    \"emitDeclarationOnly\": true,\n    \"outDir\": \"dist\",\n    \"declarationDir\": \"dist\",\n    \"rootDir\": \"src\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\", \"dist\", \"**/*.test.*\", \"examples\"]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es5\",\n    \"lib\": [\"dom\", \"dom.iterable\", \"es6\"],\n    \"allowJs\": true,\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"strict\": true,\n    \"forceConsistentCasingInFileNames\": true,\n    \"module\": \"esnext\",\n    \"moduleResolution\": \"node\",\n    \"resolveJsonModule\": true,\n    \"isolatedModules\": true,\n    \"noEmit\": true,\n    \"jsx\": \"react-jsx\",\n    \"declaration\": true,\n    \"outDir\": \"dist\",\n    \"declarationDir\": \"dist\"\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\", \"dist\", \"**/*.test.*\", \"examples\"]\n}\n"
  },
  {
    "path": "tslint.json",
    "content": "{\n  \"defaultSeverity\": \"error\",\n  \"extends\": [\"tslint:recommended\"],\n  \"jsRules\": {},\n  \"rules\": {\n    \"arrow-parens\": false,\n    \"interface-name\": [true, \"never-prefix\"],\n    \"no-empty\": [true, \"allow-empty-functions\"],\n    \"no-empty-interface\": false,\n    \"quotemark\": [true, \"single\", \"jsx-double\"],\n    \"trailing-comma\": [true, { \"multiline\": \"never\", \"singleline\": \"never\" }]\n  },\n  \"rulesDirectory\": []\n}\n"
  },
  {
    "path": "typescript/Field.test.tsx",
    "content": "import * as React from \"react\";\nimport { Field, FieldRenderProps } from \"react-final-form\";\n\nconst NumberInput: React.FC<{ value?: number }> = () => null;\n\nfunction FormText1({ input }: FieldRenderProps<string, HTMLInputElement>) {\n  // renders OK because of the used generic\n  return <input type=\"text\" {...input} />;\n}\n\n// FormText2 removed - was testing expected type error\n\nfunction FieldNumberValue() {\n  return (\n    <Field<number> name=\"numberField\">\n      {({ input }: FieldRenderProps<number>) => (\n        <NumberInput value={input.value} />\n      )}\n    </Field>\n  );\n}\n\nfunction FieldNumberInputValue() {\n  return (\n    <Field<number, HTMLElement, number>\n      name=\"numberField\"\n      parse={(value: number) => value}\n    >\n      {({ input }: FieldRenderProps<number>) => (\n        <NumberInput value={input.value} />\n      )}\n    </Field>\n  );\n}\n"
  },
  {
    "path": "typescript/FormSpy.test.tsx",
    "content": "import * as React from \"react\";\nimport { FormSpy, FormSpyRenderProps } from \"react-final-form\";\n\nfunction submitButtonSpy() {\n  return (\n    <FormSpy subscription={{ pristine: true, submitting: true, valid: true }}>\n      {({ pristine, submitting, valid }: FormSpyRenderProps) => {\n        return (\n          <button type=\"submit\" disabled={submitting || pristine || !valid}>\n            Submit\n          </button>\n        );\n      }}\n    </FormSpy>\n  );\n}\n"
  },
  {
    "path": "typescript/ReactFinalForm.test.tsx",
    "content": "/* tslint:disable: no-shadowed-variable */\n\nimport { Decorator, Mutator } from \"final-form\";\nimport * as React from \"react\";\nimport { Field, Form, FormRenderProps } from \"react-final-form\";\n\nconst noop = () => {};\n// missing required props\nconst C1 = () => {\n  return <Form onSubmit={noop} />;\n};\n\n// provided required props\nconst C2 = () => <Form onSubmit={noop} />;\n\nconst onSubmit = async (values: any) => {\n  // tslint:disable-next-line no-console\n  console.log(values);\n};\n\n// basic\nfunction basic() {\n  return (\n    <Form onSubmit={onSubmit}>\n      {({ handleSubmit }: FormRenderProps) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n            />\n          </div>\n        </form>\n      )}\n    </Form>\n  );\n}\n\n// simple\nfunction simple() {\n  return (\n    <Form onSubmit={onSubmit}>\n      {({\n        handleSubmit,\n        form,\n        submitting,\n        pristine,\n        values,\n      }: FormRenderProps) => (\n        <form onSubmit={handleSubmit}>\n          <Field\n            name=\"firstName\"\n            component=\"input\"\n            type=\"text\"\n            placeholder=\"First Name\"\n          />\n          <button\n            type=\"button\"\n            onClick={form.reset}\n            disabled={submitting || pristine}\n          >\n            Reset\n          </button>\n          <button type=\"submit\" disabled={submitting || pristine}>\n            Submit\n          </button>\n          <pre>{JSON.stringify(values)}</pre>\n        </form>\n      )}\n    </Form>\n  );\n}\n\nfunction simpleSubscription() {\n  return (\n    <Form\n      onSubmit={onSubmit}\n      subscription={{\n        pristine: true,\n        submitting: true,\n        values: true,\n      }}\n    >\n      {({\n        handleSubmit,\n        form,\n        submitting,\n        pristine,\n        values,\n      }: FormRenderProps) => (\n        <form onSubmit={handleSubmit}>\n          <button\n            type=\"button\"\n            onClick={form.reset}\n            disabled={submitting || pristine}\n          >\n            Reset\n          </button>\n          <pre>{JSON.stringify(values)}</pre>\n        </form>\n      )}\n    </Form>\n  );\n}\n\nconst setValue: Mutator = ([name, newValue], state, { changeValue }) => {\n  changeValue(state, name, (value) => newValue);\n};\n\nfunction mutated() {\n  return (\n    <Form onSubmit={onSubmit} mutators={{ setValue }}>\n      {({\n        handleSubmit,\n        form: {\n          mutators: { setValue },\n        },\n        submitting,\n        pristine,\n        values,\n      }: FormRenderProps) => (\n        <form onSubmit={handleSubmit}>\n          <Field\n            name=\"firstName\"\n            component=\"input\"\n            type=\"text\"\n            placeholder=\"First Name\"\n          />\n          <button\n            type=\"button\"\n            onClick={(e) => setValue(\"firstName\", \"Kevin\")}\n            disabled={submitting || pristine}\n          >\n            Reset\n          </button>\n          <pre>{JSON.stringify(values)}</pre>\n        </form>\n      )}\n    </Form>\n  );\n}\n\ninterface UserForm {\n  firstName: string;\n  lastName: string;\n}\n\nconst typedOnSubmit = (values: UserForm) => {\n  // tslint:disable-next-line no-console\n  console.log(values);\n};\n\n// with typed form data and field\nfunction withTypedFormData() {\n  return (\n    <Form<UserForm> onSubmit={typedOnSubmit}>\n      {({ handleSubmit }: FormRenderProps<UserForm>) => (\n        <form onSubmit={handleSubmit}>\n          <div>\n            <label>First Name</label>\n            <Field<string>\n              name=\"firstName\"\n              component=\"input\"\n              type=\"text\"\n              placeholder=\"First Name\"\n              initialValue=\"\"\n            />\n          </div>\n        </form>\n      )}\n    </Form>\n  );\n}\n\nconst decorator: Decorator<UserForm> = (form) => {\n  return form.subscribe(({ values }) => values?.firstName, {\n    values: true,\n  });\n};\n\n// with typed decorator\nfunction withTypedDecorator() {\n  return <Form<UserForm> decorators={[decorator]} onSubmit={typedOnSubmit} />;\n}\n\n// withWrongTypedDecorator removed - was testing expected type error\n"
  },
  {
    "path": "typescript/index.d.ts",
    "content": "import * as React from \"react\";\nimport {\n  FormApi,\n  Config,\n  Decorator,\n  FormState,\n  FormSubscription,\n  FieldSubscription,\n  FieldValidator,\n} from \"final-form\";\n\ntype SupportedInputs = \"input\" | \"select\" | \"textarea\";\n\nexport interface ReactContext<FormValues = Record<string, any>> {\n  reactFinalForm: FormApi<FormValues>;\n}\n\nexport interface FieldInputProps<\n  FieldValue = any,\n  T = any,\n> {\n  name: string;\n  onBlur: (event?: React.FocusEvent<T>) => void;\n  onChange: (event: React.ChangeEvent<T> | any) => void;\n  onFocus: (event?: React.FocusEvent<T>) => void;\n  value: FieldValue;\n  checked?: boolean;\n  multiple?: boolean;\n  type?: string;\n}\n\nexport interface FieldRenderProps<\n  FieldValue = any,\n  T = any,\n  _FormValues = any,\n> {\n  input: FieldInputProps<FieldValue, T>;\n  meta: {\n    active?: boolean;\n    data?: Record<string, any>;\n    dirty?: boolean;\n    dirtySinceLastSubmit?: boolean;\n    error?: any;\n    initial?: any;\n    invalid?: boolean;\n    length?: number;\n    modified?: boolean;\n    modifiedSinceLastSubmit?: boolean;\n    pristine?: boolean;\n    submitError?: any;\n    submitFailed?: boolean;\n    submitSucceeded?: boolean;\n    submitting?: boolean;\n    touched?: boolean;\n    valid?: boolean;\n    validating?: boolean;\n    visited?: boolean;\n  };\n}\n\n// Re-export of FieldMetaState for backwards compatibility\n// (removed from original sources in v7.0.0 but re-exported here)\nexport type FieldMetaState<FieldValue = any> = FieldRenderProps<FieldValue>['meta'];\n\nexport interface SubmitEvent {\n  preventDefault?: () => void;\n  stopPropagation?: () => void;\n}\n\nexport interface FormRenderProps<FormValues = Record<string, any>>\n  extends FormState<FormValues> {\n  handleSubmit: (\n    event?: SubmitEvent,\n  ) => Promise<Record<string, any> | undefined> | undefined;\n  form: FormApi<FormValues>;\n}\n\nexport interface FormSpyRenderProps<FormValues = Record<string, any>>\n  extends FormState<FormValues> {\n  form: FormApi<FormValues>;\n}\n\nexport interface RenderableProps<T> {\n  component?: React.ComponentType<any> | SupportedInputs;\n  children?: ((props: T) => React.ReactNode) | React.ReactNode;\n  render?: (props: T) => React.ReactNode;\n}\n\nexport interface FormProps<FormValues = Record<string, any>>\n  extends Config<FormValues>,\n    RenderableProps<FormRenderProps<FormValues>> {\n  subscription?: FormSubscription;\n  decorators?: Decorator<FormValues>[];\n  form?: FormApi<FormValues>;\n  initialValuesEqual?: (\n    a?: Record<string, any>,\n    b?: Record<string, any>,\n  ) => boolean;\n}\n\nexport interface UseFieldAutoConfig {\n  afterSubmit?: () => void;\n  allowNull?: boolean;\n  beforeSubmit?: () => void | false;\n  component?: RenderableProps<any>[\"component\"];\n  data?: Record<string, any>;\n  defaultValue?: any;\n  format?: (value: any, name: string) => any;\n  formatOnBlur?: boolean;\n  initialValue?: any;\n  isEqual?: (a: any, b: any) => boolean;\n  multiple?: boolean;\n  parse?: (value: any, name: string) => any;\n  type?: string;\n  validate?: FieldValidator<any>;\n  validateFields?: string[];\n  value?: any;\n}\n\nexport interface UseFieldConfig extends UseFieldAutoConfig {\n  subscription?: FieldSubscription;\n}\n\nexport interface FieldProps<\n  FieldValue = any,\n  T = any,\n  _FormValues = Record<string, any>,\n> extends UseFieldConfig,\n    Omit<RenderableProps<FieldRenderProps<FieldValue, T>>, \"children\"> {\n  name: string;\n  children?: RenderableProps<FieldRenderProps<FieldValue, T>>[\"children\"];\n  input?: Partial<FieldInputProps<FieldValue, T>>;\n  [key: string]: any;\n}\n\nexport interface UseFormStateParams<FormValues = Record<string, any>> {\n  onChange?: (formState: FormState<FormValues>) => void;\n  subscription?: FormSubscription;\n}\n\nexport interface FormSpyProps<FormValues = Record<string, any>>\n  extends UseFormStateParams<FormValues>,\n    RenderableProps<FormSpyRenderProps<FormValues>> {}\n\nexport interface FormSpyPropsWithForm<FormValues = Record<string, any>>\n  extends FormSpyProps<FormValues> {\n  reactFinalForm: FormApi<FormValues>;\n}\n\nexport const Field: <\n  FieldValue = any,\n  T = any,\n  FormValues = Record<string, any>,\n>(\n  props: FieldProps<FieldValue, T, FormValues>,\n) => React.ReactElement;\n\nexport const Form: <FormValues = Record<string, any>>(\n  props: FormProps<FormValues>,\n) => React.ReactElement;\n\nexport const FormSpy: <FormValues = Record<string, any>>(\n  props: FormSpyProps<FormValues>,\n) => React.ReactElement;\n\nexport function useField<\n  FieldValue = any,\n  T = any,\n  FormValues = Record<string, any>,\n>(\n  name: string,\n  config?: UseFieldConfig,\n): FieldRenderProps<FieldValue, T, FormValues>;\n\nexport function useForm<FormValues = Record<string, any>>(\n  componentName?: string,\n): FormApi<FormValues>;\n\nexport function useFormState<FormValues = Record<string, any>>(\n  params?: UseFormStateParams<FormValues>,\n): FormState<FormValues>;\n\nexport function withTypes<FormValues = Record<string, any>>(): {\n  Form: React.FC<FormProps<FormValues>>;\n  FormSpy: React.FC<FormSpyProps<FormValues>>;\n};\n\nexport const version: string;\n"
  },
  {
    "path": "typescript/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"lib\": [\"es2015\", \"dom\"],\n    \"jsx\": \"react\",\n    \"module\": \"esnext\",\n    \"baseUrl\": \".\",\n    \"noEmit\": true,\n    \"strict\": true,\n    \"moduleResolution\": \"bundler\",\n    \"paths\": {\n      \"react-final-form\": [\"../dist/index.d.ts\"]\n    }\n  },\n  \"include\": [\".\"]\n}\n"
  },
  {
    "path": "typescript/useField.test.tsx",
    "content": "import * as React from \"react\";\nimport { useField, FieldRenderProps } from \"react-final-form\";\n\nconst NumberInput: React.FC<{ value?: number }> = () => null;\n\nfunction NumberFieldValue() {\n  const { input } = useField<number>(\"numberField\");\n  return <NumberInput value={input.value} />;\n}\n\nfunction NumberInputValue() {\n  const { input } = useField(\"numberField\", {\n    format: (value: string) => Number(value),\n    parse: (value: number) => String(value),\n  });\n  return <NumberInput value={input.value} />;\n}\n\nfunction MyComponent() {\n  const field: FieldRenderProps = useField(\"myField\");\n  return <input {...field.input} />;\n}\n\nfunction MyTypedComponent() {\n  const field: FieldRenderProps<string> = useField<string>(\"myField\");\n  return <input {...field.input} />;\n}\n\nfunction MyTypedComponentWithElement() {\n  const field: FieldRenderProps<string, HTMLInputElement> = useField<\n    string,\n    HTMLInputElement\n  >(\"myField\");\n  return <input {...field.input} />;\n}\n"
  },
  {
    "path": "typescript/useFormState.test.tsx",
    "content": "import { useFormState } from \"react-final-form\";\nimport { FormState } from \"final-form\";\n\nconst submittingToLabel = (submitting: boolean) => (submitting ? \"Yes\" : \"No\");\n\nfunction Comp1() {\n  const { submitting } = useFormState();\n  return submittingToLabel(submitting || false);\n}\n\nfunction MyComponent() {\n  const formState: FormState = useFormState();\n  return null;\n}\n\nfunction MyTypedComponent() {\n  const formState: FormState<{ name: string }> = useFormState<{\n    name: string;\n  }>();\n  return null;\n}\n"
  }
]