@inseefr/lunatic 0.1.0-hackathon → 0.1.0-v2

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 (350) hide show
  1. package/lib/index.js +1433 -835
  2. package/lib/index.js.map +1 -1
  3. package/package.json +11 -8
  4. package/src/components/breadcrumb/component.js +29 -29
  5. package/src/components/button/index.js +1 -1
  6. package/src/components/button/lunatic-button.js +32 -0
  7. package/src/components/checkbox/checkbox-boolean/index.js +1 -0
  8. package/src/components/checkbox/checkbox-boolean/lunatic-checkbox-boolean.js +44 -0
  9. package/src/components/checkbox/checkbox-group/checkbox-group.js +78 -0
  10. package/src/components/checkbox/checkbox-group/checkbox-option.js +46 -0
  11. package/src/components/checkbox/checkbox-group/index.js +1 -0
  12. package/src/components/checkbox/checkbox-group/lunatic-checkbox-group.js +32 -0
  13. package/src/components/checkbox/checkbox-one/index.js +1 -0
  14. package/src/components/checkbox/checkbox-one/lunatic-checkbox-one.js +7 -0
  15. package/src/components/checkbox/checkbox.scss +1 -73
  16. package/src/components/checkbox/commons/checkbox-option.js +49 -0
  17. package/src/components/checkbox/commons/index.js +1 -0
  18. package/src/components/checkbox/index.js +3 -3
  19. package/src/components/commons/components/field-container/field-container.js +28 -0
  20. package/src/components/commons/components/field-container/field-container.scss +0 -0
  21. package/src/components/commons/components/field-container/index.js +1 -0
  22. package/src/components/commons/components/fieldset.js +12 -0
  23. package/src/components/commons/components/input-container.js +30 -0
  24. package/src/components/commons/components/label.js +14 -0
  25. package/src/components/commons/components/lunatic-field.js +35 -0
  26. package/src/components/commons/create-customizable-field.js +13 -0
  27. package/src/components/commons/index.js +9 -0
  28. package/src/components/commons/use-on-handle-change.js +16 -0
  29. package/src/components/commons/use-options-keydown.js +22 -0
  30. package/src/components/commons/use-previous.js +11 -0
  31. package/src/components/component-wrapper/controls/component.js +70 -0
  32. package/src/components/component-wrapper/controls/controls.scss +6 -0
  33. package/src/components/component-wrapper/controls/index.js +1 -0
  34. package/src/components/component-wrapper/controls/validators/datepicker.js +33 -0
  35. package/src/components/component-wrapper/controls/validators/index.js +16 -0
  36. package/src/components/component-wrapper/controls/validators/input-number.js +23 -0
  37. package/src/components/{missing-wrapper → component-wrapper}/index.js +1 -1
  38. package/src/components/{missing-wrapper → component-wrapper/missing}/component.js +72 -12
  39. package/src/components/component-wrapper/missing/index.js +1 -0
  40. package/src/components/{missing-wrapper → component-wrapper/missing}/missing.scss +0 -0
  41. package/src/components/component-wrapper/wrapper.js +23 -0
  42. package/src/components/components.js +22 -18
  43. package/src/components/datepicker/datepicker.js +25 -0
  44. package/src/components/datepicker/index.js +1 -1
  45. package/src/components/datepicker/lunatic-datepicker.js +50 -0
  46. package/src/components/declarations/declaration.js +11 -0
  47. package/src/components/declarations/declarations-after-text.js +8 -0
  48. package/src/components/declarations/declarations-before-text.js +8 -0
  49. package/src/components/declarations/declarations-detachable.js +8 -0
  50. package/src/components/declarations/declarations.js +35 -0
  51. package/src/components/declarations/index.js +4 -1
  52. package/src/components/declarations/wrappers/input-declarations-wrapper.js +40 -12
  53. package/src/components/declarations/wrappers/list-declarations-wrapper.js +235 -232
  54. package/src/components/dropdown/commons/actions.js +40 -31
  55. package/src/components/dropdown/commons/components/panel.js +78 -78
  56. package/src/components/dropdown/commons/reducer.js +152 -149
  57. package/src/components/dropdown/component.js +121 -115
  58. package/src/components/dropdown/dropdown-edit/dropdown-edit.js +6 -0
  59. package/src/components/dropdown/dropdown-simple/dropdown.js +8 -1
  60. package/src/components/filter-description/component.js +48 -42
  61. package/src/components/icon/component.js +31 -33
  62. package/src/components/index.scss +5 -3
  63. package/src/components/input/index.js +1 -2
  64. package/src/components/input/input.js +45 -9
  65. package/src/components/input/input.scss +0 -6
  66. package/src/components/input/lunatic-input.js +53 -0
  67. package/src/components/input-number/index.js +1 -0
  68. package/src/components/input-number/input-number.js +38 -0
  69. package/src/components/input-number/input-number.scss +0 -0
  70. package/src/components/input-number/lunatic-input-number.js +50 -0
  71. package/src/components/loop/{component.js → _old/component.js} +1 -0
  72. package/src/components/loop/{loop.scss → _old/loop.scss} +0 -0
  73. package/src/components/loop/{wrapper.js → _old/wrapper.js} +15 -15
  74. package/src/components/loop/block-for-loop/block-for-loop-ochestrator.js +6 -0
  75. package/src/components/loop/block-for-loop/block-for-loop.js +91 -0
  76. package/src/components/loop/block-for-loop/index.js +1 -0
  77. package/src/components/loop/block-for-loop/row.js +52 -0
  78. package/src/components/loop/commons/create-loop-orchestrator.js +36 -0
  79. package/src/components/loop/commons/index.js +2 -0
  80. package/src/components/loop/commons/row-component.js +52 -0
  81. package/src/components/loop/index.js +1 -1
  82. package/src/components/loop/loop.js +78 -0
  83. package/src/components/loop/roster-for-loop/add-row-button.js +12 -0
  84. package/src/components/loop/roster-for-loop/body.js +44 -0
  85. package/src/components/loop/roster-for-loop/header.js +25 -0
  86. package/src/components/loop/roster-for-loop/html-table/table.js +11 -0
  87. package/src/components/loop/roster-for-loop/html-table/tbody.js +11 -0
  88. package/src/components/loop/roster-for-loop/html-table/td.js +14 -0
  89. package/src/components/loop/roster-for-loop/html-table/th.js +11 -0
  90. package/src/components/loop/roster-for-loop/html-table/thead.js +11 -0
  91. package/src/components/loop/roster-for-loop/html-table/tr.js +11 -0
  92. package/src/components/loop/roster-for-loop/index.js +1 -0
  93. package/src/components/loop/roster-for-loop/roster-for-loop-orchestrator.js +6 -0
  94. package/src/components/loop/roster-for-loop/roster-for-loop.js +90 -0
  95. package/src/components/loop/roster-for-loop/roster-table.js +39 -0
  96. package/src/components/loop/roster-for-loop/roster.scss +42 -0
  97. package/src/components/loop/roster-for-loop/row.js +65 -0
  98. package/src/components/loop-constructor/block/component.js +2 -2
  99. package/src/components/loop-constructor/block/index.js +1 -1
  100. package/src/components/loop-constructor/index.js +1 -1
  101. package/src/components/loop-constructor/roster/component.js +2 -2
  102. package/src/components/loop-constructor/roster/index.js +1 -1
  103. package/src/components/loop-constructor/wrapper/body-component.js +6 -0
  104. package/src/components/loop-constructor/wrapper/build-components.js +33 -33
  105. package/src/components/loop-constructor/wrapper/index.js +1 -1
  106. package/src/components/modal/component.js +42 -0
  107. package/src/components/modal/index.js +1 -0
  108. package/src/components/modal/modal.scss +33 -0
  109. package/src/components/radio/index.js +1 -1
  110. package/src/components/radio/lunatic-radio-group.js +45 -0
  111. package/src/components/radio/radio-group.js +33 -0
  112. package/src/components/radio/radio-option.js +87 -0
  113. package/src/components/radio/radio.scss +52 -52
  114. package/src/components/sequence/index.js +1 -1
  115. package/src/components/sequence/sequence.js +75 -0
  116. package/src/components/subsequence/index.js +1 -1
  117. package/src/components/subsequence/subsequence.js +73 -0
  118. package/src/components/suggester/check-store.js +70 -70
  119. package/src/components/suggester/components/panel/option-container.js +11 -10
  120. package/src/components/suggester/components/panel/panel.js +20 -6
  121. package/src/components/suggester/components/selection/label.js +7 -6
  122. package/src/components/suggester/components/selection/selection.js +36 -11
  123. package/src/components/suggester/components/suggester-content.js +35 -42
  124. package/src/components/suggester/components/suggester.js +45 -26
  125. package/src/components/suggester/{components/create-on-keydown-callback.js → create-on-keydown-callback.js} +28 -28
  126. package/src/components/suggester/find-best-label/find-best-label.js +3 -1
  127. package/src/components/suggester/idb-suggester.js +2 -1
  128. package/src/components/suggester/lunatic-suggester.js +48 -96
  129. package/src/components/suggester/searching/create-searching.js +3 -1
  130. package/src/components/suggester/suggester-wrapper.js +75 -9
  131. package/src/components/switch/index.js +1 -0
  132. package/src/components/switch/lunatic-switch.js +49 -0
  133. package/src/components/switch/switch.js +72 -0
  134. package/src/components/switch/switch.scss +47 -0
  135. package/src/components/table/table.js +164 -158
  136. package/src/components/textarea/component.js +11 -5
  137. package/src/components/tooltip/response.js +58 -52
  138. package/src/stories/checkbox-boolean/data-forced.json +48 -48
  139. package/src/stories/checkbox-group/data-vtl.json +102 -102
  140. package/src/stories/cleaning/cleaning.stories.js +39 -0
  141. package/src/stories/cleaning/simple-loop.json +911 -0
  142. package/src/stories/cleaning/simpsons.json +5839 -0
  143. package/src/stories/datepicker/data.json +45 -43
  144. package/src/stories/declarations/declarations.stories.js +20 -13
  145. package/src/stories/icons/icons.stories.js +24 -16
  146. package/src/stories/loop-constructor/README.md +27 -27
  147. package/src/stories/loop-constructor/data-input-forced.json +64 -64
  148. package/src/stories/loop-constructor/data-input.json +100 -100
  149. package/src/stories/loop-constructor/data-loop-forced.json +66 -66
  150. package/src/stories/loop-constructor/data-loop-static-forced.json +66 -66
  151. package/src/stories/loop-constructor/data-loop-static.json +81 -81
  152. package/src/stories/loop-constructor/data-loop.json +81 -81
  153. package/src/stories/loop-constructor/data-roster-forced.json +68 -68
  154. package/src/stories/loop-constructor/data-roster.json +83 -83
  155. package/src/stories/loop-constructor/loop-constructor.stories.js +180 -180
  156. package/src/stories/questionnaire/logement-queen.json +23234 -0
  157. package/src/stories/questionnaire/logement.json +22068 -26812
  158. package/src/stories/questionnaire/questionnaire.stories.js +86 -29
  159. package/src/stories/questionnaire/update-external/data.json +1 -0
  160. package/src/stories/questionnaire/update-external/questionnaire.json +75 -0
  161. package/src/stories/suggester/bailleurs-sociaux-2021/fetch-bailleurs.js +12 -0
  162. package/src/stories/suggester/bailleurs-sociaux-2021/index.js +1 -0
  163. package/src/stories/suggester/data-auto.json +1 -0
  164. package/src/stories/suggester/data.json +35 -2
  165. package/src/stories/suggester/lunatic-suggester-mui.scss +27 -0
  166. package/src/stories/suggester/suggester-material-ui.js +148 -0
  167. package/src/stories/suggester/suggester-workers.stories.js +48 -1
  168. package/src/stories/suggester/suggester.stories.js +27 -1
  169. package/src/stories/switch/README.md +31 -0
  170. package/src/stories/switch/SwitchMaterialUI.js +35 -0
  171. package/src/stories/switch/data-forced.json +48 -0
  172. package/src/stories/switch/data.json +80 -0
  173. package/src/stories/switch/switch.stories.js +78 -0
  174. package/src/stories/utils/custom-lunatic.scss +28 -23
  175. package/src/stories/utils/orchestrator.js +151 -58
  176. package/src/stories/utils/waiting/index.js +1 -0
  177. package/src/stories/utils/waiting/preloader.svg +1 -0
  178. package/src/stories/utils/waiting/waiting.js +21 -0
  179. package/src/stories/utils/waiting/waiting.scss +21 -0
  180. package/src/tests/sample.spec.js +5 -0
  181. package/src/utils/icons/checkbox-checked.icon.js +25 -0
  182. package/src/utils/icons/checkbox-unchecked.icon.js +25 -0
  183. package/src/utils/icons/radio-checked.icon.js +25 -0
  184. package/src/utils/icons/radio-unchecked.icon.js +25 -0
  185. package/src/utils/lib/controls/index.js +1 -0
  186. package/src/utils/lib/controls/utils.js +146 -0
  187. package/src/utils/lib/index.js +20 -19
  188. package/src/utils/lib/pagination/navigation/shared.js +7 -4
  189. package/src/utils/lib/responses.js +9 -7
  190. package/src/utils/lib/tooltip/build-response.js +53 -41
  191. package/src/utils/store-tools/auto-load.js +2 -1
  192. package/src/utils/store-tools/create/index.js +2 -1
  193. package/src/utils/store-tools/create/update-store-info.js +26 -26
  194. package/src/utils/store-tools/index.js +7 -5
  195. package/src/utils/suggester-workers/append-to-index/create-append-task.js +3 -1
  196. package/src/utils/suggester-workers/commons-tokenizer/create-entity-tokenizer.js +56 -0
  197. package/src/utils/suggester-workers/commons-tokenizer/create-fields-tokenizer.js +56 -0
  198. package/src/utils/suggester-workers/commons-tokenizer/create-filter-stop-words.js +11 -11
  199. package/src/utils/suggester-workers/commons-tokenizer/filters/compose-filters.js +10 -0
  200. package/src/utils/suggester-workers/commons-tokenizer/filters/create-filter-stop-words.js +17 -0
  201. package/src/utils/suggester-workers/commons-tokenizer/filters/create-filter-stop-words.spec.js +14 -0
  202. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-accents.js +12 -0
  203. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-accents.spec.js +12 -0
  204. package/src/utils/suggester-workers/commons-tokenizer/{filter-double.js → filters/filter-double.js} +0 -0
  205. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-double.spec.js +20 -0
  206. package/src/utils/suggester-workers/commons-tokenizer/{filter-length.js → filters/filter-length.js} +0 -0
  207. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-length.spec.js +18 -0
  208. package/src/utils/suggester-workers/commons-tokenizer/{filter-stemmer.js → filters/filter-stemmer.js} +2 -2
  209. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-stemmer.spec.js +12 -0
  210. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-synonyms.js +36 -0
  211. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-synonyms.spec.js +12 -0
  212. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-to-lower.js +10 -0
  213. package/src/utils/suggester-workers/commons-tokenizer/filters/filter-to-lower.spec.js +12 -0
  214. package/src/utils/suggester-workers/commons-tokenizer/filters/index.js +2 -0
  215. package/src/utils/suggester-workers/commons-tokenizer/{stop-words.js → filters/stop-words.js} +0 -0
  216. package/src/utils/suggester-workers/commons-tokenizer/index.js +6 -5
  217. package/src/utils/suggester-workers/commons-tokenizer/prepare-string-indexation.js +7 -3
  218. package/src/utils/suggester-workers/commons-tokenizer/soft-tokenizer.js +1 -1
  219. package/src/utils/suggester-workers/create-worker.js +55 -0
  220. package/src/utils/suggester-workers/find-best-label/tokenize.js +2 -5
  221. package/src/utils/suggester-workers/{query-parser → searching/query-parser}/index.js +0 -0
  222. package/src/utils/suggester-workers/searching/query-parser/query-parser-soft.js +7 -0
  223. package/src/utils/suggester-workers/{query-parser → searching/query-parser}/query-parser-soft.spec.js +0 -0
  224. package/src/utils/suggester-workers/searching/query-parser/query-parser-tokenized.js +34 -0
  225. package/src/utils/suggester-workers/searching/resolve-query-parser.js +2 -2
  226. package/src/utils/suggester-workers/searching/searching.js +2 -2
  227. package/src/utils/to-expose/{calculated-variables.js → _old/calculated-variables.js} +0 -0
  228. package/src/utils/to-expose/{handler.js → _old/handler.js} +22 -0
  229. package/src/utils/to-expose/{init-questionnaire.js → _old/init-questionnaire.js} +0 -0
  230. package/src/utils/to-expose/{state.js → _old/state.js} +13 -14
  231. package/src/utils/to-expose/hooks/filter-components.js +106 -106
  232. package/src/utils/to-expose/hooks/index.js +1 -1
  233. package/src/utils/to-expose/hooks/lunatic.js +68 -7
  234. package/src/utils/to-expose/hooks/use-lunatic/actions.js +23 -0
  235. package/src/utils/to-expose/hooks/use-lunatic/commons/check-loops.js +61 -0
  236. package/src/utils/to-expose/hooks/use-lunatic/commons/create-map-pages.js +69 -0
  237. package/src/utils/to-expose/hooks/use-lunatic/commons/execute-condition-filter.js +16 -0
  238. package/src/utils/to-expose/hooks/use-lunatic/commons/execute-expression/create-execute-expression.js +182 -0
  239. package/src/utils/to-expose/hooks/use-lunatic/commons/execute-expression/create-memoizer.js +42 -0
  240. package/src/utils/to-expose/hooks/use-lunatic/commons/execute-expression/create-refresh-calculated.js +50 -0
  241. package/src/utils/to-expose/hooks/use-lunatic/commons/execute-expression/execute-expression.js +60 -0
  242. package/src/utils/to-expose/hooks/use-lunatic/commons/execute-expression/get-expressions-variables.js +22 -0
  243. package/src/utils/to-expose/hooks/use-lunatic/commons/execute-expression/index.js +1 -0
  244. package/src/utils/to-expose/hooks/use-lunatic/commons/fill-component-expressions.js +113 -0
  245. package/src/utils/to-expose/hooks/use-lunatic/commons/fill-components.js +31 -0
  246. package/src/utils/to-expose/hooks/use-lunatic/commons/get-compatible-vtl-expression.js +14 -0
  247. package/src/utils/to-expose/hooks/use-lunatic/commons/get-component-value/get-component-value.js +161 -0
  248. package/src/utils/to-expose/hooks/use-lunatic/commons/get-component-value/index.js +1 -0
  249. package/src/utils/to-expose/hooks/use-lunatic/commons/get-components-from-state.js +24 -0
  250. package/src/utils/to-expose/hooks/use-lunatic/commons/get-page-tag.js +10 -0
  251. package/src/utils/to-expose/hooks/use-lunatic/commons/index.js +12 -0
  252. package/src/utils/to-expose/hooks/use-lunatic/commons/is-First-last-page.js +8 -0
  253. package/src/utils/to-expose/hooks/use-lunatic/commons/is-paginated-loop.js +6 -0
  254. package/src/utils/to-expose/hooks/use-lunatic/commons/load-suggesters.js +59 -0
  255. package/src/utils/to-expose/hooks/use-lunatic/commons/use-components-from-state.js +20 -0
  256. package/src/utils/to-expose/hooks/use-lunatic/index.js +1 -0
  257. package/src/utils/to-expose/hooks/use-lunatic/initial-state.js +22 -0
  258. package/src/utils/to-expose/hooks/use-lunatic/reducer/commons/index.js +3 -0
  259. package/src/utils/to-expose/hooks/use-lunatic/reducer/commons/is-empty-on-empty-page.js +29 -0
  260. package/src/utils/to-expose/hooks/use-lunatic/reducer/commons/resize-array-variable.js +26 -0
  261. package/src/utils/to-expose/hooks/use-lunatic/reducer/commons/validate-loop-condition-filter.js +20 -0
  262. package/src/utils/to-expose/hooks/use-lunatic/reducer/index.js +1 -0
  263. package/src/utils/to-expose/hooks/use-lunatic/reducer/reduce-go-next-page.js +129 -0
  264. package/src/utils/to-expose/hooks/use-lunatic/reducer/reduce-go-previous-page.js +131 -0
  265. package/src/utils/to-expose/hooks/use-lunatic/reducer/reduce-handle-change/index.js +1 -0
  266. package/src/utils/to-expose/hooks/use-lunatic/reducer/reduce-handle-change/reduce-handle-change.js +69 -0
  267. package/src/utils/to-expose/hooks/use-lunatic/reducer/reduce-handle-change/reduce-variables-array.js +22 -0
  268. package/src/utils/to-expose/hooks/use-lunatic/reducer/reduce-handle-change/reduce-variables-simple.js +13 -0
  269. package/src/utils/to-expose/hooks/use-lunatic/reducer/reduce-on-init.js +166 -0
  270. package/src/utils/to-expose/hooks/use-lunatic/reducer/reduce-on-set-waiting.js +7 -0
  271. package/src/utils/to-expose/hooks/use-lunatic/reducer/reducer.js +26 -0
  272. package/src/utils/to-expose/hooks/use-lunatic/use-lunatic.js +79 -0
  273. package/src/utils/to-expose/index.js +16 -11
  274. package/src/components/button/component.js +0 -53
  275. package/src/components/checkbox/boolean.js +0 -172
  276. package/src/components/checkbox/group.js +0 -231
  277. package/src/components/checkbox/one.js +0 -11
  278. package/src/components/datepicker/component.js +0 -11
  279. package/src/components/input/input-number.js +0 -54
  280. package/src/components/missing-wrapper/wrapper.js +0 -10
  281. package/src/components/radio/component.js +0 -9
  282. package/src/components/sequence/component.js +0 -50
  283. package/src/components/subsequence/component.js +0 -49
  284. package/src/tests/components/breadcrumb.spec.js +0 -13
  285. package/src/tests/components/button.spec.js +0 -11
  286. package/src/tests/components/checkbox-boolean.spec.js +0 -45
  287. package/src/tests/components/checkbox-group.spec.js +0 -53
  288. package/src/tests/components/checkbox-one.spec.js +0 -32
  289. package/src/tests/components/datepicker.spec.js +0 -22
  290. package/src/tests/components/declarations-wrappers/input-declarations-wrapper.spec.js +0 -67
  291. package/src/tests/components/declarations-wrappers/list-declarations-wrapper.spec.js +0 -52
  292. package/src/tests/components/declarations-wrappers/simple-declarations-wrapper.spec.js +0 -21
  293. package/src/tests/components/declarations.spec.js +0 -46
  294. package/src/tests/components/input-number.spec.js +0 -194
  295. package/src/tests/components/input.spec.js +0 -18
  296. package/src/tests/components/loops/loop-static.json +0 -66
  297. package/src/tests/components/loops/loop.json +0 -258
  298. package/src/tests/components/loops/loop.spec.js +0 -30
  299. package/src/tests/components/loops/roster-for-loop.spec.js +0 -18
  300. package/src/tests/components/loops/roster-loop.json +0 -71
  301. package/src/tests/components/missing-wrapper.spec.js +0 -33
  302. package/src/tests/components/progress-bar.spec.js +0 -15
  303. package/src/tests/components/radio.spec.js +0 -27
  304. package/src/tests/components/sequence.spec.js +0 -9
  305. package/src/tests/components/subsequence.spec.js +0 -9
  306. package/src/tests/components/table.spec.js +0 -11
  307. package/src/tests/components/textarea.spec.js +0 -18
  308. package/src/tests/components/tooltip.spec.js +0 -25
  309. package/src/tests/setup/setupTests.js +0 -4
  310. package/src/tests/utils/lib/alphabet.spec.js +0 -36
  311. package/src/tests/utils/lib/array.spec.js +0 -22
  312. package/src/tests/utils/lib/checkbox/group.spec.js +0 -72
  313. package/src/tests/utils/lib/decorator/title-decorator.spec.js +0 -12
  314. package/src/tests/utils/lib/input-number.spec.js +0 -18
  315. package/src/tests/utils/lib/items-positioning.spec.js +0 -17
  316. package/src/tests/utils/lib/label-position.spec.js +0 -22
  317. package/src/tests/utils/lib/loops/bindings.spec.js +0 -75
  318. package/src/tests/utils/lib/loops/shared.spec.js +0 -82
  319. package/src/tests/utils/lib/missing/missing.spec.js +0 -74
  320. package/src/tests/utils/lib/missing/mock.js +0 -137
  321. package/src/tests/utils/lib/pagination/shared.spec.js +0 -42
  322. package/src/tests/utils/lib/responses.spec.js +0 -64
  323. package/src/tests/utils/lib/style.spec.js +0 -26
  324. package/src/tests/utils/lib/table/roster.spec.js +0 -25
  325. package/src/tests/utils/lib/tooltip/build-response.spec.js +0 -95
  326. package/src/tests/utils/lib/tooltip/content.spec.js +0 -109
  327. package/src/tests/utils/to-expose/handler/handler.spec.js +0 -94
  328. package/src/tests/utils/to-expose/handler/questionnaire.json +0 -158
  329. package/src/tests/utils/to-expose/handler/results/index.js +0 -6
  330. package/src/tests/utils/to-expose/handler/results/res-double.json +0 -158
  331. package/src/tests/utils/to-expose/handler/results/res-input-collected.json +0 -158
  332. package/src/tests/utils/to-expose/handler/results/res-input-edited.json +0 -158
  333. package/src/tests/utils/to-expose/handler/results/res-loop.json +0 -158
  334. package/src/tests/utils/to-expose/handler/results/res-matrix.json +0 -158
  335. package/src/tests/utils/to-expose/handler/results/res-responses.json +0 -158
  336. package/src/tests/utils/to-expose/hooks/use-lunatic.spec.js +0 -46
  337. package/src/tests/utils/to-expose/init-questionnaire/data.json +0 -12
  338. package/src/tests/utils/to-expose/init-questionnaire/init-questionnaire.spec.js +0 -19
  339. package/src/tests/utils/to-expose/init-questionnaire/questionnaire.json +0 -148
  340. package/src/tests/utils/to-expose/init-questionnaire/result.json +0 -181
  341. package/src/tests/utils/to-expose/interpret/interpret.spec.js +0 -48
  342. package/src/tests/utils/to-expose/state/questionnaire.json +0 -61
  343. package/src/tests/utils/to-expose/state/results.js +0 -78
  344. package/src/tests/utils/to-expose/state/state.spec.js +0 -59
  345. package/src/utils/suggester-workers/commons-tokenizer/create-tokenizer.js +0 -103
  346. package/src/utils/suggester-workers/commons-tokenizer/filter-accents-to-lower.js +0 -9
  347. package/src/utils/suggester-workers/commons-tokenizer/filter-synonyms.js +0 -10
  348. package/src/utils/suggester-workers/query-parser/query-parser-soft.js +0 -7
  349. package/src/utils/suggester-workers/query-parser/query-parser-tokenized.js +0 -31
  350. package/src/utils/suggester-workers/query-parser/query-parser-tokenized.spec.js +0 -32
