@digigov/form 2.0.0-555d1027 → 2.0.0-5701c39b

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 (433) hide show
  1. package/Field/ErrorGroup.d.ts +3 -3
  2. package/Field/ErrorGroup.js.map +1 -1
  3. package/Field/FieldBase/index.js +2 -1
  4. package/Field/FieldBase.d.ts +1 -1
  5. package/Field/FieldBase.js.map +2 -2
  6. package/Field/FieldBaseContainer/index.js +36 -34
  7. package/Field/FieldBaseContainer.d.ts +2 -2
  8. package/Field/FieldBaseContainer.js.map +2 -2
  9. package/Field/FieldConditional.d.ts +1 -1
  10. package/Field/FieldConditional.js.map +1 -1
  11. package/Field/index.d.ts +1 -1
  12. package/Field/index.js +16 -26
  13. package/Field/index.js.map +2 -2
  14. package/Field/types.d.ts +11 -10
  15. package/Field/utils/evaluateFieldWithConditions.d.ts +2 -2
  16. package/Field/utils/evaluateFieldWithConditions.js.map +2 -2
  17. package/Field/utils/resolveField/index.js +35 -0
  18. package/Field/utils/{calculateField → resolveField}/package.json +1 -1
  19. package/Field/utils/resolveField.d.ts +3 -0
  20. package/Field/utils/resolveField.js.map +7 -0
  21. package/Field/utils/useField/index.js +4 -2
  22. package/Field/utils/useField.d.ts +1 -1
  23. package/Field/utils/useField.js.map +2 -2
  24. package/FieldArray/BaseFieldArray/index.js +76 -0
  25. package/{inputs/inputsScenarios → FieldArray/BaseFieldArray}/package.json +1 -1
  26. package/FieldArray/BaseFieldArray.d.ts +5 -0
  27. package/FieldArray/BaseFieldArray.js.map +7 -0
  28. package/FieldArray/FieldArray.stories.d.ts +1 -0
  29. package/FieldArray/FormDialog/ArrayDisplay/ArrayContainerDisplay/index.js +23 -0
  30. package/FieldArray/FormDialog/ArrayDisplay/ArrayContainerDisplay/package.json +6 -0
  31. package/FieldArray/FormDialog/ArrayDisplay/ArrayContainerDisplay.d.ts +9 -0
  32. package/FieldArray/FormDialog/ArrayDisplay/ArrayContainerDisplay.js.map +7 -0
  33. package/FieldArray/FormDialog/ArrayDisplay/ArrayDisplay.stories.d.ts +13 -0
  34. package/FieldArray/FormDialog/ArrayDisplay/ArrayItemDisplay/index.js +184 -0
  35. package/FieldArray/FormDialog/ArrayDisplay/ArrayItemDisplay/package.json +6 -0
  36. package/FieldArray/FormDialog/ArrayDisplay/ArrayItemDisplay.d.ts +26 -0
  37. package/FieldArray/FormDialog/ArrayDisplay/ArrayItemDisplay.js.map +7 -0
  38. package/FieldArray/FormDialog/ArrayDisplay/ArrayItemHeader/index.js +11 -0
  39. package/FieldArray/FormDialog/ArrayDisplay/ArrayItemHeader/package.json +6 -0
  40. package/FieldArray/FormDialog/ArrayDisplay/ArrayItemHeader.d.ts +5 -0
  41. package/FieldArray/FormDialog/ArrayDisplay/ArrayItemHeader.js.map +7 -0
  42. package/FieldArray/FormDialog/ArrayDisplay/__stories__/Cards.d.ts +2 -0
  43. package/FieldArray/FormDialog/ArrayDisplay/__stories__/Default.d.ts +2 -0
  44. package/FieldArray/FormDialog/ArrayDisplay/__stories__/ReadOnly.d.ts +2 -0
  45. package/FieldArray/FormDialog/ArrayDisplay/__stories__/ReadOnlyCards.d.ts +2 -0
  46. package/FieldArray/FormDialog/ArrayDisplay/__stories__/Sortable.d.ts +2 -0
  47. package/FieldArray/FormDialog/ArrayDisplay/__stories__/SortableCards.d.ts +2 -0
  48. package/FieldArray/FormDialog/ArrayDisplay/index.d.ts +15 -0
  49. package/FieldArray/FormDialog/ArrayDisplay/index.js +57 -0
  50. package/FieldArray/FormDialog/ArrayDisplay/index.js.map +7 -0
  51. package/FieldArray/FormDialog/ArrayDisplay/package.json +6 -0
  52. package/FieldArray/FormDialog/ArrayEditModal/index.js +158 -0
  53. package/FieldArray/FormDialog/ArrayEditModal/package.json +6 -0
  54. package/FieldArray/FormDialog/ArrayEditModal.d.ts +24 -0
  55. package/FieldArray/FormDialog/ArrayEditModal.js.map +7 -0
  56. package/FieldArray/FormDialog/index.d.ts +19 -0
  57. package/FieldArray/FormDialog/index.js +183 -348
  58. package/FieldArray/FormDialog/index.js.map +7 -0
  59. package/FieldArray/__stories__/CardsWithError.d.ts +15 -0
  60. package/FieldArray/index.d.ts +4 -2
  61. package/FieldArray/index.js +34 -56
  62. package/FieldArray/index.js.map +2 -2
  63. package/FieldObject/index.d.ts +4 -4
  64. package/FieldObject/index.js +5 -12
  65. package/FieldObject/index.js.map +2 -2
  66. package/Fieldset/FieldsetWithContext.js.map +1 -1
  67. package/Fieldset/index.d.ts +1 -1
  68. package/Fieldset/index.js.map +1 -1
  69. package/Fieldset/types.d.ts +2 -2
  70. package/FormBuilder/index.d.ts +1 -1
  71. package/FormBuilder/index.js +158 -132
  72. package/FormBuilder/index.js.map +2 -2
  73. package/FormContext.d.ts +2 -2
  74. package/FormContext.js.map +2 -2
  75. package/MultiplicityField/add-objects/index.js +10 -19
  76. package/MultiplicityField/add-objects.d.ts +1 -1
  77. package/MultiplicityField/add-objects.js.map +2 -2
  78. package/MultiplicityField/index.d.ts +2 -2
  79. package/MultiplicityField/index.js.map +2 -2
  80. package/MultiplicityField/types.d.ts +2 -2
  81. package/Questions/Questions.d.ts +1 -1
  82. package/Questions/Questions.js.map +1 -1
  83. package/Questions/QuestionsContext.d.ts +1 -1
  84. package/Questions/QuestionsContext.js.map +1 -1
  85. package/Questions/Step/Step.d.ts +1 -1
  86. package/Questions/Step/Step.js.map +1 -1
  87. package/Questions/Step/StepArrayReview.d.ts +1 -1
  88. package/Questions/Step/StepArrayReview.js.map +1 -1
  89. package/Questions/Step/StepContext.d.ts +1 -1
  90. package/Questions/Step/StepContext.js.map +1 -1
  91. package/Questions/Step/StepDescription.d.ts +1 -1
  92. package/Questions/Step/StepDescription.js.map +2 -2
  93. package/Questions/Step/StepForm.d.ts +2 -2
  94. package/Questions/Step/StepForm.js.map +1 -1
  95. package/Questions/Step/StepQuote.d.ts +1 -1
  96. package/Questions/Step/StepQuote.js.map +2 -2
  97. package/Questions/Step/StepTitle.d.ts +1 -1
  98. package/Questions/Step/StepTitle.js.map +2 -2
  99. package/Questions/Step/getAddMoreFields.d.ts +2 -2
  100. package/Questions/Step/getAddMoreFields.js.map +1 -1
  101. package/Questions/Step/types.d.ts +1 -1
  102. package/Questions/getNextStep.d.ts +1 -1
  103. package/Questions/getNextStep.js.map +1 -1
  104. package/Questions/types.d.ts +1 -1
  105. package/cjs/Field/ErrorGroup.js.map +1 -1
  106. package/cjs/Field/FieldBase/index.js +2 -1
  107. package/cjs/Field/FieldBase.js.map +2 -2
  108. package/cjs/Field/FieldBaseContainer/index.js +36 -34
  109. package/cjs/Field/FieldBaseContainer.js.map +2 -2
  110. package/cjs/Field/FieldConditional.js.map +1 -1
  111. package/cjs/Field/index.js +16 -23
  112. package/cjs/Field/index.js.map +2 -2
  113. package/cjs/Field/types.js.map +1 -1
  114. package/cjs/Field/utils/evaluateFieldWithConditions.js.map +2 -2
  115. package/cjs/Field/utils/resolveField/index.js +55 -0
  116. package/cjs/Field/utils/resolveField.js.map +7 -0
  117. package/cjs/Field/utils/useField/index.js +4 -2
  118. package/cjs/Field/utils/useField.js.map +2 -2
  119. package/cjs/FieldArray/BaseFieldArray/index.js +109 -0
  120. package/cjs/FieldArray/BaseFieldArray.js.map +7 -0
  121. package/cjs/FieldArray/FormDialog/ArrayDisplay/ArrayContainerDisplay/index.js +56 -0
  122. package/cjs/FieldArray/FormDialog/ArrayDisplay/ArrayContainerDisplay.js.map +7 -0
  123. package/cjs/FieldArray/FormDialog/ArrayDisplay/ArrayItemDisplay/index.js +209 -0
  124. package/cjs/FieldArray/FormDialog/ArrayDisplay/ArrayItemDisplay.js.map +7 -0
  125. package/cjs/{locales/el → FieldArray/FormDialog/ArrayDisplay/ArrayItemHeader}/index.js +16 -7
  126. package/cjs/FieldArray/FormDialog/ArrayDisplay/ArrayItemHeader.js.map +7 -0
  127. package/cjs/FieldArray/FormDialog/ArrayDisplay/index.js +90 -0
  128. package/cjs/FieldArray/FormDialog/ArrayDisplay/index.js.map +7 -0
  129. package/cjs/FieldArray/FormDialog/ArrayEditModal/index.js +186 -0
  130. package/cjs/FieldArray/FormDialog/ArrayEditModal.js.map +7 -0
  131. package/cjs/FieldArray/FormDialog/index.js +174 -331
  132. package/cjs/FieldArray/FormDialog/index.js.map +7 -0
  133. package/cjs/FieldArray/index.js +33 -55
  134. package/cjs/FieldArray/index.js.map +3 -3
  135. package/cjs/FieldObject/index.js +5 -9
  136. package/cjs/FieldObject/index.js.map +2 -2
  137. package/cjs/Fieldset/FieldsetWithContext.js.map +1 -1
  138. package/cjs/Fieldset/index.js.map +1 -1
  139. package/cjs/Fieldset/types.js.map +1 -1
  140. package/cjs/FormBuilder/index.js +159 -133
  141. package/cjs/FormBuilder/index.js.map +3 -3
  142. package/cjs/FormContext.js.map +2 -2
  143. package/cjs/MultiplicityField/add-objects/index.js +9 -13
  144. package/cjs/MultiplicityField/add-objects.js.map +2 -2
  145. package/cjs/MultiplicityField/index.js.map +2 -2
  146. package/cjs/MultiplicityField/types.js.map +1 -1
  147. package/cjs/Questions/Questions.js.map +1 -1
  148. package/cjs/Questions/QuestionsContext.js.map +1 -1
  149. package/cjs/Questions/Step/Step.js.map +1 -1
  150. package/cjs/Questions/Step/StepArrayReview.js.map +1 -1
  151. package/cjs/Questions/Step/StepContext.js.map +1 -1
  152. package/cjs/Questions/Step/StepDescription.js.map +2 -2
  153. package/cjs/Questions/Step/StepForm.js.map +1 -1
  154. package/cjs/Questions/Step/StepQuote.js.map +2 -2
  155. package/cjs/Questions/Step/StepTitle.js.map +2 -2
  156. package/cjs/Questions/Step/getAddMoreFields.js.map +1 -1
  157. package/cjs/Questions/Step/types.js.map +1 -1
  158. package/cjs/Questions/getNextStep.js.map +1 -1
  159. package/cjs/Questions/types.js.map +1 -1
  160. package/cjs/hooks/useFieldFocusManager/index.js +135 -0
  161. package/cjs/hooks/useFieldFocusManager.js.map +7 -0
  162. package/cjs/hooks/utils/index.js +98 -0
  163. package/cjs/hooks/utils.js.map +7 -0
  164. package/cjs/inputs/AutoCompleteInput/index.js.map +2 -2
  165. package/cjs/inputs/Checkboxes/index.js +68 -63
  166. package/cjs/inputs/Checkboxes/index.js.map +2 -2
  167. package/cjs/inputs/DateInput/index.js +10 -5
  168. package/cjs/inputs/DateInput/index.js.map +2 -2
  169. package/cjs/inputs/DateTimeInput/index.js +10 -5
  170. package/cjs/inputs/DateTimeInput/index.js.map +2 -2
  171. package/cjs/inputs/FileInput/index.js +6 -14
  172. package/cjs/inputs/FileInput/index.js.map +2 -2
  173. package/cjs/inputs/ImageInput/index.js +4 -4
  174. package/cjs/inputs/ImageInput/index.js.map +2 -2
  175. package/cjs/inputs/Input/index.js +5 -4
  176. package/cjs/inputs/Input/index.js.map +2 -2
  177. package/cjs/inputs/Label/index.js.map +1 -1
  178. package/cjs/inputs/OtpInput/index.js +36 -31
  179. package/cjs/inputs/OtpInput/index.js.map +2 -2
  180. package/cjs/inputs/Radio/index.js +7 -5
  181. package/cjs/inputs/Radio/index.js.map +3 -3
  182. package/cjs/inputs/Select/index.js +2 -2
  183. package/cjs/inputs/Select/index.js.map +2 -2
  184. package/cjs/{Field/utils → inputs/registry}/index.js +4 -4
  185. package/cjs/inputs/registry.js.map +7 -0
  186. package/cjs/lazy/index.js +12 -9
  187. package/cjs/lazy.js.map +2 -2
  188. package/cjs/registry/index.js +25 -11
  189. package/cjs/registry.js.map +2 -2
  190. package/cjs/types.js.map +1 -1
  191. package/cjs/utils/index.js +9 -0
  192. package/cjs/utils.js.map +2 -2
  193. package/cjs/validators/index.js +5 -2
  194. package/cjs/validators/index.js.map +2 -2
  195. package/cjs/validators/types.js.map +1 -1
  196. package/cjs/validators/utils/date/index.js +6 -1
  197. package/cjs/validators/utils/date.js.map +2 -2
  198. package/cjs/validators/utils/datetime/index.js +6 -1
  199. package/cjs/validators/utils/datetime.js.map +2 -2
  200. package/cjs/validators/utils/email/index.js +39 -0
  201. package/cjs/validators/utils/email.js.map +7 -0
  202. package/cjs/validators/utils/file.js.map +1 -1
  203. package/cjs/validators/utils/iban.js.map +1 -1
  204. package/cjs/validators/utils/image.js.map +1 -1
  205. package/cjs/validators/utils/index.js.map +1 -1
  206. package/cjs/validators/utils/int.js.map +1 -1
  207. package/cjs/validators/utils/number.js.map +1 -1
  208. package/cjs/validators/utils/otp.js.map +1 -1
  209. package/cjs/validators/utils/phone.js.map +1 -1
  210. package/cjs/validators/utils/postal_code.js.map +1 -1
  211. package/cjs/validators/utils/text_limit.js.map +1 -1
  212. package/hooks/useFieldFocusManager/index.js +116 -0
  213. package/hooks/useFieldFocusManager/package.json +6 -0
  214. package/hooks/useFieldFocusManager.d.ts +25 -0
  215. package/hooks/useFieldFocusManager.js.map +7 -0
  216. package/hooks/utils/index.js +73 -0
  217. package/{Field → hooks}/utils/package.json +1 -1
  218. package/hooks/utils.d.ts +18 -0
  219. package/hooks/utils.js.map +7 -0
  220. package/index.js +1 -1
  221. package/inputs/AutoCompleteInput/index.d.ts +3 -3
  222. package/inputs/AutoCompleteInput/index.js +1 -3
  223. package/inputs/AutoCompleteInput/index.js.map +2 -2
  224. package/inputs/Checkboxes/index.d.ts +5 -3
  225. package/inputs/Checkboxes/index.js +68 -63
  226. package/inputs/Checkboxes/index.js.map +2 -2
  227. package/inputs/DateInput/index.d.ts +2 -5
  228. package/inputs/DateInput/index.js +10 -5
  229. package/inputs/DateInput/index.js.map +2 -2
  230. package/inputs/DateTimeInput/index.d.ts +2 -5
  231. package/inputs/DateTimeInput/index.js +10 -5
  232. package/inputs/DateTimeInput/index.js.map +2 -2
  233. package/inputs/FileInput/index.d.ts +4 -4
  234. package/inputs/FileInput/index.js +7 -18
  235. package/inputs/FileInput/index.js.map +2 -2
  236. package/inputs/ImageInput/index.d.ts +2 -2
  237. package/inputs/ImageInput/index.js +4 -4
  238. package/inputs/ImageInput/index.js.map +2 -2
  239. package/inputs/Input/index.d.ts +3 -1
  240. package/inputs/Input/index.js +5 -4
  241. package/inputs/Input/index.js.map +2 -2
  242. package/inputs/Label/index.d.ts +1 -1
  243. package/inputs/Label/index.js.map +1 -1
  244. package/inputs/OtpInput/index.d.ts +1 -5
  245. package/inputs/OtpInput/index.js +36 -31
  246. package/inputs/OtpInput/index.js.map +2 -2
  247. package/inputs/Radio/index.d.ts +6 -4
  248. package/inputs/Radio/index.js +7 -5
  249. package/inputs/Radio/index.js.map +3 -3
  250. package/inputs/Select/index.d.ts +4 -2
  251. package/inputs/Select/index.js +2 -2
  252. package/inputs/Select/index.js.map +2 -2
  253. package/{Field/utils → inputs/registry}/index.js +1 -1
  254. package/{locales/el → inputs/registry}/package.json +1 -1
  255. package/{Field/utils/index.d.ts → inputs/registry.d.ts} +2 -1
  256. package/inputs/registry.js.map +7 -0
  257. package/lazy/index.js +12 -9
  258. package/package.json +4 -4
  259. package/registry/index.js +25 -11
  260. package/src/Field/ErrorGroup.tsx +3 -3
  261. package/src/Field/FieldBase.tsx +3 -2
  262. package/src/Field/FieldBaseContainer.tsx +68 -58
  263. package/src/Field/FieldConditional.tsx +1 -1
  264. package/src/Field/index.tsx +16 -36
  265. package/src/Field/types.tsx +11 -12
  266. package/src/Field/utils/evaluateFieldWithConditions.ts +5 -2
  267. package/src/Field/utils/resolveField.ts +58 -0
  268. package/src/Field/utils/useField.ts +3 -1
  269. package/src/FieldArray/BaseFieldArray.tsx +97 -0
  270. package/src/FieldArray/FieldArray.stories.js +1 -0
  271. package/src/FieldArray/FormDialog/ArrayDisplay/ArrayContainerDisplay.tsx +45 -0
  272. package/src/FieldArray/FormDialog/ArrayDisplay/ArrayDisplay.stories.js +14 -0
  273. package/src/FieldArray/FormDialog/ArrayDisplay/ArrayItemDisplay.tsx +337 -0
  274. package/src/FieldArray/FormDialog/ArrayDisplay/ArrayItemHeader.tsx +15 -0
  275. package/src/FieldArray/FormDialog/ArrayDisplay/__stories__/Cards.tsx +88 -0
  276. package/src/FieldArray/FormDialog/ArrayDisplay/__stories__/Default.tsx +93 -0
  277. package/src/FieldArray/FormDialog/ArrayDisplay/__stories__/ReadOnly.tsx +79 -0
  278. package/src/FieldArray/FormDialog/ArrayDisplay/__stories__/ReadOnlyCards.tsx +75 -0
  279. package/src/FieldArray/FormDialog/ArrayDisplay/__stories__/Sortable.tsx +93 -0
  280. package/src/FieldArray/FormDialog/ArrayDisplay/__stories__/SortableCards.tsx +88 -0
  281. package/src/FieldArray/FormDialog/ArrayDisplay/index.test.tsx +44 -0
  282. package/src/FieldArray/FormDialog/ArrayDisplay/index.tsx +67 -0
  283. package/src/FieldArray/FormDialog/ArrayEditModal.tsx +241 -0
  284. package/src/FieldArray/FormDialog/index.tsx +302 -0
  285. package/src/FieldArray/__stories__/CardsWithError.tsx +124 -0
  286. package/src/FieldArray/__tests__/fieldset-multiplicity.spec.tsx +271 -0
  287. package/src/FieldArray/__tests__/multiplicity-attachment.spec.tsx +280 -0
  288. package/src/FieldArray/__tests__/multiplicity-optional.spec.tsx +232 -0
  289. package/src/FieldArray/__tests__/multiplicity-required.spec.tsx +170 -0
  290. package/src/FieldArray/__tests__/nested-fieldset-multiplicity.spec.tsx +627 -0
  291. package/src/FieldArray/__tests__/preference-multiple-choice.spec.tsx +222 -0
  292. package/src/FieldArray/index.spec.tsx +355 -0
  293. package/src/FieldArray/index.test.tsx +4 -0
  294. package/src/FieldArray/index.tsx +43 -63
  295. package/src/FieldObject/index.tsx +9 -17
  296. package/src/Fieldset/FieldsetWithContext.tsx +1 -1
  297. package/src/Fieldset/index.tsx +1 -1
  298. package/src/Fieldset/types.tsx +2 -2
  299. package/src/FormBuilder/index.tsx +190 -144
  300. package/src/FormBuilder/scenarios.test.tsx +760 -1
  301. package/src/FormContext.tsx +3 -2
  302. package/src/MultiplicityField/__stories__/PreviewDisplay.tsx +1 -3
  303. package/src/MultiplicityField/add-objects.tsx +12 -21
  304. package/src/MultiplicityField/index.tsx +3 -2
  305. package/src/MultiplicityField/types.ts +5 -2
  306. package/src/Questions/Questions.tsx +2 -2
  307. package/src/Questions/QuestionsContext.tsx +1 -1
  308. package/src/Questions/Step/Step.tsx +1 -1
  309. package/src/Questions/Step/StepArrayReview.tsx +2 -2
  310. package/src/Questions/Step/StepContext.tsx +1 -1
  311. package/src/Questions/Step/StepDescription.tsx +2 -1
  312. package/src/Questions/Step/StepForm.tsx +2 -2
  313. package/src/Questions/Step/StepQuote.tsx +2 -1
  314. package/src/Questions/Step/StepTitle.tsx +2 -1
  315. package/src/Questions/Step/getAddMoreFields.tsx +2 -2
  316. package/src/Questions/Step/types.tsx +1 -1
  317. package/src/Questions/getNextStep.tsx +1 -1
  318. package/src/Questions/types.tsx +1 -1
  319. package/src/hooks/__tests__/useFieldFocusManager.spec.tsx +1079 -0
  320. package/src/hooks/__tests__/utils.spec.ts +568 -0
  321. package/src/hooks/useFieldFocusManager.ts +162 -0
  322. package/src/hooks/utils.ts +122 -0
  323. package/src/inputs/AutoCompleteInput/index.tsx +4 -6
  324. package/src/inputs/Checkboxes/index.tsx +98 -87
  325. package/src/inputs/DateInput/index.tsx +19 -6
  326. package/src/inputs/DateTimeInput/index.tsx +19 -6
  327. package/src/inputs/FileInput/index.tsx +15 -21
  328. package/src/inputs/ImageInput/index.tsx +6 -6
  329. package/src/inputs/Input/index.tsx +12 -8
  330. package/src/inputs/Label/index.tsx +1 -1
  331. package/src/inputs/OtpInput/index.tsx +43 -34
  332. package/src/inputs/Radio/index.tsx +33 -22
  333. package/src/inputs/Select/index.tsx +6 -4
  334. package/src/{Field/utils/index.ts → inputs/registry.ts} +3 -1
  335. package/src/lazy.js +12 -9
  336. package/src/registry.js +25 -11
  337. package/src/types.tsx +13 -5
  338. package/src/utils.ts +14 -2
  339. package/src/validators/index.ts +15 -11
  340. package/src/validators/types.ts +1 -1
  341. package/src/validators/utils/date.ts +8 -3
  342. package/src/validators/utils/datetime.ts +8 -3
  343. package/src/validators/utils/email.ts +11 -0
  344. package/src/validators/utils/file.ts +2 -2
  345. package/src/validators/utils/iban.ts +2 -2
  346. package/src/validators/utils/image.ts +2 -2
  347. package/src/validators/utils/index.ts +2 -2
  348. package/src/validators/utils/int.ts +1 -1
  349. package/src/validators/utils/number.ts +1 -1
  350. package/src/validators/utils/otp.ts +2 -2
  351. package/src/validators/utils/phone.ts +2 -2
  352. package/src/validators/utils/postal_code.ts +2 -2
  353. package/src/validators/utils/text_limit.ts +2 -2
  354. package/types.d.ts +9 -4
  355. package/types.js.map +1 -1
  356. package/utils/index.js +8 -0
  357. package/utils.d.ts +2 -1
  358. package/utils.js.map +2 -2
  359. package/validators/index.d.ts +5 -5
  360. package/validators/index.js +5 -2
  361. package/validators/index.js.map +2 -2
  362. package/validators/types.d.ts +1 -1
  363. package/validators/utils/date/index.js +6 -1
  364. package/validators/utils/date.d.ts +2 -2
  365. package/validators/utils/date.js.map +2 -2
  366. package/validators/utils/datetime/index.js +6 -1
  367. package/validators/utils/datetime.d.ts +2 -2
  368. package/validators/utils/datetime.js.map +2 -2
  369. package/validators/utils/email/index.js +16 -0
  370. package/validators/utils/email/package.json +6 -0
  371. package/validators/utils/email.d.ts +5 -0
  372. package/validators/utils/email.js.map +7 -0
  373. package/validators/utils/file.d.ts +2 -2
  374. package/validators/utils/file.js.map +1 -1
  375. package/validators/utils/iban.d.ts +2 -2
  376. package/validators/utils/iban.js.map +1 -1
  377. package/validators/utils/image.d.ts +2 -2
  378. package/validators/utils/image.js.map +1 -1
  379. package/validators/utils/index.d.ts +2 -2
  380. package/validators/utils/index.js.map +1 -1
  381. package/validators/utils/int.d.ts +1 -1
  382. package/validators/utils/int.js.map +1 -1
  383. package/validators/utils/number.d.ts +1 -1
  384. package/validators/utils/number.js.map +1 -1
  385. package/validators/utils/otp.d.ts +2 -2
  386. package/validators/utils/otp.js.map +1 -1
  387. package/validators/utils/phone.d.ts +2 -2
  388. package/validators/utils/phone.js.map +1 -1
  389. package/validators/utils/postal_code.d.ts +2 -2
  390. package/validators/utils/postal_code.js.map +1 -1
  391. package/validators/utils/text_limit.d.ts +2 -2
  392. package/validators/utils/text_limit.js.map +1 -1
  393. package/Field/utils/calculateField/index.js +0 -27
  394. package/Field/utils/calculateField.d.ts +0 -2
  395. package/Field/utils/calculateField.js.map +0 -7
  396. package/Field/utils/index.js.map +0 -7
  397. package/FieldArray/FormDialog.d.ts +0 -67
  398. package/FieldArray/FormDialog.js.map +0 -7
  399. package/FormBuilder/index.test.d.ts +0 -1
  400. package/FormBuilder/interaction.test.d.ts +0 -1
  401. package/FormBuilder/scenarios.test.d.ts +0 -88
  402. package/MultiplicityField/index.test.d.ts +0 -1
  403. package/Questions/index.spec.d.ts +0 -1
  404. package/Questions/index.test.d.ts +0 -1
  405. package/cjs/Field/utils/calculateField/index.js +0 -50
  406. package/cjs/Field/utils/calculateField.js.map +0 -7
  407. package/cjs/Field/utils/index.js.map +0 -7
  408. package/cjs/FieldArray/FormDialog.js.map +0 -7
  409. package/cjs/inputs/inputsScenarios/index.js +0 -533
  410. package/cjs/inputs/inputsScenarios.js.map +0 -7
  411. package/cjs/locales/el.js.map +0 -7
  412. package/inputs/AutoCompleteInput/index.test.d.ts +0 -1
  413. package/inputs/Checkboxes/index.test.d.ts +0 -1
  414. package/inputs/DateInput/index.test.d.ts +0 -1
  415. package/inputs/DateTimeInput/index.test.d.ts +0 -1
  416. package/inputs/FileInput/index.test.d.ts +0 -1
  417. package/inputs/ImageInput/index.test.d.ts +0 -1
  418. package/inputs/Input/index.test.d.ts +0 -1
  419. package/inputs/Label/index.test.d.ts +0 -1
  420. package/inputs/OtpInput/index.test.d.ts +0 -1
  421. package/inputs/Radio/index.test.d.ts +0 -1
  422. package/inputs/Select/index.test.d.ts +0 -1
  423. package/inputs/inputsScenarios/index.js +0 -499
  424. package/inputs/inputsScenarios.d.ts +0 -296
  425. package/inputs/inputsScenarios.js.map +0 -7
  426. package/locales/el/index.js +0 -6
  427. package/locales/el.d.ts +0 -2
  428. package/locales/el.js.map +0 -7
  429. package/src/Field/utils/calculateField.ts +0 -49
  430. package/src/FieldArray/FormDialog.tsx +0 -568
  431. package/src/inputs/inputsScenarios.ts +0 -496
  432. package/src/locales/el.ts +0 -3
  433. /package/{FieldArray/index.test.d.ts → hooks/__tests__/utils.spec.d.ts} +0 -0
