@toptal/picasso-forms 66.3.2 → 67.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (552) hide show
  1. package/{Autocomplete → dist-package/src/Autocomplete}/Autocomplete.d.ts +1 -0
  2. package/dist-package/src/Autocomplete/Autocomplete.d.ts.map +1 -0
  3. package/dist-package/src/Autocomplete/Autocomplete.js.map +1 -0
  4. package/{Autocomplete → dist-package/src/Autocomplete}/index.d.ts +1 -0
  5. package/dist-package/src/Autocomplete/index.d.ts.map +1 -0
  6. package/dist-package/src/Autocomplete/index.js.map +1 -0
  7. package/{AvatarUpload → dist-package/src/AvatarUpload}/AvatarUpload.d.ts +1 -0
  8. package/dist-package/src/AvatarUpload/AvatarUpload.d.ts.map +1 -0
  9. package/dist-package/src/AvatarUpload/AvatarUpload.js.map +1 -0
  10. package/{AvatarUpload → dist-package/src/AvatarUpload}/index.d.ts +1 -0
  11. package/dist-package/src/AvatarUpload/index.d.ts.map +1 -0
  12. package/dist-package/src/AvatarUpload/index.js.map +1 -0
  13. package/{ButtonCheckbox → dist-package/src/ButtonCheckbox}/ButtonCheckbox.d.ts +1 -0
  14. package/dist-package/src/ButtonCheckbox/ButtonCheckbox.d.ts.map +1 -0
  15. package/dist-package/src/ButtonCheckbox/ButtonCheckbox.js.map +1 -0
  16. package/{ButtonCheckbox → dist-package/src/ButtonCheckbox}/index.d.ts +1 -0
  17. package/dist-package/src/ButtonCheckbox/index.d.ts.map +1 -0
  18. package/dist-package/src/ButtonCheckbox/index.js.map +1 -0
  19. package/{ButtonRadio → dist-package/src/ButtonRadio}/ButtonRadio.d.ts +1 -0
  20. package/dist-package/src/ButtonRadio/ButtonRadio.d.ts.map +1 -0
  21. package/dist-package/src/ButtonRadio/ButtonRadio.js.map +1 -0
  22. package/{ButtonRadio → dist-package/src/ButtonRadio}/index.d.ts +1 -0
  23. package/dist-package/src/ButtonRadio/index.d.ts.map +1 -0
  24. package/dist-package/src/ButtonRadio/index.js.map +1 -0
  25. package/{Checkbox → dist-package/src/Checkbox}/Checkbox.d.ts +1 -0
  26. package/dist-package/src/Checkbox/Checkbox.d.ts.map +1 -0
  27. package/dist-package/src/Checkbox/Checkbox.js.map +1 -0
  28. package/dist-package/src/Checkbox/index.d.ts +3 -0
  29. package/dist-package/src/Checkbox/index.d.ts.map +1 -0
  30. package/dist-package/src/Checkbox/index.js.map +1 -0
  31. package/{CheckboxGroup → dist-package/src/CheckboxGroup}/CheckboxGroup.d.ts +1 -0
  32. package/dist-package/src/CheckboxGroup/CheckboxGroup.d.ts.map +1 -0
  33. package/dist-package/src/CheckboxGroup/CheckboxGroup.js.map +1 -0
  34. package/{CheckboxGroup → dist-package/src/CheckboxGroup}/CheckboxGroupContext.d.ts +1 -0
  35. package/dist-package/src/CheckboxGroup/CheckboxGroupContext.d.ts.map +1 -0
  36. package/dist-package/src/CheckboxGroup/CheckboxGroupContext.js.map +1 -0
  37. package/{CheckboxGroup → dist-package/src/CheckboxGroup}/index.d.ts +1 -0
  38. package/dist-package/src/CheckboxGroup/index.d.ts.map +1 -0
  39. package/dist-package/src/CheckboxGroup/index.js.map +1 -0
  40. package/{DatePicker → dist-package/src/DatePicker}/DatePicker.d.ts +1 -0
  41. package/dist-package/src/DatePicker/DatePicker.d.ts.map +1 -0
  42. package/dist-package/src/DatePicker/DatePicker.js.map +1 -0
  43. package/{DatePicker → dist-package/src/DatePicker}/index.d.ts +1 -0
  44. package/dist-package/src/DatePicker/index.d.ts.map +1 -0
  45. package/dist-package/src/DatePicker/index.js.map +1 -0
  46. package/{Dropzone → dist-package/src/Dropzone}/Dropzone.d.ts +1 -0
  47. package/dist-package/src/Dropzone/Dropzone.d.ts.map +1 -0
  48. package/dist-package/src/Dropzone/Dropzone.js.map +1 -0
  49. package/{Dropzone → dist-package/src/Dropzone}/index.d.ts +1 -0
  50. package/dist-package/src/Dropzone/index.d.ts.map +1 -0
  51. package/dist-package/src/Dropzone/index.js.map +1 -0
  52. package/{Field → dist-package/src/Field}/Field.d.ts +1 -0
  53. package/dist-package/src/Field/Field.d.ts.map +1 -0
  54. package/dist-package/src/Field/Field.js.map +1 -0
  55. package/{Field → dist-package/src/Field}/index.d.ts +1 -0
  56. package/dist-package/src/Field/index.d.ts.map +1 -0
  57. package/dist-package/src/Field/index.js.map +1 -0
  58. package/dist-package/src/FieldBase/index.d.ts +2 -0
  59. package/dist-package/src/FieldBase/index.d.ts.map +1 -0
  60. package/dist-package/src/FieldBase/index.js.map +1 -0
  61. package/dist-package/src/FieldBase/types.d.ts +6 -0
  62. package/dist-package/src/FieldBase/types.d.ts.map +1 -0
  63. package/{FieldBase → dist-package/src/FieldBase}/types.js.map +1 -1
  64. package/{FieldLabel → dist-package/src/FieldLabel}/FieldLabel.d.ts +1 -0
  65. package/dist-package/src/FieldLabel/FieldLabel.d.ts.map +1 -0
  66. package/dist-package/src/FieldLabel/FieldLabel.js.map +1 -0
  67. package/{FieldLabel → dist-package/src/FieldLabel}/index.d.ts +1 -0
  68. package/dist-package/src/FieldLabel/index.d.ts.map +1 -0
  69. package/dist-package/src/FieldLabel/index.js.map +1 -0
  70. package/{FieldWrapper → dist-package/src/FieldWrapper}/FieldWrapper.d.ts +1 -0
  71. package/dist-package/src/FieldWrapper/FieldWrapper.d.ts.map +1 -0
  72. package/dist-package/src/FieldWrapper/FieldWrapper.js.map +1 -0
  73. package/{FieldWrapper → dist-package/src/FieldWrapper}/index.d.ts +1 -0
  74. package/dist-package/src/FieldWrapper/index.d.ts.map +1 -0
  75. package/dist-package/src/FieldWrapper/index.js.map +1 -0
  76. package/{FileInput → dist-package/src/FileInput}/FileInput.d.ts +1 -0
  77. package/dist-package/src/FileInput/FileInput.d.ts.map +1 -0
  78. package/dist-package/src/FileInput/FileInput.js.map +1 -0
  79. package/{FileInput → dist-package/src/FileInput}/index.d.ts +1 -0
  80. package/dist-package/src/FileInput/index.d.ts.map +1 -0
  81. package/dist-package/src/FileInput/index.js.map +1 -0
  82. package/{Form → dist-package/src/Form}/Form.d.ts +1 -0
  83. package/dist-package/src/Form/Form.d.ts.map +1 -0
  84. package/{Form → dist-package/src/Form}/Form.js +1 -1
  85. package/dist-package/src/Form/Form.js.map +1 -0
  86. package/{Form → dist-package/src/Form}/FormContext.d.ts +1 -0
  87. package/dist-package/src/Form/FormContext.d.ts.map +1 -0
  88. package/dist-package/src/Form/FormContext.js.map +1 -0
  89. package/{Form → dist-package/src/Form}/FormRenderer.d.ts +1 -0
  90. package/dist-package/src/Form/FormRenderer.d.ts.map +1 -0
  91. package/dist-package/src/Form/FormRenderer.js.map +1 -0
  92. package/{Form → dist-package/src/Form}/index.d.ts +1 -0
  93. package/dist-package/src/Form/index.d.ts.map +1 -0
  94. package/dist-package/src/Form/index.js.map +1 -0
  95. package/{Form → dist-package/src/Form}/mutators/index.d.ts +1 -0
  96. package/dist-package/src/Form/mutators/index.d.ts.map +1 -0
  97. package/dist-package/src/Form/mutators/index.js.map +1 -0
  98. package/{Form → dist-package/src/Form}/mutators/set-active-field-touched.d.ts +1 -0
  99. package/dist-package/src/Form/mutators/set-active-field-touched.d.ts.map +1 -0
  100. package/dist-package/src/Form/mutators/set-active-field-touched.js.map +1 -0
  101. package/{Form → dist-package/src/Form}/mutators/set-has-multiline-counter.d.ts +1 -0
  102. package/dist-package/src/Form/mutators/set-has-multiline-counter.d.ts.map +1 -0
  103. package/dist-package/src/Form/mutators/set-has-multiline-counter.js.map +1 -0
  104. package/{FormCompound → dist-package/src/FormCompound}/index.d.ts +7 -6
  105. package/dist-package/src/FormCompound/index.d.ts.map +1 -0
  106. package/dist-package/src/FormCompound/index.js.map +1 -0
  107. package/{FormConfig → dist-package/src/FormConfig}/FormConfig.d.ts +1 -0
  108. package/dist-package/src/FormConfig/FormConfig.d.ts.map +1 -0
  109. package/dist-package/src/FormConfig/FormConfig.js.map +1 -0
  110. package/dist-package/src/FormConfig/index.d.ts +2 -0
  111. package/dist-package/src/FormConfig/index.d.ts.map +1 -0
  112. package/dist-package/src/FormConfig/index.js.map +1 -0
  113. package/{Input → dist-package/src/Input}/Input.d.ts +1 -0
  114. package/dist-package/src/Input/Input.d.ts.map +1 -0
  115. package/dist-package/src/Input/Input.js.map +1 -0
  116. package/{Input → dist-package/src/Input}/index.d.ts +1 -0
  117. package/dist-package/src/Input/index.d.ts.map +1 -0
  118. package/dist-package/src/Input/index.js.map +1 -0
  119. package/{InputField → dist-package/src/InputField}/InputField.d.ts +1 -0
  120. package/dist-package/src/InputField/InputField.d.ts.map +1 -0
  121. package/dist-package/src/InputField/InputField.js.map +1 -0
  122. package/{InputField → dist-package/src/InputField}/index.d.ts +1 -0
  123. package/dist-package/src/InputField/index.d.ts.map +1 -0
  124. package/dist-package/src/InputField/index.js.map +1 -0
  125. package/{NumberInput → dist-package/src/NumberInput}/NumberInput.d.ts +1 -0
  126. package/dist-package/src/NumberInput/NumberInput.d.ts.map +1 -0
  127. package/dist-package/src/NumberInput/NumberInput.js.map +1 -0
  128. package/dist-package/src/NumberInput/index.d.ts +3 -0
  129. package/dist-package/src/NumberInput/index.d.ts.map +1 -0
  130. package/dist-package/src/NumberInput/index.js.map +1 -0
  131. package/{PasswordInput → dist-package/src/PasswordInput}/FieldRenderer.d.ts +1 -0
  132. package/dist-package/src/PasswordInput/FieldRenderer.d.ts.map +1 -0
  133. package/dist-package/src/PasswordInput/FieldRenderer.js.map +1 -0
  134. package/{PasswordInput → dist-package/src/PasswordInput}/PasswordInput.d.ts +1 -0
  135. package/dist-package/src/PasswordInput/PasswordInput.d.ts.map +1 -0
  136. package/dist-package/src/PasswordInput/PasswordInput.js.map +1 -0
  137. package/{PasswordInput → dist-package/src/PasswordInput}/index.d.ts +1 -0
  138. package/dist-package/src/PasswordInput/index.d.ts.map +1 -0
  139. package/dist-package/src/PasswordInput/index.js.map +1 -0
  140. package/{PasswordInput → dist-package/src/PasswordInput}/validators.d.ts +1 -0
  141. package/dist-package/src/PasswordInput/validators.d.ts.map +1 -0
  142. package/dist-package/src/PasswordInput/validators.js.map +1 -0
  143. package/{Radio → dist-package/src/Radio}/Radio.d.ts +1 -0
  144. package/dist-package/src/Radio/Radio.d.ts.map +1 -0
  145. package/dist-package/src/Radio/Radio.js.map +1 -0
  146. package/{Radio → dist-package/src/Radio}/index.d.ts +1 -0
  147. package/dist-package/src/Radio/index.d.ts.map +1 -0
  148. package/dist-package/src/Radio/index.js.map +1 -0
  149. package/{RadioGroup → dist-package/src/RadioGroup}/RadioGroup.d.ts +1 -0
  150. package/dist-package/src/RadioGroup/RadioGroup.d.ts.map +1 -0
  151. package/dist-package/src/RadioGroup/RadioGroup.js.map +1 -0
  152. package/{RadioGroup → dist-package/src/RadioGroup}/RadioGroupContext.d.ts +1 -0
  153. package/dist-package/src/RadioGroup/RadioGroupContext.d.ts.map +1 -0
  154. package/dist-package/src/RadioGroup/RadioGroupContext.js.map +1 -0
  155. package/{RadioGroup → dist-package/src/RadioGroup}/index.d.ts +1 -0
  156. package/dist-package/src/RadioGroup/index.d.ts.map +1 -0
  157. package/dist-package/src/RadioGroup/index.js.map +1 -0
  158. package/{Rating → dist-package/src/Rating}/Rating.d.ts +1 -0
  159. package/dist-package/src/Rating/Rating.d.ts.map +1 -0
  160. package/dist-package/src/Rating/Rating.js.map +1 -0
  161. package/{Rating → dist-package/src/Rating}/index.d.ts +1 -0
  162. package/dist-package/src/Rating/index.d.ts.map +1 -0
  163. package/dist-package/src/Rating/index.js.map +1 -0
  164. package/{RichTextEditor → dist-package/src/RichTextEditor}/RichTextEditor.d.ts +2 -1
  165. package/dist-package/src/RichTextEditor/RichTextEditor.d.ts.map +1 -0
  166. package/dist-package/src/RichTextEditor/RichTextEditor.js.map +1 -0
  167. package/dist-package/src/RichTextEditor/hooks/index.d.ts +2 -0
  168. package/dist-package/src/RichTextEditor/hooks/index.d.ts.map +1 -0
  169. package/dist-package/src/RichTextEditor/hooks/index.js.map +1 -0
  170. package/{RichTextEditor → dist-package/src/RichTextEditor}/hooks/use-enforce-highlight-autofill.d.ts +1 -0
  171. package/dist-package/src/RichTextEditor/hooks/use-enforce-highlight-autofill.d.ts.map +1 -0
  172. package/dist-package/src/RichTextEditor/hooks/use-enforce-highlight-autofill.js.map +1 -0
  173. package/{RichTextEditor → dist-package/src/RichTextEditor}/index.d.ts +1 -0
  174. package/dist-package/src/RichTextEditor/index.d.ts.map +1 -0
  175. package/dist-package/src/RichTextEditor/index.js.map +1 -0
  176. package/{Select → dist-package/src/Select}/Select.d.ts +1 -0
  177. package/dist-package/src/Select/Select.d.ts.map +1 -0
  178. package/{Select → dist-package/src/Select}/Select.js +1 -1
  179. package/dist-package/src/Select/Select.js.map +1 -0
  180. package/dist-package/src/Select/index.d.ts +3 -0
  181. package/dist-package/src/Select/index.d.ts.map +1 -0
  182. package/dist-package/src/Select/index.js.map +1 -0
  183. package/{SubmitButton → dist-package/src/SubmitButton}/SubmitButton.d.ts +2 -2
  184. package/dist-package/src/SubmitButton/SubmitButton.d.ts.map +1 -0
  185. package/dist-package/src/SubmitButton/SubmitButton.js.map +1 -0
  186. package/{SubmitButton → dist-package/src/SubmitButton}/index.d.ts +1 -0
  187. package/dist-package/src/SubmitButton/index.d.ts.map +1 -0
  188. package/dist-package/src/SubmitButton/index.js.map +1 -0
  189. package/{Switch → dist-package/src/Switch}/Switch.d.ts +1 -0
  190. package/dist-package/src/Switch/Switch.d.ts.map +1 -0
  191. package/dist-package/src/Switch/Switch.js.map +1 -0
  192. package/{Switch → dist-package/src/Switch}/index.d.ts +1 -0
  193. package/dist-package/src/Switch/index.d.ts.map +1 -0
  194. package/dist-package/src/Switch/index.js.map +1 -0
  195. package/{TagSelector → dist-package/src/TagSelector}/TagSelector.d.ts +1 -0
  196. package/dist-package/src/TagSelector/TagSelector.d.ts.map +1 -0
  197. package/dist-package/src/TagSelector/TagSelector.js.map +1 -0
  198. package/dist-package/src/TagSelector/index.d.ts +3 -0
  199. package/dist-package/src/TagSelector/index.d.ts.map +1 -0
  200. package/dist-package/src/TagSelector/index.js.map +1 -0
  201. package/{TimePicker → dist-package/src/TimePicker}/TimePicker.d.ts +1 -0
  202. package/dist-package/src/TimePicker/TimePicker.d.ts.map +1 -0
  203. package/dist-package/src/TimePicker/TimePicker.js.map +1 -0
  204. package/{TimePicker → dist-package/src/TimePicker}/index.d.ts +1 -0
  205. package/dist-package/src/TimePicker/index.d.ts.map +1 -0
  206. package/dist-package/src/TimePicker/index.js.map +1 -0
  207. package/{index.d.ts → dist-package/src/index.d.ts} +10 -0
  208. package/dist-package/src/index.d.ts.map +1 -0
  209. package/{index.js → dist-package/src/index.js} +3 -0
  210. package/dist-package/src/index.js.map +1 -0
  211. package/{utils → dist-package/src/utils}/flat-map.d.ts +1 -0
  212. package/dist-package/src/utils/flat-map.d.ts.map +1 -0
  213. package/dist-package/src/utils/flat-map.js.map +1 -0
  214. package/{utils → dist-package/src/utils}/form-values-change-decorator/form-values-change-decorator.d.ts +1 -0
  215. package/dist-package/src/utils/form-values-change-decorator/form-values-change-decorator.d.ts.map +1 -0
  216. package/dist-package/src/utils/form-values-change-decorator/form-values-change-decorator.js.map +1 -0
  217. package/{utils → dist-package/src/utils}/form-values-change-decorator/index.d.ts +1 -0
  218. package/dist-package/src/utils/form-values-change-decorator/index.d.ts.map +1 -0
  219. package/dist-package/src/utils/form-values-change-decorator/index.js.map +1 -0
  220. package/{utils → dist-package/src/utils}/index.d.ts +1 -0
  221. package/dist-package/src/utils/index.d.ts.map +1 -0
  222. package/dist-package/src/utils/index.js.map +1 -0
  223. package/{utils → dist-package/src/utils}/scroll-to-error-decorator.d.ts +1 -0
  224. package/dist-package/src/utils/scroll-to-error-decorator.d.ts.map +1 -0
  225. package/dist-package/src/utils/scroll-to-error-decorator.js.map +1 -0
  226. package/{utils → dist-package/src/utils}/scroll-to.d.ts +1 -0
  227. package/dist-package/src/utils/scroll-to.d.ts.map +1 -0
  228. package/dist-package/src/utils/scroll-to.js.map +1 -0
  229. package/{utils → dist-package/src/utils}/use-field-validation/index.d.ts +1 -0
  230. package/dist-package/src/utils/use-field-validation/index.d.ts.map +1 -0
  231. package/dist-package/src/utils/use-field-validation/index.js.map +1 -0
  232. package/{utils → dist-package/src/utils}/use-field-validation/use-field-validation.d.ts +1 -0
  233. package/dist-package/src/utils/use-field-validation/use-field-validation.d.ts.map +1 -0
  234. package/dist-package/src/utils/use-field-validation/use-field-validation.js.map +1 -0
  235. package/{utils → dist-package/src/utils}/use-form-auto-save/index.d.ts +1 -0
  236. package/dist-package/src/utils/use-form-auto-save/index.d.ts.map +1 -0
  237. package/dist-package/src/utils/use-form-auto-save/index.js.map +1 -0
  238. package/{utils → dist-package/src/utils}/use-form-auto-save/use-form-auto-save.d.ts +1 -0
  239. package/dist-package/src/utils/use-form-auto-save/use-form-auto-save.d.ts.map +1 -0
  240. package/dist-package/src/utils/use-form-auto-save/use-form-auto-save.js.map +1 -0
  241. package/{utils → dist-package/src/utils}/use-form-input-reset/index.d.ts +1 -0
  242. package/dist-package/src/utils/use-form-input-reset/index.d.ts.map +1 -0
  243. package/dist-package/src/utils/use-form-input-reset/index.js.map +1 -0
  244. package/{utils → dist-package/src/utils}/use-form-input-reset/use-form-input-reset.d.ts +1 -0
  245. package/dist-package/src/utils/use-form-input-reset/use-form-input-reset.d.ts.map +1 -0
  246. package/dist-package/src/utils/use-form-input-reset/use-form-input-reset.js.map +1 -0
  247. package/{utils → dist-package/src/utils}/validators.d.ts +1 -0
  248. package/dist-package/src/utils/validators.d.ts.map +1 -0
  249. package/dist-package/src/utils/validators.js.map +1 -0
  250. package/package.json +24 -11
  251. package/src/Autocomplete/Autocomplete.tsx +37 -0
  252. package/src/Autocomplete/index.ts +1 -0
  253. package/src/AvatarUpload/AvatarUpload.tsx +92 -0
  254. package/src/AvatarUpload/index.ts +1 -0
  255. package/src/ButtonCheckbox/ButtonCheckbox.tsx +63 -0
  256. package/src/ButtonCheckbox/index.ts +1 -0
  257. package/src/ButtonRadio/ButtonRadio.tsx +25 -0
  258. package/src/ButtonRadio/index.ts +1 -0
  259. package/src/Checkbox/Checkbox.tsx +79 -0
  260. package/src/Checkbox/__snapshots__/test.tsx.snap +259 -0
  261. package/src/Checkbox/index.ts +2 -0
  262. package/src/Checkbox/test.tsx +92 -0
  263. package/src/CheckboxGroup/CheckboxGroup.tsx +47 -0
  264. package/src/CheckboxGroup/CheckboxGroupContext.ts +3 -0
  265. package/src/CheckboxGroup/index.ts +3 -0
  266. package/src/CheckboxGroup/test.tsx +36 -0
  267. package/src/DatePicker/DatePicker.tsx +40 -0
  268. package/src/DatePicker/index.ts +1 -0
  269. package/src/Dropzone/Dropzone.tsx +102 -0
  270. package/src/Dropzone/index.ts +6 -0
  271. package/src/Field/Field.tsx +196 -0
  272. package/src/Field/index.ts +2 -0
  273. package/src/FieldBase/index.ts +1 -0
  274. package/src/FieldBase/types.ts +23 -0
  275. package/src/FieldLabel/FieldLabel.tsx +64 -0
  276. package/src/FieldLabel/__snapshots__/test.tsx.snap +21 -0
  277. package/src/FieldLabel/index.ts +2 -0
  278. package/src/FieldLabel/test.tsx +52 -0
  279. package/src/FieldWrapper/FieldWrapper.tsx +48 -0
  280. package/src/FieldWrapper/index.ts +6 -0
  281. package/src/FieldWrapper/story/index.jsx +153 -0
  282. package/src/FieldWrapper/test.tsx +32 -0
  283. package/src/FileInput/FileInput.tsx +85 -0
  284. package/src/FileInput/index.ts +1 -0
  285. package/src/Form/Form.tsx +161 -0
  286. package/src/Form/FormContext.ts +38 -0
  287. package/src/Form/FormRenderer.tsx +38 -0
  288. package/src/Form/__snapshots__/test.tsx.snap +140 -0
  289. package/src/Form/index.ts +2 -0
  290. package/src/Form/mutators/index.ts +2 -0
  291. package/src/Form/mutators/set-active-field-touched.ts +16 -0
  292. package/src/Form/mutators/set-has-multiline-counter.ts +16 -0
  293. package/src/Form/story/AutoSave.example.tsx +120 -0
  294. package/src/Form/story/AvatarUpload.example.tsx +81 -0
  295. package/src/Form/story/BackendCommunication.example.tsx +137 -0
  296. package/src/Form/story/CustomFormLevelConfiguration.example.tsx +35 -0
  297. package/src/Form/story/CustomValidator.example.tsx +53 -0
  298. package/src/Form/story/Default.example.tsx +218 -0
  299. package/src/Form/story/Dropzone.example.tsx +42 -0
  300. package/src/Form/story/FieldRequirements.example.tsx +58 -0
  301. package/src/Form/story/FileInput.example.tsx +43 -0
  302. package/src/Form/story/HighlightAutofill.example.tsx +96 -0
  303. package/src/Form/story/Horizontal.example.tsx +281 -0
  304. package/src/Form/story/HorizontalLabelWidth.example.tsx +26 -0
  305. package/src/Form/story/NoScrolling.example.tsx +42 -0
  306. package/src/Form/story/ParseInput.example.tsx +31 -0
  307. package/src/Form/story/RichTextEditor.example.tsx +32 -0
  308. package/src/Form/story/Status.example.tsx +35 -0
  309. package/src/Form/story/TitleCase.example.tsx +194 -0
  310. package/src/Form/story/ValidateOnSubmit.example.tsx +99 -0
  311. package/src/Form/story/index.jsx +289 -0
  312. package/src/Form/test.tsx +202 -0
  313. package/src/FormCompound/index.ts +51 -0
  314. package/src/FormConfig/FormConfig.ts +35 -0
  315. package/src/FormConfig/index.ts +1 -0
  316. package/src/FormConfig/test.tsx +44 -0
  317. package/src/Input/Input.tsx +80 -0
  318. package/src/Input/index.ts +2 -0
  319. package/src/Input/test.tsx +35 -0
  320. package/src/InputField/InputField.tsx +71 -0
  321. package/src/InputField/index.ts +1 -0
  322. package/src/InputField/test.ts +105 -0
  323. package/src/NumberInput/NumberInput.tsx +58 -0
  324. package/src/NumberInput/index.ts +2 -0
  325. package/src/PasswordInput/FieldRenderer.tsx +36 -0
  326. package/src/PasswordInput/PasswordInput.tsx +144 -0
  327. package/src/PasswordInput/index.ts +1 -0
  328. package/src/PasswordInput/test.ts +45 -0
  329. package/src/PasswordInput/validators.ts +28 -0
  330. package/src/Radio/Radio.tsx +25 -0
  331. package/src/Radio/__snapshots__/test.tsx.snap +235 -0
  332. package/src/Radio/index.ts +1 -0
  333. package/src/Radio/test.tsx +49 -0
  334. package/src/RadioGroup/RadioGroup.tsx +53 -0
  335. package/src/RadioGroup/RadioGroupContext.ts +3 -0
  336. package/src/RadioGroup/index.ts +3 -0
  337. package/src/RadioGroup/test.tsx +36 -0
  338. package/src/Rating/Rating.tsx +95 -0
  339. package/src/Rating/__snapshots__/test.tsx.snap +226 -0
  340. package/src/Rating/index.ts +1 -0
  341. package/src/Rating/test.tsx +171 -0
  342. package/src/RichTextEditor/RichTextEditor.tsx +87 -0
  343. package/{RichTextEditor/hooks/index.d.ts → src/RichTextEditor/hooks/index.ts} +1 -1
  344. package/src/RichTextEditor/hooks/use-enforce-highlight-autofill.test.tsx +67 -0
  345. package/src/RichTextEditor/hooks/use-enforce-highlight-autofill.ts +48 -0
  346. package/src/RichTextEditor/index.ts +1 -0
  347. package/src/Select/Select.tsx +55 -0
  348. package/src/Select/index.ts +2 -0
  349. package/src/SubmitButton/SubmitButton.tsx +71 -0
  350. package/src/SubmitButton/index.ts +6 -0
  351. package/src/SubmitButton/story/ButtonTypes.example.tsx +45 -0
  352. package/src/SubmitButton/story/Default.example.tsx +16 -0
  353. package/src/SubmitButton/story/index.jsx +35 -0
  354. package/src/Switch/Switch.tsx +40 -0
  355. package/src/Switch/index.ts +1 -0
  356. package/src/TagSelector/TagSelector.tsx +41 -0
  357. package/src/TagSelector/index.ts +2 -0
  358. package/src/TimePicker/TimePicker.tsx +43 -0
  359. package/src/TimePicker/index.ts +1 -0
  360. package/src/index.ts +86 -0
  361. package/src/story/Deserialization.example.tsx +40 -0
  362. package/src/story/FormSpy.example.tsx +50 -0
  363. package/src/story/index.jsx +39 -0
  364. package/src/utils/flat-map.ts +4 -0
  365. package/src/utils/form-values-change-decorator/form-values-change-decorator.ts +64 -0
  366. package/src/utils/form-values-change-decorator/index.ts +3 -0
  367. package/src/utils/form-values-change-decorator/test.tsx +77 -0
  368. package/src/utils/index.ts +6 -0
  369. package/src/utils/scroll-to-error-decorator.ts +85 -0
  370. package/src/utils/scroll-to.ts +10 -0
  371. package/src/utils/use-field-validation/index.ts +1 -0
  372. package/src/utils/use-field-validation/test.tsx +73 -0
  373. package/src/utils/use-field-validation/use-field-validation.ts +63 -0
  374. package/src/utils/use-form-auto-save/index.ts +1 -0
  375. package/src/utils/use-form-auto-save/use-form-auto-save.ts +59 -0
  376. package/src/utils/use-form-input-reset/index.ts +1 -0
  377. package/src/utils/use-form-input-reset/test.ts +72 -0
  378. package/src/utils/use-form-input-reset/use-form-input-reset.ts +32 -0
  379. package/src/utils/validators.ts +18 -0
  380. package/utils.d.ts +1 -0
  381. package/utils.js +4 -0
  382. package/Autocomplete/Autocomplete.js.map +0 -1
  383. package/Autocomplete/index.js.map +0 -1
  384. package/AvatarUpload/AvatarUpload.js.map +0 -1
  385. package/AvatarUpload/index.js.map +0 -1
  386. package/ButtonCheckbox/ButtonCheckbox.js.map +0 -1
  387. package/ButtonCheckbox/index.js.map +0 -1
  388. package/ButtonRadio/ButtonRadio.js.map +0 -1
  389. package/ButtonRadio/index.js.map +0 -1
  390. package/Checkbox/Checkbox.js.map +0 -1
  391. package/Checkbox/index.d.ts +0 -1
  392. package/Checkbox/index.js.map +0 -1
  393. package/CheckboxGroup/CheckboxGroup.js.map +0 -1
  394. package/CheckboxGroup/CheckboxGroupContext.js.map +0 -1
  395. package/CheckboxGroup/index.js.map +0 -1
  396. package/DatePicker/DatePicker.js.map +0 -1
  397. package/DatePicker/index.js.map +0 -1
  398. package/Dropzone/Dropzone.js.map +0 -1
  399. package/Dropzone/index.js.map +0 -1
  400. package/Field/Field.js.map +0 -1
  401. package/Field/index.js.map +0 -1
  402. package/FieldBase/index.d.ts +0 -1
  403. package/FieldBase/index.js.map +0 -1
  404. package/FieldBase/types.d.ts +0 -8
  405. package/FieldLabel/FieldLabel.js.map +0 -1
  406. package/FieldLabel/index.js.map +0 -1
  407. package/FieldWrapper/FieldWrapper.js.map +0 -1
  408. package/FieldWrapper/index.js.map +0 -1
  409. package/FileInput/FileInput.js.map +0 -1
  410. package/FileInput/index.js.map +0 -1
  411. package/Form/Form.js.map +0 -1
  412. package/Form/FormContext.js.map +0 -1
  413. package/Form/FormRenderer.js.map +0 -1
  414. package/Form/index.js.map +0 -1
  415. package/Form/mutators/index.js.map +0 -1
  416. package/Form/mutators/set-active-field-touched.js.map +0 -1
  417. package/Form/mutators/set-has-multiline-counter.js.map +0 -1
  418. package/FormCompound/index.js.map +0 -1
  419. package/FormConfig/FormConfig.js.map +0 -1
  420. package/FormConfig/index.d.ts +0 -1
  421. package/FormConfig/index.js.map +0 -1
  422. package/Input/Input.js.map +0 -1
  423. package/Input/index.js.map +0 -1
  424. package/InputField/InputField.js.map +0 -1
  425. package/InputField/index.js.map +0 -1
  426. package/LICENSE +0 -20
  427. package/NumberInput/NumberInput.js.map +0 -1
  428. package/NumberInput/index.d.ts +0 -1
  429. package/NumberInput/index.js.map +0 -1
  430. package/PasswordInput/FieldRenderer.js.map +0 -1
  431. package/PasswordInput/PasswordInput.js.map +0 -1
  432. package/PasswordInput/index.js.map +0 -1
  433. package/PasswordInput/validators.js.map +0 -1
  434. package/Radio/Radio.js.map +0 -1
  435. package/Radio/index.js.map +0 -1
  436. package/RadioGroup/RadioGroup.js.map +0 -1
  437. package/RadioGroup/RadioGroupContext.js.map +0 -1
  438. package/RadioGroup/index.js.map +0 -1
  439. package/Rating/Rating.js.map +0 -1
  440. package/Rating/index.js.map +0 -1
  441. package/RichTextEditor/RichTextEditor.js.map +0 -1
  442. package/RichTextEditor/hooks/index.js.map +0 -1
  443. package/RichTextEditor/hooks/use-enforce-highlight-autofill.js.map +0 -1
  444. package/RichTextEditor/hooks/use-enforce-highlight-autofill.test.d.ts +0 -1
  445. package/RichTextEditor/hooks/use-enforce-highlight-autofill.test.js +0 -51
  446. package/RichTextEditor/hooks/use-enforce-highlight-autofill.test.js.map +0 -1
  447. package/RichTextEditor/index.js.map +0 -1
  448. package/Select/Select.js.map +0 -1
  449. package/Select/index.d.ts +0 -1
  450. package/Select/index.js.map +0 -1
  451. package/SubmitButton/SubmitButton.js.map +0 -1
  452. package/SubmitButton/index.js.map +0 -1
  453. package/Switch/Switch.js.map +0 -1
  454. package/Switch/index.js.map +0 -1
  455. package/TagSelector/TagSelector.js.map +0 -1
  456. package/TagSelector/index.d.ts +0 -1
  457. package/TagSelector/index.js.map +0 -1
  458. package/TimePicker/TimePicker.js.map +0 -1
  459. package/TimePicker/index.js.map +0 -1
  460. package/index.js.map +0 -1
  461. package/utils/flat-map.js.map +0 -1
  462. package/utils/form-values-change-decorator/form-values-change-decorator.js.map +0 -1
  463. package/utils/form-values-change-decorator/index.js.map +0 -1
  464. package/utils/index.js.map +0 -1
  465. package/utils/scroll-to-error-decorator.js.map +0 -1
  466. package/utils/scroll-to.js.map +0 -1
  467. package/utils/use-field-validation/index.js.map +0 -1
  468. package/utils/use-field-validation/use-field-validation.js.map +0 -1
  469. package/utils/use-form-auto-save/index.js.map +0 -1
  470. package/utils/use-form-auto-save/use-form-auto-save.js.map +0 -1
  471. package/utils/use-form-input-reset/index.js.map +0 -1
  472. package/utils/use-form-input-reset/use-form-input-reset.js.map +0 -1
  473. package/utils/validators.js.map +0 -1
  474. /package/{Autocomplete → dist-package/src/Autocomplete}/Autocomplete.js +0 -0
  475. /package/{Autocomplete → dist-package/src/Autocomplete}/index.js +0 -0
  476. /package/{AvatarUpload → dist-package/src/AvatarUpload}/AvatarUpload.js +0 -0
  477. /package/{AvatarUpload → dist-package/src/AvatarUpload}/index.js +0 -0
  478. /package/{ButtonCheckbox → dist-package/src/ButtonCheckbox}/ButtonCheckbox.js +0 -0
  479. /package/{ButtonCheckbox → dist-package/src/ButtonCheckbox}/index.js +0 -0
  480. /package/{ButtonRadio → dist-package/src/ButtonRadio}/ButtonRadio.js +0 -0
  481. /package/{ButtonRadio → dist-package/src/ButtonRadio}/index.js +0 -0
  482. /package/{Checkbox → dist-package/src/Checkbox}/Checkbox.js +0 -0
  483. /package/{Checkbox → dist-package/src/Checkbox}/index.js +0 -0
  484. /package/{CheckboxGroup → dist-package/src/CheckboxGroup}/CheckboxGroup.js +0 -0
  485. /package/{CheckboxGroup → dist-package/src/CheckboxGroup}/CheckboxGroupContext.js +0 -0
  486. /package/{CheckboxGroup → dist-package/src/CheckboxGroup}/index.js +0 -0
  487. /package/{DatePicker → dist-package/src/DatePicker}/DatePicker.js +0 -0
  488. /package/{DatePicker → dist-package/src/DatePicker}/index.js +0 -0
  489. /package/{Dropzone → dist-package/src/Dropzone}/Dropzone.js +0 -0
  490. /package/{Dropzone → dist-package/src/Dropzone}/index.js +0 -0
  491. /package/{Field → dist-package/src/Field}/Field.js +0 -0
  492. /package/{Field → dist-package/src/Field}/index.js +0 -0
  493. /package/{FieldBase → dist-package/src/FieldBase}/index.js +0 -0
  494. /package/{FieldBase → dist-package/src/FieldBase}/types.js +0 -0
  495. /package/{FieldLabel → dist-package/src/FieldLabel}/FieldLabel.js +0 -0
  496. /package/{FieldLabel → dist-package/src/FieldLabel}/index.js +0 -0
  497. /package/{FieldWrapper → dist-package/src/FieldWrapper}/FieldWrapper.js +0 -0
  498. /package/{FieldWrapper → dist-package/src/FieldWrapper}/index.js +0 -0
  499. /package/{FileInput → dist-package/src/FileInput}/FileInput.js +0 -0
  500. /package/{FileInput → dist-package/src/FileInput}/index.js +0 -0
  501. /package/{Form → dist-package/src/Form}/FormContext.js +0 -0
  502. /package/{Form → dist-package/src/Form}/FormRenderer.js +0 -0
  503. /package/{Form → dist-package/src/Form}/index.js +0 -0
  504. /package/{Form → dist-package/src/Form}/mutators/index.js +0 -0
  505. /package/{Form → dist-package/src/Form}/mutators/set-active-field-touched.js +0 -0
  506. /package/{Form → dist-package/src/Form}/mutators/set-has-multiline-counter.js +0 -0
  507. /package/{FormCompound → dist-package/src/FormCompound}/index.js +0 -0
  508. /package/{FormConfig → dist-package/src/FormConfig}/FormConfig.js +0 -0
  509. /package/{FormConfig → dist-package/src/FormConfig}/index.js +0 -0
  510. /package/{Input → dist-package/src/Input}/Input.js +0 -0
  511. /package/{Input → dist-package/src/Input}/index.js +0 -0
  512. /package/{InputField → dist-package/src/InputField}/InputField.js +0 -0
  513. /package/{InputField → dist-package/src/InputField}/index.js +0 -0
  514. /package/{NumberInput → dist-package/src/NumberInput}/NumberInput.js +0 -0
  515. /package/{NumberInput → dist-package/src/NumberInput}/index.js +0 -0
  516. /package/{PasswordInput → dist-package/src/PasswordInput}/FieldRenderer.js +0 -0
  517. /package/{PasswordInput → dist-package/src/PasswordInput}/PasswordInput.js +0 -0
  518. /package/{PasswordInput → dist-package/src/PasswordInput}/index.js +0 -0
  519. /package/{PasswordInput → dist-package/src/PasswordInput}/validators.js +0 -0
  520. /package/{Radio → dist-package/src/Radio}/Radio.js +0 -0
  521. /package/{Radio → dist-package/src/Radio}/index.js +0 -0
  522. /package/{RadioGroup → dist-package/src/RadioGroup}/RadioGroup.js +0 -0
  523. /package/{RadioGroup → dist-package/src/RadioGroup}/RadioGroupContext.js +0 -0
  524. /package/{RadioGroup → dist-package/src/RadioGroup}/index.js +0 -0
  525. /package/{Rating → dist-package/src/Rating}/Rating.js +0 -0
  526. /package/{Rating → dist-package/src/Rating}/index.js +0 -0
  527. /package/{RichTextEditor → dist-package/src/RichTextEditor}/RichTextEditor.js +0 -0
  528. /package/{RichTextEditor → dist-package/src/RichTextEditor}/hooks/index.js +0 -0
  529. /package/{RichTextEditor → dist-package/src/RichTextEditor}/hooks/use-enforce-highlight-autofill.js +0 -0
  530. /package/{RichTextEditor → dist-package/src/RichTextEditor}/index.js +0 -0
  531. /package/{Select → dist-package/src/Select}/index.js +0 -0
  532. /package/{SubmitButton → dist-package/src/SubmitButton}/SubmitButton.js +0 -0
  533. /package/{SubmitButton → dist-package/src/SubmitButton}/index.js +0 -0
  534. /package/{Switch → dist-package/src/Switch}/Switch.js +0 -0
  535. /package/{Switch → dist-package/src/Switch}/index.js +0 -0
  536. /package/{TagSelector → dist-package/src/TagSelector}/TagSelector.js +0 -0
  537. /package/{TagSelector → dist-package/src/TagSelector}/index.js +0 -0
  538. /package/{TimePicker → dist-package/src/TimePicker}/TimePicker.js +0 -0
  539. /package/{TimePicker → dist-package/src/TimePicker}/index.js +0 -0
  540. /package/{utils → dist-package/src/utils}/flat-map.js +0 -0
  541. /package/{utils → dist-package/src/utils}/form-values-change-decorator/form-values-change-decorator.js +0 -0
  542. /package/{utils → dist-package/src/utils}/form-values-change-decorator/index.js +0 -0
  543. /package/{utils → dist-package/src/utils}/index.js +0 -0
  544. /package/{utils → dist-package/src/utils}/scroll-to-error-decorator.js +0 -0
  545. /package/{utils → dist-package/src/utils}/scroll-to.js +0 -0
  546. /package/{utils → dist-package/src/utils}/use-field-validation/index.js +0 -0
  547. /package/{utils → dist-package/src/utils}/use-field-validation/use-field-validation.js +0 -0
  548. /package/{utils → dist-package/src/utils}/use-form-auto-save/index.js +0 -0
  549. /package/{utils → dist-package/src/utils}/use-form-auto-save/use-form-auto-save.js +0 -0
  550. /package/{utils → dist-package/src/utils}/use-form-input-reset/index.js +0 -0
  551. /package/{utils → dist-package/src/utils}/use-form-input-reset/use-form-input-reset.js +0 -0
  552. /package/{utils → dist-package/src/utils}/validators.js +0 -0