@@ -0,0 +1,16 @@
1
+ import { useCallback } from 'react';
2
+
3
+ function useOnHandleChange({ handleChange, response, value }) {
4
+ const onHandlechange = useCallback(
5
+ function (valueOption) {
6
+ if (value !== valueOption) {
7
+ handleChange(response, valueOption);
8
+ }
9
+ },
10
+ [handleChange, response, value]
11
+ );
12
+
13
+ return onHandlechange;
14
+ }
15
+
16
+ export default useOnHandleChange;
@@ -0,0 +1,22 @@
1
+ import { useCallback } from 'react';
2
+
3
+ function useOptionsKeydown(options, onClick) {
4
+ const onKeyDown = useCallback(
5
+ function ({ key, index }) {
6
+ const { length } = options;
7
+
8
+ if (key === 'ArrowRight' || key === 'ArrowDown') {
9
+ const next = index === length - 1 ? 0 : index + 1;
10
+ onClick(options[next].value);
11
+ } else if (key === 'ArrowLeft' || key === 'ArrowUp') {
12
+ const next = index === 0 ? length - 1 : index - 1;
13
+ onClick(options[next].value);
14
+ }
15
+ },
16
+ [onClick, options]
17
+ );
18
+
19
+ return onKeyDown;
20
+ }
21
+
22
+ export default useOptionsKeydown;
@@ -0,0 +1,11 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ function usePrevious(value) {
4
+ const ref = useRef();
5
+ useEffect(() => {
6
+ ref.current = value;
7
+ }, [value]);
8
+ return ref.current;
9
+ }
10
+
11
+ export default usePrevious;
@@ -0,0 +1,70 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import * as U from '../../../utils/lib';
3
+ import { interpret } from '../../../utils/to-expose/interpret';
4
+ import './controls.scss';
5
+
6
+ const Controls = ({ Component, props }) => {
7
+ // handle responses & cells
8
+ const {
9
+ response,
10
+ responses,
11
+ cells,
12
+ components,
13
+ preferences,
14
+ missingResponse,
15
+ savingType,
16
+ } = props;
17
+ // savingType or preferences[preferences.length-1]?
18
+ const [applyControls, setApplyControls] = useState(() =>
19
+ U.hasToCleanMissing(savingType)({ response, responses, cells, components })
20
+ );
21
+
22
+ useEffect(() => {
23
+ if (!applyControls) {
24
+ if (
25
+ U.hasToCleanMissing(savingType)({
26
+ response,
27
+ responses,
28
+ cells,
29
+ components,
30
+ })
31
+ ) {
32
+ setApplyControls(true);
33
+ }
34
+ }
35
+ }, [response, responses, cells, components, applyControls, savingType]);
36
+
37
+ const hasMissingResponse =
38
+ U.getResponseByPreference(preferences)(missingResponse) !== null;
39
+
40
+ const { controls, features, bindings } = props;
41
+ const featuresWithoutMD = features.filter((f) => f !== 'MD');
42
+ const filteredControls =
43
+ (!applyControls && !hasMissingResponse) || !controls
44
+ ? []
45
+ : controls.filter((control) => {
46
+ const { bindingDependencies, control: formula } = control;
47
+ const reducedBindings = (bindingDependencies || []).reduce(
48
+ (acc, bD) => ({ ...acc, [bD]: bindings[bD] }),
49
+ {}
50
+ );
51
+ const vectorialBindings = U.buildVectorialBindings(reducedBindings);
52
+ return (
53
+ interpret(featuresWithoutMD)(vectorialBindings)(formula) !== true
54
+ );
55
+ }, []);
56
+ return (
57
+ <>
58
+ <Component {...props} />
59
+ <div className="lunatic-controls">
60
+ {filteredControls.map(({ id, errorMessage }) => (
61
+ <div key={`control-${id}`} className="lunatic-control">
62
+ {errorMessage}
63
+ </div>
64
+ ))}
65
+ </div>
66
+ </>
67
+ );
68
+ };
69
+
70
+ export default Controls;
@@ -0,0 +1,6 @@
1
+ .lunatic-controls {
2
+ .lunatic-control {
3
+ margin-top: 1em;
4
+ color: red;
5
+ }
6
+ }
@@ -0,0 +1 @@
1
+ export { default } from './component';
@@ -0,0 +1,33 @@
1
+ import compareAsc from 'date-fns/compareAsc';
2
+ import format from 'date-fns/format';
3
+
4
+ export const minMaxValidatorDatepicker =
5
+ ({ min, max, id }) =>
6
+ (value) => {
7
+ const errorMessage = getMessage(min, max, value);
8
+ if (errorMessage) return { id: `control-${id}`, errorMessage };
9
+ return null;
10
+ };
11
+
12
+ const getMessage = (min, max, value) => {
13
+ if (!value) {
14
+ return undefined;
15
+ }
16
+ const dateFormat = 'dd/MM/yyyy';
17
+ const date = new Date(value);
18
+ if (isNaN(Date.parse(min))) return undefined;
19
+ if (isNaN(Date.parse(max))) return undefined;
20
+ const minDate = new Date(min);
21
+ const maxDate = new Date(max);
22
+ const minDateAsString = minDate ? format(minDate, dateFormat) : '';
23
+ const maxDateAsString = maxDate ? format(maxDate, dateFormat) : '';
24
+ if (!min && isDef(max) && compareAsc(date, maxDate) > 0)
25
+ return `La date doit être inférieure au ${maxDateAsString}`;
26
+ else if (isDef(min) && !max && compareAsc(date, minDate) > 0)
27
+ return `La date doit être supérieure au ${minDateAsString}`;
28
+ else if (isDef(min) && isDef(max) && (date < minDate || date > maxDate))
29
+ return `La date doit être comprise entre le ${minDateAsString} et le ${maxDateAsString}`;
30
+ return undefined;
31
+ };
32
+
33
+ const isDef = (d) => d;
@@ -0,0 +1,16 @@
1
+ import { minMaxValidatorInputNumber } from './input-number';
2
+ import { minMaxValidatorDatepicker } from './datepicker';
3
+ import * as U from '../../../../utils/lib';
4
+
5
+ export const getTypeControls = (props) => {
6
+ const { min, max, value, response, preferences, componentType, id } = props;
7
+ const v =
8
+ value || value === null
9
+ ? value
10
+ : U.getResponseByPreference(preferences)(response);
11
+ if (componentType === 'InputNumber')
12
+ return minMaxValidatorInputNumber({ id, min, max })(v);
13
+ if (componentType === 'Datepicker')
14
+ return minMaxValidatorDatepicker({ id, min, max })(v);
15
+ return null;
16
+ };
@@ -0,0 +1,23 @@
1
+ export const minMaxValidatorInputNumber =
2
+ ({ min, max, id }) =>
3
+ (value) => {
4
+ const errorMessage = getMessage(min, max, value);
5
+ if (errorMessage) return { id: `control-${id}`, errorMessage };
6
+ return null;
7
+ };
8
+
9
+ const getMessage = (min, max, value) => {
10
+ if (!value) {
11
+ return undefined;
12
+ }
13
+ const valueNumber = Number(value);
14
+ if (!min && isDef(max) && valueNumber > max)
15
+ return `La valeur doit être inférieure à ${max}`;
16
+ else if (isDef(min) && !max && valueNumber < min)
17
+ return `La valeur doit être supérieure à ${min}`;
18
+ else if (isDef(min) && isDef(max) && (valueNumber < min || valueNumber > max))
19
+ return `La valeur doit être comprise entre ${min} et ${max}`;
20
+ return undefined;
21
+ };
22
+
23
+ const isDef = (number) => number || number === 0;
@@ -1 +1 @@
1
- export { default } from './wrapper';
1
+ export { default } from './wrapper';
@@ -1,7 +1,7 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import KeyboardEventHandler from 'react-keyboard-event-handler';
3
- import Button from '../button';
4
- import * as U from '../../utils/lib';
3
+ import Button from '../../button';
4
+ import * as U from '../../../utils/lib';
5
5
  import './missing.scss';
