@bgroup/wise-form 1.0.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.
Files changed (319) hide show
  1. package/README.md +34 -0
  2. package/dist/components/ui/Checkbox.d.ts +14 -0
  3. package/dist/components/ui/Checkbox.d.ts.map +1 -0
  4. package/dist/components/ui/Checkbox.js +43 -0
  5. package/dist/components/ui/Checkbox.js.map +1 -0
  6. package/dist/components/ui/CheckboxGroup.d.ts +15 -0
  7. package/dist/components/ui/CheckboxGroup.d.ts.map +1 -0
  8. package/dist/components/ui/CheckboxGroup.js +33 -0
  9. package/dist/components/ui/CheckboxGroup.js.map +1 -0
  10. package/dist/components/ui/Input.d.ts +14 -0
  11. package/dist/components/ui/Input.d.ts.map +1 -0
  12. package/dist/components/ui/Input.js +49 -0
  13. package/dist/components/ui/Input.js.map +1 -0
  14. package/dist/components/ui/Radio.d.ts +14 -0
  15. package/dist/components/ui/Radio.d.ts.map +1 -0
  16. package/dist/components/ui/Radio.js +43 -0
  17. package/dist/components/ui/Radio.js.map +1 -0
  18. package/dist/components/ui/Select.d.ts +18 -0
  19. package/dist/components/ui/Select.d.ts.map +1 -0
  20. package/dist/components/ui/Select.js +44 -0
  21. package/dist/components/ui/Select.js.map +1 -0
  22. package/dist/components/ui/Textarea.d.ts +13 -0
  23. package/dist/components/ui/Textarea.d.ts.map +1 -0
  24. package/dist/components/ui/Textarea.js +42 -0
  25. package/dist/components/ui/Textarea.js.map +1 -0
  26. package/dist/components/ui/index.d.ts +13 -0
  27. package/dist/components/ui/index.d.ts.map +1 -0
  28. package/dist/components/ui/index.js +7 -0
  29. package/dist/components/ui/index.js.map +1 -0
  30. package/dist/form/index.d.ts +10 -0
  31. package/dist/form/index.d.ts.map +1 -0
  32. package/dist/form/index.js +5 -0
  33. package/dist/form/index.js.map +1 -0
  34. package/dist/form/interfaces/field-container.d.ts +8 -0
  35. package/dist/form/interfaces/field-container.d.ts.map +1 -0
  36. package/dist/form/interfaces/field-container.js +2 -0
  37. package/dist/form/interfaces/field-container.js.map +1 -0
  38. package/dist/form/interfaces/interfaces.d.ts +8 -0
  39. package/dist/form/interfaces/interfaces.d.ts.map +1 -0
  40. package/dist/form/interfaces/interfaces.js +2 -0
  41. package/dist/form/interfaces/interfaces.js.map +1 -0
  42. package/dist/form/interfaces/settings.d.ts +10 -0
  43. package/dist/form/interfaces/settings.d.ts.map +1 -0
  44. package/dist/form/interfaces/settings.js +2 -0
  45. package/dist/form/interfaces/settings.js.map +1 -0
  46. package/dist/form/interfaces/template.d.ts +6 -0
  47. package/dist/form/interfaces/template.d.ts.map +1 -0
  48. package/dist/form/interfaces/template.js +2 -0
  49. package/dist/form/interfaces/template.js.map +1 -0
  50. package/dist/form/interfaces/wise-form-specs.d.ts +9 -0
  51. package/dist/form/interfaces/wise-form-specs.d.ts.map +1 -0
  52. package/dist/form/interfaces/wise-form-specs.js +2 -0
  53. package/dist/form/interfaces/wise-form-specs.js.map +1 -0
  54. package/dist/form/view/components/containers/index.d.ts +3 -0
  55. package/dist/form/view/components/containers/index.d.ts.map +1 -0
  56. package/dist/form/view/components/containers/index.js +12 -0
  57. package/dist/form/view/components/containers/index.js.map +1 -0
  58. package/dist/form/view/components/error.d.ts +5 -0
  59. package/dist/form/view/components/error.d.ts.map +1 -0
  60. package/dist/form/view/components/error.js +8 -0
  61. package/dist/form/view/components/error.js.map +1 -0
  62. package/dist/form/view/components/field/container.d.ts +5 -0
  63. package/dist/form/view/components/field/container.d.ts.map +1 -0
  64. package/dist/form/view/components/field/container.js +5 -0
  65. package/dist/form/view/components/field/container.js.map +1 -0
  66. package/dist/form/view/components/field/index.d.ts +18 -0
  67. package/dist/form/view/components/field/index.d.ts.map +1 -0
  68. package/dist/form/view/components/field/index.js +89 -0
  69. package/dist/form/view/components/field/index.js.map +1 -0
  70. package/dist/form/view/components/field/selection.d.ts +2 -0
  71. package/dist/form/view/components/field/selection.d.ts.map +1 -0
  72. package/dist/form/view/components/field/selection.js +35 -0
  73. package/dist/form/view/components/field/selection.js.map +1 -0
  74. package/dist/form/view/components/field/use-field.d.ts +4 -0
  75. package/dist/form/view/components/field/use-field.d.ts.map +1 -0
  76. package/dist/form/view/components/field/use-field.js +41 -0
  77. package/dist/form/view/components/field/use-field.js.map +1 -0
  78. package/dist/form/view/components/rows/row-container.d.ts +18 -0
  79. package/dist/form/view/components/rows/row-container.d.ts.map +1 -0
  80. package/dist/form/view/components/rows/row-container.js +89 -0
  81. package/dist/form/view/components/rows/row-container.js.map +1 -0
  82. package/dist/form/view/components/rows/wrapper.d.ts +12 -0
  83. package/dist/form/view/components/rows/wrapper.d.ts.map +1 -0
  84. package/dist/form/view/components/rows/wrapper.js +27 -0
  85. package/dist/form/view/components/rows/wrapper.js.map +1 -0
  86. package/dist/form/view/components/wrapped-form.d.ts +6 -0
  87. package/dist/form/view/components/wrapped-form.d.ts.map +1 -0
  88. package/dist/form/view/components/wrapped-form.js +26 -0
  89. package/dist/form/view/components/wrapped-form.js.map +1 -0
  90. package/dist/form/view/context.d.ts +23 -0
  91. package/dist/form/view/context.d.ts.map +1 -0
  92. package/dist/form/view/context.js +7 -0
  93. package/dist/form/view/context.js.map +1 -0
  94. package/dist/form/view/hooks/use-model.d.ts +10 -0
  95. package/dist/form/view/hooks/use-model.d.ts.map +1 -0
  96. package/dist/form/view/hooks/use-model.js +31 -0
  97. package/dist/form/view/hooks/use-model.js.map +1 -0
  98. package/dist/form/view/hooks/use-template.d.ts +14 -0
  99. package/dist/form/view/hooks/use-template.d.ts.map +1 -0
  100. package/dist/form/view/hooks/use-template.js +57 -0
  101. package/dist/form/view/hooks/use-template.js.map +1 -0
  102. package/dist/form/view/hooks/use-types.d.ts +2 -0
  103. package/dist/form/view/hooks/use-types.d.ts.map +1 -0
  104. package/dist/form/view/hooks/use-types.js +19 -0
  105. package/dist/form/view/hooks/use-types.js.map +1 -0
  106. package/dist/form/view/index.d.ts +3 -0
  107. package/dist/form/view/index.d.ts.map +1 -0
  108. package/dist/form/view/index.js +38 -0
  109. package/dist/form/view/index.js.map +1 -0
  110. package/dist/formulas/helpers/condition-types.d.ts +5 -0
  111. package/dist/formulas/helpers/condition-types.d.ts.map +1 -0
  112. package/dist/formulas/helpers/condition-types.js +5 -0
  113. package/dist/formulas/helpers/condition-types.js.map +1 -0
  114. package/dist/formulas/helpers/evaluations.d.ts +15 -0
  115. package/dist/formulas/helpers/evaluations.d.ts.map +1 -0
  116. package/dist/formulas/helpers/evaluations.js +44 -0
  117. package/dist/formulas/helpers/evaluations.js.map +1 -0
  118. package/dist/formulas/helpers/formula.d.ts +6 -0
  119. package/dist/formulas/helpers/formula.d.ts.map +1 -0
  120. package/dist/formulas/helpers/formula.js +26 -0
  121. package/dist/formulas/helpers/formula.js.map +1 -0
  122. package/dist/formulas/helpers/lexer.d.ts +10 -0
  123. package/dist/formulas/helpers/lexer.d.ts.map +1 -0
  124. package/dist/formulas/helpers/lexer.js +73 -0
  125. package/dist/formulas/helpers/lexer.js.map +1 -0
  126. package/dist/formulas/helpers/parser.d.ts +24 -0
  127. package/dist/formulas/helpers/parser.d.ts.map +1 -0
  128. package/dist/formulas/helpers/parser.js +48 -0
  129. package/dist/formulas/helpers/parser.js.map +1 -0
  130. package/dist/formulas/helpers/token.d.ts +14 -0
  131. package/dist/formulas/helpers/token.d.ts.map +1 -0
  132. package/dist/formulas/helpers/token.js +14 -0
  133. package/dist/formulas/helpers/token.js.map +1 -0
  134. package/dist/formulas/index.d.ts +59 -0
  135. package/dist/formulas/index.d.ts.map +1 -0
  136. package/dist/formulas/index.js +186 -0
  137. package/dist/formulas/index.js.map +1 -0
  138. package/dist/formulas/types/formulas.d.ts +68 -0
  139. package/dist/formulas/types/formulas.d.ts.map +1 -0
  140. package/dist/formulas/types/formulas.js +2 -0
  141. package/dist/formulas/types/formulas.js.map +1 -0
  142. package/dist/formulas/types/index.d.ts +5 -0
  143. package/dist/formulas/types/index.d.ts.map +1 -0
  144. package/dist/formulas/types/index.js +2 -0
  145. package/dist/formulas/types/index.js.map +1 -0
  146. package/dist/formulas/variants/array-formula.d.ts +24 -0
  147. package/dist/formulas/variants/array-formula.d.ts.map +1 -0
  148. package/dist/formulas/variants/array-formula.js +142 -0
  149. package/dist/formulas/variants/array-formula.js.map +1 -0
  150. package/dist/formulas/variants/base.d.ts +6 -0
  151. package/dist/formulas/variants/base.d.ts.map +1 -0
  152. package/dist/formulas/variants/base.js +3 -0
  153. package/dist/formulas/variants/base.js.map +1 -0
  154. package/dist/formulas/variants/basic.d.ts +18 -0
  155. package/dist/formulas/variants/basic.d.ts.map +1 -0
  156. package/dist/formulas/variants/basic.js +128 -0
  157. package/dist/formulas/variants/basic.js.map +1 -0
  158. package/dist/formulas/variants/comparison.d.ts +25 -0
  159. package/dist/formulas/variants/comparison.d.ts.map +1 -0
  160. package/dist/formulas/variants/comparison.js +153 -0
  161. package/dist/formulas/variants/comparison.js.map +1 -0
  162. package/dist/formulas/variants/conditional.d.ts +18 -0
  163. package/dist/formulas/variants/conditional.d.ts.map +1 -0
  164. package/dist/formulas/variants/conditional.js +183 -0
  165. package/dist/formulas/variants/conditional.js.map +1 -0
  166. package/dist/formulas/variants/iterative-array.d.ts +20 -0
  167. package/dist/formulas/variants/iterative-array.d.ts.map +1 -0
  168. package/dist/formulas/variants/iterative-array.js +155 -0
  169. package/dist/formulas/variants/iterative-array.js.map +1 -0
  170. package/dist/formulas/variants/per-value.d.ts +20 -0
  171. package/dist/formulas/variants/per-value.d.ts.map +1 -0
  172. package/dist/formulas/variants/per-value.js +154 -0
  173. package/dist/formulas/variants/per-value.js.map +1 -0
  174. package/dist/index.d.ts +5 -0
  175. package/dist/index.d.ts.map +1 -0
  176. package/dist/index.js +6 -0
  177. package/dist/index.js.map +1 -0
  178. package/dist/models/base.d.ts +55 -0
  179. package/dist/models/base.d.ts.map +1 -0
  180. package/dist/models/base.js +146 -0
  181. package/dist/models/base.js.map +1 -0
  182. package/dist/models/callback-manager.d.ts +7 -0
  183. package/dist/models/callback-manager.d.ts.map +1 -0
  184. package/dist/models/callback-manager.js +89 -0
  185. package/dist/models/callback-manager.js.map +1 -0
  186. package/dist/models/field.d.ts +121 -0
  187. package/dist/models/field.d.ts.map +1 -0
  188. package/dist/models/field.js +374 -0
  189. package/dist/models/field.js.map +1 -0
  190. package/dist/models/index.d.ts +13 -0
  191. package/dist/models/index.d.ts.map +1 -0
  192. package/dist/models/index.js +7 -0
  193. package/dist/models/index.js.map +1 -0
  194. package/dist/models/model.d.ts +37 -0
  195. package/dist/models/model.d.ts.map +1 -0
  196. package/dist/models/model.js +245 -0
  197. package/dist/models/model.js.map +1 -0
  198. package/dist/models/plugins/base.d.ts +9 -0
  199. package/dist/models/plugins/base.d.ts.map +1 -0
  200. package/dist/models/plugins/base.js +3 -0
  201. package/dist/models/plugins/base.js.map +1 -0
  202. package/dist/models/plugins/formula.d.ts +18 -0
  203. package/dist/models/plugins/formula.d.ts.map +1 -0
  204. package/dist/models/plugins/formula.js +82 -0
  205. package/dist/models/plugins/formula.js.map +1 -0
  206. package/dist/models/plugins/index.d.ts +11 -0
  207. package/dist/models/plugins/index.d.ts.map +1 -0
  208. package/dist/models/plugins/index.js +52 -0
  209. package/dist/models/plugins/index.js.map +1 -0
  210. package/dist/models/plugins/plugins.d.ts +7 -0
  211. package/dist/models/plugins/plugins.d.ts.map +1 -0
  212. package/dist/models/plugins/plugins.js +7 -0
  213. package/dist/models/plugins/plugins.js.map +1 -0
  214. package/dist/models/types/base-wise-model.d.ts +7 -0
  215. package/dist/models/types/base-wise-model.d.ts.map +1 -0
  216. package/dist/models/types/base-wise-model.js +2 -0
  217. package/dist/models/types/base-wise-model.js.map +1 -0
  218. package/dist/models/types/callbacks.d.ts +19 -0
  219. package/dist/models/types/callbacks.d.ts.map +1 -0
  220. package/dist/models/types/callbacks.js +2 -0
  221. package/dist/models/types/callbacks.js.map +1 -0
  222. package/dist/models/types/disabled.d.ts +8 -0
  223. package/dist/models/types/disabled.d.ts.map +1 -0
  224. package/dist/models/types/disabled.js +2 -0
  225. package/dist/models/types/disabled.js.map +1 -0
  226. package/dist/models/types/form-field.d.ts +25 -0
  227. package/dist/models/types/form-field.d.ts.map +1 -0
  228. package/dist/models/types/form-field.js +2 -0
  229. package/dist/models/types/form-field.js.map +1 -0
  230. package/dist/models/types/model.d.ts +13 -0
  231. package/dist/models/types/model.d.ts.map +1 -0
  232. package/dist/models/types/model.js +2 -0
  233. package/dist/models/types/model.js.map +1 -0
  234. package/dist/models/types/plugins.d.ts +13 -0
  235. package/dist/models/types/plugins.d.ts.map +1 -0
  236. package/dist/models/types/plugins.js +2 -0
  237. package/dist/models/types/plugins.js.map +1 -0
  238. package/dist/models/types/wrapped-form-model-props.d.ts +11 -0
  239. package/dist/models/types/wrapped-form-model-props.d.ts.map +1 -0
  240. package/dist/models/types/wrapped-form-model-props.js +2 -0
  241. package/dist/models/types/wrapped-form-model-props.js.map +1 -0
  242. package/dist/models/wrapper.d.ts +30 -0
  243. package/dist/models/wrapper.d.ts.map +1 -0
  244. package/dist/models/wrapper.js +213 -0
  245. package/dist/models/wrapper.js.map +1 -0
  246. package/dist/settings/index.d.ts +7 -0
  247. package/dist/settings/index.d.ts.map +1 -0
  248. package/dist/settings/index.js +26 -0
  249. package/dist/settings/index.js.map +1 -0
  250. package/dist/utils/pending-promise.d.ts +6 -0
  251. package/dist/utils/pending-promise.d.ts.map +1 -0
  252. package/dist/utils/pending-promise.js +24 -0
  253. package/dist/utils/pending-promise.js.map +1 -0
  254. package/package.json +38 -0
  255. package/src/components/ui/Checkbox.tsx +68 -0
  256. package/src/components/ui/CheckboxGroup.tsx +60 -0
  257. package/src/components/ui/Input.tsx +72 -0
  258. package/src/components/ui/Radio.tsx +68 -0
  259. package/src/components/ui/Select.tsx +73 -0
  260. package/src/components/ui/Textarea.tsx +63 -0
  261. package/src/components/ui/index.ts +14 -0
  262. package/src/form/index.ts +11 -0
  263. package/src/form/interfaces/field-container.ts +9 -0
  264. package/src/form/interfaces/interfaces.ts +12 -0
  265. package/src/form/interfaces/settings.ts +11 -0
  266. package/src/form/interfaces/template.ts +7 -0
  267. package/src/form/interfaces/wise-form-specs.ts +10 -0
  268. package/src/form/styles.css +40 -0
  269. package/src/form/view/components/containers/index.tsx +18 -0
  270. package/src/form/view/components/error.tsx +9 -0
  271. package/src/form/view/components/field/container.tsx +6 -0
  272. package/src/form/view/components/field/index.tsx +107 -0
  273. package/src/form/view/components/field/selection.tsx +39 -0
  274. package/src/form/view/components/field/use-field.tsx +49 -0
  275. package/src/form/view/components/rows/row-container.tsx +96 -0
  276. package/src/form/view/components/rows/wrapper.tsx +28 -0
  277. package/src/form/view/components/wrapped-form.tsx +32 -0
  278. package/src/form/view/context.tsx +26 -0
  279. package/src/form/view/hooks/use-model.ts +37 -0
  280. package/src/form/view/hooks/use-template.tsx +64 -0
  281. package/src/form/view/hooks/use-types.ts +21 -0
  282. package/src/form/view/index.tsx +48 -0
  283. package/src/formulas/helpers/condition-types.ts +5 -0
  284. package/src/formulas/helpers/evaluations.ts +48 -0
  285. package/src/formulas/helpers/formula.ts +27 -0
  286. package/src/formulas/helpers/lexer.ts +82 -0
  287. package/src/formulas/helpers/parser.ts +55 -0
  288. package/src/formulas/helpers/token.ts +22 -0
  289. package/src/formulas/index.ts +198 -0
  290. package/src/formulas/types/formulas.ts +72 -0
  291. package/src/formulas/types/index.ts +5 -0
  292. package/src/formulas/variants/array-formula.ts +138 -0
  293. package/src/formulas/variants/base.ts +6 -0
  294. package/src/formulas/variants/basic.ts +141 -0
  295. package/src/formulas/variants/comparison.ts +156 -0
  296. package/src/formulas/variants/conditional.ts +208 -0
  297. package/src/formulas/variants/iterative-array.ts +152 -0
  298. package/src/formulas/variants/per-value.ts +152 -0
  299. package/src/index.ts +6 -0
  300. package/src/models/base.ts +164 -0
  301. package/src/models/callback-manager.ts +102 -0
  302. package/src/models/field.ts +426 -0
  303. package/src/models/index.ts +14 -0
  304. package/src/models/model.ts +260 -0
  305. package/src/models/plugins/base.ts +11 -0
  306. package/src/models/plugins/formula.ts +80 -0
  307. package/src/models/plugins/index.ts +48 -0
  308. package/src/models/plugins/plugins.ts +8 -0
  309. package/src/models/types/base-wise-model.ts +7 -0
  310. package/src/models/types/callbacks.ts +23 -0
  311. package/src/models/types/disabled.ts +8 -0
  312. package/src/models/types/form-field.ts +22 -0
  313. package/src/models/types/model.ts +14 -0
  314. package/src/models/types/plugins.ts +15 -0
  315. package/src/models/types/wrapped-form-model-props.ts +9 -0
  316. package/src/models/wrapper.ts +242 -0
  317. package/src/settings/index.ts +11 -0
  318. package/src/utils/pending-promise.ts +29 -0
  319. package/tsconfig.json +39 -0
