{"id":26668487,"url":"https://github.com/dgonz64/react-hook-form-auto","last_synced_at":"2025-10-19T19:42:14.165Z","repository":{"id":35162502,"uuid":"214866872","full_name":"dgonz64/react-hook-form-auto","owner":"dgonz64","description":"Automatic form generation using ReactHookForm","archived":false,"fork":false,"pushed_at":"2024-06-01T11:10:05.000Z","size":2715,"stargazers_count":60,"open_issues_count":4,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-12T01:07:59.272Z","etag":null,"topics":["automatic","form","react","react-hooks"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dgonz64.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-13T17:53:36.000Z","updated_at":"2024-09-13T23:19:14.000Z","dependencies_parsed_at":"2024-06-18T21:36:57.861Z","dependency_job_id":null,"html_url":"https://github.com/dgonz64/react-hook-form-auto","commit_stats":{"total_commits":186,"total_committers":4,"mean_commits":46.5,"dds":"0.053763440860215006","last_synced_commit":"f80ac0611d54dd56b55f2e0d5b2aab5fe864da8c"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonz64%2Freact-hook-form-auto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonz64%2Freact-hook-form-auto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonz64%2Freact-hook-form-auto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dgonz64%2Freact-hook-form-auto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dgonz64","download_url":"https://codeload.github.com/dgonz64/react-hook-form-auto/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248501863,"owners_count":21114683,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automatic","form","react","react-hooks"],"created_at":"2025-03-25T20:47:35.519Z","updated_at":"2025-10-19T19:42:09.118Z","avatar_url":"https://github.com/dgonz64.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/dgonz64/react-hook-form-auto.svg?branch=master)](https://travis-ci.org/dgonz64/react-hook-form-auto)\n\nThis library allows your React application to automatically generate forms using [ReactHookForm](https://react-hook-form.com/). The form and validations are generated following a schema inspired by [SimpleSchema](https://github.com/aldeed/simple-schema-js).\n\n## New in 1.3.0\n\nNow works with React Hook Form 7 🎉\n\nAll the members of the family, like `rhfa-react-native` are updated too. You can update the corresponding one and it should work. If not, please open an issue.\n\nThe exception is if you made a skin for your project, then you should follow [this guide](docs/migrate-1.2-to-1.3.md).\n\n## Contents\n\n* [Installation](#installation)\n* [Usage](#usage)\n  * [1. Write schema](#1-write-schema)\n  * [2. Render a form](#2-render-a-form)\n  * [3. Make it prettier](#3-make-it-prettier)\n  * [4. Translate labels](#4-translate)\n* [Available skins](#available-skins)\n* [Roadmap](#roadmap)\n* [Documentation](#documentation)\n  * [Types](#types)\n    * [Select and radios](#select-and-radios)\n  * [Validators](#validators)\n    * [`validate` validator](#the-validate-validator)\n  * [Other schema fields](#other-schema-fields)\n    * [Schema onChange](docs/schema-onchange.md)\n  * [Schema](#schema)\n  * [`Autoform` component](#autoform-component)\n  * [Config](#config)\n  * [Field props override](#field-props-override)\n  * [Coercers](#coercers)\n  * [Forcing errors](#forcing-errors)\n  * [Imperative handling](#imperative-handling)\n  * [Translation](#translation)\n    * [`tr()`](#tr)\n    * [`stringExists()`](#stringexists)\n    * [Variable substitution](#variable-substitution)\n    * [Adding strings](#adding-strings)\n    * [Multilanguage](#multilanguage)\n    * [Translation utils](#translation-utils)\n    * [Use your own](#use-your-own-translation-system)\n  * [Extending](#extending)\n    * [Extending tutorial](https://github.com/dgonz64/rhfa-playground)\n    * [With styles](#with-styles)\n    * [Overriding skin](#overriding-skin)\n      * [`coerce`](#coerce)\n      * [`props`](#props)\n        * [object](#props-is-an-object)\n        * [function](#props-is-a-function)\n        * [`onChange`, `onBlur`](#onchange-and-onblur-in-props)\n          * [Directly](#use-it-directly-recommended)\n          * [`setValue`](#use-setvalue)\n      * [Other skin attributes](#other-skin-block-attributes)\n      * [`skin[type].props`](#skintypeprops)\n      * [`skin[type].component`](#skintypecomponent-or-skintypepropscomponent)\n  * [Importing base](#importing-base)\n\n## Play with the demos\n\n* [Emergency styles](https://codesandbox.io/s/rhfa-emergency-6upsj?file=/src/App.js)\n* [Bootstrap 4](https://codesandbox.io/s/rhfa-bootstrap-ttbfw?file=/src/App.js)\n* [Material-UI](https://codesandbox.io/s/rhfa-material-ui-k9pe9?file=/src/App.js)\n* [Blueprint](https://codesandbox.io/s/rhfa-blueprint-l4773?file=/src/App.js)\n\n### Full webpack project demos\n\n* [Play with the bootstrap4 demo](https://dgonz64.github.io/react-hook-form-auto-demo-bootstrap4/demo/). [Project](https://github.com/dgonz64/react-hook-form-auto-demo-bootstrap4).\n* [Play with emergency styles demo](https://dgonz64.github.io/react-hook-form-auto-demo/demo). [Project](https://github.com/dgonz64/react-hook-form-auto-demo).\n* [Play with Material-UI demo](https://dgonz64.github.io/rhfa-demo-material-ui/demo/). [Project](https://github.com/dgonz64/rhfa-demo-material-ui)\n* [React Native](https://github.com/dgonz64/rhfa-demo-react-native)\n\n## Installation\n\n    $ npm install react-hook-form react-hook-form-auto --save\n\n## Version deprecations\n\n* 1.3.0 works with react-hook-form 7.\n  * If you didn't override the skin, it should work out of the box after update.\n  * If you overrided the skin, then follow [this guide](docs/migrate-1.2-to-1.3.md).\n* 1.2.0 works with react-hook-form 6: `npm install react-hook-form@6 react-hook-form-auto@1.2 --save`\n* 1.1.0 works with react-hook-form 4 and 5. Older versions of this library (1.0.x) will only work with version 3 of react-hook-form.\n\n## Usage\n\n### 1. Write schema\n\nWrite a schema for each model you have:\n\n```javascript\n    import { createSchema } from 'react-hook-form-auto'\n\n    export const client = createSchema('client', {\n      name: {\n        type: 'string',\n        required: true,\n        max: 32\n      },\n      age: {\n        type: 'number'\n      }\n    })\n```\n\nIn this example we are stating that a `client` is required to have a `name` and providing its allowed length. Also `client` has `age` and it's a number.\n\n### 2. Render a form\n\n`\u003cAutoform /\u003e` React component will generate inputs including translatable label, proper input types and error messages.\n\n```javascript\n    import { Autoform } from 'react-hook-form-auto'\n    import { client } from './models/client'\n\n    const MyForm = ({ onSubmit }) =\u003e\n      \u003cAutoform\n        schema={client}\n        onSubmit={onSubmit}\n      /\u003e\n```\n\nForm will be validated following the rules set by the schema.\n\nIt also allows you to build arrays from other schemas. Simply specify the other schema within brackets `[\u003cother\u003e]`. `Autoform` default skin will allow you to add and remove elements.\n\n```javascript\n    import { createSchema } from 'react-hook-form-auto'\n    import { client } from './client'\n\n    export const company = createSchema('company', {\n      clients: {\n        type: [client],\n        minChildren: 10,\n        arrayMode: 'panel'  // You can override config\n      }\n    })\n```\n\nYou can override form array config for a particular field using `arrayMode`\n\n### 3. Make it prettier\n\n#### 3a. Make it less ugly with some styling\n\nInstall the emergency styles if you don't want to bundle a whole css library.\n\n    $ npm install rhfa-emergency-styles --save\n\nThen set the `styles` prop of `\u003cAutoform /\u003e`:\n\n```javascript\n    import styles from 'rhfa-emergency-styles'\n \n    // With sass...\n    import 'rhfa-emergency-styles/prefixed.sass'\n    // ...or without\n    import 'rhfa-emergency-styles/dist/styles.css'\n \n    \u003cAutoform styles={styles} /\u003e\n```\n\nIf you use `sass` you have to make sure you are [not excluding `node_modules`](https://github.com/dgonz64/react-hook-form-auto-demo/commit/94dbe78dc93a4110f915a5809a6880a8c7a55970) in your build process.\n\nIf you use `css-modules` you have [better options](https://github.com/dgonz64/rhfa-emergency-styles).\n\n#### 3b. Make it pretty with Bootstrap 4\n\nWe can take advantage of the styling strategy and pass bootstrap classes as `styles` props. You can grab them [from here](https://github.com/dgonz64/react-hook-form-auto-demo-bootstrap4/blob/master/src/styles.js) \\[[raw](https://raw.githubusercontent.com/dgonz64/react-hook-form-auto-demo-bootstrap4/master/src/styles.js)\\]. Then use them:\n\n```javascript\n    import styles from './bsStyles'  // copy-pasted styles description\n\n    \u003cAutoform styles={styles} /\u003e\n```\n\nAs you have to pass the styles on every `Autoform` render, I recommend [creating a module](https://github.com/dgonz64/react-hook-form-auto-demo/blob/master/src/components/Autoform.jsx) or a HoC.\n\nRead the [documentation](#documentation) to find out what else you can do.\n\n#### 4. Translate\n\nYou probably see labels like `models.client.name` instead of the proper ones. That's because the project uses a built-in translation system. You can setup those strings both at once or incrementally.\n\nSimple call `addTranslations` directly in your module or modules. Example:\n\n```javascript\n    import { addTranslations } from 'react-hook-form-auto'\n\n    addTranslations({\n      models: {\n        client: {\n          name: 'Name',\n          age: 'Age'\n        }\n      }\n    })\n```\n\nA simple way to fill this is by replicating the unstranslated string in the object. The dot is a subobject. In the former example you would see a label called `models.client.name`.\n\n## Available skins\n\nSome of them need other imports. See instructions from each.\n\n### [Vanilla](https://github.com/dgonz64/react-hook-form-auto) (here)\n### Bootstrap 4 (as instructed in this document)\n### [Material-UI](https://github.com/dgonz64/rhfa-material-ui)\n### [Blueprint](https://github.com/dgonz64/rhfa-blueprint)\n### [React Native](https://github.com/dgonz64/rhfa-react-native)\n\n## Rationale\n\nOne of the purposes of the library is to avoid repeating code by not having to write a set of input components for every entity. Also when time is of the essence, writing forms can be exasperating.\n\nThese are some of the advantages of using an automatic form system.\n\n* More [DRY](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself)\n* More [SSoT](https://en.wikipedia.org/wiki/Single_source_of_truth)\n* *...so less bugs*\n\nAlso react-hook-form-auto has some of its own\n\n* Includes a translation system\n* It's easily expandable\n* It's simple\n* When possible tries to use [convention over configuration](https://en.wikipedia.org/wiki/Convention_over_configuration)\n\n# Roadmap\n\nActually there aren't clearly defined goals. The library already suits my personal needs. Do you need anything that is not there? Feel free to write an issue! Those are the tasks I think may be interesting and will randomly work on them:\n\n- [x] Automatic form generation\n- [x] Able to stylize components\n- [x] Datatype coertion\n- [x] Provide more and better styling examples\n- [x] Styles to make it look like bootstrap4\n- [x] _Native_ components for famous ui libraries like bootstrap4\n  - [ ] Need other? Open issue!\n- [x] Actually limit children\n- [x] React Native support\n- [x] Translated messages from server/async\n- [x] Make it compatible with `react-hook-form` 7.\n\n# Documentation\n\n## Types\n\nEach schema can be regarded as a Rails model or a database table. You can store them anywhere, for example in a module:\n\n```javascript\n    import { createSchema } from 'react-hook-form-auto'\n\n    export const computer = createSchema('computers', { /* ...schema... */ })\n```\n\nEach first level entry in the schema object represents the fields in the form or the columns in the database analogy. To configure the field you use another object. Example:\n\n```javascript\n    {\n      name: { type: 'string' }\n    }\n```\n\nThese are the types a field can be:\n\n| Type       | Valid when...            | Input control                 |\n| ---------- | ------------------------ | ----------------------------- | \n| string     | Value is a string        | `\u003cinput type=\"text\" /\u003e`       |\n| number     | Value is a number        | `\u003cinput type=\"number\" /\u003e`     |\n| range      | Between two numbers      | `\u003cinput type=\"range\" /\u003e`      |\n| [\\\u003cschema\\\u003e] | Each array item is valid | Renders as array              |\n| \\\u003cschema\\\u003e   | Value follows schema     | Renders as submodel           |\n| select     | Value belongs to set     | `\u003cselect /\u003e`                  |\n| radios     | Value belongs to set     | `\u003cRadio /\u003e`                   |\n| boolean    | Value is boolean         | `\u003cinput type=\"checkbox /\u003e`    |\n| password   | Value is a string        | `\u003cinput type=\"password\" /\u003e`   |\n\nYou can specify the type as a constructor. There's not an easily measurable advantage. Example:\n\n```javascript\n    { type: String }\n```\n\n#### select and radios\n\nThey both allow options as an array that can be one of strings with the options keys that will be feed to translator using `trModel()` or can be objects in the form `{ value, label }`. If an object is provided, label will be used for the HTML content (display) and value for the option's value.\n\nOptions can also be a function. In that case it will be evaluated with the component props as the first argument. The results used as explained above, that is, array of strings or objects.\n\nOptions as object \n\nExample with keys:\n\n```javascript\n    {\n      type: 'select',\n      options: ['red', 'blue']\n    }\n```\n\nExample with objects:\n\n```javascript\n    {\n      type: 'select',\n      options: [\n        { value: 'r', key: 'red' },\n        { value: 'b', key: 'blue' }\n      ]\n    }\n```\n\nYou can specify label too. In that case it will be a direct already translated string. If you setup `key` then label will be infered and translated.\n\nExample with direct labels:\n\n```javascript\n    {\n      type: 'select',\n      options: [\n        { value: 'r', label: 'Some red' },\n        { value: 'b', label: 'Some blue' }\n      ]\n    }\n```\n\nExample with function. This example assumes `Autoform` component has a color collection in the props:\n\n```javascript\n    {\n      type: 'select',\n      options: props =\u003e props.colors.map(color =\u003e ({\n        value: color.id,\n        key: color.name\n      }))\n    }\n```\n\n### Validators\n\n| Validation  | Type     | Meaning | Error string ID |\n| ----------- | -------- | -------------------------------------------------- | --- |\n| minChildren | number   | Minimum amount of children an array field can have | `error.minChildren` |\n| maxChildren | number   | Maximum amount of children an array field can have | `error.maxChildren` |\n| min         | number   | Minimum value | `error.min` |\n| max         | number   | Maximum value | `error.min` |\n| required    | boolean  | The value can't be empty or undefined | `error.required` |\n| validate    | function | Function that takes the value and entry and returns validity | |\n| pattern     | regex    | Regex. The value matches the regex | |\n\nThe string returned will be translated. The translation will receive the field's schema as [variables](#variable-substitution).\n\n### The `validate` validator\n\nThe function used to validate the field, as any other validator, can return:\n\n* true to fail (and automatically generate message) or false to pass\n* An string that will be the error message\n\n### Other schema fields\n\nThere are some other attributes you can pass while defining the field schema:\n\n| Attribute       | Type      | Meaning |\n| -----------     | --------  | -------------------------------------------------- |\n| noAutocomplete  | boolean   | Inputs (or skin's `component`) will have `autocomplete=off` to help skip browser's autocomplete |\n| addWrapperProps | object    | Directly passed to wrapper component |\n| addInputProps   | object    | Props merged into input component |\n| onChange        | function  | Allows you to change values on the fly. See [this](docs/schema-onchange.md). |\n| helperText      | string    | Explicit string for the helper text for the field, for example `tr('example')` |\n\n#### Helper text\n\nThe `helperText` attribute in the schema allows you to set a fixed helper text for the field. The helper text can be changed in other ways and this is the precedence order:\n\n1. Text set using `setHelperText` from schema (or `FieldPropsOverride`) `onChange`.\n1. Explicit text set by schema `{ name: 'name', type: 'string', helperText: tr('example') }`\n1. Automatic translation string in the form `models.\u003cschemaTypeName\u003e.\u003cfield\u003e._helper`\n\n### Schema\n\nThe schema establishes the validation and inputs. The instance can be stored anywhere, like your own model object or a module. At the moment it doesn't change over time.\n\n### createSchema\n\nCreates a Schema from the specification.\n\n**Kind**: global function  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| typeName | \u003ccode\u003estring\u003c/code\u003e | Name of the model being created.    It can be chosen freely. |\n| schema | \u003ccode\u003eobject\u003c/code\u003e | Schema specification. |\n\n\n### Autoform component\n\nThe `\u003cAutoform /\u003e` component accepts the following props\n\n| Prop        | Type            | Meaning |\n| ----------- | --------------- | ------------------------------------------------------ |\n| schema      | Schema instance | Schema used to build the form |\n| elementProps | object | Props extended in all the inputs |\n| initialValues | object | Initial values |\n| children | element | Whatever you want to put inside the form |\n| onSubmit    | function        | (optional) Code called when submitting with the coerced doc |\n| onChange    | function        | (optional) Code called after any change with the current coerced doc |\n| onErrors    | function        | (optional) Code called when form has errors |\n| forceErrors    | object        | (optional) Object with the errors or _falsy_ like `null` to not force. Keys will be the field name (example `pets.0.name`) and the value is another object with key `message`. Example: `{ username: { message: 'Taken' } }` |\n| styles    | object | Styles used by the defaultSkin |\n| submitButton | boolean | (optional) Include submit button |\n| submitButtonText | element | (optional) Contents for the submit button |\n| skin | object | Base skin |\n| skinOverride | object | Override some skin components |\n| disableCoercing | boolean | Disable all coercing and get values as text |\n| noAutocomplete | boolean | Disable all autocompleting by passing `autocomplete=off` to the input or skin's `props` |\n\nAny other prop will be passed to the skin `props()`.\n\n### Config\n\nThe `config` prop is an object that has the following attributes\n\n| Attribute  | Meaning |\n| ---------- | ------------------------------------------------------------------- |\n| arrayMode  | `'table'` or `'panels'` depending on wanted array field format. `panels` uses card/box/panel wrapping for elements. `table` uses tables (might not fit but if it does is perfect for compact models) |\n\n### Field props override\n\nYou can override field props individually. You can do this with a component called `FieldPropsOverride`. This is useful when you want to create an special field with some functionality that forces you to provide an event handler. Let's see an example:\n\n```javascript\n    import { Autoform, FieldPropsOverride } from 'react-hook-form-auto'\n\n    const Component = ({ onKeyDown }) =\u003e\n      \u003cAutoform schema={client}\u003e\n        \u003cFieldPropsOverride\n          name=\"name\"\n          onKeyDown={onKeyDown}\n        /\u003e\n      \u003c/Autoform\u003e\n```\n\nThe name can specified without taking into account array ordinals. For example, if a `pet` serves as an schema array for an `owner` and you want to override every pet name from `pets` field (array), you should use `pets.name` as the `name` prop:\n\n```javascript\n    \u003cFieldPropsOverride\n      name=\"pets.name\"\n      ...overrides...\n    /\u003e\n```\n\nIt can also be an specific path like `pets[0].name`.\n\n#### `\u003cFieldPropsOverride /\u003e`'s `onChange`\n\nIn `FieldPropsOverride`, `onChange` prop is automatically chained with both ReactHookForm and schema `onChange`. The callback receives exactly [the same arguments as schema `onChange`](https://github.com/dgonz64/react-hook-form-auto/blob/master/docs/schema-onchange.md). The order of calling is:\n\n1. ReactHookForm `onChange`\n1. Schema's `onChange`\n1. `FieldPropsOverride`'s `onChange`\n\nExample:\n\n```javascript\nconst handleChange = (value, { setValue }) =\u003e {\n  if (value == 'tall')\n    setValue('name', 'André the Giant')\n}\n\nreturn (\n  \u003cAutoform\u003e\n    \u003cFieldPropsOverride\n      name=\"height\"\n      onChange={handleChange}\n    /\u003e\n  \u003c/Autoform\u003e\n)\n```\n\n### Coercers\n\nWhile react-hook-form works with inputs, this library is focused in models. This means:\n\n* Values from inputs are coerced to the datatype you define in the schema.\n* Default values are left untouched if there they are not defined or registered.\n* You can manually use setValue from your skin or skinOverride.\n\nYou can also disable coercers with the `Autoform`'s `disableCoercing` prop.\n\n### Select\n\nSelect will include an empty option for uninitialized elements. Please, write an issue if you want this to be configurable.\n\n### Forcing errors\n\nYou can force an error message for any field, including a nested one. For it you elaborate an object with the field keys in ReactHookForm notation, for example `pets.0.name`. Complete example:\n\n```javascript\nconst LoginContainer = () =\u003e {\n  const [ serverErrors, setServerErrors ] = useState(null)\n\n  const handleLogin = () =\u003e {\n    setServerErrors({\n      username: { message: 'Already taken' },\n      password: { message: 'Also, wrong password' }\n    })\n  }\n\n  return (\n    \u003cAutoform\n      ...\n      forceErrors={serverErrors}\n      onSubmit={handleLogin}\n    /\u003e\n  )\n}\n```\n\nAlso take a look at this [demo](https://codesandbox.io/s/rhfa-emergency-example-server-validation-9571b7?file=/src/App.js). After you pass client validation (just fill both names), you can click Send to simulate server validation errors.\n\n## Imperative handling\n\n`Autoform` component sets some functions to be used in referenced component:\n\n```javascript\n    let formRef\n\n    // Example: imperative submit\n    const doSubmit = () =\u003e {\n      formRef.submit()\n    }\n\n    const MyForm = ({ onSubmit }) =\u003e\n      \u003cAutoform\n        onSubmit={onSubmit}\n        ref={e =\u003e formRef = e}\n      /\u003e\n```\n\nFunctions returned:\n\n| Attribute | Description |\n| --- | --- |\n| submit()   | Imperative submit. |\n| setValue(name, value, options) | Sets a value in any place of the document. You can use a path. As this library coerces values, it's better to use this than the one from react-hook-form to avoid inconsistences. The parameter `options` is passed to ReactHookForm |\n| setVisible(name, visible) | Sets the visibility for an element. |\n| reset()    | Resets every field value to initial's. |\n| getValues() | Returns the coerced form values |\n| formHook() | Call this in order to get react-hook-form vanilla reference object. |\n\n## Translation\n\nreact-hook-form-auto uses internally a simple better-than-nothing built-in translation system. This system and its translation tables can be replaced and even completely overridden.\n\nThe translation strings are hierarchized following some pseudo-semantic rules:\n\n```javascript\n    `models.${model}.${field}.${misc}`\n```\n\nThe meaning of the last `misc` part usually depends on the type of field.\n\nThe dots navigates through children in the string table. Example:\n\n```javascript\n    {\n      models: {\n        computer: {\n          cpu: { \n            arm: 'ARM',\n            // ...\n          },\n          // ...\n        }\n      }\n    }\n```\n\nTo translate string for your use call `tr()` and pass the string path separated by dots:\n\n```javascript\n    import { tr } from 'react-hook-form-auto\n\n    const message = tr('models.computers.cpu.arm')\n\n    /* message value is 'ARM' */\n```\n\nThis is the usage of the `tr()` function:\n\n### tr\nTranslates a string given its id.\n\n**Kind**: global function  \n**Returns**: Translated string  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| id | \u003ccode\u003estring\u003c/code\u003e | Identifier in the form \t`key1.key2.key3` |\n| vars | \u003ccode\u003eobject\u003c/code\u003e | Object with substitution variables. It will \tsubstitute ocurrences when string contains this expression: \t`__variable__`. For example the string `\"My name is __name__\"` with \t`vars = { name: 'David' }` will return `\"My name is David\"`. \tKeys will be searched by partitioning the path. \tIt will get the latest found key if any. For example, given the \tstrings `{ \"a\": { \"b\": 'Hello' } }` and looking for `'a.b.c'` it will \treturn `'a.b'` (`\"Hello\"`). |\n\n\n### stringExists\nReturns if the string does exist\n\n**Kind**: global function  \n**Returns**: \u003ccode\u003eboolean\u003c/code\u003e - true if it exists  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| id | \u003ccode\u003estring\u003c/code\u003e | Identifier |\n\n\n### Variable substitution\n\nYou can also put variables in the translation strings:\n\n```javascript\n    {\n      name: {\n        create: '__name__ created'\n      }\n    }\n```\n\nThis allows you to translate and inserting a value in the correct place of the string. Example:\n\n```javascript\n    import { tr } from 'react-hook-form-auto'\n\n    const name = 'Alice'\n    const message = tr('name.create', { name })\n\n    /* message value is 'Alice created' */\n```\n\n### Adding strings\n\n```javascript\n    import { addTranslations } from 'react-hook-form-auto'\n```\n\nThen you call addTranslations with the object tree:\n\n### addTranslations\nAppends translations to current translation table\n\n**Kind**: global function  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| lang | \u003ccode\u003eobject\u003c/code\u003e | Translations merged into current. |\n\n\nIt's ok to overwrite a language with another. The non translated strings from the new language will remain from the former in the table. At the moment it's up to you to take care about language completeness (or, better, use an external translator).\n\n### Multilanguage\n\nIf your application has more than one language and it can be changed on the fly, I better recommend to use translation utils over the core translations. Those functions store the languages separately:\n\n```javascript\n    import { setLanguageByName } from 'react-hook-form-auto'\n\n    setLanguageByName('en')\n```\n\nYou can add the translation strings directly to a language:\n\n### addLanguageTranslations\nAllows to add a bunch of strings to a language\n\n**Kind**: global function  \n\n### Translation utils\n\nThere are some functions that deal with semantic organization of the translation strings this library uses. You can take advantage of them if you are building a skin:\n\n### trModel\nMultipurpose semantic-ish translation.\n\n**Kind**: global function  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| modelName | \u003ccode\u003estring\u003c/code\u003e | Object name, usually what    you pass as the first parameter when you create    the schema. |\n| field | \u003ccode\u003estring\u003c/code\u003e | Field name |\n| op | \u003ccode\u003estring\u003c/code\u003e | Thing that varies based on    the type. |\n\n\n### trField\nTranslate field name\n\n**Kind**: global function  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| modelName | \u003ccode\u003estring\u003c/code\u003e \\| \u003ccode\u003eobject\u003c/code\u003e | Object name, usually what    you pass as the first parameter when you create    the schema. It can also be an object with component    props so it will figure out the values |\n| field | \u003ccode\u003estring\u003c/code\u003e | Field name |\n\n\n### trError\nTranslates error message.\n\n**Kind**: global function  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| error | \u003ccode\u003estring\u003c/code\u003e | Code of the error (usually the    validation code-name) |\n| data | \u003ccode\u003eobject\u003c/code\u003e | Field configuration from `createSchema()`. |\n\n\n### Use your own translation system\n\nYou can disable the translation system to use your own.\n\n### setTranslator\nSets the translation engine that responds to tr().\n\n**Kind**: global function  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| translate | \u003ccode\u003efunction\u003c/code\u003e | Function with signature \ttranslate(id, params). |\n\n\nExample:\n\n```javascript\n    import { setTranslator } from 'react-hook-form-auto'\n    import { myTranslationTranslator } from './serious_translator'\n\n    setTranslator((tr, data) =\u003e {\n      /* do something with tr or data */\n\n      return myTranslationTranslator(something, somethingElse)\n    })\n```\n\nOr you can drop it directly to `setTranslator()` if it's compatible.\n\n## Extending\n\nIf you just need another appearance, you can do it changing styles. If you are adapting an existing UI library (like [Blueprint](https://blueprintjs.com/)) then it's better to extend skin.\n\n### With styles\n\nThe default skin from `react-hook-form-auto` uses css classes. You can override them providing your set. Example with css-modules:\n\n```javascript\n    import styles from './my_styles.css'\n\n    \u003cAutoform styles={styles} /\u003e\n```\n\nThe whole [rhfa-emergency-styles](https://github.com/dgonz64/rhfa-emergency-styles) does this and can serve as an example.\n\n### Overriding skin\n\nWhen you need to adapt behaviour, styles might not be enough. To solve this you can override full components.\n\nThe inputs and auxiliary elements are created using a set of components. The mapping can be set all together by overriding the skin, like this:\n\n```javascript\n    import { Autoform as RHFAutoform } from 'react-hook-form-auto'\n\n    import overrides from './skinOverride'\n\n    export const Autoform = (props) =\u003e\n      \u003cRHFAutoform\n        {...props}\n        skinOverride={overrides}\n      /\u003e\n```\n\nYou can take a look at [defaultSkin.js](https://github.com/dgonz64/react-hook-form-auto/blob/master/src/ui/defaultSkin.jsx) and [`components/index.js`](https://github.com/dgonz64/react-hook-form-auto/tree/master/src/ui/components) from any skin to have a glimpse.\n\nAlso find [here](https://github.com/dgonz64/rhfa-material-ui/blob/master/src/skinOverride.js#L56) a full skin override.\n\nI made a tutorial adapting Material-UI to react-hook-form-auto. You can find it [here](https://github.com/dgonz64/rhfa-playground).\n\n### Extension process\n\nThere's an entry in the skin object for every field type. The value of the entry is an object with two attributes like in this example:\n\n```javascript\n    number: {\n      coerce: value =\u003e parseFloat(value),\n      props: {\n        component: 'input',\n        type: 'number'\n      }\n    },\n```\n\n#### coerce\n\nFunction that converts result to its correct datatype.\n\n#### props\n\nProp transformation for the rendered component.\n\nThe attribute `component` is the React component used to render the input inside the wrappers.\n\n```javascript\n    select: {\n      props: {\n        component: Select\n      }\n    },\n```\n\nIt can be also a first level attribute, useful if you don't need to change props\n\n```javascript\n    select: {\n      component: Select\n    },\n```\n\n##### `props` is an object\n\nProps merged to component's default:\n\n```javascript\n    range: {\n      coerce: value =\u003e parseFloat(value),\n      props: {\n        component: 'input',\n        type: 'range'\n      }\n    },\n```\n\nIf `component` is a string, like in this example, it will only receive `\u003cinput /\u003e`-like props, like `name` and `onChange`.\n\n##### `props` is a function\n\nFunction that takes the component's intended props and returns component's final props:\n\n```javascript\n    string: {\n      props: props =\u003e ({\n        ...props,\n        component: props.fieldSchema.textarea ? 'textarea' : 'input'\n      }),\n    },\n```\n\n#### `onChange` and `onBlur` in props\n\nThe `component` in the `props` property is also in charge of the field update: For that matter you have two options\n\n##### Use it directly (recommended)\n\n```javascript\n  const Input = ({ name, onChange, onBlur }) =\u003e\n    \u003cMyAwesomeWrapping\u003e\n      \u003cinput name={name} onChange={onChange} onBlur={onBlur} /\u003e\n    \u003c/MyAwesomeWrapping\u003e\n\n  const mySkinOverride = {\n    string: {\n      component: Input\n    }\n  }\n```\n\n##### Use `setValue`\n\nAnother way is to use `setValue(name, newValue)` on every change. The component is still uncontrolled but model's value will be updated.\n\n```javascript\n  props: ({ name, register, setValue }) =\u003e {\n    const setValueFromEvent = event =\u003e {\n      setValue(name, event.target.value)\n    }\n\n    return {\n      component: \u003cMyComponent {...} onChange={setValueFromEvent} /\u003e\n    }\n  }\n```\n\n### Other skin block attributes\n\n```javascript\n    range: {\n      coerce: value =\u003e parseFloat(value),\n      controlled: true,\n      skipRegister: true,\n      nameForErrors: name =\u003e `${name}__counter`,\n      props: {\n        component: 'input',\n        type: 'range'\n      }\n    },\n```\n\n| Attribute | Means |\n| --------- | ----- |\n| `controlled` | Will `useController()`. Component will receive also `value` prop |\n| `skipRegister` | Will not automatically register this field. Hasn't any meaning if `controlled` is `true` |\n| `nameForErrors` | Function that receives `name` and returns a transformed name used to navigate through the `errors` object returned from `react-hook-form`'s `useFormState`. Helps to create errors for non registered field like `minChildren` does. |\n\n## Overriding skin\n\nYou can override (or add) specific types by using `\u003cAutoform /\u003e`'s `skinOverride` prop.\n\n### Avoid `array` and `schema`\n\nOnly override `array` and `schema` types if you know `react-hook-form-auto` internals. For example both need `skipRegister`.\n\n### `skin[type].props`\n\nThe rest of the properties a skin block can override:\n\n| Prop             |   Type            |  Use |\n| ---------------- | ----------------- | ------------------------------------------ |\n| `component`      | element           | Component used to render the input |\n| `wrapper`        | function          | Override wrapper `skin.defaultWrap` |\n| `name`           | string            | (**Must not be changed**) Complete field name (with hierarchy) |\n| `field`          | string            | (**Shouldn't be changed**) This field name |\n| `option`         | string            | Forces value (used in radios for example ) |\n| `inline`         | boolean           | Goes to the wrapper as `inline` |\n| `styles`         | object            | Style overriding |\n| `fieldSchema`    | object            | Schema specification for the field |\n| `schemaTypeName` | string (required) | Name of the schema that contains the field |\n| `parent`         | string            | Name of the containing field |\n| `config`         | object            | Override config for this input |\n| `index`          | number            | Index for arrays |\n| `formHook`       | object            | ReacHookForm's register() returned object |\n| `autoformProps`  | object            | Properties passed to Autoform |\n| `skinElement`    | object            | skin resolver for the type of this field (for example `skin.boolean`) |\n\n### `skin[type].component` or `skin[type].props.component`\n\nThe value of this field is used to render the input component. If it's a component, the will receive these props, appart from the rest of the `skin[type].props` block.\n\nIf `component` is specified both from `props` and directly (`skin[type].component`), the one coming from props will have priority.\n\n| Prop             |   Type   | Use |\n| ---------------- | -------- | --------------------------------------------------- |\n| `id`             | string     | Id usable to match label in dom  |\n| `name`             | string     | Full path name for the `\u003cinput /\u003e` |\n| `type`             | string     | `type` as would be passed to `\u003cinput /\u003e`  |\n| `defaultValue`     | any     | As calculated from initialValues, schema and skin |\n| `onChange`     | function     | Should be called back with dom `change` event handler |\n| `onBlur`     | function     | Callback for dom `blur` |\n| `className`     | function     | Calculated classes |\n| `field`     | function     | Relative field name |\n| `inputRef`     | function     | ref for the input element. Comes from `register` and it's used to update fields imperatively |\n| `errorText`     | string     | Validation errors or `''` |\n| `fieldSchema`     | object     | Part of the schema that refers to this field |\n| `formHook`     | object     | As returned from the `useForm()` call |\n| `styles`     | object     | All the styles in case you do class styling |\n| `skinElement`    | object     | Complete skin block specific to this type of field (for example `skin.number`) |\n| `setVisible`    | function     | Changes visibility of fields `setVisible(name, visible)`. If the field is not visible, then it will not appear in submit doc neither. |\n| `setHelperText`    | function     | Changes field helper text `setHelperText(name, text)` |\n| `setValue`    | function     | Changes value of any field `setValue(name, value)` |\n| `arrayControl`    | object     | Some control functions in the case field is inside an array. See [this](doc/schema-onchange.md#arraycontrol) |\n| `value`     | any     | Only for controlled types (`skin[type].controlled == true`) |\n| ...          | any         | ...any other prop added in schema with `addInputProps` |\n\n### `InputWrap`\n\nIt's a common component used to create all the input structure, including wrappers. You can use it to avoid boilerplate.\n\n| Prop             |   Type   | Use |\n| ---------------- | -------- | --------------------------------------------------- |\n| `children`       | element     | (optional) You can use InputWrap to... wrap. |\n| `id`             | string     | id for the `for` attribute of the label |\n| `name`           | string   | Full name (with hierarchy) |\n| `schemaTypeName` | string   | Name of the schema as created |\n| `styles`         | object   | Styles |\n| `labelOverride`  | string   | Label overriding |\n| `inline`         | boolean  | Will omit label |\n| `errorText`      | string   | Validation error |\n\nThe props for the input component are different depending if the `inputComponent` is a string, like `'input'` or a React component.\n\n#### Native component (ie. `'input'`)\n\nFor a 'lowercase' component like `\u003cinput /\u003e`, props passed are\n\n* id\n* name\n* type\n* option (if provided, for the value)\n* defaultValue\n* onChange\n* onBlur\n* ref\n* className calculated\n* ...any fields added to schema's `addInputProps`\n\n#### Class component (ie. `MySlider`)\n\nClass components receive all the provided or derived props.\n\n### Rendering\n\nTo render the input or inputs, two functions are used:\n\n### renderInputs\nRenders the inputs to make the schema work.\n\n**Kind**: global function  \n**Returns**: \u003ccode\u003earray\u003c/code\u003e - React elements with the form and inputs.  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| params | \u003ccode\u003eobject\u003c/code\u003e |  |\n| params.schema | \u003ccode\u003eSchema\u003c/code\u003e | Schema instance |\n| params.config | \u003ccode\u003eobject\u003c/code\u003e | Rendering configuration |\n| params.config.arrayMode | \u003ccode\u003estring\u003c/code\u003e | 'panels' or 'table' |\n| ...params.rest | \u003ccode\u003eobject\u003c/code\u003e | Props passed to every input |\n\n\n### renderInput\nRenders a single field.\n\n**Kind**: global function  \n\n| Param | Type | Description |\n| --- | --- | --- |\n| params | \u003ccode\u003eobject\u003c/code\u003e |  |\n| params.field | \u003ccode\u003estring\u003c/code\u003e | Name of the field |\n| params.fieldSchema | \u003ccode\u003eobject\u003c/code\u003e | Schema specification    for the field |\n| params.parent | \u003ccode\u003estring\u003c/code\u003e | Prefix of the field name |\n| params.schemaTypeName | \u003ccode\u003estring\u003c/code\u003e | Name of the schema    (first argument while instantiating a schema) |\n| params.config | \u003ccode\u003eobject\u003c/code\u003e | Form configuration |\n| ...params.rest | \u003ccode\u003eobject\u003c/code\u003e | props passed to the component |\n\n\n## Importing base\n\nYou can use the base bundle to import `AutoformBase` component. `AutoformBase` is like `Autoform` but doesn't use `react-dom` dependency.\n\n```javascript\n  import { Autoform, ... } from 'react-hook-form-auto/dist/base.js'\n```\n\nYou can also do it in a more permanent way if you use webpack:\n\n```javascript\n  resolve: {\n    alias: {\n      'react-hook-form-auto': 'react-hook-form-auto/dist/base.js'\n    }\n  },\n```\n\n# Help wanted / contribute\n\nreact-hook-form-auto needs your help. Skins must be written!\n\nAlso, it would make my day to see the library working in your project, provided it's public. Please, tell me!\n\n### Where to begin\n\nMake a fork and do your magic followed by a [pull request](https://help.github.com/articles/about-pull-requests/). If it's an implementation, test case and documentation update would be highly appreciated.\n\n### Some code pointers\n\nEverything is work in progress until there's a bunch of skins or we are in complete control of the world, whichever comes first.\n\nThe most important files:\n\n* `src/ui/components/componentRender.jsx` processes the schema to build the inputs and allows skin overrides\n* `src/ui/Autoform.jsx` The component and the coercing logic\n* `src/ui/AutofieldContainer.jsx` Registers or calls `useController()`\n* `src/ui/Autofield.jsx` Wraps component within wrapper\n* `jsdoc2md/README.hbs` Documentation source\n\nSee also the [contributing doc](https://github.com/dgonz64/react-hook-form-auto/blob/master/CONTRIBUTING.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgonz64%2Freact-hook-form-auto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdgonz64%2Freact-hook-form-auto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdgonz64%2Freact-hook-form-auto/lists"}