├── .editorconfig
├── .eslintrc
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .prettierrc
├── CHANGELOG.md
├── README.md
├── example
├── .gitignore
├── package.json
├── public
│ ├── global.css
│ └── index.html
├── rollup.config.js
├── src
│ └── index.jsx
└── yarn.lock
├── package.json
├── rollup.config.js
├── setupTest.js
├── src
├── JSONSchema
│ ├── __mocks__
│ │ ├── deepFreeze.ts
│ │ └── mockSchemaWithRefs.ts
│ ├── __tests__
│ │ ├── formPathHandler.test.ts
│ │ ├── resolveReferences.test.tsx
│ │ └── testFrozenObject.test.tsx
│ ├── index.ts
│ ├── logic
│ │ ├── index.ts
│ │ ├── pathUtils.ts
│ │ ├── refHandlers.ts
│ │ └── schemaHandlers.ts
│ ├── path-handler.ts
│ └── types
│ │ └── index.ts
├── __mocks__
│ └── mockObjectComponent.tsx
├── components
│ ├── FormContext.tsx
│ ├── __mocks__
│ │ └── mockSchema.ts
│ ├── __tests__
│ │ └── FormContext.test.tsx
│ ├── index.ts
│ └── types
│ │ └── index.ts
├── hooks
│ ├── __mocks__
│ │ ├── mockSchema.ts
│ │ └── mockTextSchema.ts
│ ├── __tests__
│ │ ├── useCheckbox.test.tsx
│ │ ├── useCustomValidator.test.tsx
│ │ ├── useInput.test.tsx
│ │ ├── useObject.test.tsx
│ │ ├── useRadio.test.tsx
│ │ ├── useRawInput.test.tsx
│ │ ├── useSelect.test.tsx
│ │ └── useTextArea.test.tsx
│ ├── index.ts
│ ├── types
│ │ └── index.ts
│ ├── useCheckbox.ts
│ ├── useGenericInput.ts
│ ├── useHidden.ts
│ ├── useInput.ts
│ ├── useObject.ts
│ ├── usePassword.ts
│ ├── useRadio.ts
│ ├── useRawInput.ts
│ ├── useSelect.ts
│ ├── useTextArea.ts
│ └── validators
│ │ ├── __tests__
│ │ └── errorMessages.test.tsx
│ │ ├── getEnum.ts
│ │ ├── getError.ts
│ │ ├── getGenericValidator.ts
│ │ ├── getNumberValidator.ts
│ │ ├── getStringValidator.ts
│ │ ├── index.ts
│ │ ├── numberUtilities.ts
│ │ └── types
│ │ └── index.ts
└── index.ts
├── tsconfig.json
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | # Use 4 spaces for HTML files
13 | [*.html]
14 | indent_size = 4
15 |
16 | # The JSON files contain newlines inconsistently
17 | [*.json]
18 | insert_final_newline = ignore
19 |
20 | # Minified JavaScript files shouldn't be changed
21 | [**.min.js]
22 | indent_style = ignore
23 | insert_final_newline = ignore
24 |
25 | [*.md]
26 | trim_trailing_whitespace = false
27 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "vtex-react",
3 | "root": true,
4 | "env": {
5 | "browser": true,
6 | "node": true,
7 | "es6": true,
8 | "jest": true
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **To Reproduce**
11 | Steps to reproduce the behavior:
12 | 1. Go to '...'
13 | 2. Click on '....'
14 | 3. Scroll down to '....'
15 | 4. See error
16 |
17 | **Expected behavior**
18 | A clear and concise description of what you expected to happen.
19 |
20 | **Screenshots**
21 | If applicable, add screenshots to help explain your problem.
22 |
23 | **Desktop (please complete the following information):**
24 | - OS: [e.g. iOS]
25 | - Browser [e.g. chrome, safari]
26 | - Version [e.g. 22]
27 |
28 | **Smartphone (please complete the following information):**
29 | - Device: [e.g. iPhone6]
30 | - OS: [e.g. iOS8.1]
31 | - Browser [e.g. stock browser, safari]
32 | - Version [e.g. 22]
33 |
34 | **Additional context**
35 | Add any other context about the problem here.
36 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | **Is your feature request related to a problem? Please describe.**
8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Describe alternatives you've considered**
14 | A clear and concise description of any alternative solutions or features you've considered.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the feature request here.
18 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | #### What problem is this solving?
2 |
3 |
4 |
5 | #### Checklist/Reminders
6 |
7 | - [ ] Updated `README.md`.
8 | - [ ] Updated `CHANGELOG.md`.
9 | - [ ] Linked this PR to a Clubhouse story (if applicable).
10 | - [ ] Updated/created tests (important for bug fixes).
11 | - [ ] Deleted the workspace after merging this PR (if applicable).
12 |
13 | #### Example usage
14 |
15 | #### Type of changes
16 |
17 |
18 | ✔️ | Type of Change
19 | ---|---
20 | _ | Bug fix
21 | _ | New feature
22 | _ | Breaking change
23 | _ | Technical improvements
24 |
25 | #### Notes
26 |
27 |
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | *.swp
4 | *.DS_STORE
5 | output/*
6 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": true,
4 | "trailingComma": "es5",
5 | "eslintIntegration": true
6 | }
7 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [Unreleased]
9 |
10 | ## [0.2.0] - 2021-08-03
11 |
12 | ## [0.2.0-beta.13] - 2020-03-26
13 |
14 | ### Fixed
15 |
16 | - Prevent `onChange` from being triggered during the initial render.
17 |
18 | ## [0.2.0-beta.12] - 2020-03-20
19 |
20 | ### Added
21 |
22 | - `defaultValues` prop.
23 |
24 | ### Security
25 |
26 | - Upgrade all upgradable dependencies.
27 |
28 | ## [0.2.0-beta.11] - 2020-02-21
29 |
30 | ### Fixed
31 |
32 | - `getDataFromPath` to `getDataFromPointer` as declared in the `README.md`.
33 |
34 | ## [0.2.0-beta.10] - 2020-02-21
35 |
36 | ### Fixed
37 |
38 | - Typo in `ErrorTypes`
39 |
40 | ### Added
41 |
42 | - `onChange` and `formProps` props to `FormContext`.
43 |
44 | ### Changed
45 |
46 | - **BREAKING**: no longer uses paths starting with `$` (which was added at version `0.2.0-beta.6`) and all 'paths' should now be relative to the JSON Schema, respecting the [RFC 6901](https://tools.ietf.org/html/rfc6901) which defines the string syntax for JSON Pointers, pay special attention to [section 6](https://tools.ietf.org/html/rfc6901#section-6) which defines the URI frament identifier representation of JSON pointers.
47 |
48 | ## [0.2.0-beta.9] - 2020-02-18
49 |
50 | ### Fixed
51 |
52 | - `notInEnum` to return expected value in `expected` field of the `ErrorMessage`.
53 |
54 | ## [0.2.0-beta.8] - 2020-02-17
55 |
56 | ### Changed
57 |
58 | - **BREAKING**: `number` error messages to now return messages describing whether the input does not match the expected pattern for a number.
59 |
60 | ## [0.2.0-beta.7] - 2020-02-14
61 |
62 | ### Changed
63 |
64 | - **BREAKING**: `onSubmit` now passes an object with `data`, `event` and `methods` as members to the callback.
65 |
66 | ## [0.2.0-beta.6] - 2020-02-13
67 |
68 | ### Added
69 |
70 | - `$ref` and `$id` resolving in accord to the [JSON Schema specification](https://tools.ietf.org/html/draft-wright-json-schema-01)
71 |
72 | ### Changed
73 |
74 | - **BREAKING**: Now uses paths starting with `$` to represent objects of an instance of the JSON Schema, instead of a path starting with `#`, which resembled a URI fragment identifier representation of a JSON pointer.
75 | - custom validator `context` parameter now gives info as an annotated sub schema
76 |
77 | ### Fixed
78 |
79 | - Not checking if value exists before using enum validation on it
80 | - `isRequired` not evaluating correctly if it is inside another object that is not required
81 | - Empty data not being ignored when parsing form data
82 |
83 | ## [0.2.0-beta.5] - 2020-02-11
84 |
85 | ### Added
86 |
87 | - `customValidators` to allow the user to define their own validation functions
88 |
89 | ### Changed
90 |
91 | - **BREAKING**: Renamed `FormValuesWithSchema` type to `JSONFormContextValues`
92 |
93 | ## [0.2.0-beta.4] - 2020-02-05
94 |
95 | ### Fixed
96 |
97 | - Returning non-filled form inputs in the object passed to onSubmit
98 |
99 | ## [0.2.0-beta.3] - 2020-01-31
100 |
101 | ### Changed
102 |
103 | - **BREAKING**: Changed `InputTypes` and `UITypes` enum values to reflect their enum names and what was documented in the `README`
104 | - **BREAKING**: Changed `min` and `max` props returned from `getInputProps()` to be strings, not numbers
105 | - **BREAKING**: Just re-exports types and `Controller` component from `react-hook-form`
106 |
107 | ## [0.2.0-beta.2] - 2020-01-30
108 |
109 | ### Fixed
110 |
111 | - type of onChange possibly being undefined
112 |
113 | ## [0.2.0-beta.1] - 2020-01-29
114 |
115 | ### Added
116 |
117 | - Added `useCheckbox` hook
118 |
119 | ### Changed
120 |
121 | - Changed the BasicInputReturnType to also return a reference to the validator used
122 | - **BREAKING**: The `useObject` hook now automatically associates a boolean to a checkbox
123 |
124 | ### Fixed
125 |
126 | - Fixed returned form data not converting string values that represent booleans to actual booleans
127 |
128 | ## [0.2.0-beta.0] - 2020-01-23
129 |
130 | ### Changed
131 |
132 | - Renamed `'mode'` prop on FormContext to `'validationMode'`
133 |
134 | ## [0.2.0-beta] - 2020-01-22
135 |
136 | ### Added
137 |
138 | - Now re-exports the `react-hook-form` public API
139 |
140 | ## [0.1.3] - 2020-01-21
141 |
142 | ### Added
143 |
144 | - Added test to make sure schema is not modified
145 |
146 | ### Changed
147 |
148 | - Fixed tons of typos on README
149 | - Made README more friendly
150 | - Refactored internal API to be more easily expandable
151 | - Removed complexity from big function bodies
152 |
153 | ## [0.1.2] - 2020-01-21
154 |
155 | ### Added
156 |
157 | - Typings for JSON Schema object
158 | - Removed unused mock
159 |
160 | ### Changed
161 |
162 | - Add typings for JSON Schema object
163 | - Build process is cleaner
164 | - React hook form is now an external dependency, not bundled with the code anymore
165 |
166 | ## [0.1.1] - 2020-01-17
167 |
168 | ### Added
169 |
170 | - Initial implementation.
171 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-hook-form-jsonschema
2 |
3 | > Small project based on [react-hook-form](https://github.com/react-hook-form/react-hook-form) that exposes an API for easily creating customizable forms based on a [JSON Schema](https://json-schema.org/understanding-json-schema/index.html) with built-in validation.
4 |
5 | `react-hook-form-jsonschema` is a React hooks library that manages all the stateful logic needed to make a functional form based on a JSON Schema. It returns a set of props that are meant to be called and their results destructured on the desired input field.
6 |
7 | Try a live demo on [CodeSandbox](https://codesandbox.io/s/react-hook-form-jsonschema-basic-example-u68o7)!
8 |
9 | [Supported JSON Schema keywords](#supported-json-schema-keywords)
10 |
11 | ## Table of Contents
12 |
13 | - [react-hook-form-jsonschema](#react-hook-form-jsonschema)
14 | - [Table of Contents](#table-of-contents)
15 | - [Simple Usage](#simple-usage)
16 | - [Installation](#installation)
17 | - [API](#api)
18 | - [Components API](#components-api)
19 | - [FormContext component API](#formcontext-component-api)
20 | - [Functions API](#functions-api)
21 | - [getDataFromPointer(pointer, data)](#getdatafrompointerpointer-data)
22 | - [Hooks API](#hooks-api)
23 | - [useCheckbox(pointer)](#usecheckboxpointer)
24 | - [useHidden(pointer)](#usehiddenpointer)
25 | - [useInput(pointer)](#useinputpointer)
26 | - [useObject(pointer, UISchema)](#useobjectpointer-uischema)
27 | - [usePassword(pointer)](#usepasswordpointer)
28 | - [useRadio(pointer)](#useradiopointer)
29 | - [useSelect(pointer)](#useselectpointer)
30 | - [useTextArea(pointer)](#usetextareapointer)
31 | - [Supported JSON Schema keywords](#supported-json-schema-keywords)
32 | - [TODO/Next Steps](#todonext-steps)
33 | - [Useful resources](#useful-resources)
34 |
35 | ## Simple Usage
36 |
37 | Suppose you have a simple JSON Schema that stores a person's first name:
38 |
39 | ```js
40 | const personSchema = {
41 | $id: 'https://example.com/person.schema.json',
42 | $schema: 'http://json-schema.org/draft-07/schema#',
43 | title: 'Person',
44 | type: 'object',
45 | properties: {
46 | firstName: {
47 | type: 'string',
48 | description: "The person's first name.",
49 | },
50 | },
51 | }
52 | ```
53 |
54 | And suppose you want to create a form field for the `firstName` field, simply use the `useInput()` hook and render the form using react:
55 |
56 | ```JSX
57 | function FirstNameField(props) {
58 | const inputMethods = useInput('#/properties/firstName');
59 |
60 | return (
61 |