@@ -0,0 +1,96 @@
1
+ import React from "react";
2
+ import { Control } from "../field";
3
+ import { FormSectionWrapper } from "./wrapper";
4
+ import { IFieldContainer } from "../../../interfaces/field-container";
5
+ import type { FormField, WrappedFormModel } from "../../../../models";
6
+
7
+ /**
8
+ * Represents a container for form fields within a row, organizing them according to a specified grid style.
9
+ * This component is used to group form fields dynamically based on the `template` property, allowing for
10
+ * a flexible layout structure within the form. It supports wrapping fields in a div with a CSS grid layout
11
+ * to align items as specified by the `template` and `styles` provided.
12
+ *
13
+ * @param {Object} props The properties passed to the RowFieldContainer component.
14
+ * @param {[number, string]} props.template A tuple where the first element is the total number of fields in the row,
15
+ * and the second element is a string representing the CSS grid template for the layout of these fields.
16
+ * @param {WiseFormField[]} props.items An array of form field configurations that will be rendered within this row.
17
+ * @param {any} [props.styles] Optional styles to be applied to the row container, allowing for further customization.
18
+ * @param
19
+ *
20
+ */
21
+ export function RowFieldContainer({ template: [totalFields, gridStyle], items, styles, model }: IFieldContainer) {
22
+ // Estado para rastrear los valores de hidden de cada campo de forma reactiva
23
+ const [fieldHiddenStates, setFieldHiddenStates] = React.useState<Record<string, boolean>>(() => {
24
+ const initialStates: Record<string, boolean> = {};
25
+ items.forEach((field) => {
26
+ const fieldItem = field as any; // Using any to access dynamic properties
27
+ const fieldName = fieldItem?.name;
28
+ if (fieldName) {
29
+ const fieldModel = model.getField(fieldName);
30
+ if (fieldModel) {
31
+ const properties = (fieldModel as FormField).getProperties();
32
+ initialStates[fieldName] = (properties as any).hidden ?? false;
33
+ } else {
34
+ initialStates[fieldName] = (fieldItem as any).hidden ?? false;
35
+ }
36
+ }
37
+ });
38
+ return initialStates;
39
+ });
40
+
41
+ // Suscribirse a los cambios de cada campo
42
+ React.useEffect(() => {
43
+ const listeners: Array<() => void> = [];
44
+
45
+ items.forEach((field) => {
46
+ const fieldItem = field as any; // Using any to access dynamic properties
47
+ const fieldName = fieldItem?.name;
48
+ const fieldType = fieldItem?.type;
49
+ if (!fieldName || fieldType === "wrapper") return;
50
+
51
+ const fieldModel = model.getField(fieldName);
52
+ if (!fieldModel) return;
53
+
54
+ const onChange = () => {
55
+ const properties = (fieldModel as FormField).getProperties();
56
+ setFieldHiddenStates((prev) => ({
57
+ ...prev,
58
+ [fieldName]: (properties as any).hidden ?? false,
59
+ }));
60
+ };
61
+
62
+ fieldModel.on('change', onChange);
63
+ listeners.push(() => fieldModel.off('change', onChange));
64
+ });
65
+
66
+ return () => {
67
+ listeners.forEach((cleanup) => cleanup());
68
+ };
69
+ }, [items, model]);
70
+
71
+ let hidden = false;
72
+ const output = items.reduce((acc: React.ReactElement[], field, index) => {
73
+ const fieldItem = field as any; // Using any to access dynamic properties
74
+ const fieldType = fieldItem?.type;
75
+ if (fieldType === "wrapper") {
76
+ const fieldModel = model.getField(fieldItem?.name);
77
+ const wrapperHidden = fieldModel ? ((fieldModel as WrappedFormModel).getProperties() as any).hidden ?? false : false;
78
+ if (wrapperHidden) hidden = true;
79
+ acc.push(<FormSectionWrapper key={`rf-row__item--${index}`} data={fieldItem} model={model} />);
80
+ return acc;
81
+ }
82
+
83
+ const fieldName = fieldItem?.name;
84
+ const isHidden = fieldName ? (fieldHiddenStates[fieldName] ?? (fieldItem as any).hidden ?? false) : false;
85
+ if (!isHidden) {
86
+ acc.push(<Control index={index} model={model} field={fieldItem} key={`rf-row__item--${index}`} hidden={isHidden} />);
87
+ }
88
+ return acc;
89
+ }, []);
90
+
91
+ const attrs = { className: `rf-fields-container`, style: {} };
92
+ attrs.style = { gridTemplateColumns: `${gridStyle}`, ...styles };
93
+ if (hidden) return null;
94
+ return <div {...attrs}>{output}</div>;
95
+ }
96
+
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+ import {useWiseFormContext} from "../../context";
3
+ /**
4
+ *
5
+ * @param data {WrappedFormModel}
6
+ * @param model {FormModel} parent.
7
+ * @returns
8
+ */
9
+ export function FormSectionWrapper({data, model}) {
10
+ const {formTypes} = useWiseFormContext();
11
+
12
+ const types = {
13
+ ...formTypes,
14
+ };
15
+
16
+ if (!data.control) throw new Error("Wrapper must have a control");
17
+ if (!data.name) {
18
+ console.error("Wrapper must have a name", data);
19
+ return null;
20
+ }
21
+ if (data?.hidden) return null;
22
+
23
+ const wrapperModel = model?.getField(data.name);
24
+ const Control = types[data.control];
25
+ // data = wrapperModel ? { ...data, ...wrapperModel.getProperties() } : data;
26
+ return <Control model={wrapperModel} />;
27
+ }
28
+
@@ -0,0 +1,32 @@
1
+ import React from 'react';
2
+ import { WrappedWiseFormContext, useWiseFormContext } from '../context';
3
+ import { RowFieldContainer } from './rows/row-container';
4
+ import { useTemplate } from '../hooks/use-template';
5
+
6
+ export function WrappedForm({ children, name, types }): JSX.Element {
7
+ const { model: parent } = useWiseFormContext();
8
+ const wrapper = parent.wrappers.get(name);
9
+ const model = wrapper;
10
+ const template = useTemplate(model.settings);
11
+ const fields = [...model.settings.fields];
12
+ const Containers = template.items.map((num, index) => {
13
+ const items = fields.splice(0, num[0]);
14
+ return <RowFieldContainer template={num} model={model} items={items} key={`rf-row--${index}.${num}`} />;
15
+ });
16
+
17
+ const value = {
18
+ model,
19
+ name,
20
+ template,
21
+ formTypes: types ?? {},
22
+ parent,
23
+ };
24
+
25
+ return (
26
+ <WrappedWiseFormContext.Provider value={value}>
27
+ {Containers}
28
+ {children}
29
+ </WrappedWiseFormContext.Provider>
30
+ );
31
+ }
32
+
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import type { FormModel, WrappedFormModel } from '@bgroup/wise-form/models';
3
+ export interface IFormContext {
4
+ model?: FormModel | WrappedFormModel;
5
+ name?: string;
6
+ values?: Record<string, any>;
7
+ items?: any;
8
+ rows?: [number, string][];
9
+ template?: {
10
+ type: string;
11
+ styles: any;
12
+ items: any[];
13
+ };
14
+ formTypes?: Record<string, React.ElementType>;
15
+ }
16
+
17
+ export interface IWrappedFormContext extends IFormContext {
18
+ parent: IFormContext;
19
+ }
20
+ const value: IFormContext = {};
21
+ export const WiseFormContext = React.createContext(value);
22
+ export const useWiseFormContext = () => React.useContext(WiseFormContext);
23
+
24
+ export const WrappedWiseFormContext = React.createContext(value);
25
+ export const useWrappedWiseFormContext = () => React.useContext(WrappedWiseFormContext);
26
+
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { FormModel } from '@bgroup/wise-form/models';
3
+ import { useTemplate } from './use-template';
4
+
5
+ export function useModel(settings, form?: FormModel) {
6
+ const [model, setModel] = React.useState(form);
7
+ const [ready, setReady] = React.useState(false);
8
+ const [values, setValues] = React.useState(form?.values || {});
9
+ const templateSpecs = settings ? settings : form;
10
+ const { type, styles, items } = useTemplate(templateSpecs, templateSpecs.gap);
11
+ const startup = () => {
12
+ setReady(false);
13
+ const onChange = () => {
14
+ setReady(form.ready);
15
+ setValues({ ...form.values });
16
+ };
17
+
18
+ if (!form) {
19
+ const properties = settings.fields.map(item => item.name);
20
+ const values = settings.values || {};
21
+ form = new FormModel(settings, { properties, ...values });
22
+ }
23
+
24
+ setModel(form);
25
+ form.on('change', onChange);
26
+
27
+ onChange();
28
+
29
+ return () => {
30
+ form.off('change', onChange);
31
+ };
32
+ };
33
+
34
+ React.useEffect(startup, [form?.name]);
35
+
36
+ return { ready, model, values, type, styles, items };
37
+ }
@@ -0,0 +1,64 @@
1
+ import { IFormTemplate } from '../../interfaces/template';
2
+
3
+ /**
4
+ * Applies a template to create a structured layout, optionally using a gap between elements.
5
+ *
6
+ * @param template - The template to be applied. Can be an array or an object conforming to the IFormTemplate interface.
7
+ * @param gap - Specifies the gap between elements.
8
+ * The `gap` parameter is deprecated and will be removed in a future version. Use the gap property within the template object instead.
9
+ * @returns An object representing the structured layout with type, styles, and items.
10
+ */
11
+ export function useTemplate(settings, gap = undefined) {
12
+ if (!settings?.template) throw new Error(`${settings?.name} Doesn't have a template`);
13
+
14
+ let template = settings?.template;
15
+ let structure = template;
16
+ let styles = {};
17
+
18
+ if (!template) {
19
+ return {
20
+ type: 'grid',
21
+ styles: {},
22
+ items: settings.fields.map(item => [1, '1fr']),
23
+ };
24
+ }
25
+
26
+ if (gap) {
27
+ template = { structure: template, gap: gap } as IFormTemplate;
28
+ }
29
+ const isArray = Array.isArray(template);
30
+
31
+ if (!isArray) {
32
+ if (typeof template !== 'object' || !template.structure || !Array.isArray(template.structure)) {
33
+ throw new Error('Template must be an array or an object');
34
+ }
35
+ structure = template.structure;
36
+
37
+ styles = template.gap ? { gap: template.gap } : {};
38
+ }
39
+
40
+ const processString = str => {
41
+ if (typeof str === 'number') return [1, '1fr'];
42
+ const [num, times] = str.split('x').map(Number);
43
+
44
+ const tpl = times
45
+ ? [
46
+ times,
47
+ Array(times)
48
+ .fill(num)
49
+ .reduce((acc, v) => `${acc} 1fr`, ''),
50
+ ]
51
+ : [1, '1fr'];
52
+ return tpl;
53
+ };
54
+
55
+ return {
56
+ type: 'grid',
57
+ styles: styles,
58
+ items: structure.map(item => {
59
+ if (!Array.isArray(item)) return processString(item);
60
+ return item;
61
+ }),
62
+ };
63
+ }
64
+
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+ import { WFSettings } from '../../../settings';
3
+ import { SelectionField } from '../components/field/selection';
4
+ import { Input, Textarea } from '../../../components/ui';
5
+
6
+ export function useTypes(types) {
7
+ return React.useMemo(() => {
8
+ const defaultTypes = {
9
+ checkbox: SelectionField,
10
+ radio: SelectionField,
11
+ select: SelectionField,
12
+ textarea: Textarea,
13
+ text: Input,
14
+ password: Input,
15
+ default: Input,
16
+ };
17
+
18
+ return { ...defaultTypes, ...WFSettings.types, ...types };
19
+ }, [types]);
20
+ }
21
+
@@ -0,0 +1,48 @@
1
+ import React from 'react';
2
+ import { useModel } from './hooks/use-model';
3
+ import { WiseFormContext } from './context';
4
+ import { useTypes } from './hooks/use-types';
5
+
6
+ import { IWiseFormSpecs } from '../interfaces/wise-form-specs';
7
+ import { Containers } from './components/containers';
8
+
9
+ export function WiseForm({ children, settings, types, model }: IWiseFormSpecs): JSX.Element {
10
+ const { ready, model: instance, type, styles, items } = useModel(settings, model);
11
+ const formTypes = useTypes(types);
12
+
13
+ if (!ready) return null;
14
+
15
+ if (!settings && !model) {
16
+ console.error('the form does not have settings or model defined', settings);
17
+ }
18
+
19
+ const onSubmit = (event: React.FormEvent) => {
20
+ event.preventDefault();
21
+ // Form submission can be handled via callbacks or custom handlers
22
+ if (instance.callbacks?.onSubmit) {
23
+ instance.callbacks.onSubmit({ form: instance, event });
24
+ }
25
+ };
26
+
27
+ const value = {
28
+ model: instance,
29
+ items,
30
+ rows: items,
31
+ values: instance.values,
32
+ name: instance.name,
33
+ template: { type, styles, items },
34
+ formTypes,
35
+ };
36
+
37
+ return (
38
+ <WiseFormContext.Provider value={value}>
39
+ <form onKeyDown={(e) => {
40
+ if (e.key === 'Enter') e.preventDefault();
41
+ }} className="reactive-form-container" onSubmit={onSubmit}>
42
+ <Containers />
43
+ {children}
44
+ </form>
45
+ </WiseFormContext.Provider>
46
+ );
47
+ }
48
+
@@ -0,0 +1,5 @@
1
+ export const conditionsTypes = {
2
+ every: "validateAll",
3
+ some: "validateAny"
4
+ }
5
+
@@ -0,0 +1,48 @@
1
+ export class EvaluationsManager {
2
+ private static evaluations: Record<string, (value: any, comparisonValue?: any) => boolean> = {
3
+ equal: (value, comparisonValue) => value == comparisonValue,
4
+ lower: (value, comparisonValue) => Number(value) < Number(comparisonValue),
5
+ upper: (value, comparisonValue) => Number(value) > Number(comparisonValue),
6
+ between: (value, [min, max]) => {
7
+ const numValue = Number(value);
8
+ return numValue >= Number(min) && numValue <= Number(max);
9
+ },
10
+ different: (value, comparisonValue) => value != comparisonValue,
11
+ hasValue: value => ![undefined, null, '', false].includes(value),
12
+ empty: value => [undefined, null, '',].includes(value),
13
+ lessOrEqual: (value, comparisonValue) => Number(value) <= Number(comparisonValue),
14
+ greaterOrEqual: (value, comparisonValue) => Number(value) >= Number(comparisonValue),
15
+ };
16
+
17
+ static validate(identifier: string, value: any, comparisonValue?: any): boolean {
18
+ if (!this.evaluations[identifier]) {
19
+ throw new Error(`Evaluation identifier "${identifier}" not recognized.`);
20
+ }
21
+
22
+ const result = this.evaluations[identifier](value, comparisonValue);
23
+ return result;
24
+ }
25
+
26
+ /**
27
+ * Evalúa un arreglo de valores para ver si alguno cumple con la condición especificada.
28
+ * Retorna true si al menos uno de los valores cumple con la condición.
29
+ */
30
+ static validateAny(identifier: string, values: any[], comparisonValue?: any): boolean {
31
+ if (!this.evaluations[identifier]) {
32
+ throw new Error(`Evaluation identifier "${identifier}" not recognized.`);
33
+ }
34
+ return values.some(value => this.evaluations[identifier](value, comparisonValue));
35
+ }
36
+
37
+ /**
38
+ * Evalúa un arreglo de valores para ver si todos cumplen con la condición especificada.
39
+ * Retorna true solo si todos los valores cumplen con la condición.
40
+ */
41
+ static validateAll(identifier: string, values: any[], comparisonValue?: any): boolean {
42
+ if (!this.evaluations[identifier]) {
43
+ throw new Error(`Evaluation identifier "${identifier}" not recognized.`);
44
+ }
45
+ return values.every(value => this.evaluations[identifier](value, comparisonValue));
46
+ }
47
+ }
48
+
@@ -0,0 +1,27 @@
1
+ import { Lexer } from './lexer';
2
+ import { Parser } from './parser';
3
+ import { Token } from './token';
4
+
5
+ type ParserData = {
6
+ parser: Parser;
7
+ tokens: Token[];
8
+ [key: string]: any;
9
+ };
10
+
11
+ export class Formula {
12
+ #lexer = new Lexer();
13
+ #parsers: Map<string, ParserData> = new Map();
14
+ #tokens: Token[];
15
+ constructor(data) {
16
+ if (!data.formula) throw new Error('To get a parser you must provide a formula');
17
+ // if (this.#parsers.has(data.formula)) return this.#parsers.get(data.formula);
18
+ const tokens = this.#lexer.tokenize(data.formula);
19
+ const parser = new Parser(tokens);
20
+ const result = { tokens, parser, ...data };
21
+ this.#parsers.set(data.formula, result);
22
+ return result;
23
+ }
24
+
25
+ initialize() {}
26
+ }
27
+
@@ -0,0 +1,82 @@
1
+ import { Token } from './token';
2
+ import { TokenType } from '../types';
3
+
4
+ export class Lexer {
5
+ private tokenRegex: RegExp = /\s*(\(|\)|\+|\-|\*|\/|\d+\.\d+|\d+|[A-Za-z_][A-Za-z0-9_]*)\s*/g;
6
+ private flattenTokens: boolean;
7
+
8
+ constructor(flattenTokens: boolean = false) {
9
+ this.flattenTokens = flattenTokens;
10
+ }
11
+
12
+ tokenize(formula: string): Token[] {
13
+ this.tokenRegex.lastIndex = 0;
14
+ const tokens: Token[] = [];
15
+ const stack: Array<Token[]> = [tokens]; // Stack to manage nested token lists
16
+ let match: RegExpExecArray | null;
17
+
18
+ while ((match = this.tokenRegex.exec(formula)) !== null) {
19
+ const tokenValue = match[1];
20
+ let tokenType: TokenType = this.determineTokenType(tokenValue);
21
+
22
+ if (tokenType === 'parenthesis') {
23
+ if (tokenValue === '(') {
24
+ if (!this.flattenTokens) {
25
+ // Start a new scope for tokens
26
+ stack.push([]);
27
+ }
28
+ } else {
29
+ if (!this.flattenTokens) {
30
+ // End the current scope
31
+ const subTokens = stack.pop();
32
+ if (!subTokens) {
33
+ throw new Error('Mismatched parentheses in the formula');
34
+ }
35
+ // Create a parenthesis token with these subtokens as children
36
+ const parentTokens = stack[stack.length - 1];
37
+ parentTokens.push(new Token('parenthesis', '()', null, subTokens));
38
+ }
39
+ }
40
+ } else {
41
+ // Add this token to the current scope
42
+ stack[stack.length - 1].push(new Token(tokenType, tokenValue));
43
+ }
44
+ }
45
+
46
+ if (stack.length !== 1) {
47
+ throw new Error('Mismatched parentheses in the formula');
48
+ }
49
+
50
+ // If flattenTokens is true, flatten all tokens into a single array
51
+ if (this.flattenTokens) {
52
+ return this.flatten(tokens);
53
+ }
54
+
55
+ return tokens; // Return the outermost list of tokens
56
+ }
57
+
58
+ private determineTokenType(value: string): TokenType {
59
+ const operators = {
60
+ '+': 'operator',
61
+ '-': 'operator',
62
+ '*': 'operator',
63
+ '/': 'operator',
64
+ '(': 'parenthesis',
65
+ ')': 'parenthesis',
66
+ };
67
+ return operators[value] || (!isNaN(parseFloat(value)) ? 'number' : 'variable');
68
+ }
69
+
70
+ private flatten(tokens: Token[]): Token[] {
71
+ const flatList: Token[] = [];
72
+ for (const token of tokens) {
73
+ if (token.type === 'parenthesis' && token.children) {
74
+ flatList.push(...this.flatten(token.children)); // Flatten nested tokens
75
+ } else {
76
+ flatList.push(token);
77
+ }
78
+ }
79
+ return flatList;
80
+ }
81
+ }
82
+
@@ -0,0 +1,55 @@
1
+ import { Token } from './token';
2
+
3
+ type TokenType = 'variable' | 'number' | 'operator';
4
+
5
+ /**
6
+ * The Parser class is responsible for parsing a sequence of tokens into an abstract syntax tree (AST).
7
+ * The tokens should be an array of objects with `type` and `value` properties.
8
+ *
9
+ * The Parser handles mathematical expressions and ensures that the tokens are in the correct order
10
+ * for later evaluation. It understands variables, numbers, and parentheses, and is extendable to support
11
+ * additional operations and precedence rules.
12
+ *
13
+ * Example usage:
14
+ * ```
15
+ * const tokens: Token[] = [...];
16
+ * const parser = new Parser(tokens);
17
+ * const ast = parser.parse();
18
+ * ```
19
+ */
20
+ export class Parser {
21
+ private tokens: Token[];
22
+ private currentTokenIndex: number;
23
+
24
+ constructor(tokens: Token[]) {
25
+ this.tokens = tokens;
26
+ this.currentTokenIndex = 0;
27
+ }
28
+
29
+ public parse(): Token | undefined {
30
+ return this.parseExpression();
31
+ }
32
+
33
+ private parseExpression(): Token | undefined {
34
+ let token = this.tokens[this.currentTokenIndex];
35
+ if (token && token.type === 'variable') {
36
+ this.currentTokenIndex++;
37
+ return token;
38
+ } else if (token && token.type === 'number') {
39
+ this.currentTokenIndex++;
40
+ return token;
41
+ } else if (token && token.value === '(') {
42
+ this.currentTokenIndex++; // Skip '('
43
+ let expr = this.parseExpression(); // Parse subexpression
44
+ if (this.tokens[this.currentTokenIndex] && this.tokens[this.currentTokenIndex].value === ')') {
45
+ this.currentTokenIndex++; // Skip ')'
46
+ return expr;
47
+ }
48
+ }
49
+ // TODO: Add cases for parsing different operations (like addition, multiplication etc.)
50
+ // TODO: Implement precedence handling for different operations
51
+ // This function should be extended to fully construct the AST.
52
+ return undefined;
53
+ }
54
+ }
55
+
@@ -0,0 +1,22 @@
1
+ import { TokenType } from '../types';
2
+
3
+ /**
4
+ * The Token class now includes a stringValue property for storing the original string value
5
+ * of the expression inside the parentheses and an optional parent property for storing the parent token.
6
+ */
7
+ export class Token {
8
+ type: TokenType;
9
+ value: string;
10
+ stringValue?: string;
11
+ children?: Token[];
12
+ parent?: Token;
13
+
14
+ constructor(type: TokenType, value: string, stringValue?: string, children?: Token[], parent?: Token) {
15
+ this.type = type;
16
+ this.value = value;
17
+ this.stringValue = stringValue;
18
+ this.children = children;
19
+ this.parent = parent;
20
+ }
21
+ }
22
+