@@ -0,0 +1,99 @@
1
+ import React, { useCallback } from 'react'
2
+ import { useField } from 'react-final-form'
3
+ import { Container } from '@toptal/picasso'
4
+ import { SPACING_4 } from '@toptal/picasso-utils'
5
+ import {
6
+ FormNonCompound,
7
+ Checkbox,
8
+ Input,
9
+ DatePicker,
10
+ ConfigProvider,
11
+ SubmitButton,
12
+ } from '@toptal/picasso-forms'
13
+
14
+ type FormType = {
15
+ 'validateOnSubmit-hide': boolean
16
+ 'validateOnSubmit-name': {
17
+ first: string
18
+ last: string
19
+ }
20
+ 'validateOnSubmit-dob': string
21
+ }
22
+
23
+ const FormContent = () => {
24
+ const {
25
+ input: { value: hide },
26
+ } = useField('validateOnSubmit-hide')
27
+
28
+ return (
29
+ <>
30
+ <Checkbox
31
+ name='validateOnSubmit-hide'
32
+ label='Check to hide fields below'
33
+ />
34
+
35
+ {!hide && (
36
+ <>
37
+ <Input
38
+ enableReset
39
+ required
40
+ name='validateOnSubmit-name.first'
41
+ label='Your first name'
42
+ placeholder='e.g. Bruce'
43
+ />
44
+ <Input
45
+ enableReset
46
+ required
47
+ name='validateOnSubmit-name.last'
48
+ label='Your last name'
49
+ placeholder='e.g. Wayne'
50
+ />
51
+ <DatePicker required name='validateOnSubmit-dob' label='DOB' />
52
+ </>
53
+ )}
54
+ </>
55
+ )
56
+ }
57
+
58
+ const Example = () => {
59
+ const handleSubmit = useCallback((values: FormType) => api.submit(values), [])
60
+
61
+ return (
62
+ <ConfigProvider value={{ validateOnSubmit: true }}>
63
+ <FormNonCompound<FormType>
64
+ onSubmit={handleSubmit}
65
+ successSubmitMessage='Success!'
66
+ failedSubmitMessage='Failure!'
67
+ >
68
+ <FormContent />
69
+
70
+ <Container top={SPACING_4}>
71
+ <SubmitButton>Submit</SubmitButton>
72
+ </Container>
73
+ </FormNonCompound>
74
+ </ConfigProvider>
75
+ )
76
+ }
77
+
78
+ // the emulation of the api call
79
+ const responseWithDelay = async (response: any) =>
80
+ new Promise(resolve => setTimeout(() => resolve(response), 2000))
81
+
82
+ const api = {
83
+ submit: async ({
84
+ 'validateOnSubmit-name': name,
85
+ 'validateOnSubmit-hide': hide,
86
+ }: FormType) => {
87
+ if (hide || name?.first.toLowerCase() === 'bruce') {
88
+ return responseWithDelay(undefined)
89
+ }
90
+
91
+ return responseWithDelay({
92
+ name: {
93
+ first: 'Unknown first name',
94
+ },
95
+ })
96
+ },
97
+ }
98
+
99
+ export default Example
@@ -0,0 +1,289 @@
1
+ import Form from '../Form'
2
+ import fieldWrapperStory from '../../FieldWrapper/story'
3
+ import PicassoBook from '~/.storybook/components/PicassoBook'
4
+
5
+ const page = PicassoBook.section('Picasso Forms').createPage(
6
+ 'Form',
7
+ `Form
8
+
9
+ ${PicassoBook.createSourceLink(__filename)}
10
+
11
+ Confused between Form from Picasso and Picasso Forms?
12
+ Take a look at this
13
+ [page](/?path=/story/tutorials-difference-between-picasso-forms-and-base-form-components--difference-between-picasso-forms-and-base-form-components).
14
+ `
15
+ )
16
+
17
+ page
18
+ .createTabChapter('Props')
19
+ .addComponentDocs({
20
+ component: Form,
21
+ name: 'Form',
22
+ additionalDocs: {
23
+ disableScrollOnError: {
24
+ name: 'disableScrollOnError',
25
+ type: {
26
+ name: 'boolean',
27
+ },
28
+ description: `Whether to scroll to the failed field on the form error.`,
29
+ defaultValue: 'false',
30
+ },
31
+ autoComplete: {
32
+ name: 'autoComplete',
33
+ type: {
34
+ name: 'string',
35
+ enums: ['on', 'off'],
36
+ },
37
+ description: `HTML Form autocomplete attribute.\n
38
+ The autocomplete attribute specifies whether a form should have autocomplete 'on' or 'off'.
39
+ When autocomplete is 'on', the browser automatically complete values based on values that the user has entered before.\n
40
+ Tip: It is possible to have autocomplete 'on' for the form, and 'off' for specific input fields, or vice versa.`,
41
+ },
42
+ debug: {
43
+ name: 'debug',
44
+ type: {
45
+ name: 'function',
46
+ description:
47
+ '(state: FormState, fieldStates: { [string]: FieldState }) => void',
48
+ },
49
+ description:
50
+ 'A callback for debugging that receives the form state and the states of all the fields',
51
+ },
52
+ decorators: {
53
+ name: 'decorators',
54
+ type: 'Decorator[]',
55
+ description: 'An array of decorators to apply to the form',
56
+ },
57
+ initialValues: {
58
+ name: 'initialValues',
59
+ type: 'FormValues | Object',
60
+ description: 'The initial values of the form',
61
+ },
62
+ initialValuesEqual: {
63
+ name: 'initialValuesEqual',
64
+ type: {
65
+ name: 'function',
66
+ description: '(Object | undefined, Object | undefined) => boolean',
67
+ },
68
+ description:
69
+ 'A predicate to determine whether or not the initialValues prop has changed',
70
+ },
71
+ keepDirtyOnReinitialize: {
72
+ name: 'keepDirtyOnReinitialize',
73
+ type: 'boolean',
74
+ description:
75
+ 'If true, only pristine values will be overwritten when initialize(newValues) is called',
76
+ },
77
+ mutators: {
78
+ name: 'mutators',
79
+ type: {
80
+ name: 'object',
81
+ description: '{ [string]: Mutator }',
82
+ },
83
+ description: 'Named mutator functions',
84
+ },
85
+ onSubmit: {
86
+ name: 'onSubmit',
87
+ type: {
88
+ name: 'function',
89
+ description:
90
+ '(values: FormValues, form: FormApi, callback: ?(errors: ?Object) => void) => ?Object | Promise<?Object> | void',
91
+ },
92
+ description: 'Function to call when the form is submitted',
93
+ required: true,
94
+ },
95
+ subscription: {
96
+ name: 'subscription',
97
+ type: {
98
+ name: 'object',
99
+ description: '{ [string]: boolean }',
100
+ },
101
+ description:
102
+ 'An object of the parts of FormState (final-form) to subscribe to',
103
+ },
104
+ validate: {
105
+ name: 'validate',
106
+ type: {
107
+ name: 'function',
108
+ description: '(values: FormValues) => Object | Promise<Object>',
109
+ },
110
+ description:
111
+ 'A whole-record validation function that takes all the values of the form and returns any validation errors',
112
+ },
113
+ validateOnBlur: {
114
+ name: 'validateOnBlur',
115
+ type: 'boolean',
116
+ description:
117
+ 'If true, validation will happen on blur. If false, validation will happen on change',
118
+ defaultValue: 'false',
119
+ },
120
+ successSubmitMessage: {
121
+ name: 'successSubmitMessage',
122
+ type: 'ReactNode',
123
+ description:
124
+ 'Message to display in a tooltip when form submitted successfully',
125
+ },
126
+ failedSubmitMessage: {
127
+ name: 'failedSubmitMessage',
128
+ type: 'ReactNode',
129
+ description:
130
+ 'Message to display in a tooltip when form submission failed',
131
+ },
132
+ scrollOffsetTop: {
133
+ name: 'scrollOffsetTop',
134
+ type: 'number',
135
+ description:
136
+ 'Offset from the viewport for inputs to focus on, defaults to the center of the window (deprecated, will not have any effect)',
137
+ },
138
+ },
139
+ })
140
+ .addComponentDocs(fieldWrapperStory.componentDocs)
141
+
142
+ page
143
+ .createChapter()
144
+ .addTextSection(
145
+ `
146
+ Form is a wrapper for 'react-final-form' Form component.
147
+ The rest of the form components can be imported from \`@toptal/picasso-forms\`
148
+ `
149
+ )
150
+ .addExample(
151
+ 'Form/story/Default.example.tsx',
152
+ {
153
+ title: 'Default',
154
+ description: `
155
+ A general look of the form includes the examples of all the input
156
+ types supported by picasso-forms.
157
+ `,
158
+ },
159
+ 'picasso-form'
160
+ )
161
+ .addExample(
162
+ 'Form/story/Horizontal.example.tsx',
163
+ {
164
+ title: 'Horizontal',
165
+ description:
166
+ 'Horizontal form with responsive design. Use "FormActionsContainer" component to align form actions according to the form layout or use "useFieldsLayoutContext()" hook to get access to the current form layout.',
167
+ screenshotBreakpoints: true,
168
+ },
169
+ 'picasso-form'
170
+ )
171
+ .addExample(
172
+ 'Form/story/HorizontalLabelWidth.example.tsx',
173
+ {
174
+ title: 'Horizontal with custom label width',
175
+ description:
176
+ "Customize the label width of your horizontal form, so it doesn't have too much empty space",
177
+ screenshotBreakpoints: true,
178
+ },
179
+ 'picasso-form'
180
+ )
181
+ .addExample(
182
+ 'Form/story/CustomValidator.example.tsx',
183
+ {
184
+ title: 'Custom validator',
185
+ description: `
186
+ We have a 'required' validator included by default to each input type,
187
+ however, you may need custom validators for more complex types of fields.
188
+ `,
189
+ takeScreenshot: false,
190
+ },
191
+ 'picasso-form'
192
+ )
193
+ .addExample(
194
+ 'Form/story/ParseInput.example.tsx',
195
+ {
196
+ title: 'Change form input value',
197
+ description: `
198
+ When you use picasso-forms your form input components are no longer
199
+ completely controlled and they are controlled by final-form, which
200
+ gives you the opportunity to rely on it with displaying errors,
201
+ validations, etc.
202
+
203
+ However, sometimes you may need to be able to modify the form input
204
+ value.
205
+ `,
206
+ takeScreenshot: false,
207
+ },
208
+ 'picasso-form'
209
+ )
210
+ .addExample(
211
+ 'Form/story/BackendCommunication.example.tsx',
212
+ {
213
+ title: 'Backend communication',
214
+ description: `
215
+ The form usually need to send data to backend, so we need to have
216
+ backend communication and display the process of submission and
217
+ the results. The form-level results are represented by notifications.
218
+ `,
219
+ takeScreenshot: false,
220
+ },
221
+ 'picasso-form'
222
+ )
223
+ .addExample(
224
+ 'Form/story/CustomFormLevelConfiguration.example.tsx',
225
+ 'Form Level Configurations'
226
+ )
227
+ .addExample(
228
+ 'Form/story/ValidateOnSubmit.example.tsx',
229
+ {
230
+ title: 'Validate only on submit',
231
+ description: `
232
+ All fields should not show any validation error messages until submission is made.
233
+ `,
234
+ takeScreenshot: false,
235
+ },
236
+ 'picasso-form'
237
+ )
238
+ .addExample('Form/story/FileInput.example.tsx', {
239
+ title: 'File input on a Form',
240
+ description: 'Showcase how to upload files on the form submission',
241
+ takeScreenshot: false,
242
+ })
243
+ .addExample('Form/story/Dropzone.example.tsx', {
244
+ title: 'Dropzone on a Form',
245
+ description:
246
+ 'Showcase how to upload files on the form submission using dropzone',
247
+ takeScreenshot: false,
248
+ })
249
+ .addExample('Form/story/TitleCase.example.tsx', {
250
+ title: 'Title case',
251
+ description: "Display the field's label in title case.",
252
+ takeScreenshot: false,
253
+ })
254
+ .addExample('Form/story/NoScrolling.example.tsx', {
255
+ title: 'No scrolling case',
256
+ description: "Showcase Form's behavior on form submission error.",
257
+ takeScreenshot: false,
258
+ })
259
+ .addExample('Form/story/RichTextEditor.example.tsx', {
260
+ title: 'Rich text editor',
261
+ description: 'Showcase how to use RichTextEditor in the form.',
262
+ takeScreenshot: false,
263
+ })
264
+ .addExample('Form/story/FieldRequirements.example.tsx', {
265
+ title: 'Field requirements',
266
+ description: 'Showcase how to display field requirements.',
267
+ takeScreenshot: false,
268
+ })
269
+ .addExample('Form/story/Status.example.tsx', {
270
+ title: 'Form Level Status Configuration',
271
+ description:
272
+ 'Showcase how to enable success status via form configuration.',
273
+ takeScreenshot: false,
274
+ })
275
+ .addExample('Form/story/AvatarUpload.example.tsx', {
276
+ title: 'AvatarUpload',
277
+ description:
278
+ 'Showcase how to handle avatar upload with external upload service.',
279
+ takeScreenshot: false,
280
+ })
281
+ .addExample('Form/story/AutoSave.example.tsx', {
282
+ title: 'Auto-save',
283
+ description: 'Showcase how to use auto-save functionality.',
284
+ takeScreenshot: false,
285
+ })
286
+ .addExample('Form/story/HighlightAutofill.example.tsx', {
287
+ title: 'Highlight fields with default value',
288
+ waitFor: () => document.querySelector('#highlight-autofill-submit-button'),
289
+ })
@@ -0,0 +1,202 @@
1
+ import React from 'react'
2
+ import { fireEvent, render, waitFor, act } from '@toptal/picasso-test-utils'
3
+ import type { OmitInternalProps } from '@toptal/picasso-shared'
4
+ import { Button } from '@toptal/picasso'
5
+
6
+ import type { Props } from './Form'
7
+ import { FormCompound as Form } from '../FormCompound'
8
+ import { scrollTo } from '../utils/scroll-to'
9
+
10
+ jest.mock('../utils', () => {
11
+ const actualUtils = jest.requireActual('../utils')
12
+
13
+ return {
14
+ ...actualUtils,
15
+ createScrollToErrorDecorator: jest.requireActual(
16
+ '../utils/scroll-to-error-decorator'
17
+ ).default,
18
+ }
19
+ })
20
+ jest.mock('../utils/scroll-to', () => ({
21
+ scrollTo: jest.fn(),
22
+ }))
23
+
24
+ const renderForm = (
25
+ props: OmitInternalProps<Props> & {
26
+ mandatory?: boolean
27
+ showValidState?: boolean
28
+ }
29
+ ) => {
30
+ const {
31
+ onSubmit,
32
+ disableScrollOnError,
33
+ mandatory,
34
+ showValidState,
35
+ validateOnBlur,
36
+ } = props
37
+
38
+ return render(
39
+ <Form.ConfigProvider value={{ showValidState }}>
40
+ <Form
41
+ data-testid='form'
42
+ onSubmit={onSubmit}
43
+ disableScrollOnError={disableScrollOnError}
44
+ validateOnBlur={validateOnBlur}
45
+ >
46
+ <Form.Input
47
+ name='test'
48
+ placeholder='test input'
49
+ required={mandatory}
50
+ testIds={{ validIcon: 'valid-icon' }}
51
+ />
52
+ <Button type='submit'>Submit</Button>
53
+ </Form>
54
+ </Form.ConfigProvider>
55
+ )
56
+ }
57
+
58
+ interface FormData {
59
+ skills: { value: string; text: string }[]
60
+ }
61
+
62
+ const skillOptions = [
63
+ { value: '0', text: 'HTML' },
64
+ { value: '1', text: 'CSS' },
65
+ { value: '2', text: 'Javascript' },
66
+ ]
67
+
68
+ const initialValues: FormData = {
69
+ skills: [skillOptions[0]],
70
+ }
71
+
72
+ const renderTagSelectorWithInitialValue = (
73
+ onSubmit: (values: FormData) => void
74
+ ) => {
75
+ return render(
76
+ <Form onSubmit={values => onSubmit(values)} initialValues={initialValues}>
77
+ <Form.TagSelector
78
+ name='skills'
79
+ label='Skills'
80
+ options={skillOptions}
81
+ inputValue=''
82
+ />
83
+ <Button type='submit'>Submit</Button>
84
+ </Form>
85
+ )
86
+ }
87
+
88
+ const scrollToMock = scrollTo as jest.Mock
89
+
90
+ describe('Form', () => {
91
+ beforeEach(() => {
92
+ scrollToMock.mockReset()
93
+ })
94
+
95
+ it('renders', async () => {
96
+ const { container, getByText } = renderForm({
97
+ onSubmit: () => {},
98
+ mandatory: false,
99
+ })
100
+
101
+ await act(() => {
102
+ fireEvent.click(getByText('Submit'))
103
+ })
104
+
105
+ await waitFor(() => {
106
+ expect(scrollToMock).toHaveBeenCalledTimes(0)
107
+ expect(container).toMatchSnapshot()
108
+ })
109
+ })
110
+
111
+ it('renders with an error', async () => {
112
+ const { container, getByText } = renderForm({
113
+ onSubmit: () => Promise.resolve({ test: 'Some error' }),
114
+ mandatory: true,
115
+ })
116
+
117
+ await act(() => {
118
+ fireEvent.click(getByText('Submit'))
119
+ })
120
+
121
+ await waitFor(() => {
122
+ expect(scrollToMock).toHaveBeenCalledTimes(1)
123
+ expect(container).toMatchSnapshot()
124
+ })
125
+ })
126
+
127
+ it('when `disableScrollOnError` is specified', async () => {
128
+ const { getByText } = renderForm({
129
+ onSubmit: () => ({ test: 'Some error' }),
130
+ disableScrollOnError: true,
131
+ mandatory: true,
132
+ })
133
+
134
+ await act(() => {
135
+ fireEvent.click(getByText('Submit'))
136
+ })
137
+
138
+ await waitFor(() => {
139
+ expect(scrollToMock).not.toHaveBeenCalled()
140
+ })
141
+ })
142
+
143
+ describe('when validateOnBlur is enabled', () => {
144
+ it('validates only on blur', async () => {
145
+ const { getByPlaceholderText, getByText, queryByText } = renderForm({
146
+ onSubmit: () => ({ test: 'Some error' }),
147
+ disableScrollOnError: true,
148
+ mandatory: true,
149
+ validateOnBlur: true,
150
+ })
151
+
152
+ const input = getByPlaceholderText('test input')
153
+
154
+ fireEvent.blur(input)
155
+ expect(getByText('Please complete this field.')).toBeInTheDocument()
156
+
157
+ fireEvent.change(input, { target: { value: 'value' } })
158
+ expect(getByText('Please complete this field.')).toBeInTheDocument()
159
+
160
+ fireEvent.blur(input)
161
+ expect(queryByText('Please complete this field.')).not.toBeInTheDocument()
162
+ })
163
+
164
+ describe('when showValidState is enabled', () => {
165
+ it('shows validation success when form submitted on Enter', async () => {
166
+ const { getByPlaceholderText, getByTestId } = renderForm({
167
+ onSubmit: () => {},
168
+ disableScrollOnError: false,
169
+ mandatory: true,
170
+ showValidState: true,
171
+ validateOnBlur: true,
172
+ })
173
+
174
+ const input = getByPlaceholderText('test input')
175
+
176
+ await act(async () => {
177
+ fireEvent.focus(input)
178
+ fireEvent.change(input, { target: { value: 'value' } })
179
+ fireEvent.submit(input)
180
+ })
181
+
182
+ await waitFor(() => {
183
+ expect(getByTestId('valid-icon')).toBeInTheDocument()
184
+ })
185
+ })
186
+ })
187
+ })
188
+
189
+ describe('when initial values provided to form', () => {
190
+ it('fills TagSelector field with provided values', async () => {
191
+ const onSubmit = jest.fn()
192
+
193
+ const { getByText } = renderTagSelectorWithInitialValue(onSubmit)
194
+
195
+ await act(() => {
196
+ fireEvent.click(getByText('Submit'))
197
+ })
198
+
199
+ expect(onSubmit).toHaveBeenCalledWith(initialValues)
200
+ })
201
+ })
202
+ })
@@ -0,0 +1,51 @@
1
+ import { FieldRequirements } from '@toptal/picasso'
2
+
3
+ import Form from '../Form'
4
+ import Autocomplete from '../Autocomplete'
5
+ import Input from '../Input'
6
+ import Select from '../Select'
7
+ import Radio from '../Radio'
8
+ import ButtonRadio from '../ButtonRadio'
9
+ import RadioGroup from '../RadioGroup'
10
+ import Checkbox from '../Checkbox'
11
+ import ButtonCheckbox from '../ButtonCheckbox'
12
+ import CheckboxGroup from '../CheckboxGroup'
13
+ import NumberInput from '../NumberInput'
14
+ import FileInput from '../FileInput'
15
+ import DatePicker from '../DatePicker'
16
+ import TimePicker from '../TimePicker'
17
+ import TagSelector from '../TagSelector'
18
+ import SubmitButton from '../SubmitButton'
19
+ import Switch from '../Switch'
20
+ import Rating from '../Rating'
21
+ import Dropzone from '../Dropzone'
22
+ import RichTextEditor from '../RichTextEditor'
23
+ import PasswordInput from '../PasswordInput'
24
+ import { FormConfigContext } from '../FormConfig'
25
+ import AvatarUpload from '../AvatarUpload'
26
+
27
+ export const FormCompound = Object.assign(Form, {
28
+ Autocomplete: Autocomplete,
29
+ Input: Input,
30
+ Select: Select,
31
+ Radio: Radio,
32
+ ButtonRadio: ButtonRadio,
33
+ RadioGroup: RadioGroup,
34
+ Checkbox: Checkbox,
35
+ ButtonCheckbox: ButtonCheckbox,
36
+ CheckboxGroup: CheckboxGroup,
37
+ NumberInput: NumberInput,
38
+ FileInput: FileInput,
39
+ DatePicker: DatePicker,
40
+ TimePicker: TimePicker,
41
+ TagSelector: TagSelector,
42
+ SubmitButton: SubmitButton,
43
+ ConfigProvider: FormConfigContext.Provider,
44
+ Switch: Switch,
45
+ Rating: Rating,
46
+ Dropzone: Dropzone,
47
+ PasswordInput: PasswordInput,
48
+ FieldRequirements: FieldRequirements,
49
+ RichTextEditor: RichTextEditor,
50
+ AvatarUpload: AvatarUpload,
51
+ })
@@ -0,0 +1,35 @@
1
+ import { createContext, useContext } from 'react'
2
+
3
+ export type RequiredVariant = 'default' | 'asterisk'
4
+
5
+ type ValidationOnSubmitConfig = {
6
+ showValidState?: false
7
+ validateOnSubmit?: true
8
+ }
9
+
10
+ type ShowValidStateConfig = {
11
+ showValidState?: true
12
+ validateOnSubmit?: false
13
+ }
14
+
15
+ type NoValidationConfig = {
16
+ showValidState?: false
17
+ validateOnSubmit?: false
18
+ }
19
+
20
+ // reason for different types is that we want to deny the user to set both showValidState and validateOnSubmit to true
21
+ export type FormConfigProps = (
22
+ | ValidationOnSubmitConfig
23
+ | ShowValidStateConfig
24
+ | NoValidationConfig
25
+ ) & {
26
+ requiredVariant?: RequiredVariant
27
+ highlightAutofill?: boolean
28
+ }
29
+
30
+ export const FormConfigContext = createContext<FormConfigProps>({
31
+ highlightAutofill: false,
32
+ })
33
+ export const FormConfigProvider = FormConfigContext.Provider
34
+
35
+ export const useFormConfig = () => useContext(FormConfigContext)
@@ -0,0 +1 @@
1
+ export * from './FormConfig'