@@ -0,0 +1,280 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
3
+ import user from '@testing-library/user-event';
4
+ import type { FieldSpec } from '@digigov/form';
5
+ import FormBuilder, { Field } from '@digigov/form';
6
+ import { Button } from '@digigov/ui/form/Button';
7
+
8
+ beforeAll(() => {
9
+ global.ResizeObserver = class ResizeObserver {
10
+ observe() {
11
+ // do nothing
12
+ }
13
+ unobserve() {
14
+ // do nothing
15
+ }
16
+ disconnect() {
17
+ // do nothing
18
+ }
19
+ };
20
+ });
21
+
22
+ const fieldSpec: FieldSpec = {
23
+ key: 'attachment_multiplicity',
24
+ type: 'array',
25
+ editable: true,
26
+ required: false,
27
+ label: {
28
+ primary: 'attachment multiplicity',
29
+ secondary: 'Ο χρήστης μπορεί να προσθέσει τιμές (σύνολο από 1 έως 10)',
30
+ },
31
+ extra: {
32
+ border: false,
33
+ editVariant: 'optional',
34
+ label: {
35
+ object: {
36
+ add: 'Προσθήκη',
37
+ addButtonVariant: 'link',
38
+ append: {
39
+ label: 'Αποθήκευση',
40
+ },
41
+ cancel: {
42
+ label: 'Ακύρωση',
43
+ },
44
+ delete: 'Αφαίρεση',
45
+ deleteButtonVariant: 'link',
46
+ edit: {
47
+ label: 'Αποθήκευση',
48
+ },
49
+ nothing_added: 'Δεν έχουν προστεθεί στοιχεία',
50
+ nothing_added_props: {
51
+ margin: 0,
52
+ paddingLeft: 2,
53
+ style: {
54
+ color: 'var(--color-gray-600)',
55
+ },
56
+ },
57
+ },
58
+ },
59
+ limit: {
60
+ maxSize: 5242880,
61
+ },
62
+ max: 10,
63
+ min: 0,
64
+ noHeader: true,
65
+ noIndex: true,
66
+ of: {
67
+ editable: true,
68
+ name: undefined,
69
+ key: undefined,
70
+ label: {},
71
+ type: 'file',
72
+ extra: {
73
+ containerProps: {
74
+ variant: 'border',
75
+ },
76
+ limit: {
77
+ maxSize: 5242880,
78
+ },
79
+ noResetButton: true,
80
+ resetButtonProps: {
81
+ color: 'warning',
82
+ },
83
+ uploadButtonProps: {
84
+ variant: 'link',
85
+ },
86
+ },
87
+ },
88
+ stackProps: {
89
+ direction: 'row',
90
+ justifyContent: 'flex-end',
91
+ spacing: 2,
92
+ },
93
+ tableContainer: {
94
+ mb: 0,
95
+ },
96
+ variant: 'dialog',
97
+ },
98
+ };
99
+
100
+ describe('multiplicity_attachment case from dilosi', () => {
101
+ const submitHandler = vi.fn();
102
+
103
+ const TestForm = () => (
104
+ <FormBuilder onSubmit={submitHandler}>
105
+ <Field name="multiplicity_attachment" {...fieldSpec} />
106
+ <Button type="submit">Συνέχεια</Button>
107
+ </FormBuilder>
108
+ );
109
+
110
+ beforeEach(() => {
111
+ submitHandler.mockClear();
112
+ });
113
+
114
+ it('should render', async () => {
115
+ render(<TestForm />);
116
+ expect(screen.getByText('attachment multiplicity')).toBeInTheDocument();
117
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
118
+ expect(addButton).toBeInTheDocument();
119
+ });
120
+
121
+ it('should open dialog on add button click', async () => {
122
+ render(<TestForm />);
123
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
124
+ fireEvent.click(addButton);
125
+ expect(screen.getByText('Αποθήκευση')).toBeInTheDocument();
126
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
127
+ expect(screen.getByText('Επιλογή αρχείου')).toBeInTheDocument();
128
+ });
129
+ it('should add a new item on dialog form submission', async () => {
130
+ render(<TestForm />);
131
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
132
+ fireEvent.click(addButton);
133
+ const fileInput = screen.getByLabelText('Επιλογή αρχείου');
134
+ const file = new File(['file content'], 'test-file.txt', {
135
+ type: 'text/plain',
136
+ });
137
+ fireEvent.change(fileInput, { target: { files: [file] } });
138
+ const saveButton = screen.getByRole('button', { name: 'Αποθήκευση' });
139
+ fireEvent.click(saveButton);
140
+ expect(screen.getByText('test-file.txt')).toBeInTheDocument();
141
+ });
142
+ it('should submit added item on main form', async () => {
143
+ render(<TestForm />);
144
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
145
+ await user.click(addButton);
146
+ const fileInput = screen.getByLabelText('Επιλογή αρχείου');
147
+ const file = new File(['file content'], 'test-file.txt', {
148
+ type: 'text/plain',
149
+ });
150
+ await user.upload(fileInput, file);
151
+ await waitFor(() => {
152
+ expect(screen.getByText(/test-file.txt/)).toBeInTheDocument();
153
+ });
154
+
155
+ const saveButton = screen.getByRole('button', { name: 'Αποθήκευση' });
156
+ await user.click(saveButton);
157
+
158
+ await waitFor(() => {
159
+ expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
160
+ expect(screen.getByText('test-file.txt')).toBeInTheDocument();
161
+ });
162
+ expect(screen.getByText('Επεξεργασία')).toBeInTheDocument();
163
+ expect(screen.getByText('Διαγραφή')).toBeInTheDocument();
164
+
165
+ const submitButton = screen.getByRole('button', { name: 'Συνέχεια' });
166
+ await user.click(submitButton);
167
+
168
+ await waitFor(() => {
169
+ expect(submitHandler).toHaveBeenCalledTimes(1);
170
+ expect(submitHandler).toHaveBeenCalledWith({
171
+ multiplicity_attachment: expect.any(Array),
172
+ });
173
+ });
174
+
175
+ const callArgs = submitHandler.mock.calls[0][0];
176
+
177
+ expect(Array.isArray(callArgs.multiplicity_attachment)).toBe(true);
178
+ expect(callArgs.multiplicity_attachment).toHaveLength(1);
179
+ expect(callArgs.multiplicity_attachment[0]).toBeInstanceOf(FileList);
180
+ expect(callArgs.multiplicity_attachment[0][0].name).toBe('test-file.txt');
181
+ });
182
+ it('should submit multiple added items', async () => {
183
+ render(<TestForm />);
184
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
185
+
186
+ // First file
187
+ await user.click(addButton);
188
+ const file1 = new File(['file content'], 'file-1.txt', {
189
+ type: 'text/plain',
190
+ });
191
+ await user.upload(screen.getByLabelText('Επιλογή αρχείου'), file1);
192
+ await waitFor(() => {
193
+ expect(screen.getByText(/file-1.txt/)).toBeInTheDocument();
194
+ });
195
+
196
+ await user.click(screen.getByRole('button', { name: 'Αποθήκευση' }));
197
+
198
+ await waitFor(() => {
199
+ expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
200
+ });
201
+ expect(screen.getByText('file-1.txt')).toBeInTheDocument();
202
+ expect(screen.getByText('Επεξεργασία')).toBeInTheDocument();
203
+ expect(screen.getByText('Διαγραφή')).toBeInTheDocument();
204
+
205
+ // Second file
206
+ await user.click(addButton);
207
+ const file2 = new File(['file content'], 'file-2.txt', {
208
+ type: 'text/plain',
209
+ });
210
+ await user.upload(screen.getByLabelText('Επιλογή αρχείου'), file2);
211
+ await waitFor(() => {
212
+ expect(screen.getByText(/file-2.txt/)).toBeInTheDocument();
213
+ });
214
+
215
+ await user.click(screen.getByRole('button', { name: 'Αποθήκευση' }));
216
+
217
+ await waitFor(() => {
218
+ expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
219
+ });
220
+ expect(screen.getByText('file-1.txt')).toBeInTheDocument();
221
+ expect(screen.getByText('file-2.txt')).toBeInTheDocument();
222
+
223
+ const submitButton = screen.getByRole('button', { name: 'Συνέχεια' });
224
+ await user.click(submitButton);
225
+
226
+ await waitFor(() => {
227
+ expect(submitHandler).toHaveBeenCalledTimes(1);
228
+ expect(submitHandler).toHaveBeenCalledWith({
229
+ multiplicity_attachment: [expect.any(FileList), expect.any(FileList)],
230
+ });
231
+ });
232
+
233
+ const callArgs = submitHandler.mock.calls[0][0];
234
+
235
+ expect(Array.isArray(callArgs.multiplicity_attachment)).toBe(true);
236
+ expect(callArgs.multiplicity_attachment).toHaveLength(2);
237
+ expect(callArgs.multiplicity_attachment[0]).toBeInstanceOf(FileList);
238
+ expect(callArgs.multiplicity_attachment[0][0].name).toBe('file-1.txt');
239
+
240
+ expect(callArgs.multiplicity_attachment[1]).toBeInstanceOf(FileList);
241
+ expect(callArgs.multiplicity_attachment[1][0].name).toBe('file-2.txt');
242
+ });
243
+ it('should allow editing of added item', async () => {
244
+ render(<TestForm />);
245
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
246
+ await user.click(addButton);
247
+ const fileInput = screen.getByLabelText('Επιλογή αρχείου');
248
+ const file = new File(['file content'], 'test-file.txt', {
249
+ type: 'text/plain',
250
+ });
251
+ await user.upload(fileInput, file);
252
+ expect(screen.getByText(/test-file.txt/)).toBeInTheDocument();
253
+ const saveButton = screen.getByRole('button', { name: 'Αποθήκευση' });
254
+ await user.click(saveButton);
255
+ await waitFor(() =>
256
+ expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
257
+ );
258
+ expect(screen.getByText(/test-file.txt/)).toBeInTheDocument();
259
+
260
+ const editButton = screen.getByRole('button', { name: 'Επεξεργασία' });
261
+ await user.click(editButton);
262
+
263
+ await waitFor(() => {
264
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
265
+ const dialog = screen.getByRole('dialog');
266
+
267
+ expect(dialog).toHaveTextContent(/test-file.txt/);
268
+ });
269
+ const editFileInput = screen.getByLabelText(/Αντικατάσταση/);
270
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
271
+ const newFile = new File(['new content'], 'new-file.txt', {
272
+ type: 'text/plain',
273
+ });
274
+ await user.upload(editFileInput, newFile);
275
+ const saveEditButton = screen.getByRole('button', { name: 'Αποθήκευση' });
276
+ await user.click(saveEditButton);
277
+ expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
278
+ expect(screen.getByText(/new-file.txt/)).toBeInTheDocument();
279
+ });
280
+ });
@@ -0,0 +1,232 @@
1
+ import React from 'react';
2
+ import {
3
+ fireEvent,
4
+ render,
5
+ screen,
6
+ waitFor,
7
+ waitForElementToBeRemoved,
8
+ } from '@testing-library/react';
9
+ import type { FieldSpec } from '@digigov/form';
10
+ import FormBuilder, { Field } from '@digigov/form';
11
+ import { Button } from '@digigov/ui/form/Button';
12
+
13
+ beforeAll(() => {
14
+ global.ResizeObserver = class ResizeObserver {
15
+ observe() {
16
+ // do nothing
17
+ }
18
+ unobserve() {
19
+ // do nothing
20
+ }
21
+ disconnect() {
22
+ // do nothing
23
+ }
24
+ };
25
+ });
26
+
27
+ const fieldSpec: FieldSpec = {
28
+ key: 'multiplicity_optional',
29
+ editable: true,
30
+ type: 'array',
31
+ required: false,
32
+ label: {
33
+ primary: '"optional" μέχρι 10',
34
+ secondary: 'Ο χρήστης μπορεί να προσθέσει τιμές (σύνολο από 1 έως 10)',
35
+ },
36
+ extra: {
37
+ variant: 'dialog',
38
+ editVariant: 'optional',
39
+ min: 0,
40
+ max: 10,
41
+ noHeader: true,
42
+ noIndex: true,
43
+ label: {
44
+ object: {
45
+ add: 'Προσθήκη',
46
+ addButtonVariant: 'link',
47
+ append: {
48
+ label: 'Αποθήκευση',
49
+ },
50
+ delete: 'Αφαίρεση',
51
+ deleteButtonVariant: 'link',
52
+ cancel: {
53
+ label: 'Ακύρωση',
54
+ },
55
+ edit: {
56
+ label: 'Αποθήκευση',
57
+ },
58
+ nothing_added: 'Δεν έχουν προστεθεί στοιχεία',
59
+ },
60
+ },
61
+ of: {
62
+ editable: true,
63
+ key: undefined,
64
+ name: undefined,
65
+ type: 'string',
66
+ required: false,
67
+ label: {},
68
+ },
69
+ },
70
+ };
71
+
72
+ describe('multiplicity_optional case from dilosi', () => {
73
+ const submitHandler = vi.fn();
74
+
75
+ const TestForm = () => (
76
+ <FormBuilder onSubmit={submitHandler}>
77
+ <Field name="multiplicity_optional" {...fieldSpec} />
78
+ <Button type="submit">Συνέχεια</Button>
79
+ </FormBuilder>
80
+ );
81
+
82
+ beforeEach(() => {
83
+ submitHandler.mockClear();
84
+ });
85
+
86
+ it('should render', async () => {
87
+ render(<TestForm />);
88
+ expect(screen.getByText('"optional" μέχρι 10')).toBeInTheDocument();
89
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
90
+ expect(addButton).toBeInTheDocument();
91
+ });
92
+
93
+ it('should open dialog on add button click', async () => {
94
+ render(<TestForm />);
95
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
96
+ fireEvent.click(addButton);
97
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
98
+ });
99
+ it('should add a new item on dialog form submission', async () => {
100
+ render(<TestForm />);
101
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
102
+ fireEvent.click(addButton);
103
+
104
+ const inputField = screen.getByRole('textbox');
105
+ fireEvent.change(inputField, { target: { value: 'Test Value' } });
106
+ expect(inputField).toHaveValue('Test Value');
107
+ const submitButton = screen.getByRole('button', { name: 'Αποθήκευση' });
108
+ fireEvent.click(submitButton);
109
+ expect(await screen.findByRole('dialog')).not.toBeVisible();
110
+
111
+ expect(screen.getByText('Test Value')).toBeInTheDocument();
112
+ expect(submitHandler).not.toHaveBeenCalled();
113
+ });
114
+ it('should submit added item on main form', async () => {
115
+ render(<TestForm />);
116
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
117
+ fireEvent.click(addButton);
118
+
119
+ const inputField = screen.getByRole('textbox');
120
+ fireEvent.change(inputField, { target: { value: 'Test Value' } });
121
+ expect(inputField).toHaveValue('Test Value');
122
+ const submitButton = screen.getByRole('button', { name: 'Αποθήκευση' });
123
+ fireEvent.click(submitButton);
124
+ expect(await screen.findByRole('dialog')).not.toBeVisible();
125
+
126
+ expect(screen.getByText('Test Value')).toBeInTheDocument();
127
+ const continueButton = screen.getByRole('button', { name: 'Συνέχεια' });
128
+ fireEvent.click(continueButton);
129
+
130
+ await waitFor(() => {
131
+ expect(submitHandler).toHaveBeenCalledTimes(1);
132
+ });
133
+ expect(submitHandler).toHaveBeenCalledWith({
134
+ multiplicity_optional: ['Test Value'],
135
+ });
136
+ });
137
+ it('should allow submitting empty form', async () => {
138
+ render(<TestForm />);
139
+ const continueButton = screen.getByRole('button', { name: 'Συνέχεια' });
140
+
141
+ fireEvent.click(continueButton);
142
+ await waitFor(() => {
143
+ expect(submitHandler).toHaveBeenCalledTimes(1);
144
+ });
145
+ expect(submitHandler).toHaveBeenCalledWith({ multiplicity_optional: [] });
146
+ });
147
+ it('should allow adding up to max items', async () => {
148
+ render(<TestForm />);
149
+
150
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
151
+ const continueButton = screen.getByRole('button', { name: 'Συνέχεια' });
152
+
153
+ for (let i = 1; i <= 10; i++) {
154
+ fireEvent.click(addButton);
155
+ await waitFor(() =>
156
+ expect(screen.getByRole('dialog')).toBeInTheDocument()
157
+ );
158
+ const inputField = screen.getByRole('textbox');
159
+ fireEvent.change(inputField, { target: { value: `Test ${i}` } });
160
+ expect(inputField).toHaveValue(`Test ${i}`);
161
+ const submitButton = screen.getByRole('button', { name: 'Αποθήκευση' });
162
+ fireEvent.click(submitButton);
163
+ await waitForElementToBeRemoved(screen.getByRole('dialog'));
164
+ }
165
+
166
+ expect(addButton).toBeDisabled();
167
+
168
+ for (let i = 1; i <= 10; i++) {
169
+ expect(screen.getByText(`Test ${i}`)).toBeInTheDocument();
170
+ }
171
+
172
+ fireEvent.click(continueButton);
173
+
174
+ await waitFor(() => {
175
+ expect(submitHandler).toHaveBeenCalledTimes(1);
176
+ });
177
+
178
+ expect(submitHandler).toHaveBeenCalledWith({
179
+ multiplicity_optional: [
180
+ 'Test 1',
181
+ 'Test 2',
182
+ 'Test 3',
183
+ 'Test 4',
184
+ 'Test 5',
185
+ 'Test 6',
186
+ 'Test 7',
187
+ 'Test 8',
188
+ 'Test 9',
189
+ 'Test 10',
190
+ ],
191
+ });
192
+ });
193
+ it('should allow submitting empty item to the main form', async () => {
194
+ render(<TestForm />);
195
+
196
+ expect(
197
+ screen.getByText('Δεν έχουν προστεθεί στοιχεία')
198
+ ).toBeInTheDocument();
199
+
200
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
201
+
202
+ // Just focus and submit without entering any value
203
+ fireEvent.click(addButton);
204
+ await waitFor(() => expect(screen.getByRole('dialog')).toBeInTheDocument());
205
+ fireEvent.focus(screen.getByRole('textbox'));
206
+ fireEvent.click(screen.getByRole('button', { name: 'Αποθήκευση' }));
207
+ await waitForElementToBeRemoved(screen.getByRole('dialog'));
208
+
209
+ expect(
210
+ screen.getByText('Δεν έχουν προστεθεί στοιχεία')
211
+ ).toBeInTheDocument();
212
+
213
+ // Submit empty string
214
+ fireEvent.click(addButton);
215
+ await waitFor(() => expect(screen.getByRole('dialog')).toBeInTheDocument());
216
+ fireEvent.change(screen.getByRole('textbox'), { target: { value: '' } });
217
+ fireEvent.click(screen.getByRole('button', { name: 'Αποθήκευση' }));
218
+ await waitForElementToBeRemoved(screen.getByRole('dialog'));
219
+
220
+ expect(
221
+ screen.getByText('Δεν έχουν προστεθεί στοιχεία')
222
+ ).toBeInTheDocument();
223
+
224
+ const continueButton = screen.getByRole('button', { name: 'Συνέχεια' });
225
+ fireEvent.click(continueButton);
226
+
227
+ await waitFor(() => {
228
+ expect(submitHandler).toHaveBeenCalledTimes(1);
229
+ });
230
+ expect(submitHandler).toHaveBeenCalledWith({ multiplicity_optional: [] });
231
+ });
232
+ });
@@ -0,0 +1,170 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
3
+ import type { FieldSpec } from '@digigov/form';
4
+ import FormBuilder, { Field } from '@digigov/form';
5
+ import { Button } from '@digigov/ui/form/Button';
6
+
7
+ beforeAll(() => {
8
+ global.ResizeObserver = class ResizeObserver {
9
+ observe() {
10
+ // do nothing
11
+ }
12
+ unobserve() {
13
+ // do nothing
14
+ }
15
+ disconnect() {
16
+ // do nothing
17
+ }
18
+ };
19
+ });
20
+
21
+ const fieldSpec: FieldSpec = {
22
+ key: 'multiplicity_required',
23
+ editable: true,
24
+ type: 'array',
25
+ required: true,
26
+ label: {
27
+ primary: '"required" μέχρι 10',
28
+ secondary: 'Ο χρήστης μπορεί να προσθέσει τιμές (σύνολο από 1 έως 10)',
29
+ },
30
+ extra: {
31
+ variant: 'dialog',
32
+ editVariant: 'required',
33
+ min: 1,
34
+ max: 10,
35
+ noHeader: true,
36
+ noIndex: true,
37
+ label: {
38
+ object: {
39
+ add: 'Προσθήκη',
40
+ addButtonVariant: 'link',
41
+ append: {
42
+ label: 'Αποθήκευση',
43
+ },
44
+ delete: 'Αφαίρεση',
45
+ deleteButtonVariant: 'link',
46
+ cancel: {
47
+ label: 'Ακύρωση',
48
+ },
49
+ edit: {
50
+ label: 'Αποθήκευση',
51
+ },
52
+ nothing_added: 'Δεν έχουν προστεθεί στοιχεία',
53
+ },
54
+ },
55
+ of: {
56
+ editable: true,
57
+ key: undefined,
58
+ name: undefined,
59
+ type: 'string',
60
+ required: true,
61
+ label: {},
62
+ },
63
+ },
64
+ };
65
+
66
+ describe('multiplicity_required case from dilosi', () => {
67
+ const submitHandler = vi.fn();
68
+
69
+ const TestForm = () => (
70
+ <FormBuilder onSubmit={submitHandler}>
71
+ <Field name="multiplicity_required" {...fieldSpec} />
72
+ <Button type="submit">Συνέχεια</Button>
73
+ </FormBuilder>
74
+ );
75
+
76
+ beforeEach(() => {
77
+ submitHandler.mockClear();
78
+ });
79
+
80
+ it('should render', async () => {
81
+ render(<TestForm />);
82
+ expect(screen.getByText('"required" μέχρι 10')).toBeInTheDocument();
83
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
84
+ expect(addButton).toBeInTheDocument();
85
+ });
86
+
87
+ it('should open dialog on add button click', async () => {
88
+ render(<TestForm />);
89
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
90
+ fireEvent.click(addButton);
91
+ expect(screen.getByRole('dialog')).toBeInTheDocument();
92
+ });
93
+ it('should add a new item on dialog form submission', async () => {
94
+ render(<TestForm />);
95
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
96
+ fireEvent.click(addButton);
97
+
98
+ const inputField = screen.getByRole('textbox');
99
+ fireEvent.change(inputField, { target: { value: 'Test Value' } });
100
+ expect(inputField).toHaveValue('Test Value');
101
+ const submitButton = screen.getByRole('button', { name: 'Αποθήκευση' });
102
+ fireEvent.click(submitButton);
103
+ expect(await screen.findByRole('dialog')).not.toBeVisible();
104
+
105
+ expect(screen.getByText('Test Value')).toBeInTheDocument();
106
+ expect(submitHandler).not.toHaveBeenCalled();
107
+ });
108
+ it('should submit added item on main form', async () => {
109
+ render(<TestForm />);
110
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
111
+ fireEvent.click(addButton);
112
+
113
+ const inputField = screen.getByRole('textbox');
114
+ fireEvent.change(inputField, { target: { value: 'Test Value' } });
115
+ expect(inputField).toHaveValue('Test Value');
116
+ const submitButton = screen.getByRole('button', { name: 'Αποθήκευση' });
117
+ fireEvent.click(submitButton);
118
+ expect(await screen.findByRole('dialog')).not.toBeVisible();
119
+
120
+ expect(screen.getByText('Test Value')).toBeInTheDocument();
121
+ const continueButton = screen.getByRole('button', { name: 'Συνέχεια' });
122
+ fireEvent.click(continueButton);
123
+
124
+ await waitFor(() => {
125
+ expect(submitHandler).toHaveBeenCalledTimes(1);
126
+ });
127
+ expect(submitHandler).toHaveBeenCalledWith({
128
+ multiplicity_required: ['Test Value'],
129
+ });
130
+ });
131
+ it('should show validation error if submitted empty', async () => {
132
+ render(<TestForm />);
133
+ const continueButton = screen.getByRole('button', { name: 'Συνέχεια' });
134
+
135
+ fireEvent.click(continueButton);
136
+
137
+ await waitFor(() => {
138
+ expect(submitHandler).not.toHaveBeenCalled();
139
+ });
140
+
141
+ await waitFor(() => {
142
+ expect(
143
+ screen.getByText(/Το πεδίο πρέπει να έχει τουλάχιστον 1 εγγραφές/)
144
+ ).toBeInTheDocument();
145
+ });
146
+ });
147
+ it('should show validation error if item is empty', async () => {
148
+ render(<TestForm />);
149
+ const addButton = screen.getByRole('button', { name: 'Προσθήκη' });
150
+
151
+ fireEvent.click(addButton);
152
+ await waitFor(() => expect(screen.getByRole('dialog')).toBeInTheDocument());
153
+
154
+ // Just focus the input
155
+ fireEvent.focus(screen.getByRole('textbox'));
156
+ fireEvent.click(screen.getByRole('button', { name: 'Αποθήκευση' }));
157
+
158
+ await waitFor(() =>
159
+ expect(screen.getByText(/Το πεδίο είναι υποχρεωτικό/)).toBeInTheDocument()
160
+ );
161
+
162
+ // Add empty string
163
+ fireEvent.change(screen.getByRole('textbox'), { target: { value: '' } });
164
+ fireEvent.click(screen.getByRole('button', { name: 'Αποθήκευση' }));
165
+
166
+ await waitFor(() =>
167
+ expect(screen.getByText(/Το πεδίο είναι υποχρεωτικό/)).toBeInTheDocument()
168
+ );
169
+ });
170
+ });