@nvs-dynamic-form/react-core 1.5.0 → 2.1.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.
Files changed (191) hide show
  1. package/dist/cjs/nvs-dynamic-form/_style.css +40 -0
  2. package/dist/cjs/nvs-dynamic-form/_template.d.ts +2 -2
  3. package/dist/cjs/nvs-dynamic-form/_template.js +24 -62
  4. package/dist/cjs/nvs-dynamic-form/_template.js.map +1 -1
  5. package/dist/cjs/nvs-dynamic-form/_type.d.ts +20 -4
  6. package/dist/cjs/nvs-dynamic-form/elements/arrayField/_template.d.ts +3 -0
  7. package/dist/cjs/nvs-dynamic-form/elements/arrayField/_template.js +88 -0
  8. package/dist/cjs/nvs-dynamic-form/elements/arrayField/_template.js.map +1 -0
  9. package/dist/cjs/nvs-dynamic-form/elements/arrayField/_type.d.ts +12 -0
  10. package/dist/cjs/nvs-dynamic-form/elements/arrayField/_type.js.map +1 -0
  11. package/dist/cjs/nvs-dynamic-form/elements/arrayField/index.js.map +1 -0
  12. package/dist/cjs/nvs-dynamic-form/elements/button/_template.d.ts +3 -0
  13. package/dist/cjs/nvs-dynamic-form/elements/button/_template.js +28 -0
  14. package/dist/cjs/nvs-dynamic-form/elements/button/_template.js.map +1 -0
  15. package/dist/cjs/nvs-dynamic-form/elements/button/_type.d.ts +8 -0
  16. package/dist/cjs/nvs-dynamic-form/elements/button/_type.js +3 -0
  17. package/dist/cjs/nvs-dynamic-form/elements/button/_type.js.map +1 -0
  18. package/dist/cjs/nvs-dynamic-form/elements/button/index.js +19 -0
  19. package/dist/cjs/nvs-dynamic-form/elements/button/index.js.map +1 -0
  20. package/dist/cjs/nvs-dynamic-form/elements/container/_template.d.ts +3 -0
  21. package/dist/cjs/nvs-dynamic-form/elements/container/_template.js +12 -0
  22. package/dist/cjs/nvs-dynamic-form/elements/container/_template.js.map +1 -0
  23. package/dist/cjs/nvs-dynamic-form/elements/container/_type.d.ts +8 -0
  24. package/dist/cjs/nvs-dynamic-form/elements/container/_type.js +3 -0
  25. package/dist/cjs/nvs-dynamic-form/elements/container/_type.js.map +1 -0
  26. package/dist/cjs/nvs-dynamic-form/elements/container/index.d.ts +2 -0
  27. package/dist/cjs/nvs-dynamic-form/elements/container/index.js +19 -0
  28. package/dist/cjs/nvs-dynamic-form/elements/container/index.js.map +1 -0
  29. package/dist/cjs/nvs-dynamic-form/elements/field/_type.d.ts +7 -6
  30. package/dist/cjs/nvs-dynamic-form/elements/groupField/_template.d.ts +2 -0
  31. package/dist/cjs/nvs-dynamic-form/elements/groupField/_template.js +26 -0
  32. package/dist/cjs/nvs-dynamic-form/elements/groupField/_template.js.map +1 -0
  33. package/dist/cjs/nvs-dynamic-form/elements/groupField/_type.d.ts +9 -0
  34. package/dist/cjs/nvs-dynamic-form/elements/groupField/_type.js +3 -0
  35. package/dist/cjs/nvs-dynamic-form/elements/groupField/_type.js.map +1 -0
  36. package/dist/cjs/nvs-dynamic-form/elements/groupField/index.d.ts +2 -0
  37. package/dist/cjs/nvs-dynamic-form/elements/groupField/index.js +19 -0
  38. package/dist/cjs/nvs-dynamic-form/elements/groupField/index.js.map +1 -0
  39. package/dist/cjs/nvs-dynamic-form/formikForm/_template.d.ts +3 -0
  40. package/dist/cjs/nvs-dynamic-form/formikForm/_template.js +87 -0
  41. package/dist/cjs/nvs-dynamic-form/formikForm/_template.js.map +1 -0
  42. package/dist/cjs/nvs-dynamic-form/formikForm/_type.d.ts +8 -0
  43. package/dist/cjs/nvs-dynamic-form/formikForm/_type.js +3 -0
  44. package/dist/cjs/nvs-dynamic-form/formikForm/_type.js.map +1 -0
  45. package/dist/cjs/nvs-dynamic-form/formikForm/index.d.ts +1 -0
  46. package/dist/cjs/nvs-dynamic-form/formikForm/index.js +18 -0
  47. package/dist/cjs/nvs-dynamic-form/formikForm/index.js.map +1 -0
  48. package/dist/cjs/nvs-dynamic-form/services/generateFormContentUtils.d.ts +44 -0
  49. package/dist/cjs/nvs-dynamic-form/services/generateFormContentUtils.js +96 -0
  50. package/dist/cjs/nvs-dynamic-form/services/generateFormContentUtils.js.map +1 -0
  51. package/dist/cjs/types/array-field-action-button.type.d.ts +14 -0
  52. package/dist/cjs/types/array-field-action-button.type.js +26 -0
  53. package/dist/cjs/types/array-field-action-button.type.js.map +1 -0
  54. package/dist/cjs/types/array-field.type.d.ts +13 -0
  55. package/dist/cjs/types/array-field.type.js +15 -0
  56. package/dist/cjs/types/array-field.type.js.map +1 -0
  57. package/dist/cjs/types/{form-field.type.js → field-base.type.js} +1 -1
  58. package/dist/cjs/types/{form-field.type.js.map → field-base.type.js.map} +1 -1
  59. package/dist/cjs/types/group-field.type.d.ts +10 -0
  60. package/dist/cjs/types/group-field.type.js +13 -0
  61. package/dist/cjs/types/group-field.type.js.map +1 -0
  62. package/dist/cjs/types/index.d.ts +5 -2
  63. package/dist/cjs/types/index.js +5 -2
  64. package/dist/cjs/types/index.js.map +1 -1
  65. package/dist/cjs/types/{submit-button-options.type.d.ts → submit-button-default-options.type.d.ts} +1 -1
  66. package/dist/cjs/types/submit-button-default-options.type.js +3 -0
  67. package/dist/cjs/types/submit-button-default-options.type.js.map +1 -0
  68. package/dist/esm/nvs-dynamic-form/_style.css +40 -0
  69. package/dist/esm/nvs-dynamic-form/_template.d.ts +2 -2
  70. package/dist/esm/nvs-dynamic-form/_template.js +22 -40
  71. package/dist/esm/nvs-dynamic-form/_template.js.map +1 -1
  72. package/dist/esm/nvs-dynamic-form/_type.d.ts +20 -4
  73. package/dist/esm/nvs-dynamic-form/elements/arrayField/_template.d.ts +3 -0
  74. package/dist/esm/nvs-dynamic-form/elements/arrayField/_template.js +61 -0
  75. package/dist/esm/nvs-dynamic-form/elements/arrayField/_template.js.map +1 -0
  76. package/dist/esm/nvs-dynamic-form/elements/arrayField/_type.d.ts +12 -0
  77. package/dist/esm/nvs-dynamic-form/elements/arrayField/_type.js.map +1 -0
  78. package/dist/esm/nvs-dynamic-form/elements/arrayField/index.js.map +1 -0
  79. package/dist/esm/nvs-dynamic-form/elements/button/_template.d.ts +3 -0
  80. package/dist/esm/nvs-dynamic-form/elements/button/_template.js +21 -0
  81. package/dist/esm/nvs-dynamic-form/elements/button/_template.js.map +1 -0
  82. package/dist/esm/nvs-dynamic-form/elements/button/_type.d.ts +8 -0
  83. package/dist/esm/nvs-dynamic-form/elements/button/_type.js +2 -0
  84. package/dist/esm/nvs-dynamic-form/elements/button/_type.js.map +1 -0
  85. package/dist/esm/nvs-dynamic-form/elements/button/index.d.ts +2 -0
  86. package/dist/esm/nvs-dynamic-form/elements/button/index.js +3 -0
  87. package/dist/esm/nvs-dynamic-form/elements/button/index.js.map +1 -0
  88. package/dist/esm/nvs-dynamic-form/elements/container/_template.d.ts +3 -0
  89. package/dist/esm/nvs-dynamic-form/elements/container/_template.js +5 -0
  90. package/dist/esm/nvs-dynamic-form/elements/container/_template.js.map +1 -0
  91. package/dist/esm/nvs-dynamic-form/elements/container/_type.d.ts +8 -0
  92. package/dist/esm/nvs-dynamic-form/elements/container/_type.js +2 -0
  93. package/dist/esm/nvs-dynamic-form/elements/container/_type.js.map +1 -0
  94. package/dist/esm/nvs-dynamic-form/elements/container/index.d.ts +2 -0
  95. package/dist/esm/nvs-dynamic-form/elements/container/index.js +3 -0
  96. package/dist/esm/nvs-dynamic-form/elements/container/index.js.map +1 -0
  97. package/dist/esm/nvs-dynamic-form/elements/field/_type.d.ts +7 -6
  98. package/dist/esm/nvs-dynamic-form/elements/groupField/_template.d.ts +2 -0
  99. package/dist/esm/nvs-dynamic-form/elements/groupField/_template.js +22 -0
  100. package/dist/esm/nvs-dynamic-form/elements/groupField/_template.js.map +1 -0
  101. package/dist/esm/nvs-dynamic-form/elements/groupField/_type.d.ts +9 -0
  102. package/dist/esm/nvs-dynamic-form/elements/groupField/_type.js +2 -0
  103. package/dist/esm/nvs-dynamic-form/elements/groupField/_type.js.map +1 -0
  104. package/dist/esm/nvs-dynamic-form/elements/groupField/index.d.ts +2 -0
  105. package/dist/esm/nvs-dynamic-form/elements/groupField/index.js +3 -0
  106. package/dist/esm/nvs-dynamic-form/elements/groupField/index.js.map +1 -0
  107. package/dist/esm/nvs-dynamic-form/formikForm/_template.d.ts +3 -0
  108. package/dist/esm/nvs-dynamic-form/formikForm/_template.js +60 -0
  109. package/dist/esm/nvs-dynamic-form/formikForm/_template.js.map +1 -0
  110. package/dist/esm/nvs-dynamic-form/formikForm/_type.d.ts +8 -0
  111. package/dist/esm/nvs-dynamic-form/formikForm/_type.js +2 -0
  112. package/dist/esm/nvs-dynamic-form/formikForm/_type.js.map +1 -0
  113. package/dist/esm/nvs-dynamic-form/formikForm/index.d.ts +1 -0
  114. package/dist/esm/nvs-dynamic-form/formikForm/index.js +2 -0
  115. package/dist/esm/nvs-dynamic-form/formikForm/index.js.map +1 -0
  116. package/dist/esm/nvs-dynamic-form/services/generateFormContentUtils.d.ts +44 -0
  117. package/dist/esm/nvs-dynamic-form/services/generateFormContentUtils.js +89 -0
  118. package/dist/esm/nvs-dynamic-form/services/generateFormContentUtils.js.map +1 -0
  119. package/dist/esm/types/array-field-action-button.type.d.ts +14 -0
  120. package/dist/esm/types/array-field-action-button.type.js +20 -0
  121. package/dist/esm/types/array-field-action-button.type.js.map +1 -0
  122. package/dist/esm/types/array-field.type.d.ts +13 -0
  123. package/dist/esm/types/array-field.type.js +11 -0
  124. package/dist/esm/types/array-field.type.js.map +1 -0
  125. package/dist/esm/types/{form-field.type.js → field-base.type.js} +1 -1
  126. package/dist/esm/types/{form-field.type.js.map → field-base.type.js.map} +1 -1
  127. package/dist/esm/types/group-field.type.d.ts +10 -0
  128. package/dist/esm/types/group-field.type.js +9 -0
  129. package/dist/esm/types/group-field.type.js.map +1 -0
  130. package/dist/esm/types/index.d.ts +5 -2
  131. package/dist/esm/types/index.js +5 -2
  132. package/dist/esm/types/index.js.map +1 -1
  133. package/dist/esm/types/{submit-button-options.type.d.ts → submit-button-default-options.type.d.ts} +1 -1
  134. package/dist/esm/types/submit-button-default-options.type.js +2 -0
  135. package/dist/esm/types/submit-button-default-options.type.js.map +1 -0
  136. package/lib/nvs-dynamic-form/_stories.tsx +275 -16
  137. package/lib/nvs-dynamic-form/_style.css +40 -0
  138. package/lib/nvs-dynamic-form/_template.tsx +44 -65
  139. package/lib/nvs-dynamic-form/_type.tsx +27 -4
  140. package/lib/nvs-dynamic-form/elements/arrayField/_template.tsx +149 -0
  141. package/lib/nvs-dynamic-form/elements/arrayField/_type.tsx +18 -0
  142. package/lib/nvs-dynamic-form/elements/arrayField/index.tsx +2 -0
  143. package/lib/nvs-dynamic-form/elements/button/_template.tsx +42 -0
  144. package/lib/nvs-dynamic-form/elements/button/_type.tsx +8 -0
  145. package/lib/nvs-dynamic-form/elements/button/index.tsx +2 -0
  146. package/lib/nvs-dynamic-form/elements/container/_template.tsx +10 -0
  147. package/lib/nvs-dynamic-form/elements/container/_type.tsx +7 -0
  148. package/lib/nvs-dynamic-form/elements/container/index.tsx +2 -0
  149. package/lib/nvs-dynamic-form/elements/field/_type.tsx +8 -6
  150. package/lib/nvs-dynamic-form/elements/groupField/_template.tsx +32 -0
  151. package/lib/nvs-dynamic-form/elements/groupField/_type.tsx +10 -0
  152. package/lib/nvs-dynamic-form/elements/groupField/index.tsx +2 -0
  153. package/lib/nvs-dynamic-form/formikForm/_template.tsx +85 -0
  154. package/lib/nvs-dynamic-form/formikForm/_type.tsx +9 -0
  155. package/lib/nvs-dynamic-form/formikForm/index.tsx +1 -0
  156. package/lib/nvs-dynamic-form/services/generateFormContentUtils.tsx +190 -0
  157. package/lib/types/array-field-action-button.type.tsx +26 -0
  158. package/lib/types/array-field.type.tsx +23 -0
  159. package/lib/types/group-field.type.tsx +15 -0
  160. package/lib/types/index.tsx +5 -2
  161. package/lib/types/submit-button-default-options.type.tsx +5 -0
  162. package/package.json +1 -1
  163. package/dist/cjs/nvs-dynamic-form/elements/submit-button/_template.d.ts +0 -3
  164. package/dist/cjs/nvs-dynamic-form/elements/submit-button/_template.js +0 -30
  165. package/dist/cjs/nvs-dynamic-form/elements/submit-button/_template.js.map +0 -1
  166. package/dist/cjs/nvs-dynamic-form/elements/submit-button/_type.d.ts +0 -11
  167. package/dist/cjs/nvs-dynamic-form/elements/submit-button/_type.js.map +0 -1
  168. package/dist/cjs/nvs-dynamic-form/elements/submit-button/index.js.map +0 -1
  169. package/dist/cjs/types/submit-button-options.type.js +0 -7
  170. package/dist/cjs/types/submit-button-options.type.js.map +0 -1
  171. package/dist/esm/nvs-dynamic-form/elements/submit-button/_template.d.ts +0 -3
  172. package/dist/esm/nvs-dynamic-form/elements/submit-button/_template.js +0 -23
  173. package/dist/esm/nvs-dynamic-form/elements/submit-button/_template.js.map +0 -1
  174. package/dist/esm/nvs-dynamic-form/elements/submit-button/_type.d.ts +0 -11
  175. package/dist/esm/nvs-dynamic-form/elements/submit-button/_type.js.map +0 -1
  176. package/dist/esm/nvs-dynamic-form/elements/submit-button/index.js.map +0 -1
  177. package/dist/esm/types/submit-button-options.type.js +0 -3
  178. package/dist/esm/types/submit-button-options.type.js.map +0 -1
  179. package/lib/nvs-dynamic-form/elements/submit-button/_template.tsx +0 -42
  180. package/lib/nvs-dynamic-form/elements/submit-button/_type.tsx +0 -12
  181. package/lib/types/submit-button-options.type.tsx +0 -5
  182. /package/dist/cjs/nvs-dynamic-form/elements/{submit-button → arrayField}/_type.js +0 -0
  183. /package/dist/cjs/nvs-dynamic-form/elements/{submit-button → arrayField}/index.d.ts +0 -0
  184. /package/dist/cjs/nvs-dynamic-form/elements/{submit-button → arrayField}/index.js +0 -0
  185. /package/dist/{esm/nvs-dynamic-form/elements/submit-button → cjs/nvs-dynamic-form/elements/button}/index.d.ts +0 -0
  186. /package/dist/cjs/types/{form-field.type.d.ts → field-base.type.d.ts} +0 -0
  187. /package/dist/esm/nvs-dynamic-form/elements/{submit-button → arrayField}/_type.js +0 -0
  188. /package/{lib/nvs-dynamic-form/elements/submit-button/index.tsx → dist/esm/nvs-dynamic-form/elements/arrayField/index.d.ts} +0 -0
  189. /package/dist/esm/nvs-dynamic-form/elements/{submit-button → arrayField}/index.js +0 -0
  190. /package/dist/esm/types/{form-field.type.d.ts → field-base.type.d.ts} +0 -0
  191. /package/lib/types/{form-field.type.tsx → field-base.type.tsx} +0 -0
