@nvs-dynamic-form/react-core 1.4.1 → 2.0.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/dist/cjs/nvs-dynamic-form/_style.css +40 -0
- package/dist/cjs/nvs-dynamic-form/_template.d.ts +2 -2
- package/dist/cjs/nvs-dynamic-form/_template.js +22 -62
- package/dist/cjs/nvs-dynamic-form/_template.js.map +1 -1
- package/dist/cjs/nvs-dynamic-form/_type.d.ts +18 -4
- package/dist/cjs/nvs-dynamic-form/elements/arrayField/_template.d.ts +3 -0
- package/dist/cjs/nvs-dynamic-form/elements/arrayField/_template.js +62 -0
- package/dist/cjs/nvs-dynamic-form/elements/arrayField/_template.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/arrayField/_type.d.ts +10 -0
- package/dist/cjs/nvs-dynamic-form/elements/arrayField/_type.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/arrayField/index.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/button/_template.d.ts +3 -0
- package/dist/cjs/nvs-dynamic-form/elements/button/_template.js +28 -0
- package/dist/cjs/nvs-dynamic-form/elements/button/_template.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/button/_type.d.ts +8 -0
- package/dist/cjs/nvs-dynamic-form/elements/button/_type.js +3 -0
- package/dist/cjs/nvs-dynamic-form/elements/button/_type.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/button/index.js +19 -0
- package/dist/cjs/nvs-dynamic-form/elements/button/index.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/_template.d.ts +3 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/_template.js +12 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/_template.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/_type.d.ts +8 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/_type.js +3 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/_type.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/index.d.ts +2 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/index.js +19 -0
- package/dist/cjs/nvs-dynamic-form/elements/container/index.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/field/_template.js +9 -3
- package/dist/cjs/nvs-dynamic-form/elements/field/_template.js.map +1 -1
- package/dist/cjs/nvs-dynamic-form/elements/field/_type.d.ts +7 -6
- package/dist/cjs/nvs-dynamic-form/elements/groupField/_template.d.ts +2 -0
- package/dist/cjs/nvs-dynamic-form/elements/groupField/_template.js +26 -0
- package/dist/cjs/nvs-dynamic-form/elements/groupField/_template.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/groupField/_type.d.ts +9 -0
- package/dist/cjs/nvs-dynamic-form/elements/groupField/_type.js +3 -0
- package/dist/cjs/nvs-dynamic-form/elements/groupField/_type.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/elements/groupField/index.d.ts +2 -0
- package/dist/cjs/nvs-dynamic-form/elements/groupField/index.js +19 -0
- package/dist/cjs/nvs-dynamic-form/elements/groupField/index.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/_template.d.ts +3 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/_template.js +87 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/_template.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/_type.d.ts +8 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/_type.js +3 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/_type.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/index.d.ts +1 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/index.js +18 -0
- package/dist/cjs/nvs-dynamic-form/formikForm/index.js.map +1 -0
- package/dist/cjs/nvs-dynamic-form/services/generateFormContentUtils.d.ts +39 -0
- package/dist/cjs/nvs-dynamic-form/services/generateFormContentUtils.js +92 -0
- package/dist/cjs/nvs-dynamic-form/services/generateFormContentUtils.js.map +1 -0
- package/dist/cjs/types/array-field-action-button.type.d.ts +14 -0
- package/dist/cjs/types/array-field-action-button.type.js +26 -0
- package/dist/cjs/types/array-field-action-button.type.js.map +1 -0
- package/dist/cjs/types/array-field.type.d.ts +13 -0
- package/dist/cjs/types/array-field.type.js +16 -0
- package/dist/cjs/types/array-field.type.js.map +1 -0
- package/dist/cjs/types/{form-field.type.d.ts → field-base.type.d.ts} +1 -1
- package/dist/cjs/types/{form-field.type.js → field-base.type.js} +1 -1
- package/dist/cjs/types/{form-field.type.js.map → field-base.type.js.map} +1 -1
- package/dist/cjs/types/group-field.type.d.ts +10 -0
- package/dist/cjs/types/group-field.type.js +13 -0
- package/dist/cjs/types/group-field.type.js.map +1 -0
- package/dist/cjs/types/index.d.ts +4 -2
- package/dist/cjs/types/index.js +4 -2
- package/dist/cjs/types/index.js.map +1 -1
- package/dist/cjs/types/{submit-button-options.type.d.ts → submit-button-default-options.type.d.ts} +1 -1
- package/dist/cjs/types/submit-button-default-options.type.js +3 -0
- package/dist/cjs/types/submit-button-default-options.type.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/_style.css +40 -0
- package/dist/esm/nvs-dynamic-form/_template.d.ts +2 -2
- package/dist/esm/nvs-dynamic-form/_template.js +20 -40
- package/dist/esm/nvs-dynamic-form/_template.js.map +1 -1
- package/dist/esm/nvs-dynamic-form/_type.d.ts +18 -4
- package/dist/esm/nvs-dynamic-form/elements/arrayField/_template.d.ts +3 -0
- package/dist/esm/nvs-dynamic-form/elements/arrayField/_template.js +55 -0
- package/dist/esm/nvs-dynamic-form/elements/arrayField/_template.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/arrayField/_type.d.ts +10 -0
- package/dist/esm/nvs-dynamic-form/elements/arrayField/_type.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/arrayField/index.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/button/_template.d.ts +3 -0
- package/dist/esm/nvs-dynamic-form/elements/button/_template.js +21 -0
- package/dist/esm/nvs-dynamic-form/elements/button/_template.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/button/_type.d.ts +8 -0
- package/dist/esm/nvs-dynamic-form/elements/button/_type.js +2 -0
- package/dist/esm/nvs-dynamic-form/elements/button/_type.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/button/index.d.ts +2 -0
- package/dist/esm/nvs-dynamic-form/elements/button/index.js +3 -0
- package/dist/esm/nvs-dynamic-form/elements/button/index.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/container/_template.d.ts +3 -0
- package/dist/esm/nvs-dynamic-form/elements/container/_template.js +5 -0
- package/dist/esm/nvs-dynamic-form/elements/container/_template.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/container/_type.d.ts +8 -0
- package/dist/esm/nvs-dynamic-form/elements/container/_type.js +2 -0
- package/dist/esm/nvs-dynamic-form/elements/container/_type.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/container/index.d.ts +2 -0
- package/dist/esm/nvs-dynamic-form/elements/container/index.js +3 -0
- package/dist/esm/nvs-dynamic-form/elements/container/index.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/field/_template.js +9 -3
- package/dist/esm/nvs-dynamic-form/elements/field/_template.js.map +1 -1
- package/dist/esm/nvs-dynamic-form/elements/field/_type.d.ts +7 -6
- package/dist/esm/nvs-dynamic-form/elements/groupField/_template.d.ts +2 -0
- package/dist/esm/nvs-dynamic-form/elements/groupField/_template.js +22 -0
- package/dist/esm/nvs-dynamic-form/elements/groupField/_template.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/groupField/_type.d.ts +9 -0
- package/dist/esm/nvs-dynamic-form/elements/groupField/_type.js +2 -0
- package/dist/esm/nvs-dynamic-form/elements/groupField/_type.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/elements/groupField/index.d.ts +2 -0
- package/dist/esm/nvs-dynamic-form/elements/groupField/index.js +3 -0
- package/dist/esm/nvs-dynamic-form/elements/groupField/index.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/formikForm/_template.d.ts +3 -0
- package/dist/esm/nvs-dynamic-form/formikForm/_template.js +60 -0
- package/dist/esm/nvs-dynamic-form/formikForm/_template.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/formikForm/_type.d.ts +8 -0
- package/dist/esm/nvs-dynamic-form/formikForm/_type.js +2 -0
- package/dist/esm/nvs-dynamic-form/formikForm/_type.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/formikForm/index.d.ts +1 -0
- package/dist/esm/nvs-dynamic-form/formikForm/index.js +2 -0
- package/dist/esm/nvs-dynamic-form/formikForm/index.js.map +1 -0
- package/dist/esm/nvs-dynamic-form/services/generateFormContentUtils.d.ts +39 -0
- package/dist/esm/nvs-dynamic-form/services/generateFormContentUtils.js +85 -0
- package/dist/esm/nvs-dynamic-form/services/generateFormContentUtils.js.map +1 -0
- package/dist/esm/types/array-field-action-button.type.d.ts +14 -0
- package/dist/esm/types/array-field-action-button.type.js +20 -0
- package/dist/esm/types/array-field-action-button.type.js.map +1 -0
- package/dist/esm/types/array-field.type.d.ts +13 -0
- package/dist/esm/types/array-field.type.js +12 -0
- package/dist/esm/types/array-field.type.js.map +1 -0
- package/dist/esm/types/{form-field.type.d.ts → field-base.type.d.ts} +1 -1
- package/dist/esm/types/{form-field.type.js → field-base.type.js} +1 -1
- package/dist/esm/types/{form-field.type.js.map → field-base.type.js.map} +1 -1
- package/dist/esm/types/group-field.type.d.ts +10 -0
- package/dist/esm/types/group-field.type.js +9 -0
- package/dist/esm/types/group-field.type.js.map +1 -0
- package/dist/esm/types/index.d.ts +4 -2
- package/dist/esm/types/index.js +4 -2
- package/dist/esm/types/index.js.map +1 -1
- package/dist/esm/types/{submit-button-options.type.d.ts → submit-button-default-options.type.d.ts} +1 -1
- package/dist/esm/types/submit-button-default-options.type.js +2 -0
- package/dist/esm/types/submit-button-default-options.type.js.map +1 -0
- package/lib/nvs-dynamic-form/_stories.tsx +276 -16
- package/lib/nvs-dynamic-form/_style.css +40 -0
- package/lib/nvs-dynamic-form/_template.tsx +40 -65
- package/lib/nvs-dynamic-form/_type.tsx +23 -4
- package/lib/nvs-dynamic-form/elements/arrayField/_template.tsx +123 -0
- package/lib/nvs-dynamic-form/elements/arrayField/_type.tsx +11 -0
- package/lib/nvs-dynamic-form/elements/arrayField/index.tsx +2 -0
- package/lib/nvs-dynamic-form/elements/button/_template.tsx +42 -0
- package/lib/nvs-dynamic-form/elements/button/_type.tsx +8 -0
- package/lib/nvs-dynamic-form/elements/button/index.tsx +2 -0
- package/lib/nvs-dynamic-form/elements/container/_template.tsx +10 -0
- package/lib/nvs-dynamic-form/elements/container/_type.tsx +7 -0
- package/lib/nvs-dynamic-form/elements/container/index.tsx +2 -0
- package/lib/nvs-dynamic-form/elements/field/_template.tsx +9 -4
- package/lib/nvs-dynamic-form/elements/field/_type.tsx +8 -6
- package/lib/nvs-dynamic-form/elements/groupField/_template.tsx +32 -0
- package/lib/nvs-dynamic-form/elements/groupField/_type.tsx +10 -0
- package/lib/nvs-dynamic-form/elements/groupField/index.tsx +2 -0
- package/lib/nvs-dynamic-form/formikForm/_template.tsx +85 -0
- package/lib/nvs-dynamic-form/formikForm/_type.tsx +9 -0
- package/lib/nvs-dynamic-form/formikForm/index.tsx +1 -0
- package/lib/nvs-dynamic-form/services/generateFormContentUtils.tsx +173 -0
- package/lib/types/array-field-action-button.type.tsx +26 -0
- package/lib/types/array-field.type.tsx +27 -0
- package/lib/types/{form-field.type.tsx → field-base.type.tsx} +1 -1
- package/lib/types/group-field.type.tsx +15 -0
- package/lib/types/index.tsx +4 -2
- package/lib/types/submit-button-default-options.type.tsx +5 -0
- package/package.json +1 -1
- package/dist/cjs/nvs-dynamic-form/elements/submit-button/_template.d.ts +0 -3
- package/dist/cjs/nvs-dynamic-form/elements/submit-button/_template.js +0 -30
- package/dist/cjs/nvs-dynamic-form/elements/submit-button/_template.js.map +0 -1
- package/dist/cjs/nvs-dynamic-form/elements/submit-button/_type.d.ts +0 -11
- package/dist/cjs/nvs-dynamic-form/elements/submit-button/_type.js.map +0 -1
- package/dist/cjs/nvs-dynamic-form/elements/submit-button/index.js.map +0 -1
- package/dist/cjs/types/submit-button-options.type.js +0 -7
- package/dist/cjs/types/submit-button-options.type.js.map +0 -1
- package/dist/esm/nvs-dynamic-form/elements/submit-button/_template.d.ts +0 -3
- package/dist/esm/nvs-dynamic-form/elements/submit-button/_template.js +0 -23
- package/dist/esm/nvs-dynamic-form/elements/submit-button/_template.js.map +0 -1
- package/dist/esm/nvs-dynamic-form/elements/submit-button/_type.d.ts +0 -11
- package/dist/esm/nvs-dynamic-form/elements/submit-button/_type.js.map +0 -1
- package/dist/esm/nvs-dynamic-form/elements/submit-button/index.js.map +0 -1
- package/dist/esm/types/submit-button-options.type.js +0 -3
- package/dist/esm/types/submit-button-options.type.js.map +0 -1
- package/lib/nvs-dynamic-form/elements/submit-button/_template.tsx +0 -42
- package/lib/nvs-dynamic-form/elements/submit-button/_type.tsx +0 -12
- package/lib/types/submit-button-options.type.tsx +0 -5
- /package/dist/cjs/nvs-dynamic-form/elements/{submit-button → arrayField}/_type.js +0 -0
- /package/dist/cjs/nvs-dynamic-form/elements/{submit-button → arrayField}/index.d.ts +0 -0
- /package/dist/cjs/nvs-dynamic-form/elements/{submit-button → arrayField}/index.js +0 -0
- /package/dist/{esm/nvs-dynamic-form/elements/submit-button → cjs/nvs-dynamic-form/elements/button}/index.d.ts +0 -0
- /package/dist/esm/nvs-dynamic-form/elements/{submit-button → arrayField}/_type.js +0 -0
- /package/{lib/nvs-dynamic-form/elements/submit-button/index.tsx → dist/esm/nvs-dynamic-form/elements/arrayField/index.d.ts} +0 -0
- /package/dist/esm/nvs-dynamic-form/elements/{submit-button → arrayField}/index.js +0 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { FieldArray } from "formik";
|
|
2
|
+
import { GenerateFormContentUtils } from "../../services/generateFormContentUtils";
|
|
3
|
+
import { IArrayField } from "./_type";
|
|
4
|
+
import React from "react";
|
|
5
|
+
|
|
6
|
+
export const ArrayField: React.FC<IArrayField> = ({
|
|
7
|
+
field: arrayField,
|
|
8
|
+
formElements,
|
|
9
|
+
containerComponent,
|
|
10
|
+
containerVisible,
|
|
11
|
+
useContainersOutsideGroup,
|
|
12
|
+
useGroupContainer,
|
|
13
|
+
buttonComponent: ButtonComponent,
|
|
14
|
+
}) => {
|
|
15
|
+
const generateFormContentUtils = new GenerateFormContentUtils({
|
|
16
|
+
containerComponent,
|
|
17
|
+
formElements,
|
|
18
|
+
useContainersOutsideGroup,
|
|
19
|
+
useGroupContainer,
|
|
20
|
+
containerVisible: containerVisible,
|
|
21
|
+
fields: arrayField.fields,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const createArrayItem = (name: string, index: number) => {
|
|
25
|
+
return arrayField.fields.map((field) => ({
|
|
26
|
+
...field,
|
|
27
|
+
id: `${name}[${index}].${field.id}`,
|
|
28
|
+
}));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const getDefaultItem = () => {
|
|
32
|
+
return arrayField.fields.reduce((acc: { [key: string]: any }, field) => {
|
|
33
|
+
acc[field.id] = field.defaultValue;
|
|
34
|
+
return acc;
|
|
35
|
+
}, {});
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const createArrayFields = (index: number) => {
|
|
39
|
+
return (
|
|
40
|
+
<div className="df-array-field-content">
|
|
41
|
+
<div className="nvs-container-fluid">
|
|
42
|
+
<div className="nvs-row">
|
|
43
|
+
{generateFormContentUtils.createFormElements(
|
|
44
|
+
createArrayItem(arrayField.id, index),
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const createRemoveButton = (onRemoveItem: Function) => {
|
|
53
|
+
return (
|
|
54
|
+
<div className="nvs-col-12">
|
|
55
|
+
<ButtonComponent
|
|
56
|
+
onClick={() => {
|
|
57
|
+
onRemoveItem();
|
|
58
|
+
}}
|
|
59
|
+
type="button"
|
|
60
|
+
>
|
|
61
|
+
{arrayField.removeButtonOptions?.label}
|
|
62
|
+
</ButtonComponent>
|
|
63
|
+
</div>
|
|
64
|
+
);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const createArrayItemRemoveButton = (onRemoveItem: Function) => {
|
|
68
|
+
return (
|
|
69
|
+
<div className="df-array-field-remove-button">
|
|
70
|
+
{generateFormContentUtils.createContentContainer(
|
|
71
|
+
createRemoveButton(onRemoveItem),
|
|
72
|
+
)}
|
|
73
|
+
</div>
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const createFieldArrayContent = (
|
|
78
|
+
onRemoveItem: (index: number) => void,
|
|
79
|
+
index: number,
|
|
80
|
+
) => {
|
|
81
|
+
return (
|
|
82
|
+
<div
|
|
83
|
+
className={`df-array-field remove-button-${arrayField.removeButtonOptions?.position}`}
|
|
84
|
+
key={index}
|
|
85
|
+
>
|
|
86
|
+
{createArrayFields(index)}
|
|
87
|
+
{createArrayItemRemoveButton(() => onRemoveItem(index))}
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const createAddButton = (onAddItem: Function) => {
|
|
93
|
+
return (
|
|
94
|
+
<div className="df-array-field-add-button">
|
|
95
|
+
<ButtonComponent
|
|
96
|
+
onClick={() => onAddItem(getDefaultItem())}
|
|
97
|
+
type="button"
|
|
98
|
+
>
|
|
99
|
+
{arrayField.addButtonOptions?.label}
|
|
100
|
+
</ButtonComponent>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const createArrayItemAddButton = (onAddItem: Function) => {
|
|
106
|
+
return generateFormContentUtils.createContentContainer(
|
|
107
|
+
createAddButton(onAddItem),
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<FieldArray name={arrayField.id}>
|
|
113
|
+
{({ push, remove, form }) => (
|
|
114
|
+
<>
|
|
115
|
+
{form.values[arrayField.id]?.map((_: any, index: number) =>
|
|
116
|
+
createFieldArrayContent(remove, index),
|
|
117
|
+
)}
|
|
118
|
+
{createArrayItemAddButton(push)}
|
|
119
|
+
</>
|
|
120
|
+
)}
|
|
121
|
+
</FieldArray>
|
|
122
|
+
);
|
|
123
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ArrayField } from "../../../types";
|
|
2
|
+
import { IField } from "../field";
|
|
3
|
+
|
|
4
|
+
export interface IArrayField extends IField {
|
|
5
|
+
field: ArrayField;
|
|
6
|
+
buttonComponent: React.FC<any>;
|
|
7
|
+
containerComponent: React.FC<any>;
|
|
8
|
+
containerVisible: boolean;
|
|
9
|
+
useContainersOutsideGroup: boolean;
|
|
10
|
+
useGroupContainer: boolean;
|
|
11
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { IButton } from "./_type";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
export const Button = ({
|
|
5
|
+
buttonComponent: ButtonComponent,
|
|
6
|
+
visible,
|
|
7
|
+
label,
|
|
8
|
+
position = "right",
|
|
9
|
+
isFullWidth,
|
|
10
|
+
containerClass,
|
|
11
|
+
}: IButton) => {
|
|
12
|
+
const getButtonPositionClass = (position: "left" | "right" | "center") => {
|
|
13
|
+
const classes = {
|
|
14
|
+
left: "nvs-jc-start",
|
|
15
|
+
right: "nvs-jc-end",
|
|
16
|
+
center: "nvs-jc-center",
|
|
17
|
+
};
|
|
18
|
+
return classes[position];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const getSubmitButtonClasses = () => {
|
|
22
|
+
const buttonClasses = ["df-button"];
|
|
23
|
+
|
|
24
|
+
isFullWidth && buttonClasses.push("nvs-col-12");
|
|
25
|
+
|
|
26
|
+
return buttonClasses.join(" ");
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return visible ? (
|
|
30
|
+
<div
|
|
31
|
+
className={`nvs-container-fluid${containerClass ? ` ${containerClass}` : ""}`}
|
|
32
|
+
>
|
|
33
|
+
<div className={`nvs-row ${getButtonPositionClass(position)}`}>
|
|
34
|
+
<div className={getSubmitButtonClasses()}>
|
|
35
|
+
<ButtonComponent>{label}</ButtonComponent>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
) : (
|
|
40
|
+
<></>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { IContainer } from "./_type";
|
|
2
|
+
import React from "react";
|
|
3
|
+
|
|
4
|
+
export const Container = ({
|
|
5
|
+
containerComponent: CustomContainer,
|
|
6
|
+
options = {},
|
|
7
|
+
children,
|
|
8
|
+
}: IContainer) => {
|
|
9
|
+
return <CustomContainer {...options}>{children}</CustomContainer>;
|
|
10
|
+
};
|
|
@@ -7,7 +7,7 @@ export const Field = ({
|
|
|
7
7
|
formElements,
|
|
8
8
|
field: { fieldType, screenSize = 12, onBlur, onChange, ...fieldProps },
|
|
9
9
|
}: IField) => {
|
|
10
|
-
const [formikField, meta] = useField({
|
|
10
|
+
const [formikField, meta, helpers] = useField({
|
|
11
11
|
id: fieldProps.id,
|
|
12
12
|
name: fieldProps.id,
|
|
13
13
|
});
|
|
@@ -23,9 +23,14 @@ export const Field = ({
|
|
|
23
23
|
return className.join(" ");
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
const onChangeHandler = (event: ChangeEvent) => {
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
const onChangeHandler = (event: ChangeEvent | Array<unknown>) => {
|
|
27
|
+
if (Array.isArray(event)) {
|
|
28
|
+
helpers.setValue(event);
|
|
29
|
+
onChange && onChange(event);
|
|
30
|
+
} else {
|
|
31
|
+
onChange && onChange(event);
|
|
32
|
+
formikField.onChange(event);
|
|
33
|
+
}
|
|
29
34
|
};
|
|
30
35
|
|
|
31
36
|
const onBlurHandler = (event: FocusEvent) => {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { FieldBase } from "../../../types";
|
|
2
2
|
|
|
3
|
+
export interface IFormElement {
|
|
4
|
+
[key: string]: {
|
|
5
|
+
component: React.FC<any>;
|
|
6
|
+
class: typeof FieldBase<any>;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
export interface IField {
|
|
4
11
|
field: FieldBase<unknown>;
|
|
5
|
-
formElements:
|
|
6
|
-
[key: string]: {
|
|
7
|
-
component: React.FC<any>;
|
|
8
|
-
class: typeof FieldBase<any>;
|
|
9
|
-
};
|
|
10
|
-
};
|
|
12
|
+
formElements: IFormElement;
|
|
11
13
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GenerateFormContentUtils } from "../../services/generateFormContentUtils";
|
|
2
|
+
import { IGroupField } from "./_type";
|
|
3
|
+
|
|
4
|
+
export const GroupField = ({
|
|
5
|
+
field: groupField,
|
|
6
|
+
formElements,
|
|
7
|
+
containerComponent,
|
|
8
|
+
containerVisible,
|
|
9
|
+
useContainersOutsideGroup,
|
|
10
|
+
useGroupContainer,
|
|
11
|
+
}: IGroupField) => {
|
|
12
|
+
const generateFormContentUtils = new GenerateFormContentUtils({
|
|
13
|
+
containerComponent,
|
|
14
|
+
formElements,
|
|
15
|
+
useContainersOutsideGroup,
|
|
16
|
+
useGroupContainer,
|
|
17
|
+
containerOptions: groupField.containerOptions,
|
|
18
|
+
containerVisible: containerVisible && groupField.containerVisible!,
|
|
19
|
+
fields: groupField.fields.map((field) => {
|
|
20
|
+
field.id = `${groupField.id}.${field.id}`;
|
|
21
|
+
return field;
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const isContainerVisible = () => {
|
|
26
|
+
return groupField.containerVisible && useGroupContainer && containerVisible;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return isContainerVisible()
|
|
30
|
+
? generateFormContentUtils.createFormContent()
|
|
31
|
+
: generateFormContentUtils.createFormElements(groupField.fields);
|
|
32
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { GroupField } from "../../../types";
|
|
2
|
+
import { IField } from "../field";
|
|
3
|
+
|
|
4
|
+
export interface IGroupField extends IField {
|
|
5
|
+
field: GroupField;
|
|
6
|
+
containerComponent: React.FC<any>;
|
|
7
|
+
containerVisible: boolean;
|
|
8
|
+
useContainersOutsideGroup: boolean;
|
|
9
|
+
useGroupContainer: boolean;
|
|
10
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import * as Yup from "yup";
|
|
2
|
+
|
|
3
|
+
import { ArrayField, DynamicObject, FieldBase, GroupField } from "../../types";
|
|
4
|
+
import { Form, FormikProvider, useFormik } from "formik";
|
|
5
|
+
import React, { useEffect, useState } from "react";
|
|
6
|
+
|
|
7
|
+
import { FieldType } from "../_type";
|
|
8
|
+
import { IFormikForm } from "./_type";
|
|
9
|
+
|
|
10
|
+
export const FormikForm = ({
|
|
11
|
+
children,
|
|
12
|
+
fields,
|
|
13
|
+
onSubmit,
|
|
14
|
+
formClass,
|
|
15
|
+
}: IFormikForm) => {
|
|
16
|
+
const getFieldDefaultValue = (field: FieldType) => {
|
|
17
|
+
let defaultValue;
|
|
18
|
+
if (field instanceof ArrayField) defaultValue = field.defaultValues ?? [];
|
|
19
|
+
else if (field instanceof GroupField)
|
|
20
|
+
defaultValue = getFieldsDefaultValues(field.fields!);
|
|
21
|
+
else defaultValue = field.defaultValue;
|
|
22
|
+
|
|
23
|
+
return defaultValue;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const getFieldsDefaultValues = (fields: Array<FieldType>): DynamicObject => {
|
|
27
|
+
return fields.reduce((acc: DynamicObject, field: FieldType) => {
|
|
28
|
+
acc[field.id] = getFieldDefaultValue(field);
|
|
29
|
+
return acc;
|
|
30
|
+
}, {});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const getFieldValidate = (field: FieldType) => {
|
|
34
|
+
let validate;
|
|
35
|
+
if (field instanceof GroupField)
|
|
36
|
+
validate = createValidateSchema(field.fields!);
|
|
37
|
+
else if (field instanceof ArrayField)
|
|
38
|
+
validate = createArrayValidateSchema(field.fields!);
|
|
39
|
+
else if (field?.validate) validate = field.validate;
|
|
40
|
+
|
|
41
|
+
return validate;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const createValidateSchema = (fields: Array<FieldType>) => {
|
|
45
|
+
const validationSchema = fields.reduce(
|
|
46
|
+
(acc: { [key: string]: Yup.AnySchema }, field) => {
|
|
47
|
+
const validate = getFieldValidate(field);
|
|
48
|
+
if (validate) acc[field.id] = validate;
|
|
49
|
+
return acc;
|
|
50
|
+
},
|
|
51
|
+
{},
|
|
52
|
+
);
|
|
53
|
+
return Yup.object(validationSchema);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const createArrayValidateSchema = (fields: Array<FieldBase<any>>) => {
|
|
57
|
+
return Yup.array().of(createValidateSchema(fields));
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const [defaultValues, setDefaultValues] = useState(
|
|
61
|
+
getFieldsDefaultValues(fields),
|
|
62
|
+
);
|
|
63
|
+
const [validateSchema, setValidateSchema] = useState(
|
|
64
|
+
createValidateSchema(fields),
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
setDefaultValues(getFieldsDefaultValues(fields));
|
|
69
|
+
setValidateSchema(createValidateSchema(fields));
|
|
70
|
+
}, [fields]);
|
|
71
|
+
|
|
72
|
+
const formik = useFormik({
|
|
73
|
+
initialValues: defaultValues,
|
|
74
|
+
validationSchema: validateSchema,
|
|
75
|
+
onSubmit: async (values) => {
|
|
76
|
+
onSubmit && (await onSubmit(values));
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<FormikProvider value={formik}>
|
|
82
|
+
<Form className={formClass ? ` ${formClass}` : ""}>{children}</Form>
|
|
83
|
+
</FormikProvider>
|
|
84
|
+
);
|
|
85
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FieldType } from "../_type";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
|
+
|
|
4
|
+
export interface IFormikForm {
|
|
5
|
+
onSubmit?: ((values: unknown) => void) | ((values: unknown) => Promise<void>);
|
|
6
|
+
fields: Array<FieldType>;
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
formClass?: string;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./_template";
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { ArrayField, FieldBase, GroupField } from "../../types";
|
|
2
|
+
|
|
3
|
+
import { ArrayField as ArrayFieldElement } from "../elements/arrayField";
|
|
4
|
+
import { Container } from "../elements/container";
|
|
5
|
+
import { Field } from "../elements/field";
|
|
6
|
+
import { FieldType } from "../_type";
|
|
7
|
+
import { GroupField as GroupFieldElement } from "../elements/groupField";
|
|
8
|
+
import { IFormElement } from "../elements/field";
|
|
9
|
+
import React from "react";
|
|
10
|
+
import { ReactNode } from "react";
|
|
11
|
+
|
|
12
|
+
export class GenerateFormContentUtils {
|
|
13
|
+
private readonly containerComponent: React.FC<any>;
|
|
14
|
+
private readonly formElements: IFormElement;
|
|
15
|
+
private readonly useContainersOutsideGroup: boolean;
|
|
16
|
+
private readonly useGroupContainer: boolean;
|
|
17
|
+
private readonly containerVisible: boolean;
|
|
18
|
+
private readonly fields: Array<FieldType>;
|
|
19
|
+
private readonly containerOptions: { [key: string]: any };
|
|
20
|
+
private readonly buttonComponent?: React.FC<any>;
|
|
21
|
+
|
|
22
|
+
constructor({
|
|
23
|
+
containerComponent,
|
|
24
|
+
formElements,
|
|
25
|
+
useContainersOutsideGroup,
|
|
26
|
+
useGroupContainer,
|
|
27
|
+
containerVisible,
|
|
28
|
+
fields,
|
|
29
|
+
containerOptions,
|
|
30
|
+
buttonComponent,
|
|
31
|
+
}: {
|
|
32
|
+
containerComponent: React.FC<any>;
|
|
33
|
+
formElements: IFormElement;
|
|
34
|
+
useContainersOutsideGroup: boolean;
|
|
35
|
+
useGroupContainer: boolean;
|
|
36
|
+
containerVisible: boolean;
|
|
37
|
+
fields: Array<FieldType>;
|
|
38
|
+
buttonComponent?: React.FC<any>;
|
|
39
|
+
containerOptions?: { [key: string]: any };
|
|
40
|
+
}) {
|
|
41
|
+
this.containerComponent = containerComponent;
|
|
42
|
+
this.formElements = formElements;
|
|
43
|
+
this.useContainersOutsideGroup = useContainersOutsideGroup;
|
|
44
|
+
this.useGroupContainer = useGroupContainer;
|
|
45
|
+
this.containerVisible = containerVisible;
|
|
46
|
+
this.fields = fields;
|
|
47
|
+
this.containerOptions = containerOptions || {};
|
|
48
|
+
this.buttonComponent = buttonComponent;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
createContainer(content: ReactNode, containerProps: object) {
|
|
52
|
+
return (
|
|
53
|
+
<Container
|
|
54
|
+
containerComponent={this.containerComponent}
|
|
55
|
+
options={containerProps}
|
|
56
|
+
>
|
|
57
|
+
{content}
|
|
58
|
+
</Container>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
createFormContent() {
|
|
63
|
+
const singleFields = this.createSingleFieldsElements();
|
|
64
|
+
const groupFields = this.createGroupFieldsElements();
|
|
65
|
+
|
|
66
|
+
let formContent;
|
|
67
|
+
if (this.containerVisible && this.useContainersOutsideGroup && singleFields)
|
|
68
|
+
formContent = (
|
|
69
|
+
<>
|
|
70
|
+
{this.createContainer(singleFields, this.containerOptions)}
|
|
71
|
+
{groupFields}
|
|
72
|
+
</>
|
|
73
|
+
);
|
|
74
|
+
else
|
|
75
|
+
formContent = this.createFormGroup(
|
|
76
|
+
<>
|
|
77
|
+
{singleFields}
|
|
78
|
+
{groupFields}
|
|
79
|
+
</>,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return formContent;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
createFormElements(fields: Array<FieldType>): JSX.Element[] {
|
|
86
|
+
const fieldsElements = [];
|
|
87
|
+
for (const field of fields) {
|
|
88
|
+
if (field instanceof GroupField)
|
|
89
|
+
fieldsElements.push(this.createGroupFieldElement(field));
|
|
90
|
+
else if (field instanceof ArrayField)
|
|
91
|
+
fieldsElements.push(this.createArrayFieldElement(field));
|
|
92
|
+
else fieldsElements.push(this.createSingleFieldElement(field));
|
|
93
|
+
}
|
|
94
|
+
return fieldsElements;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
createContentContainer(formElements: ReactNode) {
|
|
98
|
+
return (
|
|
99
|
+
<div className="nvs-container-fluid">
|
|
100
|
+
<div className="nvs-row">{formElements}</div>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private getSingleFields() {
|
|
106
|
+
return this.fields.filter((field) => this.isSingleField(field));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private getGroupFields() {
|
|
110
|
+
return this.fields.filter((field) => !this.isSingleField(field));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private createSingleFieldsElements() {
|
|
114
|
+
const singleFields = this.getSingleFields();
|
|
115
|
+
return (
|
|
116
|
+
singleFields.length > 0 &&
|
|
117
|
+
this.createContentContainer(this.createFormElements(singleFields))
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private createGroupFieldsElements() {
|
|
122
|
+
const groupFields = this.getGroupFields();
|
|
123
|
+
return groupFields.length > 0 && this.createFormElements(groupFields);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private createSingleFieldElement(field: FieldBase<unknown>) {
|
|
127
|
+
return (
|
|
128
|
+
<Field key={field.id} formElements={this.formElements} field={field} />
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
private createGroupFieldElement(field: GroupField) {
|
|
133
|
+
return (
|
|
134
|
+
<GroupFieldElement
|
|
135
|
+
key={field.id}
|
|
136
|
+
formElements={this.formElements}
|
|
137
|
+
field={field}
|
|
138
|
+
containerComponent={this.containerComponent}
|
|
139
|
+
useContainersOutsideGroup={this.useContainersOutsideGroup}
|
|
140
|
+
useGroupContainer={this.useGroupContainer}
|
|
141
|
+
containerVisible={this.containerVisible}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
private createArrayFieldElement(field: ArrayField) {
|
|
147
|
+
return (
|
|
148
|
+
<ArrayFieldElement
|
|
149
|
+
key={field.id}
|
|
150
|
+
formElements={this.formElements}
|
|
151
|
+
field={field}
|
|
152
|
+
containerComponent={this.containerComponent}
|
|
153
|
+
useContainersOutsideGroup={this.useContainersOutsideGroup}
|
|
154
|
+
useGroupContainer={this.useGroupContainer}
|
|
155
|
+
containerVisible={this.containerVisible}
|
|
156
|
+
buttonComponent={this.buttonComponent!}
|
|
157
|
+
/>
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private isSingleField(field: FieldType) {
|
|
162
|
+
return !(
|
|
163
|
+
field instanceof GroupField &&
|
|
164
|
+
field.containerVisible &&
|
|
165
|
+
this.useGroupContainer &&
|
|
166
|
+
this.containerVisible
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private createFormGroup(formContent: ReactNode) {
|
|
171
|
+
return <div className="df-form-group">{formContent}</div>;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class ArrayFieldButton {
|
|
2
|
+
label?: string;
|
|
3
|
+
options?: { [key: string]: any };
|
|
4
|
+
|
|
5
|
+
constructor(options: ArrayFieldButton) {
|
|
6
|
+
this.label = options.label;
|
|
7
|
+
this.options = options.options ?? {};
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class ArrayFieldRemoveButton extends ArrayFieldButton {
|
|
12
|
+
position?: "bottom" | "right";
|
|
13
|
+
|
|
14
|
+
constructor(options: ArrayFieldRemoveButton) {
|
|
15
|
+
options.label = options.label ?? "-";
|
|
16
|
+
super(options);
|
|
17
|
+
this.position = options.position ?? "right";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class ArrayFieldAddButton extends ArrayFieldButton {
|
|
22
|
+
constructor(options: ArrayFieldRemoveButton) {
|
|
23
|
+
options.label = options.label ?? "+";
|
|
24
|
+
super(options);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ArrayFieldAddButton,
|
|
3
|
+
ArrayFieldRemoveButton,
|
|
4
|
+
} from "./array-field-action-button.type";
|
|
5
|
+
|
|
6
|
+
import { FieldBase } from "./field-base.type";
|
|
7
|
+
|
|
8
|
+
export class ArrayField<ValueType = { [key: string]: any }> {
|
|
9
|
+
fieldType?: string = "fieldArray";
|
|
10
|
+
id!: string;
|
|
11
|
+
fields: Array<FieldBase<any>>;
|
|
12
|
+
addButtonOptions?: ArrayFieldAddButton;
|
|
13
|
+
removeButtonOptions?: ArrayFieldRemoveButton;
|
|
14
|
+
defaultValues?: Array<ValueType>;
|
|
15
|
+
|
|
16
|
+
constructor(options: ArrayField<ValueType>) {
|
|
17
|
+
this.id = options.id;
|
|
18
|
+
this.fields = options.fields ?? [];
|
|
19
|
+
this.addButtonOptions = new ArrayFieldAddButton(
|
|
20
|
+
options.addButtonOptions ?? {},
|
|
21
|
+
);
|
|
22
|
+
this.removeButtonOptions = new ArrayFieldRemoveButton(
|
|
23
|
+
options.removeButtonOptions ?? {},
|
|
24
|
+
);
|
|
25
|
+
this.defaultValues = options.defaultValues ?? [];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -11,7 +11,7 @@ export abstract class FieldBase<ValueType, HtmlElement = any> {
|
|
|
11
11
|
screenSize?: ScreenSizeType | IScreenSize;
|
|
12
12
|
validate?: Yup.AnySchema;
|
|
13
13
|
error?: string;
|
|
14
|
-
onChange?: (event: ChangeEvent<HtmlElement>) => void;
|
|
14
|
+
onChange?: (event: ChangeEvent<HtmlElement> | Array<unknown>) => void;
|
|
15
15
|
onBlur?: (event: FocusEvent<HtmlElement>) => void;
|
|
16
16
|
|
|
17
17
|
constructor(options: FieldBase<ValueType>, fieldDefaultValue?: ValueType) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FieldBase } from "./field-base.type";
|
|
2
|
+
|
|
3
|
+
export class GroupField {
|
|
4
|
+
id!: string;
|
|
5
|
+
fields: Array<FieldBase<unknown>>;
|
|
6
|
+
containerVisible?: boolean;
|
|
7
|
+
containerOptions?: { [key: string]: any };
|
|
8
|
+
|
|
9
|
+
constructor(options: GroupField) {
|
|
10
|
+
this.id = options.id;
|
|
11
|
+
this.fields = options.fields ?? [];
|
|
12
|
+
this.containerVisible = options.containerVisible ?? false;
|
|
13
|
+
this.containerOptions = options.containerOptions ?? {};
|
|
14
|
+
}
|
|
15
|
+
}
|
package/lib/types/index.tsx
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export * from "./
|
|
1
|
+
export * from "./field-base.type";
|
|
2
2
|
export * from "./screen-size.type";
|
|
3
3
|
export * from "./dynamic-object.type";
|
|
4
|
-
export * from "./submit-button-options.type";
|
|
4
|
+
export * from "./submit-button-default-options.type";
|
|
5
|
+
export * from "./group-field.type";
|
|
6
|
+
export * from "./array-field.type";
|