@nolwenture/formik-jsonschema-form 0.26.8 → 0.27.1
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 +19 -0
- package/dist/cjs/Form.stories.js +8 -1
- package/dist/cjs/fields/ObjectField.js +18 -7
- package/dist/cjs/pdfFields/ObjectField.js +18 -7
- package/dist/cjs/pdfTemplates/ObjectSectionTemplate.js +11 -0
- package/dist/cjs/pdfTemplates/index.js +1 -0
- package/dist/cjs/sampleData/groupedData.js +20 -0
- package/dist/cjs/styledComponents.js +4 -2
- package/dist/cjs/templates/ObjectSectionTemplate.js +16 -0
- package/dist/cjs/templates/index.js +1 -0
- package/dist/cjs/utils/__tests/orderByUiSchema.test.js +22 -3
- package/dist/cjs/utils/orderByUiSchema.js +3 -2
- package/dist/esm/Form.stories.js +7 -0
- package/dist/esm/fields/ObjectField.js +18 -7
- package/dist/esm/pdfFields/ObjectField.js +18 -7
- package/dist/esm/pdfTemplates/ObjectSectionTemplate.js +7 -0
- package/dist/esm/pdfTemplates/index.js +1 -0
- package/dist/esm/sampleData/groupedData.js +17 -0
- package/dist/esm/styledComponents.js +2 -0
- package/dist/esm/templates/ObjectSectionTemplate.js +12 -0
- package/dist/esm/templates/index.js +1 -0
- package/dist/esm/utils/__tests/orderByUiSchema.test.js +22 -3
- package/dist/esm/utils/orderByUiSchema.js +3 -2
- package/dist/types/Form.stories.d.ts +1 -0
- package/dist/types/pdfTemplates/ObjectSectionTemplate.d.ts +3 -0
- package/dist/types/pdfTemplates/index.d.ts +1 -0
- package/dist/types/sampleData/groupedData.d.ts +7 -0
- package/dist/types/styledComponents.d.ts +2 -0
- package/dist/types/templates/ObjectSectionTemplate.d.ts +3 -0
- package/dist/types/templates/index.d.ts +1 -0
- package/dist/types/types.d.ts +13 -0
- package/dist/types/utils/orderByUiSchema.d.ts +6 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -989,6 +989,25 @@ const uiSchema = {
|
|
|
989
989
|
};
|
|
990
990
|
```
|
|
991
991
|
|
|
992
|
+
Order can be used to group items inside object to sections.
|
|
993
|
+
|
|
994
|
+
```tsx
|
|
995
|
+
const schema = {
|
|
996
|
+
properties: {
|
|
997
|
+
firstField: { type: "string" },
|
|
998
|
+
secondField: { type: "string" },
|
|
999
|
+
thirdField: { type: "string" },
|
|
1000
|
+
},
|
|
1001
|
+
};
|
|
1002
|
+
|
|
1003
|
+
const uiSchema = {
|
|
1004
|
+
"ui:order": [
|
|
1005
|
+
"firstField",
|
|
1006
|
+
{title: "More fields", fields: ["secondField", "thirdField"] collapsible: true}
|
|
1007
|
+
],
|
|
1008
|
+
};
|
|
1009
|
+
```
|
|
1010
|
+
|
|
992
1011
|
In this example, the resulting order would be ["secondField", "firstField", "thirdField"].
|
|
993
1012
|
|
|
994
1013
|
Wildcard `"*"` and `hidden fields` cannot be combined.
|
package/dist/cjs/Form.stories.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.HideSubmitButton = exports.FileUploadForm = exports.proExample = exports.Collapsible = exports.MultipleChoice = exports.WithRefAndDefinitions = exports.WithConditions = exports.WithRequiredInput = exports.WithGeneratedSchema = exports.StylesCustomized = exports.StrictlyTyped = exports.CompleteSchema = exports.WithUiSchema = exports.Simple = void 0;
|
|
6
|
+
exports.GroupedForm = exports.HideSubmitButton = exports.FileUploadForm = exports.proExample = exports.Collapsible = exports.MultipleChoice = exports.WithRefAndDefinitions = exports.WithConditions = exports.WithRequiredInput = exports.WithGeneratedSchema = exports.StylesCustomized = exports.StrictlyTyped = exports.CompleteSchema = exports.WithUiSchema = exports.Simple = void 0;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
8
|
const addon_actions_1 = require("@storybook/addon-actions");
|
|
9
9
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
@@ -15,6 +15,7 @@ const pdfProExampleSchema_1 = require("./sampleData/pdfProExampleSchema");
|
|
|
15
15
|
const fileUpload_1 = require("./sampleData/fileUpload");
|
|
16
16
|
const FileUploadContext_1 = require("./FileUploadContext");
|
|
17
17
|
const FileUploadField_stories_1 = require("./fields/stories/FileUploadField.stories");
|
|
18
|
+
const groupedData_1 = require("./sampleData/groupedData");
|
|
18
19
|
const MockFileUploadProvider = ({ children, }) => {
|
|
19
20
|
return ((0, jsx_runtime_1.jsx)(FileUploadContext_1.FileUploadContext.Provider, { value: {
|
|
20
21
|
uploadFile: FileUploadField_stories_1.mockUploadFile,
|
|
@@ -228,3 +229,9 @@ exports.HideSubmitButton = {
|
|
|
228
229
|
hideSubmit: true,
|
|
229
230
|
},
|
|
230
231
|
};
|
|
232
|
+
exports.GroupedForm = {
|
|
233
|
+
args: {
|
|
234
|
+
schema: groupedData_1.groupedSchema,
|
|
235
|
+
uiSchema: groupedData_1.groupedUiSchema,
|
|
236
|
+
},
|
|
237
|
+
};
|
|
@@ -19,7 +19,7 @@ const useObjectField = (name) => {
|
|
|
19
19
|
return { value, setValue };
|
|
20
20
|
};
|
|
21
21
|
const ObjectField = (props) => {
|
|
22
|
-
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate }, components: { ObjectFieldItem, ObjectFieldItemButtons }, hideUnmarkedAdditionalProperties, } = (0, react_1.useContext)(Form_1.FormRegistry);
|
|
22
|
+
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate, ObjectSectionTemplate, }, components: { ObjectFieldItem, ObjectFieldItemButtons }, hideUnmarkedAdditionalProperties, } = (0, react_1.useContext)(Form_1.FormRegistry);
|
|
23
23
|
(0, hooks_1.useSetDefault)(props);
|
|
24
24
|
const { name, schema, uiSchema } = props;
|
|
25
25
|
const { value, setValue } = useObjectField(name);
|
|
@@ -41,12 +41,23 @@ const ObjectField = (props) => {
|
|
|
41
41
|
? CollapsibleObjectFieldTemplate
|
|
42
42
|
: ObjectFieldTemplate;
|
|
43
43
|
const orderedProperties = (0, utils_1.orderByUiSchema)(uiSchema?.["ui:order"], Object.keys(properties || {}));
|
|
44
|
-
return ((0, jsx_runtime_1.jsxs)(FieldTemplateComponent, { ...props, "data-fjsf-object": name, children: [
|
|
45
|
-
.map((
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
return ((0, jsx_runtime_1.jsxs)(FieldTemplateComponent, { ...props, "data-fjsf-object": name, children: [orderedProperties
|
|
45
|
+
.map((child) => {
|
|
46
|
+
if (typeof child === "string") {
|
|
47
|
+
const childSchema = properties?.[child];
|
|
48
|
+
if (!childSchema)
|
|
49
|
+
return undefined;
|
|
50
|
+
return ((0, jsx_runtime_1.jsx)(SchemaField, { required: required?.includes(child), name: name ? [name, child].join(".") : child, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema?.[child] }, child));
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const { title, fields, collapsible } = child;
|
|
54
|
+
return ((0, jsx_runtime_1.jsx)(ObjectSectionTemplate, { title: title, collapsible: collapsible, children: fields.map((child2) => {
|
|
55
|
+
const childSchema = properties?.[child2];
|
|
56
|
+
if (!childSchema)
|
|
57
|
+
return undefined;
|
|
58
|
+
return ((0, jsx_runtime_1.jsx)(SchemaField, { name: name ? [name, child2].join(".") : child2, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema?.[child2] }, child2));
|
|
59
|
+
}) }, fields.join("_")));
|
|
60
|
+
}
|
|
50
61
|
})
|
|
51
62
|
.filter((x) => x), (!hideUnmarkedAdditionalProperties || additionalProperties) &&
|
|
52
63
|
Object.entries(additionalValues || {}).map(([childName]) => ((0, jsx_runtime_1.jsxs)(ObjectFieldItem, { children: [(0, jsx_runtime_1.jsx)(SchemaField, { required: required?.includes(childName), name: name ? [name, childName].join(".") : childName, schema: typeof schema.additionalProperties !== "boolean"
|
|
@@ -17,7 +17,7 @@ const useObjectField = (name) => {
|
|
|
17
17
|
return { value, setValue };
|
|
18
18
|
};
|
|
19
19
|
const ObjectField = (props) => {
|
|
20
|
-
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate }, } = (0, react_1.useContext)(FormPdf_1.FormPdfRegistry);
|
|
20
|
+
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate, ObjectSectionTemplate, }, } = (0, react_1.useContext)(FormPdf_1.FormPdfRegistry);
|
|
21
21
|
(0, hooks_1.useSetDefault)(props);
|
|
22
22
|
const { name, schema, uiSchema } = props;
|
|
23
23
|
const { value, setValue } = useObjectField(name);
|
|
@@ -37,12 +37,23 @@ const ObjectField = (props) => {
|
|
|
37
37
|
? CollapsibleObjectFieldTemplate
|
|
38
38
|
: ObjectFieldTemplate;
|
|
39
39
|
const orderedProperties = (0, utils_1.orderByUiSchema)(uiSchema?.["ui:order"], Object.keys(properties || {}));
|
|
40
|
-
return ((0, jsx_runtime_1.jsx)(FieldTemplateComponent, { ...props, children:
|
|
41
|
-
.map((
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
40
|
+
return ((0, jsx_runtime_1.jsx)(FieldTemplateComponent, { ...props, children: orderedProperties
|
|
41
|
+
.map((child, index) => {
|
|
42
|
+
if (typeof child === "string") {
|
|
43
|
+
const childSchema = properties?.[child];
|
|
44
|
+
if (!childSchema)
|
|
45
|
+
return undefined;
|
|
46
|
+
return ((0, jsx_runtime_1.jsx)(SchemaField, { name: name ? [name, child].join(".") : child, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema?.[child] }, child));
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const { title, fields } = child;
|
|
50
|
+
return ((0, jsx_runtime_1.jsx)(ObjectSectionTemplate, { title: title, children: fields.map((child2) => {
|
|
51
|
+
const childSchema = properties?.[child2];
|
|
52
|
+
if (!childSchema)
|
|
53
|
+
return undefined;
|
|
54
|
+
return ((0, jsx_runtime_1.jsx)(SchemaField, { name: name ? [name, child2].join(".") : child2, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema?.[child2] }, child2));
|
|
55
|
+
}) }, fields.join("_")));
|
|
56
|
+
}
|
|
46
57
|
})
|
|
47
58
|
.filter((x) => x) }));
|
|
48
59
|
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ObjectSectionTemplate = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const Form_1 = require("../Form");
|
|
7
|
+
const ObjectSectionTemplate = ({ title, children, }) => {
|
|
8
|
+
const { components: { ObjectFieldSection, ObjectFieldSectionTitle }, } = (0, react_1.useContext)(Form_1.FormRegistry);
|
|
9
|
+
return ((0, jsx_runtime_1.jsxs)(ObjectFieldSection, { children: [(0, jsx_runtime_1.jsx)(ObjectFieldSectionTitle, { children: title }), children] }));
|
|
10
|
+
};
|
|
11
|
+
exports.ObjectSectionTemplate = ObjectSectionTemplate;
|
|
@@ -18,3 +18,4 @@ __exportStar(require("./ArrayFieldTemplate"), exports);
|
|
|
18
18
|
__exportStar(require("./FieldTemplate"), exports);
|
|
19
19
|
__exportStar(require("./ObjectFieldTemplate"), exports);
|
|
20
20
|
__exportStar(require("./CollapsibleObjectFieldTemplate"), exports);
|
|
21
|
+
__exportStar(require("./ObjectSectionTemplate"), exports);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.groupedUiSchema = exports.groupedSchema = void 0;
|
|
4
|
+
exports.groupedSchema = {
|
|
5
|
+
title: "TITLE",
|
|
6
|
+
required: ["firstName"],
|
|
7
|
+
properties: {
|
|
8
|
+
firstName: { type: "string", title: "First name" },
|
|
9
|
+
lastName: { type: "string", title: "Last name" },
|
|
10
|
+
age: { type: "number", title: "Age" },
|
|
11
|
+
hoppy: { type: "string", title: "Hoppy" },
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
exports.groupedUiSchema = {
|
|
15
|
+
"ui:order": [
|
|
16
|
+
{ title: "Names", fields: ["firstName", "lastName"], collapsible: true },
|
|
17
|
+
"*",
|
|
18
|
+
"hoppy",
|
|
19
|
+
],
|
|
20
|
+
};
|
|
@@ -26,8 +26,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.
|
|
30
|
-
exports.FileUploadField = exports.FileUploadFieldContainer = exports.FileInfoText = exports.RemoveButton = exports.FileItemContainer = exports.ProgressText = exports.ProgressBar = exports.ProgressBarContainer = exports.HiddenFileInput = exports.FileUploadButton = exports.MultipleChoiceFieldPdf = exports.BooleanFieldPdf = exports.EJSField = exports.TextAreaPdf = exports.StringFieldPdf = exports.SearchInputContainer = exports.SearchClearButton = exports.SearchInput = exports.SearchNotFound = exports.SearchListExpand = exports.SearchListOption = exports.SearchDropdownContainer = exports.SearchableSelectContainer = exports.CollapsibleObjectFieldTitle = exports.CollapsibleObjectFieldWrapper = exports.CollapsibleChildWrapper = exports.Icon = exports.CollapsibleToggle = exports.Clickable = exports.BooleanFieldWrapper = exports.TextAreaInputField = exports.TextAreaFieldInput = exports.SearchableMultiTagSelectField = exports.MultiSelectOptionListWithoutItem = exports.MultiSelectOptionListItem = exports.MultiSelectOptionList = exports.MultiSelectBadgeCloseElement = exports.MultiSelectBadge = exports.MultiSelectBadgeContainer = exports.MultiSelectInput = exports.MultiSelectSearchContainer = exports.MultiSelectContainer = exports.MultipleChoiceField = exports.MultipleChoiceFieldLabel = exports.MultipleChoiceFieldInput = exports.MultipleChoiceFieldElement = exports.MultipleChoiceFieldContainer = void 0;
|
|
29
|
+
exports.ButtonLabelTrue = exports.ButtonLabel = exports.RadioButtonFieldInput = exports.RadioButtonFieldElement = exports.RadioButtonFieldContainer = exports.ToggleSwitchField = exports.ToggleFieldInput = exports.ToggleLabel = exports.Toggle = exports.RequiredIndicator = exports.FieldInput = exports.ErrorMessage = exports.InfoFieldButton = exports.InfoFieldLabel = exports.InfoFieldContainerElement = exports.InfoFieldBoxInnerElement = exports.InfoFieldBoxArrowElement = exports.InfoFieldBoxElement = exports.FieldHelp = exports.FieldDescription = exports.FieldTitle = exports.FieldWrapper = exports.ArrayFieldAddButton = exports.ArrayFieldRemoveButton = exports.ArrayFieldDownButton = exports.ArrayFieldUpButton = exports.ArrayFieldLineButton = exports.ArrayFieldButton = exports.ArrayFieldItemButtons = exports.ArrayFieldItem = exports.ArrayFieldList = exports.ArrayFieldTitle = exports.ArrayFieldWrapper = exports.ObjectFieldSectionTitle = exports.ObjectFieldSection = exports.getObjectFieldButton = exports.ObjectFieldAddButton = exports.ObjectFieldRemoveButton = exports.ObjectFieldDownButton = exports.ObjectFieldUpButton = exports.ObjectFieldLineButton = exports.ObjectFieldButton = exports.ObjectFieldItemButtons = exports.ObjectFieldItem = exports.ObjectFieldList = exports.ObjectFieldTitle = exports.ObjectFieldWrapper = exports.FormButton = exports.FormButtonWrapper = exports.Form = void 0;
|
|
30
|
+
exports.FileUploadField = exports.FileUploadFieldContainer = exports.FileInfoText = exports.RemoveButton = exports.FileItemContainer = exports.ProgressText = exports.ProgressBar = exports.ProgressBarContainer = exports.HiddenFileInput = exports.FileUploadButton = exports.MultipleChoiceFieldPdf = exports.BooleanFieldPdf = exports.EJSField = exports.TextAreaPdf = exports.StringFieldPdf = exports.SearchInputContainer = exports.SearchClearButton = exports.SearchInput = exports.SearchNotFound = exports.SearchListExpand = exports.SearchListOption = exports.SearchDropdownContainer = exports.SearchableSelectContainer = exports.CollapsibleObjectFieldTitle = exports.CollapsibleObjectFieldWrapper = exports.CollapsibleChildWrapper = exports.Icon = exports.CollapsibleToggle = exports.Clickable = exports.BooleanFieldWrapper = exports.TextAreaInputField = exports.TextAreaFieldInput = exports.SearchableMultiTagSelectField = exports.MultiSelectOptionListWithoutItem = exports.MultiSelectOptionListItem = exports.MultiSelectOptionList = exports.MultiSelectBadgeCloseElement = exports.MultiSelectBadge = exports.MultiSelectBadgeContainer = exports.MultiSelectInput = exports.MultiSelectSearchContainer = exports.MultiSelectContainer = exports.MultipleChoiceField = exports.MultipleChoiceFieldLabel = exports.MultipleChoiceFieldInput = exports.MultipleChoiceFieldElement = exports.MultipleChoiceFieldContainer = exports.RadioButtonField = exports.ButtonLabelFalse = void 0;
|
|
31
31
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
32
32
|
const formik = __importStar(require("formik"));
|
|
33
33
|
const react_1 = require("react");
|
|
@@ -77,6 +77,8 @@ const getObjectFieldButton = ({ purpose, onClick, uiSchema, }) => {
|
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
exports.getObjectFieldButton = getObjectFieldButton;
|
|
80
|
+
exports.ObjectFieldSection = styled_components_1.default.fieldset ``;
|
|
81
|
+
exports.ObjectFieldSectionTitle = styled_components_1.default.legend ``;
|
|
80
82
|
exports.ArrayFieldWrapper = exports.ObjectFieldWrapper;
|
|
81
83
|
exports.ArrayFieldTitle = exports.ObjectFieldTitle;
|
|
82
84
|
exports.ArrayFieldList = exports.ObjectFieldList;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ObjectSectionTemplate = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const Form_1 = require("../Form");
|
|
7
|
+
const ObjectSectionTemplate = ({ title, collapsible, children, }) => {
|
|
8
|
+
const [collapsed, setCollapsed] = (0, react_1.useState)(collapsible);
|
|
9
|
+
const { components: { ObjectFieldSection, ObjectFieldSectionTitle }, } = (0, react_1.useContext)(Form_1.FormRegistry);
|
|
10
|
+
return ((0, jsx_runtime_1.jsxs)(ObjectFieldSection, { children: [(0, jsx_runtime_1.jsxs)(ObjectFieldSectionTitle, { onClick: () => {
|
|
11
|
+
if (collapsible) {
|
|
12
|
+
setCollapsed((currentState) => !currentState);
|
|
13
|
+
}
|
|
14
|
+
}, children: [collapsible && (collapsed ? "▸" : "▾"), title] }), !collapsed && children] }));
|
|
15
|
+
};
|
|
16
|
+
exports.ObjectSectionTemplate = ObjectSectionTemplate;
|
|
@@ -18,3 +18,4 @@ __exportStar(require("./ArrayFieldTemplate"), exports);
|
|
|
18
18
|
__exportStar(require("./FieldTemplate"), exports);
|
|
19
19
|
__exportStar(require("./ObjectFieldTemplate"), exports);
|
|
20
20
|
__exportStar(require("./CollapsibleObjectFieldTemplate"), exports);
|
|
21
|
+
__exportStar(require("./ObjectSectionTemplate"), exports);
|
|
@@ -7,11 +7,22 @@ const noAsteriskOrder = ["firstName", "age"];
|
|
|
7
7
|
const asteriskAsFirstElement = ["*", "firstName"];
|
|
8
8
|
const asteriskAsLastElement = ["age", "*"];
|
|
9
9
|
const asteriskAsMiddleElement = ["hobbies", "*", "age"];
|
|
10
|
-
const orderWithDuplicates = [
|
|
10
|
+
const orderWithDuplicates = [
|
|
11
|
+
"age",
|
|
12
|
+
"*",
|
|
13
|
+
"age",
|
|
14
|
+
"*",
|
|
15
|
+
"lastName",
|
|
16
|
+
];
|
|
17
|
+
const orderWithGroups = [
|
|
18
|
+
{ title: "names", fields: ["firstName", "lastName"] },
|
|
19
|
+
"*",
|
|
20
|
+
"hobbies",
|
|
21
|
+
];
|
|
11
22
|
describe("orderByUiSchema", () => {
|
|
12
|
-
it("returns
|
|
23
|
+
it("returns allProperties when ui:order is not given", () => {
|
|
13
24
|
const orderedProperties = (0, orderByUiSchema_1.orderByUiSchema)(emptyOrder, allProperties);
|
|
14
|
-
expect(orderedProperties).toEqual(
|
|
25
|
+
expect(orderedProperties).toEqual(allProperties);
|
|
15
26
|
});
|
|
16
27
|
it("returns only given properties when order includes no asterisk", () => {
|
|
17
28
|
const orderedProperties = (0, orderByUiSchema_1.orderByUiSchema)(noAsteriskOrder, allProperties);
|
|
@@ -62,4 +73,12 @@ describe("orderByUiSchema", () => {
|
|
|
62
73
|
"lastName",
|
|
63
74
|
]);
|
|
64
75
|
});
|
|
76
|
+
it("solves groups properly", () => {
|
|
77
|
+
const orderedProperties = (0, orderByUiSchema_1.orderByUiSchema)(orderWithGroups, allProperties);
|
|
78
|
+
expect(orderedProperties).toMatchObject([
|
|
79
|
+
{ title: "names", fields: ["firstName", "lastName"] },
|
|
80
|
+
"age",
|
|
81
|
+
"hobbies",
|
|
82
|
+
]);
|
|
83
|
+
});
|
|
65
84
|
});
|
|
@@ -10,14 +10,15 @@ function orderByUiSchema(order, allProperties) {
|
|
|
10
10
|
return order;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
return
|
|
13
|
+
return allProperties;
|
|
14
14
|
}
|
|
15
15
|
function orderWithAsterisk(order, allProperties) {
|
|
16
16
|
const orderWithoutDuplicates = [...new Set(order)];
|
|
17
|
+
const fieldsInOrder = orderWithoutDuplicates.flatMap((entry) => typeof entry === "string" ? entry : entry.fields);
|
|
17
18
|
const finalOrderedArray = [];
|
|
18
19
|
orderWithoutDuplicates.forEach((element) => {
|
|
19
20
|
if (element === "*") {
|
|
20
|
-
const propertiesWithoutOrder = allProperties.filter((prop) => !
|
|
21
|
+
const propertiesWithoutOrder = allProperties.filter((prop) => !fieldsInOrder.includes(prop));
|
|
21
22
|
finalOrderedArray.push(...propertiesWithoutOrder);
|
|
22
23
|
}
|
|
23
24
|
else {
|
package/dist/esm/Form.stories.js
CHANGED
|
@@ -9,6 +9,7 @@ import { pdfProExampleSchema, pdfProExampleUiSchema, } from "./sampleData/pdfPro
|
|
|
9
9
|
import { fileUploadSchema, fileUploadUiSchema } from "./sampleData/fileUpload";
|
|
10
10
|
import { FileUploadContext } from "./FileUploadContext";
|
|
11
11
|
import { mockFetchFile, mockRemoveFile, mockUploadFile, } from "./fields/stories/FileUploadField.stories";
|
|
12
|
+
import { groupedSchema, groupedUiSchema } from "./sampleData/groupedData";
|
|
12
13
|
const MockFileUploadProvider = ({ children, }) => {
|
|
13
14
|
return (_jsx(FileUploadContext.Provider, { value: {
|
|
14
15
|
uploadFile: mockUploadFile,
|
|
@@ -220,3 +221,9 @@ export const HideSubmitButton = {
|
|
|
220
221
|
hideSubmit: true,
|
|
221
222
|
},
|
|
222
223
|
};
|
|
224
|
+
export const GroupedForm = {
|
|
225
|
+
args: {
|
|
226
|
+
schema: groupedSchema,
|
|
227
|
+
uiSchema: groupedUiSchema,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
@@ -16,7 +16,7 @@ const useObjectField = (name) => {
|
|
|
16
16
|
return { value, setValue };
|
|
17
17
|
};
|
|
18
18
|
export const ObjectField = (props) => {
|
|
19
|
-
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate }, components: { ObjectFieldItem, ObjectFieldItemButtons }, hideUnmarkedAdditionalProperties, } = useContext(FormRegistry);
|
|
19
|
+
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate, ObjectSectionTemplate, }, components: { ObjectFieldItem, ObjectFieldItemButtons }, hideUnmarkedAdditionalProperties, } = useContext(FormRegistry);
|
|
20
20
|
useSetDefault(props);
|
|
21
21
|
const { name, schema, uiSchema } = props;
|
|
22
22
|
const { value, setValue } = useObjectField(name);
|
|
@@ -38,12 +38,23 @@ export const ObjectField = (props) => {
|
|
|
38
38
|
? CollapsibleObjectFieldTemplate
|
|
39
39
|
: ObjectFieldTemplate;
|
|
40
40
|
const orderedProperties = orderByUiSchema(uiSchema?.["ui:order"], Object.keys(properties || {}));
|
|
41
|
-
return (_jsxs(FieldTemplateComponent, { ...props, "data-fjsf-object": name, children: [
|
|
42
|
-
.map((
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
41
|
+
return (_jsxs(FieldTemplateComponent, { ...props, "data-fjsf-object": name, children: [orderedProperties
|
|
42
|
+
.map((child) => {
|
|
43
|
+
if (typeof child === "string") {
|
|
44
|
+
const childSchema = properties?.[child];
|
|
45
|
+
if (!childSchema)
|
|
46
|
+
return undefined;
|
|
47
|
+
return (_jsx(SchemaField, { required: required?.includes(child), name: name ? [name, child].join(".") : child, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema?.[child] }, child));
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const { title, fields, collapsible } = child;
|
|
51
|
+
return (_jsx(ObjectSectionTemplate, { title: title, collapsible: collapsible, children: fields.map((child2) => {
|
|
52
|
+
const childSchema = properties?.[child2];
|
|
53
|
+
if (!childSchema)
|
|
54
|
+
return undefined;
|
|
55
|
+
return (_jsx(SchemaField, { name: name ? [name, child2].join(".") : child2, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema?.[child2] }, child2));
|
|
56
|
+
}) }, fields.join("_")));
|
|
57
|
+
}
|
|
47
58
|
})
|
|
48
59
|
.filter((x) => x), (!hideUnmarkedAdditionalProperties || additionalProperties) &&
|
|
49
60
|
Object.entries(additionalValues || {}).map(([childName]) => (_jsxs(ObjectFieldItem, { children: [_jsx(SchemaField, { required: required?.includes(childName), name: name ? [name, childName].join(".") : childName, schema: typeof schema.additionalProperties !== "boolean"
|
|
@@ -14,7 +14,7 @@ const useObjectField = (name) => {
|
|
|
14
14
|
return { value, setValue };
|
|
15
15
|
};
|
|
16
16
|
export const ObjectField = (props) => {
|
|
17
|
-
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate }, } = useContext(FormPdfRegistry);
|
|
17
|
+
const { fields: { SchemaField }, templates: { ObjectFieldTemplate, CollapsibleObjectFieldTemplate, ObjectSectionTemplate, }, } = useContext(FormPdfRegistry);
|
|
18
18
|
useSetDefault(props);
|
|
19
19
|
const { name, schema, uiSchema } = props;
|
|
20
20
|
const { value, setValue } = useObjectField(name);
|
|
@@ -34,12 +34,23 @@ export const ObjectField = (props) => {
|
|
|
34
34
|
? CollapsibleObjectFieldTemplate
|
|
35
35
|
: ObjectFieldTemplate;
|
|
36
36
|
const orderedProperties = orderByUiSchema(uiSchema?.["ui:order"], Object.keys(properties || {}));
|
|
37
|
-
return (_jsx(FieldTemplateComponent, { ...props, children:
|
|
38
|
-
.map((
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
return (_jsx(FieldTemplateComponent, { ...props, children: orderedProperties
|
|
38
|
+
.map((child, index) => {
|
|
39
|
+
if (typeof child === "string") {
|
|
40
|
+
const childSchema = properties?.[child];
|
|
41
|
+
if (!childSchema)
|
|
42
|
+
return undefined;
|
|
43
|
+
return (_jsx(SchemaField, { name: name ? [name, child].join(".") : child, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema?.[child] }, child));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const { title, fields } = child;
|
|
47
|
+
return (_jsx(ObjectSectionTemplate, { title: title, children: fields.map((child2) => {
|
|
48
|
+
const childSchema = properties?.[child2];
|
|
49
|
+
if (!childSchema)
|
|
50
|
+
return undefined;
|
|
51
|
+
return (_jsx(SchemaField, { name: name ? [name, child2].join(".") : child2, schema: typeof childSchema !== "boolean" ? childSchema : {}, uiSchema: uiSchema?.[child2] }, child2));
|
|
52
|
+
}) }, fields.join("_")));
|
|
53
|
+
}
|
|
43
54
|
})
|
|
44
55
|
.filter((x) => x) }));
|
|
45
56
|
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useContext } from "react";
|
|
3
|
+
import { FormRegistry } from "../Form";
|
|
4
|
+
export const ObjectSectionTemplate = ({ title, children, }) => {
|
|
5
|
+
const { components: { ObjectFieldSection, ObjectFieldSectionTitle }, } = useContext(FormRegistry);
|
|
6
|
+
return (_jsxs(ObjectFieldSection, { children: [_jsx(ObjectFieldSectionTitle, { children: title }), children] }));
|
|
7
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const groupedSchema = {
|
|
2
|
+
title: "TITLE",
|
|
3
|
+
required: ["firstName"],
|
|
4
|
+
properties: {
|
|
5
|
+
firstName: { type: "string", title: "First name" },
|
|
6
|
+
lastName: { type: "string", title: "Last name" },
|
|
7
|
+
age: { type: "number", title: "Age" },
|
|
8
|
+
hoppy: { type: "string", title: "Hoppy" },
|
|
9
|
+
},
|
|
10
|
+
};
|
|
11
|
+
export const groupedUiSchema = {
|
|
12
|
+
"ui:order": [
|
|
13
|
+
{ title: "Names", fields: ["firstName", "lastName"], collapsible: true },
|
|
14
|
+
"*",
|
|
15
|
+
"hoppy",
|
|
16
|
+
],
|
|
17
|
+
};
|
|
@@ -46,6 +46,8 @@ export const getObjectFieldButton = ({ purpose, onClick, uiSchema, }) => {
|
|
|
46
46
|
return (_jsx(ObjectFieldButton, { ...(uiSchema?.["ui:customButtonOptions"]?.props ?? {}), onClick: onClick, children: uiSchema?.["ui:customButtonOptions"]?.content ?? "" }));
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
+
export const ObjectFieldSection = styled.fieldset ``;
|
|
50
|
+
export const ObjectFieldSectionTitle = styled.legend ``;
|
|
49
51
|
export const ArrayFieldWrapper = ObjectFieldWrapper;
|
|
50
52
|
export const ArrayFieldTitle = ObjectFieldTitle;
|
|
51
53
|
export const ArrayFieldList = ObjectFieldList;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useContext, useState } from "react";
|
|
3
|
+
import { FormRegistry } from "../Form";
|
|
4
|
+
export const ObjectSectionTemplate = ({ title, collapsible, children, }) => {
|
|
5
|
+
const [collapsed, setCollapsed] = useState(collapsible);
|
|
6
|
+
const { components: { ObjectFieldSection, ObjectFieldSectionTitle }, } = useContext(FormRegistry);
|
|
7
|
+
return (_jsxs(ObjectFieldSection, { children: [_jsxs(ObjectFieldSectionTitle, { onClick: () => {
|
|
8
|
+
if (collapsible) {
|
|
9
|
+
setCollapsed((currentState) => !currentState);
|
|
10
|
+
}
|
|
11
|
+
}, children: [collapsible && (collapsed ? "▸" : "▾"), title] }), !collapsed && children] }));
|
|
12
|
+
};
|
|
@@ -5,11 +5,22 @@ const noAsteriskOrder = ["firstName", "age"];
|
|
|
5
5
|
const asteriskAsFirstElement = ["*", "firstName"];
|
|
6
6
|
const asteriskAsLastElement = ["age", "*"];
|
|
7
7
|
const asteriskAsMiddleElement = ["hobbies", "*", "age"];
|
|
8
|
-
const orderWithDuplicates = [
|
|
8
|
+
const orderWithDuplicates = [
|
|
9
|
+
"age",
|
|
10
|
+
"*",
|
|
11
|
+
"age",
|
|
12
|
+
"*",
|
|
13
|
+
"lastName",
|
|
14
|
+
];
|
|
15
|
+
const orderWithGroups = [
|
|
16
|
+
{ title: "names", fields: ["firstName", "lastName"] },
|
|
17
|
+
"*",
|
|
18
|
+
"hobbies",
|
|
19
|
+
];
|
|
9
20
|
describe("orderByUiSchema", () => {
|
|
10
|
-
it("returns
|
|
21
|
+
it("returns allProperties when ui:order is not given", () => {
|
|
11
22
|
const orderedProperties = orderByUiSchema(emptyOrder, allProperties);
|
|
12
|
-
expect(orderedProperties).toEqual(
|
|
23
|
+
expect(orderedProperties).toEqual(allProperties);
|
|
13
24
|
});
|
|
14
25
|
it("returns only given properties when order includes no asterisk", () => {
|
|
15
26
|
const orderedProperties = orderByUiSchema(noAsteriskOrder, allProperties);
|
|
@@ -60,4 +71,12 @@ describe("orderByUiSchema", () => {
|
|
|
60
71
|
"lastName",
|
|
61
72
|
]);
|
|
62
73
|
});
|
|
74
|
+
it("solves groups properly", () => {
|
|
75
|
+
const orderedProperties = orderByUiSchema(orderWithGroups, allProperties);
|
|
76
|
+
expect(orderedProperties).toMatchObject([
|
|
77
|
+
{ title: "names", fields: ["firstName", "lastName"] },
|
|
78
|
+
"age",
|
|
79
|
+
"hobbies",
|
|
80
|
+
]);
|
|
81
|
+
});
|
|
63
82
|
});
|
|
@@ -7,14 +7,15 @@ export function orderByUiSchema(order, allProperties) {
|
|
|
7
7
|
return order;
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
return
|
|
10
|
+
return allProperties;
|
|
11
11
|
}
|
|
12
12
|
function orderWithAsterisk(order, allProperties) {
|
|
13
13
|
const orderWithoutDuplicates = [...new Set(order)];
|
|
14
|
+
const fieldsInOrder = orderWithoutDuplicates.flatMap((entry) => typeof entry === "string" ? entry : entry.fields);
|
|
14
15
|
const finalOrderedArray = [];
|
|
15
16
|
orderWithoutDuplicates.forEach((element) => {
|
|
16
17
|
if (element === "*") {
|
|
17
|
-
const propertiesWithoutOrder = allProperties.filter((prop) => !
|
|
18
|
+
const propertiesWithoutOrder = allProperties.filter((prop) => !fieldsInOrder.includes(prop));
|
|
18
19
|
finalOrderedArray.push(...propertiesWithoutOrder);
|
|
19
20
|
}
|
|
20
21
|
else {
|
|
@@ -28,6 +28,8 @@ export declare const ObjectFieldAddButton: import("styled-components/dist/types"
|
|
|
28
28
|
ref?: ((instance: HTMLAnchorElement | null) => void | React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof React.DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | React.RefObject<HTMLAnchorElement> | null | undefined;
|
|
29
29
|
}, never>> & string;
|
|
30
30
|
export declare const getObjectFieldButton: ({ purpose, onClick, uiSchema, }: ObjectFieldButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export declare const ObjectFieldSection: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.FieldsetHTMLAttributes<HTMLFieldSetElement>, HTMLFieldSetElement>, never>> & string;
|
|
32
|
+
export declare const ObjectFieldSectionTitle: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLLegendElement>, HTMLLegendElement>, never>> & string;
|
|
31
33
|
export declare const ArrayFieldWrapper: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.FieldsetHTMLAttributes<HTMLFieldSetElement>, HTMLFieldSetElement>, never>> & string;
|
|
32
34
|
export declare const ArrayFieldTitle: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLLegendElement>, HTMLLegendElement>, never>> & string;
|
|
33
35
|
export declare const ArrayFieldList: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLUListElement>, HTMLUListElement>, never>> & string;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -45,6 +45,11 @@ export type UiSchema = {
|
|
|
45
45
|
[key: string]: any;
|
|
46
46
|
};
|
|
47
47
|
};
|
|
48
|
+
"ui:order"?: (string | {
|
|
49
|
+
title: string;
|
|
50
|
+
fields: string[];
|
|
51
|
+
collapsible?: boolean;
|
|
52
|
+
})[];
|
|
48
53
|
[name: string]: any;
|
|
49
54
|
};
|
|
50
55
|
export type FormRegistryContextValue = {
|
|
@@ -107,11 +112,17 @@ export type CollapsibleObjectFieldTemplateProps = {
|
|
|
107
112
|
children: React.ReactNode;
|
|
108
113
|
name?: string;
|
|
109
114
|
};
|
|
115
|
+
export type ObjectSectionTemplateProps = {
|
|
116
|
+
title: string;
|
|
117
|
+
collapsible?: boolean;
|
|
118
|
+
children: React.ReactNode;
|
|
119
|
+
};
|
|
110
120
|
export type TemplatesType = {
|
|
111
121
|
FieldTemplate: React.FunctionComponent<FieldTemplateProps>;
|
|
112
122
|
ObjectFieldTemplate: React.FunctionComponent<ObjectFieldTemplateProps>;
|
|
113
123
|
ArrayFieldTemplate: React.FunctionComponent<ArrayFieldTemplateProps>;
|
|
114
124
|
CollapsibleObjectFieldTemplate: React.FunctionComponent<ObjectFieldTemplateProps>;
|
|
125
|
+
ObjectSectionTemplate: React.FunctionComponent<ObjectSectionTemplateProps>;
|
|
115
126
|
};
|
|
116
127
|
/*** COMPONENTS ***/
|
|
117
128
|
export type ComponentsType = {
|
|
@@ -128,6 +139,8 @@ export type ComponentsType = {
|
|
|
128
139
|
ObjectFieldRemoveButton: React.FunctionComponent<any>;
|
|
129
140
|
ObjectFieldUpButton: React.FunctionComponent<any>;
|
|
130
141
|
ObjectFieldDownButton: React.FunctionComponent<any>;
|
|
142
|
+
ObjectFieldSection: React.FunctionComponent<any>;
|
|
143
|
+
ObjectFieldSectionTitle: React.FunctionComponent<any>;
|
|
131
144
|
ArrayFieldWrapper: React.FunctionComponent<any>;
|
|
132
145
|
ArrayFieldTitle: React.FunctionComponent<any>;
|
|
133
146
|
ArrayFieldItem: React.FunctionComponent<any>;
|
|
@@ -1 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { UiSchema } from "../types";
|
|
2
|
+
export declare function orderByUiSchema(order: UiSchema["ui:order"], allProperties: string[]): (string | {
|
|
3
|
+
title: string;
|
|
4
|
+
fields: string[];
|
|
5
|
+
collapsible?: boolean;
|
|
6
|
+
})[];
|