@nolwenture/formik-jsonschema-form 0.1.3 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,46 +1,149 @@
1
- # Getting Started with Create React App
2
-
3
- This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4
-
5
- ## Available Scripts
6
-
7
- In the project directory, you can run:
8
-
9
- ### `npm start`
10
-
11
- Runs the app in the development mode.\
12
- Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13
-
14
- The page will reload if you make edits.\
15
- You will also see any lint errors in the console.
16
-
17
- ### `npm test`
18
-
19
- Launches the test runner in the interactive watch mode.\
20
- See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21
-
22
- ### `npm run build`
23
-
24
- Builds the app for production to the `build` folder.\
25
- It correctly bundles React in production mode and optimizes the build for the best performance.
26
-
27
- The build is minified and the filenames include the hashes.\
28
- Your app is ready to be deployed!
29
-
30
- See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31
-
32
- ### `npm run eject`
33
-
34
- **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35
-
36
- If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37
-
38
- Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39
-
40
- You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41
-
42
- ## Learn More
43
-
44
- You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45
-
46
- To learn React, check out the [React documentation](https://reactjs.org/).
1
+ # formik-jsonschema-form
2
+
3
+ ## Installation
4
+
5
+ With npm:
6
+
7
+ ```text
8
+ npm install @nolwenture/formik-jsonschema-form
9
+ ```
10
+
11
+ With yarn:
12
+
13
+ ```text
14
+ yarn add @nolwenture/formik-jsonschema-form
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### Basic usage
20
+
21
+ Pass your schema to the `Form` component, which should be passed as a child to the `Formik` component, for example:
22
+
23
+ ```tsx
24
+ import { Form } from "@nolwenture/formik-jsonschema-form";
25
+ import { Formik } from "formik";
26
+
27
+ const schema = {
28
+ title: "My form",
29
+ type: "object",
30
+ properties: {
31
+ firstName: { type: "string", title: "First name" },
32
+ lastName: { type: "string", title: "Last name" },
33
+ },
34
+ };
35
+
36
+ const uiSchema = {
37
+ "ui:description": "Form description",
38
+ firstName: { "ui:description": "Field description" },
39
+ };
40
+
41
+ export function MyFormComponent() {
42
+ return (
43
+ <Formik
44
+ initialValues={{ firstName: "", lastName: "" }}
45
+ onSubmit={handleSubmit}
46
+ >
47
+ <Form schema={schema} uiSchema={uiSchema}></Form>
48
+ </Formik>
49
+ );
50
+ }
51
+ ```
52
+
53
+ ### Using custom components
54
+
55
+ Form components (such as wrappers) can be overriden with custom ones
56
+
57
+ Here is an example of overriding `FieldWrapper` (wrapper used on all fields):
58
+
59
+ ```tsx
60
+ function CustomFieldWrapper({ children }) {
61
+ return (
62
+ <div
63
+ style={{
64
+ backgroundColor: "lightgrey",
65
+ boxShadow: "1px 1px 5px gray",
66
+ margin: "10px",
67
+ padding: "10px",
68
+ }}
69
+ >
70
+ {children}
71
+ </div>
72
+ );
73
+ }
74
+
75
+ ...
76
+
77
+ return (
78
+ <Formik initialValues={initialValues} onSubmit={handleOnSubmit}>
79
+ <Form
80
+ schema={schema}
81
+ uiSchema={uiSchema}
82
+ components={{
83
+ FieldWrapper: CustomFieldWrapper,
84
+ }}
85
+ ></Form>
86
+ </Formik>
87
+ );
88
+ ```
89
+
90
+ Custom fields can be used in addition to all the default fields:
91
+
92
+ ```tsx
93
+ import { Form, FormRegistry } from "@nolwenture/formik-jsonschema-form";
94
+ import { useContext } from "react";
95
+
96
+ const schema = {
97
+ title: "My form",
98
+ type: "object",
99
+ properties: {
100
+ firstField: { title: "First field" },
101
+ },
102
+ };
103
+
104
+ function MyCustomFieldComponent(props) {
105
+ const {
106
+ templates: { FieldTemplate },
107
+ } = useContext(FormRegistry);
108
+
109
+ return (
110
+ <FieldTemplate {...props}>
111
+ <p>My awesome field!</p>
112
+ </FieldTemplate>
113
+ );
114
+ }
115
+
116
+ const fields = { myField: MyCustomFieldComponent };
117
+
118
+ // Specify the fields that should use your custom field component in uiSchema
119
+ const uiSchema = {
120
+ firstField = { "ui:field": "myField" },
121
+ };
122
+
123
+ ...
124
+
125
+ return (
126
+ <Formik initialValues={initialValues} onSubmit={handleOnSubmit}>
127
+ <Form schema={schema} uiSchema={uiSchema} fields={fields}></Form>
128
+ </Formik>
129
+ );
130
+ ```
131
+
132
+ ## Props
133
+
134
+ `Form` component props:
135
+
136
+ ```tsx
137
+ <Form
138
+ // Required
139
+ schema={schema} // Form schema
140
+ // Optional
141
+ uiSchema={uiSchema} // Form UI schema
142
+ className={"className"} // Form class name
143
+ fields={fields} // Additional custom field components
144
+ templates={templates} // Additional custom field templates
145
+ components={components} // Override form components (e.g. wrappers) with custom ones
146
+ formContext={formContext} // Form context
147
+ useItemsAsAdditionalItems={true} // Allow "items" to be used as "additionalItems" in array fields that are missing "additionalItems", false by default
148
+ />
149
+ ```
package/dist/Form.js CHANGED
@@ -23,6 +23,7 @@ export var FormRegistry = React.createContext({
23
23
  definitions: {},
24
24
  formContext: {},
25
25
  useItemsAsAdditionalItems: false,
26
+ hideUnmarkedAdditionalProperties: false,
26
27
  });
27
28
  export function Form(props) {
28
29
  warnFromUnsupportedKeys("Form", props, [
@@ -37,7 +38,7 @@ export function Form(props) {
37
38
  "formContext",
38
39
  ]);
39
40
  var isSubmitting = useFormikContext().isSubmitting;
40
- var schema = props.schema, _a = props.uiSchema, uiSchema = _a === void 0 ? {} : _a, className = props.className, children = props.children, _b = props.fields, fields = _b === void 0 ? {} : _b, _c = props.templates, templates = _c === void 0 ? {} : _c, _d = props.components, components = _d === void 0 ? {} : _d, _e = props.formContext, formContext = _e === void 0 ? {} : _e, _f = props.useItemsAsAdditionalItems, useItemsAsAdditionalItems = _f === void 0 ? false : _f;
41
+ var schema = props.schema, _a = props.uiSchema, uiSchema = _a === void 0 ? {} : _a, className = props.className, children = props.children, _b = props.fields, fields = _b === void 0 ? {} : _b, _c = props.templates, templates = _c === void 0 ? {} : _c, _d = props.components, components = _d === void 0 ? {} : _d, _e = props.formContext, formContext = _e === void 0 ? {} : _e, _f = props.useItemsAsAdditionalItems, useItemsAsAdditionalItems = _f === void 0 ? false : _f, _g = props.hideUnmarkedAdditionalProperties, hideUnmarkedAdditionalProperties = _g === void 0 ? false : _g;
41
42
  var registry = {
42
43
  fields: __assign(__assign({}, defaultFields), fields),
43
44
  templates: __assign(__assign({}, defaultTemplates), templates),
@@ -45,8 +46,9 @@ export function Form(props) {
45
46
  definitions: {},
46
47
  formContext: formContext,
47
48
  useItemsAsAdditionalItems: useItemsAsAdditionalItems,
49
+ hideUnmarkedAdditionalProperties: hideUnmarkedAdditionalProperties,
48
50
  };
49
- var _g = registry.components, FormEl = _g.Form, FormButton = _g.FormButton, FormButtonWrapper = _g.FormButtonWrapper;
51
+ var _h = registry.components, FormEl = _h.Form, FormButton = _h.FormButton, FormButtonWrapper = _h.FormButtonWrapper;
50
52
  var _SchemaField = registry.fields.SchemaField;
51
53
  return (_jsx(FormRegistry.Provider, __assign({ value: registry }, { children: _jsxs(FormEl, __assign({ className: className }, { children: [_jsx(_SchemaField, { name: "", schema: schema, uiSchema: uiSchema }), children ? (children) : (_jsx(FormButtonWrapper, { children: _jsx(FormButton, __assign({ type: "submit", disabled: isSubmitting }, { children: "Send" })) }))] })) })));
52
54
  }
@@ -26,7 +26,7 @@ import { useContext, useMemo } from "react";
26
26
  import { FormRegistry } from "../Form";
27
27
  import { ObjectFieldButtonPurpose } from "../types";
28
28
  export function ObjectField(props) {
29
- var _a = useContext(FormRegistry), SchemaField = _a.fields.SchemaField, ObjectFieldTemplate = _a.templates.ObjectFieldTemplate, _b = _a.components, ObjectFieldItem = _b.ObjectFieldItem, ObjectFieldList = _b.ObjectFieldList, ObjectFieldItemButtons = _b.ObjectFieldItemButtons, ObjectFieldButton = _b.ObjectFieldButton;
29
+ var _a = useContext(FormRegistry), SchemaField = _a.fields.SchemaField, ObjectFieldTemplate = _a.templates.ObjectFieldTemplate, _b = _a.components, ObjectFieldItem = _b.ObjectFieldItem, ObjectFieldList = _b.ObjectFieldList, ObjectFieldItemButtons = _b.ObjectFieldItemButtons, ObjectFieldButton = _b.ObjectFieldButton, hideUnmarkedAdditionalProperties = _a.hideUnmarkedAdditionalProperties;
30
30
  var name = props.name, schema = props.schema, uiSchema = props.uiSchema;
31
31
  var _c = useField(name), value = _c[0].value, _ = _c[1], setValue = _c[2].setValue;
32
32
  var properties = schema.properties, additionalProperties = schema.additionalProperties;
@@ -40,13 +40,14 @@ export function ObjectField(props) {
40
40
  return (_jsxs(ObjectFieldTemplate, __assign({}, props, { children: [Object.entries(properties || {}).map(function (_a) {
41
41
  var childName = _a[0], childSchema = _a[1];
42
42
  return (_jsx(SchemaField, { name: name ? [name, childName].join(".") : childName, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema === null || uiSchema === void 0 ? void 0 : uiSchema[childName] }, childName));
43
- }), Object.entries(additionalValues || {}).map(function (_a) {
44
- var childName = _a[0], childSchema = _a[1];
45
- return (_jsxs(ObjectFieldItem, { children: [_jsx(SchemaField, { name: name ? [name, childName].join(".") : childName, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema === null || uiSchema === void 0 ? void 0 : uiSchema[childName] }, childName), _jsx(ObjectFieldItemButtons, { children: _jsx(ObjectFieldButton, { purpose: ObjectFieldButtonPurpose.REMOVE, onClick: function () {
46
- var _a = value, _b = childName, _removedProperty = _a[_b], newValue = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
47
- setValue(newValue);
48
- } }) })] }));
49
- }), additionalProperties && (_jsx(ObjectFieldButton, { purpose: ObjectFieldButtonPurpose.ADD, onClick: function () {
43
+ }), (!hideUnmarkedAdditionalProperties || additionalProperties) &&
44
+ Object.entries(additionalValues || {}).map(function (_a) {
45
+ var childName = _a[0], childSchema = _a[1];
46
+ return (_jsxs(ObjectFieldItem, { children: [_jsx(SchemaField, { name: name ? [name, childName].join(".") : childName, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema === null || uiSchema === void 0 ? void 0 : uiSchema[childName] }), _jsx(ObjectFieldItemButtons, { children: _jsx(ObjectFieldButton, { purpose: ObjectFieldButtonPurpose.REMOVE, onClick: function () {
47
+ var _a = value, _b = childName, _removedProperty = _a[_b], newValue = __rest(_a, [typeof _b === "symbol" ? _b : _b + ""]);
48
+ setValue(newValue);
49
+ } }) })] }, childName));
50
+ }), additionalProperties && (_jsx(ObjectFieldButton, { purpose: ObjectFieldButtonPurpose.ADD, onClick: function () {
50
51
  var _a;
51
52
  var key = prompt("Give key");
52
53
  if (key) {
@@ -1,11 +1,27 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
1
12
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
13
  import { useContext } from "react";
3
14
  import { FormRegistry } from "../Form";
4
- import { getDescription, getTitle } from "../utils";
15
+ import { getDescription, getTitle, useExtractUiSchema } from "../utils";
5
16
  export function ObjectFieldTemplate(props) {
6
- var _a = useContext(FormRegistry).components, FieldDescription = _a.FieldDescription, ObjectFieldTitle = _a.ObjectFieldTitle, ObjectFieldWrapper = _a.ObjectFieldWrapper;
7
- var children = props.children;
17
+ var _a = useContext(FormRegistry).components, FieldDescription = _a.FieldDescription, ObjectFieldTitle = _a.ObjectFieldTitle, ObjectFieldWrapper = _a.ObjectFieldWrapper, FieldHelp = _a.FieldHelp;
18
+ var children = props.children, uiSchema = props.uiSchema;
8
19
  var title = getTitle(props);
9
20
  var description = getDescription(props);
10
- return (_jsxs(ObjectFieldWrapper, { children: [title && _jsx(ObjectFieldTitle, { children: title }), description && _jsx(FieldDescription, { children: description }), children] }));
21
+ var _b = useExtractUiSchema(uiSchema), help = _b.help,
22
+ //TODO: This is not right
23
+ _c = _b.props,
24
+ //TODO: This is not right
25
+ _d = _c === void 0 ? {} : _c, wrapperProps = _d.wrapper, titleProps = _d.title, descriptionProps = _d.description, helpProps = _d.help;
26
+ return (_jsxs(ObjectFieldWrapper, __assign({}, wrapperProps, { children: [title && _jsx(ObjectFieldTitle, __assign({}, titleProps, { children: title })), description && _jsx(FieldDescription, __assign({}, descriptionProps, { children: description })), children, help && _jsx(FieldHelp, __assign({}, helpProps, { children: help }))] })));
11
27
  }
package/dist/types.d.ts CHANGED
@@ -5,6 +5,8 @@ export type FormProps<T> = React.PropsWithChildren<{
5
5
  disabled?: boolean | undefined;
6
6
  /** If true, array field schemas missing 'additionalItems' will replace it with 'items' */
7
7
  useItemsAsAdditionalItems?: boolean | undefined;
8
+ /** If true, properties in object fields' data that aren't in the schema will only be displayed if `additionalProperties` is enabled in the schema */
9
+ hideUnmarkedAdditionalProperties?: boolean;
8
10
  className?: string | undefined;
9
11
  /** Form schema */
10
12
  schema: Schema;
@@ -43,6 +45,7 @@ export type FormRegistryContextValue = {
43
45
  definitions: Record<string, any>;
44
46
  formContext: Record<string, any>;
45
47
  useItemsAsAdditionalItems: boolean;
48
+ hideUnmarkedAdditionalProperties: boolean;
46
49
  };
47
50
  export interface FieldProps extends Pick<React.HTMLAttributes<HTMLElement>, Exclude<keyof React.HTMLAttributes<HTMLElement>, "onBlur">> {
48
51
  name: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nolwenture/formik-jsonschema-form",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Formik form generation from json schema",
5
5
  "author": "Antti Vikman <antti.vikman@nolwenture.com>",
6
6
  "contributors": [