@@ -0,0 +1,149 @@
1
+ import * as lodash from "lodash";
2
+
3
+ import { ArrayFieldAddButton, ArrayFieldRemoveButton } from "../../../types";
4
+ import React, { useState } from "react";
5
+
6
+ import { FieldArray } from "formik";
7
+ import { GenerateFormContentUtils } from "../../services/generateFormContentUtils";
8
+ import { IArrayField } from "./_type";
9
+
10
+ export const ArrayField: React.FC<IArrayField> = ({
11
+ field: arrayField,
12
+ formElements,
13
+ containerComponent,
14
+ containerVisible,
15
+ useContainersOutsideGroup,
16
+ useGroupContainer,
17
+ buttonComponent: ButtonComponent,
18
+ addButtonDefaultOptions,
19
+ removeButtonDefaultOptions,
20
+ }: IArrayField) => {
21
+ const [addButtonOptions] = useState(
22
+ new ArrayFieldAddButton(
23
+ lodash.merge(
24
+ addButtonDefaultOptions ?? {},
25
+ arrayField.addButtonOptions ?? {},
26
+ ),
27
+ ),
28
+ );
29
+ const [removeButtonOptions] = useState(
30
+ new ArrayFieldRemoveButton(
31
+ lodash.merge(
32
+ removeButtonDefaultOptions ?? {},
33
+ arrayField.removeButtonOptions ?? {},
34
+ ),
35
+ ),
36
+ );
37
+ const generateFormContentUtils = new GenerateFormContentUtils({
38
+ containerComponent,
39
+ formElements,
40
+ useContainersOutsideGroup,
41
+ useGroupContainer,
42
+ containerVisible: containerVisible,
43
+ fields: arrayField.fields,
44
+ fieldArrayAddButtonDefaultOptions: addButtonDefaultOptions,
45
+ fieldArrayRemoveButtonDefaultOptions: removeButtonDefaultOptions,
46
+ });
47
+
48
+ const createArrayItem = (name: string, index: number) => {
49
+ return arrayField.fields.map((field) => ({
50
+ ...field,
51
+ id: `${name}[${index}].${field.id}`,
52
+ }));
53
+ };
54
+
55
+ const getDefaultItem = () => {
56
+ return arrayField.fields.reduce((acc: { [key: string]: any }, field) => {
57
+ acc[field.id] = field.defaultValue;
58
+ return acc;
59
+ }, {});
60
+ };
61
+
62
+ const createArrayFields = (index: number) => {
63
+ return (
64
+ <div className="df-array-field-content">
65
+ <div className="nvs-container-fluid">
66
+ <div className="nvs-row">
67
+ {generateFormContentUtils.createFormElements(
68
+ createArrayItem(arrayField.id, index),
69
+ )}
70
+ </div>
71
+ </div>
72
+ </div>
73
+ );
74
+ };
75
+
76
+ const createRemoveButton = (onRemoveItem: Function) => {
77
+ return (
78
+ <div className="nvs-col-12">
79
+ <ButtonComponent
80
+ onClick={() => {
81
+ onRemoveItem();
82
+ }}
83
+ type="button"
84
+ {...removeButtonOptions.options}
85
+ >
86
+ {removeButtonOptions.label}
87
+ </ButtonComponent>
88
+ </div>
89
+ );
90
+ };
91
+
92
+ const createArrayItemRemoveButton = (onRemoveItem: Function) => {
93
+ return (
94
+ <div className="df-array-field-remove-button">
95
+ {generateFormContentUtils.createContentContainer(
96
+ createRemoveButton(onRemoveItem),
97
+ )}
98
+ </div>
99
+ );
100
+ };
101
+
102
+ const createFieldArrayContent = (
103
+ onRemoveItem: (index: number) => void,
104
+ index: number,
105
+ ) => {
106
+ return (
107
+ <div
108
+ className={`df-array-field remove-button-${removeButtonOptions.position}`}
109
+ key={index}
110
+ >
111
+ {createArrayFields(index)}
112
+ {createArrayItemRemoveButton(() => onRemoveItem(index))}
113
+ </div>
114
+ );
115
+ };
116
+
117
+ const createAddButton = (onAddItem: Function) => {
118
+ return (
119
+ <div className="df-array-field-add-button">
120
+ <ButtonComponent
121
+ onClick={() => onAddItem(getDefaultItem())}
122
+ type="button"
123
+ {...addButtonOptions.options}
124
+ >
125
+ {addButtonOptions.label}
126
+ </ButtonComponent>
127
+ </div>
128
+ );
129
+ };
130
+
131
+ const createArrayItemAddButton = (onAddItem: Function) => {
132
+ return generateFormContentUtils.createContentContainer(
133
+ createAddButton(onAddItem),
134
+ );
135
+ };
136
+
137
+ return (
138
+ <FieldArray name={arrayField.id}>
139
+ {({ push, remove, form }) => (
140
+ <>
141
+ {form.values[arrayField.id]?.map((_: any, index: number) =>
142
+ createFieldArrayContent(remove, index),
143
+ )}
144
+ {createArrayItemAddButton(push)}
145
+ </>
146
+ )}
147
+ </FieldArray>
148
+ );
149
+ };
@@ -0,0 +1,18 @@
1
+ import {
2
+ ArrayField,
3
+ ArrayFieldAddButton,
4
+ ArrayFieldRemoveButton,
5
+ } from "../../../types";
6
+
7
+ import { IField } from "../field";
8
+
9
+ export interface IArrayField extends IField {
10
+ field: ArrayField;
11
+ buttonComponent: React.FC<any>;
12
+ containerComponent: React.FC<any>;
13
+ containerVisible: boolean;
14
+ useContainersOutsideGroup: boolean;
15
+ useGroupContainer: boolean;
16
+ addButtonDefaultOptions?: ArrayFieldAddButton;
17
+ removeButtonDefaultOptions?: ArrayFieldRemoveButton;
18
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./_template";
2
+ export * from "./_type";
@@ -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,8 @@
1
+ export interface IButton {
2
+ buttonComponent: React.FC<any>;
3
+ visible?: boolean;
4
+ label?: string;
5
+ position?: "left" | "center" | "right";
6
+ isFullWidth?: boolean;
7
+ containerClass?: string;
8
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./_template";
2
+ export * from "./_type";
@@ -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
+ };
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from "react";
2
+
3
+ export interface IContainer {
4
+ containerComponent: React.FC<any>;
5
+ options?: { [key: string]: any };
6
+ children?: ReactNode;
7
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./_type";
2
+ export * from "./_template";
@@ -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,2 @@
1
+ export * from "./_type";
2
+ export * from "./_template";
@@ -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,190 @@
1
+ import {
2
+ ArrayField,
3
+ ArrayFieldAddButton,
4
+ FieldBase,
5
+ GroupField,
6
+ } from "../../types";
7
+
8
+ import { ArrayField as ArrayFieldElement } from "../elements/arrayField";
9
+ import { Container } from "../elements/container";
10
+ import { Field } from "../elements/field";
11
+ import { FieldType } from "../_type";
12
+ import { GroupField as GroupFieldElement } from "../elements/groupField";
13
+ import { IFormElement } from "../elements/field";
14
+ import React from "react";
15
+ import { ReactNode } from "react";
16
+
17
+ export class GenerateFormContentUtils {
18
+ private readonly containerComponent: React.FC<any>;
19
+ private readonly formElements: IFormElement;
20
+ private readonly useContainersOutsideGroup: boolean;
21
+ private readonly useGroupContainer: boolean;
22
+ private readonly containerVisible: boolean;
23
+ private readonly fields: Array<FieldType>;
24
+ private readonly containerOptions: { [key: string]: any };
25
+ private readonly buttonComponent?: React.FC<any>;
26
+ private readonly fieldArrayAddButtonDefaultOptions: ArrayFieldAddButton;
27
+ private readonly fieldArrayRemoveButtonDefaultOptions: ArrayFieldAddButton;
28
+
29
+ constructor({
30
+ containerComponent,
31
+ formElements,
32
+ useContainersOutsideGroup,
33
+ useGroupContainer,
34
+ containerVisible,
35
+ fields,
36
+ containerOptions,
37
+ buttonComponent,
38
+ fieldArrayAddButtonDefaultOptions,
39
+ fieldArrayRemoveButtonDefaultOptions,
40
+ }: {
41
+ containerComponent: React.FC<any>;
42
+ formElements: IFormElement;
43
+ useContainersOutsideGroup: boolean;
44
+ useGroupContainer: boolean;
45
+ containerVisible: boolean;
46
+ fields: Array<FieldType>;
47
+ buttonComponent?: React.FC<any>;
48
+ containerOptions?: { [key: string]: any };
49
+ fieldArrayAddButtonDefaultOptions?: ArrayFieldAddButton;
50
+ fieldArrayRemoveButtonDefaultOptions?: ArrayFieldAddButton;
51
+ }) {
52
+ this.containerComponent = containerComponent;
53
+ this.formElements = formElements;
54
+ this.useContainersOutsideGroup = useContainersOutsideGroup;
55
+ this.useGroupContainer = useGroupContainer;
56
+ this.containerVisible = containerVisible;
57
+ this.fields = fields;
58
+ this.containerOptions = containerOptions ?? {};
59
+ this.buttonComponent = buttonComponent;
60
+ this.fieldArrayAddButtonDefaultOptions =
61
+ fieldArrayAddButtonDefaultOptions ?? {};
62
+ this.fieldArrayRemoveButtonDefaultOptions =
63
+ fieldArrayRemoveButtonDefaultOptions ?? {};
64
+ }
65
+
66
+ createContainer(content: ReactNode, containerProps: object) {
67
+ return (
68
+ <Container
69
+ containerComponent={this.containerComponent}
70
+ options={containerProps}
71
+ >
72
+ {content}
73
+ </Container>
74
+ );
75
+ }
76
+
77
+ createFormContent() {
78
+ const singleFields = this.createSingleFieldsElements();
79
+ const groupFields = this.createGroupFieldsElements();
80
+
81
+ let formContent;
82
+ if (this.containerVisible && this.useContainersOutsideGroup && singleFields)
83
+ formContent = (
84
+ <>
85
+ {this.createContainer(singleFields, this.containerOptions)}
86
+ {groupFields}
87
+ </>
88
+ );
89
+ else
90
+ formContent = this.createFormGroup(
91
+ <>
92
+ {singleFields}
93
+ {groupFields}
94
+ </>,
95
+ );
96
+
97
+ return formContent;
98
+ }
99
+
100
+ createFormElements(fields: Array<FieldType>): JSX.Element[] {
101
+ const fieldsElements = [];
102
+ for (const field of fields) {
103
+ if (field instanceof GroupField)
104
+ fieldsElements.push(this.createGroupFieldElement(field));
105
+ else if (field instanceof ArrayField)
106
+ fieldsElements.push(this.createArrayFieldElement(field));
107
+ else fieldsElements.push(this.createSingleFieldElement(field));
108
+ }
109
+ return fieldsElements;
110
+ }
111
+
112
+ createContentContainer(formElements: ReactNode) {
113
+ return (
114
+ <div className="nvs-container-fluid">
115
+ <div className="nvs-row">{formElements}</div>
116
+ </div>
117
+ );
118
+ }
119
+
120
+ private getSingleFields() {
121
+ return this.fields.filter((field) => this.isSingleField(field));
122
+ }
123
+
124
+ private getGroupFields() {
125
+ return this.fields.filter((field) => !this.isSingleField(field));
126
+ }
127
+
128
+ private createSingleFieldsElements() {
129
+ const singleFields = this.getSingleFields();
130
+ return (
131
+ singleFields.length > 0 &&
132
+ this.createContentContainer(this.createFormElements(singleFields))
133
+ );
134
+ }
135
+
136
+ private createGroupFieldsElements() {
137
+ const groupFields = this.getGroupFields();
138
+ return groupFields.length > 0 && this.createFormElements(groupFields);
139
+ }
140
+
141
+ private createSingleFieldElement(field: FieldBase<unknown>) {
142
+ return (
143
+ <Field key={field.id} formElements={this.formElements} field={field} />
144
+ );
145
+ }
146
+
147
+ private createGroupFieldElement(field: GroupField) {
148
+ return (
149
+ <GroupFieldElement
150
+ key={field.id}
151
+ formElements={this.formElements}
152
+ field={field}
153
+ containerComponent={this.containerComponent}
154
+ useContainersOutsideGroup={this.useContainersOutsideGroup}
155
+ useGroupContainer={this.useGroupContainer}
156
+ containerVisible={this.containerVisible}
157
+ />
158
+ );
159
+ }
160
+
161
+ private createArrayFieldElement(field: ArrayField) {
162
+ return (
163
+ <ArrayFieldElement
164
+ key={field.id}
165
+ formElements={this.formElements}
166
+ field={field}
167
+ containerComponent={this.containerComponent}
168
+ useContainersOutsideGroup={this.useContainersOutsideGroup}
169
+ useGroupContainer={this.useGroupContainer}
170
+ containerVisible={this.containerVisible}
171
+ buttonComponent={this.buttonComponent!}
172
+ addButtonDefaultOptions={this.fieldArrayAddButtonDefaultOptions}
173
+ removeButtonDefaultOptions={this.fieldArrayRemoveButtonDefaultOptions}
174
+ />
175
+ );
176
+ }
177
+
178
+ private isSingleField(field: FieldType) {
179
+ return !(
180
+ field instanceof GroupField &&
181
+ field.containerVisible &&
182
+ this.useGroupContainer &&
183
+ this.containerVisible
184
+ );
185
+ }
186
+
187
+ private createFormGroup(formContent: ReactNode) {
188
+ return <div className="df-form-group">{formContent}</div>;
189
+ }
190
+ }
@@ -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,23 @@
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 = options.addButtonOptions ?? {};
20
+ this.removeButtonOptions = options.removeButtonOptions ?? {};
21
+ this.defaultValues = options.defaultValues ?? [];
22
+ }
23
+ }
@@ -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
+ }
@@ -1,4 +1,7 @@
1
- export * from "./form-field.type";
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";
7
+ export * from "./array-field-action-button.type";