@nolwenture/formik-jsonschema-form 0.12.0 → 0.14.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 +83 -3
- package/dist/fields/ObjectField.js +4 -2
- package/dist/fields/TextAreaField.js +1 -2
- package/dist/utils/__tests/createValidationSchema.test.d.ts +1 -0
- package/dist/utils/__tests/createValidationSchema.test.js +136 -0
- package/dist/utils/__tests/orderByUiSchema.test.d.ts +1 -0
- package/dist/utils/__tests/orderByUiSchema.test.js +63 -0
- package/dist/utils/createValidationSchema.d.ts +3 -0
- package/dist/utils/createValidationSchema.js +47 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/orderByUiSchema.d.ts +1 -0
- package/dist/utils/orderByUiSchema.js +67 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -70,8 +70,7 @@ export function MyFormComponent() {
|
|
|
70
70
|
}
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
Pass your uiSchema to the `Form`component
|
|
74
|
-
just like schema. uiSchema will tell the form more about its own layout and styles.
|
|
73
|
+
Pass your uiSchema to the `Form`component, which should be passed as a child to the `Formik`component, just like schema. uiSchema will tell the form more about its own layout and styles.
|
|
75
74
|
|
|
76
75
|
Basic available elements to add to the form or a field of the form via uiSchema are:
|
|
77
76
|
|
|
@@ -131,6 +130,51 @@ export function MyFormComponent() {
|
|
|
131
130
|
}
|
|
132
131
|
```
|
|
133
132
|
|
|
133
|
+
### Using create-functions for initialValues and validationSchema
|
|
134
|
+
|
|
135
|
+
This library offers create-functions that, based on the JSON schema provided, will return a basic object of either initialValues or yup validationSchema.
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
import { Form } from "@nolwenture/formik-jsonschema-form";
|
|
139
|
+
import {
|
|
140
|
+
createInitialValues,
|
|
141
|
+
createValidationSchema,
|
|
142
|
+
} from "@nolwenture/formik-jsonschema-form/dist/utils";
|
|
143
|
+
import { Formik } from "formik";
|
|
144
|
+
|
|
145
|
+
const schema = {
|
|
146
|
+
title: "My form",
|
|
147
|
+
type: "object",
|
|
148
|
+
properties: {
|
|
149
|
+
firstName: { type: "string", title: "First name" },
|
|
150
|
+
lastName: { type: "string", title: "Last name" },
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const uiSchema = {
|
|
155
|
+
"ui:description": "Form description",
|
|
156
|
+
firstName: { "ui:description": "Field description" },
|
|
157
|
+
lastName: {
|
|
158
|
+
"ui:info": {
|
|
159
|
+
label: "?",
|
|
160
|
+
content: "Add your family name",
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export function MyFormComponent() {
|
|
166
|
+
return (
|
|
167
|
+
<Formik
|
|
168
|
+
initialValues={createInitialValues(schema)}
|
|
169
|
+
validationSchema={createValidationSchema(schema)}
|
|
170
|
+
onSubmit={handleSubmit}
|
|
171
|
+
>
|
|
172
|
+
<Form schema={schema} uiSchema={uiSchema}></Form>
|
|
173
|
+
</Formik>
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
134
178
|
### Using custom components
|
|
135
179
|
|
|
136
180
|
Form components (such as wrappers) can be overridden with custom ones
|
|
@@ -822,7 +866,7 @@ const refDefUiSchema: UiSchema = {
|
|
|
822
866
|
### Ordering fields
|
|
823
867
|
|
|
824
868
|
The order of fields can be set using `"ui:order": ["fieldName"]` inside the uiSchema.
|
|
825
|
-
If using "ui:order"
|
|
869
|
+
If using `"ui:order"`, all fields that should be visible in the form need to be included in the given array. Fields excluded will not show on the form, in the following they will be referred to as `"hidden fields"`.
|
|
826
870
|
|
|
827
871
|
```tsx
|
|
828
872
|
const schema = {
|
|
@@ -838,6 +882,42 @@ const uiSchema = {
|
|
|
838
882
|
};
|
|
839
883
|
```
|
|
840
884
|
|
|
885
|
+
Fields excluded will not show on the form. So in the following example "thirdField" will be a `hidden field`.
|
|
886
|
+
|
|
887
|
+
```tsx
|
|
888
|
+
const schema = {
|
|
889
|
+
properties: {
|
|
890
|
+
secondField: { type: "string" },
|
|
891
|
+
firstField: { type: "string" },
|
|
892
|
+
thirdField: { type: "string" },
|
|
893
|
+
},
|
|
894
|
+
};
|
|
895
|
+
|
|
896
|
+
const uiSchema = {
|
|
897
|
+
"ui:order": ["firstField", "secondField"],
|
|
898
|
+
};
|
|
899
|
+
```
|
|
900
|
+
|
|
901
|
+
Using `"*"`-wildcard inside the array will add all property fields that were not specifically added to the order-array.
|
|
902
|
+
|
|
903
|
+
```tsx
|
|
904
|
+
const schema = {
|
|
905
|
+
properties: {
|
|
906
|
+
secondField: { type: "string" },
|
|
907
|
+
firstField: { type: "string" },
|
|
908
|
+
thirdField: { type: "string" },
|
|
909
|
+
},
|
|
910
|
+
};
|
|
911
|
+
|
|
912
|
+
const uiSchema = {
|
|
913
|
+
"ui:order": ["secondField", "*"],
|
|
914
|
+
};
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
In this example, the resulting order would be ["secondField", "firstField", "thirdField"].
|
|
918
|
+
|
|
919
|
+
Wildcard `"*"` and `hidden fields` cannot be combined.
|
|
920
|
+
|
|
841
921
|
## Props
|
|
842
922
|
|
|
843
923
|
`Form` component props:
|
|
@@ -17,6 +17,7 @@ import { ObjectFieldButtonPurpose } from "../types";
|
|
|
17
17
|
import { resolveSchema } from "../utils/resolveSchema";
|
|
18
18
|
import { useSetDefault } from "../hooks";
|
|
19
19
|
import { getObjectFieldButton } from "../styledComponents";
|
|
20
|
+
import { orderByUiSchema } from "../utils";
|
|
20
21
|
const useObjectField = (name) => {
|
|
21
22
|
if (!name) {
|
|
22
23
|
const { values = {}, setValues } = useFormikContext();
|
|
@@ -26,7 +27,7 @@ const useObjectField = (name) => {
|
|
|
26
27
|
return { value, setValue };
|
|
27
28
|
};
|
|
28
29
|
export const ObjectField = (props) => {
|
|
29
|
-
var _a, _b
|
|
30
|
+
var _a, _b;
|
|
30
31
|
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate }, components: { ObjectFieldItem, ObjectFieldItemButtons }, hideUnmarkedAdditionalProperties, } = useContext(FormRegistry);
|
|
31
32
|
useSetDefault(props);
|
|
32
33
|
const { name, schema, uiSchema } = props;
|
|
@@ -48,7 +49,8 @@ export const ObjectField = (props) => {
|
|
|
48
49
|
const FieldTemplateComponent = ((_b = (_a = props.uiSchema) === null || _a === void 0 ? void 0 : _a.props) === null || _b === void 0 ? void 0 : _b.isCollapsible)
|
|
49
50
|
? CollapsibleObjectFieldTemplate
|
|
50
51
|
: ObjectFieldTemplate;
|
|
51
|
-
|
|
52
|
+
const orderedProperties = orderByUiSchema(uiSchema === null || uiSchema === void 0 ? void 0 : uiSchema["ui:order"], Object.keys(properties || {}));
|
|
53
|
+
return (_jsxs(FieldTemplateComponent, Object.assign({}, props, { children: [(orderedProperties !== null && orderedProperties !== void 0 ? orderedProperties : Object.keys(properties || {}))
|
|
52
54
|
.map((childName) => {
|
|
53
55
|
const childSchema = properties === null || properties === void 0 ? void 0 : properties[childName];
|
|
54
56
|
if (!childSchema)
|
|
@@ -2,9 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useContext } from "react";
|
|
3
3
|
import { FormRegistry } from "../Form";
|
|
4
4
|
import { useExtractUiSchema, useSetDefault } from "../hooks";
|
|
5
|
-
import { TextAreaInputField } from "../styledComponents";
|
|
6
5
|
export const TextAreaField = (props) => {
|
|
7
|
-
const { templates: { FieldTemplate }, } = useContext(FormRegistry);
|
|
6
|
+
const { templates: { FieldTemplate }, components: { TextAreaInputField }, } = useContext(FormRegistry);
|
|
8
7
|
useSetDefault(props);
|
|
9
8
|
const { name, uiSchema } = props;
|
|
10
9
|
const { props: inputProps } = useExtractUiSchema(uiSchema);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { ageFieldDefinition } from "../../sampleData/ageFieldDefinition";
|
|
11
|
+
import { createValidationSchema } from "../createValidationSchema";
|
|
12
|
+
const exampleSchema = {
|
|
13
|
+
title: "TITLE",
|
|
14
|
+
required: ["name", "age", "feeling"],
|
|
15
|
+
properties: {
|
|
16
|
+
name: { type: "string", title: "Full name" },
|
|
17
|
+
age: { $ref: "#/definitions/age" },
|
|
18
|
+
feeling: { type: "boolean", title: "Feeling happy today?" },
|
|
19
|
+
arrayOfObject: {
|
|
20
|
+
type: "array",
|
|
21
|
+
title: "Array of objects",
|
|
22
|
+
items: {
|
|
23
|
+
type: "object",
|
|
24
|
+
title: "Favourites",
|
|
25
|
+
required: ["favouriteFood"],
|
|
26
|
+
properties: {
|
|
27
|
+
favouriteFood: { type: "string", title: "Favourite food" },
|
|
28
|
+
favouriteSong: { type: "string", title: "Favourite song" },
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
additionalItems: {
|
|
32
|
+
type: "object",
|
|
33
|
+
title: "Second favourites",
|
|
34
|
+
required: ["anotherFavouriteSong"],
|
|
35
|
+
properties: {
|
|
36
|
+
anotherFavouriteFood: {
|
|
37
|
+
type: "string",
|
|
38
|
+
title: "Another favourite food",
|
|
39
|
+
},
|
|
40
|
+
anotherFavouriteSong: {
|
|
41
|
+
type: "string",
|
|
42
|
+
title: "Another favourite song",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
nestedObject: {
|
|
48
|
+
type: "object",
|
|
49
|
+
title: "Nested Object",
|
|
50
|
+
required: ["tasks"],
|
|
51
|
+
properties: {
|
|
52
|
+
hobbies: { type: "string", title: "Hobbies" },
|
|
53
|
+
tasks: { type: "string", title: "Tasks" },
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
definitions: {
|
|
58
|
+
age: ageFieldDefinition,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
const simpleExampleSchema = {
|
|
62
|
+
title: "TITLE",
|
|
63
|
+
required: ["lastName"],
|
|
64
|
+
properties: {
|
|
65
|
+
firstName: { type: "string", title: "First name" },
|
|
66
|
+
lastName: { type: "string", title: "Last name" },
|
|
67
|
+
age: { type: "number", title: "Age" },
|
|
68
|
+
drinksCoffee: { type: "boolean", title: "Do you drink coffee?" },
|
|
69
|
+
simpleArray: { type: "array", title: "Simple array" },
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
describe("Create Validation Schema", () => {
|
|
73
|
+
it("creates yup validationSchema based on given JSON schema", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
74
|
+
const result = createValidationSchema(exampleSchema);
|
|
75
|
+
const expected = result.isValidSync({
|
|
76
|
+
name: "Jane",
|
|
77
|
+
age: 54,
|
|
78
|
+
feeling: false,
|
|
79
|
+
arrayOfObject: [
|
|
80
|
+
{ favouriteFood: "Pizza!", favouriteSong: undefined },
|
|
81
|
+
{
|
|
82
|
+
anotherFavouriteFood: undefined,
|
|
83
|
+
anotherFavouriteSong: "On the turning away",
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
nestedObject: {
|
|
87
|
+
hobbies: undefined,
|
|
88
|
+
tasks: "buy groceries",
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
expect(expected).toEqual(true);
|
|
92
|
+
}));
|
|
93
|
+
it("throws error when required input is missing", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
94
|
+
const result = createValidationSchema(simpleExampleSchema);
|
|
95
|
+
yield expect(() => result.validate({
|
|
96
|
+
firstName: "Jane",
|
|
97
|
+
lastName: undefined,
|
|
98
|
+
age: 55,
|
|
99
|
+
})).rejects.toThrow("Required");
|
|
100
|
+
}));
|
|
101
|
+
it("throws error when given input is not matching defined type", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
|
+
const result = createValidationSchema(simpleExampleSchema);
|
|
103
|
+
// for 'number' type
|
|
104
|
+
yield expect(() => result.validate({
|
|
105
|
+
firstName: "Ella",
|
|
106
|
+
lastName: "Myller",
|
|
107
|
+
age: true,
|
|
108
|
+
drinksCoffee: false,
|
|
109
|
+
simpleArray: [],
|
|
110
|
+
}, { strict: true })).rejects.toThrow("age must be a `number` type, but the final value was: `true`.");
|
|
111
|
+
// for 'string' type
|
|
112
|
+
yield expect(() => result.validate({
|
|
113
|
+
firstName: 123,
|
|
114
|
+
lastName: "Myller",
|
|
115
|
+
age: 17,
|
|
116
|
+
drinksCoffee: false,
|
|
117
|
+
simpleArray: [],
|
|
118
|
+
}, { strict: true })).rejects.toThrow("firstName must be a `string` type, but the final value was: `123`.");
|
|
119
|
+
// for 'boolean' type
|
|
120
|
+
yield expect(() => result.validate({
|
|
121
|
+
firstName: "Ella",
|
|
122
|
+
lastName: "Myller",
|
|
123
|
+
age: 17,
|
|
124
|
+
drinksCoffee: "Well, sometimes...",
|
|
125
|
+
simpleArray: [],
|
|
126
|
+
}, { strict: true })).rejects.toThrow('drinksCoffee must be a `boolean` type, but the final value was: `"Well, sometimes..."`.');
|
|
127
|
+
// for 'array' type
|
|
128
|
+
yield expect(() => result.validate({
|
|
129
|
+
firstName: "Ella",
|
|
130
|
+
lastName: "Myller",
|
|
131
|
+
age: 17,
|
|
132
|
+
drinksCoffee: false,
|
|
133
|
+
simpleArray: "Hello :)",
|
|
134
|
+
}, { strict: true })).rejects.toThrow('simpleArray must be a `array` type, but the final value was: `"Hello :)"`.');
|
|
135
|
+
}));
|
|
136
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { orderByUiSchema } from "../orderByUiSchema";
|
|
2
|
+
const allProperties = ["firstName", "lastName", "age", "hobbies"];
|
|
3
|
+
const emptyOrder = undefined;
|
|
4
|
+
const noAsteriskOrder = ["firstName", "age"];
|
|
5
|
+
const asteriskAsFirstElement = ["*", "firstName"];
|
|
6
|
+
const asteriskAsLastElement = ["age", "*"];
|
|
7
|
+
const asteriskAsMiddleElement = ["hobbies", "*", "age"];
|
|
8
|
+
const orderWithDuplicates = ["age", "*", "age", "*", "lastName"];
|
|
9
|
+
describe("orderByUiSchema", () => {
|
|
10
|
+
it("returns empty array when ui:order is not given", () => {
|
|
11
|
+
const orderedProperties = orderByUiSchema(emptyOrder, allProperties);
|
|
12
|
+
expect(orderedProperties).toEqual(undefined);
|
|
13
|
+
});
|
|
14
|
+
it("returns only given properties when order includes no asterisk", () => {
|
|
15
|
+
const orderedProperties = orderByUiSchema(noAsteriskOrder, allProperties);
|
|
16
|
+
expect(orderedProperties).toEqual(["firstName", "age"]);
|
|
17
|
+
});
|
|
18
|
+
it("returns all properties in the given order with asterisk as first element", () => {
|
|
19
|
+
const orderedProperties = orderByUiSchema(asteriskAsFirstElement, allProperties);
|
|
20
|
+
expect(orderedProperties).toEqual([
|
|
21
|
+
"lastName",
|
|
22
|
+
"age",
|
|
23
|
+
"hobbies",
|
|
24
|
+
"firstName",
|
|
25
|
+
]);
|
|
26
|
+
});
|
|
27
|
+
it("returns all properties in the given order with asterisk as last element", () => {
|
|
28
|
+
const orderedProperties = orderByUiSchema(asteriskAsLastElement, allProperties);
|
|
29
|
+
expect(orderedProperties).toEqual([
|
|
30
|
+
"age",
|
|
31
|
+
"firstName",
|
|
32
|
+
"lastName",
|
|
33
|
+
"hobbies",
|
|
34
|
+
]);
|
|
35
|
+
});
|
|
36
|
+
it("returns all properties in the given order with asterisk as middle element", () => {
|
|
37
|
+
const orderedProperties = orderByUiSchema(asteriskAsMiddleElement, allProperties);
|
|
38
|
+
expect(orderedProperties).toEqual([
|
|
39
|
+
"hobbies",
|
|
40
|
+
"firstName",
|
|
41
|
+
"lastName",
|
|
42
|
+
"age",
|
|
43
|
+
]);
|
|
44
|
+
});
|
|
45
|
+
it("returns all properties in the given order with asterisk as middle element", () => {
|
|
46
|
+
const orderedProperties = orderByUiSchema(asteriskAsMiddleElement, allProperties);
|
|
47
|
+
expect(orderedProperties).toEqual([
|
|
48
|
+
"hobbies",
|
|
49
|
+
"firstName",
|
|
50
|
+
"lastName",
|
|
51
|
+
"age",
|
|
52
|
+
]);
|
|
53
|
+
});
|
|
54
|
+
it("ignores duplicates in order array to avoid errors", () => {
|
|
55
|
+
const orderedProperties = orderByUiSchema(orderWithDuplicates, allProperties);
|
|
56
|
+
expect(orderedProperties).toEqual([
|
|
57
|
+
"age",
|
|
58
|
+
"firstName",
|
|
59
|
+
"hobbies",
|
|
60
|
+
"lastName",
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { solveReferences } from "./solveReferences";
|
|
2
|
+
import * as Yup from "yup";
|
|
3
|
+
export function createValidationSchema(schema, definitions = {}) {
|
|
4
|
+
var _a;
|
|
5
|
+
if (!schema || !schema.properties) {
|
|
6
|
+
return Yup.object().shape({});
|
|
7
|
+
}
|
|
8
|
+
const schemaDefinitions = Object.assign(Object.assign({}, definitions), ((_a = schema.definitions) !== null && _a !== void 0 ? _a : {}));
|
|
9
|
+
const requiredFields = schema.required;
|
|
10
|
+
function getValue(schema, key) {
|
|
11
|
+
if (schema.properties) {
|
|
12
|
+
return createValidationSchema(schema, schemaDefinitions);
|
|
13
|
+
}
|
|
14
|
+
const type = schema.type;
|
|
15
|
+
let yupType;
|
|
16
|
+
switch (type) {
|
|
17
|
+
case "array":
|
|
18
|
+
yupType = Yup.array();
|
|
19
|
+
break;
|
|
20
|
+
case "boolean":
|
|
21
|
+
yupType = Yup.boolean();
|
|
22
|
+
break;
|
|
23
|
+
case "integer":
|
|
24
|
+
case "number":
|
|
25
|
+
yupType = Yup.number();
|
|
26
|
+
break;
|
|
27
|
+
case "null":
|
|
28
|
+
yupType = Yup.string().nullable();
|
|
29
|
+
break;
|
|
30
|
+
case "string":
|
|
31
|
+
yupType = Yup.string();
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
throw new Error("Unsupported schema type");
|
|
35
|
+
}
|
|
36
|
+
if (requiredFields !== undefined && requiredFields.includes(key)) {
|
|
37
|
+
yupType = yupType["required"]("Required");
|
|
38
|
+
}
|
|
39
|
+
return yupType;
|
|
40
|
+
}
|
|
41
|
+
return Object.keys(schema.properties).reduce((validationSchema, key) => {
|
|
42
|
+
var _a;
|
|
43
|
+
const value = (_a = schema.properties) === null || _a === void 0 ? void 0 : _a[key];
|
|
44
|
+
const solvedValue = solveReferences(value, schemaDefinitions, {}, {});
|
|
45
|
+
return validationSchema.concat(Yup.object().shape({ [key]: getValue(solvedValue.schema, key) }));
|
|
46
|
+
}, Yup.object().shape({}));
|
|
47
|
+
}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -6,4 +6,6 @@ export * from "./mergeSchemas";
|
|
|
6
6
|
export * from "./resolveSchema";
|
|
7
7
|
export * from "./solveReferences";
|
|
8
8
|
export * from "./createInitialValues";
|
|
9
|
+
export * from "./createValidationSchema";
|
|
10
|
+
export * from "./orderByUiSchema";
|
|
9
11
|
export declare const warnFromUnsupportedKeys: (componentName: string, data: Record<string, any>, supportedKeys: string[]) => void;
|
package/dist/utils/index.js
CHANGED
|
@@ -6,6 +6,8 @@ export * from "./mergeSchemas";
|
|
|
6
6
|
export * from "./resolveSchema";
|
|
7
7
|
export * from "./solveReferences";
|
|
8
8
|
export * from "./createInitialValues";
|
|
9
|
+
export * from "./createValidationSchema";
|
|
10
|
+
export * from "./orderByUiSchema";
|
|
9
11
|
//TODO: REMOVE WHEN ALL SUPPORTED
|
|
10
12
|
export const warnFromUnsupportedKeys = (componentName, data, supportedKeys) => {
|
|
11
13
|
Object.keys(data).forEach((key) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function orderByUiSchema(order: string[] | undefined, allProperties: string[]): string[] | undefined;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export function orderByUiSchema(order, allProperties) {
|
|
2
|
+
if (order !== undefined && allProperties !== undefined) {
|
|
3
|
+
if (order.includes("*")) {
|
|
4
|
+
return orderWithAsterisk(order, allProperties);
|
|
5
|
+
}
|
|
6
|
+
else {
|
|
7
|
+
return order;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
function orderWithAsterisk(order, allProperties) {
|
|
13
|
+
//to avoid issues when asterisk or other strings were wrongly given multiple times
|
|
14
|
+
const orderWithoutDuplicates = [...new Set(order)];
|
|
15
|
+
const indexOfAsterisk = orderWithoutDuplicates.indexOf("*");
|
|
16
|
+
const elementsBeforeAsterisk = indexOfAsterisk !== 0
|
|
17
|
+
? orderWithoutDuplicates.slice(0, indexOfAsterisk)
|
|
18
|
+
: undefined;
|
|
19
|
+
const elementsAfterAsterisk = indexOfAsterisk !== orderWithoutDuplicates.length - 1
|
|
20
|
+
? orderWithoutDuplicates.slice(indexOfAsterisk + 1, orderWithoutDuplicates.length)
|
|
21
|
+
: undefined;
|
|
22
|
+
let asteriskArray = [];
|
|
23
|
+
let finalOrderedArray = [];
|
|
24
|
+
if (elementsBeforeAsterisk === undefined &&
|
|
25
|
+
elementsAfterAsterisk === undefined) {
|
|
26
|
+
finalOrderedArray = allProperties;
|
|
27
|
+
}
|
|
28
|
+
if (elementsBeforeAsterisk !== undefined) {
|
|
29
|
+
finalOrderedArray = finalOrderedArray.concat(elementsBeforeAsterisk);
|
|
30
|
+
allProperties.map((property) => {
|
|
31
|
+
elementsBeforeAsterisk.map((e) => {
|
|
32
|
+
if (e !== property) {
|
|
33
|
+
asteriskArray.push(property);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
if (elementsAfterAsterisk === undefined) {
|
|
38
|
+
finalOrderedArray = finalOrderedArray.concat(asteriskArray);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (elementsAfterAsterisk !== undefined) {
|
|
42
|
+
if (asteriskArray.length === 0) {
|
|
43
|
+
allProperties.map((property) => {
|
|
44
|
+
elementsAfterAsterisk.map((e) => {
|
|
45
|
+
if (e !== property) {
|
|
46
|
+
asteriskArray.push(property);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
finalOrderedArray = finalOrderedArray.concat(asteriskArray);
|
|
51
|
+
finalOrderedArray = finalOrderedArray.concat(elementsAfterAsterisk);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
asteriskArray.map((property) => {
|
|
55
|
+
elementsAfterAsterisk.map((e) => {
|
|
56
|
+
if (e === property) {
|
|
57
|
+
const index = asteriskArray.indexOf(property);
|
|
58
|
+
asteriskArray.splice(index, 1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
finalOrderedArray = finalOrderedArray.concat(asteriskArray);
|
|
63
|
+
finalOrderedArray = finalOrderedArray.concat(elementsAfterAsterisk);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return finalOrderedArray;
|
|
67
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nolwenture/formik-jsonschema-form",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Formik form generation from json schema",
|
|
5
5
|
"author": "Antti Vikman <antti.vikman@nolwenture.com>",
|
|
6
6
|
"contributors": [
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
"json-schema": "^0.4.0",
|
|
40
40
|
"react": "^18.2.0",
|
|
41
41
|
"styled-components": "^6.1.8",
|
|
42
|
-
"typescript": "^5.4.3"
|
|
42
|
+
"typescript": "^5.4.3",
|
|
43
|
+
"yup": "^1.4.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@babel/preset-react": "^7.24.1",
|