6
6
 
7
7
  const Missing = ({ Component, props }) => {
@@ -20,6 +20,8 @@ const Missing = ({ Component, props }) => {
20
20
  savingType,
21
21
  bindings,
22
22
  shortcut,
23
+ componentType,
24
+ missingLoopIteration,
23
25
  } = props;
24
26
 
25
27
  const buttonState = U.getResponseByPreference(preferences)(missingResponse);
@@ -57,19 +59,44 @@ const Missing = ({ Component, props }) => {
57
59
 
58
60
  const onClick = (value) => () => {
59
61
  const isSameValue = buttonState === value;
60
- const newValue = isSameValue ? null : value;
61
- const toClean = getVarsToClean();
62
- if (Object.keys(toClean)) {
63
- handleChange(toClean);
64
- if (U.isFunction(missingStrategy) && !isSameValue)
65
- missingStrategy({ ...bindings, ...toClean });
66
- } else {
67
- if (U.isFunction(missingStrategy) && !isSameValue)
68
- missingStrategy(bindings);
62
+ if (!isSameValue) {
63
+ const toClean = getVarsToClean();
64
+ if (Object.keys(toClean)) {
65
+ const { missingLoopIteration, currentPage } = props;
66
+ const currentIterationIndex = getCurrentIterationIndex({
67
+ currentPage,
68
+ missingLoopIteration,
69
+ });
70
+ handleChange(toClean);
71
+ if (U.isFunction(missingStrategy)) {
72
+ const { fullBindings } = props;
73
+ const toHandle = getVarsToHandle({
74
+ toClean,
75
+ fullBindings,
76
+ currentIterationIndex,
77
+ });
78
+ const missingBindings = getMissingBindings({
79
+ currentIterationIndex,
80
+ bindings,
81
+ fullBindings,
82
+ toHandle,
83
+ });
84
+ missingStrategy(missingBindings);
85
+ }
86
+ } else {
87
+ if (U.isFunction(missingStrategy)) missingStrategy(bindings);
88
+ }
89
+ handleChange({ [U.getResponseName(missingResponse)]: value });
69
90
  }
70
- handleChange({ [U.getResponseName(missingResponse)]: newValue });
71
91
  };
72
92
 
93
+ if (
94
+ componentType === 'Loop' ||
95
+ missingLoopIteration ||
96
+ missingLoopIteration === 0
97
+ )
98
+ return <Component {...props} />;
99
+
73
100
  return (
74
101
  <div className="missing-wrapper">
75
102
  <div className="missing-component">
@@ -118,3 +145,36 @@ const Missing = ({ Component, props }) => {
118
145
  };
119
146
 
120
147
  export default Missing;
148
+
149
+ // TODO: make it recursive for Loop into Loop
150
+ const getCurrentIterationIndex = ({ currentPage, missingLoopIteration }) => {
151
+ const { currentIteration } = U.splitPage(currentPage, 1);
152
+ if (currentIteration) return currentIteration - 1;
153
+ if (missingLoopIteration || missingLoopIteration === 0)
154
+ return missingLoopIteration;
155
+ return null;
156
+ };
157
+
158
+ // TODO: make it recursive for Loop into Loop
159
+ const getVarsToHandle = ({ toClean, fullBindings, currentIterationIndex }) => {
160
+ if (currentIterationIndex || currentIterationIndex === 0) {
161
+ return Object.entries(toClean).reduce((acc, [name, value]) => {
162
+ const newValue = fullBindings[name].map((v, i) =>
163
+ i === currentIterationIndex ? value : v
164
+ );
165
+ return { ...acc, [name]: newValue };
166
+ }, {});
167
+ }
168
+ return toClean;
169
+ };
170
+
171
+ const getMissingBindings = ({
172
+ bindings,
173
+ fullBindings,
174
+ currentIterationIndex,
175
+ toHandle,
176
+ }) => {
177
+ if (currentIterationIndex || currentIterationIndex === 0)
178
+ return { ...fullBindings, ...toHandle };
179
+ return { ...bindings, ...toHandle };
180
+ };
@@ -0,0 +1 @@
1
+ export { default } from './component';
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import Missing from './missing';
3
+ import Controls from './controls';
4
+
5
+ const hasControls = (controls, componentType) =>
6
+ (Array.isArray(controls) && controls.length > 0) ||
7
+ ['InputNumber', 'Datepicker'].includes(componentType);
8
+
9
+ const componentWrapper = (Component) => (props) => {
10
+ const { missing, controls, componentType } = props;
11
+ const hasC = hasControls(controls, componentType);
12
+ if (missing && !hasC) return <Missing Component={Component} props={props} />;
13
+ if (!missing && hasC) return <Controls Component={Component} props={props} />;
14
+ if (missing && hasC) {
15
+ const ControlComponent = () => (
16
+ <Controls Component={Component} props={props} />
17
+ );
18
+ return <Missing Component={ControlComponent} props={props} />;
19
+ }
20
+ return <Component {...props} />;
21
+ };
22
+
23
+ export default componentWrapper;
@@ -1,18 +1,22 @@
1
- export { default as Breadcrumb } from './breadcrumb';
2
- export { default as Button } from './button';
3
- export * from './checkbox';
4
- export { default as Datepicker } from './datepicker';
5
- export { default as Declarations } from './declarations';
6
- export { default as Dropdown } from './dropdown';
7
- export * from './input';
8
- export { default as FilterDescription } from './filter-description';
9
- export { default as ProgressBar } from './progress-bar';
10
- export { default as Radio } from './radio';
11
- export { default as Loop } from './loop';
12
- export * from './loop-constructor';
13
- export { default as Sequence } from './sequence';
14
- export { default as Subsequence } from './subsequence';
15
- export { default as Suggester } from './suggester';
16
- export { default as Textarea } from './textarea';
17
- export { default as SuggesterLoaderWidget } from './suggester-loader-widget';
18
- export { TooltipResponse } from './tooltip';
1
+ export { default as Breadcrumb } from './breadcrumb';
2
+ export { default as Button } from './button';
3
+ export * from './checkbox';
4
+ export { default as Datepicker } from './datepicker';
5
+ export { default as Switch } from './switch';
6
+ export { default as Declarations } from './declarations';
7
+ export { default as Dropdown } from './dropdown';
8
+ export { default as Input } from './input';
9
+ export { default as InputNumber } from './input-number';
10
+ export { default as FilterDescription } from './filter-description';
11
+ export { default as Modal } from './modal';
12
+ export { default as ProgressBar } from './progress-bar';
13
+ export { default as Radio } from './radio';
14
+ export { default as Loop } from './loop';
15
+ export { default as RosterForLoop } from './loop';
16
+ export * from './loop-constructor';
17
+ export { default as Sequence } from './sequence';
18
+ export { default as Subsequence } from './subsequence';
19
+ export { default as Suggester } from './suggester';
20
+ export { default as Textarea } from './textarea';
21
+ export { default as SuggesterLoaderWidget } from './suggester-loader-widget';
22
+ export { TooltipResponse } from './tooltip';
@@ -0,0 +1,25 @@
1
+ import React, { useCallback } from 'react';
2
+ import classnames from 'classnames';
3
+ import './datepicker.scss';
4
+
5
+ function Datepicker({ disabled, readOnly, value, onChange, labelId }) {
6
+ const handleChange = useCallback(
7
+ function (e) {
8
+ const value = e.target.value;
9
+ onChange(value);
10
+ },
11
+ [onChange]
12
+ );
13
+ return (
14
+ <input
15
+ className={classnames('datepicker-lunatic', { disabled, readOnly })}
16
+ type="date"
17
+ labelledby={labelId}
18
+ readOnly={readOnly}
19
+ disabled={disabled}
20
+ value={value}
21
+ onChange={handleChange}
22
+ />
23
+ );
24
+ }
25
+ export default Datepicker;
@@ -1 +1 @@
1
- export { default } from './component';
1
+ export { default } from './lunatic-datepicker';
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import { InputContainer } from '../commons';
3
+ import Datepicker from './datepicker';
4
+ import { useOnHandleChange } from '../commons';
5
+ import './datepicker.scss';
6
+
7
+ function LunaticDatepicker({
8
+ declarations,
9
+ executeExpression,
10
+ label,
11
+ id,
12
+ response,
13
+ value,
14
+ handleChange,
15
+ disabled,
16
+ readOnly,
17
+ iteration,
18
+ bindingDependencies,
19
+ }) {
20
+ const onChange = useOnHandleChange({ handleChange, response, value });
21
+
22
+ const inputId = `lunatic-datepicker-${id}`;
23
+ const labelId = `lunatic-datepicker-label-${id}`;
24
+
25
+ return (
26
+ <InputContainer
27
+ declarations={declarations}
28
+ executeExpression={executeExpression}
29
+ label={label}
30
+ id={id}
31
+ value={value}
32
+ inputId={inputId}
33
+ labelId={labelId}
34
+ labelClassName="todo"
35
+ iteration={iteration}
36
+ bindingDependencies={bindingDependencies}
37
+ >
38
+ <Datepicker
39
+ id={inputId}
40
+ labelledBy={labelId}
41
+ value={value}
42
+ onChange={onChange}
43
+ disabled={disabled}
44
+ readOnly={readOnly}
45
+ />
46
+ </InputContainer>
47
+ );
48
+ }
49
+
50
+ export default LunaticDatepicker;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+
3
+ function Declaration({ children, type }) {
4
+ return (
5
+ <div className={`declaration-lunatic declaration-${type.toLowerCase()}`}>
6
+ {children}
7
+ </div>
8
+ );
9
+ }
10
+
11
+ export default Declaration;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import Declarations, { DECLARATION_POSITIONS } from './declarations';
3
+
4
+ function DeclarationsAfterText(props) {
5
+ return <Declarations type={DECLARATION_POSITIONS.after} {...props} />;
6
+ }
7
+
8
+ export default DeclarationsAfterText;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import Declarations, { DECLARATION_POSITIONS } from './declarations';
3
+
4
+ function DeclarationsBeforeText(props) {
5
+ return <Declarations type={DECLARATION_POSITIONS.before} {...props} />;
6
+ }
7
+
8
+ export default DeclarationsBeforeText;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import Declarations, { DECLARATION_POSITIONS } from './declarations';
3
+
4
+ function DeclarationsDetachable(props) {
5
+ return <Declarations type={DECLARATION_POSITIONS.detachable} {...props} />;
6
+ }
7
+
8
+ export default DeclarationsDetachable;
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import './declarations.scss';
3
+ import Declaration from './declaration';
4
+
5
+ export const DECLARATION_POSITIONS = {
6
+ after: 'AFTER_QUESTION_TEXT',
7
+ before: 'BEFORE_QUESTION_TEXT',
8
+ detachable: 'DETACHABLE',
9
+ };
10
+
11
+ function Declarations({ id, type, declarations, logFunction }) {
12
+ const filtered = declarations.filter(({ position }) => position === type);
13
+ if (filtered.length === 0) return null;
14
+
15
+ return (
16
+ <div id={`declarations-${id}-${type}`} className="declarations-lunatic">
17
+ {filtered.map(({ id: idD, label, declarationType }) => (
18
+ <Declaration key={`${idD}`} type={declarationType.toLowerCase()}>
19
+ {label}
20
+ </Declaration>
21
+ ))}
22
+ </div>
23
+ );
24
+ }
25
+
26
+ Declarations.defaultProps = {
27
+ type: 'AFTER_QUESTION_TEXT',
28
+ declarations: [],
29
+ features: [],
30
+ bindings: {},
31
+ };
32
+
33
+ Declarations.propTypes = {};
34
+
35
+ export default Declarations;
@@ -1 +1,4 @@
1
- export { default } from './component';
1
+ export { default, DECLARATION_POSITIONS } from './declarations';
2
+ export { default as DeclarationsBeforeText } from './declarations-before-text';
3
+ export { default as DeclarationsAfterText } from './declarations-after-text';
4
+ export { default as DeclarationsDetachable } from './declarations-detachable';
@@ -36,6 +36,7 @@ const InputDeclarationsWrapper = ({
36
36
  isInputNumber,
37
37
  numberAsTextfield,
38
38
  logFunction,
39
+ componentType,
39
40
  }) => {
40
41
  const inputRef = useRef();
41
42
  const createEventFocus = (focusIn = true) =>
@@ -46,12 +47,15 @@ const InputDeclarationsWrapper = ({
46
47
  U.getResponseName(response),
47
48
  value
48
49
  );
50
+
49
51
  const [value, setValue] = useState(() =>
50
52
  U.getResponseByPreference(preferences)(response)
51
53
  );
52
54
 
53
55
  const [messagesError, setMessagesError] = useState(
54
- validators.map((v) => v(value)).filter((m) => m !== undefined)
56
+ validators
57
+ .map((v) => v({ min, max, value, preferences, componentType, id }))
58
+ .filter((m) => m)
55
59
  );
56
60
 
57
61
  useEffect(() => {
@@ -68,17 +72,30 @@ const InputDeclarationsWrapper = ({
68
72
 
69
73
  const validate = (v) => {
70
74
  setMessagesError(
71
- validators.map((f) => f(v)).filter((m) => m !== undefined)
75
+ validators
76
+ .map((v) => v({ min, max, value: v, preferences, componentType, id }))
77
+ .filter((m) => m)
72
78
  );
73
79
  };
74
80
 
75
81
  useEffect(() => {
76
- if (isInputNumber) {
82
+ if (['InputNumber', 'Datepicker'].includes(componentType)) {
77
83
  setMessagesError(
78
- validators.map((v) => v(value)).filter((m) => m !== undefined)
84
+ validators
85
+ .map((v) => v({ min, max, value, preferences, componentType, id }))
86
+ .filter((m) => m)
79
87
  );
80
88
  }
81
- }, [value, min, max, validators, isInputNumber]);
89
+ }, [
90
+ value,
91
+ min,
92
+ max,
93
+ validators,
94
+ isInputNumber,
95
+ id,
96
+ preferences,
97
+ componentType,
98
+ ]);
82
99
 
83
100
  const handleChangeOnBlur = () => {
84
101
  const initValue = U.getResponseByPreference(preferences)(response);
@@ -143,7 +160,10 @@ const InputDeclarationsWrapper = ({
143
160
  placeholder={placeholder}
144
161
  autoComplete={autoComplete ? 'on' : 'off'}
145
162
  className={`${roleType}-lunatic ${
146
- isInputNumber && messagesError.length > 0 ? 'warning' : ''
163
+ (isInputNumber || roleType === 'datepicker') &&
164
+ messagesError.length > 0
165
+ ? 'warning'
166
+ : ''
147
167
  }`}
148
168
  style={U.buildStyleObject(style)}
149
169
  readOnly={readOnly}
@@ -154,12 +174,20 @@ const InputDeclarationsWrapper = ({
154
174
  onChange={(e) => {
155
175
  const v = e.target.value;
156
176
  if (
177
+ ([null, ''].includes(v) && value.length > 0) ||
178
+ ([null, ''].includes(value) && v.length > 0)
179
+ ) {
180
+ setValue(v);
181
+ handleChange({
182
+ [U.getResponseName(response)]: v,
183
+ });
184
+ } else if (
157
185
  // Chrome
158
186
  (Object.getPrototypeOf(e.nativeEvent).constructor.name ===
159
187
  'Event' &&
160
188
  roleType !== 'datepicker') ||
161
189
  // FF hack: impossible to handle arrow events
162
- Math.abs(v - value) === 1
190
+ (Math.abs(v - value) === 1 && isInputNumber)
163
191
  ) {
164
192
  setValue(v);
165
193
  handleChange({
@@ -197,11 +225,11 @@ const InputDeclarationsWrapper = ({
197
225
  </div>
198
226
  )}
199
227
  </div>
200
- {isInputNumber && (
201
- <div className="lunatic-input-number-errors">
202
- {messagesError.map((m, i) => (
203
- <div key={i} className="error">
204
- {m}
228
+ {messagesError.length > 0 && (
229
+ <div className="lunatic-controls">
230
+ {messagesError.map(({ id, errorMessage }) => (
231
+ <div key={`control-${id}`} className="lunatic-control">
232
+ {errorMessage}
205
233
  </div>
206
234
  ))}
207
235
  </div>